]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.99pre3-1 2.3.99pre3-1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:33:12 +0000 (15:33 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:33:12 +0000 (15:33 -0500)
28 files changed:
CREDITS
Documentation/isapnp.txt
Documentation/video4linux/bttv/README
Makefile
drivers/char/bttv.c
drivers/char/bttv.h
drivers/char/serial.c
drivers/pnp/isapnp.c
drivers/scsi/advansys.c
drivers/usb/hid-debug.h
drivers/usb/hid.c
drivers/usb/hid.h
drivers/usb/keybdev.c
drivers/usb/mousedev.c
drivers/usb/serial/usb-serial.c
drivers/usb/serial/usb-serial.h
drivers/usb/uhci.c
drivers/usb/usb-ohci.c
drivers/usb/usb-uhci.c
drivers/usb/wacom.c
fs/ntfs/inode.c
include/linux/input.h
include/linux/isapnp.h
ipc/shm.c
net/ipv4/netfilter/Makefile
net/ipv4/netfilter/ip_conntrack_ftp.c
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/netfilter/ip_nat_standalone.c

diff --git a/CREDITS b/CREDITS
index e20a1f141d61f55df619ccc912fe529caddeb8ea..b0c8c54217682ac078662ae0b5b27c4c421291e3 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1327,6 +1327,13 @@ N: Andreas S. Krebs
 E: akrebs@altavista.net
 D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards
 
+N: Greg Kroah-Hartman
+E: greg@kroah.com
+W: http://www.kroah.com/linux-usb/
+D: USB Serial Converter driver framework, USB Handspring Visor driver
+D: ConnectTech WHITEHeat USB driver, Generic USB Serial driver
+D: bits and pieces of USB core code.
+
 N: Russell Kroll
 E: rkroll@exploits.org
 W: http://www.exploits.org/
@@ -1360,10 +1367,13 @@ S: D-91080 Uttenreuth
 S: Germany
 
 N: Jaroslav Kysela
-E: perex@jcu.cz
-W: http://www.pf.jcu.cz/~perex
+E: perex@suse.cz
+W: http://www.perex.cz
 D: Original Author and Maintainer for HP 10/100 Mbit Network Adapters
-S: Unix Centre of Pedagogical Faculty, University of South Bohemia
+D: ISA PnP
+S: Sindlovy Dvory 117
+S: 370 01  Ceske Budejovice
+S: Czech Republic
 
 N: Bas Laarhoven
 E: bas@vimec.nl
index 4054ecf2fba8fe739ff8bde98574b5bcba511d50..4cb7a9b593111ea77e83744cf5c41d9b5998ed29 100644 (file)
@@ -64,10 +64,10 @@ extern struct pci_bus *isapnp_find_card(unsigned short vendor,
                                         unsigned short device,
                                         struct pci_bus *from);
 
-The above function finds a ISA PnP card. For the vendor device should
+This function finds a ISA PnP card. For the vendor device should
 be used ISAPNP_VENDOR(a,b,c) where a,b,c are characters or integers.
 For the device number should be used ISAPNP_DEVICE(x) macro where x is
-integer value. Both vendor and device numbers can be get from contents
+integer value. Both vendor and device numbers can be taken from contents
 of the /proc/isapnp file.
 
 extern struct pci_dev *isapnp_find_dev(struct pci_bus *card,
@@ -75,12 +75,37 @@ extern struct pci_dev *isapnp_find_dev(struct pci_bus *card,
                                        unsigned short function,
                                        struct pci_dev *from);
 
-The above function finds the ISA PnP device. If card is NULL, then
+This function finds the ISA PnP device. If card is NULL, then
 the global search mode is used (all devices are used for the searching).
 Otherwise only devices which belongs to the specified card are verified.
 For the function number can be used ISAPNP_FUNCTION(x) macro which works
 similarly as the ISAPNP_DEVICE(x) macro.
 
+extern int isapnp_probe_cards(const struct isapnp_card_id *ids,
+                             int (*probe)(struct pci_bus *card,
+                                          const struct isapnp_card_id *id));
+
+
+This function is a helper for drivers which requires to use more than
+one device from an ISA PnP card. For each cards is called the probe
+callback with appropriate information.
+
+Example for ids parameter initialization:
+
+static struct isapnp_card_id ids[] __devinitdata = {
+       {
+               ISAPNP_CARD_ID('A','D','V', 0x550a),
+                devs: {
+                       ISAPNP_DEVICE_ID('A', 'D', 'V', 0x0010),
+                       ISAPNP_DEVICE_ID('A', 'D', 'V', 0x0011)
+               },
+               driver_data: 0x1234,
+       },
+       {
+               ISAPNP_CARD_END,
+       }
+};
+
 ISA PnP configuration
 =====================
 
@@ -99,19 +124,25 @@ otherwise the access to the ISA PnP configuration functions will be blocked.
 Second way is auto-configuration
 --------------------------------
 
-These two functions gives to the driver the real power of the ISA PnP
-feature. First function dev->prepare() only initialize the resource
-members in the device structure. This structure contains all resources
-set to auto configuration values after the initialization. The driver for
-ISA PnP device may modify (or not) some resources to skip auto configuration
-for the given resource.
+This feature gives to the driver the real power of the ISA PnP code.
+Function dev->prepare() initializes the resource members in the device
+structure. This structure contains all resources set to auto configuration
+values after the initialization. The device driver may modify some resources
+to skip the auto configuration for a given resource.
 
-The function isapnp_configure does:
-       - resources which have the auto configuration value are configured
+Once the device structure contains all requested resource values, the function
+dev->activate() must be called to assign free resources to resource members
+with the auto configuration value.
+
+Function dev->activate() does:
+       - resources with the auto configuration value are configured
        - the auto configuration is created using ISA PnP resource map
        - the function writes configuration to ISA PnP configuration registers
        - the function returns to the caller actual used resources
 
+When the device driver is removing, function dev->deactivate() has to be
+called to free all assigned resources.
+
 Example (game port initialization)
 ==================================
 
index 4d82987722324c0454e197dbad2003e75d8bc0ec..868feedb997ceec3916fa76f15073b80b11341d3 100644 (file)
@@ -84,6 +84,13 @@ trouble with some specific TV card, try to ask there instead of
 mailing me directly.  The chance that someone with the same card
 listens there is much higher...
 
+For problems with sound:  There are alot of different systems used
+for TV sound all over the world.  And there are also different chips
+which decode the audio signal.  Reports about sound problems ("stereo
+does'nt work") are pretty useless unless you include some details
+about your hardware and the TV sound scheme used in your country (or
+at least the country you are living in).
+
 
 Finally: If you mail some patches for bttv around the world (to
 linux-kernel/Alan/Linus/...), please Cc: me.
index ca65a9a8d7f006af3dd7b81dca35eb330604deba..96c739e8d9c8e3d2a1c3f25bd8ee41701baeb4ca 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 3
 SUBLEVEL = 99
-EXTRAVERSION = -pre2
+EXTRAVERSION = -pre3
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -179,8 +179,7 @@ DRIVERS += $(DRIVERS-y)
 
 include arch/$(ARCH)/Makefile
 
-export CORE_FILES NETWORKS DRIVERS LIBS HEAD LDFLAGS LIBS LINKFLAGS \
-       MAKEBOOT ASFLAGS
+export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
 
 # use '-fno-strict-aliasing', but only if the compiler can take it
 CFLAGS += $(shell if $(CC) -fno-strict-aliasing -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strict-aliasing"; fi)
index 66dfc0fe5257e2cb94add3d69f8f633eb04c1041..59adf47bc88a4885bbbeca3a276a67a9d55561d1 100644 (file)
@@ -121,6 +121,7 @@ static unsigned int autoload = 0;
 #define I2C_GET()   (btread(BT848_I2C)&1)
 
 #define BURSTOFFSET 76
+#define BTTV_ERRORS 5
 
 
 /* ----------------------------------------------------------------------- */
@@ -133,7 +134,6 @@ int bttv_get_id(unsigned int card)
        if (card >= bttv_num) {
                return -1;
        }
-               
        return bttvs[card].type;
 }
 
@@ -146,10 +146,7 @@ int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data)
        }
        
        btv = &bttvs[card];
-       down(&btv->lock);
        btaor(data, ~mask, BT848_GPIO_OUT_EN);
-       up(&btv->lock);
-
        return 0;
 }
 
@@ -167,15 +164,9 @@ int bttv_read_gpio(unsigned int card, unsigned long *data)
                return -ENODEV;
        }
 
-       down(&btv->lock);
-
 /* prior setting BT848_GPIO_REG_INP is (probably) not needed 
    because we set direct input on init */
-
        *data = btread(BT848_GPIO_DATA);
-
-       up(&btv->lock);
-
        return 0;
 }
 
@@ -189,15 +180,9 @@ int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data)
 
        btv = &bttvs[card];
 
-       down(&btv->lock);
-
 /* prior setting BT848_GPIO_REG_INP is (probably) not needed 
    because direct input is set on init */
-
        btaor(data & mask, ~mask, BT848_GPIO_DATA);
-
-       up(&btv->lock);
-
        return 0;
 }
 
@@ -210,11 +195,9 @@ WAIT_QUEUE* bttv_get_gpio_queue(unsigned int card)
        }
 
        btv = &bttvs[card];
-
        if (bttvs[card].shutdown) {
                return NULL;
        }
-
        return &btv->gpioq;
 }
 
@@ -787,7 +770,7 @@ static struct tvcard tvcards[] =
           4, 1, 0, 2,15, { 2, 3, 1, 1}, { 2, 0, 0, 0,10},0,
          1,1,1,1,0 },
         { "Hauppauge old",
-          3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4},0,
+          4, 1, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4},0,
          1,1,0,1,0 },
         { "STB",
           3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 4, 0, 2, 3, 1},0,
