bk://kernel.bkbits.net/gregkh/linux/usb-2.6 stern@rowland.harvard.edu|ChangeSet|20040602210726|57672 stern # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/06/02 23:58:29-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/core/usb.c # 2004/06/02 23:58:25-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/02 14:07:26-07:00 stern@rowland.harvard.edu # [PATCH] USB: Move usb_new_device() et al. into hub.c # # This patch moves usb_new_device(), usb_disconnect(), usb_choose_address(), # and usb_release_address() from usb.c to hub.c. As a side benefit, # choose_address() and release_address() can now become static. The other # two can't, because they have to be exported for use by HCD's when # registering/unregistering root hubs. # # Some other features of the patch: # # The usb_snddefctrl() and usb_rcvdefctrl() macros have been # removed, since only one of them was used and only in one spot. # # The comment about configuration choice needing to interact with # hub power budgeting has been moved in accordance with David's # wish. usb_new_device() checks to make sure a configuration # could be chosen and logs a warning if no choice was made. # # Following Linus's preference, the #ifdef preprocessor stuff has # been removed from around the calls the show_string routine. It # is now defined as a non-inline routine when debugging is enabled # and as an inline no-op otherwise (the compiler will optimize # away the useless tests). # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/usb.c # 2004/06/01 09:54:17-07:00 stern@rowland.harvard.edu +0 -229 # USB: Move usb_new_device() et al. into hub.c # # drivers/usb/core/hub.c # 2004/06/01 09:54:17-07:00 stern@rowland.harvard.edu +231 -3 # USB: Move usb_new_device() et al. into hub.c # # drivers/usb/core/hcd.h # 2004/06/01 09:54:17-07:00 stern@rowland.harvard.edu +0 -7 # USB: Move usb_new_device() et al. into hub.c # # ChangeSet # 2004/06/02 14:06:55-07:00 stern@rowland.harvard.edu # [PATCH] USB: Minor cleanups for hub driver # # Greg: # # This patch takes care of some small miscellaneous items in hub.c: # # Move the definition of CONFIG to the right place; # # Print the proper value for submission status in the error log; # # Remove an unused list of all hubs; # # Remove some unneeded braces; # # Kill an accidentally-resurrected comment. # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.h # 2004/06/01 09:31:11-07:00 stern@rowland.harvard.edu +0 -1 # USB: Minor cleanups for hub driver # # drivers/usb/core/hub.c # 2004/06/01 09:39:04-07:00 stern@rowland.harvard.edu +9 -25 # USB: Minor cleanups for hub driver # # ChangeSet # 2004/06/02 13:55:44-07:00 oliver@neukum.org # [PATCH] USB: fix race between disconnect and write of acm driver # # acm uses a workqueue to defer part of a write operation. # In case of disconnect this work must be waited for. # - fix race between write and disconnect # # Signed-off-by: Oliver Neukum # Signed-off-by: Vojtech Pavlik # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/cdc-acm.c # 2004/05/31 08:13:14-07:00 oliver@neukum.org +2 -0 # USB: fix race between disconnect and write of acm driver # # ChangeSet # 2004/06/02 13:49:28-07:00 oliver@neukum.org # [PATCH] USB: fix racy access to urb->status in cdc acm driver # # Hi, # # fix access to urb->status by introduction of an explicit flag # for finished data transfer. # - fix racy access to urb->status # # Signed-off-by: Oliver Neukum # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/cdc-acm.h # 2004/05/31 08:02:12-07:00 oliver@neukum.org +1 -0 # USB: fix racy access to urb->status in cdc acm driver # # drivers/usb/class/cdc-acm.c # 2004/05/31 08:02:12-07:00 oliver@neukum.org +10 -6 # USB: fix racy access to urb->status in cdc acm driver # # ChangeSet # 2004/06/02 13:38:13-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/core/message.c # 2004/06/02 13:38:09-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/02 13:37:23-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/pci_ids.h # 2004/06/02 13:37:20-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/02 13:36:24-07:00 oliver@neukum.org # [PATCH] USB: error handling of open of acm driver # # this adds error handling to the open method of the cdc acm driver. # The change set is relative to my last patch rewriting probe. # - add error handling to open method # # # Signed-off-by: Oliver Neukum # Signed-off-by: Vojtech Pavlik # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/cdc-acm.c # 2004/05/31 06:54:36-07:00 oliver@neukum.org +23 -8 # USB: error handling of open of acm driver # # ChangeSet # 2004/06/02 13:31:54-07:00 oliver@neukum.org # [PATCH] USB: proper evaluation of the union descriptor for CDC ACM # # this changes acm_probe() to using the proper union descriptor. # It contains the workaround David suggested. Please apply. # # - fix probing to use cdc union descriptor # # Signed-off-by: Oliver Neukum # Signed-off-by: Vojtech Pavlik # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/cdc-acm.c # 2004/05/30 03:56:45-07:00 oliver@neukum.org +100 -174 # USB: proper evaluation of the union descriptor for CDC ACM # # drivers/usb/class/cdc-acm.h # 2004/05/30 03:56:45-07:00 oliver@neukum.org +114 -0 # USB: proper evaluation of the union descriptor for CDC ACM # # drivers/usb/class/cdc-acm.h # 2004/05/30 03:56:45-07:00 oliver@neukum.org +0 -0 # BitKeeper file /home/greg/linux/BK/usb-2.6/drivers/usb/class/cdc-acm.h # # ChangeSet # 2004/06/02 13:25:59-07:00 david-b@pacbell.net # [PATCH] USB: usb retry cleanups # # This patch stops changing the reported fault mode in cases where retries of # GET_DESCRIPTOR fail because the device just doesn't have such a descriptor. # Plus, it stops printing messages when retrying. # # It also reduces the number of retries; the first retry seems to resolve most # of these firmware problems. # # Signed-Off-By: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/message.c # 2004/06/01 08:10:37-07:00 david-b@pacbell.net +1 -4 # USB: usb retry cleanups # # ChangeSet # 2004/06/02 13:25:08-07:00 david-b@pacbell.net # [PATCH] USB: pxa/rndis device descriptor # # This fixes a problem that all pxa2xx_udc g_ether devices # would run into. They'd give the wrong descriptors, like: # # > --------msg1- usbview ---------- # > Device Descriptor: bcdUSB: 0x0200 # > bDeviceClass: 0xFF # > bDeviceSubClass: 0x00 # > bDeviceProtocol: 0x00 # > bMaxPacketSize0: 0x10 (16) # # Windows doesn't like RNDIS-supporting devices to point # out that they're really vendor-specific. So this patch # makes sure they don't. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/ether.c # 2004/05/29 04:01:44-07:00 david-b@pacbell.net +10 -11 # USB: pxa/rndis device descriptor # # ChangeSet # 2004/06/02 13:19:56-07:00 vojtech@suse.cz # [PATCH] USB: Patch to prevent overlapping access by usb-storage and usbfs # # usb: Based on a 2.4 patch from John_Hull@Dell.com, this patch # serializes usb storage and usbfs operation, so that usbfs # cannot disturb storage by seemingly harmless control reads. # # Signed-off-by: Vojtech Pavlik # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/transport.c # 2004/05/30 09:13:33-07:00 vojtech@suse.cz +11 -0 # USB: Patch to prevent overlapping access by usb-storage and usbfs # # drivers/usb/storage/isd200.c # 2004/05/30 13:42:13-07:00 vojtech@suse.cz +4 -0 # USB: Patch to prevent overlapping access by usb-storage and usbfs # # ChangeSet # 2004/06/02 13:19:23-07:00 numlock@freesurf.ch # [PATCH] Add support for ISD-300 controller # # This patch adds support in unusual_devs.h for the ISD-300 USB controller # used in CD-ROM enclosures. # # With it, since 2.6.0 it allowed me to move gigabytes of data and worked # without a hitch. # # # Signed-off-by: Andrew Morton # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/05/25 20:32:24-07:00 numlock@freesurf.ch +6 -0 # Add support for ISD-300 controller # # ChangeSet # 2004/06/02 13:18:53-07:00 stern@rowland.harvard.edu # [PATCH] USB: Fix disconnect bug in dummy_hcd # # Greg: # # This patch fixes a bug in disconnect handling for the dummy_hcd driver. # After a disconnect the driver would still accept URBs for endpoint 0, # leading to an oops. It also improves the ad-hoc technique used by the # driver to track its gadget's struct usb_device and fixes the way # port-power changes are handled. Please apply. # # Alan Stern # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/dummy_hcd.c # 2004/05/17 10:12:20-07:00 stern@rowland.harvard.edu +11 -4 # USB: Fix disconnect bug in dummy_hcd # # ChangeSet # 2004/06/02 13:18:15-07:00 stern@rowland.harvard.edu # [PATCH] USB: unusual_devs.h update # # On Mon, 3 May 2004, zcat wrote: # # > I am trying to get my camera going as a webcam (concord EyeQ Duo in PC # > mode, not HDD mode) with the 2.6.4 kernel using the se401 driver # > (compiled in).. It logged the following message, which doesn't mean much # > to me so I have no idea if it's useful information or not; # > # > May 3 21:08:11 mrsnorris kernel: usb 1-1: new full speed USB device # > using address 2 # > May 3 21:08:16 mrsnorris kernel: usb 1-1: control timeout on ep0out # > May 3 21:08:16 mrsnorris kernel: usb-storage: This device # > (0595,4343,0100 S 00 P 00) has an unneeded Protocol entry in unusual_devs.h # > May 3 21:08:16 mrsnorris kernel: Please send a copy of this message # > to # # This fixes the "unneeded Protocol entry" message. We never solved the # control timeout problem. # # Alan Stern # # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/05/03 04:15:35-07:00 stern@rowland.harvard.edu +1 -1 # USB: unusual_devs.h update # # ChangeSet # 2004/06/01 13:57:49-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/06/01 13:57:45-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/30 00:23:52-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/05/30 00:23:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # CREDITS # 2004/05/30 00:23:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/28 17:18:45-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/pci_ids.h # 2004/05/28 17:18:42-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/28 14:16:41-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/input/hiddev.c # 2004/05/28 14:16:37-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/28 14:15:52-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/pci_ids.h # 2004/05/28 14:15:49-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/05/28 14:15:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/25 13:48:31-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/input/hiddev.c # 2004/05/25 13:48:27-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/usb.c # 2004/05/25 13:48:27-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/message.c # 2004/05/25 13:48:27-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/25 13:47:38-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/05/25 13:47:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/24 11:48:01-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/pci_ids.h # 2004/05/24 11:47:57-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/22 23:48:51-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/pci_ids.h # 2004/05/22 23:48:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/05/22 23:48:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/21 19:09:03-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # arch/ia64/defconfig # 2004/05/21 19:09:00-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/05/21 19:09:00-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/19 18:31:55-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/05/19 18:31:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/19 00:07:04-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/usb.h # 2004/05/19 00:07:01-07:00 akpm@bix.(none) +0 -0 # Auto merged # # include/linux/pci_ids.h # 2004/05/19 00:07:01-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/usb.c # 2004/05/19 00:07:01-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ppc/defconfig # 2004/05/19 00:07:01-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ppc/configs/pmac_defconfig # 2004/05/19 00:07:01-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ppc/configs/common_defconfig # 2004/05/19 00:07:01-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/18 14:54:09-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/usb.h # 2004/05/18 14:54:06-07:00 akpm@bix.(none) +0 -0 # Auto merged # # include/linux/pci_ids.h # 2004/05/18 14:54:06-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/hid-core.c # 2004/05/18 14:54:06-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/usb.c # 2004/05/18 14:54:06-07:00 akpm@bix.(none) +0 -0 # Auto merged # # CREDITS # 2004/05/18 14:54:06-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/16 01:52:25-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/pci_ids.h # 2004/05/16 01:52:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/14 21:45:47-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/pci_ids.h # 2004/05/14 21:45:43-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/14 09:41:12-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/input/hid-core.c # 2004/05/14 09:41:09-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/usb.c # 2004/05/14 09:41:09-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/message.c # 2004/05/14 09:41:09-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/12 20:32:44-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/core/inode.c # 2004/05/12 20:32:41-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/05/12 20:32:41-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/12 01:26:11-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/input/wacom.c # 2004/05/12 01:26:08-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/hid-core.c # 2004/05/12 01:26:08-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/12 01:25:17-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/pci_ids.h # 2004/05/12 01:25:14-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/parisc/configs/c3000_defconfig # 2004/05/12 01:25:14-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/05/12 01:25:14-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/05 14:52:58-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/core/message.c # 2004/05/05 14:52:55-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/05 14:52:11-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # CREDITS # 2004/05/05 14:52:08-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/04 14:13:11-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # include/linux/usb.h # 2004/05/04 14:13:08-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/01 15:23:25-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/05/01 15:23:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/30 22:06:45-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/core/inode.c # 2004/04/30 22:06:42-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/29 16:00:47-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/pci_ids.h # 2004/04/29 16:00:44-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/04/29 16:00:44-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/28 13:38:52-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/input/hid-core.c # 2004/04/28 13:38:49-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/27 19:39:13-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # include/linux/usb.h # 2004/04/27 19:39:10-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/usb.c # 2004/04/27 19:39:10-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/message.c # 2004/04/27 19:39:10-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/26 18:31:48-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # include/linux/usb.h # 2004/04/26 18:31:45-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/usb.c # 2004/04/26 18:31:45-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/25 23:06:05-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/pci_ids.h # 2004/04/25 23:06:02-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/24 23:51:05-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/core/usb.c # 2004/04/24 23:51:02-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/23 12:58:38-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # CREDITS # 2004/04/23 12:58:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/19 19:45:10-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/pci_ids.h # 2004/04/19 19:45:07-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/04/19 19:45:07-07:00 akpm@bix.(none) +0 -0 # Auto merged # # CREDITS # 2004/04/19 19:45:06-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/07 20:17:13-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/core/message.c # 2004/04/07 20:17:11-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/02 11:35:28-08:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # include/linux/pci_ids.h # 2004/04/02 11:35:25-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/01 15:16:14-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # CREDITS # 2004/04/01 15:16:11-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/31 19:24:39-08:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # include/linux/usb.h # 2004/03/31 19:24:37-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/usb.c # 2004/03/31 19:24:37-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/message.c # 2004/03/31 19:24:37-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ppc64/defconfig # 2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ppc64/configs/pSeries_defconfig # 2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ppc/defconfig # 2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ppc/configs/pmac_defconfig # 2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ppc/configs/common_defconfig # 2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/parisc/configs/c3000_defconfig # 2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/defconfig # 2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/configs/zx1_defconfig # 2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/configs/generic_defconfig # 2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/arm/configs/neponset_defconfig # 2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/30 20:18:36-08:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # arch/ppc64/defconfig # 2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ppc64/configs/pSeries_defconfig # 2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ppc/defconfig # 2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ppc/configs/pmac_defconfig # 2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ppc/configs/common_defconfig # 2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/parisc/configs/c3000_defconfig # 2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/defconfig # 2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/configs/zx1_defconfig # 2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/configs/generic_defconfig # 2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/arm/configs/neponset_defconfig # 2004/03/30 20:18:32-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/30 12:09:32-08:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # include/linux/usb.h # 2004/03/30 12:09:29-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/usb.c # 2004/03/30 12:09:29-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/message.c # 2004/03/30 12:09:29-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/29 18:05:43-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/03/29 18:05:41-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/29 13:51:58-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # CREDITS # 2004/03/29 13:51:56-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/28 12:29:41-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/core/message.c # 2004/03/28 12:29:38-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/27 02:28:18-08:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/input/wacom.c # 2004/03/27 02:28:16-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/26 12:24:49-08:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # include/linux/usb_gadget.h # 2004/03/26 12:24:46-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/usb.c # 2004/03/26 12:24:46-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/20 13:26:55-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # CREDITS # 2004/03/20 13:26:53-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/16 21:53:42-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/input/wacom.c # 2004/03/16 21:53:39-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/hid-core.c # 2004/03/16 21:53:39-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/16 12:59:58-08:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # include/linux/usb_gadget.h # 2004/03/16 12:59:47-08:00 akpm@bix.(none) +0 -0 # Auto merged # # include/linux/usb.h # 2004/03/16 12:59:47-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/usb.c # 2004/03/16 12:59:46-08:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/03/16 12:59:46-08:00 akpm@bix.(none) +0 -0 # Auto merged # # CREDITS # 2004/03/16 12:59:46-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/16 12:58:57-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/input/wacom.c # 2004/03/16 12:58:47-08:00 akpm@bix.(none) +0 -4 # Auto merged # # drivers/usb/input/hid-core.c # 2004/03/16 12:58:47-08:00 akpm@bix.(none) +0 -0 # Auto merged # # CREDITS # 2004/03/16 12:58:46-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/14 11:03:00-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/usb_gadget.h # 2004/03/14 11:02:47-08:00 akpm@bix.(none) +0 -0 # Auto merged # # include/linux/usb.h # 2004/03/14 11:02:47-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/usb.c # 2004/03/14 11:02:47-08:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/03/14 11:02:47-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/12 10:57:17-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/03/12 10:57:02-08:00 akpm@bix.(none) +0 -0 # Auto merged # # CREDITS # 2004/03/12 10:57:01-08:00 akpm@bix.(none) +0 -0 # Auto merged # diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c --- a/drivers/usb/class/cdc-acm.c 2004-06-02 23:59:13 -07:00 +++ b/drivers/usb/class/cdc-acm.c 2004-06-02 23:59:13 -07:00 @@ -27,6 +27,7 @@ * v0.22 - probe only the control interface. if usbcore doesn't choose the * config we want, sysadmin changes bConfigurationValue in sysfs. * v0.23 - use softirq for rx processing, as needed by tty layer + * v0.24 - change probe method to evaluate CDC union descriptor */ /* @@ -60,6 +61,8 @@ #include #include +#include "cdc-acm.h" + /* * Version Information */ @@ -67,102 +70,12 @@ #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik" #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" -/* - * CMSPAR, some architectures can't have space and mark parity. - */ - -#ifndef CMSPAR -#define CMSPAR 0 -#endif - -/* - * Major and minor numbers. - */ - -#define ACM_TTY_MAJOR 166 -#define ACM_TTY_MINORS 32 - -/* - * Requests. - */ - -#define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE) - -#define ACM_REQ_COMMAND 0x00 -#define ACM_REQ_RESPONSE 0x01 -#define ACM_REQ_SET_FEATURE 0x02 -#define ACM_REQ_GET_FEATURE 0x03 -#define ACM_REQ_CLEAR_FEATURE 0x04 - -#define ACM_REQ_SET_LINE 0x20 -#define ACM_REQ_GET_LINE 0x21 -#define ACM_REQ_SET_CONTROL 0x22 -#define ACM_REQ_SEND_BREAK 0x23 - -/* - * IRQs. - */ - -#define ACM_IRQ_NETWORK 0x00 -#define ACM_IRQ_LINE_STATE 0x20 - -/* - * Output control lines. - */ - -#define ACM_CTRL_DTR 0x01 -#define ACM_CTRL_RTS 0x02 - -/* - * Input control lines and line errors. - */ - -#define ACM_CTRL_DCD 0x01 -#define ACM_CTRL_DSR 0x02 -#define ACM_CTRL_BRK 0x04 -#define ACM_CTRL_RI 0x08 - -#define ACM_CTRL_FRAMING 0x10 -#define ACM_CTRL_PARITY 0x20 -#define ACM_CTRL_OVERRUN 0x40 - -/* - * Line speed and caracter encoding. - */ - -struct acm_line { - __u32 speed; - __u8 stopbits; - __u8 parity; - __u8 databits; -} __attribute__ ((packed)); - -/* - * Internal driver structures. - */ - -struct acm { - struct usb_device *dev; /* the corresponding usb device */ - struct usb_interface *control; /* control interface */ - struct usb_interface *data; /* data interface */ - struct tty_struct *tty; /* the corresponding tty */ - struct urb *ctrlurb, *readurb, *writeurb; /* urbs */ - struct acm_line line; /* line coding (bits, stop, parity) */ - struct work_struct work; /* work queue entry for line discipline waking up */ - struct tasklet_struct bh; /* rx processing */ - unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ - unsigned int ctrlout; /* output control lines (DTR, RTS) */ - unsigned int writesize; /* max packet size for the output bulk endpoint */ - unsigned int used; /* someone has this acm's device open */ - unsigned int minor; /* acm minor number */ - unsigned char throttle; /* throttled by tty layer */ - unsigned char clocal; /* termios CLOCAL */ -}; - static struct usb_driver acm_driver; static struct tty_driver *acm_tty_driver; static struct acm *acm_table[ACM_TTY_MINORS]; +static DECLARE_MUTEX(open_sem); + #define ACM_READY(acm) (acm && acm->dev && acm->used) /* @@ -310,12 +223,14 @@ struct acm *acm = (struct acm *)urb->context; if (!ACM_READY(acm)) - return; + goto out; if (urb->status) dbg("nonzero write bulk status received: %d", urb->status); schedule_work(&acm->work); +out: + acm->ready_for_write = 1; } static void acm_softint(void *private) @@ -346,22 +261,23 @@ tty->driver_data = acm; acm->tty = tty; - lock_kernel(); + down(&open_sem); - if (acm->used++) { - unlock_kernel(); - return 0; + if (acm->used) { + goto done; } - unlock_kernel(); - acm->ctrlurb->dev = acm->dev; - if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) + if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { dbg("usb_submit_urb(ctrl irq) failed"); + goto bail_out; + } acm->readurb->dev = acm->dev; - if (usb_submit_urb(acm->readurb, GFP_KERNEL)) + if (usb_submit_urb(acm->readurb, GFP_KERNEL)) { dbg("usb_submit_urb(read bulk) failed"); + goto bail_out_and_unlink; + } acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS); @@ -369,7 +285,16 @@ otherwise it is scheduled, and with high data rates data can get lost. */ tty->low_latency = 1; +done: + acm->used++; + up(&open_sem); return 0; + +bail_out_and_unlink: + usb_unlink_urb(acm->ctrlurb); +bail_out: + up(&open_sem); + return -EIO; } static void acm_tty_close(struct tty_struct *tty, struct file *filp) @@ -379,6 +304,7 @@ if (!acm || !acm->used) return; + down(&open_sem); if (!--acm->used) { if (acm->dev) { acm_set_control(acm, acm->ctrlout = 0); @@ -394,6 +320,7 @@ kfree(acm); } } + up(&open_sem); } static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count) @@ -403,7 +330,7 @@ if (!ACM_READY(acm)) return -EINVAL; - if (acm->writeurb->status == -EINPROGRESS) + if (!acm->ready_for_write) return 0; if (!count) return 0; @@ -419,10 +346,11 @@ acm->writeurb->transfer_buffer_length = count; acm->writeurb->dev = acm->dev; - /* GFP_KERNEL probably works if from_user */ - stat = usb_submit_urb(acm->writeurb, GFP_ATOMIC); + acm->ready_for_write = 0; + stat = usb_submit_urb(acm->writeurb, GFP_NOIO); if (stat < 0) { dbg("usb_submit_urb(write bulk) failed"); + acm->ready_for_write = 1; return stat; } @@ -434,7 +362,7 @@ struct acm *acm = tty->driver_data; if (!ACM_READY(acm)) return -EINVAL; - return acm->writeurb->status == -EINPROGRESS ? 0 : acm->writesize; + return !acm->ready_for_write ? 0 : acm->writesize; } static int acm_tty_chars_in_buffer(struct tty_struct *tty) @@ -442,7 +370,7 @@ struct acm *acm = tty->driver_data; if (!ACM_READY(acm)) return -EINVAL; - return acm->writeurb->status == -EINPROGRESS ? acm->writeurb->transfer_buffer_length : 0; + return !acm->ready_for_write ? acm->writeurb->transfer_buffer_length : 0; } static void acm_tty_throttle(struct tty_struct *tty) @@ -567,77 +495,102 @@ * USB probe and disconnect routines. */ -#define CHECK_XFERTYPE(descr, xfer_type) (((descr)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == xfer_type) - static int acm_probe (struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_device *dev; + struct union_desc *union_header = NULL; + char *buffer = intf->altsetting->extra; + int buflen = intf->altsetting->extralen; + struct usb_interface *control_interface; + struct usb_interface *data_interface; + struct usb_endpoint_descriptor *epctrl; + struct usb_endpoint_descriptor *epread; + struct usb_endpoint_descriptor *epwrite; + struct usb_device *usb_dev = interface_to_usbdev(intf); struct acm *acm; - struct usb_host_config *cfacm; - struct usb_interface *data = NULL; - struct usb_host_interface *ifcom, *ifdata = NULL; - struct usb_endpoint_descriptor *epctrl = NULL; - struct usb_endpoint_descriptor *epread = NULL; - struct usb_endpoint_descriptor *epwrite = NULL; - int readsize, ctrlsize, minor, j; - unsigned char *buf; - - dev = interface_to_usbdev (intf); - - cfacm = dev->actconfig; - - /* We know we're probe()d with the control interface. */ - ifcom = intf->cur_altsetting; - - /* ACM doesn't guarantee the data interface is - * adjacent to the control interface, or that if one - * is there it's not for call management ... so find - * it - */ - for (j = 0; j < cfacm->desc.bNumInterfaces; j++) { - ifdata = cfacm->interface[j]->cur_altsetting; - data = cfacm->interface[j]; - - if (ifdata->desc.bInterfaceClass == USB_CLASS_CDC_DATA - && ifdata->desc.bNumEndpoints == 2) { - - epctrl = &ifcom->endpoint[0].desc; - epread = &ifdata->endpoint[0].desc; - epwrite = &ifdata->endpoint[1].desc; - - if ((epctrl->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN - || !CHECK_XFERTYPE(epctrl, USB_ENDPOINT_XFER_INT) - || !CHECK_XFERTYPE(epread, USB_ENDPOINT_XFER_BULK) - || !CHECK_XFERTYPE(epwrite, USB_ENDPOINT_XFER_BULK) - || ((epread->bEndpointAddress & USB_DIR_IN) - ^ (epwrite->bEndpointAddress & USB_DIR_IN)) != USB_DIR_IN) { - /* not suitable */ - goto next_interface; - } - - if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) { - /* descriptors are swapped */ - epread = &ifdata->endpoint[1].desc; - epwrite = &ifdata->endpoint[0].desc; - } - dev_dbg(&intf->dev, "found data interface at %d\n", j); - break; - } else { -next_interface: - ifdata = NULL; - data = NULL; + int minor; + int ctrlsize,readsize; + char *buf; + + if (!buffer) { + err("Wierd descriptor references"); + return -EINVAL; + } + + while (buflen > 0) { + if (buffer [1] != USB_DT_CS_INTERFACE) { + err("skipping garbage"); + goto next_desc; } + + switch (buffer [2]) { + case CDC_UNION_TYPE: /* we've found it */ + if (union_header) { + err("More than one union descriptor, skipping ..."); + goto next_desc; + } + union_header = (struct union_desc *)buffer; + break; + default: + err("Ignoring extra header"); + break; + } +next_desc: + buflen -= buffer[0]; + buffer += buffer[0]; } - /* there's been a problem */ - if (!ifdata) { - dev_dbg(&intf->dev, "data interface not found\n"); + if (!union_header) { + dev_dbg(&intf->dev,"No union descriptor, giving up\n"); return -ENODEV; + } + control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); + data_interface = usb_ifnum_to_if(usb_dev, union_header->bSlaveInterface0); + if (!control_interface || !data_interface) { + dev_dbg(&intf->dev,"no interfaces\n"); + return -ENODEV; + } + + if (usb_interface_claimed(data_interface)) { /* valid in this context */ + dev_dbg(&intf->dev,"The data interface isn't available\n"); + return -EBUSY; } + /*workaround for switched interfaces */ + if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) { + if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) { + struct usb_interface *t; + dev_dbg(&intf->dev,"Your device has switched interfaces.\n"); + + t = control_interface; + control_interface = data_interface; + data_interface = t; + } else { + return -EINVAL; + } + } + if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) + return -EINVAL; + + epctrl = &control_interface->cur_altsetting->endpoint[0].desc; + epread = &data_interface->cur_altsetting->endpoint[0].desc; + epwrite = &data_interface->cur_altsetting->endpoint[1].desc; + + + /* workaround for switched endpoints */ + if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) { + /* descriptors are swapped */ + struct usb_endpoint_descriptor *t; + dev_dbg(&intf->dev,"The data interface has switched endpoints\n"); + + t = epread; + epread = epwrite; + epwrite = t; + } + dbg("interfaces are valid"); for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); + if (acm_table[minor]) { err("no more free acm devices"); return -ENODEV; @@ -647,20 +600,21 @@ dev_dbg(&intf->dev, "out of memory (acm kmalloc)\n"); return -ENOMEM; } - memset(acm, 0, sizeof(struct acm)); ctrlsize = epctrl->wMaxPacketSize; readsize = epread->wMaxPacketSize; acm->writesize = epwrite->wMaxPacketSize; - acm->control = intf; - acm->data = data; + acm->control = control_interface; + acm->data = data_interface; acm->minor = minor; - acm->dev = dev; + acm->dev = usb_dev; acm->bh.func = acm_rx_tasklet; acm->bh.data = (unsigned long) acm; INIT_WORK(&acm->work, acm_softint, acm); + acm->ready_for_write = 1; + if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) { dev_dbg(&intf->dev, "out of memory (buf kmalloc)\n"); @@ -693,29 +647,17 @@ return -ENOMEM; } - usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress), - buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval); + usb_fill_int_urb(acm->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress), + buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval); - usb_fill_bulk_urb(acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress), - buf += ctrlsize, readsize, acm_read_bulk, acm); + usb_fill_bulk_urb(acm->readurb, usb_dev, usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress), + buf += ctrlsize, readsize, acm_read_bulk, acm); acm->readurb->transfer_flags |= URB_NO_FSBR; - usb_fill_bulk_urb(acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress), - buf += readsize, acm->writesize, acm_write_bulk, acm); + usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), + buf += readsize, acm->writesize, acm_write_bulk, acm); acm->writeurb->transfer_flags |= URB_NO_FSBR; - if ( (j = usb_driver_claim_interface(&acm_driver, data, acm)) != 0) { - err("claim failed"); - usb_free_urb(acm->ctrlurb); - usb_free_urb(acm->readurb); - usb_free_urb(acm->writeurb); - kfree(acm); - kfree(buf); - return j; - } - - tty_register_device(acm_tty_driver, minor, &intf->dev); - dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); acm_set_control(acm, acm->ctrlout); @@ -724,11 +666,14 @@ acm->line.databits = 8; acm_set_line(acm, &acm->line); + usb_driver_claim_interface(&acm_driver, data_interface, acm); + + tty_register_device(acm_tty_driver, minor, &intf->dev); + acm_table[minor] = acm; usb_set_intfdata (intf, acm); return 0; } -#undef CHECK_XFERTYPE static void acm_disconnect(struct usb_interface *intf) { @@ -745,6 +690,8 @@ usb_unlink_urb(acm->ctrlurb); usb_unlink_urb(acm->readurb); usb_unlink_urb(acm->writeurb); + + flush_scheduled_work(); /* wait for acm_softint */ kfree(acm->ctrlurb->transfer_buffer); diff -Nru a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/usb/class/cdc-acm.h 2004-06-02 23:59:13 -07:00 @@ -0,0 +1,115 @@ +/* + * + * Includes for cdc-acm.c + * + * Mainly take from usbnet's cdc-ether part + * + */ + +/* + * CMSPAR, some architectures can't have space and mark parity. + */ + +#ifndef CMSPAR +#define CMSPAR 0 +#endif + +/* + * Major and minor numbers. + */ + +#define ACM_TTY_MAJOR 166 +#define ACM_TTY_MINORS 32 + +/* + * Requests. + */ + +#define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE) + +#define ACM_REQ_COMMAND 0x00 +#define ACM_REQ_RESPONSE 0x01 +#define ACM_REQ_SET_FEATURE 0x02 +#define ACM_REQ_GET_FEATURE 0x03 +#define ACM_REQ_CLEAR_FEATURE 0x04 + +#define ACM_REQ_SET_LINE 0x20 +#define ACM_REQ_GET_LINE 0x21 +#define ACM_REQ_SET_CONTROL 0x22 +#define ACM_REQ_SEND_BREAK 0x23 + +/* + * IRQs. + */ + +#define ACM_IRQ_NETWORK 0x00 +#define ACM_IRQ_LINE_STATE 0x20 + +/* + * Output control lines. + */ + +#define ACM_CTRL_DTR 0x01 +#define ACM_CTRL_RTS 0x02 + +/* + * Input control lines and line errors. + */ + +#define ACM_CTRL_DCD 0x01 +#define ACM_CTRL_DSR 0x02 +#define ACM_CTRL_BRK 0x04 +#define ACM_CTRL_RI 0x08 + +#define ACM_CTRL_FRAMING 0x10 +#define ACM_CTRL_PARITY 0x20 +#define ACM_CTRL_OVERRUN 0x40 + +/* + * Line speed and caracter encoding. + */ + +struct acm_line { + __u32 speed; + __u8 stopbits; + __u8 parity; + __u8 databits; +} __attribute__ ((packed)); + +/* + * Internal driver structures. + */ + +struct acm { + struct usb_device *dev; /* the corresponding usb device */ + struct usb_interface *control; /* control interface */ + struct usb_interface *data; /* data interface */ + struct tty_struct *tty; /* the corresponding tty */ + struct urb *ctrlurb, *readurb, *writeurb; /* urbs */ + struct acm_line line; /* line coding (bits, stop, parity) */ + struct work_struct work; /* work queue entry for line discipline waking up */ + struct tasklet_struct bh; /* rx processing */ + unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ + unsigned int ctrlout; /* output control lines (DTR, RTS) */ + unsigned int writesize; /* max packet size for the output bulk endpoint */ + unsigned int used; /* someone has this acm's device open */ + unsigned int minor; /* acm minor number */ + unsigned char throttle; /* throttled by tty layer */ + unsigned char clocal; /* termios CLOCAL */ + unsigned char ready_for_write; /* write urb can be used */ +}; + +/* "Union Functional Descriptor" from CDC spec 5.2.3.X */ +struct union_desc { + u8 bLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + + u8 bMasterInterface0; + u8 bSlaveInterface0; + /* ... and there could be other slave interfaces */ +} __attribute__ ((packed)); + +#define CDC_UNION_TYPE 0x06 +#define CDC_DATA_INTERFACE_TYPE 0x0a + diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h --- a/drivers/usb/core/hcd.h 2004-06-02 23:59:13 -07:00 +++ b/drivers/usb/core/hcd.h 2004-06-02 23:59:13 -07:00 @@ -244,16 +244,9 @@ struct usb_bus *, unsigned port); extern int usb_new_device(struct usb_device *dev); extern void usb_disconnect(struct usb_device **); -extern void usb_choose_address(struct usb_device *dev); -extern void usb_release_address(struct usb_device *dev); -/* exported to hub driver ONLY to support usb_reset_device () */ extern int usb_get_configuration(struct usb_device *dev); extern void usb_destroy_configuration(struct usb_device *dev); - -/* use these only before the device's address has been set */ -#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30)) -#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | USB_DIR_IN) /*-------------------------------------------------------------------------*/ diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c --- a/drivers/usb/core/hub.c 2004-06-02 23:59:13 -07:00 +++ b/drivers/usb/core/hub.c 2004-06-02 23:59:13 -07:00 @@ -9,6 +9,11 @@ */ #include +#ifdef CONFIG_USB_DEBUG + #define DEBUG +#else + #undef DEBUG +#endif #include #include #include @@ -19,11 +24,6 @@ #include #include #include -#ifdef CONFIG_USB_DEBUG - #define DEBUG -#else - #undef DEBUG -#endif #include #include #include @@ -40,7 +40,6 @@ static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED; static LIST_HEAD(hub_event_list); /* List of hubs needing servicing */ -static LIST_HEAD(hub_list); /* List of all hubs (for cleanup) */ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); static pid_t khubd_pid = 0; /* PID of khubd */ @@ -268,7 +267,7 @@ if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0 /* ENODEV means we raced disconnect() */ && status != -ENODEV) - dev_err (&hub->intf->dev, "resubmit --> %d\n", urb->status); + dev_err (&hub->intf->dev, "resubmit --> %d\n", status); if (status == 0) hub->urb_active = 1; done: @@ -646,7 +645,6 @@ /* Delete it and then reset it */ list_del_init(&hub->event_list); - list_del_init(&hub->hub_list); spin_unlock_irqrestore(&hub_event_lock, flags); @@ -695,7 +693,6 @@ struct usb_device *hdev; struct usb_hub *hub; struct device *hub_dev; - unsigned long flags; desc = intf->cur_altsetting; hdev = interface_to_usbdev(intf); @@ -711,23 +708,19 @@ } /* Multiple endpoints? What kind of mutant ninja-hub is this? */ - if (desc->desc.bNumEndpoints != 1) { + if (desc->desc.bNumEndpoints != 1) goto descriptor_error; - } endpoint = &desc->endpoint[0].desc; /* Output endpoint? Curiouser and curiouser.. */ - if (!(endpoint->bEndpointAddress & USB_DIR_IN)) { + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) goto descriptor_error; - } /* If it's not an interrupt endpoint, we'd better punt! */ if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - != USB_ENDPOINT_XFER_INT) { + != USB_ENDPOINT_XFER_INT) goto descriptor_error; - return -EIO; - } /* We found a hub */ dev_info (hub_dev, "USB hub found\n"); @@ -745,12 +738,6 @@ init_MUTEX(&hub->khubd_sem); INIT_WORK(&hub->leds, led_work, hub); - /* Record the new hub's existence */ - spin_lock_irqsave(&hub_event_lock, flags); - INIT_LIST_HEAD(&hub->hub_list); - list_add(&hub->hub_list, &hub_list); - spin_unlock_irqrestore(&hub_event_lock, flags); - usb_set_intfdata (intf, hub); if (hdev->speed == USB_SPEED_HIGH) @@ -845,6 +832,234 @@ dev_err(&hdev->dev, "cannot disconnect hub!\n"); } + +static void choose_address(struct usb_device *udev) +{ + int devnum; + struct usb_bus *bus = udev->bus; + + /* If khubd ever becomes multithreaded, this will need a lock */ + + /* Try to allocate the next devnum beginning at bus->devnum_next. */ + devnum = find_next_zero_bit(bus->devmap.devicemap, 128, + bus->devnum_next); + if (devnum >= 128) + devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1); + + bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1); + + if (devnum < 128) { + set_bit(devnum, bus->devmap.devicemap); + udev->devnum = devnum; + } +} + +static void release_address(struct usb_device *udev) +{ + if (udev->devnum > 0) { + clear_bit(udev->devnum, udev->bus->devmap.devicemap); + udev->devnum = -1; + } +} + +/** + * usb_disconnect - disconnect a device (usbcore-internal) + * @pdev: pointer to device being disconnected + * Context: !in_interrupt () + * + * Something got disconnected. Get rid of it, and all of its children. + * + * Only hub drivers (including virtual root hub drivers for host + * controllers) should ever call this. + * + * This call is synchronous, and may not be used in an interrupt context. + */ +void usb_disconnect(struct usb_device **pdev) +{ + struct usb_device *udev = *pdev; + struct usb_bus *bus; + struct usb_operations *ops; + int i; + + if (!udev) { + pr_debug ("%s nodev\n", __FUNCTION__); + return; + } + bus = udev->bus; + if (!bus) { + pr_debug ("%s nobus\n", __FUNCTION__); + return; + } + ops = bus->op; + + *pdev = NULL; + + /* mark the device as inactive, so any further urb submissions for + * this device will fail. + */ + udev->state = USB_STATE_NOTATTACHED; + down(&udev->serialize); + + dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum); + + /* Free up all the children before we remove this device */ + for (i = 0; i < USB_MAXCHILDREN; i++) { + struct usb_device **child = udev->children + i; + if (*child) + usb_disconnect(child); + } + + /* deallocate hcd/hardware state ... nuking all pending urbs and + * cleaning up all state associated with the current configuration + */ + usb_disable_device(udev, 0); + + /* Free the device number and remove the /proc/bus/usb entry */ + dev_dbg (&udev->dev, "unregistering device\n"); + release_address(udev); + usbfs_remove_device(udev); + up(&udev->serialize); + device_unregister(&udev->dev); +} + +static int choose_configuration(struct usb_device *udev) +{ + int c, i; + + /* NOTE: this should interact with hub power budgeting */ + + c = udev->config[0].desc.bConfigurationValue; + if (udev->descriptor.bNumConfigurations != 1) { + for (i = 0; i < udev->descriptor.bNumConfigurations; i++) { + struct usb_interface_descriptor *desc; + + /* heuristic: Linux is more likely to have class + * drivers, so avoid vendor-specific interfaces. + */ + desc = &udev->config[i].intf_cache[0] + ->altsetting->desc; + if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) + continue; + /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */ + if (desc->bInterfaceClass == USB_CLASS_COMM + && desc->bInterfaceSubClass == 2 + && desc->bInterfaceProtocol == 0xff) + continue; + c = udev->config[i].desc.bConfigurationValue; + break; + } + dev_info(&udev->dev, + "configuration #%d chosen from %d choices\n", + c, udev->descriptor.bNumConfigurations); + } + return c; +} + +#ifdef DEBUG +static void show_string(struct usb_device *udev, char *id, int index) +{ + char *buf; + + if (!index) + return; + if (!(buf = kmalloc(256, GFP_KERNEL))) + return; + if (usb_string(udev, index, buf, 256) > 0) + dev_printk(KERN_INFO, &udev->dev, "%s: %s\n", id, buf); + kfree(buf); +} + +#else +static inline void show_string(struct usb_device *udev, char *id, int index) +{} +#endif + +/* + * usb_new_device - perform initial device setup (usbcore-internal) + * @dev: newly addressed device (in ADDRESS state) + * + * This is called with devices which have been enumerated, but not yet + * configured. The device descriptor is available, but not descriptors + * for any device configuration. The caller owns dev->serialize, and + * the device is not visible through sysfs or other filesystem code. + * + * Returns 0 for success (device is configured and listed, with its + * interfaces, in sysfs); else a negative errno value. On error, one + * reference count to the device has been dropped. + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Only the hub driver should ever call this; root hub registration + * uses it only indirectly. + */ +int usb_new_device(struct usb_device *udev) +{ + int err; + int c; + + err = usb_get_configuration(udev); + if (err < 0) { + dev_err(&udev->dev, "can't read configurations, error %d\n", + err); + goto fail; + } + + /* Tell the world! */ + dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " + "SerialNumber=%d\n", + udev->descriptor.iManufacturer, + udev->descriptor.iProduct, + udev->descriptor.iSerialNumber); + + if (udev->descriptor.iProduct) + show_string(udev, "Product", + udev->descriptor.iProduct); + if (udev->descriptor.iManufacturer) + show_string(udev, "Manufacturer", + udev->descriptor.iManufacturer); + if (udev->descriptor.iSerialNumber) + show_string(udev, "SerialNumber", + udev->descriptor.iSerialNumber); + + /* put device-specific files into sysfs */ + err = device_add (&udev->dev); + if (err) { + dev_err(&udev->dev, "can't device_add, error %d\n", err); + goto fail; + } + usb_create_sysfs_dev_files (udev); + + /* choose and set the configuration. that registers the interfaces + * with the driver core, and lets usb device drivers bind to them. + */ + c = choose_configuration(udev); + if (c < 0) + dev_warn(&udev->dev, + "can't choose an initial configuration\n"); + else { + err = usb_set_configuration(udev, c); + if (err) { + dev_err(&udev->dev, "can't set config #%d, error %d\n", + c, err); + device_del(&udev->dev); + goto fail; + } + } + + /* USB device state == configured ... usable */ + + /* add a /proc/bus/usb entry */ + usbfs_add_device(udev); + return 0; + +fail: + udev->state = USB_STATE_NOTATTACHED; + release_address(udev); + usb_put_dev(udev); + return err; +} + + static int hub_port_status(struct usb_device *hdev, int port, u16 *status, u16 *change) { @@ -1037,7 +1252,7 @@ if (udev->state != USB_STATE_DEFAULT && udev->state != USB_STATE_ADDRESS) return -EINVAL; - retval = usb_control_msg(udev, usb_snddefctrl(udev), + retval = usb_control_msg(udev, (PIPE_CONTROL << 30) /* Address 0 */, USB_REQ_SET_ADDRESS, 0, udev->devnum, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); if (retval == 0) @@ -1111,7 +1326,7 @@ /* set the address */ if (udev->devnum <= 0) { - usb_choose_address(udev); + choose_address(udev); if (udev->devnum <= 0) goto fail; @@ -1166,7 +1381,7 @@ udev->devnum, retval); fail: hub_port_disable(hdev, port); - usb_release_address(udev); + release_address(udev); usb_put_dev(udev); up(&usb_address0_sem); return retval; @@ -1581,9 +1796,6 @@ .id_table = hub_id_table, }; -/* - * This should be a separate module. - */ int usb_hub_init(void) { pid_t pid; diff -Nru a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h --- a/drivers/usb/core/hub.h 2004-06-02 23:59:13 -07:00 +++ b/drivers/usb/core/hub.h 2004-06-02 23:59:13 -07:00 @@ -202,7 +202,6 @@ int error; /* last reported error */ int nerrors; /* track consecutive errors */ - struct list_head hub_list; /* all hubs */ struct list_head event_list; /* hubs w/data or errs ready */ struct usb_hub_descriptor *descriptor; /* class descriptor */ diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c --- a/drivers/usb/core/message.c 2004-06-02 23:59:13 -07:00 +++ b/drivers/usb/core/message.c 2004-06-02 23:59:13 -07:00 @@ -566,7 +566,7 @@ */ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size) { - int i = 5; + int i = 3; int result; memset(buf,0,size); // Make sure we parse really received data @@ -579,9 +579,6 @@ HZ * USB_CTRL_GET_TIMEOUT)) > 0 || result != -EPIPE) break; - - dev_dbg (&dev->dev, "RETRY descriptor, result %d\n", result); - result = -ENOMSG; } return result; } diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c 2004-06-02 23:59:13 -07:00 +++ b/drivers/usb/core/usb.c 2004-06-02 23:59:13 -07:00 @@ -945,235 +945,6 @@ } /** - * usb_disconnect - disconnect a device (usbcore-internal) - * @pdev: pointer to device being disconnected - * Context: !in_interrupt () - * - * Something got disconnected. Get rid of it, and all of its children. - * - * Only hub drivers (including virtual root hub drivers for host - * controllers) should ever call this. - * - * This call is synchronous, and may not be used in an interrupt context. - */ -void usb_disconnect(struct usb_device **pdev) -{ - struct usb_device *dev = *pdev; - struct usb_bus *bus; - struct usb_operations *ops; - int i; - - might_sleep (); - - if (!dev) { - pr_debug ("%s nodev\n", __FUNCTION__); - return; - } - bus = dev->bus; - if (!bus) { - pr_debug ("%s nobus\n", __FUNCTION__); - return; - } - ops = bus->op; - - *pdev = NULL; - - /* mark the device as inactive, so any further urb submissions for - * this device will fail. - */ - dev->state = USB_STATE_NOTATTACHED; - down(&dev->serialize); - - dev_info (&dev->dev, "USB disconnect, address %d\n", dev->devnum); - - /* Free up all the children before we remove this device */ - for (i = 0; i < USB_MAXCHILDREN; i++) { - struct usb_device **child = dev->children + i; - if (*child) - usb_disconnect(child); - } - - /* deallocate hcd/hardware state ... nuking all pending urbs and - * cleaning up all state associated with the current configuration - */ - usb_disable_device(dev, 0); - - /* Free the device number and remove the /proc/bus/usb entry */ - dev_dbg (&dev->dev, "unregistering device\n"); - usb_release_address(dev); - usbfs_remove_device(dev); - up(&dev->serialize); - device_unregister(&dev->dev); -} - -/** - * usb_choose_address - pick device address (usbcore-internal) - * @dev: newly detected device (in DEFAULT state) - * - * Picks a device address. It's up to the hub (or root hub) driver - * to handle and manage enumeration, starting from the DEFAULT state. - * Only hub drivers (but not virtual root hub drivers for host - * controllers) should ever call this. - */ -void usb_choose_address(struct usb_device *dev) -{ - int devnum; - // FIXME needs locking for SMP!! - /* why? this is called only from the hub thread, - * which hopefully doesn't run on multiple CPU's simultaneously 8-) - */ - - /* Try to allocate the next devnum beginning at bus->devnum_next. */ - devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, dev->bus->devnum_next); - if (devnum >= 128) - devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1); - - dev->bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1); - - if (devnum < 128) { - set_bit(devnum, dev->bus->devmap.devicemap); - dev->devnum = devnum; - } -} - -/** - * usb_release_address - deallocate device address (usbcore-internal) - * @dev: newly removed device - * - * Removes and deallocates the address assigned to a device. - * Only hub drivers (but not virtual root hub drivers for host - * controllers) should ever call this. - */ -void usb_release_address(struct usb_device *dev) -{ - if (dev->devnum > 0) { - clear_bit(dev->devnum, dev->bus->devmap.devicemap); - dev->devnum = -1; - } -} - - -static inline void usb_show_string(struct usb_device *dev, char *id, int index) -{ - char *buf; - - if (!index) - return; - if (!(buf = kmalloc(256, GFP_KERNEL))) - return; - if (usb_string(dev, index, buf, 256) > 0) - dev_printk(KERN_INFO, &dev->dev, "%s: %s\n", id, buf); - kfree(buf); -} - -static int usb_choose_configuration(struct usb_device *dev) -{ - int c, i; - - c = dev->config[0].desc.bConfigurationValue; - if (dev->descriptor.bNumConfigurations != 1) { - for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { - struct usb_interface_descriptor *desc; - - /* heuristic: Linux is more likely to have class - * drivers, so avoid vendor-specific interfaces. - */ - desc = &dev->config[i].intf_cache[0] - ->altsetting->desc; - if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) - continue; - /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */ - if (desc->bInterfaceClass == USB_CLASS_COMM - && desc->bInterfaceSubClass == 2 - && desc->bInterfaceProtocol == 0xff) - continue; - c = dev->config[i].desc.bConfigurationValue; - break; - } - dev_info(&dev->dev, - "configuration #%d chosen from %d choices\n", - c, dev->descriptor.bNumConfigurations); - } - return c; -} - -/* - * usb_new_device - perform initial device setup (usbcore-internal) - * @dev: newly addressed device (in ADDRESS state) - * - * This is called with devices which have been enumerated, but not yet - * configured. The device descriptor is available, but not descriptors - * for any device configuration. The caller owns dev->serialize, and - * the device is not visible through sysfs or other filesystem code. - * - * Returns 0 for success (device is configured and listed, with its - * interfaces, in sysfs); else a negative errno value. On error, one - * reference count to the device has been dropped. - * - * This call is synchronous, and may not be used in an interrupt context. - * - * Only the hub driver should ever call this; root hub registration - * uses it only indirectly. - */ -int usb_new_device(struct usb_device *dev) -{ - int err; - int c; - - err = usb_get_configuration(dev); - if (err < 0) { - dev_err(&dev->dev, "can't read configurations, error %d\n", - err); - goto fail; - } - - /* Tell the world! */ - dev_dbg(&dev->dev, "new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n", - dev->descriptor.iManufacturer, dev->descriptor.iProduct, dev->descriptor.iSerialNumber); - -#ifdef DEBUG - if (dev->descriptor.iProduct) - usb_show_string(dev, "Product", dev->descriptor.iProduct); - if (dev->descriptor.iManufacturer) - usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer); - if (dev->descriptor.iSerialNumber) - usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber); -#endif - - /* put device-specific files into sysfs */ - err = device_add (&dev->dev); - if (err) { - dev_err(&dev->dev, "can't device_add, error %d\n", err); - goto fail; - } - usb_create_sysfs_dev_files (dev); - - /* choose and set the configuration. that registers the interfaces - * with the driver core, and lets usb device drivers bind to them. - * NOTE: should interact with hub power budgeting. - */ - c = usb_choose_configuration(dev); - err = usb_set_configuration(dev, c); - if (err) { - dev_err(&dev->dev, "can't set config #%d, error %d\n", c, err); - device_del(&dev->dev); - goto fail; - } - - /* USB device state == configured ... usable */ - - /* add a /proc/bus/usb entry */ - usbfs_add_device(dev); - - return 0; -fail: - dev->state = USB_STATE_NOTATTACHED; - usb_release_address(dev); - usb_put_dev(dev); - return err; -} - -/** * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP * @dev: device the buffer will be used with * @size: requested buffer size diff -Nru a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c --- a/drivers/usb/gadget/dummy_hcd.c 2004-06-02 23:59:13 -07:00 +++ b/drivers/usb/gadget/dummy_hcd.c 2004-06-02 23:59:13 -07:00 @@ -825,8 +825,7 @@ dum = container_of (hcd, struct dummy, hcd); spin_lock_irqsave (&dum->lock, flags); - if (!dum->hdev) - dum->hdev = urb->dev->hcpriv; + dum->hdev = urb->dev->hcpriv; urb->hcpriv = dum; if (usb_pipetype (urb->pipe) == PIPE_CONTROL) urb->error_count = 1; /* mark as a new urb */ @@ -994,10 +993,17 @@ return limit; } +#define is_active(dum) ((dum->port_status & \ + (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE | \ + USB_PORT_STAT_SUSPEND)) \ + == (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE)) + static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) { int i; + if (!is_active (dum)) + return NULL; if ((address & ~USB_DIR_IN) == 0) return &dum->ep [0]; for (i = 1; i < DUMMY_ENDPOINTS; i++) { @@ -1011,6 +1017,8 @@ return NULL; } +#undef is_active + #define Dev_Request (USB_TYPE_STANDARD | USB_RECIP_DEVICE) #define Dev_InRequest (Dev_Request | USB_DIR_IN) #define Intf_Request (USB_TYPE_STANDARD | USB_RECIP_INTERFACE) @@ -1404,9 +1412,8 @@ break; case USB_PORT_FEAT_POWER: dum->port_status = 0; - dum->address = 0; - dum->hdev = 0; dum->resuming = 0; + stop_activity(dum, dum->driver); break; default: dum->port_status &= ~(1 << wValue); diff -Nru a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c --- a/drivers/usb/gadget/ether.c 2004-06-02 23:59:13 -07:00 +++ b/drivers/usb/gadget/ether.c 2004-06-02 23:59:13 -07:00 @@ -2302,17 +2302,6 @@ UTS_SYSNAME " " UTS_RELEASE "/%s", gadget->name); - /* CDC subset ... recognized by Linux since 2.4.10, but Windows - * drivers aren't widely available. - */ - if (!cdc) { - device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; - device_desc.idVendor = - __constant_cpu_to_le16(SIMPLE_VENDOR_NUM); - device_desc.idProduct = - __constant_cpu_to_le16(SIMPLE_PRODUCT_NUM); - } - /* If there's an RNDIS configuration, that's what Windows wants to * be using ... so use these product IDs here and in the "linux.inf" * needed to install MSFT drivers. Current Linux kernels will use @@ -2326,6 +2315,16 @@ __constant_cpu_to_le16(RNDIS_PRODUCT_NUM); snprintf (product_desc, sizeof product_desc, "RNDIS/%s", driver_desc); + + /* CDC subset ... recognized by Linux since 2.4.10, but Windows + * drivers aren't widely available. + */ + } else if (!cdc) { + device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; + device_desc.idVendor = + __constant_cpu_to_le16(SIMPLE_VENDOR_NUM); + device_desc.idProduct = + __constant_cpu_to_le16(SIMPLE_PRODUCT_NUM); } /* support optional vendor/distro customization */ diff -Nru a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c --- a/drivers/usb/storage/isd200.c 2004-06-02 23:59:13 -07:00 +++ b/drivers/usb/storage/isd200.c 2004-06-02 23:59:13 -07:00 @@ -485,7 +485,9 @@ memcpy(srb->cmnd, &ata, sizeof(ata.generic)); srb->cmd_len = sizeof(ata.generic); + down(&(us->pusb_dev->serialize)); status = usb_stor_Bulk_transport(srb, us); + up(&(us->pusb_dev->serialize)); if (status == USB_STOR_TRANSPORT_GOOD) status = ISD200_GOOD; else { @@ -545,7 +547,9 @@ /* send the command to the transport layer */ memcpy(srb->cmnd, ataCdb, sizeof(ataCdb->generic)); srb->cmd_len = sizeof(ataCdb->generic); + down(&(us->pusb_dev->serialize)); transferStatus = usb_stor_Bulk_transport(srb, us); + up(&(us->pusb_dev->serialize)); /* if the command gets aborted by the higher layers, we need to * short-circuit all other processing diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c --- a/drivers/usb/storage/transport.c 2004-06-02 23:59:13 -07:00 +++ b/drivers/usb/storage/transport.c 2004-06-02 23:59:13 -07:00 @@ -527,9 +527,18 @@ int need_auto_sense; int result; + /* + * Grab device's serialize mutex to prevent /usbfs and others from + * sending out a command in the middle of ours (if libusb sends a + * get_descriptor or something on pipe 0 after our CBW and before + * our CSW, and then we get a stall, we have trouble) + */ + /* send the command to the transport layer */ + down(&(us->pusb_dev->serialize)); srb->resid = 0; result = us->transport(srb, us); + up(&(us->pusb_dev->serialize)); /* if the command gets aborted by the higher layers, we need to * short-circuit all other processing @@ -648,9 +657,11 @@ srb->serial_number ^= 0x80000000; /* issue the auto-sense command */ + down(&(us->pusb_dev->serialize)); old_resid = srb->resid; srb->resid = 0; temp_result = us->transport(us->srb, us); + up(&(us->pusb_dev->serialize)); /* let's clean up right away */ srb->resid = old_resid; diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h --- a/drivers/usb/storage/unusual_devs.h 2004-06-02 23:59:13 -07:00 +++ b/drivers/usb/storage/unusual_devs.h 2004-06-02 23:59:13 -07:00 @@ -359,12 +359,18 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, "Fujifilm", "Digital Camera EX-20 DSC", - US_SC_8070, US_PR_CBI, NULL, 0 ), + US_SC_8070, US_PR_DEVICE, NULL, 0 ), UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200, "LaCie", "USB Hard Disk", US_SC_RBC, US_PR_CB, NULL, 0 ), + +/* Submitted by Jol Bourquard */ +UNUSUAL_DEV( 0x05ab, 0x0060, 0x1104, 0x1110, + "In-System", + "PyroGate External CD-ROM Enclosure (FCD-523)", + US_SC_SCSI, US_PR_BULK, NULL, 0 ), #ifdef CONFIG_USB_STORAGE_ISD200 UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110,