@@ -815,7 +798,7 @@ static struct tvcard tvcards[] =
           3, 1, 0, 2, 3, { 2, 3, 1, 1}, { 1, 1, 2, 3, 0},0,
          1,1,1,1,0 },
         { "Hauppauge new (bt878)",
-         3, 1, 0, 2, 7, { 2, 0, 1, 1}, { 0, 1, 2, 3, 4},0,
+         4, 1, 0, 2, 7, { 2, 0, 1, 1}, { 0, 1, 2, 3, 4},0,
          1,1,0,1,0 },
         { "MIRO PCTV pro",
           3, 1, 0, 2, 65551, { 2, 3, 1, 1}, {1,65537, 0, 0,10},0,
@@ -1213,7 +1196,7 @@ static void make_vbitab(struct bttv *btv)
        unsigned int *pe=(unsigned int *) btv->vbi_even;
   
        if (debug)
-               printk("bttv%d: vbi: po=%08lx pe=%08lx\n",
+               printk("bttv%d: vbi1: po=%08lx pe=%08lx\n",
                       btv->nr,virt_to_bus(po), virt_to_bus(pe));
         
        *(po++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(po++)=0;
@@ -1233,8 +1216,10 @@ static void make_vbitab(struct bttv *btv)
        }
        *(pe++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(0x01<<16));
        *(pe++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+10));
-       DEBUG(printk(KERN_DEBUG "po: 0x%lx\n",(long)po));
-       DEBUG(printk(KERN_DEBUG "pe: 0x%lx\n",(long)pe));
+
+       if (debug)
+               printk("bttv%d: vbi2: po=%08lx pe=%08lx\n",
+                      btv->nr,virt_to_bus(po), virt_to_bus(pe));
 }
 
 static int fmtbppx2[16] = {
@@ -1310,7 +1295,7 @@ static int  make_prisctab(struct bttv *btv, unsigned int *ro,
        int shift, csize;       
 
        if (debug)
-               printk("bttv%d: prisc: ro=%08lx re=%08lx\n",
+               printk("bttv%d: prisc1: ro=%08lx re=%08lx\n",
                       btv->nr,virt_to_bus(ro), virt_to_bus(re));
 
        switch(fmt)
@@ -1406,6 +1391,10 @@ static int  make_prisctab(struct bttv *btv, unsigned int *ro,
        *(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
        *(re++)=cpu_to_le32(btv->bus_vbi_odd);
        
+       if (debug)
+               printk("bttv%d: prisc2: ro=%08lx re=%08lx\n",
+                      btv->nr,virt_to_bus(ro), virt_to_bus(re));
+
        return 0;
 }
  
@@ -1428,7 +1417,7 @@ static int  make_vrisctab(struct bttv *btv, unsigned int *ro,
                 return make_prisctab(btv, ro, re, vbuf, width, height, palette);
 
        if (debug)
-               printk("bttv%d: vrisc: ro=%08lx re=%08lx\n",
+               printk("bttv%d: vrisc1: ro=%08lx re=%08lx\n",
                       btv->nr,virt_to_bus(ro), virt_to_bus(re));
        
        inter = (height>tvnorms[btv->win.norm].sheight/2) ? 1 : 0;
@@ -1478,6 +1467,10 @@ static int  make_vrisctab(struct bttv *btv, unsigned int *ro,
        *(ro++)=cpu_to_le32(btv->bus_vbi_even);
        *(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
        *(re++)=cpu_to_le32(btv->bus_vbi_odd);
+
+       if (debug)
+               printk("bttv%d: vrisc2: ro=%08lx re=%08lx\n",
+                      btv->nr,virt_to_bus(ro), virt_to_bus(re));
        
        return 0;
 }
@@ -1555,7 +1548,7 @@ static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr)
        width=btv->win.width;
        height=btv->win.height;
        if (debug)
-               printk("bttv%d: make_clip: pal=%d size=%dx%d, bpl=%d bpp=%d\n",
+               printk("bttv%d: clip1: pal=%d size=%dx%d, bpl=%d bpp=%d\n",
                       btv->nr,btv->picture.palette,width,height,bpl,bpp);
        if(width > 1023)
                width = 1023;           /* sanity check */
@@ -1662,6 +1655,10 @@ static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr)
        *(ro++)=cpu_to_le32(btv->bus_vbi_even);
        *(re++)=cpu_to_le32(BT848_RISC_JUMP);
        *(re++)=cpu_to_le32(btv->bus_vbi_odd);
+
+       if (debug)
+               printk("bttv%d: clip2: pal=%d size=%dx%d, bpl=%d bpp=%d\n",
+                      btv->nr,btv->picture.palette,width,height,bpl,bpp);
 }
 
 /*
@@ -1879,7 +1876,7 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
        if(btv->gbuf[mp->frame].stat != GBUFFER_UNUSED)
                return -EBUSY;
                
-       if(mp->height <0 || mp->width <0)
+       if(mp->height < 32 || mp->width < 32)
                return -EINVAL;
        if (mp->format >= PALETTEFMT_MAX)
                return -EINVAL;
@@ -1890,12 +1887,6 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
        if(-1 == palette2fmt[mp->format])
                return -EINVAL;
 
-       /*
-        *      FIXME: Check the format of the grab here. This is probably
-        *      also less restrictive than the normal overlay grabs. Stuff
-        *      like QCIF has meaning as a capture.
-        */
-        
        /*
         *      Ok load up the BT848
         */
@@ -1906,7 +1897,8 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
         make_vrisctab(btv, ro, re, vbuf, mp->width, mp->height, mp->format);
 
        if (debug)
-               printk("bttv%d: cap vgrab: queue %d\n",btv->nr,mp->frame);
+               printk("bttv%d: cap vgrab: queue %d (%dx%d)\n",
+                      btv->nr,mp->frame,mp->width,mp->height);
         cli();
         btv->gbuf[mp->frame].stat    = GBUFFER_GRABBING;
        btv->gbuf[mp->frame].fmt     = palette2fmt[mp->format];
@@ -1995,6 +1987,26 @@ static inline void burst(int on)
        tvnorms[2].hdelayx1     = 186  - (on?BURSTOFFSET  :0);
 }
 
+static void bt848_restart(struct bttv *btv)
+{
+       if (verbose)
+               printk("bttv%d: resetting chip\n",btv->nr);
+       btwrite(0xfffffUL, BT848_INT_STAT);
+       btand(~15, BT848_GPIO_DMA_CTL);
+       btwrite(0, BT848_SRESET);
+       btwrite(virt_to_bus(btv->risc_jmp+2),
+               BT848_RISC_STRT_ADD);
+
+       /* enforce pll reprogramming */
+       btv->pll.pll_current = 0;
+       set_pll(btv);
+
+       btv->errors = 0;
+       btv->needs_restart = 0;
+       bt848_set_geo(btv,0);
+       bt848_set_risc_jmps(btv,-1);
+}
+
 /*
  *     Open a bttv card. Right now the flags stuff is just playing
  */
@@ -2020,6 +2032,8 @@ static int bttv_open(struct video_device *dev, int flags)
         for (i = 0; i < gbuffers; i++)
                 btv->gbuf[i].stat = GBUFFER_UNUSED;
 
+       if (btv->needs_restart)
+               bt848_restart(btv);
         burst(0);
        set_pll(btv);
         btv->user++;
@@ -2117,7 +2131,6 @@ static inline void bt848_sat_v(struct bttv *btv, unsigned long data)
        btaor(datahi, ~1, BT848_O_CONTROL);
 }
 
-
 /*
  *     ioctl routine
  */
@@ -2126,7 +2139,7 @@ static inline void bt848_sat_v(struct bttv *btv, unsigned long data)
 static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
 {
        struct bttv *btv=(struct bttv *)dev;
-       int i,ret;
+       int i,ret = 0;
 
        if (debug) printk("bttv%d: ioctl 0x%x\n",btv->nr,cmd);
 
@@ -2281,7 +2294,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        
                if(copy_from_user(&vw,arg,sizeof(vw)))
                        return -EFAULT;
-                               
+
                if(vw.flags || vw.width < 16 || vw.height < 16) 
                {
                         down(&btv->lock);
@@ -2296,6 +2309,8 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        vw.width &= ~3;
                }
                down(&btv->lock);
+               if (btv->needs_restart)
+                       bt848_restart(btv);
                btv->win.x=vw.x;
                btv->win.y=vw.y;
                btv->win.width=vw.width;
@@ -2551,14 +2566,17 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        return -EINVAL;
                switch (btv->gbuf[i].stat) {
                case GBUFFER_UNUSED:
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       break;
                case GBUFFER_GRABBING:
                        while(btv->gbuf[i].stat==GBUFFER_GRABBING) {
                                if (debug)
                                        printk("bttv%d: cap sync: sleep on %d\n",btv->nr,i);
                                interruptible_sleep_on(&btv->capq);
-                               if(signal_pending(current))
-                                       return -EINTR;
+                               if(signal_pending(current)) {
+                                       ret = -EINTR;
+                                       break;
+                               }
                        }
                        /* fall throuth */
                case GBUFFER_DONE:
@@ -2567,9 +2585,13 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        if (debug)
                                printk("bttv%d: cap sync: buffer %d, retval %d\n",btv->nr,i,ret);
                        btv->gbuf[i].stat = GBUFFER_UNUSED;
-                       return ret;
                }
-               return 0;
+               if (btv->needs_restart) {
+                       down(&btv->lock);
+                       bt848_restart(btv);
+                       up(&btv->lock);
+               }
+               return ret;
 
        case BTTV_FIELDNR: 
                if(copy_to_user((void *) arg, (void *) &btv->last_field, 
@@ -2742,6 +2764,11 @@ static long vbi_read(struct video_device *v, char *buf, unsigned long count,
        todo=count;
        while (todo && todo>(q=VBIBUF_SIZE-btv->vbip)) 
        {
+               if (btv->needs_restart) {
+                       down(&btv->lock);
+                       bt848_restart(btv);
+                       up(&btv->lock);
+               }
                if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, q))
                        return -EFAULT;
                todo-=q;
@@ -2796,6 +2823,8 @@ static int vbi_open(struct video_device *dev, int flags)
        struct bttv *btv=(struct bttv *)(dev-2);
 
         down(&btv->lock);
+       if (btv->needs_restart)
+               bt848_restart(btv);
        btv->vbip=VBIBUF_SIZE;
        btv->vbi_on = 1;
        bt848_set_risc_jmps(btv,-1);
@@ -2938,8 +2967,8 @@ static int radio_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                if(v.tuner||btv->channel)       /* Only tuner 0 */
                        return -EINVAL;
                strcpy(v.name, "Radio");
-               v.rangelow=(int)(87.5*16);
-               v.rangehigh=(int)(108*16);
+               v.rangelow=(int)(76*16);        /* jp: 76.0MHz - 89.9MHz  */
+               v.rangehigh=(int)(108*16);      /* eu: 87.5MHz - 108.0MHz */
                v.flags= 0; /* XXX */
                v.mode = 0; /* XXX */
                if(copy_to_user(arg,&v,sizeof(v)))
@@ -3100,12 +3129,10 @@ static void idcard(int i)
        /* print which board we have found */
        printk(KERN_INFO "bttv%d: model: ",btv->nr);
 
-       sprintf(btv->video_dev.name,"BT%d",btv->id);
-        if (btv->id==848 && btv->revision==0x12) 
-                strcat(btv->video_dev.name,"A");
-        strcat(btv->video_dev.name,"(");
-        strcat(btv->video_dev.name, tvcards[btv->type].name);
-        strcat(btv->video_dev.name,")");
+       sprintf(btv->video_dev.name,"BT%d%s(%.22s)",
+               btv->id,
+               (btv->id==848 && btv->revision==0x12) ? "A" : "",
+               tvcards[btv->type].name);
        printk("%s\n",btv->video_dev.name);
 
         /* board specific initialisations */
@@ -3357,6 +3384,9 @@ static int init_bt848(int i)
        btv->vbibuf=0;
         btv->field=btv->last_field=0;
 
+       btv->errors=0;
+       btv->needs_restart=0;
+
        /* i2c */
         btv->tuner_type=-1;
         init_bttv_i2c(btv);
@@ -3458,7 +3488,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
 {
        u32 stat,astat;
        u32 dstat;
-       int count;
+       int count,i;
        struct bttv *btv;
  
        btv=(struct bttv *)dev_id;
@@ -3498,24 +3528,43 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
                         btv->field++;
                }
                if (astat&(BT848_INT_SCERR|BT848_INT_OCERR)) {
-                       printk("bttv%d: irq:%s%s risc_count=%08x\n",btv->nr,
-                              (astat&BT848_INT_SCERR) ? " SCERR" : "",
-                              (astat&BT848_INT_OCERR) ? " OCERR" : "",
-                              btread(BT848_RISC_COUNT));
-                       bt848_set_risc_jmps(btv,0);
-                       btwrite(0, BT848_SRESET);
-                       btwrite(virt_to_bus(btv->risc_jmp),
-                               BT848_RISC_STRT_ADD);
-                       bt848_set_geo(btv,0);
-                       bt848_set_risc_jmps(btv,-1);
-#if 0
-                       wake_up_interruptible(&btv->vbiq);
-                       wake_up_interruptible(&btv->capq);
-#endif
+                       if (verbose)
+                               printk("bttv%d: irq:%s%s risc_count=%08x\n",
+                                      btv->nr,
+                                      (astat&BT848_INT_SCERR) ? " SCERR" : "",
+                                      (astat&BT848_INT_OCERR) ? " OCERR" : "",
+                                      btread(BT848_RISC_COUNT));
+                       btv->errors++;
+                       if (btv->errors < BTTV_ERRORS) {
+                               btand(~15, BT848_GPIO_DMA_CTL);
+                               btwrite(virt_to_bus(btv->risc_jmp+2),
+                                       BT848_RISC_STRT_ADD);
+                               bt848_set_geo(btv,0);
+                               bt848_set_risc_jmps(btv,-1);
+                       } else {
+                               if (verbose)
+                                       printk("bttv%d: aiee: error loops\n",btv->nr);
+                               /* cancel all outstanding grab requests */
+                               btv->gq_in = 0;
+                               btv->gq_out = 0;
+                               btv->gq_grab = -1;
+                               for (i = 0; i < gbuffers; i++)
+                                       if (btv->gbuf[i].stat == GBUFFER_GRABBING)
+                                               btv->gbuf[i].stat = GBUFFER_ERROR;
+                               /* disable DMA */
+                               btv->risc_cap_odd  = 0;
+                               btv->risc_cap_even = 0;
+                               bt848_set_risc_jmps(btv,0);
+
+                               btv->needs_restart = 1;
+                               wake_up_interruptible(&btv->vbiq);
+                               wake_up_interruptible(&btv->capq);
+                       }
                }
                if (astat&BT848_INT_RISCI) 
                {
-                       IDEBUG(printk ("bttv%d: IRQ_RISCI\n", btv->nr));
+                       if (debug > 1)
+                               printk("bttv%d: IRQ_RISCI\n",btv->nr);
 
                        /* captured VBI frame */
                        if (stat&(1<<28)) 
@@ -3527,11 +3576,12 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
                        }
 
                        /* captured full frame */
-                       if (stat&(2<<28)) 
+                       if (stat&(2<<28) && btv->gq_grab != -1
                        {
                                 btv->last_field=btv->field;
                                if (debug)
                                        printk("bttv%d: cap irq: done %d\n",btv->nr,btv->gq_grab);
+                               do_gettimeofday(&btv->gbuf[btv->gq_grab].tv);
                                btv->gbuf[btv->gq_grab].stat = GBUFFER_DONE;
                                btv->gq_grab = -1;
                                if (btv->gq_in != btv->gq_out)
@@ -3662,6 +3712,11 @@ int configure_bt848(struct pci_dev *dev, int bttv_num)
         btv->id=dev->device;
         btv->irq=dev->irq;
         btv->bt848_adr=dev->resource[0].start;
+       if (!request_mem_region(pci_resource_start(dev,0),
+                               pci_resource_len(dev,0),
+                               "bttv")) {
+               return -EBUSY;
+       }
         if (btv->id >= 878)
                 btv->i2c_command = 0x83;                   
         else
@@ -3720,15 +3775,15 @@ int configure_bt848(struct pci_dev *dev, int bttv_num)
         {
                 printk(KERN_ERR "bttv%d: Bad irq number or handler\n",
                        bttv_num);
-                return -EINVAL;
+               goto fail;
         }
         if (result==-EBUSY)
         {
                 printk(KERN_ERR "bttv%d: IRQ %d busy, change your PnP config in BIOS\n",bttv_num,btv->irq);
-                return result;
+               goto fail;
         }
         if (result < 0) 
-                return result;
+               goto fail;
         
         pci_set_master(dev);
 
@@ -3744,11 +3799,16 @@ int configure_bt848(struct pci_dev *dev, int bttv_num)
                 if (!(command&BT878_EN_TBFX)) 
                 {
                         printk("bttv: 430FX compatibility could not be enabled\n");
-                        return -1;
+                       result = -1;
+                       goto fail;
                 }
         }
-        
         return 0;
+       
+ fail:
+       release_mem_region(pci_resource_start(btv->dev,0),
+                          pci_resource_len(btv->dev,0));
+       return result;
 }
 
 static int find_bt848(void)
@@ -3834,6 +3894,8 @@ static void release_bttv(void)
                if (radio[btv->nr] && btv->radio_dev.minor != -1)
                        video_unregister_device(&btv->radio_dev);
 
+               release_mem_region(pci_resource_start(btv->dev,0),
+                                  pci_resource_len(btv->dev,0));
                        /* wake up any waiting processes
                   because shutdown flag is set, no new processes (in this queue) 
                   are expected
index 3a2cd7e21eefb6929df608e2155ee65f1537cc62..c1e9b3e9ab3f2eda898689b21e9f3a69034d21b9 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef _BTTV_H_
 #define _BTTV_H_
 
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,22
+#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,24
 
 #include <linux/types.h>
 #include <linux/wait.h>
@@ -112,7 +112,8 @@ struct bttv_gbuf {
 #define GBUFFER_GRABBING     1
 #define GBUFFER_DONE         2
 #define GBUFFER_ERROR        3
-
+       struct timeval tv;
+       
        u16 width;
        u16 height;
        u16 fmt;
@@ -122,8 +123,7 @@ struct bttv_gbuf {
        unsigned long re;
 };
 
-struct bttv
-{
+struct bttv {
        struct video_device video_dev;
        struct video_device radio_dev;
        struct video_device vbi_dev;
@@ -193,6 +193,9 @@ struct bttv
        int i2c_command;
        int triton1;
 
+       int errors;
+       int needs_restart;
+
        WAIT_QUEUE gpioq;
        int shutdown;
 };
index 2c512ccbf47cce83daad699e3d172d449bbb0012..073a8be67d30bad21be2ea5f5a28e3fba4d648d4 100644 (file)
@@ -4306,6 +4306,9 @@ static void __init probe_serial_pci(void)
 #ifdef ENABLE_SERIAL_PNP
 
 static struct pci_board pnp_devices[] __initdata = {
+       /* Motorola VoiceSURFR 56K Modem */
+       {       ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x15F0), 0, 0,
+               SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
        /* Rockwell 56K ACF II Fax+Data+Voice Modem */
        {       ISAPNP_VENDOR('A', 'K', 'Y'), ISAPNP_DEVICE(0x1021), 0, 0,
                SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
index 51468e1ef126643460f94fa223ba4fe3b40a4cc1..06bf946645abf258e97852db6cd49f1e6c131d6c 100644 (file)
@@ -1208,6 +1208,50 @@ struct pci_dev *isapnp_find_dev(struct pci_bus *card,
        return NULL;
 }
 
+static const struct isapnp_card_id *
+isapnp_match_card(const struct isapnp_card_id *ids, struct pci_bus *card)
+{
+       int idx;
+
+       while (ids->vendor || ids->device) {
+               if ((ids->vendor == ISAPNP_ANY_ID || ids->vendor == card->vendor) &&
+                   (ids->device == ISAPNP_ANY_ID || ids->device == card->device)) {
+                       for (idx = 0; idx < ISAPNP_CARD_DEVS; idx++) {
+                               if (ids->devs[idx].vendor == 0 &&
+                                   ids->devs[idx].function == 0)
+                                       return ids;
+                               if (isapnp_find_dev(card,
+                                                   ids->devs[idx].vendor,
+                                                   ids->devs[idx].function,
+                                                   NULL) == NULL)
+                                       goto __next;
+                       }
+                       return ids;
+               }
+             __next:
+               ids++;
+       }
+       return NULL;
+}
+
+int isapnp_probe_cards(const struct isapnp_card_id *ids,
+                      int (*probe)(struct pci_bus *_card,
+                                   const struct isapnp_card_id *_id))
+{
+       struct pci_bus *card;   
+       const struct isapnp_card_id *id;
+       int count = 0;
+
+       if (ids == NULL || probe == NULL)
+               return -EINVAL;
+       isapnp_for_each_card(card) {
+               id = isapnp_match_card(ids, card);
+               if (id != NULL && probe(card, id) >= 0)
+                       count++;
+       }
+       return count;
+}
+
 static unsigned int isapnp_dma_resource_flags(struct isapnp_dma *dma)
 {
        return dma->flags | IORESOURCE_DMA | IORESOURCE_AUTO;
@@ -2065,6 +2109,8 @@ static void __init isapnp_pci_init(void)
 
 #endif /* CONFIG_PCI */
 
+EXPORT_SYMBOL(isapnp_cards);
+EXPORT_SYMBOL(isapnp_devices);
 EXPORT_SYMBOL(isapnp_present);
 EXPORT_SYMBOL(isapnp_cfg_begin);
 EXPORT_SYMBOL(isapnp_cfg_end);
@@ -2080,6 +2126,7 @@ EXPORT_SYMBOL(isapnp_activate);
 EXPORT_SYMBOL(isapnp_deactivate);
 EXPORT_SYMBOL(isapnp_find_card);
 EXPORT_SYMBOL(isapnp_find_dev);
+EXPORT_SYMBOL(isapnp_probe_cards);
 EXPORT_SYMBOL(isapnp_resource_change);
 
 int __init isapnp_init(void)
index 9e2f14548ab808c129a9f2e28d6394d6693e8f89..eb3c22cf0c1c0a043eb181552bb93fe5c256c040 100644 (file)
@@ -4186,7 +4186,7 @@ STATIC void         asc_prt_hex(char *f, uchar *, int);
 #endif /* ADVANSYS_DEBUG */
 
 #ifdef ADVANSYS_ASSERT
-STATIC int             interrupts_enabled(void);
+STATIC int             advansys_interrupts_enabled(void);
 #endif /* ADVANSYS_ASSERT */
 
 
@@ -7053,7 +7053,7 @@ asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
     Scsi_Device        *device;
     int                ret;
 
-    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
+    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %lx, done %lx\n",
         (ulong) scp, (ulong) scp->scsi_done);
 
@@ -7182,7 +7182,7 @@ asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
     }
 
     ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
-    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
+    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     return ret;
 }
 
@@ -7602,7 +7602,7 @@ asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
     struct Scsi_Host    *shp;
     int                 i;
 
-    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
+    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp %lx, qdonep %lx\n",
         (ulong) asc_dvc_varp, (ulong) qdonep);
     ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
@@ -7773,7 +7773,7 @@ adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
     struct Scsi_Host    *shp;
     int                 i;
 
-    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
+    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp %lx, scsiqp %lx\n",
         (ulong) adv_dvc_varp, (ulong) scsiqp);
     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
@@ -8422,7 +8422,7 @@ asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
 
     ASC_DBG3(3, "asc_enqueue: ascq %lx, reqp %lx, flag %d\n",
         (ulong) ascq, (ulong) reqp, flag);
-    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
+    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     ASC_ASSERT(reqp != NULL);
     ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
     tid = REQPTID(reqp);
@@ -8475,7 +8475,7 @@ asc_dequeue(asc_queue_t *ascq, int tid)
     REQP    reqp;
 
     ASC_DBG2(3, "asc_dequeue: ascq %lx, tid %d\n", (ulong) ascq, tid);
-    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
+    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
     if ((reqp = ascq->q_first[tid]) != NULL) {
         ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
@@ -8524,7 +8524,7 @@ asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
     int     i;
 
     ASC_DBG2(3, "asc_dequeue_list: ascq %lx, tid %d\n", (ulong) ascq, tid);
-    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
+    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
 
     /*
@@ -8607,7 +8607,7 @@ asc_rmqueue(asc_queue_t *ascq, REQP reqp)
 
     ASC_DBG2(3, "asc_rmqueue: ascq %lx, reqp %lx\n",
         (ulong) ascq, (ulong) reqp);
-    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
+    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     ASC_ASSERT(reqp != NULL);
 
     tid = REQPTID(reqp);
@@ -8675,7 +8675,7 @@ asc_isqueued(asc_queue_t *ascq, REQP reqp)
 
     ASC_DBG2(3, "asc_isqueued: ascq %lx, reqp %lx\n",
         (ulong) ascq, (ulong) reqp);
-    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
+    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     ASC_ASSERT(reqp != NULL);
 
     tid = REQPTID(reqp);
@@ -8705,7 +8705,7 @@ asc_execute_queue(asc_queue_t *ascq)
     int                     i;
 
     ASC_DBG1(1, "asc_execute_queue: ascq %lx\n", (ulong) ascq);
-    ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
+    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     /*
      * Execute queued commands for devices attached to
      * the current board in round-robin fashion.
@@ -10919,12 +10919,12 @@ asc_prt_hex(char *f, uchar *s, int l)
 
 #ifdef ADVANSYS_ASSERT
 /*
- * interrupts_enabled()
+ * advansys_interrupts_enabled()
  *
  * Return 1 if interrupts are enabled, otherwise return 0.
  */
 STATIC int
-interrupts_enabled(void)
+advansys_interrupts_enabled(void)
 {
     int flags;
 
index 8aaf4be8151b3fc553fc49d0e7c9760413ad19e9..b72565fb95ee65422a885d7324c73bdabb278c9e 100644 (file)
@@ -105,6 +105,7 @@ static struct hid_usage_entry hid_usage_table[] = {
     {0, 0x35, "Tap"},
     {0, 0x39, "TabletFunctionKey"},
     {0, 0x3a, "ProgramChangeKey"},
+    {0, 0x3c, "Invert"},
     {0, 0x42, "TipSwitch"},
     {0, 0x43, "SecondaryTipSwitch"},
     {0, 0x44, "BarrelSwitch"},
index c7bb34e4df1c0210bc35179cfa784f42adb54659..b8af560514de4c0aa7445abfdd71aab438578a50 100644 (file)
@@ -802,6 +802,11 @@ static void hid_configure_usage(struct hid_device *device, struct hid_field *fie
 
                                case 0x30: /* TipPressure */
 
+                                       if (!test_bit(BTN_TOUCH, input->keybit)) {
+                                               device->quirks |= HID_QUIRK_NOTOUCH;
+                                               set_bit(EV_KEY, input->evbit);
+                                               set_bit(BTN_TOUCH, input->keybit);
+                                       }
                                        usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; 
                                        usage->code = ABS_PRESSURE;
                                        clear_bit(usage->code, bit);
@@ -817,10 +822,18 @@ static void hid_configure_usage(struct hid_device *device, struct hid_field *fie
                                        }
                                        break;
 
+                               case 0x3c: /* Invert */
+
+                                       usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+                                       usage->code = BTN_TOOL_RUBBER;
+                                       clear_bit(usage->code, bit);
+                                       break;
+
                                case 0x33: /* Touch */
                                case 0x42: /* TipSwitch */
                                case 0x43: /* TipSwitch2 */
 
+                                       device->quirks &= ~HID_QUIRK_NOTOUCH;
                                        usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
                                        usage->code = BTN_TOUCH;
                                        clear_bit(usage->code, bit);
@@ -930,7 +943,7 @@ static void hid_configure_usage(struct hid_device *device, struct hid_field *fie
        }
 }
 
-static void hid_process_event(struct input_dev *input, int flags, struct hid_usage *usage, __s32 value)
+static void hid_process_event(struct input_dev *input, int *quirks, struct hid_field *field, struct hid_usage *usage, __s32 value)
 {
        hid_dump_input(usage, value);
 
@@ -941,9 +954,30 @@ static void hid_process_event(struct input_dev *input, int flags, struct hid_usa
                return;
        }
 
+       if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */
+               *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT);
+               return;
+       }
+
+       if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */
+               if (value) {
+                       input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1);
+                       return;
+               }
+               input_event(input, usage->type, usage->code, 0);
+               input_event(input, usage->type, BTN_TOOL_RUBBER, 0);
+               return;
+       }
+
+       if (usage->hid == (HID_UP_DIGITIZER | 0x0030) && (*quirks & HID_QUIRK_NOTOUCH)) { /* Pressure */
+               int a = field->logical_minimum;
+               int b = field->logical_maximum;
+               input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3));
+       }
+
        input_event(input, usage->type, usage->code, value);
 
-       if ((flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
+       if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
                input_event(input, usage->type, usage->code, 0);
 }
 
@@ -986,19 +1020,21 @@ static void hid_input_field(struct hid_device *dev, struct hid_field *field, __u
                        } else {
                                if (value[n] == field->value[n]) continue;
                        }
-                       hid_process_event(&dev->input, field->flags, &field->usage[n], value[n]);
+                       hid_process_event(&dev->input, &dev->quirks, field, &field->usage[n], value[n]);
 
                } else {
 
                        if (field->value[n] >= min && field->value[n] <= max                    /* non-NULL value */
                                && field->usage[field->value[n] - min].hid                      /* nonzero usage */
                                && search(value, field->value[n], count))
-                                       hid_process_event(&dev->input, field->flags, &field->usage[field->value[n] - min], 0);
+                                       hid_process_event(&dev->input, &dev->quirks, field,
+                                               &field->usage[field->value[n] - min], 0);
 
                        if (value[n] >= min && value[n] <= max                                  /* non-NULL value */
                                && field->usage[value[n] - min].hid                             /* nonzero usage */
                                && search(field->value, value[n], count))
-                                       hid_process_event(&dev->input, field->flags, &field->usage[value[n] - min], 1);
+                                       hid_process_event(&dev->input, &dev->quirks,
+                                               field, &field->usage[value[n] - min], 1);
                }
        }
 
@@ -1261,14 +1297,18 @@ static void hid_init_input(struct hid_device *hid)
 
 #define USB_VENDOR_ID_WACOM            0x056a
 #define USB_DEVICE_ID_WACOM_GRAPHIRE   0x0010
-#define USB_DEVICE_ID_WACOM_INTUOS     0x0021
+#define USB_DEVICE_ID_WACOM_INTUOS     0x0020
 
 struct hid_blacklist {
        __u16 idVendor;
        __u16 idProduct;
 } hid_blacklist[] = {
-       { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS },
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE },
+       { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS },
+       { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 1},
+       { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 2},
+       { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 3},
+       { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 4},
        { 0, 0 }
 };
 
index 4a4caf401bd25e83ad2b361d7497d54bf181a4bf..18e7481c2b74cc25394244ea5d8fdb7c53ac87da 100644 (file)
@@ -178,6 +178,13 @@ struct hid_item {
 #define HID_OUTPUT_REPORT      1
 #define HID_FEATURE_REPORT     2
 
+/*
+ * HID device quirks.
+ */
+
+#define HID_QUIRK_INVERT       0x01
+#define HID_QUIRK_NOTOUCH      0x02
+
 /*
  * This is the global enviroment of the parser. This information is
  * persistent for main-items. The global enviroment can be saved and
@@ -285,6 +292,7 @@ struct hid_device {                                                 /* device report descriptor */
        struct urb urb;                                                 /* USB URB structure */
        struct urb urbout;                                              /* Output URB */
        struct input_dev input;                                         /* input device structure */
+       int quirks;                                                     /* Various nasty tricks the device can pull on us */
 };
 
 #define HID_GLOBAL_STACK_SIZE 4
index 2aef212cb1972341a729635525b1f9a7126775e3..7c94c185b23ac8b785f28ab79cf56bc6a5987677 100644 (file)
@@ -58,7 +58,8 @@ static unsigned char keybdev_mac_codes[256] =
 
 #endif
 
-struct input_handler keybdev_handler;
+static struct input_handler keybdev_handler;
+static int keybdev_alt = 0;
 
 void keybdev_ledfunc(unsigned int led)
 {
@@ -93,14 +94,22 @@ void keybdev_event(struct input_handle *handle, unsigned int type, unsigned int
                handle_scancode(0x1d, down);
                handle_scancode(0x45, down);
        } else if (code >= 96) {
-               handle_scancode(0xe0, 1);
-               handle_scancode(keybdev_x86_e0s[code - 96], down);
-               if (code == 99) {
+               if (code == 99 && keybdev_alt) {
+                        handle_scancode(84, down);
+               } else {
                        handle_scancode(0xe0, 1);
-                       handle_scancode(0x37, down);
+                       handle_scancode(keybdev_x86_e0s[code - 96], down);
+                       if (code == 99) {
+                               handle_scancode(0xe0, 1);
+                               handle_scancode(0x37, down);
+                       }
                }
+       } else if (code == 84) {
+               handle_scancode(43, down);
        } else handle_scancode(code, down);
 
+       if (code == 56 || code == 100) keybdev_alt = down;
+
 #elif CONFIG_ADB_KEYBOARD
 
        if (code < 128 && keybdev_mac_codes[code]) 
@@ -152,7 +161,7 @@ static void keybdev_disconnect(struct input_handle *handle)
        kfree(handle);
 }
        
-struct input_handler keybdev_handler = {
+static struct input_handler keybdev_handler = {
        event:          keybdev_event,
        connect:        keybdev_connect,
        disconnect:     keybdev_disconnect,
index 607782829ada542a029a8b7a4aedd5e50ee81a8e..bfdc4ab3d7d71ba6e1daf9be74e986d8e95624f9 100644 (file)
@@ -95,8 +95,8 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig
                                                break;
                                        case ABS_Y:
                                                size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
-                                               list->dy += (value * CONFIG_MOUSEDEV_SCREEN_Y - list->oldy) / size;
-                                               list->oldy += list->dy * size;
+                                               list->dy -= (value * CONFIG_MOUSEDEV_SCREEN_Y - list->oldy) / size;
+                                               list->oldy -= list->dy * size;
                                                break;
                                }
                                break;
index 6effcc048cc86c77e77ab397e645b29f95b7a937..021754994259a9614d73d8a64d6890d36464f116 100644 (file)
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (03/19/2000) gkh
+ *     Fixed oops that could happen when device was removed while a program
+ *     was talking to the device.
+ *     Removed the static urbs and now all urbs are created and destroyed
+ *     dynamically.
+ *     Reworked the internal interface. Now everything is based on the 
+ *     usb_serial_port structure instead of the larger usb_serial structure.
+ *     This fixes the bug that a multiport device could not have more than
+ *     one port open at one time.
+ *
  * (03/17/2000) gkh
  *     Added config option for debugging messages.
  *     Added patch for keyspan pda from Brian Warner.
@@ -220,10 +230,9 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum);
 static void usb_serial_disconnect(struct usb_device *dev, void *ptr);
 
 static struct usb_driver usb_serial_driver = {
-       "serial",
-       usb_serial_probe,
-       usb_serial_disconnect,
-       { NULL, NULL }
+       name:           "serial",
+       probe:          usb_serial_probe,
+       disconnect:     usb_serial_disconnect,
 };
 
 static int                     serial_refcount;
@@ -233,11 +242,50 @@ static struct termios *           serial_termios_locked[SERIAL_TTY_MINORS];
 static struct usb_serial       *serial_table[SERIAL_TTY_MINORS] = {NULL, };
 
 
+static inline int serial_paranoia_check (struct usb_serial *serial, const char *function)
+{
+       if (!serial) {
+               dbg("%s - serial == NULL", function);
+               return -1;
+       }
+       if (serial->magic != USB_SERIAL_MAGIC) {
+               dbg("%s - bad magic number for serial", function);
+               return -1;
+       }
+       if (!serial->type) {
+               dbg("%s - serial->type == NULL!", function);
+               return -1;
+       }
+
+       return 0;
+}
 
-static struct usb_serial *get_serial_by_minor (int minor)
+
+static inline int port_paranoia_check (struct usb_serial_port *port, const char *function)
 {
-       dbg("get_serial_by_minor %d", minor);
+       if (!port) {
+               dbg("%s - port == NULL", function);
+               return -1;
+       }
+       if (port->magic != USB_SERIAL_PORT_MAGIC) {
+               dbg("%s - bad magic number for port", function);
+               return -1;
+       }
+       if (!port->serial) {
+               dbg("%s - port->serial == NULL", function);
+               return -1;
+       }
+       if (!port->tty) {
+               dbg("%s - port->tty == NULL", function);
+               return -1;
+       }
 
+       return 0;
+}
+
+
+static struct usb_serial *get_serial_by_minor (int minor)
+{
        return serial_table[minor];
 }
 
@@ -267,6 +315,7 @@ static struct usb_serial *get_free_serial (int num_ports, int *minor)
                        return NULL;
                }
                memset(serial, 0, sizeof(struct usb_serial));
+               serial->magic = USB_SERIAL_MAGIC;
                serial_table[i] = serial;
                *minor = i;
                dbg("minor base = %d", *minor);
@@ -337,6 +386,8 @@ static int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit)
 static int serial_open (struct tty_struct *tty, struct file * filp)
 {
        struct usb_serial *serial;
+       struct usb_serial_port *port;
+       int portNumber;
        
        dbg("serial_open");
 
@@ -346,180 +397,182 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
        /* get the serial object associated with this tty pointer */
        serial = get_serial_by_minor (MINOR(tty->device));
 
-       /* do some sanity checking that we really have a device present */
-       if (!serial) {
-               dbg("serial == NULL!");
-               return (-ENODEV);
-       }
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
-               return (-ENODEV);
+       if (serial_paranoia_check (serial, "serial_open")) {
+               return -ENODEV;
        }
 
-       /* make the tty driver remember our serial object, and us it */
-       tty->driver_data = serial;
-       serial->tty = tty;
+       /* set up our port structure */
+       portNumber = MINOR(tty->device) - serial->minor;
+       port = &serial->port[portNumber];
+       port->number = portNumber;
+       port->serial = serial;
+       port->magic = USB_SERIAL_PORT_MAGIC;
+       
+       /* make the tty driver remember our port object, and us it */
+       tty->driver_data = port;
+       port->tty = tty;
         
        /* pass on to the driver specific version of this function if it is available */
        if (serial->type->open) {
-               return (serial->type->open(tty, filp));
+               return (serial->type->open(port, filp));
        } else {
-               return (generic_serial_open(tty, filp));
+               return (generic_open(port, filp));
        }
 }
 
 
 static void serial_close(struct tty_struct *tty, struct file * filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port;       
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
 
        dbg("serial_close");
 
-       if (!serial) {
-               dbg("serial == NULL!");
+       if (port_paranoia_check (port, "serial_close")) {
                return;
        }
 
-       port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_close port %d", port);
-       
-       /* do some sanity checking that we really have a device present */
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_close")) {
                return;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not opened");
+
+       dbg("serial_close port %d", port->number);
+       
+       if (!port->active) {
+               dbg ("port not opened");
                return;
        }
 
        /* pass on to the driver specific version of this function if it is available */
        if (serial->type->close) {
-               serial->type->close(tty, filp);
+               serial->type->close(port, filp);
        } else {
-               generic_serial_close(tty, filp);
+               generic_close(port, filp);
        }
 }      
 
 
 static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
        
-       dbg("serial_write port %d, %d byte(s)", port, count);
-
-       /* do some sanity checking that we really have a device present */
-       if (!serial) {
-               dbg("serial == NULL!");
-               return (-ENODEV);
+       dbg("serial_write");
+       
+       if (port_paranoia_check (port, "serial_write")) {
+               return -ENODEV;
        }
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
-               return (-ENODEV);
+       
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_write")) {
+               return -ENODEV;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not opened");
-               return (-EINVAL);
+       
+       dbg("serial_write port %d, %d byte(s)", port->number, count);
+
+       if (!port->active) {
+               dbg ("port not opened");
+               return -EINVAL;
        }
        
        /* pass on to the driver specific version of this function if it is available */
        if (serial->type->write) {
-               return (serial->type->write(tty, from_user, buf, count));
+               return (serial->type->write(port, from_user, buf, count));
        } else {
-               return (generic_serial_write(tty, from_user, buf, count));
+               return (generic_write(port, from_user, buf, count));
        }
 }
 
 
 static int serial_write_room (struct tty_struct *tty) 
 {
-       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_write_room port %d", port);
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
        
-       /* do some sanity checking that we really have a device present */
-       if (!serial) {
-               dbg("serial == NULL!");
-               return (-ENODEV);
+       dbg("serial_write_room");
+       
+       if (port_paranoia_check (port, "serial_write")) {
+               return -ENODEV;
        }
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
-               return (-ENODEV);
+       
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_write")) {
+               return -ENODEV;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
-               return (-EINVAL);
+       
+       dbg("serial_write_room port %d", port->number);
+       
+       if (!port->active) {
+               dbg ("port not open");
+               return -EINVAL;
        }
        
        /* pass on to the driver specific version of this function if it is available */
        if (serial->type->write_room) {
-               return (serial->type->write_room(tty));
+               return (serial->type->write_room(port));
        } else {
-               return (generic_write_room(tty));
+               return (generic_write_room(port));
        }
 }
 
 
 static int serial_chars_in_buffer (struct tty_struct *tty) 
 {
-       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_chars_in_buffer port %d", port);
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
        
-       /* do some sanity checking that we really have a device present */
-       if (!serial) {
-               dbg("serial == NULL!");
-               return (-ENODEV);
+       dbg("serial_chars_in_buffer");
+       
+       if (port_paranoia_check (port, "serial_chars_in_buffer")) {
+               return -ENODEV;
        }
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
-               return (-ENODEV);
+       
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_chars_in_buffer")) {
+               return -ENODEV;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
-               return (-EINVAL);
+       
+       if (!port->active) {
+               dbg ("port not open");
+               return -EINVAL;
        }
        
        /* pass on to the driver specific version of this function if it is available */
        if (serial->type->chars_in_buffer) {
-               return (serial->type->chars_in_buffer(tty));
+               return (serial->type->chars_in_buffer(port));
        } else {
-               return (generic_chars_in_buffer(tty));
+               return (generic_chars_in_buffer(port));
        }
 }
 
 
 static void serial_throttle (struct tty_struct * tty)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_throttle port %d", port);
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
        
-       /* do some sanity checking that we really have a device present */
-       if (!serial) {
-               dbg("serial == NULL!");
+       dbg("serial_throttle");
+       
+       if (port_paranoia_check (port, "serial_throttle")) {
                return;
        }
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
+       
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_throttle")) {
                return;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
+       
+       dbg("serial_throttle port %d", port->number);
+       
+       if (!port->active) {
+               dbg ("port not open");
                return;
        }
 
        /* pass on to the driver specific version of this function */
        if (serial->type->throttle) {
-               serial->type->throttle(tty);
-       } else {
-               generic_throttle(tty);
+               serial->type->throttle(port);
        }
 
        return;
@@ -528,30 +581,30 @@ static void serial_throttle (struct tty_struct * tty)
 
 static void serial_unthrottle (struct tty_struct * tty)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_unthrottle port %d", port);
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
        
-       /* do some sanity checking that we really have a device present */
-       if (!serial) {
-               dbg("serial == NULL!");
+       dbg("serial_unthrottle");
+       
+       if (port_paranoia_check (port, "serial_unthrottle")) {
                return;
        }
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
+       
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_unthrottle")) {
                return;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
+       
+       dbg("serial_unthrottle port %d", port->number);
+       
+       if (!port->active) {
+               dbg ("port not open");
                return;
        }
 
        /* pass on to the driver specific version of this function */
        if (serial->type->unthrottle) {
-               serial->type->unthrottle(tty);
-       } else {
-               generic_unthrottle(tty);
+               serial->type->unthrottle(port);
        }
 
        return;
@@ -560,70 +613,62 @@ static void serial_unthrottle (struct tty_struct * tty)
 
 static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port;       
-
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
+       
        dbg("serial_ioctl");
-
-       if (!serial) {
-               dbg("serial == NULL!");
+       
+       if (port_paranoia_check (port, "serial_ioctl")) {
                return -ENODEV;
        }
 
-       port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_ioctl port %d", port);
-       
-       /* do some sanity checking that we really have a device present */
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_ioctl")) {
                return -ENODEV;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
+       
+       dbg("serial_ioctl port %d", port->number);
+       
+       if (!port->active) {
+               dbg ("port not open");
                return -ENODEV;
        }
 
        /* pass on to the driver specific version of this function if it is available */
        if (serial->type->ioctl) {
-               return (serial->type->ioctl(tty, file, cmd, arg));
+               return (serial->type->ioctl(port, file, cmd, arg));
        } else {
-               return (generic_ioctl (tty, file, cmd, arg));
+               return -ENOIOCTLCMD;
        }
 }
 
 
 static void serial_set_termios (struct tty_struct *tty, struct termios * old)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port;       
-
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
+       
        dbg("serial_set_termios");
-
-       if (!serial) {
-               dbg("serial == NULL!");
+       
+       if (port_paranoia_check (port, "serial_set_termios")) {
                return;
        }
 
-       port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_set_termios port %d", port);
-       
-       /* do some sanity checking that we really have a device present */
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_set_termios")) {
                return;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
+
+       dbg("serial_set_termios port %d", port->number);
+
+       if (!port->active) {
+               dbg ("port not open");
                return;
        }
 
        /* pass on to the driver specific version of this function if it is available */
        if (serial->type->set_termios) {
-               serial->type->set_termios(tty, old);
-       } else {
-               generic_set_termios (tty, old);
+               serial->type->set_termios(port, old);
        }
        
        return;
@@ -632,32 +677,31 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old)
 
 static void serial_break (struct tty_struct *tty, int break_state)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port;       
-
-       if (!serial) {
-               dbg("serial == NULL!");
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
+       
+       dbg("serial_break");
+       
+       if (port_paranoia_check (port, "serial_break")) {
                return;
        }
 
-       port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_break port %d", port);
-       
-       /* do some sanity checking that we really have a device present */
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_break")) {
                return;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
+
+       dbg("serial_break port %d", port->number);
+
+       if (!port->active) {
+               dbg ("port not open");
                return;
        }
 
        /* pass on to the driver specific version of this function if it is
            available */
        if (serial->type->break_ctl) {
-               serial->type->break_ctl(tty, break_state);
+               serial->type->break_ctl(port, break_state);
        }
 }
 
@@ -666,13 +710,9 @@ static void serial_break (struct tty_struct *tty, int break_state)
 /*****************************************************************************
  * Connect Tech's White Heat specific driver functions
  *****************************************************************************/
-static int whiteheat_serial_open (struct tty_struct *tty, struct file *filp)
+static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
-
-       dbg("whiteheat_serial_open port %d", portNumber);
+       dbg("whiteheat_open port %d", port->number);
 
        if (port->active) {
                dbg ("device already open");
@@ -681,7 +721,7 @@ static int whiteheat_serial_open (struct tty_struct *tty, struct file *filp)
        port->active = 1;
  
        /*Start reading from the device*/
-       if (usb_submit_urb(&port->read_urb))
+       if (usb_submit_urb(port->read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
        /* Need to do device specific setup here (control lines, baud rate, etc.) */
@@ -691,36 +731,30 @@ static int whiteheat_serial_open (struct tty_struct *tty, struct file *filp)
 }
 
 
-static void whiteheat_serial_close(struct tty_struct *tty, struct file * filp)
+static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
-
-       dbg("whiteheat_serial_close port %d", portNumber);
+       dbg("whiteheat_close port %d", port->number);
        
        /* Need to change the control lines here */
        /* FIXME */
        
        /* shutdown our bulk reads and writes */
-       usb_unlink_urb (&port->write_urb);
-       usb_unlink_urb (&port->read_urb);
+       usb_unlink_urb (port->write_urb);
+       usb_unlink_urb (port->read_urb);
        port->active = 0;
 }
 
 
-static void whiteheat_set_termios (struct tty_struct *tty, struct termios *old_termios)
+static void whiteheat_set_termios (struct usb_serial_port *port, struct termios *old_termios)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-       unsigned int cflag = tty->termios->c_cflag;
+       unsigned int cflag = port->tty->termios->c_cflag;
 
-       dbg("whiteheat_set_termios port %d", port);
+       dbg("whiteheat_set_termios port %d", port->number);
 
        /* check that they really want us to change something */
        if (old_termios) {
                if ((cflag == old_termios->c_cflag) &&
-                   (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
+                   (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
                        dbg("nothing to change...");
                        return;
                }
@@ -732,12 +766,9 @@ static void whiteheat_set_termios (struct tty_struct *tty, struct termios *old_t
        return;
 }
 
-static void whiteheat_throttle (struct tty_struct * tty)
+static void whiteheat_throttle (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("whiteheat_throttle port %d", port);
+       dbg("whiteheat_throttle port %d", port->number);
 
        /* Change the control signals */
        /* FIXME!!! */
@@ -746,12 +777,9 @@ static void whiteheat_throttle (struct tty_struct * tty)
 }
 
 
-static void whiteheat_unthrottle (struct tty_struct * tty)
+static void whiteheat_unthrottle (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("whiteheat_unthrottle port %d", port);
+       dbg("whiteheat_unthrottle port %d", port->number);
 
        /* Change the control signals */
        /* FIXME!!! */
@@ -837,13 +865,9 @@ static int  whiteheat_startup (struct usb_serial *serial)
 /******************************************************************************
  * Handspring Visor specific driver functions
  ******************************************************************************/
-static int visor_serial_open (struct tty_struct *tty, struct file *filp)
+static int visor_open (struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
-
-       dbg("visor_serial_open port %d", portNumber);
+       dbg("visor_open port %d", port->number);
 
        if (port->active) {
                dbg ("device already open");
@@ -853,23 +877,22 @@ static int visor_serial_open (struct tty_struct *tty, struct file *filp)
        port->active = 1;
 
        /*Start reading from the device*/
-       if (usb_submit_urb(&port->read_urb))
+       if (usb_submit_urb(port->read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
        return (0);
 }
 
-static void visor_serial_close(struct tty_struct *tty, struct file * filp)
+
+static void visor_close (struct usb_serial_port *port, struct file * filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
        unsigned char *transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
        
-       dbg("visor_serial_close port %d", portNumber);
+       dbg("visor_close port %d", port->number);
                         
        if (!transfer_buffer) {
-               err("visor_serial_close: kmalloc(%d) failed.", 0x12);
+               err("visor_close: kmalloc(%d) failed.", 0x12);
        } else {
                /* send a shutdown message to the device */
                usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_CLOSE_NOTIFICATION,
@@ -877,33 +900,27 @@ static void visor_serial_close(struct tty_struct *tty, struct file * filp)
        }
 
        /* shutdown our bulk reads and writes */
-       usb_unlink_urb (&port->write_urb);
-       usb_unlink_urb (&port->read_urb);
+       usb_unlink_urb (port->write_urb);
+       usb_unlink_urb (port->read_urb);
        port->active = 0;
 }
 
 
-static void visor_throttle (struct tty_struct * tty)
+static void visor_throttle (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("visor_throttle port %d", port);
+       dbg("visor_throttle port %d", port->number);
 
-       usb_unlink_urb (&serial->port[port].read_urb);
+       usb_unlink_urb (port->read_urb);
 
        return;
 }
 
 
-static void visor_unthrottle (struct tty_struct * tty)
+static void visor_unthrottle (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
-       int port = MINOR(tty->device) - serial->minor;
+       dbg("visor_unthrottle port %d", port->number);
 
-       dbg("visor_unthrottle port %d", port);
-
-       if (usb_unlink_urb (&serial->port[port].read_urb))
+       if (usb_unlink_urb (port->read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
        return;
@@ -988,17 +1005,15 @@ static int  visor_startup (struct usb_serial *serial)
 
 #include "ftdi_sio.h"
 
-static int  ftdi_sio_serial_open (struct tty_struct *tty, struct file *filp)
+static int  ftdi_sio_open (struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
        char buf[1]; /* Needed for the usb_control_msg I think */
 
-       dbg("ftdi_sio_serial_open port %d", portNumber);
+       dbg("ftdi_sio_open port %d", port->number);
 
        if (port->active) {
-               dbg ("device already open");
+               dbg ("port already open");
                return -EINVAL;
        }
        port->active = 1;
@@ -1069,21 +1084,19 @@ static int  ftdi_sio_serial_open (struct tty_struct *tty, struct file *filp)
        }
        
        /*Start reading from the device*/
-       if (usb_submit_urb(&port->read_urb))
+       if (usb_submit_urb(port->read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
        return (0);
 }
 
 
-static void ftdi_sio_serial_close (struct tty_struct *tty, struct file *filp)
+static void ftdi_sio_close (struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
        char buf[1];
 
-       dbg("ftdi_sio_serial_close port %d", portNumber);
+       dbg("ftdi_sio_close port %d", port->number);
        
        /* FIXME - might be able to do both simultaneously */
        if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
@@ -1104,8 +1117,8 @@ static void ftdi_sio_serial_close (struct tty_struct *tty, struct file *filp)
        /* FIXME Should I flush the device here? - not doing it for now */
 
        /* shutdown our bulk reads and writes */
-       usb_unlink_urb (&port->write_urb);
-       usb_unlink_urb (&port->read_urb);
+       usb_unlink_urb (port->write_urb);
+       usb_unlink_urb (port->read_urb);
        port->active = 0;
 }
 
@@ -1116,15 +1129,13 @@ static void ftdi_sio_serial_close (struct tty_struct *tty, struct file *filp)
    B1 0
    B2..7 length of message excluding byte 0
 */
-static int ftdi_sio_serial_write (struct tty_struct * tty, int from_user, 
-                                 const unsigned char *buf, int count)
+static int ftdi_sio_write (struct usb_serial_port *port, int from_user, 
+                          const unsigned char *buf, int count)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
        const int data_offset = 1;
 
-       dbg("ftdi_sio_serial_write port %d, %d bytes", portNumber, count);
+       dbg("ftdi_sio_serial_write port %d, %d bytes", port->number, count);
 
        if (count == 0) {
                dbg("write request of 0 bytes");
@@ -1133,9 +1144,9 @@ static int ftdi_sio_serial_write (struct tty_struct * tty, int from_user,
 
        /* only do something if we have a bulk out endpoint */
        if (serial->num_bulk_out) {
-               unsigned char *first_byte = port->write_urb.transfer_buffer;
+               unsigned char *first_byte = port->write_urb->transfer_buffer;
 
-               if (port->write_urb.status == -EINPROGRESS) {
+               if (port->write_urb->status == -EINPROGRESS) {
                        dbg ("already writing");
                        return 0;
                }
@@ -1148,16 +1159,16 @@ static int ftdi_sio_serial_write (struct tty_struct * tty, int from_user,
 
                /* Copy in the data to send */
                if (from_user) {
-                       copy_from_user(port->write_urb.transfer_buffer + data_offset , 
+                       copy_from_user(port->write_urb->transfer_buffer + data_offset , 
                                       buf, count - data_offset );
                }
                else {
-                       memcpy(port->write_urb.transfer_buffer + data_offset,
+                       memcpy(port->write_urb->transfer_buffer + data_offset,
                               buf, count - data_offset );
                }  
 
                /* Write the control byte at the front of the packet*/
-               first_byte = port->write_urb.transfer_buffer;
+               first_byte = port->write_urb->transfer_buffer;
                *first_byte = 1 | ((count-data_offset) << 2) ; 
 
 #ifdef DEBUG
@@ -1181,9 +1192,9 @@ static int ftdi_sio_serial_write (struct tty_struct * tty, int from_user,
 
 #endif
                /* send the data out the bulk port */
-               port->write_urb.transfer_buffer_length = count;
+               port->write_urb->transfer_buffer_length = count;
 
-               if (usb_submit_urb(&port->write_urb))
+               if (usb_submit_urb(port->write_urb))
                        dbg("usb_submit_urb(write bulk) failed");
 
                dbg("write returning: %d", count - data_offset);
@@ -1197,14 +1208,24 @@ static int ftdi_sio_serial_write (struct tty_struct * tty, int from_user,
 
 static void ftdi_sio_read_bulk_callback (struct urb *urb)
 { /* ftdi_sio_serial_buld_callback */
-       struct usb_serial *serial = (struct usb_serial *)urb->context;
-               struct tty_struct *tty = serial->tty; 
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial *serial;
+               struct tty_struct *tty;
                unsigned char *data = urb->transfer_buffer;
        const int data_offset = 2;
        int i;
 
        dbg("ftdi_sio_read_bulk_callback");
 
+       if (port_paranoia_check (port, "ftdi_sio_read_bulk_callback")) {
+               return;
+       }
+
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "ftdi_sio_read_bulk_callback")) {
+               return;
+       }
+       
        if (urb->status) {
                dbg("nonzero read bulk status received: %d", urb->status);
                return;
@@ -1227,6 +1248,7 @@ static void ftdi_sio_read_bulk_callback (struct urb *urb)
        
 
        if (urb->actual_length > data_offset) {
+               tty = port->tty;
                for (i = data_offset ; i < urb->actual_length ; ++i) {
                        tty_insert_flip_char(tty, data[i], 0);
                }
@@ -1241,14 +1263,14 @@ static void ftdi_sio_read_bulk_callback (struct urb *urb)
 } /* ftdi_sio_serial_read_bulk_callback */
 
 
-static void ftdi_sio_set_termios (struct tty_struct *tty, struct termios *old_termios)
+static void ftdi_sio_set_termios (struct usb_serial_port *port, struct termios *old_termios)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-       unsigned int cflag = tty->termios->c_cflag;
+       struct usb_serial *serial = port->serial;
+       unsigned int cflag = port->tty->termios->c_cflag;
        __u16 urb_value; /* Will hold the new flags */
        char buf[1]; /* Perhaps I should dynamically alloc this? */
-       dbg("ftdi_sio_set_termios port %d", port);
+       
+       dbg("ftdi_sio_set_termios port %d", port->number);
 
        /* FIXME - we should keep the old termios really */
        /* FIXME -For this cut I don't care if the line is really changing or 
@@ -1312,14 +1334,14 @@ static void ftdi_sio_set_termios (struct tty_struct *tty, struct termios *old_te
 
 
 /*FIXME - the beginnings of this implementation - not even hooked into the driver yet */
-static int ftdi_sio_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
+static int ftdi_sio_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       struct usb_serial *serial = port->serial;
        __u16 urb_value=0; /* Will hold the new flags */
        char buf[1];
        int  ret, mask;
-       dbg("ftdi_sio_ioctl port %d", port);
+       
+       dbg("ftdi_sio_ioctl port %d", port->number);
 
        /* Based on code from acm.c */
        switch (cmd) {
@@ -1408,8 +1430,9 @@ static int ftdi_sio_ioctl (struct tty_struct *tty, struct file * file, unsigned
 
 static void keyspan_pda_rx_interrupt (struct urb *urb)
 {
-       struct usb_serial *serial = (struct usb_serial *) urb->context;
-       struct tty_struct *tty = serial->tty;
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial *serial;
+               struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        int i;
 
@@ -1417,11 +1440,21 @@ static void keyspan_pda_rx_interrupt (struct urb *urb)
        if (urb->status)
                return;
        
-       /* see if the message is data or a status interrupt */
+       if (port_paranoia_check (port, "keyspan_pda_rx_interrupt")) {
+               return;
+       }
+
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "keyspan_pda_rx_interrupt")) {
+               return;
+       }
+       
+       /* see if the message is data or a status interrupt */
        switch (data[0]) {
        case 0:
                /* rest of message is rx data */
                if (urb->actual_length) {
+                       tty = serial->port[0].tty;
                        for (i = 1; i < urb->actual_length ; ++i) {
                                tty_insert_flip_char(tty, data[i], 0);
                        }
@@ -1435,6 +1468,7 @@ static void keyspan_pda_rx_interrupt (struct urb *urb)
                case 1: /* modemline change */
                        break;
                case 2: /* tx unthrottle interrupt */
+                       tty = serial->port[0].tty;
                        serial->tx_throttled = 0;
                        wake_up(&serial->write_wait); /* wake up writer */
                        wake_up(&tty->write_wait); /* them too */
@@ -1451,11 +1485,8 @@ static void keyspan_pda_rx_interrupt (struct urb *urb)
 }
 
 
-static void keyspan_pda_rx_throttle (struct tty_struct *tty)
+static void keyspan_pda_rx_throttle (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
        /* stop receiving characters. We just turn off the URB request, and
           let chars pile up in the device. If we're doing hardware
           flowcontrol, the device will signal the other end when its buffer
@@ -1463,19 +1494,16 @@ static void keyspan_pda_rx_throttle (struct tty_struct *tty)
           send an XOFF, although it might make sense to foist that off
           upon the device too. */
 
-       dbg("keyspan_pda_rx_throttle port %d", port);
-       usb_unlink_urb(&serial->port[port].read_urb);
+       dbg("keyspan_pda_rx_throttle port %d", port->number);
+       usb_unlink_urb(port->read_urb);
 }
 
 
-static void keyspan_pda_rx_unthrottle (struct tty_struct *tty)
+static void keyspan_pda_rx_unthrottle (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
        /* just restart the receive interrupt URB */
-       dbg("keyspan_pda_rx_unthrottle port %d", port);
-       if (usb_submit_urb(&serial->port[port].read_urb))
+       dbg("keyspan_pda_rx_unthrottle port %d", port->number);
+       if (usb_submit_urb(port->read_urb))
                dbg(" usb_submit_urb(read urb) failed");
        return;
 }
@@ -1516,9 +1544,9 @@ static int keyspan_pda_setbaud (struct usb_serial *serial, int baud)
 }
 
 
-static void keyspan_pda_break_ctl (struct tty_struct *tty, int break_state)
+static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
+       struct usb_serial *serial = port->serial;
        int value;
        if (break_state == -1)
                value = 1; /* start break */
@@ -1535,11 +1563,11 @@ static void keyspan_pda_break_ctl (struct tty_struct *tty, int break_state)
 }
 
 
-static void keyspan_pda_set_termios (struct tty_struct *tty,
+static void keyspan_pda_set_termios (struct usb_serial_port *port, 
                                     struct termios *old_termios)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       unsigned int cflag = tty->termios->c_cflag;
+       struct usb_serial *serial = port->serial;
+       unsigned int cflag = port->tty->termios->c_cflag;
 
        /* cflag specifies lots of stuff: number of stop bits, parity, number
           of data bits, baud. What can the device actually handle?:
@@ -1611,10 +1639,10 @@ static int keyspan_pda_set_modem_info(struct usb_serial *serial,
 }
 
 
-static int keyspan_pda_ioctl(struct tty_struct *tty, struct file *file,
+static int keyspan_pda_ioctl(struct usb_serial_port *port, struct file *file,
                             unsigned int cmd, unsigned long arg)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
+       struct usb_serial *serial = port->serial;
        int rc;
        unsigned int value;
        unsigned char status, mask;
@@ -1677,11 +1705,10 @@ static int keyspan_pda_ioctl(struct tty_struct *tty, struct file *file,
        return -ENOIOCTLCMD;
 }
 
-static int keyspan_pda_write(struct tty_struct * tty, int from_user, 
+static int keyspan_pda_write(struct usb_serial_port *port, int from_user, 
                             const unsigned char *buf, int count)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       struct usb_serial *serial = port->serial;
        int request_unthrottle = 0;
        int rc = 0;
        DECLARE_WAITQUEUE(wait, current);
@@ -1704,7 +1731,7 @@ static int keyspan_pda_write(struct tty_struct * tty, int from_user,
           the TX urb is in-flight (wait until it completes)
           the device is full (wait until it says there is room)
        */
-       while (serial->port[port].write_urb.status == -EINPROGRESS) {
+       while (port->write_urb->status == -EINPROGRESS) {
                if (0 /* file->f_flags & O_NONBLOCK */) {
                        rc = -EAGAIN;
                        goto err;
@@ -1746,8 +1773,7 @@ static int keyspan_pda_write(struct tty_struct * tty, int from_user,
        remove_wait_queue(&serial->write_wait, &wait);
        set_current_state(TASK_RUNNING);
 
-       count = (count > serial->port[port].bulk_out_size) ? 
-               serial->port[port].bulk_out_size : count;
+       count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
        if (count > serial->tx_room) {
                unsigned char room;
                /* Looks like we might overrun the Tx buffer. Ask the device
@@ -1784,17 +1810,15 @@ static int keyspan_pda_write(struct tty_struct * tty, int from_user,
        if (count) {
                /* now transfer data */
                if (from_user) {
-                       copy_from_user(serial->port[port].write_urb.transfer_buffer,
-                                      buf, count);
+                       copy_from_user(port->write_urb->transfer_buffer, buf, count);
                }
                else {
-                       memcpy (serial->port[port].write_urb.transfer_buffer, 
-                               buf, count);
+                       memcpy (port->write_urb->transfer_buffer, buf, count);
                }  
                /* send the data out the bulk port */
-               serial->port[port].write_urb.transfer_buffer_length = count;
+               port->write_urb->transfer_buffer_length = count;
                
-               if (usb_submit_urb(&serial->port[port].write_urb))
+               if (usb_submit_urb(port->write_urb))
                        dbg(" usb_submit_urb(write bulk) failed");
        }
        else {
@@ -1828,11 +1852,22 @@ static int keyspan_pda_write(struct tty_struct * tty, int from_user,
 
 static void keyspan_pda_write_bulk_callback (struct urb *urb)
 {
-       struct usb_serial *serial = (struct usb_serial *) urb->context;
-       struct tty_struct *tty = serial->tty; 
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial *serial;
+               struct tty_struct *tty;
 
+       if (port_paranoia_check (port, "keyspan_pda_rx_interrupt")) {
+               return;
+       }
+
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "keyspan_pda_rx_interrupt")) {
+               return;
+       }
+       
        wake_up_interruptible(&serial->write_wait);
 
+       tty = port->tty;
        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && 
            tty->ldisc.write_wakeup)
                (tty->ldisc.write_wakeup)(tty);
@@ -1841,9 +1876,9 @@ static void keyspan_pda_write_bulk_callback (struct urb *urb)
 }
 
 
-static int keyspan_pda_write_room (struct tty_struct *tty)
+static int keyspan_pda_write_room (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
+       struct usb_serial *serial = port->serial;
 
        /* used by n_tty.c for processing of tabs and such. Giving it our
           conservative guess is probably good enough, but needs testing by
@@ -1853,9 +1888,9 @@ static int keyspan_pda_write_room (struct tty_struct *tty)
 }
 
 
-static int keyspan_pda_chars_in_buffer (struct tty_struct *tty) 
+static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
+       struct usb_serial *serial = port->serial;
        
        /* when throttled, return at least WAKEUP_CHARS to tell select() (via
           n_tty.c:normal_poll() ) that we're not writeable. */
@@ -1865,11 +1900,9 @@ static int keyspan_pda_chars_in_buffer (struct tty_struct *tty)
 }
 
 
-static int keyspan_pda_serial_open (struct tty_struct *tty, struct file *filp)
+static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
        unsigned char room;
        int rc;
 
@@ -1901,33 +1934,30 @@ static int keyspan_pda_serial_open (struct tty_struct *tty, struct file *filp)
 
        /* the normal serial device seems to always turn on DTR and RTS here,
           so do the same */
-       if (tty->termios->c_cflag & CBAUD)
+       if (port->tty->termios->c_cflag & CBAUD)
                keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2) );
        else
                keyspan_pda_set_modem_info(serial, 0);
 
        /*Start reading from the device*/
-       if (usb_submit_urb(&port->read_urb))
+       if (usb_submit_urb(port->read_urb))
                dbg(" usb_submit_urb(read int) failed");
 
        return (0);
 }
 
 
-static void keyspan_pda_serial_close(struct tty_struct *tty, 
-                                    struct file *filp)
+static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
 
        /* the normal serial device seems to always shut off DTR and RTS now */
-       if (tty->termios->c_cflag & HUPCL)
+       if (port->tty->termios->c_cflag & HUPCL)
                keyspan_pda_set_modem_info(serial, 0);
 
        /* shutdown our bulk reads and writes */
-       usb_unlink_urb (&port->write_urb);
-       usb_unlink_urb (&port->read_urb);
+       usb_unlink_urb (port->write_urb);
+       usb_unlink_urb (port->read_urb);
        port->active = 0;
 }
 
@@ -1971,7 +2001,7 @@ static int keyspan_pda_startup (struct usb_serial *serial)
        intin = serial->port[0].interrupt_in_endpoint;
 
        /* set up the receive interrupt urb */
-       FILL_INT_URB(&serial->port[0].read_urb, serial->dev,
+       FILL_INT_URB(serial->port[0].read_urb, serial->dev,
                     usb_rcvintpipe(serial->dev, intin->bEndpointAddress),
                     serial->port[0].interrupt_in_buffer,
                     intin->wMaxPacketSize,
@@ -1990,13 +2020,11 @@ static int keyspan_pda_startup (struct usb_serial *serial)
 /*****************************************************************************
  * generic devices specific driver functions
  *****************************************************************************/
-static int generic_serial_open (struct tty_struct *tty, struct file *filp)
+static int generic_open (struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
 
-       dbg("generic_serial_open port %d", portNumber);
+       dbg("generic_open port %d", port->number);
 
        if (port->active) {
                dbg ("device already open");
@@ -2007,7 +2035,7 @@ static int generic_serial_open (struct tty_struct *tty, struct file *filp)
        /* if we have a bulk interrupt, start reading from it */
        if (serial->num_bulk_in) {
                /*Start reading from the device*/
-               if (usb_submit_urb(&port->read_urb))
+               if (usb_submit_urb(port->read_urb))
                        dbg("usb_submit_urb(read bulk) failed");
        }
 
@@ -2015,33 +2043,29 @@ static int generic_serial_open (struct tty_struct *tty, struct file *filp)
 }
 
 
-static void generic_serial_close(struct tty_struct *tty, struct file * filp)
+static void generic_close (struct usb_serial_port *port, struct file * filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
 
-       dbg("generic_serial_close port %d", portNumber);
+       dbg("generic_close port %d", port->number);
        
        /* shutdown any bulk reads that might be going on */
        if (serial->num_bulk_out) {
-               usb_unlink_urb (&port->write_urb);
+               usb_unlink_urb (port->write_urb);
        }
        if (serial->num_bulk_in) {
-               usb_unlink_urb (&port->read_urb);
+               usb_unlink_urb (port->read_urb);
        }
 
        port->active = 0;
 }
 
 
-static int generic_serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
+static int generic_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
 
-       dbg("generic_serial_write port %d", portNumber);
+       dbg("generic_serial_write port %d", port->number);
 
        if (count == 0) {
                dbg("write request of 0 bytes");
@@ -2050,7 +2074,7 @@ static int generic_serial_write (struct tty_struct * tty, int from_user, const u
 
        /* only do something if we have a bulk out endpoint */
        if (serial->num_bulk_out) {
-               if (port->write_urb.status == -EINPROGRESS) {
+               if (port->write_urb->status == -EINPROGRESS) {
                        dbg ("already writing");
                        return (0);
                }
@@ -2058,16 +2082,16 @@ static int generic_serial_write (struct tty_struct * tty, int from_user, const u
                count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
 
                if (from_user) {
-                       copy_from_user(port->write_urb.transfer_buffer, buf, count);
+                       copy_from_user(port->write_urb->transfer_buffer, buf, count);
                }
                else {
-                       memcpy (port->write_urb.transfer_buffer, buf, count);
+                       memcpy (port->write_urb->transfer_buffer, buf, count);
                }  
 
                /* send the data out the bulk port */
-               port->write_urb.transfer_buffer_length = count;
+               port->write_urb->transfer_buffer_length = count;
 
-               if (usb_submit_urb(&port->write_urb))
+               if (usb_submit_urb(port->write_urb))
                        dbg("usb_submit_urb(write bulk) failed");
 
                return (count);
@@ -2078,17 +2102,15 @@ static int generic_serial_write (struct tty_struct * tty, int from_user, const u
 } 
 
 
-static int generic_write_room (struct tty_struct *tty) 
+static int generic_write_room (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
        int room;
 
-       dbg("generic_write_room port %d", portNumber);
+       dbg("generic_write_room port %d", port->number);
        
        if (serial->num_bulk_out) {
-               if (port->write_urb.status == -EINPROGRESS)
+               if (port->write_urb->status == -EINPROGRESS)
                        room = 0;
                else
                        room = port->bulk_out_size;
@@ -2100,16 +2122,14 @@ static int generic_write_room (struct tty_struct *tty)
 }
 
 
-static int generic_chars_in_buffer (struct tty_struct *tty) 
+static int generic_chars_in_buffer (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
 
-       dbg("generic_chars_in_buffer port %d", portNumber);
+       dbg("generic_chars_in_buffer port %d", port->number);
        
        if (serial->num_bulk_out) {
-               if (port->write_urb.status == -EINPROGRESS) {
+               if (port->write_urb->status == -EINPROGRESS) {
                        return (port->bulk_out_size);
                }
        }
@@ -2118,43 +2138,25 @@ static int generic_chars_in_buffer (struct tty_struct *tty)
 }
 
 
-static void generic_throttle (struct tty_struct *tty) 
-{
-       /* do nothing for the generic device */
-       return;
-}
-
-
-static void generic_unthrottle (struct tty_struct *tty) 
-{
-       /* do nothing for the generic device */
-       return;
-}
-
-
-static int generic_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
-{
-       /* generic driver doesn't support any ioctls yet */
-       return -ENOIOCTLCMD;
-}
-
-
-static void generic_set_termios (struct tty_struct *tty, struct termios * old)
-{
-       /* generic driver doesn't really care about setting any line settings */
-       return;
-}
-
-
 static void generic_read_bulk_callback (struct urb *urb)
 {
-       struct usb_serial *serial = (struct usb_serial *)urb->context;
-               struct tty_struct *tty = serial->tty; 
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial *serial;
+               struct tty_struct *tty;
                unsigned char *data = urb->transfer_buffer;
        int i;
 
        dbg("generic_read_bulk_callback");
 
+       if (port_paranoia_check (port, "generic_read_bulk_callback")) {
+               return;
+       }
+
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "generic_read_bulk_callback")) {
+               return;
+       }
+       
        if (urb->status) {
                dbg("nonzero read bulk status received: %d", urb->status);
                return;
@@ -2169,7 +2171,8 @@ static void generic_read_bulk_callback (struct urb *urb)
                printk ("\n");
        }
 #endif
-       
+
+       tty = port->tty;
        if (urb->actual_length) {
                for (i = 0; i < urb->actual_length ; ++i) {
                         tty_insert_flip_char(tty, data[i], 0);
@@ -2187,16 +2190,27 @@ static void generic_read_bulk_callback (struct urb *urb)
 
 static void generic_write_bulk_callback (struct urb *urb)
 {
-       struct usb_serial *serial = (struct usb_serial *) urb->context; 
-               struct tty_struct *tty = serial->tty; 
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial *serial;
+               struct tty_struct *tty;
 
        dbg("generic_write_bulk_callback");
 
+       if (port_paranoia_check (port, "generic_write_bulk_callback")) {
+               return;
+       }
+
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "generic_write_bulk_callback")) {
+               return;
+       }
+       
        if (urb->status) {
                dbg("nonzero write bulk status received: %d", urb->status);
                return;
        }
 
+       tty = port->tty;
        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
                (tty->ldisc.write_wakeup)(tty);
 
@@ -2206,7 +2220,6 @@ static void generic_write_bulk_callback (struct urb *urb)
 }
 
 
-
 static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
 {
        struct usb_serial *serial = NULL;
@@ -2331,6 +2344,11 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                                /* set up the endpoint information */
                                for (i = 0; i < num_bulk_in; ++i) {
                                        port = &serial->port[i];
+                                       port->read_urb = usb_alloc_urb (0);
+                                       if (!port->read_urb) {
+                                               err("No free urbs available");
+                                               goto probe_error;
+                                       }
                                        buffer_size = bulk_in_endpoint[i]->wMaxPacketSize;
                                        port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
                                        if (!port->bulk_in_buffer) {
@@ -2338,16 +2356,21 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                                                goto probe_error;
                                        }
                                        if (serial->type->read_bulk_callback) {
-                                               FILL_BULK_URB(&port->read_urb, dev, usb_rcvbulkpipe (dev, bulk_in_endpoint[i]->bEndpointAddress),
-                                                               port->bulk_in_buffer, buffer_size, serial->type->read_bulk_callback, serial);
+                                               FILL_BULK_URB(port->read_urb, dev, usb_rcvbulkpipe (dev, bulk_in_endpoint[i]->bEndpointAddress),
+                                                               port->bulk_in_buffer, buffer_size, serial->type->read_bulk_callback, port);
                                        } else {
-                                               FILL_BULK_URB(&port->read_urb, dev, usb_rcvbulkpipe (dev, bulk_in_endpoint[i]->bEndpointAddress),
-                                                               port->bulk_in_buffer, buffer_size, generic_read_bulk_callback, serial);
+                                               FILL_BULK_URB(port->read_urb, dev, usb_rcvbulkpipe (dev, bulk_in_endpoint[i]->bEndpointAddress),
+                                                               port->bulk_in_buffer, buffer_size, generic_read_bulk_callback, port);
                                        }
                                }
 
                                for (i = 0; i < num_bulk_out; ++i) {
                                        port = &serial->port[i];
+                                       port->write_urb = usb_alloc_urb(0);
+                                       if (!port->write_urb) {
+                                               err("No free urbs available");
+                                               goto probe_error;
+                                       }
                                        port->bulk_out_size = bulk_out_endpoint[i]->wMaxPacketSize;
                                        port->bulk_out_buffer = kmalloc (port->bulk_out_size, GFP_KERNEL);
                                        if (!port->bulk_out_buffer) {
@@ -2355,25 +2378,31 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                                                goto probe_error;
                                        }
                                        if (serial->type->write_bulk_callback) {
-                                               FILL_BULK_URB(&port->write_urb, dev, usb_sndbulkpipe (dev, bulk_out_endpoint[i]->bEndpointAddress),
-                                                               port->bulk_out_buffer, port->bulk_out_size, serial->type->write_bulk_callback, serial);
+                                               FILL_BULK_URB(port->write_urb, dev, usb_sndbulkpipe (dev, bulk_out_endpoint[i]->bEndpointAddress),
+                                                               port->bulk_out_buffer, port->bulk_out_size, serial->type->write_bulk_callback, port);
                                        } else {
-                                               FILL_BULK_URB(&port->write_urb, dev, usb_sndbulkpipe (dev, bulk_out_endpoint[i]->bEndpointAddress),
-                                                               port->bulk_out_buffer, port->bulk_out_size, generic_write_bulk_callback, serial);
+                                               FILL_BULK_URB(port->write_urb, dev, usb_sndbulkpipe (dev, bulk_out_endpoint[i]->bEndpointAddress),
+                                                               port->bulk_out_buffer, port->bulk_out_size, generic_write_bulk_callback, port);
                                        }
                                }
 
 #if 0 /* use this code when WhiteHEAT is up and running */
                                for (i = 0; i < num_interrupt_in; ++i) {
+                                       port = &serial->port[i];
+                                       port->control_urb = usb_alloc_urb(0);
+                                       if (!port->control_urb) {
+                                               err("No free urbs available");
+                                               goto probe_error;
+                                       }
                                        buffer_size = interrupt_in_endpoint[i]->wMaxPacketSize;
-                                       serial->interrupt_in_buffer[i] = kmalloc (buffer_size, GFP_KERNEL);
-                                       if (!serial->interrupt_in_buffer[i]) {
+                                       port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+                                       if (!port->interrupt_in_buffer) {
                                                err("Couldn't allocate interrupt_in_buffer");
                                                goto probe_error;
                                        }
-                                       FILL_INT_URB(&serial->control_urb[i], dev, usb_rcvintpipe (dev, interrupt_in_endpoint[i]->bEndpointAddress),
-                                                       serial->interrupt_in_buffer[i], buffer_size, serial_control_irq,
-                                                       serial, interrupt_in_endpoint[i]->bInterval);
+                                       FILL_INT_URB(port->control_urb, dev, usb_rcvintpipe (dev, interrupt_in_endpoint[i]->bEndpointAddress),
+                                                       port->interrupt_in_buffer, buffer_size, serial_control_irq,
+                                                       port, interrupt_in_endpoint[i]->bInterval);
                                }
 #endif
 
@@ -2395,15 +2424,27 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
 
 probe_error:
        if (serial) {
-               for (i = 0; i < num_bulk_in; ++i)
+               for (i = 0; i < num_bulk_in; ++i) {
+                       port = &serial->port[i];
+                       if (port->read_urb)
+                               usb_free_urb (port->read_urb);
                        if (serial->port[i].bulk_in_buffer[i])
                                kfree (serial->port[i].bulk_in_buffer);
-               for (i = 0; i < num_bulk_out; ++i)
+               }
+               for (i = 0; i < num_bulk_out; ++i) {
+                       port = &serial->port[i];
+                       if (port->write_urb)
+                               usb_free_urb (port->write_urb);
                        if (serial->port[i].bulk_out_buffer)
                                kfree (serial->port[i].bulk_out_buffer);
-               for (i = 0; i < num_interrupt_in; ++i)
+               }
+               for (i = 0; i < num_interrupt_in; ++i) {
+                       port = &serial->port[i];
+                       if (port->control_urb)
+                               usb_free_urb (port->control_urb);
                        if (serial->port[i].interrupt_in_buffer)
                                kfree (serial->port[i].interrupt_in_buffer);
+               }
                
                /* return the minor range that this device had */
                return_serial (serial);
@@ -2422,27 +2463,33 @@ static void usb_serial_disconnect(struct usb_device *dev, void *ptr)
        int i;
 
        if (serial) {
-               /* need to stop any transfers...*/
-               for (i = 0; i < serial->num_ports; ++i) {
-                       port = &serial->port[i];
-                       usb_unlink_urb (&port->write_urb);
-                       usb_unlink_urb (&port->read_urb);
-                       port->active = 0;
-               }
+               for (i = 0; i < serial->num_ports; ++i)
+                       serial->port[i].active = 0;
 
-               /* free up any memory that we allocated */
                for (i = 0; i < serial->num_bulk_in; ++i) {
                        port = &serial->port[i];
+                       if (port->read_urb) {
+                               usb_unlink_urb (port->read_urb);
+                               usb_free_urb (port->read_urb);
+                       }
                        if (port->bulk_in_buffer)
                                kfree (port->bulk_in_buffer);
                }
                for (i = 0; i < serial->num_bulk_out; ++i) {
                        port = &serial->port[i];
+                       if (port->write_urb) {
+                               usb_unlink_urb (port->write_urb);
+                               usb_free_urb (port->write_urb);
+                       }
                        if (port->bulk_out_buffer)
                                kfree (port->bulk_out_buffer);
                }
                for (i = 0; i < serial->num_interrupt_in; ++i) {
                        port = &serial->port[i];
+                       if (port->control_urb) {
+                               usb_unlink_urb (port->control_urb);
+                               usb_free_urb (port->control_urb);
+                       }
                        if (port->interrupt_in_buffer)
                                kfree (port->interrupt_in_buffer);
                }
@@ -2468,7 +2515,7 @@ static void usb_serial_disconnect(struct usb_device *dev, void *ptr)
 static struct tty_driver serial_tty_driver = {
        magic:                  TTY_DRIVER_MAGIC,
        driver_name:            "usb",
-       name:                   "ttyUSB",
+       name:                   "ttyUSB%d",
        major:                  SERIAL_TTY_MAJOR,
        minor_start:            0,
        num:                    SERIAL_TTY_MINORS,
index 71fecb0ec27b8a91e7024a19f3ca3528af3befd9..48082101acbbe5c7f3ea4301ec1882c769936bcc 100644 (file)
@@ -52,8 +52,12 @@ MODULE_PARM_DESC(product, "User specified USB idProduct");
 
 #define MAX_NUM_PORTS  8       /* The maximum number of ports one device can grab at once */
 
+#define USB_SERIAL_MAGIC       0x6702  /* magic number for usb_serial struct */
+#define USB_SERIAL_PORT_MAGIC  0x7301  /* magic number for usb_serial_port struct */
+
 
 struct usb_serial_port {
+       int                     magic;
        struct usb_serial       *serial;        /* pointer back to the owner of this port */
        struct tty_struct *     tty;            /* the coresponding tty for this device */
        unsigned char           minor;
@@ -63,21 +67,21 @@ struct usb_serial_port {
        struct usb_endpoint_descriptor * interrupt_in_endpoint;
        __u8                    interrupt_in_interval;
        unsigned char *         interrupt_in_buffer;
-       struct urb              control_urb;
+       struct urb *            control_urb;
 
        unsigned char *         bulk_in_buffer;
-       struct urb              read_urb;
+       struct urb *            read_urb;
 
        unsigned char *         bulk_out_buffer;
        int                     bulk_out_size;
-       struct urb              write_urb;
+       struct urb *            write_urb;
        void *                  private;        /* data private to the specific driver */
 };
 
 struct usb_serial {
+       int                             magic;
        struct usb_device *             dev;
        struct usb_serial_device_type * type;
-       struct tty_struct *             tty;                    /* the coresponding tty for this device */
        unsigned char                   minor;
        unsigned char                   num_ports;              /* the number of ports this device has */
        char                            num_interrupt_in;       /* number of interrupt in endpoints we have */
@@ -121,16 +125,16 @@ struct usb_serial_device_type {
        int (*startup) (struct usb_serial *serial);     /* return 0 to continue initialization, anything else to abort */
        
        /* serial function calls */
-       int  (*open)(struct tty_struct * tty, struct file * filp);
-       void (*close)(struct tty_struct * tty, struct file * filp);
-       int  (*write)(struct tty_struct * tty, int from_user,const unsigned char *buf, int count);
-       int  (*write_room)(struct tty_struct *tty);
-       int  (*ioctl)(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
-       void (*set_termios)(struct tty_struct *tty, struct termios * old);
-       void (*break_ctl)(struct tty_struct *tty, int break_state);
-       int  (*chars_in_buffer)(struct tty_struct *tty);
-       void (*throttle)(struct tty_struct * tty);
-       void (*unthrottle)(struct tty_struct * tty);
+       int  (*open)            (struct usb_serial_port *port, struct file * filp);
+       void (*close)           (struct usb_serial_port *port, struct file * filp);
+       int  (*write)           (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
+       int  (*write_room)      (struct usb_serial_port *port);
+       int  (*ioctl)           (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
+       void (*set_termios)     (struct usb_serial_port *port, struct termios * old);
+       void (*break_ctl)       (struct usb_serial_port *port, int break_state);
+       int  (*chars_in_buffer) (struct usb_serial_port *port);
+       void (*throttle)        (struct usb_serial_port *port);
+       void (*unthrottle)      (struct usb_serial_port *port);
        
        void (*read_bulk_callback)(struct urb *urb);
        void (*write_bulk_callback)(struct urb *urb);
@@ -140,15 +144,11 @@ struct usb_serial_device_type {
 /* function prototypes for a "generic" type serial converter (no flow control, not all endpoints needed) */
 /* need to always compile these in, as some of the other devices use these functions as their own. */
 /* if a driver does not provide a function pointer, the generic function will be called. */
-static int  generic_serial_open                (struct tty_struct *tty, struct file *filp);
-static void generic_serial_close       (struct tty_struct *tty, struct file *filp);
-static int  generic_serial_write       (struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
-static int  generic_write_room         (struct tty_struct *tty);
-static int  generic_ioctl              (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
-static void generic_set_termios                (struct tty_struct *tty, struct termios * old);
-static int  generic_chars_in_buffer    (struct tty_struct *tty);
-static void generic_throttle           (struct tty_struct *tty);
-static void generic_unthrottle         (struct tty_struct *tty);
+static int  generic_open               (struct usb_serial_port *port, struct file *filp);
+static void generic_close              (struct usb_serial_port *port, struct file *filp);
+static int  generic_write              (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
+static int  generic_write_room         (struct usb_serial_port *port);
+static int  generic_chars_in_buffer    (struct usb_serial_port *port);
 static void generic_read_bulk_callback (struct urb *urb);
 static void generic_write_bulk_callback        (struct urb *urb);
 
@@ -172,11 +172,11 @@ static struct usb_serial_device_type generic_device = {
 
 #ifdef CONFIG_USB_SERIAL_WHITEHEAT
 /* function prototypes for the Connect Tech WhiteHEAT serial converter */
-static int  whiteheat_serial_open      (struct tty_struct *tty, struct file *filp);
-static void whiteheat_serial_close     (struct tty_struct *tty, struct file *filp);
-static void whiteheat_set_termios      (struct tty_struct *tty, struct termios * old);
-static void whiteheat_throttle         (struct tty_struct *tty);
-static void whiteheat_unthrottle       (struct tty_struct *tty);
+static int  whiteheat_open             (struct usb_serial_port *port, struct file *filp);
+static void whiteheat_close            (struct usb_serial_port *port, struct file *filp);
+static void whiteheat_set_termios      (struct usb_serial_port *port, struct termios * old);
+static void whiteheat_throttle         (struct usb_serial_port *port);
+static void whiteheat_unthrottle       (struct usb_serial_port *port);
 static int  whiteheat_startup          (struct usb_serial *serial);
 
 /* All of the device info needed for the Connect Tech WhiteHEAT */
@@ -193,6 +193,7 @@ static struct usb_serial_device_type whiteheat_fake_device = {
        num_interrupt_in:       NUM_DONT_CARE,
        num_bulk_in:            NUM_DONT_CARE,
        num_bulk_out:           NUM_DONT_CARE,
+       num_ports:              1,
        startup:                whiteheat_startup       
 };
 static struct usb_serial_device_type whiteheat_device = {
@@ -206,8 +207,8 @@ static struct usb_serial_device_type whiteheat_device = {
        num_bulk_in:            NUM_DONT_CARE,
        num_bulk_out:           NUM_DONT_CARE,
        num_ports:              4,
-       open:                   whiteheat_serial_open,
-       close:                  whiteheat_serial_close,
+       open:                   whiteheat_open,
+       close:                  whiteheat_close,
        throttle:               whiteheat_throttle,
        unthrottle:             whiteheat_unthrottle,
        set_termios:            whiteheat_set_termios,
@@ -269,11 +270,11 @@ struct visor_connection_info {
 
 
 /* function prototypes for a handspring visor */
-static int  visor_serial_open          (struct tty_struct *tty, struct file *filp);
-static void visor_serial_close         (struct tty_struct *tty, struct file *filp);
-static void visor_throttle             (struct tty_struct *tty);
-static void visor_unthrottle           (struct tty_struct *tty);
-static int  visor_startup              (struct usb_serial *serial);
+static int  visor_open         (struct usb_serial_port *port, struct file *filp);
+static void visor_close                (struct usb_serial_port *port, struct file *filp);
+static void visor_throttle     (struct usb_serial_port *port);
+static void visor_unthrottle   (struct usb_serial_port *port);
+static int  visor_startup      (struct usb_serial *serial);
 
 /* All of the device info needed for the Handspring Visor */
 static __u16   handspring_vendor_id    = HANDSPRING_VENDOR_ID;
@@ -289,8 +290,8 @@ static struct usb_serial_device_type handspring_device = {
        num_bulk_in:            2,
        num_bulk_out:           2,
        num_ports:              2,
-       open:                   visor_serial_open,
-       close:                  visor_serial_close,
+       open:                   visor_open,
+       close:                  visor_close,
        throttle:               visor_throttle,
        unthrottle:             visor_unthrottle,
        startup:                visor_startup,
@@ -300,12 +301,12 @@ static struct usb_serial_device_type handspring_device = {
 
 #ifdef CONFIG_USB_SERIAL_FTDI_SIO
 /* function prototypes for a FTDI serial converter */
-static int  ftdi_sio_serial_open       (struct tty_struct *tty, struct file *filp);
-static void ftdi_sio_serial_close      (struct tty_struct *tty, struct file *filp);
-static int  ftdi_sio_serial_write      (struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
+static int  ftdi_sio_open              (struct usb_serial_port *port, struct file *filp);
+static void ftdi_sio_close             (struct usb_serial_port *port, struct file *filp);
+static int  ftdi_sio_write             (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
 static void ftdi_sio_read_bulk_callback        (struct urb *urb);
-static void ftdi_sio_set_termios               (struct tty_struct *tty, struct termios * old);
-static int ftdi_sio_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
+static void ftdi_sio_set_termios       (struct usb_serial_port *port, struct termios * old);
+static int  ftdi_sio_ioctl             (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
 
 /* All of the device info needed for the FTDI SIO serial converter */
 static __u16   ftdi_vendor_id          = FTDI_VENDOR_ID;
@@ -321,9 +322,10 @@ static struct usb_serial_device_type ftdi_sio_device = {
        num_bulk_in:            1,
        num_bulk_out:           1,
        num_ports:              1,
-       open:                   ftdi_sio_serial_open,
-       close:                  ftdi_sio_serial_close,
-       write:                  ftdi_sio_serial_write,
+       open:                   ftdi_sio_open,
+       close:                  ftdi_sio_close,
+       write:                  ftdi_sio_write,
+       ioctl:                  ftdi_sio_ioctl,
        read_bulk_callback:     ftdi_sio_read_bulk_callback,
        set_termios:            ftdi_sio_set_termios
 };
@@ -332,28 +334,28 @@ static struct usb_serial_device_type ftdi_sio_device = {
 
 #ifdef CONFIG_USB_SERIAL_KEYSPAN_PDA
 /* function prototypes for a Keyspan PDA serial converter */
-static int  keyspan_pda_serial_open    (struct tty_struct *tty, 
+static int  keyspan_pda_open           (struct usb_serial_port *port,
                                         struct file *filp);
-static void keyspan_pda_serial_close   (struct tty_struct *tty, 
+static void keyspan_pda_close          (struct usb_serial_port *port,
                                         struct file *filp);
 static int  keyspan_pda_startup                (struct usb_serial *serial);
-static void keyspan_pda_rx_throttle    (struct tty_struct *tty);
-static void keyspan_pda_rx_unthrottle  (struct tty_struct *tty);
+static void keyspan_pda_rx_throttle    (struct usb_serial_port *port);
+static void keyspan_pda_rx_unthrottle  (struct usb_serial_port *port);
 static int  keyspan_pda_setbaud                (struct usb_serial *serial, int baud);
-static int  keyspan_pda_write_room     (struct tty_struct *tty);
-static int  keyspan_pda_write          (struct tty_struct *tty,
+static int  keyspan_pda_write_room     (struct usb_serial_port *port);
+static int  keyspan_pda_write          (struct usb_serial_port *port,
                                         int from_user,
                                         const unsigned char *buf,
                                         int count);
 static void keyspan_pda_write_bulk_callback (struct urb *urb);
-static int  keyspan_pda_chars_in_buffer (struct tty_struct *tty);
-static int  keyspan_pda_ioctl          (struct tty_struct *tty,
+static int  keyspan_pda_chars_in_buffer (struct usb_serial_port *port);
+static int  keyspan_pda_ioctl          (struct usb_serial_port *port,
                                         struct file *file,
                                         unsigned int cmd,
                                         unsigned long arg);
-static void keyspan_pda_set_termios    (struct tty_struct *tty,
+static void keyspan_pda_set_termios    (struct usb_serial_port *port,
                                         struct termios *old);
-static void keyspan_pda_break_ctl      (struct tty_struct *tty,
+static void keyspan_pda_break_ctl      (struct usb_serial_port *port,
                                         int break_state);
 static int  keyspan_pda_fake_startup   (struct usb_serial *serial);
 
@@ -385,8 +387,8 @@ static struct usb_serial_device_type keyspan_pda_device = {
        num_bulk_in:            0,
        num_bulk_out:           1,
        num_ports:              1,
-       open:                   keyspan_pda_serial_open,
-       close:                  keyspan_pda_serial_close,
+       open:                   keyspan_pda_open,
+       close:                  keyspan_pda_close,
        write:                  keyspan_pda_write,
        write_room:             keyspan_pda_write_room,
        write_bulk_callback:    keyspan_pda_write_bulk_callback,
index f5e67acec17072087596c07a0c5a4c01abed6b66..28117e4fa3ad5038f876647054083551946cca30 100644 (file)
@@ -1985,6 +1985,15 @@ static int setup_uhci(struct pci_dev *dev, int irq, unsigned int io_addr, unsign
 {
        int retval;
        struct uhci *uhci;
+       char buf[8], *bufp = buf;
+
+#ifndef __sparc__
+       sprintf(buf, "%d", irq);
+#else
+       bufp = __irq_itoa(irq);
+#endif
+       printk(KERN_INFO __FILE__ ": USB UHCI at I/O 0x%x, IRQ %s\n",
+               io_addr, bufp);
 
        uhci = alloc_uhci(io_addr, io_size);
        if (!uhci)
index 78ae0a0ea88386dfadeb4e1e7dc6135a68e147fa..08c6f6789d6239f6756294ca9a34c77cf89d9519 100644 (file)
@@ -1650,16 +1650,24 @@ static void hc_release_ohci (ohci_t * ohci)
 static int hc_found_ohci (struct pci_dev *dev, int irq, void * mem_base)
 {
        ohci_t * ohci;
-       dbg("USB HC found: irq= %d membase= %lx", irq, (unsigned long) mem_base);
+       char buf[8], *bufp = buf;
+
+#ifndef __sparc__
+       sprintf(buf, "%d", irq);
+#else
+       bufp = __irq_itoa(irq);
+#endif
+       printk(KERN_INFO __FILE__ ": USB OHCI at membase 0x%lx, IRQ %s\n",
+               (unsigned long) mem_base, bufp);
     
        ohci = hc_alloc_ohci (mem_base);
        if (!ohci) {
                return -ENOMEM;
        }
-       
+
        INIT_LIST_HEAD (&ohci->ohci_hcd_list);
        list_add (&ohci->ohci_hcd_list, &ohci_hcd_list);
-       
+
        hc_reset (ohci);
        writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control);
        wait_ms (10);
index 5dbde295985663655b6306e1baaa12d2112bb954..1d8240a0ac046e521940b64c7daa28637310c4e3 100644 (file)
@@ -2597,6 +2597,15 @@ _static int __init alloc_uhci (struct pci_dev *dev, int irq, unsigned int io_add
        uhci_t *s;
        struct usb_bus *bus;
        struct pm_dev *pmdev;
+       char buf[8], *bufp = buf;
+
+#ifndef __sparc__
+       sprintf(buf, "%d", irq);
+#else
+       bufp = __irq_itoa(irq);
+#endif
+       printk(KERN_INFO __FILE__ ": USB UHCI at I/O 0x%x, IRQ %s\n",
+               io_addr, bufp);
 
        s = kmalloc (sizeof (uhci_t), GFP_KERNEL);
        if (!s)
index 6dc9ab48093bb2a425625b78e50c078a428ba0f1..cb77f0717f2903f16c443603d0bb836df6e6ee6d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  wacom.c  Version 0.4
+ *  wacom.c  Version 0.5
  *
  *  Copyright (c) 2000 Vojtech Pavlik          <vojtech@suse.cz>
  *  Copyright (c) 2000 Andreas Bach Aaen       <abach@stofanet.dk>
  *      v0.1 (vp)  - Initial release
  *      v0.2 (aba) - Support for all buttons / combinations
  *      v0.3 (vp)  - Support for Intuos added
- *      v0.4 (sm)  - Support for more Intuos models, menustrip,
- *                   relative mode, proximity.
+ *     v0.4 (sm)  - Support for more Intuos models, menustrip
+ *                     relative mode, proximity.
+ *     v0.5 (vp)  - Big cleanup, nifty features removed,
+ *                     they belong in userspace
  */
 
 /*
@@ -50,16 +52,14 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 /*
  * Wacom Graphire packet:
  *
- * The input report:
- * 
  * byte 0: report ID (2)
- * byte 1: bit7        mouse/pen/rubber near
- *         bit5-6      0 - pen, 1 - rubber, 2 - mouse
- *        bit4         1 ?
- *         bit3                0 ?
- *         bit2                mouse middle button / pen button2
- *         bit1                mouse right button / pen button1
- *         bit0                mouse left button / pen tip / rubber
+ * byte 1: bit7                pointer in range
+ *        bit5-6       pointer type 0 - pen, 1 - rubber, 2 - mouse
+ *        bit4         1 ?
+ *        bit3         0 ?
+ *        bit2         mouse middle button / pen button2
+ *        bit1         mouse right button / pen button1
+ *        bit0         mouse left button / touch
  * byte 2: X low bits
  * byte 3: X high bits
  * byte 4: Y low bits
@@ -69,115 +69,58 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
  * 
  * There are also two single-byte feature reports (2 and 3).
  *
- * Resolution:
- * X: 0 - 10206
- * Y: 0 - 7422
- * 
- * (0,0) is upper left corner
- *
- * Wacom Intuos Status packet:
+ * Wacom Intuos status packet:
  *
- *  byte 0: report ID (2)
- *  byte 1: bit7       1 (Sync Byte)
- *          bit6       Pointer Near
- *          bit5       0 - first proximity report
- *          bit4       0 ?
- *          bit3       0 ?
- *          bit2       pen button2
- *          bit1       pen button1
- *          bit0       0 ?
- *  byte 2: X high bits
- *  byte 3: X low bits
- *  byte 4: Y high bits
- *  byte 5: Y low bits
- *  byte 6: bits 0-7:  pressure (bits 2-9)
- *  byte 7: bits 6-7:  pressure (bits 0-1)
- *  byte 7: bits 0-5:  X tilt  (bits 1-6)
- *  byte 8: bit    7:  X tilt  (bit  0)
- *  byte 8: bits 0-6:  Y tilt  (bits 0-6)
- *  byte 9: bits 4-7:  Proximity
+ * byte 0: report ID (2)
+ * byte 1: bit7                1 - sync bit 
+ *        bit6         pointer in range
+ *        bit5         pointer type report
+ *        bit4         0 ?
+ *        bit3         0 ?
+ *        bit2         pen button2
+ *        bit1         pen button1
+ *        bit0         0 ?
+ * byte 2: X high bits
+ * byte 3: X low bits
+ * byte 4: Y high bits
+ * byte 5: Y low bits
+ * byte 6: bits 0-7: pressure  (bits 2-9)
+ * byte 7: bits 6-7: pressure  (bits 0-1)
+ * byte 7: bits 0-5: X tilt    (bits 1-6)
+ * byte 8: bit    7: X tilt    (bit  0)
+ * byte 8: bits 0-6: Y tilt    (bits 0-6)
+ * byte 9: bits 4-7: distance
  */
 
-#define USB_VENDOR_ID_WACOM            0x056a
-#define USB_DEVICE_ID_WACOM_GRAPHIRE   0x0010
-#define USB_DEVICE_ID_WACOM_INTUOS45   0x0020 /* Guess */
-#define USB_DEVICE_ID_WACOM_INTUOS68   0x0021
-#define USB_DEVICE_ID_WACOM_INTUOS912  0x0022 /* Guess */
-#define USB_DEVICE_ID_WACOM_INTUOS1212 0x0023
-#define USB_DEVICE_ID_WACOM_INTUOS1218 0x0024 /* Guess */
-
-#define USB_TOOL_ID_WACOM_PEN          0x0022
-#define USB_TOOL_ID_WACOM_ERASER        0x00fa
-#define USB_TOOL_ID_WACOM_STROKE_PEN    0x0032
-#define USB_TOOL_ID_WACOM_INKING_PEN    0x0012
-#define USB_TOOL_ID_WACOM_AIRBRUSH      0x0112
-#define USB_TOOL_ID_WACOM_MOUSE4D       0x0094
-#define USB_TOOL_ID_WACOM_LENS_CURSOR   0x0096
-
-#define INTUOS_PEN_MODE_ABS             0x00
-#define INTUOS_PEN_MODE_REL             0x01
-#define INTUOS_PEN_MODE_QUICKPOINT      0x02
-
-#define INTUOS_PRESSURE_MODE_SOFT       0x00
-#define INTUOS_PRESSURE_MODE_MED        0x01
-#define INTUOS_PRESSURE_MODE_FIRM       0x02
-
-#define INTUOS_MENUSTRIP_Y_ZONE         1400
-#define INTUOS_MENUSTRIP_BTN_YMIN        270
-#define INTUOS_MENUSTRIP_BTN_YMAX       1070
-#define INTUOS_MENUSTRIP_F1_XMIN          40
-#define INTUOS_MENUSTRIP_F7_XMIN        8340
-#define INTUOS_MENUSTRIP_F12_XMIN      15300
-
-#define INTUOS_MENUSTRIP_BTN_WIDTH      1300
-
-#define INTUOS_MENUSTRIP_F7_IX_OFFSET      6 /* offset into wacom_fkeys */
-#define INTUOS_MENUSTRIP_F12_IX_OFFSET    11
+#define USB_VENDOR_ID_WACOM    0x056a
+
+struct wacom_features {
+       char *name;
+       int idProduct;
+       int pktlen;
+       int x_max;
+       int y_max;
+       int pressure_max;
+       int distance_max;
+       void (*irq)(struct urb *urb);
+       unsigned long evbit;
+       unsigned long relbit;
+       unsigned long absbit;
+       unsigned long btnbit;
+       unsigned long digibit;
+};
 
 struct wacom {
-        signed char data[10];
+       signed char data[10];
        struct input_dev dev;
        struct urb irq;
-
-        int last_x, last_y;
-       unsigned int tool, device;
-       unsigned int ymax, menustrip_touch;
-       unsigned int pen_mode;
-       unsigned int pressure_mode;
+       struct wacom_features *features;
+       int tool;
 };
 
-static int wacom_fkeys[16] = { KEY_F1,  KEY_F2,  KEY_F3,  KEY_F4,
-                              KEY_F5,  KEY_F6,  KEY_F7,  KEY_F8,
-                              KEY_F9,  KEY_F10, KEY_F11, KEY_F12,
-                              KEY_F13, KEY_F14, KEY_F15, KEY_F16};
-
-#define INTUOS_EXTENTS_MAX_X              0x00
-#define INTUOS_EXTENTS_MAX_Y              0x01
-#define INTUOS_EXTENTS_HAS_F7             0x02
-#define INTUOS_EXTENTS_HAS_F12            0x03
-#define INTUOS_EXTENTS_PEN_MODE           0x04
-#define INTUOS_EXTENTS_HAS_QUICKPOINT     0x05
-#define INTUOS_EXTENTS_HAS_PRESSURE_MODE  0x06
-#define INTUOS_EXTENTS_PRESSURE_MODE      0x07
-
-#define WACOM_TRUE   1
-#define WACOM_FALSE  0
-
-static int intuos_extents[5][8] = {
-       { 12700, 10360, WACOM_FALSE, WACOM_FALSE,  8340, WACOM_FALSE, WACOM_FALSE,     0},  /* Intuos 4x5   */
-       { 20320, 15040,  WACOM_TRUE, WACOM_FALSE, 15300, WACOM_FALSE,  WACOM_TRUE, 18360},  /* Intuos 6x8   */
-       { 30480, 23060,  WACOM_TRUE,  WACOM_TRUE, 22280,  WACOM_TRUE,  WACOM_TRUE, 26640},  /* Intuos 9x12  */
-       { 30480, 30480,  WACOM_TRUE,  WACOM_TRUE, 22280,  WACOM_TRUE,  WACOM_TRUE, 26640},  /* Intuos 12x12 */
-       { 47720, 30480,  WACOM_TRUE,  WACOM_TRUE, 29260,  WACOM_TRUE,  WACOM_TRUE, 33620}}; /* Intuos 12x18 */
-
-static char intuos_names[5][12] = {
-       {"Intuos 4x5  "}, {"Intuos 6x8  "},
-       {"Intuos 9x12 "}, {"Intuos 12x12"},
-       {"Intuos 12x18"}};
-
 static void wacom_graphire_irq(struct urb *urb)
 {
-        struct wacom *wacom = urb->context;
+       struct wacom *wacom = urb->context;
        unsigned char *data = wacom->data;
        struct input_dev *dev = &wacom->dev;
 
@@ -186,285 +129,135 @@ static void wacom_graphire_irq(struct urb *urb)
        if (data[0] != 2)
                dbg("received unknown report #%d", data[0]);
 
-        if ( data[1] & 0x80 ) {
-               input_report_abs(dev, ABS_X, data[2] | ((__u32)data[3] << 8));
-               input_report_abs(dev, ABS_Y, 7422 - (data[4] | ((__u32)data[5] << 8)));
+       if ( data[1] & 0x80 ) {
+               input_report_abs(dev, ABS_X, data[2] | ((__u32)data[3] << 8));
+               input_report_abs(dev, ABS_Y, data[4] | ((__u32)data[5] << 8));
        }
 
        switch ((data[1] >> 5) & 3) {
 
-       case 0: /* Pen */
-               input_report_btn(dev, BTN_TOOL_PEN, data[1] & 0x80);
-               input_report_btn(dev, BTN_TOUCH, data[1] & 0x01);
-               input_report_btn(dev, BTN_STYLUS, data[1] & 0x02);
-               input_report_btn(dev, BTN_STYLUS2, data[1] & 0x04);
-               input_report_abs(dev, ABS_PRESSURE, data[6] | ((__u32)data[7] << 8));
-               break;
-
-       case 1: /* Rubber */
-               input_report_btn(dev, BTN_TOOL_RUBBER, data[1] & 0x80);
-               input_report_btn(dev, BTN_TOUCH, data[1] & 0x01);
-               input_report_btn(dev, BTN_STYLUS, data[1] & 0x02);
-               input_report_btn(dev, BTN_STYLUS2, data[1] & 0x04);
-               input_report_abs(dev, ABS_PRESSURE, data[6] | ((__u32)data[7] << 8));
-               break;
-
-       case 2: /* Mouse */
-               input_report_btn(dev, BTN_TOOL_MOUSE, data[7] > 24);
-               input_report_btn(dev, BTN_LEFT, data[1] & 0x01);
-               input_report_btn(dev, BTN_RIGHT, data[1] & 0x02);
-               input_report_btn(dev, BTN_MIDDLE, data[1] & 0x04);
-               input_report_abs(dev, ABS_DISTANCE, data[7]);
-               input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
-               break;
-       }
-}
+               case 0: /* Pen */
+                       input_report_btn(dev, BTN_TOOL_PEN, data[1] & 0x80);
+                       break;
 
-static void intuos_menustrip( unsigned int x, unsigned int y, struct wacom *wacom )
-{
-       struct input_dev *dev = &wacom->dev;
-       unsigned int local_x = x;
-       unsigned int local_y = y - ( wacom->ymax - INTUOS_MENUSTRIP_Y_ZONE );
-       unsigned int fkey_index ;
-
-       /* Ensure we are in the vertical strip for the buttons */
-       if ( (local_y > INTUOS_MENUSTRIP_BTN_YMIN) && (local_y < INTUOS_MENUSTRIP_BTN_YMAX) ) {
-
-               /* Handle Pressure Mode */
-               if ( intuos_extents[wacom->device][INTUOS_EXTENTS_HAS_PRESSURE_MODE] ) {
-                       int pressure_mode = ( (local_x - intuos_extents[wacom->device][INTUOS_EXTENTS_PRESSURE_MODE])
-                                             / INTUOS_MENUSTRIP_BTN_WIDTH );
-                       if ( ( pressure_mode >= INTUOS_PRESSURE_MODE_SOFT ) &&
-                            ( pressure_mode <= INTUOS_PRESSURE_MODE_FIRM ) ) {
-                               wacom->pressure_mode = pressure_mode;
-                               return;
-                       }
-               }
-
-               /* Handle Pen Mode */
-               {
-                       int pen_mode = ( (local_x - intuos_extents[wacom->device][INTUOS_EXTENTS_PEN_MODE])
-                                        / INTUOS_MENUSTRIP_BTN_WIDTH );
-                       if ( ( pen_mode == INTUOS_PEN_MODE_ABS ) ||
-                            ( pen_mode == INTUOS_PEN_MODE_REL ) ||
-                            ( ( pen_mode == INTUOS_PEN_MODE_QUICKPOINT ) &&
-                              ( intuos_extents[wacom->device][INTUOS_EXTENTS_HAS_QUICKPOINT] ) ) ) {
-                               wacom->pen_mode = pen_mode;
-                               return;
-                       }
-               }
-
-               /* Handle Function Keys */
-               if ( local_x > INTUOS_MENUSTRIP_F12_XMIN ) {
-                       fkey_index = INTUOS_MENUSTRIP_F12_IX_OFFSET
-                               + ( (local_x - INTUOS_MENUSTRIP_F12_XMIN) / INTUOS_MENUSTRIP_BTN_WIDTH );
-                       fkey_index = ( fkey_index > 16 ) ? 16 : fkey_index; /* Ensure in range */
-               }
-               else if ( local_x > INTUOS_MENUSTRIP_F7_XMIN ) {
-                       fkey_index = INTUOS_MENUSTRIP_F7_IX_OFFSET
-                               + ( (local_x - INTUOS_MENUSTRIP_F7_XMIN) / INTUOS_MENUSTRIP_BTN_WIDTH );
-                       fkey_index = ( fkey_index > 11 ) ? 11 : fkey_index;
-               }
-               else {
-                       fkey_index = ( (local_x - INTUOS_MENUSTRIP_F1_XMIN) / INTUOS_MENUSTRIP_BTN_WIDTH );
-                       fkey_index = ( fkey_index > 6 ) ? 6 : fkey_index;
-               }
-               input_report_key(dev, wacom_fkeys[fkey_index], 1);
-               input_report_key(dev, wacom_fkeys[fkey_index], 0);
+               case 1: /* Rubber */
+                       input_report_btn(dev, BTN_TOOL_RUBBER, data[1] & 0x80);
+                       break;
 
-               return;
+               case 2: /* Mouse */
+                       input_report_btn(dev, BTN_TOOL_MOUSE, data[7] > 24);
+                       input_report_btn(dev, BTN_LEFT, data[1] & 0x01);
+                       input_report_btn(dev, BTN_RIGHT, data[1] & 0x02);
+                       input_report_btn(dev, BTN_MIDDLE, data[1] & 0x04);
+                       input_report_abs(dev, ABS_DISTANCE, data[7]);
+                       input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
+                       return;
        }
+
+       input_report_abs(dev, ABS_PRESSURE, data[6] | ((__u32)data[7] << 8));
+
+       input_report_btn(dev, BTN_TOUCH, data[1] & 0x01);
+       input_report_btn(dev, BTN_STYLUS, data[1] & 0x02);
+       input_report_btn(dev, BTN_STYLUS2, data[1] & 0x04);
 }
-               
+
 static void wacom_intuos_irq(struct urb *urb)
 {
-        struct wacom *wacom = urb->context;
+       struct wacom *wacom = urb->context;
        unsigned char *data = wacom->data;
        struct input_dev *dev = &wacom->dev;
        unsigned int t;
-       int x, y;
 
        if (urb->status) return;
 
        if (data[0] != 2)
                dbg("received unknown report #%d", data[0]);
 
-       if ( ((data[1] >> 5) & 0x3) == 0x2 ) /* First record, feature report */
-               {
-                       wacom->tool = (((char)data[2] << 4) | (char)data[3] >> 4) & 0xff ;
-                       /* Report tool type */
-                       switch ( wacom->tool )  {
-                       case USB_TOOL_ID_WACOM_PEN: 
-                               input_report_btn(dev, BTN_TOOL_PEN, 1);
-                               break;
-                       case USB_TOOL_ID_WACOM_ERASER: 
-                               input_report_btn(dev, BTN_TOOL_RUBBER, 1);
-                               break;
-                       case USB_TOOL_ID_WACOM_STROKE_PEN: 
-                               input_report_btn(dev, BTN_TOOL_BRUSH, 1);
-                               break;
-                       case USB_TOOL_ID_WACOM_INKING_PEN: 
-                               input_report_btn(dev, BTN_TOOL_PENCIL, 1);
-                               break;
-                       case USB_TOOL_ID_WACOM_AIRBRUSH: 
-                               input_report_btn(dev, BTN_TOOL_AIRBRUSH, 1);
-                               break;
-                       case USB_TOOL_ID_WACOM_MOUSE4D: 
-                       case USB_TOOL_ID_WACOM_LENS_CURSOR: 
-                               input_report_btn(dev, BTN_TOOL_MOUSE, 1);
-                               break;
-                       default:
-                               break;
-                       }                       
-                       return;
-               }
-
-       if ( ( data[1] | data[2] | data[3] | data[4] | data[5] | data[6]
-              | data[7] | data[8] | data[9] ) == 0x80 ) { /* exit report */
-               switch ( wacom->tool ) {
-               case USB_TOOL_ID_WACOM_PEN: 
-                       input_report_btn(dev, BTN_TOOL_PEN, 0);
-                       break;
-               case USB_TOOL_ID_WACOM_ERASER: 
-                       input_report_btn(dev, BTN_TOOL_RUBBER, 0);
-                       break;
-               case USB_TOOL_ID_WACOM_STROKE_PEN: 
-                       input_report_btn(dev, BTN_TOOL_BRUSH, 0);
-                       break;
-               case USB_TOOL_ID_WACOM_INKING_PEN: 
-                       input_report_btn(dev, BTN_TOOL_PENCIL, 0);
-                       break;
-               case USB_TOOL_ID_WACOM_AIRBRUSH: 
-                       input_report_btn(dev, BTN_TOOL_AIRBRUSH, 0);
-                       break;
-               case USB_TOOL_ID_WACOM_MOUSE4D: 
-               case USB_TOOL_ID_WACOM_LENS_CURSOR: 
-                       input_report_btn(dev, BTN_TOOL_MOUSE, 0);
-                       break;
-               default:
-                       break;
+       if (((data[1] >> 5) & 0x3) == 0x2) {                            /* Enter report */
+
+               switch (((__u32)data[2] << 4) | (data[3] >> 4)) {
+                       case 0x012: wacom->tool = BTN_TOOL_PENCIL;      break;  /* Inking pen */
+                       case 0x022: wacom->tool = BTN_TOOL_PEN;         break;  /* Pen */
+                       case 0x032: wacom->tool = BTN_TOOL_BRUSH;       break;  /* Stroke pen */
+                       case 0x094: wacom->tool = BTN_TOOL_MOUSE;       break;  /* Mouse 4D */
+                       case 0x096: wacom->tool = BTN_TOOL_LENS;        break;  /* Lens cursor */
+                       case 0x0fa: wacom->tool = BTN_TOOL_RUBBER;      break;  /* Eraser */
+                       case 0x112: wacom->tool = BTN_TOOL_AIRBRUSH;    break;  /* Airbrush */
+                       default:    wacom->tool = BTN_TOOL_PEN;         break;  /* Unknown tool */
                }                       
+               input_report_btn(dev, wacom->tool, 1);
                return;
        }
 
-       x = (((unsigned int) data[2]) << 8) | data[3] ;
-       y = wacom->dev.absmax[ABS_Y] - ((((unsigned int) data[4]) << 8) | data[5]);
-
-       t = (((unsigned int) data[6]) << 2) | ((data[7] & 0xC0) >> 6);
-
-       /* Handle touch near menustrip */
-       if ( y > ( wacom->dev.absmax[ABS_Y] - INTUOS_MENUSTRIP_Y_ZONE ) ) {
-               if ( t > 10 ) /* Touch */
-                       wacom->menustrip_touch = 1;
-               if ( (wacom->menustrip_touch) && (t <= 10) ) { /* Pen Up */
-                       intuos_menustrip( x, y, wacom );
-                       wacom->menustrip_touch = 0;
-               }
+       if ((data[1] | data[2] | data[3] | data[4] | data[5] |
+            data[6] | data[7] | data[8] | data[9]) == 0x80) {          /* Exit report */
+               input_report_btn(dev, wacom->tool, 0);
                return;
        }
-       else
-               wacom->menustrip_touch = 0;
-
-       switch ( wacom->pen_mode ) {
-       case INTUOS_PEN_MODE_ABS:
-               input_report_abs(dev, ABS_X, x);
-               input_report_abs(dev, ABS_Y, y);
-               break;
-       case INTUOS_PEN_MODE_REL:
-               input_report_rel(dev, REL_X, ( x - wacom->last_x) / 8 );
-               input_report_rel(dev, REL_Y, - ( y - wacom->last_y) / 8 );
-               break;
-       default: break;
-       }
-
-       wacom->last_x = x;
-       wacom->last_y = y;
 
-       input_report_btn(dev, BTN_STYLUS, data[1] & 0x02);
-       input_report_btn(dev, BTN_STYLUS2, data[1] & 0x04);
-
-       input_report_btn(dev, BTN_TOUCH, t > 10);
-       input_report_abs(dev, ABS_PRESSURE, t);
-
-       input_report_abs(dev, ABS_DISTANCE, ( data[9] & 0xf0 ) >> 4 );
-
-       input_report_abs(dev, ABS_TILT_X, ((((unsigned int) data[7]) & 0x3f) << 1) | ((data[8] & 0x80) >> 7));
+       input_report_abs(dev, ABS_X, ((__u32)data[2] << 8) | data[3]);
+       input_report_abs(dev, ABS_Y, ((__u32)data[4] << 8) | data[5]);
+       input_report_abs(dev, ABS_PRESSURE, t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
+       input_report_abs(dev, ABS_DISTANCE, data[9] >> 4);
+       input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7));
        input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f);
 
+       input_report_btn(dev, BTN_STYLUS, data[1] & 2);
+       input_report_btn(dev, BTN_STYLUS2, data[1] & 4);
+       input_report_btn(dev, BTN_TOUCH, t > 10);
 }
 
+#define WACOM_INTUOS_TOOLS     (BIT(BTN_TOOL_BRUSH) | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS))
+
+struct wacom_features wacom_features[] = {
+       { "Graphire",     0x10,  8, 10206,  7422,  511, 32, wacom_graphire_irq,
+               BIT(EV_REL), 0, BIT(REL_WHEEL), BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE), 0 },
+       { "Intuos 4x5",   0x20, 10, 12700, 10360, 1023, 15, wacom_intuos_irq,
+               0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS },
+       { "Intuos 6x8",   0x21, 10, 20320, 15040, 1023, 15, wacom_intuos_irq,
+               0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS },
+       { "Intuos 9x12",  0x22, 10, 30480, 23060, 1023, 15, wacom_intuos_irq,
+               0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS },
+       { "Intuos 12x12", 0x23, 10, 30480, 30480, 1023, 15, wacom_intuos_irq,
+               0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS },
+       { "Intuos 12x18", 0x24, 10, 47720, 30480, 1023, 15, wacom_intuos_irq,
+               0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS },
+       { NULL , 0 }
+};
+
 static void *wacom_probe(struct usb_device *dev, unsigned int ifnum)
 {
        struct usb_endpoint_descriptor *endpoint;
        struct wacom *wacom;
-       char *name;
+       int i;
 
-       if (dev->descriptor.idVendor != USB_VENDOR_ID_WACOM ||
-           (dev->descriptor.idProduct != USB_DEVICE_ID_WACOM_GRAPHIRE &&
-            dev->descriptor.idProduct != USB_DEVICE_ID_WACOM_INTUOS45 &&
-            dev->descriptor.idProduct != USB_DEVICE_ID_WACOM_INTUOS68 &&
-            dev->descriptor.idProduct != USB_DEVICE_ID_WACOM_INTUOS912 &&
-            dev->descriptor.idProduct != USB_DEVICE_ID_WACOM_INTUOS1212 &&
-            dev->descriptor.idProduct != USB_DEVICE_ID_WACOM_INTUOS1218))
-               return NULL;
+       if (dev->descriptor.idVendor != USB_VENDOR_ID_WACOM) return NULL;
+       for (i = 0; wacom_features[i].idProduct && wacom_features[i].idProduct != dev->descriptor.idProduct; i++);
+       if (!wacom_features[i].idProduct) return NULL;
 
        endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
 
        if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) return NULL;
        memset(wacom, 0, sizeof(struct wacom));
 
-       if ( dev->descriptor.idProduct == USB_DEVICE_ID_WACOM_GRAPHIRE ) {
-               wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
-               wacom->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-               wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE);
-               wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
-               wacom->dev.relbit[0] |= BIT(REL_WHEEL);
-               wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE);
-
-               wacom->dev.absmax[ABS_X] = 10206;
-               wacom->dev.absmax[ABS_Y] = 7422;
-               wacom->dev.absmax[ABS_PRESSURE] = 511;
-               wacom->dev.absmax[ABS_DISTANCE] = 32;
-
-               FILL_INT_URB(&wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),
-                            wacom->data, 8, wacom_graphire_irq, wacom, endpoint->bInterval);
-
-               name = "Graphire";
-       }
-       else { /* Intuos */
-
-               wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL);
-               wacom->dev.keybit[LONG(KEY_F1)]  |= BIT(KEY_F1)  | BIT(KEY_F2)  | BIT(KEY_F3)  | BIT(KEY_F4) | BIT(KEY_F5);
-               wacom->dev.keybit[LONG(KEY_F6)]  |= BIT(KEY_F6)  | BIT(KEY_F7)  | BIT(KEY_F8);
-               wacom->dev.keybit[LONG(KEY_F9)]  |= BIT(KEY_F9)  | BIT(KEY_F10) | BIT(KEY_F11) | BIT(KEY_F12);
-               wacom->dev.keybit[LONG(KEY_F13)] |= BIT(KEY_F13) | BIT(KEY_F14) | BIT(KEY_F15) | BIT(KEY_F16);
-               wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
-               wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_BRUSH);
-               wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_MOUSE);
-               wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE);
-               wacom->dev.absbit[0] |= BIT(ABS_TILT_X) | BIT(ABS_TILT_Y);
-               wacom->dev.relbit[0] |= BIT(REL_X) | BIT(REL_Y);
-
-               wacom->dev.absmax[ABS_PRESSURE] = 1023;
-               wacom->dev.absmax[ABS_DISTANCE] = 15;
-               wacom->dev.absmax[ABS_TILT_X] = 127;
-               wacom->dev.absmax[ABS_TILT_Y] = 127;
-
-               wacom->device = dev->descriptor.idProduct - USB_DEVICE_ID_WACOM_INTUOS45;
+       wacom->features = wacom_features + i;
 
-               wacom->dev.absmax[ABS_X] = intuos_extents[wacom->device][INTUOS_EXTENTS_MAX_X];
-               wacom->dev.absmax[ABS_Y] = intuos_extents[wacom->device][INTUOS_EXTENTS_MAX_Y];
+       wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | wacom->features->evbit;
+       wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE) | wacom->features->absbit;
+       wacom->dev.relbit[0] |= wacom->features->relbit;
+       wacom->dev.keybit[LONG(BTN_LEFT)] |= wacom->features->btnbit;
+       wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) |
+               BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2) | wacom->features->digibit;
 
-               wacom->ymax = intuos_extents[wacom->device][INTUOS_EXTENTS_MAX_Y];
-               wacom->pen_mode = INTUOS_PEN_MODE_ABS;
-               wacom->pressure_mode = INTUOS_PRESSURE_MODE_SOFT;
+       wacom->dev.absmax[ABS_X] = wacom->features->x_max;
+       wacom->dev.absmax[ABS_Y] = wacom->features->y_max;
+       wacom->dev.absmax[ABS_PRESSURE] = wacom->features->pressure_max;
+       wacom->dev.absmax[ABS_DISTANCE] = wacom->features->distance_max;
+       wacom->dev.absmax[ABS_TILT_X] = 127;
+       wacom->dev.absmax[ABS_TILT_Y] = 127;
 
-               name = intuos_names[wacom->device];
-
-               FILL_INT_URB(&wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),
-                            wacom->data, 10, wacom_intuos_irq, wacom, endpoint->bInterval);
-
-       }
+       FILL_INT_URB(&wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),
+                    wacom->data, wacom->features->pktlen, wacom->features->irq, wacom, endpoint->bInterval);
 
        if (usb_submit_urb(&wacom->irq)) {
                kfree(wacom);
@@ -473,7 +266,7 @@ static void *wacom_probe(struct usb_device *dev, unsigned int ifnum)
 
        input_register_device(&wacom->dev);
 
-       printk(KERN_INFO "input%d: Wacom %s\n", wacom->dev.number, name);
+       printk(KERN_INFO "input%d: Wacom %s on usb%d\n", wacom->dev.number, wacom->features->name, dev->devnum);
 
        return wacom;
 }
index 8a5e404b19816340df5b3f66d6fac6ce7785fc52..bd8aa6b98031149375a0f69f08eb74d608c71e36 100644 (file)
@@ -258,7 +258,7 @@ static void ntfs_load_attributes(ntfs_inode* ino)
        if( !buf )
                return;
        delta=0;
-       for(offset=0;datasize;datasize-=len)
+       for(offset=0;datasize;datasize-=len,offset+=len)
        {
                ntfs_io io;
                io.fn_put=ntfs_put;
@@ -268,7 +268,7 @@ static void ntfs_load_attributes(ntfs_inode* ino)
                if(ntfs_read_attr(ino,vol->at_attribute_list,0,offset,&io)){
                        ntfs_error("error in load_attributes\n");
                }
-               delta=len;
+               delta+=len;
                parse_attributes(ino,buf,&delta);
                if(delta)
                        /* move remaining bytes to buffer start */
index d5b75700a746cc2021b327bc40ca955d22d8c124..4cc82fbf41e298dc7a5e9d66778e510f268c8f9c 100644 (file)
@@ -302,9 +302,10 @@ struct input_event {
 #define BTN_TOOL_AIRBRUSH      0x144
 #define BTN_TOOL_FINGER                0x145
 #define BTN_TOOL_MOUSE         0x146
-#define BTN_TOUCH              0x147
-#define BTN_STYLUS             0x148
-#define BTN_STYLUS2            0x149
+#define BTN_TOOL_LENS          0x147
+#define BTN_TOUCH              0x14a
+#define BTN_STYLUS             0x14b
+#define BTN_STYLUS2            0x14c
 
 #define KEY_MAX                        0x1ff
 
index 7a52a7c4d709af8f512672ac8e2a78bb7f68380c..0985c29fbfaa15ea372dd058b883ad81008ca94d 100644 (file)
@@ -128,6 +128,24 @@ struct isapnp_resources {
        struct isapnp_resources *next;  /* next resource */
 };
 
+#define ISAPNP_ANY_ID          0xffff
+#define ISAPNP_CARD_DEVS       8
+
+#define ISAPNP_CARD_ID(_va, _vb, _vc, _device) \
+               vendor: ISAPNP_VENDOR(_va, _vb, _vc), device: ISAPNP_DEVICE(_device)
+#define ISAPNP_CARD_END \
+               vendor: 0, device: 0
+#define ISAPNP_DEVICE_ID(_va, _vb, _vc, _function) \
+               { vendor: ISAPNP_VENDOR(_va, _vb, _vc), function: ISAPNP_FUNCTION(_function) }
+
+struct isapnp_card_id {
+       unsigned short vendor, device;
+       struct {
+               unsigned short vendor, function;
+       } devs[ISAPNP_CARD_DEVS];       /* logical devices */
+       unsigned long driver_data;      /* data private to the driver */
+};
+
 #if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
 
 #define __ISAPNP__
@@ -158,6 +176,9 @@ struct pci_dev *isapnp_find_dev(struct pci_bus *card,
                                unsigned short vendor,
                                unsigned short function,
                                struct pci_dev *from);
+int isapnp_probe_cards(const struct isapnp_card_id *ids,
+                      int (*probe)(struct pci_bus *card,
+                                   const struct isapnp_card_id *id));
 /* misc */
 void isapnp_resource_change(struct resource *resource,
                            unsigned long start,
@@ -196,7 +217,10 @@ extern inline struct pci_bus *isapnp_find_card(unsigned short vendor,
 extern inline struct pci_dev *isapnp_find_dev(struct pci_bus *card,
                                              unsigned short vendor,
                                              unsigned short function,
-                                      struct pci_dev *from) { return NULL; }
+                                             struct pci_dev *from) { return NULL; }
+extern inline int isapnp_probe_cards(const struct isapnp_card_id *ids,
+                                    int (*probe)(struct pci_bus *card,
+                                                 const struct isapnp_card_id *id)) { return -ENODEV; }
 extern inline void isapnp_resource_change(struct resource *resource,
                                          unsigned long start,
                                          unsigned long size) { ; }
index fc0b1aae2a48027299277b792bda28c24ff54a76..196460c6f7ff33d4104ca6fb8244909b9ac96b65 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -30,6 +30,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/shm.h>
 #include <linux/swap.h>
index 41a61e010b8c9f3c86e2c10aeddbcf54855f08e8..c507acc31452550a6e6c523a49c55a052dc1d548 100644 (file)
@@ -21,6 +21,8 @@ OX_OBJS += ip_conntrack_standalone.o
 O_OBJS += $(IP_NF_CONNTRACK_OBJ)
 else
   ifeq ($(CONFIG_IP_NF_CONNTRACK),m)
+  MI_OBJS += $(IP_NF_CONNTRACK_OBJ)
+  MIX_OBJS += ip_conntrack_standalone.o
   M_OBJS += ip_conntrack.o
   endif
 endif
@@ -37,7 +39,7 @@ ifeq ($(CONFIG_IP_NF_FTP),y)
 OX_OBJS += ip_conntrack_ftp.o
 else
   ifeq ($(CONFIG_IP_NF_FTP),m)
-  M_OBJS += ip_conntrack_ftp.o
+  MX_OBJS += ip_conntrack_ftp.o
   endif
 endif
 
@@ -129,6 +131,8 @@ O_OBJS += ip_nat_rule.o $(IP_NF_NAT_OBJ)
   endif
 else
   ifeq ($(CONFIG_IP_NF_NAT),m)
+  MI_OBJS += ip_nat_rule.o $(IP_NF_NAT_OBJ) 
+  MIX_OBJS += ip_nat_standalone.o
   M_OBJS += iptable_nat.o
     ifeq ($(CONFIG_IP_NF_FTP),m)
     M_OBJS += ip_nat_ftp.o
index 9137d13ead5e8f8d8fe388e4e572c740c3c20981..23ccf74cf18c6cf2b83aa4dd10d9c25b943a60c4 100644 (file)
@@ -1,7 +1,4 @@
 /* FTP extension for IP connection tracking. */
-#ifdef MODULE
-#define EXPORT_SYMTAB
-#endif
 #include <linux/module.h>
 #include <linux/netfilter.h>
 #include <linux/ip.h>
index ce79c3263b8d0133bc2328acbc3833d03676308d..a69be542daed4313658cab632cfe7e688049845e 100644 (file)
@@ -7,9 +7,6 @@
 /* (c) 1999 Paul `Rusty' Russell.  Licenced under the GNU General
    Public Licence. */
 
-#ifdef MODULE
-#define EXPORT_SYMTAB
-#endif
 #include <linux/types.h>
 #include <linux/ip.h>
 #include <linux/netfilter.h>
index bf278d6f97f1b83f828a2c3f93635c29ceac82bb..6031110632c7a6bbcda8b37313f57e1e612cdb1e 100644 (file)
@@ -7,9 +7,6 @@
 /* (c) 1999 Paul `Rusty' Russell.  Licenced under the GNU General
    Public Licence. */
 
-#ifdef MODULE
-#define EXPORT_SYMTAB
-#endif
 #include <linux/types.h>
 #include <linux/ip.h>
 #include <linux/netfilter.h>