bk://kernel.bkbits.net/gregkh/linux/usb-2.6 stern@rowland.harvard.edu|ChangeSet|20040910220414|45628 stern # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/09/11 15:14:19-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/pci/quirks.c # 2004/09/11 15:14:15-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/10 17:19:49-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/09/10 17:19:45-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/10 15:04:14-07:00 stern@rowland.harvard.edu # [PATCH] USB: Fix off-by-one error in the hub driver # # This one-liner fixes a simple mistake in a newly-added part of the hub # driver. When a connect change takes place on a suspended port the code # clears the suspend, but the port number it passes is origin-0 and it # should be origin-1. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/09/07 10:22:52-07:00 stern@rowland.harvard.edu +1 -1 # USB: Fix off-by-one error in the hub driver # # ChangeSet # 2004/09/10 15:02:34-07:00 stern@rowland.harvard.edu # [PATCH] USB: Improve UHCI suspend/resume # # This patch fixes some problems with the suspend/resume handling in the # UHCI driver: # # Don't try to resume ports that aren't already suspended. # # The controller won't permit Resume signals to be sent to a port # if the port isn't enabled, so don't assume it will work. # # Port reset and port disable will terminate Resume signalling. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/uhci-hub.c # 2004/09/09 11:26:05-07:00 stern@rowland.harvard.edu +47 -20 # USB: Improve UHCI suspend/resume # # ChangeSet # 2004/09/10 15:02:06-07:00 johnstul@us.ibm.com # [PATCH] USB: early usb handoff for 2.6 # # Apparently there is an issue w/ the IBM x440/x445's BIOS's USB # Legacy support. Due to the delay in issuing SMI's across the IOAPICs, # its possible for I/O to ports 60/64 to cause register corruption. # # The solution is to disable the BIOS's USB Legacy support early in # boot(via PCI quirks) for x440/x445 systems. # # Originally written by Vojtech against SuSE's tree, this patch was then # updated to disable EHCI by Aleksey Gorelov, cleaned up by Pete Zaitcev # for 2.4 and finally tweaked and updated against 2.6 by me. # # I've lightly tested this version of the patch, but it differs little # from what Aleksey, Pete and I have been testing for 2.4. # # # Signed-off-by: John Stultz # Signed-off-by: Greg Kroah-Hartman # # include/asm-i386/mach-summit/mach_mpparse.h # 2004/09/09 17:59:01-07:00 johnstul@us.ibm.com +3 -0 # USB: early usb handoff for 2.6 # # drivers/pci/quirks.c # 2004/09/09 17:59:01-07:00 johnstul@us.ibm.com +230 -0 # USB: early usb handoff for 2.6 # # Documentation/kernel-parameters.txt # 2004/09/09 17:59:01-07:00 johnstul@us.ibm.com +2 -0 # USB: early usb handoff for 2.6 # # ChangeSet # 2004/09/10 10:05:02-07:00 oliver@neukum.org # [PATCH] USB: maintainership of acm cdc # # I've discussed this with Vojtech. If I brake the probe method, # I can also break the rest ;-) # # # Signed-Off-By: Oliver Neukum # Signed-off-by: Greg Kroah-Hartman # # # - new cdc acm maintainer # # MAINTAINERS # 2004/09/10 03:17:08-07:00 oliver@neukum.org +5 -5 # USB: maintainership of acm cdc # # ChangeSet # 2004/09/09 16:46:47-07:00 david-b@pacbell.net # [PATCH] USB: omap_udc supports 5910/1510 chips # # This removes the "don't run on OMAP 1510" constraint from the # driver and teaches it how not to use registers only available on # newer chips. It's effectively just a compile fix, though ... hasn't # got any board support yet. # # # Basic build fixes for the OMAP 1510/5910. This first generation chip # doesn't include an OTG controller. The patch makes the driver stop # using OTG registers, and adds some #defines that will be needed to # support boards using those chips. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/omap_udc.h # 2004/09/09 15:02:43-07:00 david-b@pacbell.net +9 -2 # USB: omap_udc supports 5910/1510 chips # # drivers/usb/gadget/omap_udc.c # 2004/09/08 22:53:58-07:00 david-b@pacbell.net +80 -64 # USB: omap_udc supports 5910/1510 chips # # ChangeSet # 2004/09/09 16:07:40-07:00 david-b@pacbell.net # [PATCH] USB: khubd looks at ports after probe # # Fix the hub probe logic so that when khubd wakes up, it will actually # look at all ports on the new hub. This resolved a root hub enumeration # issue, and I expect the "boot from USB disk" folk will like this too. # # The fix includes cleanup: centralizing the logic to make khubd look # at a given hub, instead of cloning it three times (or in the case of # hub probing, frankensteining it). # # This also adds a FIXME to the new routine centralizing disconnect # processing: we also want "power down port but don't wake khubd" # (for PM_SUSPEND_DISK as well as SRP). # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/09/09 02:44:08-07:00 david-b@pacbell.net +31 -16 # USB: khubd looks at ports after probe # # ChangeSet # 2004/09/09 16:06:55-07:00 david-b@pacbell.net # [PATCH] USB: ohci updates # # Small bugfixes, at least one of which gets rid of some # rather random behavior from certain board init # behaviors. # # # OHCI updates: # # - Bugfix the code taking frame clock adjustments from the boot loader. # A recent change had a bug which caused inconsistent failures on some # OHCI configs, including amd756. Thanks to # for tracking down the specifics. # # - From Lothar Wassmann two fixes: # (a) don't let tick clock sign-extend, that can make unlinks # take excessively long (could happen easily enough); # (b) when re-activating schedules after suspend, use the right # bitmask (rare/exotic) # # - When suspending the root hub, mark it as USB_STATE_SUSPENDED # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/ohci.h # 2004/09/08 15:49:26-07:00 david-b@pacbell.net +3 -2 # USB: ohci updates # # drivers/usb/host/ohci-hub.c # 2004/09/08 15:49:26-07:00 david-b@pacbell.net +5 -4 # USB: ohci updates # # drivers/usb/host/ohci-hcd.c # 2004/09/08 15:49:26-07:00 david-b@pacbell.net +12 -4 # USB: ohci updates # # drivers/usb/host/ohci-dbg.c # 2004/09/08 15:49:26-07:00 david-b@pacbell.net +2 -2 # USB: ohci updates # # ChangeSet # 2004/09/09 16:05:48-07:00 david-b@pacbell.net # [PATCH] USB: gadget_is_n9604 # # This adds recognition of one more UDC driver. # (Driver is available separately.) # # # Tell gadget drivers about the National 9603/9604 UDC. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/zero.c # 2004/09/08 15:48:01-07:00 david-b@pacbell.net +2 -0 # USB: gadget_is_n9604 # # drivers/usb/gadget/gadget_chips.h # 2004/09/08 15:48:01-07:00 david-b@pacbell.net +6 -0 # USB: gadget_is_n9604 # # drivers/usb/gadget/file_storage.c # 2004/09/08 15:48:01-07:00 david-b@pacbell.net +3 -1 # USB: gadget_is_n9604 # # drivers/usb/gadget/ether.c # 2004/09/08 15:48:00-07:00 david-b@pacbell.net +6 -0 # USB: gadget_is_n9604 # # ChangeSet # 2004/09/09 16:05:09-07:00 david-b@pacbell.net # [PATCH] export usb_set_device_state(), use in ohci # # This patch is mostly cleanup, but it all helps make PM_SUSPEND_DISK # start to behave better. # # # This exports the new usb_set_device_state() routine for the virtual root # hubs, and uses it in OHCI during resume after power-off to replace some # HC-private code doing almost the same thing. # # Note that all HCDs will likely need the same kind of suspend-to-disk # support (though it's different when BIOS kicks in). Some systems # even power-off during suspend-to-ram (to save extra power), which is # why OHCI already has this logic! # # Related updates: # # - Use usb_set_device_state() immediately when an HC dies, making khubd # handle disconnect processing instead of a workqueue. So now drivers # won't self-deadlock in this should-be-rare path, when disconnect() # calls flush_scheduled_work(). # # - Don't warn about "Unlink after no-IRQ" for the the root hub's status # URB ... like when suspending an HCD that never enumerated a device. # # - Minor IRQ handler cleanup, including more accurate tracking of whether # this driver ever returned IRQ_HANDLED (shared IRQs don't count). # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/ohci-hcd.c # 2004/09/09 03:59:25-07:00 david-b@pacbell.net +1 -13 # export usb_set_device_state(), use in ohci # # drivers/usb/core/usb.h # 2004/09/09 04:00:10-07:00 david-b@pacbell.net +0 -2 # export usb_set_device_state(), use in ohci # # drivers/usb/core/hub.c # 2004/09/09 04:10:54-07:00 david-b@pacbell.net +2 -1 # export usb_set_device_state(), use in ohci # # drivers/usb/core/hcd.h # 2004/09/09 04:09:29-07:00 david-b@pacbell.net +3 -1 # export usb_set_device_state(), use in ohci # # drivers/usb/core/hcd.c # 2004/09/09 03:59:25-07:00 david-b@pacbell.net +6 -23 # export usb_set_device_state(), use in ohci # # ChangeSet # 2004/09/09 11:56:19-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in generic usb-serial driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/generic.c # 2004/09/09 11:55:59-07:00 greg@kroah.com +2 -2 # USB: fix usb_unlink_urb() usage in generic usb-serial driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:54:43-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in keyspan_pda driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/keyspan_pda.c # 2004/09/09 11:54:25-07:00 greg@kroah.com +3 -3 # USB: fix usb_unlink_urb() usage in keyspan_pda driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:52:22-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in ftdi_sio driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/ftdi_sio.c # 2004/09/09 11:52:08-07:00 greg@kroah.com +2 -10 # USB: fix usb_unlink_urb() usage in ftdi_sio driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:51:42-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in io_ti driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/io_ti.c # 2004/09/09 11:51:26-07:00 greg@kroah.com +3 -3 # USB: fix usb_unlink_urb() usage in io_ti driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:50:55-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in kobil_sct driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/kobil_sct.c # 2004/09/09 11:50:37-07:00 greg@kroah.com +6 -8 # USB: fix usb_unlink_urb() usage in kobil_sct driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:49:56-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in kl5kusb105 driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/kl5kusb105.c # 2004/09/09 11:49:41-07:00 greg@kroah.com +6 -6 # USB: fix usb_unlink_urb() usage in kl5kusb105 driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:49:19-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in visor driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/visor.c # 2004/09/09 11:49:03-07:00 greg@kroah.com +3 -3 # USB: fix usb_unlink_urb() usage in visor driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:48:32-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in omninet driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/omninet.c # 2004/09/09 11:48:14-07:00 greg@kroah.com +2 -2 # USB: fix usb_unlink_urb() usage in omninet driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:47:46-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in mct_u232 driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/mct_u232.c # 2004/09/09 11:47:29-07:00 greg@kroah.com +3 -3 # USB: fix usb_unlink_urb() usage in mct_u232 driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:45:53-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in empeg driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/empeg.c # 2004/09/09 11:45:35-07:00 greg@kroah.com +4 -4 # USB: fix usb_unlink_urb() usage in empeg driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:44:04-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in digi_acceleport driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/digi_acceleport.c # 2004/09/09 11:43:45-07:00 greg@kroah.com +3 -3 # USB: fix usb_unlink_urb() usage in digi_acceleport driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:42:45-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in ipaq driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/ipaq.c # 2004/09/09 11:42:19-07:00 greg@kroah.com +2 -2 # USB: fix usb_unlink_urb() usage in ipaq driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:41:32-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in ir-usb driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/ir-usb.c # 2004/09/09 11:41:14-07:00 greg@kroah.com +1 -1 # USB: fix usb_unlink_urb() usage in ir-usb driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:36:08-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in io_edgeport driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/io_edgeport.c # 2004/09/09 11:35:44-07:00 greg@kroah.com +3 -3 # USB: fix usb_unlink_urb() usage in io_edgeport driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:35:24-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in whiteheat driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/whiteheat.c # 2004/09/09 11:35:05-07:00 greg@kroah.com +4 -4 # USB: fix usb_unlink_urb() usage in whiteheat driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:34:35-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in cyberjack driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/cyberjack.c # 2004/09/09 11:34:15-07:00 greg@kroah.com +3 -3 # USB: fix usb_unlink_urb() usage in cyberjack driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:34:02-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in belkin_sa driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/belkin_sa.c # 2004/09/09 11:33:07-07:00 greg@kroah.com +4 -4 # USB: fix usb_unlink_urb() usage in belkin_sa driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:32:18-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in usb-serial core # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/usb-serial.c # 2004/09/09 11:31:48-07:00 greg@kroah.com +6 -6 # USB: fix usb_unlink_urb() usage in usb-serial core # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 11:29:39-07:00 greg@kroah.com # USB: fix usb_unlink_urb() usage in pl2303 driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/pl2303.c # 2004/09/09 11:28:44-07:00 greg@kroah.com +3 -18 # USB: fix usb_unlink_urb() usage in pl2303 driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/09 10:04:25-07:00 stern@rowland.harvard.edu # [PATCH] USB: Unusual_devs entry for Panasonic cameras # # Thanks to Tom Hughes for jogging my memory about this patch, which has # been sitting here waiting for Greg's return. It adds an unusual_devs.h # entry for the Panasonic DMC-LCx line of cameras, which incorrectly report # the total number of blocks in response to READ CAPACITY rather than the # highest available block number. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/08/23 03:25:19-07:00 stern@rowland.harvard.edu +10 -0 # USB: Unusual_devs entry for Panasonic cameras # # ChangeSet # 2004/09/09 10:04:05-07:00 petkov@uni-muenster.de # [PATCH] USB: fix up usblp usb_unlink_urb() warning # # On Thursday 09 September 2004 08:38, Greg KH wrote: # > On Thu, Sep 09, 2004 at 01:07:05AM -0400, Gene Heskett wrote: # > > Greetings; # > > # > > I just had to reboot back to -mm2 after playing with some printer configs # > > in cups, although the test pages worked, so I'm not sure what this all # > > about, from var log/messages: # > > # > > Sep 8 23:13:42 coyote cups: cupsd -HUP succeeded # > > Sep 8 23:13:43 coyote kernel: usb_unlink_urb() is deprecated for # > > synchronous unlinks. Use usb_kill_urb() Sep 8 23:13:43 coyote kernel: # > > Badness in usb_unlink_urb at drivers/usb/core/urb.c:456 Sep 8 23:13:44 # > > coyote kernel: [] dump_stack+0x1e/0x20 Sep 8 23:13:44 coyote # > > kernel: [] usb_unlink_urb+0x85/0xa0 Sep 8 23:13:44 coyote # > > kernel: [] usblp_unlink_urbs+0x17/0x40 Sep 8 23:13:44 coyote # > > kernel: [] usblp_release+0x38/0x60 Sep 8 23:13:44 coyote # > > kernel: [] __fput+0x12a/0x140 # > > Sep 8 23:13:44 coyote kernel: [] filp_close+0x57/0x80 # > > Sep 8 23:13:44 coyote kernel: [] sys_close+0x61/0x90 # > > Sep 8 23:13:44 coyote kernel: [] sysenter_past_esp+0x52/0x71 # # # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/usblp.c # 2004/09/09 02:24:11-07:00 petkov@uni-muenster.de +2 -2 # USB: fix up usblp usb_unlink_urb() warning # # ChangeSet # 2004/09/09 10:03:34-07:00 stern@rowland.harvard.edu # [PATCH] USB: New submission procedure for unusual_devs.h # # As you requested, this patch updates the documented procedure for # submitting new unusual_devs.h entries. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/09/09 04:50:31-07:00 stern@rowland.harvard.edu +8 -5 # USB: New submission procedure for unusual_devs.h # # ChangeSet # 2004/09/09 10:03:05-07:00 stern@rowland.harvard.edu # [PATCH] USB: Add OTG support to g_file_storage # # This patch adds minimal USB On-The-Go support (mainly just an extra # descriptor) to the File-Storage Gadget. The changes were based on the # additions made to the Gadget Zero driver. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/file_storage.c # 2004/09/09 04:37:43-07:00 stern@rowland.harvard.edu +23 -3 # USB: Add OTG support to g_file_storage # # ChangeSet # 2004/09/09 09:49:54-07:00 greg@kroah.com # USB: make usb_unlink_urb() message only show up if CONFIG_DEBUG_KERNEL is enabled. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/urb.c # 2004/09/09 09:49:03-07:00 greg@kroah.com +3 -1 # USB: make usb_unlink_urb() message only show up if CONFIG_DEBUG_KERNEL is enabled. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/08 12:00:14-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/09/08 12:00:10-07:00 akpm@bix.(none) +0 -0 # Auto merged # # CREDITS # 2004/09/08 12:00:10-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/08 11:59:15-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/fs.h # 2004/09/08 11:59:11-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/08 11:23:33-07:00 mdharm-usb@one-eyed-alien.net # [PATCH] USB Storage: change how INQUIRY is fixed up # # The usb-storage driver 'fixes up' the INQUIRY data returned by a device so # that it reads SCSI rev 2 by intercepting the data in-flight. This was done # to make various SCSI drivers (sd, sr, etc.) work with the device. # # However, this technique also has the unfortunate side-effect that nobody # can see the real rev. -- not even sg users. # # This patch changes that. Now, the SCSI revision is changed in the # slave_configure() function. Thus, the 'real' data is available to anyone # who wants to issue an INQUIRY directly via any means. # # This also simplifies the code somewhat. # # # Signed-off-by: Matthew Dharm # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/scsiglue.c # 2004/09/08 11:23:11-07:00 mdharm-usb@one-eyed-alien.net +17 -0 # [PATCH] USB Storage: change how INQUIRY is fixed up # # The usb-storage driver 'fixes up' the INQUIRY data returned by a device so # that it reads SCSI rev 2 by intercepting the data in-flight. This was done # to make various SCSI drivers (sd, sr, etc.) work with the device. # # However, this technique also has the unfortunate side-effect that nobody # can see the real rev. -- not even sg users. # # This patch changes that. Now, the SCSI revision is changed in the # slave_configure() function. Thus, the 'real' data is available to anyone # who wants to issue an INQUIRY directly via any means. # # This also simplifies the code somewhat. # # # Signed-off-by: Matthew Dharm # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/protocol.c # 2004/09/08 11:23:11-07:00 mdharm-usb@one-eyed-alien.net +0 -49 # [PATCH] USB Storage: change how INQUIRY is fixed up # # The usb-storage driver 'fixes up' the INQUIRY data returned by a device so # that it reads SCSI rev 2 by intercepting the data in-flight. This was done # to make various SCSI drivers (sd, sr, etc.) work with the device. # # However, this technique also has the unfortunate side-effect that nobody # can see the real rev. -- not even sg users. # # This patch changes that. Now, the SCSI revision is changed in the # slave_configure() function. Thus, the 'real' data is available to anyone # who wants to issue an INQUIRY directly via any means. # # This also simplifies the code somewhat. # # # Signed-off-by: Matthew Dharm # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/isd200.c # 2004/09/08 11:23:11-07:00 mdharm-usb@one-eyed-alien.net +0 -6 # [PATCH] USB Storage: change how INQUIRY is fixed up # # The usb-storage driver 'fixes up' the INQUIRY data returned by a device so # that it reads SCSI rev 2 by intercepting the data in-flight. This was done # to make various SCSI drivers (sd, sr, etc.) work with the device. # # However, this technique also has the unfortunate side-effect that nobody # can see the real rev. -- not even sg users. # # This patch changes that. Now, the SCSI revision is changed in the # slave_configure() function. Thus, the 'real' data is available to anyone # who wants to issue an INQUIRY directly via any means. # # This also simplifies the code somewhat. # # # Signed-off-by: Matthew Dharm # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/08 11:22:56-07:00 util@deuroconsult.ro # [PATCH] USB Serial: Correct a use of out of range variable # # Bug found by Coverity: # http://linuxbugs.coverity.com/external/editbugparent.php?viewbugid=2137&checkers%5B%5D=all&status%5B%5D=BUG&status%5B%5D=UNINSPECTED&status%5B%5D=UNKNOWN&status%5B%5D=DON%27T%20CARE&status%5B%5D=PENDING&product%5B%5D=all&component%5B%5D=all&file=&fn=&sortby=reverse_rank&before=&after=&curpage=2&bugid=-1&comment=&reason= # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/usb-serial.c # 2004/09/08 11:22:38-07:00 util@deuroconsult.ro +1 -1 # [PATCH] USB Serial: Correct a use of out of range variable # # Bug found by Coverity: # http://linuxbugs.coverity.com/external/editbugparent.php?viewbugid=2137&checkers%5B%5D=all&status%5B%5D=BUG&status%5B%5D=UNINSPECTED&status%5B%5D=UNKNOWN&status%5B%5D=DON%27T%20CARE&status%5B%5D=PENDING&product%5B%5D=all&component%5B%5D=all&file=&fn=&sortby=reverse_rank&before=&after=&curpage=2&bugid=-1&comment=&reason= # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/08 11:18:37-07:00 akpm@osdl.org # [PATCH] USB: Codemercs IO-Warrior support # # From: Steffen Zieger # # Here is a patch to get the kernel module from Codemerces to work. The module # is available in source for the 2.4 and 2.6 series except the needed changes in # hid-core.c. Codemercs distribute the needed changes as a complete file # (version 2.6.4). This isn't working with 2.6.8.1. # # http://www.codemercs.com # # Signed-off-by: Andrew Morton # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/input/hid-core.c # 2004/09/08 11:17:52-07:00 akpm@osdl.org +11 -0 # [PATCH] USB: Codemercs IO-Warrior support # # From: Steffen Zieger # # Here is a patch to get the kernel module from Codemerces to work. The module # is available in source for the 2.4 and 2.6 series except the needed changes in # hid-core.c. Codemercs distribute the needed changes as a complete file # (version 2.6.4). This isn't working with 2.6.8.1. # # http://www.codemercs.com # # Signed-off-by: Andrew Morton # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/08 11:08:27-07:00 david-b@pacbell.net # [PATCH] USB: EHCI SMP fix # # This addresses an SMP-only issue with the EHCI driver, where only one CPU # should scan the schedule at a time (scanning is not re-entrant) but either # the IRQ handler or a watchdog timer could end up starting it. Many thanks # to Olaf Hering for isolating the failure mode, and testing this fix! # # Once once CPU starts scanning, any other might as well finish right # away. This fix just adds a flag to detect that case. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/ehci.h # 2004/09/02 08:32:30-07:00 david-b@pacbell.net +1 -0 # USB: EHCI SMP fix # # drivers/usb/host/ehci-hcd.c # 2004/09/02 09:05:47-07:00 david-b@pacbell.net +9 -0 # USB: EHCI SMP fix # # ChangeSet # 2004/09/08 11:05:50-07:00 luca.risolia@studio.unibo.it # [PATCH] USB: SN9C10x driver update # # Changes: # # - Add support for SN9C103 based devices. The audio capability is already # supported but not released in this version. I will release # it once someone donates two SN9C103 based devices. # - Implement VIDIOC_G_CTRL for TAS5110C1B and TAS51130D1B # - Replace "SN9C10[12]" strings with "SN9C10x" # - Add red, green, blue gain controls to the SN9C103 # - Memory offsets are now page-aligned # - Fix typos in the documentation # - Documentation updates # - Setting bounds are checked by the core module # - Add exposure control for TAS51130D1B # # Signed-off-by: Luca Risolia # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/sn9c102_tas5130d1b.c # 2004/08/27 08:39:40-07:00 luca.risolia@studio.unibo.it +49 -11 # USB: SN9C10x driver update # # drivers/usb/media/sn9c102_tas5110c1b.c # 2004/08/27 08:39:40-07:00 luca.risolia@studio.unibo.it +34 -11 # USB: SN9C10x driver update # # drivers/usb/media/sn9c102_sensor.h # 2004/08/27 08:38:59-07:00 luca.risolia@studio.unibo.it +42 -16 # USB: SN9C10x driver update # # drivers/usb/media/sn9c102_pas202bcb.c # 2004/08/27 08:38:47-07:00 luca.risolia@studio.unibo.it +6 -6 # USB: SN9C10x driver update # # drivers/usb/media/sn9c102_pas106b.c # 2004/08/27 08:38:47-07:00 luca.risolia@studio.unibo.it +7 -7 # USB: SN9C10x driver update # # drivers/usb/media/sn9c102_core.c # 2004/08/27 08:38:22-07:00 luca.risolia@studio.unibo.it +97 -27 # USB: SN9C10x driver update # # drivers/usb/media/sn9c102.h # 2004/08/27 08:38:30-07:00 luca.risolia@studio.unibo.it +11 -4 # USB: SN9C10x driver update # # drivers/usb/media/Kconfig # 2004/08/27 08:43:31-07:00 luca.risolia@studio.unibo.it +3 -3 # USB: SN9C10x driver update # # MAINTAINERS # 2004/08/27 08:41:49-07:00 luca.risolia@studio.unibo.it +1 -1 # USB: SN9C10x driver update # # Documentation/usb/sn9c102.txt # 2004/08/27 23:06:47-07:00 luca.risolia@studio.unibo.it +66 -34 # USB: SN9C10x driver update # # CREDITS # 2004/08/27 08:42:17-07:00 luca.risolia@studio.unibo.it +1 -1 # USB: SN9C10x driver update # # ChangeSet # 2004/09/08 09:44:25-07:00 stern@rowland.harvard.edu # [PATCH] USB: Internal port numbers start at 0 # # This patch changes a couple of new routines in the suspend/resume code. # Internally they use port numbers starting from 1, unlike every other # routine in the hub driver. This changes the port numbers to origin-0, for # consistency's sake. Of course, messages sent to the system log will # continue to start counting from 1. # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/09/08 09:41:15-07:00 stern@rowland.harvard.edu +14 -14 # USB: Internal port numbers start at 0 # # ChangeSet # 2004/09/07 21:13:32-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/09/07 21:13:28-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/06 17:32:27-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/media/dabusb.c # 2004/09/06 17:32:23-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/usb-midi.c # 2004/09/06 17:32:23-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/audio.c # 2004/09/06 17:32:23-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/05 05:53:15+02:00 stern@rowland.harvard.edu # [PATCH] USB: Centralize logical disconnects in the hub driver # # This patch takes some code that was only used in one place in the hub # driver, and packages it up into a subroutine which is now called from # several places. The routine does a logical disconnect -- for example, # after issuing a port reset, if the device descriptors have changed # (because of a firmware update perhaps) we logically disconnect the old # device structure and create a new one. Or if a resume fails for any # reason we can do the same thing. # # This touches some of David Brownell's suspend/resume code, obviously. # (It also fixes a couple of small errors in there.) He has said it looks # okay. # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/08/18 17:44:48+02:00 stern@rowland.harvard.edu +36 -23 # USB: Centralize logical disconnects in the hub driver # # ChangeSet # 2004/09/05 05:23:24+02:00 janitor@sternwelten.at # [PATCH] list_for_each_entry: drivers-usb-class-audio.c # # Make code more readable with list_for_each_entry. # Compile tested. # # # Signed-off-by: Domen Puncer # Signed-off-by: Maximilian Attems # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/audio.c # 2004/09/01 19:34:25+02:00 janitor@sternwelten.at +6 -15 # list_for_each_entry: drivers-usb-class-audio.c # # ChangeSet # 2004/09/05 05:22:50+02:00 janitor@sternwelten.at # [PATCH] list_for_each_entry: drivers-usb-class-usb-midi.c # # Make code more readable with list_for_each_entry. # Compile tested. # # # Signed-off-by: Domen Puncer # Signed-off-by: Maximilian Attems # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/usb-midi.c # 2004/09/01 19:34:26+02:00 janitor@sternwelten.at +3 -8 # list_for_each_entry: drivers-usb-class-usb-midi.c # # ChangeSet # 2004/09/05 05:22:18+02:00 janitor@sternwelten.at # [PATCH] list_for_each_entry: drivers-usb-media-dabusb.c # # Use list_for_each_entry to make code more readable. # Compile tested. # # Signed-off-by: Domen Puncer # Signed-off-by: Maximilian Attems # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/dabusb.c # 2004/09/01 19:34:30+02:00 janitor@sternwelten.at +1 -4 # list_for_each_entry: drivers-usb-media-dabusb.c # # ChangeSet # 2004/09/05 05:21:45+02:00 janitor@sternwelten.at # [PATCH] list_for_each_entry: drivers-usb-host-hc_sl811.c # # Make code more readable with list_for_each_entry_safe. # (Is this a non i386? I can't compile it.) # # Signed-off-by: Domen Puncer # Signed-off-by: Maximilian Attems # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/hc_sl811.c # 2004/09/01 19:34:32+02:00 janitor@sternwelten.at +2 -6 # list_for_each_entry: drivers-usb-host-hc_sl811.c # # ChangeSet # 2004/09/05 05:21:11+02:00 janitor@sternwelten.at # [PATCH] list_for_each_entry: drivers-usb-serial-ipaq.c # # Use list_for_each_entry_safe to make code more readable. # Compile tested. # # Signed-off-by: Domen Puncer # Signed-off-by: Maximilian Attems # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/ipaq.c # 2004/09/01 19:34:33+02:00 janitor@sternwelten.at +5 -14 # list_for_each_entry: drivers-usb-serial-ipaq.c # # ChangeSet # 2004/09/05 05:04:18+02:00 janitor@sternwelten.at # [PATCH] list_for_each_entry: drivers-usb-core-devices.c # # Make code more readable with list_for_each_entry. # Compile tested. # # Patch incremental on the list_for_each() change. # # Signed-off-by: Domen Puncer # Signed-off-by: Maximilian Attems # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/devices.c # 2004/09/01 19:34:25+02:00 janitor@sternwelten.at +2 -6 # list_for_each_entry: drivers-usb-core-devices.c # # ChangeSet # 2004/09/05 04:53:18+02:00 greg@kroah.com # USB: remove usbdevfs filesystem name, usbfs is the proper one to use. # # This has been publicised for years now, and the usvfs name will work just # fine with a 2.4 kernel, so we are not breaking backwards compatibility. # # Signed-off-by: Greg Kroah-Hartman # # include/linux/usbdevice_fs.h # 2004/09/05 04:52:09+02:00 greg@kroah.com +0 -10 # USB: remove usbdevfs filesystem name, usbfs is the proper one to use. # # This has been publicised for years now, and the usvfs name will work just # fine with a 2.4 kernel, so we are not breaking backwards compatibility. # # Signed-off-by: Greg Kroah-Hartman # # include/linux/usb.h # 2004/09/05 04:52:09+02:00 greg@kroah.com +0 -2 # USB: remove usbdevfs filesystem name, usbfs is the proper one to use. # # This has been publicised for years now, and the usvfs name will work just # fine with a 2.4 kernel, so we are not breaking backwards compatibility. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/usb.h # 2004/09/05 04:52:09+02:00 greg@kroah.com +6 -0 # USB: remove usbdevfs filesystem name, usbfs is the proper one to use. # # This has been publicised for years now, and the usvfs name will work just # fine with a 2.4 kernel, so we are not breaking backwards compatibility. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/inode.c # 2004/09/05 04:52:09+02:00 greg@kroah.com +13 -108 # USB: remove usbdevfs filesystem name, usbfs is the proper one to use. # # This has been publicised for years now, and the usvfs name will work just # fine with a 2.4 kernel, so we are not breaking backwards compatibility. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/devio.c # 2004/09/05 04:52:09+02:00 greg@kroah.com +5 -5 # USB: remove usbdevfs filesystem name, usbfs is the proper one to use. # # This has been publicised for years now, and the usvfs name will work just # fine with a 2.4 kernel, so we are not breaking backwards compatibility. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/devices.c # 2004/09/05 04:52:09+02:00 greg@kroah.com +2 -2 # USB: remove usbdevfs filesystem name, usbfs is the proper one to use. # # This has been publicised for years now, and the usvfs name will work just # fine with a 2.4 kernel, so we are not breaking backwards compatibility. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/09/03 14:25:14-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/misc/tiglusb.c # 2004/09/03 14:25:09-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/media/dabusb.c # 2004/09/03 14:25:09-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/03 14:24:12-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/09/03 14:24:08-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/03 14:29:45+02:00 alborchers@steinerpoint.com # [PATCH] USB: close waits for drain in pl2303 # # Here is an additional patch for pl2303 in 2.6.9-rc1, # to be applied after my previous circular buffer patch. # This patch waits for the buffer to drain on close and # then clears the buffer. In addition to the obvious # features, this also fixes a bug where closing a port # with a full buffer would accidentally disable writes # when the port was re-opened. # # The original pl2303 could lose data that was still going # out the port on close, and even this patch only solves # the problem completely for data rates of 1200 bps and # above. # # Waiting for data to drain from the circular buffer is # easy, but the problem is waiting for data to drain from # the 256 byte hardware buffer on the device. I don't know # how much data is in the hardware buffer, so I just wait # long enough for a potentially full hardware buffer to # drain, but I don't want to wait that long for low data # rates if the buffer isn't full. There is probably some # way to query the pl2303 to find out how much data is in # its hardware buffer, maybe snooping would reveal that. # # - Added a wait for data to drain from the driver # write buffer when closing. # # - Added a wait for the data to drain from the # device hardware buffer when closing. # # - Cleared the driver write buffer when closing. # # Signed-off-by: Al Borchers # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/pl2303.c # 2004/08/30 02:27:08+02:00 alborchers@steinerpoint.com +58 -4 # USB: close waits for drain in pl2303 # # ChangeSet # 2004/09/03 14:29:06+02:00 alborchers@steinerpoint.com # [PATCH] USB: circular buffer for pl2303 # # Here is the patch adding a circular buffer to pl2303 # updated to 2.6.9-rc1. Phil and I both tested this. # (Phil tested a slightly different earlier version.) # # This fixes the carriage return newline problem Olaf # Hering reported and helps Phil with hotsyncing his # phone. This patch also fixes a problem that would # sometimes leave a pl2303 port unable to send data, # reporting "already writing", after closing the port # while writing was in progress. This happened about # 1/3 of the time in my tests with the stock 2.6.9-rc1 # pl2303 driver. # # # - Added a circular write buffer, protected by the # existing spin lock. # # - Write_room and chars_in_buffer now report room and # chars in the circular buffer. # # - Added a "bounce buffer" when transfering data from # user space to the circular buffer--needed for locking. # # - Replaced (urb->status != -EINPROGRESS) with a private # write_urb_in_use flag protected by the existing spin # lock. Clear this flag when the urb is unlinked. # # - Free memory on failed startup. # # - These changes make ONLCR mapping work and fix a bug # that would sometimes leave the port unable to write, # reporting "already writing", after closing the port # while writing was in progress. # # Signed-off-by: Al Borchers # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/pl2303.c # 2004/08/28 22:44:17+02:00 alborchers@steinerpoint.com +324 -25 # USB: circular buffer for pl2303 # # ChangeSet # 2004/09/03 13:33:55+02:00 stern@rowland.harvard.edu # [PATCH] USB: Nag message for usb_kill_urb # # This patch is only for nuisance value. It puts a nag message in the # system log every time usb_unlink_urb() is called for synchronous # unlinking. My hope is this will speed the process of converting drivers # to use usb_kill_urb(). # # Don't apply this if it generates too much noise, but otherwise go ahead. # A little prodding never hurt anyone. # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/urb.c # 2004/08/30 13:39:08+02:00 stern@rowland.harvard.edu +3 -0 # USB: Nag message for usb_kill_urb # # ChangeSet # 2004/09/03 13:33:20+02:00 janitor@sternwelten.at # [PATCH] usb/dabusb: insert set_current_state() before schedule_timeout() # # After discussing this patch with Mark Hollomon, I think it is much safer # / better to leave the conditional check within the while loop. This way # the mutex state is as expected and maintainability is not compromised. # The previous patch should not be applied. # # # Description: Inserts appropriate set_current_state() call so that # schedule_timeout() functions as expected. # # Signed-off-by: Nishanth Aravamudan # Signed-off-by: Maximilian Attems # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/dabusb.c # 2004/09/01 19:35:55+02:00 janitor@sternwelten.at +1 -0 # usb/dabusb: insert set_current_state() before schedule_timeout() # # ChangeSet # 2004/09/03 13:32:49+02:00 janitor@sternwelten.at # [PATCH] usb/tiglusb: insert set_current_state() before schedule_timeout() # # Insert set_current_state() so schedule_timeout() functions as expected. # # Signed-off-by: Nishanth Aravamudan # Signed-off-by: Maximilian Attems # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/misc/tiglusb.c # 2004/09/01 19:35:55+02:00 janitor@sternwelten.at +1 -0 # usb/tiglusb: insert set_current_state() before schedule_timeout() # # ChangeSet # 2004/09/03 13:32:12+02:00 bjorn.helgaas@hp.com # [PATCH] HCD PCI probe: print actual, not ioremapped, address # # I think the USB HCD should print the actual PCI memory address, not the # ioremapped address. AFAIK, there's no reason the ioremapped address has # to have any fixed relationship to the actual address. Also, this makes # it match what's in /proc/iomem. I also added a leading "0x". Example # from ia64: # # - ehci_hcd 0000:00:01.2: irq 52, pci mem c000000080021000 # + ehci_hcd 0000:00:01.2: irq 52, pci mem 0x80021000 # # # # USB HCD: print actual PCI mem address, not the ioremapped value. # # Signed-off-by: Bjorn Helgaas # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hcd-pci.c # 2004/09/01 18:42:03+02:00 bjorn.helgaas@hp.com +2 -2 # HCD PCI probe: print actual, not ioremapped, address # # ChangeSet # 2004/09/03 13:31:41+02:00 stern@rowland.harvard.edu # [PATCH] USB: Remove inappropriate unusual_devs.h entry # # A couple of months ago you applied a patch from Torsten Scherer to create # a new unusual_devs.h entry. In further discussions with him I learned # that the entry wasn't needed to access the device; the only reason for it # was as a workaround for some old, buggy hotplug program on his system. # # Now Evan Fletcher reports that the entry actively prevents him from using # his device. For me that's the last straw, so here's a patch to remove the # entry. Torsten should be okay if he simply upgrades his hotplug package # or removes the buggy program. # # On Mon, 30 Aug 2004, Evan Fletcher wrote: # > Hi list, # > # > I have a Bytecc 5.25" External Enclosure, model ME-320U2F, that has # > both USB 2.0 and Firewire connections # > (http://www.byteccusa.com/product/enclosure/ME-320.htm). It used to # > work fine on earlier Linux 2.6 kernels, but stopped working a few # > revisions ago. # > # > I tracked the problem down to an entry in unusual_devs.h: # > # > /* : I don't know the name of the bridge # > * manufacturer, but I've got an external USB drive by the Revoltec company # > * that needs this. otherwise the drive is recognized as /dev/sda, but any # > * access to it blocks indefinitely. # > */ # > UNUSUAL_DEV( 0x0402, 0x5621, 0x0103, 0x0103, # > "Revoltec", # > "USB/IDE Bridge (ATA/ATAPI)", # > US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), # # <...> # > So, is there some way that this entry can be modified so that my DVD+R # > works properly, and Mr. Scherer can still use his Revoltec external # > disk? # > # > Thank you, # > Evan Fletcher # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/08/30 16:12:17+02:00 stern@rowland.harvard.edu +0 -10 # USB: Remove inappropriate unusual_devs.h entry # # ChangeSet # 2004/09/03 13:31:05+02:00 akpm@osdl.org # [PATCH] USB: "Lost sync on frames" error in konicawc module # # From: # # http://bugme.osdl.org/show_bug.cgi?id=3286 # # The kernel keeps printing "Lost sync on frames" error messages as soon as a # program tries to access the webcam. No video data can be retrieved from # the webcam. # # The following patch seems enough to solve the problem. (just inverting the # order at which the old and new data blocks are sent to the user). # # Signed-off-by: Andrew Morton # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/konicawc.c # 2004/08/28 08:58:21+02:00 akpm@osdl.org +1 -1 # USB: "Lost sync on frames" error in konicawc module # # ChangeSet # 2004/09/03 13:30:33+02:00 abbotti@mev.co.uk # [PATCH] USB: Add B&B Electronics VID/PIDs to ftdi_sio # # This patch adds VID/PIDs for a few FTDI-based USB serial devices # from B&B Electronics to the ftdi_sio driver. # # # Signed-off-by: Ian Abbott # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/ftdi_sio.h # 2004/09/01 14:04:37+02:00 abbotti@mev.co.uk +8 -0 # USB: Add B&B Electronics VID/PIDs to ftdi_sio # # drivers/usb/serial/ftdi_sio.c # 2004/09/01 14:04:37+02:00 abbotti@mev.co.uk +9 -0 # USB: Add B&B Electronics VID/PIDs to ftdi_sio # # ChangeSet # 2004/09/03 13:29:55+02:00 david-b@pacbell.net # [PATCH] USB: OHCI init cleanups # # This ought to fix the NS9750 init issue, and make the AMD756 case # at least somewhat better. It makes the init go "by the book" in more # ways, and formalizes one quirk. # # Various OHCI init/reset cleanups for different silicion environments: # # - Reset a bit more "by the book". # # * Define a new quirk flag for the SiS and OPTi problem seen earlier. # Since 2.4 we've always worked around that quirk, even though we've # not seen that on other chips; but it's "wrong" and doesn't work on # some chips (notably NetSilicon NS9750). # # The quirk still seems to be needed for SiS, but either this test # machine is too fast for the OPTi problem to show up, or the frame # timing setup problem there came from a now-fixed bug. # # * Look at the HC state before resetting it; depending on whether # it was previously owned by BIOS, SMM, an OS, or nobody, different # USB signaling (and timings) might be needed. # # * Re-init the frame timings right after soft reset, rather than # later (potentially too much later). # # * Restore a reset in the PCI startup code, so this logic more closely # resembles the non-PCI paths (future code sharing). It also makes it # easier to guarantee a 1-millisecond ceiling between reset and "go". # # An earlier reset is being done to help workaround BIOS-related # problems on some boards, but we may need an even earlier one # (as a PCI quirk, before IRQs get reconfigured). # # - Add an explicit #define to disable the BIOS/SMM handoff; it's # not just HPPA, many embedded chips don't expect BIOS either. # # - There are reports of AMD 756 machines disliking the OHCI suspend # patch of a few months back. Erratum #10 partly explains that, so # now root hubs won't autosuspend on those Slot-A era chips. # # - Other minor fixes # # * We've got lots of non-PCI OHCI now too, so comments shouldn't # be assuming all-is-pci! # # * Hey, it's unsafe to call hc_reset() in IRQ (after unrecoverable # error); so just force a soft reset, don't do the whole thing. # # Tested on half a dozen different OHCI versions, but maybe some other # versions of OHCI will be sensitive to one of these changes. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/ohci.h # 2004/09/02 18:39:10+02:00 david-b@pacbell.net +1 -0 # USB: OHCI init cleanups # # drivers/usb/host/ohci-pci.c # 2004/09/02 18:39:10+02:00 david-b@pacbell.net +18 -0 # USB: OHCI init cleanups # # drivers/usb/host/ohci-hcd.c # 2004/09/02 18:39:09+02:00 david-b@pacbell.net +52 -22 # USB: OHCI init cleanups # # ChangeSet # 2004/09/03 13:29:11+02:00 alborchers@steinerpoint.com # [PATCH] USB: corrected digi_acceleport 2.6.9-rc1 fix for hang on disconnect # # - Fixed hang on disconnect in digi_acceleport USB serial driver. # See http://bugme.osdl.org/show_bug.cgi?id=2459. Close after # disconnect no longer tries to communicate with the device. # # Signed-off-by: Al Borchers # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/digi_acceleport.c # 2004/09/03 10:43:16+02:00 alborchers@steinerpoint.com +6 -1 # USB: corrected digi_acceleport 2.6.9-rc1 fix for hang on disconnect # # ChangeSet # 2004/09/03 13:28:34+02:00 oliver@neukum.org # [PATCH] USB: switching microtek to usb_kill_urb # # Am Dienstag, 31. August 2004 17:41 schrieb Alan Stern: # > On Tue, 31 Aug 2004, Oliver Neukum wrote: # > # > Alan Stern # > # > # > # > # > > @@ -822,9 +822,8 @@ # > > # > > usb_set_intfdata(intf, NULL); # > > # > > + usb_kill_urb(desc->urb); # > > scsi_remove_host(desc->host); # > > - usb_unlink_urb(desc->urb); # > > - scsi_host_put(desc->host); # > > # > > usb_free_urb(desc->urb); # > > kfree(desc); # > # > I think you still need the scsi_host_put(), to account for the fact that # > scsi_host_alloc() sets the refcount to 1 initially. # # Right you are. Greg, please also apply this one. # # Signed-Off-By: Oliver Neukum # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/image/microtek.c # 2004/08/31 21:10:57+02:00 oliver@neukum.org +1 -0 # USB: switching microtek to usb_kill_urb # # ChangeSet # 2004/09/03 13:28:02+02:00 petkan@nucleusys.com # [PATCH] USB: small rtl8150 patch # # this one make rtl8150 auto-load its register values at reset. Not doing # so is known to cause improper setup when the device is being reseted # frequently. # # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/rtl8150.c # 2004/08/27 10:50:54+02:00 petkan@nucleusys.com +2 -2 # USB: small rtl8150 patch # # ChangeSet # 2004/09/03 13:27:27+02:00 wouter-kernel@fort-knox.rave.org # [PATCH] USB: usb audio is for oss only # # Doh. Fixed. # # drivers/usb/class/Kconfig # 2004/08/27 16:45:25+02:00 wouter-kernel@fort-knox.rave.org +2 -1 # USB: usb audio is for oss only # # ChangeSet # 2004/09/03 13:26:56+02:00 oliver@neukum.org # [PATCH] USB: correct interrupt interval for kaweth # # - overriding the media check interrupt interval # # Signed-Off-By: Oliver Neukum # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/kaweth.c # 2004/08/29 15:08:48+02:00 oliver@neukum.org +1 -1 # USB: correct interrupt interval for kaweth # # ChangeSet # 2004/09/03 13:26:21+02:00 stern@rowland.harvard.edu # [PATCH] USB: Suspend/resume/wakeup support for UHCI root hub ports # # This patch adds support for suspending, resuming, and remote wakeup # detection on root hub ports to the UHCI driver. It doesn't add support # for suspending or resuming the root hub itself (beyond what's already # there) -- that will require considerably more work. But at least devices # plugged directly into the computer will interact nicely with power # management. # # Of lesser importance, the patch also simplifies some constant expressions. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/uhci-hub.c # 2004/08/27 18:33:25+02:00 stern@rowland.harvard.edu +65 -26 # USB: Suspend/resume/wakeup support for UHCI root hub ports # # drivers/usb/host/uhci-hcd.h # 2004/08/27 18:33:25+02:00 stern@rowland.harvard.edu +6 -0 # USB: Suspend/resume/wakeup support for UHCI root hub ports # # drivers/usb/host/uhci-hcd.c # 2004/08/27 18:33:25+02:00 stern@rowland.harvard.edu +2 -0 # USB: Suspend/resume/wakeup support for UHCI root hub ports # # ChangeSet # 2004/09/03 13:25:50+02:00 stern@rowland.harvard.edu # [PATCH] USB: Make usbcore use usb_kill_urb() # # This patch changes the only places in usbcore where usb_unlink_urb() is # still used for synchronous unlinking; now they will use usb_kill_urb(). # As it turns out, there were only a couple of changes needed. # # This still leaves all the drivers to audit! # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/devio.c # 2004/08/30 13:34:24+02:00 stern@rowland.harvard.edu +4 -3 # USB: Make usbcore use usb_kill_urb() # # ChangeSet # 2004/09/03 13:25:14+02:00 zaitcev@redhat.com # [PATCH] USB: Fixes for ub in 2.4.9-rc1 from Oliver and Pat # # - Set the allocation size in REQUEST SENSE (Pat LaVarre) # - Move add_timer invocations to safer places (Oliver Neukum) # # # Signed-off-by: Greg Kroah-Hartman # # drivers/block/ub.c # 2004/08/27 21:24:25+02:00 zaitcev@redhat.com +32 -27 # USB: Fixes for ub in 2.4.9-rc1 from Oliver and Pat # # ChangeSet # 2004/09/03 13:24:41+02:00 oliver@neukum.org # [PATCH] USB: switching microtek to usb_kill_urb # # this reworks the microtek driver's disconnect method, now that # usb_kill_urb is available. # # Signed-Off-By: Oliver Neukum # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/image/microtek.c # 2004/08/30 23:10:24+02:00 oliver@neukum.org +2 -3 # USB: switching microtek to usb_kill_urb # # ChangeSet # 2004/09/03 13:24:05+02:00 oliver@neukum.org # [PATCH] USB: update of help text for hpusbscsi # # Signed-Off-By: Oliver Neukum # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/image/Kconfig # 2004/08/30 21:05:25+02:00 oliver@neukum.org +4 -3 # USB: update of help text for hpusbscsi # # ChangeSet # 2004/08/31 14:05:55-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/08/31 14:05:51-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/28 16:26:13-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/08/28 16:26:10-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/27 23:57:59-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/gadget/inode.c # 2004/08/27 23:57:54-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/08/27 23:57:54-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/27 14:14:37-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/fs.h # 2004/08/27 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/08/27 14:14:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/26 20:00:22-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/gadget/inode.c # 2004/08/26 20:00:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/message.c # 2004/08/26 20:00:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/25 19:43:53-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/misc/auerswald.c # 2004/08/25 19:43:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/gadget/inode.c # 2004/08/25 19:43:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/message.c # 2004/08/25 19:43:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/08/25 19:43:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/24 17:51:22-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/misc/legousbtower.c # 2004/08/24 17:51:16-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/24 17:50:09-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/fs.h # 2004/08/24 17:50:05-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/08/24 17:50:05-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/23 17:04:36-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/fs.h # 2004/08/23 17:04:32-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/misc/auerswald.c # 2004/08/23 17:04:32-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/media/dabusb.c # 2004/08/23 17:04:32-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/block/Kconfig # 2004/08/23 17:04:32-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/08/23 17:04:32-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/23 14:47:21-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # include/linux/fs.h # 2004/08/23 14:47:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/misc/tiglusb.c # 2004/08/23 14:47:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/misc/legousbtower.c # 2004/08/23 14:47:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/misc/auerswald.c # 2004/08/23 14:47:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/media/ov511.c # 2004/08/23 14:47:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/media/dabusb.c # 2004/08/23 14:47:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/usb-midi.c # 2004/08/23 14:47:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/audio.c # 2004/08/23 14:47:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/block/Kconfig # 2004/08/23 14:47:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/08/23 14:47:17-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/23 14:46:26-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/fs.h # 2004/08/23 14:46:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/misc/auerswald.c # 2004/08/23 14:46:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/media/dabusb.c # 2004/08/23 14:46:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/block/Kconfig # 2004/08/23 14:46:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/08/23 14:46:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/22 21:47:19-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/08/22 21:47:15-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/15 01:35:04-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/fs.h # 2004/08/15 01:35:01-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/08 14:55:28-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/misc/tiglusb.c # 2004/08/08 14:55:24-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/misc/legousbtower.c # 2004/08/08 14:55:24-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/misc/auerswald.c # 2004/08/08 14:55:24-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/media/dabusb.c # 2004/08/08 14:55:24-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/usb-midi.c # 2004/08/08 14:55:24-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/audio.c # 2004/08/08 14:55:24-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/08 02:33:24-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/fs.h # 2004/08/08 02:33:20-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/07 19:17:31-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/fs.h # 2004/08/07 19:17:28-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/07 14:49:01-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/fs.h # 2004/08/07 14:48:57-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/06 16:01:52-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/block/Kconfig # 2004/08/06 16:01:49-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/06 16:01:00-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/fs.h # 2004/08/06 16:00:56-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/05 20:16:41-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # include/linux/fs.h # 2004/08/05 20:16:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/08/05 20:16:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/05 13:06:30-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/media/ov511.c # 2004/08/05 13:06:26-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/04 03:03:16-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/misc/tiglusb.c # 2004/08/04 03:03:12-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/media/ov511.c # 2004/08/04 03:03:12-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/02 13:35:47-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/08/02 13:35:43-07:00 akpm@bix.(none) +0 -0 # Auto merged # diff -Nru a/CREDITS b/CREDITS --- a/CREDITS 2004-09-12 22:25:42 -07:00 +++ b/CREDITS 2004-09-12 22:25:43 -07:00 @@ -2763,7 +2763,7 @@ E: luca.risolia@studio.unibo.it P: 1024D/FCE635A4 88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4 D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chips -D: V4L2 driver for SN9C10[12] PC Camera Controllers +D: V4L2 driver for SN9C10x PC Camera Controllers S: Via Liberta' 41/A S: Osio Sotto, 24046, Bergamo S: Italy diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt --- a/Documentation/kernel-parameters.txt 2004-09-12 22:25:43 -07:00 +++ b/Documentation/kernel-parameters.txt 2004-09-12 22:25:43 -07:00 @@ -1270,6 +1270,8 @@ uart6850= [HW,OSS] Format: , + + usb-handoff [HW] Enable early USB BIOS -> OS handoff video= [FB] Frame buffer configuration See Documentation/fb/modedb.txt. diff -Nru a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt --- a/Documentation/usb/sn9c102.txt 2004-09-12 22:25:43 -07:00 +++ b/Documentation/usb/sn9c102.txt 2004-09-12 22:25:43 -07:00 @@ -1,7 +1,7 @@ - SN9C10[12] PC Camera Controllers + SN9C10x PC Camera Controllers Driver for Linux - ================================ + ============================= - Documentation - @@ -49,22 +49,23 @@ 3. Overview =========== -This driver attempts to support the video streaming capabilities of the devices -mounting the SONiX SN9C101 or SONiX SN9C102 PC Camera Controllers. +This driver attempts to support the video and audio streaming capabilities of +the devices mounting the SONiX SN9C101, SN9C102 and SN9C103 (or SUI-102) PC +Camera Controllers. - It's worth to note that SONiX has never collaborated with me during the -development of this project, despite of several requests for enough detailed +development of this project, despite several requests for enough detailed specifications of the register tables, compression engine and video data format of the above chips - Up to 64 cameras can be handled at the same time. They can be connected and disconnected from the host many times without turning off the computer, if -your system supports the hotplug facility. +your system supports hotplugging. The driver relies on the Video4Linux2 and USB core modules. It has been designed to run properly on SMP systems as well. -The latest version of the SN9C10[12] driver can be found at the following URL: +The latest version of the SN9C10x driver can be found at the following URL: http://go.lamarinapunto.com/ @@ -150,17 +151,20 @@ 7. Optional device control through "sysfs" ========================================== -It is possible to read and write both the SN9C10[12] and the image sensor +It is possible to read and write both the SN9C10x and the image sensor registers by using the "sysfs" filesystem interface. -Every time a supported device is recognized, a read-only file named "green" is +Every time a supported device is recognized, a write-only file named "green" is created in the /sys/class/video4linux/videoX directory. You can set the green channel's gain by writing the desired value to it. The value may range from 0 -to 15. +to 15 for SN9C101 or SN9C102 bridges, from 0 to 127 for SN9C103 bridges. +Similarly, only for SN9C103 controllers, blue and red gain control files are +available in the same directory, for which accepted values may range from 0 to +127. There are other four entries in the directory above for each registered camera: "reg", "val", "i2c_reg" and "i2c_val". The first two files control the -SN9C10[12] bridge, while the other two control the sensor chip. "reg" and +SN9C10x bridge, while the other two control the sensor chip. "reg" and "i2c_reg" hold the values of the current register index where the following reading/writing operations are addressed at through "val" and "i2c_val". Their use is not intended for end-users, unless you know what you are doing. Note @@ -169,19 +173,19 @@ root before writing to them. As an example, suppose we were to want to read the value contained in the -register number 1 of the sensor register table - which usually is the product +register number 1 of the sensor register table - which is usually the product identifier - of the camera registered as "/dev/video0": [root@localhost #] cd /sys/class/video4linux/video0 [root@localhost #] echo 1 > i2c_reg [root@localhost #] cat i2c_val -Now let's set the green gain's register of the SN9C10[12] chip to 2: +Now let's set the green gain's register of the SN9C10x chip to 2: [root@localhost #] echo 0x11 > reg [root@localhost #] echo 2 > val -Note that the SN9C10[12] always returns 0 when some of its registers are read. +Note that the SN9C10x always returns 0 when some of its registers are read. To avoid race conditions, all the I/O accesses to the files are serialized. @@ -192,25 +196,52 @@ From the point of view of a driver, what unambiguously identify a device are its vendor and product USB identifiers. Below is a list of known identifiers of -devices mounting the SN9C10[12] PC camera controllers: +devices mounting the SN9C10x PC camera controllers: Vendor ID Product ID --------- ---------- -0xc45 0x6001 -0xc45 0x6005 -0xc45 0x6009 -0xc45 0x600d -0xc45 0x6024 -0xc45 0x6025 -0xc45 0x6028 -0xc45 0x6029 -0xc45 0x602a -0xc45 0x602c -0xc45 0x6030 +0x0c45 0x6001 +0x0c45 0x6005 +0x0c45 0x6009 +0x0c45 0x600d +0x0c45 0x6024 +0x0c45 0x6025 +0x0c45 0x6028 +0x0c45 0x6029 +0x0c45 0x602a +0x0c45 0x602b +0x0c45 0x602c +0x0c45 0x6030 +0x0c45 0x6080 +0x0c45 0x6082 +0x0c45 0x6083 +0x0c45 0x6088 +0x0c45 0x608a +0x0c45 0x608b +0x0c45 0x608c +0x0c45 0x608e +0x0c45 0x608f +0x0c45 0x60a0 +0x0c45 0x60a2 +0x0c45 0x60a3 +0x0c45 0x60a8 +0x0c45 0x60aa +0x0c45 0x60ab +0x0c45 0x60ac +0x0c45 0x60ae +0x0c45 0x60af +0x0c45 0x60b0 +0x0c45 0x60b2 +0x0c45 0x60b3 +0x0c45 0x60b8 +0x0c45 0x60ba +0x0c45 0x60bb +0x0c45 0x60bc +0x0c45 0x60be The list above does NOT imply that all those devices work with this driver: up -until now only the ones that mount the following image sensors are supported. -Kernel messages will always tell you whether this is the case: +until now only the ones that mount the following image sensors are supported; +kernel messages will always tell you whether this is the case: Model Manufacturer ----- ------------ @@ -224,7 +255,7 @@ ProductID identifiers to the sn9c102_id_table[] in the file "sn9c102_sensor.h"; then compile, load the module again and look at the kernel output. If this works, please send an email to me reporting the kernel messages, so -that I will add a new entry in the list of supported devices. +that I can add a new entry in the list of supported devices. Donations of new models for further testing and support would be much appreciated. I won't add official support for hardware that I don't actually @@ -238,8 +269,8 @@ (documentation is included there). As an example, have a look at the code in "sn9c102_pas106b.c", which uses the mentioned interface. -At the moment, not yet supported image sensors are: HV7131[D|E1] (VGA), -MI03 (VGA), OV7620 (VGA). +At the moment, possible unsupported image sensors are: HV7131x series (VGA), +MI03x series (VGA), OV7620 (VGA), OV7630 (VGA), CIS-VF10 (VGA). 10. Notes for V4L2 application developers @@ -254,12 +285,13 @@ - previously mapped buffer memory must always be unmapped before calling any of the "VIDIOC_S_CROP", "VIDIOC_TRY_FMT" and "VIDIOC_S_FMT" ioctl's. The same number of buffers as before will be allocated again to match the size of the -new video frames, so you have to map them again before any I/O attempts. +new video frames, so you have to map the buffers again before any I/O attempts +on them. Consistently with the hardware limits, this driver also supports image downscaling with arbitrary scaling factors from 1, 2 and 4 in both directions. -However the V4L2 API specifications don't correctly define how the scaling -factor can be choosen arbitrarily by the "negotiation" of the "source" and +However, the V4L2 API specifications don't correctly define how the scaling +factor can be chosen arbitrarily by the "negotiation" of the "source" and "target" rectangles. To work around this flaw, we have added the convention that, during the negotiation, whenever the "VIDIOC_S_CROP" ioctl is issued, the scaling factor is restored to 1. diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS 2004-09-12 22:25:42 -07:00 +++ b/MAINTAINERS 2004-09-12 22:25:42 -07:00 @@ -947,7 +947,7 @@ HPUSBSCSI P: Oliver Neukum -M: drivers@neukum.org +M: oliver@neukum.name S: Maintained I2C AND SENSORS DRIVERS @@ -1428,7 +1428,7 @@ MICROTEK X6 SCANNER P: Oliver Neukum -M: drivers@neukum.org +M: oliver@neukum.name S: Maintained MIPS @@ -2192,8 +2192,8 @@ S: Maintained USB ACM DRIVER -P: Vojtech Pavlik -M: vojtech@suse.cz +P: Oliver Neukum +M: oliver@neukum.name L: linux-usb-users@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net S: Maintained @@ -2237,7 +2237,7 @@ USB KAWASAKI LSI DRIVER P: Oliver Neukum -M: drivers@neukum.org +M: oliver@neukum.name L: linux-usb-users@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net S: Maintained @@ -2354,7 +2354,7 @@ W: http://www.connecttech.com S: Supported -USB SN9C10[12] DRIVER +USB SN9C10x DRIVER P: Luca Risolia M: luca.risolia@studio.unibo.it L: linux-usb-devel@lists.sourceforge.net diff -Nru a/drivers/block/ub.c b/drivers/block/ub.c --- a/drivers/block/ub.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/block/ub.c 2004-09-12 22:25:43 -07:00 @@ -786,17 +786,16 @@ sc->work_urb.error_count = 0; sc->work_urb.status = 0; - sc->work_timer.expires = jiffies + UB_URB_TIMEOUT; - add_timer(&sc->work_timer); - if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { /* XXX Clear stalls */ printk("ub: cmd #%d start failed (%d)\n", cmd->tag, rc); /* P3 */ - del_timer(&sc->work_timer); ub_complete(&sc->work_done); return rc; } + sc->work_timer.expires = jiffies + UB_URB_TIMEOUT; + add_timer(&sc->work_timer); + cmd->state = UB_CMDST_CMD; ub_cmdtr_state(sc, cmd); return 0; @@ -968,18 +967,17 @@ sc->work_urb.error_count = 0; sc->work_urb.status = 0; - sc->work_timer.expires = jiffies + UB_URB_TIMEOUT; - add_timer(&sc->work_timer); - if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { /* XXX Clear stalls */ printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */ - del_timer(&sc->work_timer); ub_complete(&sc->work_done); ub_state_done(sc, cmd, rc); return; } + sc->work_timer.expires = jiffies + UB_URB_TIMEOUT; + add_timer(&sc->work_timer); + cmd->state = UB_CMDST_DATA; ub_cmdtr_state(sc, cmd); @@ -1063,19 +1061,18 @@ sc->work_urb.error_count = 0; sc->work_urb.status = 0; - sc->work_timer.expires = jiffies + UB_URB_TIMEOUT; - add_timer(&sc->work_timer); - rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC); if (rc != 0) { /* XXX Clear stalls */ printk("%s: CSW #%d submit failed (%d)\n", sc->name, cmd->tag, rc); /* P3 */ - del_timer(&sc->work_timer); ub_complete(&sc->work_done); ub_state_done(sc, cmd, rc); return; } + + sc->work_timer.expires = jiffies + UB_URB_TIMEOUT; + add_timer(&sc->work_timer); return; } @@ -1186,18 +1183,17 @@ sc->work_urb.error_count = 0; sc->work_urb.status = 0; - sc->work_timer.expires = jiffies + UB_URB_TIMEOUT; - add_timer(&sc->work_timer); - if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { /* XXX Clear stalls */ printk("ub: CSW #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */ - del_timer(&sc->work_timer); ub_complete(&sc->work_done); ub_state_done(sc, cmd, rc); return; } + sc->work_timer.expires = jiffies + UB_URB_TIMEOUT; + add_timer(&sc->work_timer); + cmd->stat_count = 0; cmd->state = UB_CMDST_STAT; ub_cmdtr_state(sc, cmd); @@ -1217,9 +1213,17 @@ goto error; } + /* + * ``If the allocation length is eighteen or greater, and a device + * server returns less than eithteen bytes of data, the application + * client should assume that the bytes not transferred would have been + * zeroes had the device server returned those bytes.'' + */ memset(&sc->top_sense, 0, UB_SENSE_SIZE); + scmd = &sc->top_rqs_cmd; scmd->cdb[0] = REQUEST_SENSE; + scmd->cdb[4] = UB_SENSE_SIZE; scmd->cdb_len = 6; scmd->dir = UB_DIR_READ; scmd->state = UB_CMDST_INIT; @@ -1271,14 +1275,13 @@ sc->work_urb.error_count = 0; sc->work_urb.status = 0; - sc->work_timer.expires = jiffies + UB_CTRL_TIMEOUT; - add_timer(&sc->work_timer); - if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { - del_timer(&sc->work_timer); ub_complete(&sc->work_done); return rc; } + + sc->work_timer.expires = jiffies + UB_CTRL_TIMEOUT; + add_timer(&sc->work_timer); return 0; } @@ -1289,6 +1292,9 @@ unsigned char *sense = scmd->data; struct ub_scsi_cmd *cmd; + /* + * Ignoring scmd->act_len, because the buffer was pre-zeroed. + */ ub_cmdtr_sense(sc, scmd, sense); if ((cmd = ub_cmdq_peek(sc)) == NULL) { @@ -1725,18 +1731,17 @@ sc->work_urb.error_count = 0; sc->work_urb.status = 0; - init_timer(&timer); - timer.function = ub_probe_timeout; - timer.data = (unsigned long) &compl; - timer.expires = jiffies + UB_CTRL_TIMEOUT; - add_timer(&timer); - if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { printk(KERN_WARNING "%s: Unable to submit a probe clear (%d)\n", sc->name, rc); - del_timer_sync(&timer); return rc; } + + init_timer(&timer); + timer.function = ub_probe_timeout; + timer.data = (unsigned long) &compl; + timer.expires = jiffies + UB_CTRL_TIMEOUT; + add_timer(&timer); wait_for_completion(&compl); diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c --- a/drivers/pci/quirks.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/pci/quirks.c 2004-09-12 22:25:42 -07:00 @@ -826,6 +826,236 @@ pci_read_config_byte(dev, 0x77, &val); } + +#define UHCI_USBLEGSUP 0xc0 /* legacy support */ +#define UHCI_USBCMD 0 /* command register */ +#define UHCI_USBSTS 2 /* status register */ +#define UHCI_USBINTR 4 /* interrupt register */ +#define UHCI_USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ +#define UHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ +#define UHCI_USBCMD_GRESET (1 << 2) /* Global reset */ +#define UHCI_USBCMD_CONFIGURE (1 << 6) /* config semaphore */ +#define UHCI_USBSTS_HALTED (1 << 5) /* HCHalted bit */ + +#define OHCI_CONTROL 0x04 +#define OHCI_CMDSTATUS 0x08 +#define OHCI_INTRSTATUS 0x0c +#define OHCI_INTRENABLE 0x10 +#define OHCI_INTRDISABLE 0x14 +#define OHCI_OCR (1 << 3) /* ownership change request */ +#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ +#define OHCI_INTR_OC (1 << 30) /* ownership change */ + +#define EHCI_HCC_PARAMS 0x08 /* extended capabilities */ +#define EHCI_USBCMD 0 /* command register */ +#define EHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ +#define EHCI_USBSTS 4 /* status register */ +#define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ +#define EHCI_USBINTR 8 /* interrupt register */ +#define EHCI_USBLEGSUP 0 /* legacy support register */ +#define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ +#define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ +#define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ +#define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ + +int usb_early_handoff __initdata = 0; +static int __init usb_handoff_early(char *str) +{ + usb_early_handoff = 1; + return 0; +} +__setup("usb-handoff", usb_handoff_early); + +static void __init quirk_usb_handoff_uhci(struct pci_dev *pdev) +{ + unsigned long base = 0; + int wait_time, delta; + u16 val, sts; + int i; + + for (i = 0; i < PCI_ROM_RESOURCE; i++) + if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { + base = pci_resource_start(pdev, i); + break; + } + + if (!base) + return; + + /* + * stop controller + */ + sts = inw(base + UHCI_USBSTS); + val = inw(base + UHCI_USBCMD); + val &= ~(u16)(UHCI_USBCMD_RUN | UHCI_USBCMD_CONFIGURE); + outw(val, base + UHCI_USBCMD); + + /* + * wait while it stops if it was running + */ + if ((sts & UHCI_USBSTS_HALTED) == 0) + { + wait_time = 1000; + delta = 100; + + do { + outw(0x1f, base + UHCI_USBSTS); + udelay(delta); + wait_time -= delta; + val = inw(base + UHCI_USBSTS); + if (val & UHCI_USBSTS_HALTED) + break; + } while (wait_time > 0); + } + + /* + * disable interrupts & legacy support + */ + outw(0, base + UHCI_USBINTR); + outw(0x1f, base + UHCI_USBSTS); + pci_read_config_word(pdev, UHCI_USBLEGSUP, &val); + if (val & 0xbf) + pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT); + +} + +static void __init quirk_usb_handoff_ohci(struct pci_dev *pdev) +{ + char *base; + int wait_time; + + base = ioremap_nocache(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + if (base == NULL) return; + + if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { + wait_time = 500; /* 0.5 seconds */ + writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); + writel(OHCI_OCR, base + OHCI_CMDSTATUS); + while (wait_time > 0 && + readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { + wait_time -= 10; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((HZ*10 + 999) / 1000); + } + } + + /* + * disable interrupts + */ + writel(~(u32)0, base + OHCI_INTRDISABLE); + writel(~(u32)0, base + OHCI_INTRSTATUS); + + iounmap(base); +} + +static void __init quirk_usb_disable_ehci(struct pci_dev *pdev) +{ + int wait_time, delta; + char *base, *op_reg_base; + u32 hcc_params, val, temp; + u8 cap_length; + + base = ioremap_nocache(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + if (base == NULL) return; + + cap_length = readb(base); + op_reg_base = base + cap_length; + hcc_params = readl(base + EHCI_HCC_PARAMS); + hcc_params = (hcc_params >> 8) & 0xff; + if (hcc_params) { + pci_read_config_dword(pdev, + hcc_params + EHCI_USBLEGSUP, + &val); + if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) { + /* + * Ok, BIOS is in smm mode, try to hand off... + */ + pci_read_config_dword(pdev, + hcc_params + EHCI_USBLEGCTLSTS, + &temp); + pci_write_config_dword(pdev, + hcc_params + EHCI_USBLEGCTLSTS, + temp | EHCI_USBLEGCTLSTS_SOOE); + val |= EHCI_USBLEGSUP_OS; + pci_write_config_dword(pdev, + hcc_params + EHCI_USBLEGSUP, + val); + + wait_time = 500; + do { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((HZ*10+999)/1000); + wait_time -= 10; + pci_read_config_dword(pdev, + hcc_params + EHCI_USBLEGSUP, + &val); + } while (wait_time && (val & EHCI_USBLEGSUP_BIOS)); + if (!wait_time) { + /* + * well, possibly buggy BIOS... + */ + printk(KERN_WARNING "EHCI early BIOS handoff " + "failed (BIOS bug ?)\n"); + pci_write_config_dword(pdev, + hcc_params + EHCI_USBLEGSUP, + EHCI_USBLEGSUP_OS); + pci_write_config_dword(pdev, + hcc_params + EHCI_USBLEGCTLSTS, + 0); + } + } + } + + /* + * halt EHCI & disable its interrupts in any case + */ + val = readl(op_reg_base + EHCI_USBSTS); + if ((val & EHCI_USBSTS_HALTED) == 0) { + val = readl(op_reg_base + EHCI_USBCMD); + val &= ~EHCI_USBCMD_RUN; + writel(val, op_reg_base + EHCI_USBCMD); + + wait_time = 2000; + delta = 100; + do { + writel(0x3f, op_reg_base + EHCI_USBSTS); + udelay(delta); + wait_time -= delta; + val = readl(op_reg_base + EHCI_USBSTS); + if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { + break; + } + } while (wait_time > 0); + } + writel(0, op_reg_base + EHCI_USBINTR); + writel(0x3f, op_reg_base + EHCI_USBSTS); + + iounmap(base); + + return; +} + + + +static void __init quirk_usb_early_handoff(struct pci_dev *pdev) +{ + if (!usb_early_handoff) + return; + + if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x00)) { /* UHCI */ + quirk_usb_handoff_uhci(pdev); + } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) { /* OHCI */ + quirk_usb_handoff_ohci(pdev); + } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x20)) { /* EHCI */ + quirk_usb_disable_ehci(pdev); + } + + return; +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); + /* * ... This is further complicated by the fact that some SiS96x south * bridges pretend to be 85C503/5513 instead. In that case see if we diff -Nru a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig --- a/drivers/usb/class/Kconfig 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/class/Kconfig 2004-09-12 22:25:42 -07:00 @@ -9,7 +9,8 @@ depends on USB && SOUND help Say Y here if you want to connect USB audio equipment such as - speakers to your computer's USB port. + speakers to your computer's USB port. You only need this if you use + the OSS sound driver; ALSA has its own option for usb audio support. To compile this driver as a module, choose M here: the module will be called audio. diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c --- a/drivers/usb/class/audio.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/class/audio.c 2004-09-12 22:25:43 -07:00 @@ -1949,15 +1949,12 @@ static int usb_audio_open_mixdev(struct inode *inode, struct file *file) { unsigned int minor = iminor(inode); - struct list_head *devs, *mdevs; struct usb_mixerdev *ms; struct usb_audio_state *s; down(&open_sem); - list_for_each(devs, &audiodevs) { - s = list_entry(devs, struct usb_audio_state, audiodev); - list_for_each(mdevs, &s->mixerlist) { - ms = list_entry(mdevs, struct usb_mixerdev, list); + list_for_each_entry(s, &audiodevs, audiodev) { + list_for_each_entry(ms, &s->mixerlist, list) { if (ms->dev_mixer == minor) goto mixer_found; } @@ -2634,16 +2631,13 @@ { unsigned int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); - struct list_head *devs, *adevs; struct usb_audiodev *as; struct usb_audio_state *s; for (;;) { down(&open_sem); - list_for_each(devs, &audiodevs) { - s = list_entry(devs, struct usb_audio_state, audiodev); - list_for_each(adevs, &s->audiolist) { - as = list_entry(adevs, struct usb_audiodev, list); + list_for_each_entry(s, &audiodevs, audiodev) { + list_for_each_entry(as, &s->audiolist, list) { if (!((as->dev_audio ^ minor) & ~0xf)) goto device_found; } @@ -3809,7 +3803,6 @@ static void usb_audio_disconnect(struct usb_interface *intf) { struct usb_audio_state *s = usb_get_intfdata (intf); - struct list_head *list; struct usb_audiodev *as; struct usb_mixerdev *ms; @@ -3831,8 +3824,7 @@ usb_set_intfdata (intf, NULL); /* deregister all audio and mixer devices, so no new processes can open this device */ - list_for_each(list, &s->audiolist) { - as = list_entry(list, struct usb_audiodev, list); + list_for_each_entry(as, &s->audiolist, list) { usbin_disc(as); usbout_disc(as); wake_up(&as->usbin.dma.wait); @@ -3843,8 +3835,7 @@ } as->dev_audio = -1; } - list_for_each(list, &s->mixerlist) { - ms = list_entry(list, struct usb_mixerdev, list); + list_for_each_entry(ms, &s->mixerlist, list) { if (ms->dev_mixer >= 0) { unregister_sound_mixer(ms->dev_mixer); printk(KERN_INFO "usbaudio: unregister mixer 14,%d\n", ms->dev_mixer); diff -Nru a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c --- a/drivers/usb/class/usb-midi.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/class/usb-midi.c 2004-09-12 22:25:42 -07:00 @@ -805,7 +805,6 @@ { int minor = iminor(inode); DECLARE_WAITQUEUE(wait, current); - struct list_head *devs, *mdevs; struct usb_midi_state *s; struct usb_mididev *m; unsigned long flags; @@ -817,10 +816,8 @@ for(;;) { down(&open_sem); - list_for_each(devs, &mididevs) { - s = list_entry(devs, struct usb_midi_state, mididev); - list_for_each(mdevs, &s->midiDevList) { - m = list_entry(mdevs, struct usb_mididev, list); + list_for_each_entry(s, &mididevs, mididev) { + list_for_each_entry(m, &s->midiDevList, list) { if ( !((m->dev_midi ^ minor) & ~0xf) ) goto device_found; } @@ -1994,7 +1991,6 @@ static void usb_midi_disconnect(struct usb_interface *intf) { struct usb_midi_state *s = usb_get_intfdata (intf); - struct list_head *list; struct usb_mididev *m; if ( !s ) @@ -2012,8 +2008,7 @@ s->usbdev = NULL; usb_set_intfdata (intf, NULL); - list_for_each(list, &s->midiDevList) { - m = list_entry(list, struct usb_mididev, list); + list_for_each_entry(m, &s->midiDevList, list) { wake_up(&(m->min.ep->wait)); wake_up(&(m->mout.ep->wait)); if ( m->dev_midi >= 0 ) { diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c --- a/drivers/usb/class/usblp.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/class/usblp.c 2004-09-12 22:25:42 -07:00 @@ -410,9 +410,9 @@ static void usblp_unlink_urbs(struct usblp *usblp) { - usb_unlink_urb(usblp->writeurb); + usb_kill_urb(usblp->writeurb); if (usblp->bidir) - usb_unlink_urb(usblp->readurb); + usb_kill_urb(usblp->readurb); } static int usblp_release(struct inode *inode, struct file *file) diff -Nru a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c --- a/drivers/usb/core/devices.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/core/devices.c 2004-09-12 22:25:43 -07:00 @@ -149,7 +149,7 @@ /*****************************************************************/ -void usbdevfs_conn_disc_event(void) +void usbfs_conn_disc_event(void) { conndiscevcnt++; wake_up(&deviceconndiscwq); @@ -569,7 +569,6 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { - struct list_head *buslist; struct usb_bus *bus; ssize_t ret, total_written = 0; loff_t skip_bytes = *ppos; @@ -581,12 +580,9 @@ if (!access_ok(VERIFY_WRITE, buf, nbytes)) return -EFAULT; - /* enumerate busses */ down (&usb_bus_list_lock); - list_for_each(buslist, &usb_bus_list) { - /* print devices for this bus */ - bus = list_entry(buslist, struct usb_bus, bus_list); - + /* print devices for all busses */ + list_for_each_entry(bus, &usb_bus_list, bus_list) { /* recurse through all children of the root hub */ if (!bus->root_hub) continue; @@ -682,7 +678,7 @@ return ret; } -struct file_operations usbdevfs_devices_fops = { +struct file_operations usbfs_devices_fops = { .llseek = usb_device_lseek, .read = usb_device_read, .poll = usb_device_poll, diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c --- a/drivers/usb/core/devio.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/core/devio.c 2004-09-12 22:25:42 -07:00 @@ -21,7 +21,7 @@ * * $Id: devio.c,v 1.7 2000/02/01 17:28:48 fliegl Exp $ * - * This file implements the usbdevfs/x/y files, where + * This file implements the usbfs/x/y files, where * x is the bus number and y the device number. * * It allows user space programs/"drivers" to communicate directly @@ -286,9 +286,10 @@ while (!list_empty(list)) { as = list_entry(list->next, struct async, asynclist); list_del_init(&as->asynclist); + + /* drop the spinlock so the completion handler can run */ spin_unlock_irqrestore(&ps->lock, flags); - /* usb_unlink_urb calls the completion handler with status == -ENOENT */ - usb_unlink_urb(as->urb); + usb_kill_urb(as->urb); spin_lock_irqsave(&ps->lock, flags); } spin_unlock_irqrestore(&ps->lock, flags); @@ -353,7 +354,7 @@ destroy_async_on_interface(ps, ifnum); } -struct usb_driver usbdevfs_driver = { +struct usb_driver usbfs_driver = { .owner = THIS_MODULE, .name = "usbfs", .probe = driver_probe, @@ -378,7 +379,7 @@ if (!intf) err = -ENOENT; else - err = usb_driver_claim_interface(&usbdevfs_driver, intf, ps); + err = usb_driver_claim_interface(&usbfs_driver, intf, ps); up_write(&usb_bus_type.subsys.rwsem); if (err == 0) set_bit(ifnum, &ps->ifclaimed); @@ -401,7 +402,7 @@ if (!intf) err = -ENOENT; else if (test_and_clear_bit(ifnum, &ps->ifclaimed)) { - usb_driver_release_interface(&usbdevfs_driver, intf); + usb_driver_release_interface(&usbfs_driver, intf); err = 0; } up_write(&usb_bus_type.subsys.rwsem); @@ -976,7 +977,7 @@ as = async_getpending(ps, arg); if (!as) return -EINVAL; - usb_unlink_urb(as->urb); + usb_kill_urb(as->urb); return 0; } @@ -1314,7 +1315,7 @@ return mask; } -struct file_operations usbdevfs_device_file_operations = { +struct file_operations usbfs_device_file_operations = { .llseek = usbdev_lseek, .read = usbdev_read, .poll = usbdev_poll, diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c --- a/drivers/usb/core/hcd-pci.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/core/hcd-pci.c 2004-09-12 22:25:42 -07:00 @@ -188,9 +188,9 @@ } hcd->irq = dev->irq; - dev_info (hcd->self.controller, "irq %s, %s %p\n", bufp, + dev_info (hcd->self.controller, "irq %s, %s 0x%lx\n", bufp, (driver->flags & HCD_MEMORY) ? "pci mem" : "io base", - base); + resource); usb_bus_init (&hcd->self); hcd->self.op = &usb_hcd_operations; diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c --- a/drivers/usb/core/hcd.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/core/hcd.c 2004-09-12 22:25:42 -07:00 @@ -1263,7 +1263,7 @@ * never get completion IRQs ... maybe even the ones we need to * finish unlinking the initial failed usb_set_address(). */ - if (!hcd->saw_irq) { + if (!hcd->saw_irq && hcd->rh_timer.data != (unsigned long) urb) { dev_warn (hcd->self.controller, "Unlink after no-IRQ? " "Different ACPI or APIC settings may help." "\n"); @@ -1572,13 +1572,12 @@ struct usb_hcd *hcd = __hcd; int start = hcd->state; - if (unlikely (hcd->state == USB_STATE_HALT)) /* irq sharing? */ + if (start == USB_STATE_HALT) return IRQ_NONE; - - hcd->saw_irq = 1; if (hcd->driver->irq (hcd, r) == IRQ_NONE) return IRQ_NONE; + hcd->saw_irq = 1; if (hcd->state != start && hcd->state == USB_STATE_HALT) usb_hc_died (hcd); return IRQ_HANDLED; @@ -1587,22 +1586,6 @@ /*-------------------------------------------------------------------------*/ -static void hcd_panic (void *_hcd) -{ - struct usb_hcd *hcd = _hcd; - struct usb_device *hub = hcd->self.root_hub; - unsigned i; - - /* hc's root hub is removed later removed in hcd->stop() */ - down (&hub->serialize); - usb_set_device_state(hub, USB_STATE_NOTATTACHED); - for (i = 0; i < hub->maxchild; i++) { - if (hub->children [i]) - usb_disconnect (&hub->children [i]); - } - up (&hub->serialize); -} - /** * usb_hc_died - report abnormal shutdown of a host controller (bus glue) * @hcd: pointer to the HCD representing the controller @@ -1615,9 +1598,9 @@ { dev_err (hcd->self.controller, "HC died; cleaning up\n"); - /* clean up old urbs and devices; needs a task context */ - INIT_WORK (&hcd->work, hcd_panic, hcd); - (void) schedule_work (&hcd->work); + /* make khubd clean up old urbs and devices */ + usb_set_device_state(hcd->self.root_hub, USB_STATE_NOTATTACHED); + mod_timer(&hcd->rh_timer, jiffies); } EXPORT_SYMBOL (usb_hc_died); diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h --- a/drivers/usb/core/hcd.h 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/core/hcd.h 2004-09-12 22:25:42 -07:00 @@ -67,7 +67,6 @@ struct timer_list rh_timer; /* drives root hub */ struct list_head dev_list; /* devices on this bus */ - struct work_struct work; /* * hardware info/state @@ -362,6 +361,9 @@ return usb_register_root_hub (usb_dev, hcd->self.controller); } + +extern void usb_set_device_state(struct usb_device *udev, + enum usb_device_state new_state); /*-------------------------------------------------------------------------*/ diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c --- a/drivers/usb/core/hub.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/core/hub.c 2004-09-12 22:25:42 -07:00 @@ -39,12 +39,13 @@ /* Protect struct usb_device state and children members */ static spinlock_t device_state_lock = SPIN_LOCK_UNLOCKED; -/* Wakes up khubd */ +/* khubd's worklist and its lock */ static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED; - static LIST_HEAD(hub_event_list); /* List of hubs needing servicing */ +/* Wakes up khubd */ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); + static pid_t khubd_pid = 0; /* PID of khubd */ static DECLARE_COMPLETION(khubd_exited); @@ -226,6 +227,19 @@ data, sizeof(*data), HZ * USB_CTRL_GET_TIMEOUT); } +static void kick_khubd(struct usb_hub *hub) +{ + unsigned long flags; + + spin_lock_irqsave(&hub_event_lock, flags); + if (list_empty(&hub->event_list)) { + list_add_tail(&hub->event_list, &hub_event_list); + wake_up(&khubd_wait); + } + spin_unlock_irqrestore(&hub_event_lock, flags); +} + + /* completion function, fires on port status changes and various faults */ static void hub_irq(struct urb *urb, struct pt_regs *regs) { @@ -261,12 +275,7 @@ hub->nerrors = 0; /* Something happened, let khubd figure it out */ - spin_lock(&hub_event_lock); - if (list_empty(&hub->event_list)) { - list_add_tail(&hub->event_list, &hub_event_list); - wake_up(&khubd_wait); - } - spin_unlock(&hub_event_lock); + kick_khubd(hub); resubmit: if (hub->quiescing) @@ -579,6 +588,9 @@ dev_dbg(hub_dev, "%sover-current condition exists\n", (hubstatus & HUB_STATUS_OVERCURRENT) ? "" : "no "); + /* scan all ports ASAP on new hubs */ + hub->change_bits[0] = ~0; + /* Start the interrupt endpoint */ pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress); maxp = usb_maxpacket(hdev, pipe, usb_pipeout(pipe)); @@ -604,7 +616,7 @@ } /* Wake up khubd */ - wake_up(&khubd_wait); + kick_khubd(hub); /* maybe start cycling the hub leds */ if (hub->has_indicators && blinkenlights) { @@ -910,7 +922,7 @@ } /** - * usb_set_device_state - change a device's current state (usbcore-internal) + * usb_set_device_state - change a device's current state (usbcore, hcds) * @udev: pointer to device whose state should be changed * @new_state: new state value to be stored * @@ -941,6 +953,7 @@ recursively_mark_NOTATTACHED(udev); spin_unlock_irqrestore(&device_state_lock, flags); } +EXPORT_SYMBOL(usb_set_device_state); static void choose_address(struct usb_device *udev) @@ -1384,7 +1397,6 @@ int ret; if (hdev->children[port]) { - /* FIXME need disconnect() for NOTATTACHED device */ usb_set_device_state(hdev->children[port], USB_STATE_NOTATTACHED); } @@ -1396,6 +1408,33 @@ return ret; } +/* + * Disable a port and mark a logical connnect-change event, so that some + * time later khubd will disconnect() any existing usb_device on the port + * and will re-enumerate if there actually is a device attached. + */ +static void hub_port_logical_disconnect(struct usb_device *hdev, int port) +{ + struct usb_hub *hub; + + dev_dbg(hubdev(hdev), "logical disconnect on port %d\n", port + 1); + hub_port_disable(hdev, port); + + /* FIXME let caller ask to power down the port: + * - some devices won't enumerate without a VBUS power cycle + * - SRP saves power that way + * - usb_suspend_device(dev,PM_SUSPEND_DISK) + * That's easy if this hub can switch power per-port, and + * khubd reactivates the port later (timer, SRP, etc). + * Powerdown must be optional, because of reset/DFU. + */ + + hub = usb_get_intfdata(hdev->actconfig->interface[0]); + set_bit(port, hub->change_bits); + kick_khubd(hub); +} + + #ifdef CONFIG_USB_SUSPEND /* @@ -1413,8 +1452,8 @@ int status; struct usb_device *udev; - udev = hdev->children[port - 1]; - // dev_dbg(hubdev(hdev), "suspend port %d\n", port); + udev = hdev->children[port]; + // dev_dbg(hubdev(hdev), "suspend port %d\n", port + 1); /* enable remote wakeup when appropriate; this lets the device * wake up the upstream hub (including maybe the root hub). @@ -1439,11 +1478,11 @@ } /* see 7.1.7.6 */ - status = set_port_feature(hdev, port, USB_PORT_FEAT_SUSPEND); + status = set_port_feature(hdev, port + 1, USB_PORT_FEAT_SUSPEND); if (status) { dev_dbg(hubdev(hdev), "can't suspend port %d, status %d\n", - port, status); + port + 1, status); /* paranoia: "should not happen" */ (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0), USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, @@ -1562,7 +1601,7 @@ else status = -EOPNOTSUPP; } else - status = hub_port_suspend(udev->parent, port + 1); + status = hub_port_suspend(udev->parent, port); if (status == 0) udev->dev.power.power_state = state; @@ -1687,15 +1726,15 @@ int status; struct usb_device *udev; - udev = hdev->children[port - 1]; - // dev_dbg(hubdev(hdev), "resume port %d\n", port); + udev = hdev->children[port]; + // dev_dbg(hubdev(hdev), "resume port %d\n", port + 1); /* see 7.1.7.7; affects power usage, but not budgeting */ - status = clear_port_feature(hdev, port, USB_PORT_FEAT_SUSPEND); + status = clear_port_feature(hdev, port + 1, USB_PORT_FEAT_SUSPEND); if (status) { dev_dbg(&hdev->actconfig->interface[0]->dev, "can't resume port %d, status %d\n", - port, status); + port + 1, status); } else { u16 devstatus; u16 portchange; @@ -1713,7 +1752,7 @@ * sequence. */ devstatus = portchange = 0; - status = hub_port_status(hdev, port - 1, + status = hub_port_status(hdev, port, &devstatus, &portchange); if (status < 0 || (devstatus & LIVE_FLAGS) != LIVE_FLAGS @@ -1721,7 +1760,7 @@ ) { dev_dbg(&hdev->actconfig->interface[0]->dev, "port %d status %04x.%04x after resume, %d\n", - port, portchange, devstatus, status); + port + 1, portchange, devstatus, status); } else { /* TRSMRCY = 10 msec */ msleep(10); @@ -1729,7 +1768,7 @@ } } if (status < 0) - status = hub_port_disable(hdev, port); + hub_port_logical_disconnect(hdev, port); return status; } @@ -1773,7 +1812,7 @@ ->actconfig->interface[0]); } } else if (udev->state == USB_STATE_SUSPENDED) { - status = hub_port_resume(udev->parent, port + 1); + status = hub_port_resume(udev->parent, port); } else { status = 0; udev->dev.power.power_state = PM_SUSPEND_ON; @@ -1866,14 +1905,14 @@ continue; down (&udev->serialize); if (portstat & USB_PORT_STAT_SUSPEND) - status = hub_port_resume(hdev, port + 1); + status = hub_port_resume(hdev, port); else { status = finish_port_resume(udev); - if (status < 0) - status = hub_port_disable(hdev, port); - if (status < 0) + if (status < 0) { dev_dbg(&intf->dev, "resume port %d --> %d\n", - port, status); + port + 1, status); + hub_port_logical_disconnect(hdev, port); + } } up(&udev->serialize); } @@ -2011,7 +2050,7 @@ hdev->bus->b_hnp_enable = 0; } - retval = clear_port_feature(hdev, port, USB_PORT_FEAT_SUSPEND); + retval = clear_port_feature(hdev, port + 1, USB_PORT_FEAT_SUSPEND); if (retval < 0 && retval != -EPIPE) dev_dbg(&udev->dev, "can't clear suspend; %d\n", retval); @@ -2502,15 +2541,17 @@ if (portchange & USB_PORT_STAT_C_SUSPEND) { clear_port_feature(hdev, i + 1, USB_PORT_FEAT_C_SUSPEND); - if (hdev->children[i]) + if (hdev->children[i]) { ret = remote_wakeup(hdev->children[i]); - else + if (ret < 0) + connect_change = 1; + } else { ret = -ENODEV; + hub_port_disable(hdev, i); + } dev_dbg (hub_dev, "resume on port %d, status %d\n", i + 1, ret); - if (ret < 0) - ret = hub_port_disable(hdev, i); } if (portchange & USB_PORT_STAT_C_OVERCURRENT) { @@ -2713,7 +2754,6 @@ struct usb_device *parent = udev->parent; struct usb_device_descriptor descriptor = udev->descriptor; int i, ret, port = -1; - struct usb_hub *hub; if (udev->state == USB_STATE_NOTATTACHED || udev->state == USB_STATE_SUSPENDED) { @@ -2794,18 +2834,7 @@ return 0; re_enumerate: - hub_port_disable(parent, port); - - hub = usb_get_intfdata(parent->actconfig->interface[0]); - set_bit(port, hub->change_bits); - - spin_lock_irq(&hub_event_lock); - if (list_empty(&hub->event_list)) { - list_add_tail(&hub->event_list, &hub_event_list); - wake_up(&khubd_wait); - } - spin_unlock_irq(&hub_event_lock); - + hub_port_logical_disconnect(parent, port); return -ENODEV; } EXPORT_SYMBOL(__usb_reset_device); diff -Nru a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c --- a/drivers/usb/core/inode.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/core/inode.c 2004-09-12 22:25:42 -07:00 @@ -4,7 +4,7 @@ * inode.c -- Inode/Dentry functions for the USB device file system. * * Copyright (C) 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) - * Copyright (C) 2001,2002 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001,2002,2004 Greg Kroah-Hartman (greg@kroah.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,17 +40,15 @@ #include #include #include +#include "usb.h" static struct super_operations usbfs_ops; static struct file_operations default_file_operations; static struct inode_operations usbfs_dir_inode_operations; -static struct vfsmount *usbdevfs_mount; static struct vfsmount *usbfs_mount; -static int usbdevfs_mount_count; /* = 0 */ static int usbfs_mount_count; /* = 0 */ static int ignore_mount = 0; -static struct dentry *devices_usbdevfs_dentry; static struct dentry *devices_usbfs_dentry; static int num_buses; /* = 0 */ @@ -240,9 +238,6 @@ if (usbfs_mount && usbfs_mount->mnt_sb) update_sb(usbfs_mount->mnt_sb); - if (usbdevfs_mount && usbdevfs_mount->mnt_sb) - update_sb(usbdevfs_mount->mnt_sb); - return 0; } @@ -561,28 +556,12 @@ /* --------------------------------------------------------------------- */ - - -/* - * The usbdevfs name is now deprecated (as of 2.5.1). - * It will be removed when the 2.7.x development cycle is started. - * You have been warned :) - */ -static struct file_system_type usbdevice_fs_type; - static struct super_block *usb_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { return get_sb_single(fs_type, flags, data, usbfs_fill_super); } -static struct file_system_type usbdevice_fs_type = { - .owner = THIS_MODULE, - .name = "usbdevfs", - .get_sb = usb_get_sb, - .kill_sb = kill_litter_super, -}; - static struct file_system_type usb_fs_type = { .owner = THIS_MODULE, .name = "usbfs", @@ -603,16 +582,10 @@ ignore_mount = 1; /* create the devices special file */ - retval = simple_pin_fs("usbdevfs", &usbdevfs_mount, &usbdevfs_mount_count); - if (retval) { - err ("Unable to get usbdevfs mount"); - goto exit; - } - retval = simple_pin_fs("usbfs", &usbfs_mount, &usbfs_mount_count); if (retval) { err ("Unable to get usbfs mount"); - goto error_clean_usbdevfs_mount; + goto exit; } ignore_mount = 0; @@ -620,7 +593,7 @@ parent = usbfs_mount->mnt_sb->s_root; devices_usbfs_dentry = fs_create_file ("devices", listmode | S_IFREG, parent, - NULL, &usbdevfs_devices_fops, + NULL, &usbfs_devices_fops, listuid, listgid); if (devices_usbfs_dentry == NULL) { err ("Unable to create devices usbfs file"); @@ -628,42 +601,19 @@ goto error_clean_mounts; } - parent = usbdevfs_mount->mnt_sb->s_root; - devices_usbdevfs_dentry = fs_create_file ("devices", - listmode | S_IFREG, parent, - NULL, &usbdevfs_devices_fops, - listuid, listgid); - if (devices_usbdevfs_dentry == NULL) { - err ("Unable to create devices usbfs file"); - retval = -ENODEV; - goto error_remove_file; - } - goto exit; -error_remove_file: - fs_remove_file (devices_usbfs_dentry); - devices_usbfs_dentry = NULL; - error_clean_mounts: simple_release_fs(&usbfs_mount, &usbfs_mount_count); - -error_clean_usbdevfs_mount: - simple_release_fs(&usbdevfs_mount, &usbdevfs_mount_count); - exit: return retval; } static void remove_special_files (void) { - if (devices_usbdevfs_dentry) - fs_remove_file (devices_usbdevfs_dentry); if (devices_usbfs_dentry) fs_remove_file (devices_usbfs_dentry); - devices_usbdevfs_dentry = NULL; devices_usbfs_dentry = NULL; - simple_release_fs(&usbdevfs_mount, &usbdevfs_mount_count); simple_release_fs(&usbfs_mount, &usbfs_mount_count); } @@ -671,11 +621,6 @@ { struct inode *inode; - if (devices_usbdevfs_dentry) { - inode = devices_usbdevfs_dentry->d_inode; - if (inode) - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; - } if (devices_usbfs_dentry) { inode = devices_usbfs_dentry->d_inode; if (inode) @@ -707,29 +652,16 @@ return; } - parent = usbdevfs_mount->mnt_sb->s_root; - bus->usbdevfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent, - bus, NULL, busuid, busgid); - if (bus->usbdevfs_dentry == NULL) { - err ("error creating usbdevfs bus entry"); - return; - } - usbfs_update_special(); - usbdevfs_conn_disc_event(); + usbfs_conn_disc_event(); } - void usbfs_remove_bus(struct usb_bus *bus) { if (bus->usbfs_dentry) { fs_remove_file (bus->usbfs_dentry); bus->usbfs_dentry = NULL; } - if (bus->usbdevfs_dentry) { - fs_remove_file (bus->usbdevfs_dentry); - bus->usbdevfs_dentry = NULL; - } --num_buses; if (num_buses <= 0) { @@ -738,7 +670,7 @@ } usbfs_update_special(); - usbdevfs_conn_disc_event(); + usbfs_conn_disc_event(); } void usbfs_add_device(struct usb_device *dev) @@ -750,20 +682,12 @@ sprintf (name, "%03d", dev->devnum); dev->usbfs_dentry = fs_create_file (name, devmode | S_IFREG, dev->bus->usbfs_dentry, dev, - &usbdevfs_device_file_operations, + &usbfs_device_file_operations, devuid, devgid); if (dev->usbfs_dentry == NULL) { err ("error creating usbfs device entry"); return; } - dev->usbdevfs_dentry = fs_create_file (name, devmode | S_IFREG, - dev->bus->usbdevfs_dentry, dev, - &usbdevfs_device_file_operations, - devuid, devgid); - if (dev->usbdevfs_dentry == NULL) { - err ("error creating usbdevfs device entry"); - return; - } /* Set the size of the device's file to be * equal to the size of the device descriptors. */ @@ -775,11 +699,9 @@ } if (dev->usbfs_dentry->d_inode) dev->usbfs_dentry->d_inode->i_size = i_size; - if (dev->usbdevfs_dentry->d_inode) - dev->usbdevfs_dentry->d_inode->i_size = i_size; usbfs_update_special(); - usbdevfs_conn_disc_event(); + usbfs_conn_disc_event(); } void usbfs_remove_device(struct usb_device *dev) @@ -791,10 +713,6 @@ fs_remove_file (dev->usbfs_dentry); dev->usbfs_dentry = NULL; } - if (dev->usbdevfs_dentry) { - fs_remove_file (dev->usbdevfs_dentry); - dev->usbdevfs_dentry = NULL; - } while (!list_empty(&dev->filelist)) { ds = list_entry(dev->filelist.next, struct dev_state, list); list_del_init(&ds->list); @@ -807,51 +725,38 @@ } } usbfs_update_special(); - usbdevfs_conn_disc_event(); + usbfs_conn_disc_event(); } /* --------------------------------------------------------------------- */ -#ifdef CONFIG_PROC_FS static struct proc_dir_entry *usbdir = NULL; -#endif int __init usbfs_init(void) { int retval; - retval = usb_register(&usbdevfs_driver); + retval = usb_register(&usbfs_driver); if (retval) return retval; retval = register_filesystem(&usb_fs_type); if (retval) { - usb_deregister(&usbdevfs_driver); - return retval; - } - retval = register_filesystem(&usbdevice_fs_type); - if (retval) { - unregister_filesystem(&usb_fs_type); - usb_deregister(&usbdevfs_driver); + usb_deregister(&usbfs_driver); return retval; } -#ifdef CONFIG_PROC_FS - /* create mount point for usbdevfs */ + /* create mount point for usbfs */ usbdir = proc_mkdir("usb", proc_bus); -#endif return 0; } void usbfs_cleanup(void) { - usb_deregister(&usbdevfs_driver); + usb_deregister(&usbfs_driver); unregister_filesystem(&usb_fs_type); - unregister_filesystem(&usbdevice_fs_type); -#ifdef CONFIG_PROC_FS if (usbdir) remove_proc_entry("usb", proc_bus); -#endif } diff -Nru a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c --- a/drivers/usb/core/urb.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/core/urb.c 2004-09-12 22:25:42 -07:00 @@ -451,6 +451,11 @@ if (!urb) return -EINVAL; if (!(urb->transfer_flags & URB_ASYNC_UNLINK)) { +#ifdef CONFIG_DEBUG_KERNEL + printk(KERN_NOTICE "usb_unlink_urb() is deprecated for " + "synchronous unlinks. Use usb_kill_urb() instead.\n"); + WARN_ON(1); +#endif usb_kill_urb(urb); return 0; } diff -Nru a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h --- a/drivers/usb/core/usb.h 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/core/usb.h 2004-09-12 22:25:42 -07:00 @@ -22,8 +22,12 @@ unsigned int size); extern int usb_set_configuration(struct usb_device *dev, int configuration); -extern void usb_set_device_state(struct usb_device *udev, - enum usb_device_state new_state); /* for labeling diagnostics */ extern const char *usbcore_name; + +/* usbfs stuff */ +extern struct usb_driver usbfs_driver; +extern struct file_operations usbfs_devices_fops; +extern struct file_operations usbfs_device_file_operations; +extern void usbfs_conn_disc_event(void); diff -Nru a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c --- a/drivers/usb/gadget/ether.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/gadget/ether.c 2004-09-12 22:25:43 -07:00 @@ -231,6 +231,10 @@ #define DEV_CONFIG_CDC #endif +#ifdef CONFIG_USB_GADGET_N9604 +#define DEV_CONFIG_CDC +#endif + /* For CDC-incapable hardware, choose the simple cdc subset. * Anything that talks bulk (without notable bugs) can do this. @@ -2334,6 +2338,8 @@ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208); } else if (gadget_is_lh7a40x(gadget)) { device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209); + } else if (gadget_is_n9604(gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x020a); } else { /* can't assume CDC works. don't want to default to * anything less functional on CDC-capable hardware, diff -Nru a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c --- a/drivers/usb/gadget/file_storage.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/gadget/file_storage.c 2004-09-12 22:25:43 -07:00 @@ -248,7 +248,7 @@ #define DRIVER_DESC "File-backed Storage Gadget" #define DRIVER_NAME "g_file_storage" -#define DRIVER_VERSION "28 July 2004" +#define DRIVER_VERSION "31 August 2004" static const char longname[] = DRIVER_DESC; static const char shortname[] = DRIVER_NAME; @@ -866,6 +866,14 @@ .bMaxPower = 1, // self-powered }; +static struct usb_otg_descriptor +otg_desc = { + .bLength = sizeof(otg_desc), + .bDescriptorType = USB_DT_OTG, + + .bmAttributes = USB_OTG_SRP, +}; + /* There is only one interface. */ static struct usb_interface_descriptor @@ -914,6 +922,7 @@ }; static const struct usb_descriptor_header *fs_function[] = { + (struct usb_descriptor_header *) &otg_desc, (struct usb_descriptor_header *) &intf_desc, (struct usb_descriptor_header *) &fs_bulk_in_desc, (struct usb_descriptor_header *) &fs_bulk_out_desc, @@ -976,6 +985,7 @@ }; static const struct usb_descriptor_header *hs_function[] = { + (struct usb_descriptor_header *) &otg_desc, (struct usb_descriptor_header *) &intf_desc, (struct usb_descriptor_header *) &hs_bulk_in_desc, (struct usb_descriptor_header *) &hs_bulk_out_desc, @@ -1018,9 +1028,10 @@ * and with code managing interfaces and their altsettings. They must * also handle different speeds and other-speed requests. */ -static int populate_config_buf(enum usb_device_speed speed, +static int populate_config_buf(struct usb_gadget *gadget, u8 *buf, u8 type, unsigned index) { + enum usb_device_speed speed = gadget->speed; int len; const struct usb_descriptor_header **function; @@ -1036,6 +1047,10 @@ #endif function = fs_function; + /* for now, don't advertise srp-only devices */ + if (!gadget->is_otg) + function++; + len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function); ((struct usb_config_descriptor *) buf)->bDescriptorType = type; return len; @@ -1366,7 +1381,7 @@ #ifdef CONFIG_USB_GADGET_DUALSPEED get_config: #endif - value = populate_config_buf(fsg->gadget->speed, + value = populate_config_buf(fsg->gadget, req->buf, ctrl->wValue >> 8, ctrl->wValue & 0xff); @@ -3713,8 +3728,10 @@ mod_data.release = __constant_cpu_to_le16(0x0307); else if (gadget_is_omap(fsg->gadget)) mod_data.release = __constant_cpu_to_le16(0x0308); - else if (gadget_is_lh7a40x(gadget)) + else if (gadget_is_lh7a40x(fsg->gadget)) mod_data.release = __constant_cpu_to_le16 (0x0309); + else if (gadget_is_n9604(fsg->gadget)) + mod_data.release = __constant_cpu_to_le16 (0x030a); else { WARN(fsg, "controller '%s' not recognized\n", fsg->gadget->name); @@ -3895,6 +3912,11 @@ hs_bulk_out_desc.bEndpointAddress = fs_bulk_out_desc.bEndpointAddress; hs_intr_in_desc.bEndpointAddress = fs_intr_in_desc.bEndpointAddress; #endif + + if (gadget->is_otg) { + otg_desc.bmAttributes |= USB_OTG_HNP, + config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + } rc = -ENOMEM; diff -Nru a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h --- a/drivers/usb/gadget/gadget_chips.h 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/gadget/gadget_chips.h 2004-09-12 22:25:42 -07:00 @@ -62,6 +62,12 @@ #define gadget_is_omap(g) 0 #endif +#ifdef CONFIG_USB_GADGET_N9604 +#define gadget_is_n9604(g) !strcmp("n9604_udc", (g)->name) +#else +#define gadget_is_n9604(g) 0 +#endif + // CONFIG_USB_GADGET_AT91RM9200 // CONFIG_USB_GADGET_SX2 // CONFIG_USB_GADGET_AU1X00 diff -Nru a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c --- a/drivers/usb/gadget/omap_udc.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/gadget/omap_udc.c 2004-09-12 22:25:42 -07:00 @@ -1200,7 +1200,8 @@ { UDC_SYSCON1_REG |= UDC_PULLUP_EN; #ifndef CONFIG_USB_OTG - OTG_CTRL_REG |= OTG_BSESSVLD; + if (!cpu_is_omap15xx()) + OTG_CTRL_REG |= OTG_BSESSVLD; #endif UDC_IRQ_EN_REG = UDC_DS_CHG_IE; } @@ -1208,7 +1209,8 @@ static void pullup_disable(struct omap_udc *udc) { #ifndef CONFIG_USB_OTG - OTG_CTRL_REG &= ~OTG_BSESSVLD; + if (!cpu_is_omap15xx()) + OTG_CTRL_REG &= ~OTG_BSESSVLD; #endif UDC_IRQ_EN_REG = UDC_DS_CHG_IE; UDC_SYSCON1_REG &= ~UDC_PULLUP_EN; @@ -1688,7 +1690,7 @@ } change &= ~UDC_SUS; } - if (change & OTG_FLAGS) { + if (!cpu_is_omap15xx() && (change & OTG_FLAGS)) { update_otg(udc); change &= ~OTG_FLAGS; } @@ -2036,34 +2038,14 @@ } } -static int proc_udc_show(struct seq_file *s, void *_) +static int proc_otg_show(struct seq_file *s) { u32 tmp; - struct omap_ep *ep; - unsigned long flags; - - spin_lock_irqsave(&udc->lock, flags); - seq_printf(s, "%s, version: " DRIVER_VERSION -#ifdef USE_ISO - " (iso)" -#endif - "%s\n", - driver_desc, - use_dma ? " (dma)" : ""); - - tmp = UDC_REV_REG & 0xff; - seq_printf(s, - "UDC rev %d.%d, OTG rev %d.%d, fifo mode %d, gadget %s\n" - "hmc %d, transceiver %08x %s\n", + tmp = OTG_REV_REG; + seq_printf(s, "OTG rev %d.%d, transceiver_ctrl %08x\n", tmp >> 4, tmp & 0xf, - OTG_REV_REG >> 4, OTG_REV_REG & 0xf, - fifo_mode, - udc->driver ? udc->driver->driver.name : "(none)", - HMC, USB_TRANSCEIVER_CTRL_REG, - udc->transceiver ? udc->transceiver->label : ""); - - /* OTG controller registers */ + USB_TRANSCEIVER_CTRL_REG); tmp = OTG_SYSCON_1_REG; seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s," FOURBITS "\n", tmp, @@ -2117,6 +2099,37 @@ seq_printf(s, "otg_outctrl %04x" "\n", tmp); tmp = OTG_TEST_REG; seq_printf(s, "otg_test %04x" "\n", tmp); +} + +static int proc_udc_show(struct seq_file *s, void *_) +{ + u32 tmp; + struct omap_ep *ep; + unsigned long flags; + + spin_lock_irqsave(&udc->lock, flags); + + seq_printf(s, "%s, version: " DRIVER_VERSION +#ifdef USE_ISO + " (iso)" +#endif + "%s\n", + driver_desc, + use_dma ? " (dma)" : ""); + + tmp = UDC_REV_REG & 0xff; + seq_printf(s, + "UDC rev %d.%d, fifo mode %d, gadget %s\n" + "hmc %d, transceiver %s\n", + tmp >> 4, tmp & 0xf, + fifo_mode, + udc->driver ? udc->driver->driver.name : "(none)", + HMC, + udc->transceiver ? udc->transceiver->label : ""); + + /* OTG controller registers */ + if (!cpu_is_omap15xx()) + proc_otg_show(s); tmp = UDC_SYSCON1_REG; seq_printf(s, "\nsyscon1 %04x" EIGHTBITS "\n", tmp, @@ -2496,41 +2509,51 @@ return -EBUSY; } - INFO("OMAP UDC rev %d.%d, OTG rev %d.%d, %s receptacle\n", + INFO("OMAP UDC rev %d.%d, %s receptacle\n", UDC_REV_REG >> 4, UDC_REV_REG & 0xf, - OTG_REV_REG >> 4, OTG_REV_REG & 0xf, config->otg ? "Mini-AB" : "B/Mini-B"); /* use the mode given to us by board init code */ - hmc = HMC; - switch (hmc) { - case 3: - case 11: - case 19: - case 25: - xceiv = otg_get_transceiver(); - if (!xceiv) { - DBG("external transceiver not registered!\n"); - goto cleanup0; - } - type = xceiv->label; - break; - case 0: /* POWERUP DEFAULT == 0 */ - case 4: - case 12: - case 20: - type = "INTEGRATED"; - break; - case 21: /* internal loopback */ - type = "(loopback)"; - break; - case 14: /* transceiverless */ - type = "(none)"; - break; + if (cpu_is_omap15xx()) { + hmc = HMC_1510; + type = "(unknown)"; - default: - ERR("unrecognized UDC HMC mode %d\n", hmc); - return -ENODEV; + /* FIXME may need a GPIO-0 handler to call + * usb_gadget_vbus_{dis,}connect() on us... + */ + } else { + hmc = HMC_1610; + switch (hmc) { + case 3: + case 11: + case 19: + case 25: + xceiv = otg_get_transceiver(); + if (!xceiv) { + DBG("external transceiver not registered!\n"); + if (config->otg) + goto cleanup0; + type = "(unknown external)"; + } else + type = xceiv->label; + break; + case 0: /* POWERUP DEFAULT == 0 */ + case 4: + case 12: + case 20: + type = "INTEGRATED"; + break; + case 21: /* internal loopback */ + type = "(loopback)"; + break; + case 14: /* transceiverless */ + type = "(none)"; + break; + + default: + ERR("unrecognized UDC HMC mode %d\n", hmc); + return -ENODEV; + } } INFO("hmc mode %d, transceiver %s\n", hmc, type); @@ -2671,13 +2694,6 @@ static int __init udc_init(void) { - /* should work on many OMAP systems with at most minor changes, - * but the 1510 doesn't have an OTG controller. - */ - if (cpu_is_omap1510()) { - DBG("no OMAP1510 support yet\n"); - return -ENODEV; - } INFO("%s, version: " DRIVER_VERSION "%s\n", driver_desc, use_dma ? " (dma)" : ""); return driver_register(&udc_driver); diff -Nru a/drivers/usb/gadget/omap_udc.h b/drivers/usb/gadget/omap_udc.h --- a/drivers/usb/gadget/omap_udc.h 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/gadget/omap_udc.h 2004-09-12 22:25:42 -07:00 @@ -193,7 +193,14 @@ /*-------------------------------------------------------------------------*/ -// #define HMC_1510 ((MOD_CONF_CTRL_0_REG >> 1) & 0x3f) +#define MOD_CONF_CTRL_0_REG __REG32(MOD_CONF_CTRL_0) +#define VBUS_W2FC_1510 (1 << 17) /* 0 gpio0, 1 dvdd2 pin */ + +#define FUNC_MUX_CTRL_0_REG __REG32(FUNC_MUX_CTRL_0) +#define VBUS_CTRL_1510 (1 << 19) /* 1 connected (software) */ +#define VBUS_MODE_1510 (1 << 18) /* 0 hardware, 1 software */ + +#define HMC_1510 ((MOD_CONF_CTRL_0_REG >> 1) & 0x3f) #define HMC_1610 (OTG_SYSCON_2_REG & 0x3f) -#define HMC HMC_1610 +#define HMC (cpu_is_omap15xx() ? HMC_1510 : HMC_1610) diff -Nru a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c --- a/drivers/usb/gadget/zero.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/gadget/zero.c 2004-09-12 22:25:42 -07:00 @@ -1188,6 +1188,8 @@ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208); } else if (gadget_is_lh7a40x(gadget)) { device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209); + } else if (gadget_is_n9604(gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x020a); } else { /* gadget zero is so simple (for now, no altsettings) that * it SHOULD NOT have problems with bulk-capable hardware. diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c --- a/drivers/usb/host/ehci-hcd.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/host/ehci-hcd.c 2004-09-12 22:25:42 -07:00 @@ -695,9 +695,18 @@ timer_action_done (ehci, TIMER_IO_WATCHDOG); if (ehci->reclaim_ready) end_unlink_async (ehci, regs); + + /* another CPU may drop ehci->lock during a schedule scan while + * it reports urb completions. this flag guards against bogus + * attempts at re-entrant schedule scanning. + */ + if (ehci->scanning) + return; + ehci->scanning = 1; scan_async (ehci, regs); if (ehci->next_uframe != -1) scan_periodic (ehci, regs); + ehci->scanning = 0; /* the IO watchdog guards against hardware or driver bugs that * misplace IRQs, and should let us run completely without IRQs. diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h --- a/drivers/usb/host/ehci.h 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/host/ehci.h 2004-09-12 22:25:43 -07:00 @@ -53,6 +53,7 @@ struct ehci_qh *async; struct ehci_qh *reclaim; unsigned reclaim_ready : 1; + unsigned scanning : 1; /* periodic schedule support */ #define DEFAULT_I_TDPS 1024 /* some HCs can do less */ diff -Nru a/drivers/usb/host/hc_sl811.c b/drivers/usb/host/hc_sl811.c --- a/drivers/usb/host/hc_sl811.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/host/hc_sl811.c 2004-09-12 22:25:43 -07:00 @@ -1343,15 +1343,11 @@ *****************************************************************/ static void __exit hci_hcd_cleanup (void) { - struct list_head *hci_l; - hci_t *hci; + hci_t *hci, *tmp; DBGFUNC ("Enter hci_hcd_cleanup\n"); - for (hci_l = hci_hcd_list.next; hci_l != &hci_hcd_list;) { - hci = list_entry (hci_l, hci_t, hci_hcd_list); - hci_l = hci_l->next; + list_for_each_entry_safe(hci, tmp, &hci_hcd_list, hci_hcd_list) hc_release_hci (hci); - } } module_init (hci_hcd_init); diff -Nru a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c --- a/drivers/usb/host/ohci-dbg.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/host/ohci-dbg.c 2004-09-12 22:25:43 -07:00 @@ -640,14 +640,14 @@ rdata = ohci_readl (®s->fminterval); temp = scnprintf (next, size, "fmintvl 0x%08x %sFSMPS=0x%04x FI=0x%04x\n", - rdata, (rdata >> 31) ? " FIT" : "", + rdata, (rdata >> 31) ? "FIT " : "", (rdata >> 16) & 0xefff, rdata & 0xffff); size -= temp; next += temp; rdata = ohci_readl (®s->fmremaining); temp = scnprintf (next, size, "fmremaining 0x%08x %sFR=0x%04x\n", - rdata, (rdata >> 31) ? " FRT" : "", + rdata, (rdata >> 31) ? "FRT " : "", rdata & 0x3fff); size -= temp; next += temp; diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c --- a/drivers/usb/host/ohci-hcd.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/host/ohci-hcd.c 2004-09-12 22:25:42 -07:00 @@ -2,7 +2,7 @@ * OHCI HCD (Host Controller Driver) for USB. * * (C) Copyright 1999 Roman Weissgaerber - * (C) Copyright 2000-2002 David Brownell + * (C) Copyright 2000-2004 David Brownell * * [ Initialisation is based on Linus' ] * [ uhci code and gregs ohci fragments ] @@ -122,6 +122,16 @@ #define OHCI_INTR_INIT \ (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_WDH) +#ifdef __hppa__ +/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ +#define IR_DISABLE +#endif + +#ifdef CONFIG_ARCH_OMAP +/* OMAP doesn't support IR (no SMM; not needed) */ +#define IR_DISABLE +#endif + /*-------------------------------------------------------------------------*/ static const char hcd_name [] = "ohci_hcd"; @@ -399,18 +409,24 @@ /* boot firmware should have set this up (5.1.1.3.1) */ if (!ohci->fminterval) { + u32 t2; + temp = ohci_readl (&ohci->regs->fminterval); - if (temp & 0x3fff0000) - ohci->fminterval = temp; - else - ohci->fminterval = DEFAULT_FMINTERVAL; + ohci->fminterval = temp & 0x3fff; + if (ohci->fminterval != FI) + ohci_dbg (ohci, "fminterval delta %d\n", + ohci->fminterval - FI); + + t2 = FSMP (ohci->fminterval); + temp >>= 16; + if ((t2/2) < temp || temp > t2) + temp = t2; + ohci->fminterval |= temp << 16; /* also: power/overcurrent flags in roothub.a */ } - /* SMM owns the HC? not for long! - * On PA-RISC, PDC can leave IR set incorrectly; ignore it there. - */ -#ifndef __hppa__ +#ifndef IR_DISABLE + /* SMM owns the HC? not for long! */ if (ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) { ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n"); @@ -435,18 +451,40 @@ /* Disable HC interrupts */ writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); - ohci_dbg (ohci, "reset, control = 0x%x\n", - ohci_readl (&ohci->regs->control)); - - /* Reset USB (needed by some controllers); RemoteWakeupConnected + /* Reset USB nearly "by the book". RemoteWakeupConnected * saved if boot firmware (BIOS/SMM/...) told us it's connected * (for OHCI integrated on mainboard, it normally is) */ ohci->hc_control = ohci_readl (&ohci->regs->control); - ohci->hc_control &= OHCI_CTRL_RWC; /* hcfs 0 = RESET */ - if (ohci->hc_control) + ohci_dbg (ohci, "resetting from state '%s', control = 0x%x\n", + hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS), + ohci->hc_control); + + if (ohci->hc_control & OHCI_CTRL_RWC + && !(ohci->flags & OHCI_QUIRK_AMD756)) ohci->hcd.can_wakeup = 1; + + switch (ohci->hc_control & OHCI_CTRL_HCFS) { + case OHCI_USB_OPER: + temp = 0; + break; + case OHCI_USB_SUSPEND: + case OHCI_USB_RESUME: + ohci->hc_control &= OHCI_CTRL_RWC; + ohci->hc_control |= OHCI_USB_RESUME; + temp = 10 /* msec wait */; + break; + // case OHCI_USB_RESET: + default: + ohci->hc_control &= OHCI_CTRL_RWC; + ohci->hc_control |= OHCI_USB_RESET; + temp = 50 /* msec wait */; + break; + } writel (ohci->hc_control, &ohci->regs->control); + // flush the writes + (void) ohci_readl (&ohci->regs->control); + msleep(temp); if (power_switching) { unsigned ports = roothub_a (ohci) & RH_A_NDP; @@ -455,9 +493,8 @@ writel (RH_PS_LSDA, &ohci->regs->roothub.portstatus [temp]); } - // flush those pci writes + // flush those writes (void) ohci_readl (&ohci->regs->control); - msleep (50); /* HC Reset requires max 10 us delay */ writel (OHCI_HCR, &ohci->regs->cmdstatus); @@ -469,6 +506,7 @@ } udelay (1); } + periodic_reinit (ohci); /* now we're in the SUSPEND state ... must go OPERATIONAL * within 2msec else HC enters RESUME @@ -477,10 +515,11 @@ * (SiS, OPTi ...), so reset again instead. SiS doesn't need * this if we write fmInterval after we're OPERATIONAL. */ - writel (ohci->hc_control, &ohci->regs->control); - // flush those pci writes - (void) ohci_readl (&ohci->regs->control); - + if (ohci->flags & OHCI_QUIRK_INITRESET) { + writel (ohci->hc_control, &ohci->regs->control); + // flush those writes + (void) ohci_readl (&ohci->regs->control); + } return 0; } @@ -506,8 +545,6 @@ /* a reset clears this */ writel ((u32) ohci->hcca_dma, &ohci->regs->hcca); - periodic_reinit (ohci); - /* some OHCI implementations are finicky about how they init. * bogus values here mean not even enumeration could work. */ @@ -553,7 +590,7 @@ writel (tmp, &ohci->regs->roothub.a); writel (RH_HS_LPSC, &ohci->regs->roothub.status); writel (power_switching ? RH_B_PPCM : 0, &ohci->regs->roothub.b); - // flush those pci writes + // flush those writes (void) ohci_readl (&ohci->regs->control); // POTPGT delay is bits 24-31, in 2 ms units. @@ -620,7 +657,8 @@ // e.g. due to PCI Master/Target Abort ohci_dump (ohci, 1); - hc_reset (ohci); + ohci->hc_control &= OHCI_CTRL_RWC; /* hcfs 0 = RESET */ + writel (ohci->hc_control, &ohci->regs->control); } if (ints & OHCI_INTR_RD) { @@ -655,7 +693,7 @@ if (HCD_IS_RUNNING(ohci->hcd.state)) { writel (ints, ®s->intrstatus); writel (OHCI_INTR_MIE, ®s->intrenable); - // flush those pci writes + // flush those writes (void) ohci_readl (&ohci->regs->control); } @@ -696,18 +734,6 @@ #if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) -static void mark_children_gone (struct usb_device *dev) -{ - unsigned i; - - for (i = 0; i < dev->maxchild; i++) { - if (dev->children [i] == 0) - continue; - dev->children [i]->state = USB_STATE_NOTATTACHED; - mark_children_gone (dev->children [i]); - } -} - static int hc_restart (struct ohci_hcd *ohci) { int temp; @@ -721,7 +747,7 @@ */ spin_lock_irq(&ohci->lock); disable (ohci); - mark_children_gone (ohci->hcd.self.root_hub); + usb_set_device_state (ohci->hcd.self.root_hub, USB_STATE_NOTATTACHED); if (!list_empty (&ohci->pending)) ohci_dbg(ohci, "abort schedule...\n"); list_for_each_entry (priv, &ohci->pending, pending) { diff -Nru a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c --- a/drivers/usb/host/ohci-hub.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/host/ohci-hub.c 2004-09-12 22:25:42 -07:00 @@ -146,10 +146,11 @@ ohci->next_statechange = jiffies + msecs_to_jiffies (5); succeed: - /* it's not USB_STATE_SUSPENDED unless access to this + /* it's not HCD_STATE_SUSPENDED unless access to this * hub from the non-usb side (PCI, SOC, etc) stopped */ root->dev.power.power_state = 3; + root->state = USB_STATE_SUSPENDED; done: spin_unlock_irq (&ohci->lock); return status; @@ -289,7 +290,7 @@ ohci->hc_control |= enables; writel (ohci->hc_control, &ohci->regs->control); if (temp) - writel (status, &ohci->regs->cmdstatus); + writel (temp, &ohci->regs->cmdstatus); (void) ohci_readl (&ohci->regs->control); } @@ -481,8 +482,8 @@ /* this timer value might be vendor-specific ... */ #define PORT_RESET_HW_MSEC 10 -/* wrap-aware logic stolen from */ -#define tick_before(t1,t2) ((((s16)(t1))-((s16)(t2))) < 0) +/* wrap-aware logic morphed from */ +#define tick_before(t1,t2) ((s16)(((s16)(t1))-((s16)(t2))) < 0) /* called from some task, normally khubd */ static inline void root_port_reset (struct ohci_hcd *ohci, unsigned port) diff -Nru a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c --- a/drivers/usb/host/ohci-pci.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/host/ohci-pci.c 2004-09-12 22:25:43 -07:00 @@ -61,6 +61,7 @@ && pdev->device == 0x740c) { ohci->flags = OHCI_QUIRK_AMD756; ohci_info (ohci, "AMD756 erratum 4 workaround\n"); + // also somewhat erratum 10 (suspend/resume issues) } /* FIXME for some of the early AMD 760 southbridges, OHCI @@ -75,6 +76,8 @@ && pdev->device == 0xc861) { ohci_info (ohci, "WARNING: OPTi workarounds unavailable\n"); + /* OPTi sometimes acts wierd during init */ + ohci->flags = OHCI_QUIRK_INITRESET; } /* Check for NSC87560. We have to look at the bridge (fn1) to @@ -92,6 +95,12 @@ ohci_info (ohci, "Using NSC SuperIO setup\n"); } } + + /* SiS sometimes acts wierd during init */ + else if (pdev->vendor == PCI_VENDOR_ID_SI) { + ohci->flags = OHCI_QUIRK_INITRESET; + ohci_info(ohci, "SiS init quirk\n"); + } } @@ -99,6 +108,15 @@ if ((ret = ohci_mem_init (ohci)) < 0) { ohci_stop (hcd); return ret; + } + + /* NOTE: this is a second reset. the first one helps + * keep bios/smm irqs from making trouble, but it was + * probably more than 1msec ago... + */ + if (hc_reset (ohci) < 0) { + ohci_stop (hcd); + return -ENODEV; } if (hc_start (ohci) < 0) { diff -Nru a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h --- a/drivers/usb/host/ohci.h 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/host/ohci.h 2004-09-12 22:25:43 -07:00 @@ -387,6 +387,7 @@ unsigned long flags; /* for HC bugs */ #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ +#define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ // there are also chip quirks/bugs in init logic /* @@ -405,13 +406,14 @@ } #define FI 0x2edf /* 12000 bits per frame (-1) */ -#define DEFAULT_FMINTERVAL ((((6 * (FI - 210)) / 7) << 16) | FI) +#define FSMP(fi) ((6 * ((fi) - 210)) / 7) #define LSTHRESH 0x628 /* lowspeed bit threshold */ static inline void periodic_reinit (struct ohci_hcd *ohci) { + u32 fi = ohci->fminterval & 0x0ffff; writel (ohci->fminterval, &ohci->regs->fminterval); - writel (((9 * FI) / 10) & 0x3fff, &ohci->regs->periodicstart); + writel (((9 * fi) / 10) & 0x3fff, &ohci->regs->periodicstart); writel (LSTHRESH, &ohci->regs->lsthresh); } diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c --- a/drivers/usb/host/uhci-hcd.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/host/uhci-hcd.c 2004-09-12 22:25:43 -07:00 @@ -1661,6 +1661,8 @@ /* Poll for and perform state transitions */ hc_state_transitions(uhci); + if (unlikely(uhci->suspended_ports && uhci->state != UHCI_SUSPENDED)) + uhci_check_resume(uhci); init_stall_timer(hcd); } diff -Nru a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h --- a/drivers/usb/host/uhci-hcd.h 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/host/uhci-hcd.h 2004-09-12 22:25:43 -07:00 @@ -352,6 +352,12 @@ int resume_detect; /* Need a Global Resume */ unsigned int saved_framenumber; /* Save during PM suspend */ + /* Support for port suspend/resume */ + unsigned long port_c_suspend; /* Bit-arrays of ports */ + unsigned long suspended_ports; + unsigned long resuming_ports; + unsigned long resume_timeout; /* Time to stop signalling */ + /* Main list of URB's currently controlled by this HC */ struct list_head urb_list; /* P: uhci->schedule_lock */ diff -Nru a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c --- a/drivers/usb/host/uhci-hub.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/host/uhci-hub.c 2004-09-12 22:25:42 -07:00 @@ -36,13 +36,13 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); - unsigned long io_addr = uhci->io_addr; - int i; + int port; *buf = 0; - for (i = 0; i < uhci->rh_numports; i++) { - if (inw(io_addr + USBPORTSC1 + i * 2) & RWC_BITS) - *buf |= (1 << (i + 1)); + for (port = 0; port < uhci->rh_numports; ++port) { + if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & RWC_BITS) || + test_bit(port, &uhci->port_c_suspend)) + *buf |= (1 << (port + 1)); } return !!*buf; } @@ -62,31 +62,67 @@ status &= ~(RWC_BITS|WZ_BITS); \ outw(status, port_addr) +/* UHCI controllers don't automatically stop resume signalling after 20 msec, + * so we have to poll and check timeouts in order to take care of it. + * FIXME: Synchronize access to these fields by a spinlock. + */ +static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, + unsigned int port_addr) +{ + int status; + + if (test_bit(port, &uhci->suspended_ports)) { + CLR_RH_PORTSTAT(USBPORTSC_SUSP | USBPORTSC_RD); + clear_bit(port, &uhci->suspended_ports); + clear_bit(port, &uhci->resuming_ports); + set_bit(port, &uhci->port_c_suspend); + } +} + +static void uhci_check_resume(struct uhci_hcd *uhci) +{ + unsigned int port; + unsigned int port_addr; + + for (port = 0; port < uhci->rh_numports; ++port) { + port_addr = uhci->io_addr + USBPORTSC1 + 2 * port; + if (unlikely(inw(port_addr) & USBPORTSC_RD)) { + if (!test_bit(port, &uhci->resuming_ports)) { + + /* Port received a wakeup request */ + set_bit(port, &uhci->resuming_ports); + uhci->resume_timeout = jiffies + + msecs_to_jiffies(20); + } else if (time_after_eq(jiffies, + uhci->resume_timeout)) { + uhci_finish_suspend(uhci, port, port_addr); + } + } + } +} /* size of returned buffer is part of USB spec */ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); - int status, retval = 0, len = 0; - unsigned long port_addr = uhci->io_addr + USBPORTSC1 + 2 * (wIndex-1); - __u16 wPortChange, wPortStatus; + int status, lstatus, retval = 0, len = 0; + unsigned int port = wIndex - 1; + unsigned long port_addr = uhci->io_addr + USBPORTSC1 + 2 * port; + u16 wPortChange, wPortStatus; switch (typeReq) { - /* Request Destination: - without flags: Device, - RH_INTERFACE: interface, - RH_ENDPOINT: endpoint, - RH_CLASS means HUB here, - RH_OTHER | RH_CLASS almost ever means HUB_PORT here - */ case GetHubStatus: - *(__u32 *)buf = cpu_to_le32(0); + *(u32 *) buf = cpu_to_le32(0); OK(4); /* hub power */ case GetPortStatus: - if (!wIndex || wIndex > uhci->rh_numports) + if (port >= uhci->rh_numports) goto err; + + if (uhci->resuming_ports) + uhci_check_resume(uhci); + status = inw(port_addr); /* Intel controllers report the OverCurrent bit active on. @@ -97,37 +133,46 @@ PCI_VENDOR_ID_VIA) status ^= USBPORTSC_OC; - /* UHCI doesn't support C_SUSPEND and C_RESET (always false) */ - wPortChange = 0; + /* UHCI doesn't support C_RESET (always false) */ + wPortChange = lstatus = 0; if (status & USBPORTSC_CSC) - wPortChange |= 1 << (USB_PORT_FEAT_C_CONNECTION - 16); + wPortChange |= USB_PORT_STAT_C_CONNECTION; if (status & USBPORTSC_PEC) - wPortChange |= 1 << (USB_PORT_FEAT_C_ENABLE - 16); + wPortChange |= USB_PORT_STAT_C_ENABLE; if (status & USBPORTSC_OCC) - wPortChange |= 1 << (USB_PORT_FEAT_C_OVER_CURRENT - 16); + wPortChange |= USB_PORT_STAT_C_OVERCURRENT; + + if (test_bit(port, &uhci->port_c_suspend)) { + wPortChange |= USB_PORT_STAT_C_SUSPEND; + lstatus |= 1; + } + if (test_bit(port, &uhci->suspended_ports)) + lstatus |= 2; + if (test_bit(port, &uhci->resuming_ports)) + lstatus |= 4; /* UHCI has no power switching (always on) */ - wPortStatus = 1 << USB_PORT_FEAT_POWER; + wPortStatus = USB_PORT_STAT_POWER; if (status & USBPORTSC_CCS) - wPortStatus |= 1 << USB_PORT_FEAT_CONNECTION; + wPortStatus |= USB_PORT_STAT_CONNECTION; if (status & USBPORTSC_PE) { - wPortStatus |= 1 << USB_PORT_FEAT_ENABLE; + wPortStatus |= USB_PORT_STAT_ENABLE; if (status & (USBPORTSC_SUSP | USBPORTSC_RD)) - wPortStatus |= 1 << USB_PORT_FEAT_SUSPEND; + wPortStatus |= USB_PORT_STAT_SUSPEND; } if (status & USBPORTSC_OC) - wPortStatus |= 1 << USB_PORT_FEAT_OVER_CURRENT; + wPortStatus |= USB_PORT_STAT_OVERCURRENT; if (status & USBPORTSC_PR) - wPortStatus |= 1 << USB_PORT_FEAT_RESET; + wPortStatus |= USB_PORT_STAT_RESET; if (status & USBPORTSC_LSDA) - wPortStatus |= 1 << USB_PORT_FEAT_LOWSPEED; + wPortStatus |= USB_PORT_STAT_LOW_SPEED; if (wPortChange) - dev_dbg(uhci_dev(uhci), "port %d portsc %04x\n", - wIndex, status); + dev_dbg(uhci_dev(uhci), "port %d portsc %04x,%02x\n", + wIndex, status, lstatus); - *(__u16 *)buf = cpu_to_le16(wPortStatus); - *(__u16 *)(buf + 2) = cpu_to_le16(wPortChange); + *(u16 *) buf = cpu_to_le16(wPortStatus); + *(u16 *) (buf + 2) = cpu_to_le16(wPortChange); OK(4); case SetHubFeature: /* We don't implement these */ case ClearHubFeature: @@ -140,11 +185,12 @@ } break; case SetPortFeature: - if (!wIndex || wIndex > uhci->rh_numports) + if (port >= uhci->rh_numports) goto err; switch (wValue) { case USB_PORT_FEAT_SUSPEND: + set_bit(port, &uhci->suspended_ports); SET_RH_PORTSTAT(USBPORTSC_SUSP); OK(0); case USB_PORT_FEAT_RESET: @@ -152,6 +198,9 @@ mdelay(50); /* USB v1.1 7.1.7.3 */ CLR_RH_PORTSTAT(USBPORTSC_PR); udelay(10); + + /* Reset terminates Resume signalling */ + uhci_finish_suspend(uhci, port, port_addr); SET_RH_PORTSTAT(USBPORTSC_PE); mdelay(10); CLR_RH_PORTSTAT(USBPORTSC_PEC|USBPORTSC_CSC); @@ -164,21 +213,38 @@ } break; case ClearPortFeature: - if (!wIndex || wIndex > uhci->rh_numports) + if (port >= uhci->rh_numports) goto err; switch (wValue) { case USB_PORT_FEAT_ENABLE: CLR_RH_PORTSTAT(USBPORTSC_PE); + + /* Disable terminates Resume signalling */ + uhci_finish_suspend(uhci, port, port_addr); OK(0); case USB_PORT_FEAT_C_ENABLE: CLR_RH_PORTSTAT(USBPORTSC_PEC); OK(0); case USB_PORT_FEAT_SUSPEND: - CLR_RH_PORTSTAT(USBPORTSC_SUSP); + if (test_bit(port, &uhci->suspended_ports) && + !test_and_set_bit(port, + &uhci->resuming_ports)) { + uhci->resume_timeout = jiffies + + msecs_to_jiffies(20); + SET_RH_PORTSTAT(USBPORTSC_RD); + + /* The controller won't allow RD to be set + * if the port is disabled. When this happens + * just skip the Resume signalling. + */ + if (!(inw(port_addr) & USBPORTSC_RD)) + uhci_finish_suspend(uhci, port, + port_addr); + } OK(0); case USB_PORT_FEAT_C_SUSPEND: - /* this driver won't report these */ + clear_bit(port, &uhci->port_c_suspend); OK(0); case USB_PORT_FEAT_POWER: /* UHCI has no power switching */ diff -Nru a/drivers/usb/image/Kconfig b/drivers/usb/image/Kconfig --- a/drivers/usb/image/Kconfig 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/image/Kconfig 2004-09-12 22:25:42 -07:00 @@ -30,11 +30,12 @@ This driver can be compiled as a module, called microtek. config USB_HPUSBSCSI - tristate "HP53xx USB scanner support (EXPERIMENTAL)" - depends on USB && SCSI && EXPERIMENTAL + tristate "HP53xx USB scanner support" + depends on USB && SCSI help Say Y here if you want support for the HP 53xx series of scanners - and the Minolta Scan Dual. This driver is experimental. + and the Minolta Scan Dual. The scanner will be accessible as a SCSI device. + Please note that recent versions of SANE use usbfs, not this driver. This can be compiled as a module, called hpusbscsi. diff -Nru a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c --- a/drivers/usb/image/microtek.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/image/microtek.c 2004-09-12 22:25:43 -07:00 @@ -324,7 +324,7 @@ MTS_DEBUG_GOT_HERE(); mts_debug_dump(desc); - usb_unlink_urb( desc->urb ); + usb_kill_urb( desc->urb ); } static int mts_scsi_abort (Scsi_Cmnd *srb) @@ -822,10 +822,10 @@ usb_set_intfdata(intf, NULL); + usb_kill_urb(desc->urb); scsi_remove_host(desc->host); - usb_unlink_urb(desc->urb); - scsi_host_put(desc->host); + scsi_host_put(desc->host); usb_free_urb(desc->urb); kfree(desc); } diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c --- a/drivers/usb/input/hid-core.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/input/hid-core.c 2004-09-12 22:25:42 -07:00 @@ -1439,6 +1439,12 @@ #define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 #define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 +#define USB_VENDOR_ID_CODEMERCS 0x07c0 +#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500 +#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501 +#define USB_DEVICE_ID_CODEMERCS_IOW48 0x1502 +#define USB_DEVICE_ID_CODEMERCS_IOW28 0x1503 + static struct hid_blacklist { __u16 idVendor; __u16 idProduct; @@ -1520,6 +1526,11 @@ { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, + + { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, { 0, 0 } }; diff -Nru a/drivers/usb/media/Kconfig b/drivers/usb/media/Kconfig --- a/drivers/usb/media/Kconfig 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/media/Kconfig 2004-09-12 22:25:42 -07:00 @@ -123,11 +123,11 @@ module will be called se401. config USB_SN9C102 - tristate "USB SN9C10[12] PC Camera Controller support" + tristate "USB SN9C10x PC Camera Controller support" depends on USB && VIDEO_DEV ---help--- - Say Y here if you want support for cameras based on SONiX SN9C101 - or SN9C102 PC Camera Controllers. + Say Y here if you want support for cameras based on SONiX SN9C101, + SN9C102 or SN9C103 PC Camera Controllers. See for more informations. diff -Nru a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c --- a/drivers/usb/media/dabusb.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/media/dabusb.c 2004-09-12 22:25:42 -07:00 @@ -109,16 +109,13 @@ static int dabusb_cancel_queue (pdabusb_t s, struct list_head *q) { unsigned long flags; - struct list_head *p; pbuff_t b; dbg("dabusb_cancel_queue"); spin_lock_irqsave (&s->lock, flags); - for (p = q->next; p != q; p = p->next) { - b = list_entry (p, buff_t, buff_list); - + list_for_each_entry(b, q, buff_list) { #ifdef DEBUG dump_urb(b->purb); #endif @@ -598,6 +595,7 @@ if (file->f_flags & O_NONBLOCK) { return -EBUSY; } + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout (HZ / 2); if (signal_pending (current)) { diff -Nru a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c --- a/drivers/usb/media/konicawc.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/media/konicawc.c 2004-09-12 22:25:42 -07:00 @@ -362,8 +362,8 @@ else if (!urb->status && !cam->last_data_urb->status) len = konicawc_compress_iso(uvd, cam->last_data_urb, urb); - resubmit_urb(uvd, urb); resubmit_urb(uvd, cam->last_data_urb); + resubmit_urb(uvd, urb); cam->last_data_urb = NULL; uvd->stats.urb_length = len; uvd->stats.data_count += len; diff -Nru a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h --- a/drivers/usb/media/sn9c102.h 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/media/sn9c102.h 2004-09-12 22:25:42 -07:00 @@ -1,5 +1,5 @@ /*************************************************************************** - * V4L2 driver for SN9C10[12] PC Camera Controllers * + * V4L2 driver for SN9C10x PC Camera Controllers * * * * Copyright (C) 2004 by Luca Risolia * * * @@ -49,12 +49,18 @@ /*****************************************************************************/ -#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10[12] PC Camera Controllers" +#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers" #define SN9C102_MODULE_AUTHOR "(C) 2004 Luca Risolia" #define SN9C102_AUTHOR_EMAIL "" #define SN9C102_MODULE_LICENSE "GPL" -#define SN9C102_MODULE_VERSION "1:1.08" -#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 8) +#define SN9C102_MODULE_VERSION "1:1.10" +#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 10) + +enum sn9c102_bridge { + BRIDGE_SN9C101 = 0x01, + BRIDGE_SN9C102 = 0x02, + BRIDGE_SN9C103 = 0x04, +}; SN9C102_ID_TABLE; SN9C102_SENSOR_TABLE; @@ -105,6 +111,7 @@ struct video_device* v4ldev; + enum sn9c102_bridge bridge; struct sn9c102_sensor* sensor; struct usb_device* usbdev; diff -Nru a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c --- a/drivers/usb/media/sn9c102_core.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/media/sn9c102_core.c 2004-09-12 22:25:42 -07:00 @@ -1,5 +1,5 @@ /*************************************************************************** - * V4L2 driver for SN9C10[12] PC Camera Controllers * + * V4L2 driver for SN9C10x PC Camera Controllers * * * * Copyright (C) 2004 by Luca Risolia * * * @@ -169,15 +169,15 @@ cam->nbuffers = count; while (cam->nbuffers > 0) { - if ((buff = rvmalloc(cam->nbuffers * imagesize))) + if ((buff = rvmalloc(cam->nbuffers * PAGE_ALIGN(imagesize)))) break; cam->nbuffers--; } for (i = 0; i < cam->nbuffers; i++) { - cam->frame[i].bufmem = buff + i*imagesize; + cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize); cam->frame[i].buf.index = i; - cam->frame[i].buf.m.offset = i*imagesize; + cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize); cam->frame[i].buf.length = imagesize; cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; cam->frame[i].buf.sequence = 0; @@ -388,7 +388,7 @@ data[4] = data3; data[5] = data4; data[6] = data5; - data[7] = 0x10; + data[7] = 0x14; res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41, 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT); if (res < 0) @@ -1022,15 +1022,79 @@ static ssize_t sn9c102_store_green(struct class_device* cd, const char* buf, size_t len) { + struct sn9c102_device* cam; + enum sn9c102_bridge bridge; ssize_t res = 0; u8 value; ssize_t count; + if (down_interruptible(&sn9c102_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { + up(&sn9c102_sysfs_lock); + return -ENODEV; + } + + bridge = cam->bridge; + + up(&sn9c102_sysfs_lock); + value = sn9c102_strtou8(buf, len, &count); - if (!count || value > 0x0f) + if (!count) return -EINVAL; - if ((res = sn9c102_store_reg(cd, "0x11", 4)) >= 0) + switch (bridge) { + case BRIDGE_SN9C101: + case BRIDGE_SN9C102: + if (value > 0x0f) + return -EINVAL; + if ((res = sn9c102_store_reg(cd, "0x11", 4)) >= 0) + res = sn9c102_store_val(cd, buf, len); + break; + case BRIDGE_SN9C103: + if (value > 0x7f) + return -EINVAL; + if ((res = sn9c102_store_reg(cd, "0x04", 4)) >= 0) + res = sn9c102_store_val(cd, buf, len); + break; + } + + return res; +} + + +static ssize_t +sn9c102_store_blue(struct class_device* cd, const char* buf, size_t len) +{ + ssize_t res = 0; + u8 value; + ssize_t count; + + value = sn9c102_strtou8(buf, len, &count); + if (!count || value > 0x7f) + return -EINVAL; + + if ((res = sn9c102_store_reg(cd, "0x06", 4)) >= 0) + res = sn9c102_store_val(cd, buf, len); + + return res; +} + + +static ssize_t +sn9c102_store_red(struct class_device* cd, const char* buf, size_t len) +{ + ssize_t res = 0; + u8 value; + ssize_t count; + + value = sn9c102_strtou8(buf, len, &count); + if (!count || value > 0x7f) + return -EINVAL; + + if ((res = sn9c102_store_reg(cd, "0x05", 4)) >= 0) res = sn9c102_store_val(cd, buf, len); return res; @@ -1046,6 +1110,8 @@ static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR, sn9c102_show_i2c_val, sn9c102_store_i2c_val); static CLASS_DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green); +static CLASS_DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue); +static CLASS_DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red); static void sn9c102_create_sysfs(struct sn9c102_device* cam) @@ -1054,7 +1120,12 @@ video_device_create_file(v4ldev, &class_device_attr_reg); video_device_create_file(v4ldev, &class_device_attr_val); - video_device_create_file(v4ldev, &class_device_attr_green); + if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) + video_device_create_file(v4ldev, &class_device_attr_green); + else if (cam->bridge == BRIDGE_SN9C103) { + video_device_create_file(v4ldev, &class_device_attr_blue); + video_device_create_file(v4ldev, &class_device_attr_red); + } if (cam->sensor->slave_write_id && cam->sensor->slave_read_id) { video_device_create_file(v4ldev, &class_device_attr_i2c_reg); video_device_create_file(v4ldev, &class_device_attr_i2c_val); @@ -1092,21 +1163,13 @@ u8 h_start = (u8)(rect->left - s->cropcap.bounds.left), v_start = (u8)(rect->top - s->cropcap.bounds.top), h_size = (u8)(rect->width / 16), - v_size = (u8)(rect->height / 16), - ae_strx = 0x00, - ae_stry = 0x00, - ae_endx = h_size / 2, - ae_endy = v_size / 2; + v_size = (u8)(rect->height / 16); int err = 0; err += sn9c102_write_reg(cam, h_start, 0x12); err += sn9c102_write_reg(cam, v_start, 0x13); err += sn9c102_write_reg(cam, h_size, 0x15); err += sn9c102_write_reg(cam, v_size, 0x16); - err += sn9c102_write_reg(cam, ae_strx, 0x1c); - err += sn9c102_write_reg(cam, ae_stry, 0x1d); - err += sn9c102_write_reg(cam, ae_endx, 0x1e); - err += sn9c102_write_reg(cam, ae_endy, 0x1f); if (err) return -EIO; @@ -1636,16 +1699,21 @@ if (copy_from_user(&ctrl, arg, sizeof(ctrl))) return -EFAULT; - if ((err = s->set_ctrl(cam, &ctrl))) - return err; - n = sizeof(s->qctrl) / sizeof(s->qctrl[0]); for (i = 0; i < n; i++) if (ctrl.id == s->qctrl[i].id) { - s->_qctrl[i].default_value = ctrl.value; + if (ctrl.value < s->qctrl[i].minimum || + ctrl.value > s->qctrl[i].maximum) + return -ERANGE; + ctrl.value -= ctrl.value % s->qctrl[i].step; break; } + if ((err = s->set_ctrl(cam, &ctrl))) + return err; + + s->_qctrl[i].default_value = ctrl.value; + return 0; } @@ -1776,7 +1844,7 @@ DBG(1, "VIDIOC_S_CROP failed because of hardware " "problems. To use the camera, close and open " "/dev/video%d again.", cam->v4ldev->minor) - return err; + return -EIO; } s->pix_format.width = rect->width/scale; @@ -1951,7 +2019,7 @@ DBG(1, "VIDIOC_S_FMT failed because of hardware " "problems. To use the camera, close and open " "/dev/video%d again.", cam->v4ldev->minor) - return err; + return -EIO; } memcpy(pfmt, pix, sizeof(*pix)); @@ -2286,15 +2354,17 @@ r = sn9c102_read_reg(cam, 0x00); if (r < 0 || r != 0x10) { - DBG(1, "Sorry, this is not a SN9C10[12] based camera " + DBG(1, "Sorry, this is not a SN9C10x based camera " "(vid/pid 0x%04X/0x%04X)", sn9c102_id_table[i].idVendor,sn9c102_id_table[i].idProduct) err = -ENODEV; goto fail; } - DBG(2, "SN9C10[12] PC Camera Controller detected " - "(vid/pid 0x%04X/0x%04X)", + cam->bridge = (sn9c102_id_table[i].idProduct & 0xffc0) == 0x6080 ? + BRIDGE_SN9C102 : BRIDGE_SN9C103; + + DBG(2, "SN9C10x PC Camera Controller detected (vid/pid 0x%04X/0x%04X)", sn9c102_id_table[i].idVendor, sn9c102_id_table[i].idProduct) for (i = 0; sn9c102_sensor_table[i]; i++) { @@ -2318,7 +2388,7 @@ cam->state |= DEV_MISCONFIGURED; } - strcpy(cam->v4ldev->name, "SN9C10[12] PC Camera"); + strcpy(cam->v4ldev->name, "SN9C10x PC Camera"); cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->hardware = VID_HARDWARE_SN9C102; diff -Nru a/drivers/usb/media/sn9c102_pas106b.c b/drivers/usb/media/sn9c102_pas106b.c --- a/drivers/usb/media/sn9c102_pas106b.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/media/sn9c102_pas106b.c 2004-09-12 22:25:42 -07:00 @@ -1,5 +1,5 @@ /*************************************************************************** - * Driver for PAS106B image sensor connected to the SN9C10[12] PC Camera * + * Driver for PAS106B image sensor connected to the SN9C10x PC Camera * * Controllers * * * * Copyright (C) 2004 by Luca Risolia * @@ -100,26 +100,26 @@ switch (ctrl->id) { case V4L2_CID_RED_BALANCE: - err += sn9c102_i2c_write(cam, 0x0c, ctrl->value & 0x1f); + err += sn9c102_i2c_write(cam, 0x0c, ctrl->value); break; case V4L2_CID_BLUE_BALANCE: - err += sn9c102_i2c_write(cam, 0x09, ctrl->value & 0x1f); + err += sn9c102_i2c_write(cam, 0x09, ctrl->value); break; case V4L2_CID_GAIN: - err += sn9c102_i2c_write(cam, 0x0e, ctrl->value & 0x1f); + err += sn9c102_i2c_write(cam, 0x0e, ctrl->value); break; case V4L2_CID_BRIGHTNESS: - err += sn9c102_i2c_write(cam, 0x0d, 0x1f-(ctrl->value & 0x1f)); + err += sn9c102_i2c_write(cam, 0x0d, 0x1f - ctrl->value); break; case V4L2_CID_CONTRAST: - err += sn9c102_i2c_write(cam, 0x0f, ctrl->value & 0x03); + err += sn9c102_i2c_write(cam, 0x0f, ctrl->value); break; default: return -EINVAL; } err += sn9c102_i2c_write(cam, 0x13, 0x01); - return err; + return err ? -EIO : 0; } diff -Nru a/drivers/usb/media/sn9c102_pas202bcb.c b/drivers/usb/media/sn9c102_pas202bcb.c --- a/drivers/usb/media/sn9c102_pas202bcb.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/media/sn9c102_pas202bcb.c 2004-09-12 22:25:43 -07:00 @@ -1,5 +1,5 @@ /*************************************************************************** - * Driver for PAS202BCB image sensor connected to the SN9C10[12] PC Camera * + * Driver for PAS202BCB image sensor connected to the SN9C10x PC Camera * * Controllers * * * * Copyright (C) 2004 by Carlos Eduardo Medaglia Dyonisio * @@ -95,23 +95,23 @@ switch (ctrl->id) { case V4L2_CID_RED_BALANCE: - err += sn9c102_i2c_write(cam, 0x09, ctrl->value & 0x0f); + err += sn9c102_i2c_write(cam, 0x09, ctrl->value); break; case V4L2_CID_BLUE_BALANCE: - err += sn9c102_i2c_write(cam, 0x07, ctrl->value & 0x0f); + err += sn9c102_i2c_write(cam, 0x07, ctrl->value); break; case V4L2_CID_GAIN: - err += sn9c102_i2c_write(cam, 0x10, ctrl->value & 0x1f); + err += sn9c102_i2c_write(cam, 0x10, ctrl->value); break; case V4L2_CID_BRIGHTNESS: - err += sn9c102_i2c_write(cam, 0x06, 0x0f-(ctrl->value & 0x0f)); + err += sn9c102_i2c_write(cam, 0x06, 0x0f - ctrl->value); break; default: return -EINVAL; } err += sn9c102_i2c_write(cam, 0x11, 0x01); - return err; + return err ? -EIO : 0; } diff -Nru a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h --- a/drivers/usb/media/sn9c102_sensor.h 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/media/sn9c102_sensor.h 2004-09-12 22:25:42 -07:00 @@ -1,5 +1,5 @@ /*************************************************************************** - * API for image sensors connected to the SN9C10[12] PC Camera Controllers * + * API for image sensors connected to the SN9C10x PC Camera Controllers * * * * Copyright (C) 2004 by Luca Risolia * * * @@ -89,17 +89,44 @@ /* Each SN9C10X camera has proper PID/VID identifiers. Add them here in case.*/ #define SN9C102_ID_TABLE \ static const struct usb_device_id sn9c102_id_table[] = { \ - { USB_DEVICE(0xc45, 0x6001), }, /* TAS5110C1B */ \ - { USB_DEVICE(0xc45, 0x6005), }, /* TAS5110C1B */ \ - { USB_DEVICE(0xc45, 0x6009), }, /* PAS106B */ \ - { USB_DEVICE(0xc45, 0x600d), }, /* PAS106B */ \ - { USB_DEVICE(0xc45, 0x6024), }, \ - { USB_DEVICE(0xc45, 0x6025), }, /* TAS5130D1B and TAS5110C1B */ \ - { USB_DEVICE(0xc45, 0x6028), }, /* PAS202BCB */ \ - { USB_DEVICE(0xc45, 0x6029), }, /* PAS106B */ \ - { USB_DEVICE(0xc45, 0x602a), }, /* HV7131[D|E1] */ \ - { USB_DEVICE(0xc45, 0x602c), }, /* OV7620 */ \ - { USB_DEVICE(0xc45, 0x6030), }, /* MI03 */ \ + { USB_DEVICE(0x0c45, 0x6001), }, /* TAS5110C1B */ \ + { USB_DEVICE(0x0c45, 0x6005), }, /* TAS5110C1B */ \ + { USB_DEVICE(0x0c45, 0x6009), }, /* PAS106B */ \ + { USB_DEVICE(0x0c45, 0x600d), }, /* PAS106B */ \ + { USB_DEVICE(0x0c45, 0x6024), }, \ + { USB_DEVICE(0x0c45, 0x6025), }, /* TAS5130D1B and TAS5110C1B */ \ + { USB_DEVICE(0x0c45, 0x6028), }, /* PAS202BCB */ \ + { USB_DEVICE(0x0c45, 0x6029), }, /* PAS106B */ \ + { USB_DEVICE(0x0c45, 0x602a), }, /* HV7131[D|E1] */ \ + { USB_DEVICE(0x0c45, 0x602b), }, \ + { USB_DEVICE(0x0c45, 0x602c), }, /* OV7620 */ \ + { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \ + { USB_DEVICE(0x0c45, 0x6080), }, \ + { USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */ \ + { USB_DEVICE(0x0c45, 0x6083), }, /* HV7131[D|E1] */ \ + { USB_DEVICE(0x0c45, 0x6088), }, \ + { USB_DEVICE(0x0c45, 0x608a), }, \ + { USB_DEVICE(0x0c45, 0x608b), }, \ + { USB_DEVICE(0x0c45, 0x608c), }, /* HV7131x */ \ + { USB_DEVICE(0x0c45, 0x608e), }, /* CIS-VF10 */ \ + { USB_DEVICE(0x0c45, 0x608f), }, /* OV7630 */ \ + { USB_DEVICE(0x0c45, 0x60a0), }, \ + { USB_DEVICE(0x0c45, 0x60a2), }, \ + { USB_DEVICE(0x0c45, 0x60a3), }, \ + { USB_DEVICE(0x0c45, 0x60a8), }, /* PAS106B */ \ + { USB_DEVICE(0x0c45, 0x60aa), }, /* TAS5130D1B */ \ + { USB_DEVICE(0x0c45, 0x60ab), }, /* TAS5110C1B */ \ + { USB_DEVICE(0x0c45, 0x60ac), }, \ + { USB_DEVICE(0x0c45, 0x60ae), }, \ + { USB_DEVICE(0x0c45, 0x60af), }, /* PAS202BCB */ \ + { USB_DEVICE(0x0c45, 0x60b0), }, \ + { USB_DEVICE(0x0c45, 0x60b2), }, \ + { USB_DEVICE(0x0c45, 0x60b3), }, \ + { USB_DEVICE(0x0c45, 0x60b8), }, \ + { USB_DEVICE(0x0c45, 0x60ba), }, \ + { USB_DEVICE(0x0c45, 0x60bb), }, \ + { USB_DEVICE(0x0c45, 0x60bc), }, \ + { USB_DEVICE(0x0c45, 0x60be), }, \ { } \ }; @@ -173,9 +200,7 @@ /* These identifiers must be provided if the image sensor implements - the standard I2C protocol. TASC sensors don't, although they have a - serial interface: so this is a case where the "raw" I2C version - could be helpful. + the standard I2C protocol. */ u8 slave_read_id, slave_write_id; /* reg. 0x09 */ @@ -214,7 +239,8 @@ the list above. The returned value must follow the V4L2 specifications for the VIDIOC_G|C_CTRL ioctls. V4L2_CID_H|VCENTER are not supported by this driver, so do not implement them. Also, - passed values are NOT checked to see if they are out of bounds. + you don't have to check whether the passed values are out of bounds, + given that this is done by the core module. */ struct v4l2_cropcap cropcap; diff -Nru a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c --- a/drivers/usb/media/sn9c102_tas5110c1b.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/media/sn9c102_tas5110c1b.c 2004-09-12 22:25:42 -07:00 @@ -1,6 +1,6 @@ /*************************************************************************** - * Driver for TAS5110C1B image sensor connected to the SN9C10[12] PC * - * Camera Controllers * + * Driver for TAS5110C1B image sensor connected to the SN9C10x PC Camera * + * Controllers * * * * Copyright (C) 2004 by Luca Risolia * * * @@ -24,6 +24,8 @@ static struct sn9c102_sensor tas5110c1b; +static struct v4l2_control tas5110c1b_gain; + static int tas5110c1b_init(struct sn9c102_device* cam) { @@ -38,25 +40,42 @@ err += sn9c102_write_reg(cam, 0x06, 0x18); err += sn9c102_write_reg(cam, 0xfb, 0x19); - err += sn9c102_i2c_try_raw_write(cam, &tas5110c1b, 4, 0x11, 0x00, 0xc0, - 0x80, 0, 0); + err += sn9c102_i2c_write(cam, 0xc0, 0x80); return err; } +static int tas5110c1b_get_ctrl(struct sn9c102_device* cam, + struct v4l2_control* ctrl) +{ + switch (ctrl->id) { + case V4L2_CID_GAIN: + ctrl->value = tas5110c1b_gain.value; + break; + default: + return -EINVAL; + } + + return 0; +} + + static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, const struct v4l2_control* ctrl) { + int err = 0; + switch (ctrl->id) { case V4L2_CID_GAIN: - return sn9c102_i2c_try_raw_write(cam, &tas5110c1b, 4, 0x11, - 0x02, 0x20, - 0xff - (ctrl->value & 0xff), - 0, 0); + if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value))) + tas5110c1b_gain.value = ctrl->value; + break; default: return -EINVAL; } + + return err ? -EIO : 0; } @@ -85,6 +104,8 @@ .maintainer = "Luca Risolia ", .frequency = SN9C102_I2C_100KHZ, .interface = SN9C102_I2C_3WIRES, + .slave_read_id = 0xff, /* fictitious */ + .slave_write_id = 0xff, /* fictitious */ .init = &tas5110c1b_init, .qctrl = { { @@ -92,9 +113,9 @@ .type = V4L2_CTRL_TYPE_INTEGER, .name = "global gain", .minimum = 0x00, - .maximum = 0xff, + .maximum = 0xf6, .step = 0x01, - .default_value = 0x48, + .default_value = 0x40, .flags = 0, }, }, @@ -113,6 +134,7 @@ .height = 288, }, }, + .get_ctrl = &tas5110c1b_get_ctrl, .set_crop = &tas5110c1b_set_crop, .pix_format = { .width = 352, @@ -130,7 +152,8 @@ /* At the moment, sensor detection is based on USB pid/vid */ if (tas5110c1b.usbdev->descriptor.idProduct != 0x6001 && - tas5110c1b.usbdev->descriptor.idProduct != 0x6005) + tas5110c1b.usbdev->descriptor.idProduct != 0x6005 && + tas5110c1b.usbdev->descriptor.idProduct != 0x60ab) return -ENODEV; return 0; diff -Nru a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c --- a/drivers/usb/media/sn9c102_tas5130d1b.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/media/sn9c102_tas5130d1b.c 2004-09-12 22:25:42 -07:00 @@ -1,6 +1,6 @@ /*************************************************************************** - * Driver for TAS5130D1B image sensor connected to the SN9C10[12] PC * - * Camera Controllers * + * Driver for TAS5130D1B image sensor connected to the SN9C10x PC Camera * + * Controllers * * * * Copyright (C) 2004 by Luca Risolia * * * @@ -24,6 +24,8 @@ static struct sn9c102_sensor tas5130d1b; +static struct v4l2_control tas5130d1b_gain, tas5130d1b_exposure; + static int tas5130d1b_init(struct sn9c102_device* cam) { @@ -38,25 +40,47 @@ err += sn9c102_write_reg(cam, 0x60, 0x17); err += sn9c102_write_reg(cam, 0x07, 0x18); - err += sn9c102_i2c_try_raw_write(cam, &tas5130d1b, 4, 0x11, 0x00, 0x40, - 0x47, 0, 0); - return err; } +static int tas5130d1b_get_ctrl(struct sn9c102_device* cam, + struct v4l2_control* ctrl) +{ + switch (ctrl->id) { + case V4L2_CID_GAIN: + ctrl->value = tas5130d1b_gain.value; + break; + case V4L2_CID_EXPOSURE: + ctrl->value = tas5130d1b_exposure.value; + break; + default: + return -EINVAL; + } + + return 0; +} + + static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, const struct v4l2_control* ctrl) { + int err = 0; + switch (ctrl->id) { case V4L2_CID_GAIN: - return sn9c102_i2c_try_raw_write(cam, &tas5130d1b, 4, 0x11, - 0x02, 0x20, - 0xff - (ctrl->value & 0xff), - 0, 0); + if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value))) + tas5130d1b_gain.value = ctrl->value; + break; + case V4L2_CID_EXPOSURE: + if (!(err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value))) + tas5130d1b_exposure.value = ctrl->value; + break; default: return -EINVAL; } + + return err ? -EIO : 0; } @@ -85,6 +109,8 @@ .maintainer = "Luca Risolia ", .frequency = SN9C102_I2C_100KHZ, .interface = SN9C102_I2C_3WIRES, + .slave_read_id = 0xff, /* fictitious */ + .slave_write_id = 0xff, /* fictitious */ .init = &tas5130d1b_init, .qctrl = { { @@ -92,12 +118,23 @@ .type = V4L2_CTRL_TYPE_INTEGER, .name = "global gain", .minimum = 0x00, - .maximum = 0xff, + .maximum = 0xf6, + .step = 0x02, + .default_value = 0x00, + .flags = 0, + }, + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "exposure", + .minimum = 0x00, + .maximum = 0x47, .step = 0x01, .default_value = 0x00, .flags = 0, }, }, + .get_ctrl = &tas5130d1b_get_ctrl, .set_ctrl = &tas5130d1b_set_ctrl, .cropcap = { .bounds = { @@ -129,7 +166,8 @@ sn9c102_attach_sensor(cam, &tas5130d1b); /* At the moment, sensor detection is based on USB pid/vid */ - if (tas5130d1b.usbdev->descriptor.idProduct != 0x6025) + if (tas5130d1b.usbdev->descriptor.idProduct != 0x6025 && + tas5130d1b.usbdev->descriptor.idProduct != 0x60aa) return -ENODEV; return 0; diff -Nru a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c --- a/drivers/usb/misc/tiglusb.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/misc/tiglusb.c 2004-09-12 22:25:42 -07:00 @@ -115,6 +115,7 @@ return -EBUSY; } + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout (HZ / 2); if (signal_pending (current)) { diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c --- a/drivers/usb/net/kaweth.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/net/kaweth.c 2004-09-12 22:25:43 -07:00 @@ -668,7 +668,7 @@ INTBUFFERSIZE, int_callback, kaweth, - 8); + 250); /* overriding the descriptor */ kaweth->irq_urb->transfer_dma = kaweth->intbufferhandle; kaweth->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; diff -Nru a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c --- a/drivers/usb/net/rtl8150.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/net/rtl8150.c 2004-09-12 22:25:42 -07:00 @@ -20,7 +20,7 @@ #include /* Version Information */ -#define DRIVER_VERSION "v0.6.1 (2004/03/13)" +#define DRIVER_VERSION "v0.6.2 (2004/08/27)" #define DRIVER_AUTHOR "Petko Manolov " #define DRIVER_DESC "rtl8150 based usb-ethernet driver" @@ -344,7 +344,7 @@ static int rtl8150_reset(rtl8150_t * dev) { - u8 data = 0x10; + u8 data = 0x11; int i = HZ; set_registers(dev, CR, 1, &data); diff -Nru a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c --- a/drivers/usb/serial/belkin_sa.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/serial/belkin_sa.c 2004-09-12 22:25:42 -07:00 @@ -228,7 +228,7 @@ port->interrupt_in_urb->dev = port->serial->dev; retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (retval) { - usb_unlink_urb(port->read_urb); + usb_kill_urb(port->read_urb); err(" usb_submit_urb(read int) failed"); } @@ -242,9 +242,9 @@ dbg("%s port %d", __FUNCTION__, port->number); /* shutdown our bulk reads and writes */ - usb_unlink_urb (port->write_urb); - usb_unlink_urb (port->read_urb); - usb_unlink_urb (port->interrupt_in_urb); + usb_kill_urb(port->write_urb); + usb_kill_urb(port->read_urb); + usb_kill_urb(port->interrupt_in_urb); } /* belkin_sa_close */ diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c --- a/drivers/usb/serial/cyberjack.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/serial/cyberjack.c 2004-09-12 22:25:43 -07:00 @@ -149,7 +149,7 @@ dbg("%s", __FUNCTION__); for (i=0; i < serial->num_ports; ++i) { - usb_unlink_urb (serial->port[i]->interrupt_in_urb); + usb_kill_urb(serial->port[i]->interrupt_in_urb); /* My special items, the standard routines free my urbs */ kfree(usb_get_serial_port_data(serial->port[i])); usb_set_serial_port_data(serial->port[i], NULL); @@ -189,8 +189,8 @@ if (port->serial->dev) { /* shutdown any bulk reads that might be going on */ - usb_unlink_urb (port->write_urb); - usb_unlink_urb (port->read_urb); + usb_kill_urb(port->write_urb); + usb_kill_urb(port->read_urb); } } diff -Nru a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c --- a/drivers/usb/serial/digi_acceleport.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/serial/digi_acceleport.c 2004-09-12 22:25:42 -07:00 @@ -1553,13 +1553,17 @@ dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count ); + /* if disconnected, just clear flags */ + if (!usb_get_intfdata(port->serial->interface)) + goto exit; + /* do cleanup only after final close on this port */ spin_lock_irqsave( &priv->dp_port_lock, flags ); priv->dp_in_close = 1; spin_unlock_irqrestore( &priv->dp_port_lock, flags ); /* tell line discipline to process only XON/XOFF */ - tty->closing = 1; + tty->closing = 1; /* wait for output to drain */ if( (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) { @@ -1619,11 +1623,12 @@ DIGI_CLOSE_TIMEOUT ); /* shutdown any outstanding bulk writes */ - usb_unlink_urb (port->write_urb); + usb_kill_urb(port->write_urb); } tty->closing = 0; +exit: spin_lock_irqsave( &priv->dp_port_lock, flags ); priv->dp_write_urb_in_use = 0; priv->dp_in_close = 0; @@ -1757,8 +1762,8 @@ /* stop reads and writes on all ports */ for( i=0; itype->num_ports+1; i++ ) { - usb_unlink_urb( serial->port[i]->read_urb ); - usb_unlink_urb( serial->port[i]->write_urb ); + usb_kill_urb(serial->port[i]->read_urb); + usb_kill_urb(serial->port[i]->write_urb); } /* free the private data structures for all ports */ diff -Nru a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c --- a/drivers/usb/serial/empeg.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/serial/empeg.c 2004-09-12 22:25:43 -07:00 @@ -185,7 +185,7 @@ dbg("%s - port %d", __FUNCTION__, port->number); /* shutdown our bulk read */ - usb_unlink_urb (port->read_urb); + usb_kill_urb(port->read_urb); /* Uncomment the following line if you want to see some statistics in your syslog */ /* dev_info (&port->dev, "Bytes In = %d Bytes Out = %d\n", bytes_in, bytes_out); */ } @@ -406,7 +406,7 @@ static void empeg_throttle (struct usb_serial_port *port) { dbg("%s - port %d", __FUNCTION__, port->number); - usb_unlink_urb (port->read_urb); + usb_kill_urb(port->read_urb); } @@ -583,10 +583,10 @@ for (i = 0; i < NUM_URBS; ++i) { if (write_urb_pool[i]) { - /* FIXME - uncomment the following usb_unlink_urb call when + /* FIXME - uncomment the following usb_kill_urb call when * the host controllers get fixed to set urb->dev = NULL after * the urb is finished. Otherwise this call oopses. */ - /* usb_unlink_urb(write_urb_pool[i]); */ + /* usb_kill_urb(write_urb_pool[i]); */ if (write_urb_pool[i]->transfer_buffer) kfree(write_urb_pool[i]->transfer_buffer); usb_free_urb (write_urb_pool[i]); diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c --- a/drivers/usb/serial/ftdi_sio.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/serial/ftdi_sio.c 2004-09-12 22:25:43 -07:00 @@ -368,6 +368,9 @@ { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FALCOM_VID, FALCOM_TWIST_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_SUUNTO_SPORTS_PID, 0, 0x3ff) }, + { USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0, 0x3ff) }, + { USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0, 0x3ff) }, + { USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0, 0x3ff) }, { } /* Terminating entry */ }; @@ -478,6 +481,9 @@ { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FALCOM_VID, FALCOM_TWIST_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_SUUNTO_SPORTS_PID, 0x400, 0xffff) }, + { USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0x400, 0xffff) }, + { USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0x400, 0xffff) }, + { USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0x400, 0xffff) }, { } /* Terminating entry */ }; @@ -595,6 +601,9 @@ { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) }, + { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, + { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, + { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, { } /* Terminating entry */ }; @@ -1479,16 +1488,8 @@ } /* Note change no line if hupcl is off */ /* shutdown our bulk read */ - if (port->read_urb) { - if (usb_unlink_urb (port->read_urb) < 0) { - /* Generally, this isn't an error. If the previous - read bulk callback occurred (or is about to occur) - while the port was being closed or was throtted - (and is still throttled), the read urb will not - have been submitted. */ - dbg("%s - failed to unlink read urb (generally not an error)", __FUNCTION__); - } - } + if (port->read_urb) + usb_kill_urb(port->read_urb); } /* ftdi_close */ diff -Nru a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h --- a/drivers/usb/serial/ftdi_sio.h 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/serial/ftdi_sio.h 2004-09-12 22:25:43 -07:00 @@ -225,6 +225,14 @@ */ #define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */ +/* + * Definitions for B&B Electronics products. + */ +#define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ +#define BANDB_USOTL4_PID 0xAC01 /* USOTL4 Isolated RS-485 Converter */ +#define BANDB_USTL4_PID 0xAC02 /* USTL4 RS-485 Converter */ +#define BANDB_USO9ML2_PID 0xAC03 /* USO9ML2 Isolated RS-232 Converter */ + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff -Nru a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c --- a/drivers/usb/serial/generic.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/serial/generic.c 2004-09-12 22:25:42 -07:00 @@ -147,9 +147,9 @@ if (serial->dev) { /* shutdown any bulk reads that might be going on */ if (serial->num_bulk_out) - usb_unlink_urb (port->write_urb); + usb_kill_urb(port->write_urb); if (serial->num_bulk_in) - usb_unlink_urb (port->read_urb); + usb_kill_urb(port->read_urb); } } diff -Nru a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c --- a/drivers/usb/serial/io_edgeport.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/serial/io_edgeport.c 2004-09-12 22:25:42 -07:00 @@ -1243,7 +1243,7 @@ edge_port->openPending = FALSE; if (edge_port->write_urb) { - usb_unlink_urb (edge_port->write_urb); + usb_kill_urb(edge_port->write_urb); } if (edge_port->write_urb) { @@ -2448,8 +2448,8 @@ if (status) { /* something went wrong */ dbg("%s - usb_submit_urb(write bulk) failed", __FUNCTION__); - usb_unlink_urb (urb); - usb_free_urb (urb); + usb_kill_urb(urb); + usb_free_urb(urb); return status; } diff -Nru a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c --- a/drivers/usb/serial/io_ti.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/serial/io_ti.c 2004-09-12 22:25:43 -07:00 @@ -1977,7 +1977,7 @@ /* chase the port close */ TIChasePort (edge_port); - usb_unlink_urb (port->read_urb); + usb_kill_urb(port->read_urb); /* assuming we can still talk to the device, * send a close port command to it */ @@ -1992,7 +1992,7 @@ --edge_port->edge_serial->num_ports_open; if (edge_port->edge_serial->num_ports_open <= 0) { /* last port is now closed, let's shut down our interrupt urb */ - usb_unlink_urb (port->serial->port[0]->interrupt_in_urb); + usb_kill_urb(port->serial->port[0]->interrupt_in_urb); edge_port->edge_serial->num_ports_open = 0; } edge_port->close_pending = 0; @@ -2126,7 +2126,7 @@ status = TIClearRts (edge_port); } - usb_unlink_urb (port->read_urb); + usb_kill_urb(port->read_urb); } static void edge_unthrottle (struct usb_serial_port *port) diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c --- a/drivers/usb/serial/ipaq.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/serial/ipaq.c 2004-09-12 22:25:43 -07:00 @@ -288,8 +288,8 @@ /* * shut down bulk read and write */ - usb_unlink_urb(port->write_urb); - usb_unlink_urb(port->read_urb); + usb_kill_urb(port->write_urb); + usb_kill_urb(port->read_urb); ipaq_destroy_lists(port); kfree(priv); usb_set_serial_port_data(port, NULL); @@ -419,9 +419,8 @@ struct ipaq_private *priv = usb_get_serial_port_data(port); struct usb_serial *serial = port->serial; int count, room; - struct ipaq_packet *pkt; + struct ipaq_packet *pkt, *tmp; struct urb *urb = port->write_urb; - struct list_head *tmp; if (urb->status == -EINPROGRESS) { /* Should never happen */ @@ -429,9 +428,7 @@ return; } room = URBDATA_SIZE; - for (tmp = priv->queue.next; tmp != &priv->queue;) { - pkt = list_entry(tmp, struct ipaq_packet, list); - tmp = tmp->next; + list_for_each_entry_safe(pkt, tmp, &priv->queue, list) { count = min(room, (int)(pkt->len - pkt->written)); memcpy(urb->transfer_buffer + (URBDATA_SIZE - room), pkt->data + pkt->written, count); @@ -503,22 +500,16 @@ static void ipaq_destroy_lists(struct usb_serial_port *port) { struct ipaq_private *priv = usb_get_serial_port_data(port); - struct list_head *tmp; - struct ipaq_packet *pkt; + struct ipaq_packet *pkt, *tmp; - for (tmp = priv->queue.next; tmp != &priv->queue;) { - pkt = list_entry(tmp, struct ipaq_packet, list); - tmp = tmp->next; + list_for_each_entry_safe(pkt, tmp, &priv->queue, list) { kfree(pkt->data); kfree(pkt); } - for (tmp = priv->freelist.next; tmp != &priv->freelist;) { - pkt = list_entry(tmp, struct ipaq_packet, list); - tmp = tmp->next; + list_for_each_entry_safe(pkt, tmp, &priv->freelist, list) { kfree(pkt->data); kfree(pkt); } - return; } diff -Nru a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c --- a/drivers/usb/serial/ir-usb.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/serial/ir-usb.c 2004-09-12 22:25:42 -07:00 @@ -322,7 +322,7 @@ dbg("%s - port %d", __FUNCTION__, port->number); /* shutdown our bulk read */ - usb_unlink_urb (port->read_urb); + usb_kill_urb(port->read_urb); } static int ir_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count) diff -Nru a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c --- a/drivers/usb/serial/keyspan_pda.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/serial/keyspan_pda.c 2004-09-12 22:25:42 -07:00 @@ -291,7 +291,7 @@ upon the device too. */ dbg("keyspan_pda_rx_throttle port %d", port->number); - usb_unlink_urb(port->interrupt_in_urb); + usb_kill_urb(port->interrupt_in_urb); } @@ -712,8 +712,8 @@ keyspan_pda_set_modem_info(serial, 0); /* shutdown our bulk reads and writes */ - usb_unlink_urb (port->write_urb); - usb_unlink_urb (port->interrupt_in_urb); + usb_kill_urb(port->write_urb); + usb_kill_urb(port->interrupt_in_urb); } } diff -Nru a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c --- a/drivers/usb/serial/kl5kusb105.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/serial/kl5kusb105.c 2004-09-12 22:25:42 -07:00 @@ -336,12 +336,12 @@ for (j = 0; j < NUM_URBS; j++) { if (write_urbs[j]) { /* FIXME - uncomment the following - * usb_unlink_urb call when the host + * usb_kill_urb call when the host * controllers get fixed to set * urb->dev = NULL after the urb is * finished. Otherwise this call * oopses. */ - /* usb_unlink_urb(write_urbs[j]); */ + /* usb_kill_urb(write_urbs[j]); */ if (write_urbs[j]->transfer_buffer) kfree(write_urbs[j]->transfer_buffer); usb_free_urb (write_urbs[j]); @@ -467,12 +467,12 @@ err("Disabling read failed (error = %d)", rc); /* shutdown our bulk reads and writes */ - usb_unlink_urb (port->write_urb); - usb_unlink_urb (port->read_urb); + usb_kill_urb(port->write_urb); + usb_kill_urb(port->read_urb); /* unlink our write pool */ /* FIXME */ /* wgg - do I need this? I think so. */ - usb_unlink_urb (port->interrupt_in_urb); + usb_kill_urb(port->interrupt_in_urb); info("kl5kusb105 port stats: %ld bytes in, %ld bytes out", priv->bytes_in, priv->bytes_out); } /* klsi_105_close */ @@ -994,7 +994,7 @@ static void klsi_105_throttle (struct usb_serial_port *port) { dbg("%s - port %d", __FUNCTION__, port->number); - usb_unlink_urb (port->read_urb); + usb_kill_urb(port->read_urb); } static void klsi_105_unthrottle (struct usb_serial_port *port) diff -Nru a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c --- a/drivers/usb/serial/kobil_sct.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/serial/kobil_sct.c 2004-09-12 22:25:43 -07:00 @@ -350,14 +350,13 @@ { dbg("%s - port %d", __FUNCTION__, port->number); - if (port->write_urb){ - usb_unlink_urb( port->write_urb ); + if (port->write_urb) { + usb_kill_urb(port->write_urb); usb_free_urb( port->write_urb ); port->write_urb = NULL; } - if (port->interrupt_in_urb){ - usb_unlink_urb (port->interrupt_in_urb); - } + if (port->interrupt_in_urb) + usb_kill_urb(port->interrupt_in_urb); } @@ -458,9 +457,8 @@ ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4))) ) { // stop reading (except TWIN and KAAN SIM) - if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) ) { - usb_unlink_urb( port->interrupt_in_urb ); - } + if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) ) + usb_kill_urb(port->interrupt_in_urb); todo = priv->filled - priv->cur_pos; diff -Nru a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c --- a/drivers/usb/serial/mct_u232.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/serial/mct_u232.c 2004-09-12 22:25:42 -07:00 @@ -480,9 +480,9 @@ if (port->serial->dev) { /* shutdown our urbs */ - usb_unlink_urb (port->write_urb); - usb_unlink_urb (port->read_urb); - usb_unlink_urb (port->interrupt_in_urb); + usb_kill_urb(port->write_urb); + usb_kill_urb(port->read_urb); + usb_kill_urb(port->interrupt_in_urb); } } /* mct_u232_close */ diff -Nru a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c --- a/drivers/usb/serial/omninet.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/serial/omninet.c 2004-09-12 22:25:43 -07:00 @@ -183,8 +183,8 @@ dbg("%s - port %d", __FUNCTION__, port->number); wport = serial->port[1]; - usb_unlink_urb(wport->write_urb); - usb_unlink_urb(port->read_urb); + usb_kill_urb(wport->write_urb); + usb_kill_urb(port->read_urb); od = usb_get_serial_port_data(port); if (od) diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c --- a/drivers/usb/serial/pl2303.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/serial/pl2303.c 2004-09-12 22:25:42 -07:00 @@ -55,11 +55,26 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.11" +#define DRIVER_VERSION "v0.12" #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver" static int debug; +#define PL2303_CLOSING_WAIT (30*HZ) + +#define PL2303_BUF_SIZE 1024 +#define PL2303_TMP_BUF_SIZE 1024 + +static char pl2303_tmp_buf[PL2303_TMP_BUF_SIZE]; +static DECLARE_MUTEX(pl2303_tmp_buf_sem); + +struct pl2303_buf { + unsigned int buf_size; + char *buf_buf; + char *buf_get; + char *buf_put; +}; + static struct usb_device_id id_table [] = { { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) }, @@ -134,12 +149,24 @@ static void pl2303_write_bulk_callback (struct urb *urb, struct pt_regs *regs); static int pl2303_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count); +static void pl2303_send (struct usb_serial_port *port); +static int pl2303_write_room(struct usb_serial_port *port); +static int pl2303_chars_in_buffer(struct usb_serial_port *port); static void pl2303_break_ctl(struct usb_serial_port *port,int break_state); static int pl2303_tiocmget (struct usb_serial_port *port, struct file *file); static int pl2303_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); static int pl2303_startup (struct usb_serial *serial); static void pl2303_shutdown (struct usb_serial *serial); +static struct pl2303_buf *pl2303_buf_alloc(unsigned int size); +static void pl2303_buf_free(struct pl2303_buf *pb); +static void pl2303_buf_clear(struct pl2303_buf *pb); +static unsigned int pl2303_buf_data_avail(struct pl2303_buf *pb); +static unsigned int pl2303_buf_space_avail(struct pl2303_buf *pb); +static unsigned int pl2303_buf_put(struct pl2303_buf *pb, const char *buf, + unsigned int count); +static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf, + unsigned int count); /* All of the device info needed for the PL2303 SIO serial converter */ @@ -162,6 +189,8 @@ .read_bulk_callback = pl2303_read_bulk_callback, .read_int_callback = pl2303_read_int_callback, .write_bulk_callback = pl2303_write_bulk_callback, + .write_room = pl2303_write_room, + .chars_in_buffer = pl2303_chars_in_buffer, .attach = pl2303_startup, .shutdown = pl2303_shutdown, }; @@ -174,6 +203,8 @@ struct pl2303_private { spinlock_t lock; + struct pl2303_buf *buf; + int write_urb_in_use; wait_queue_head_t delta_msr_wait; u8 line_control; u8 line_status; @@ -201,14 +232,28 @@ for (i = 0; i < serial->num_ports; ++i) { priv = kmalloc (sizeof (struct pl2303_private), GFP_KERNEL); if (!priv) - return -ENOMEM; + goto cleanup; memset (priv, 0x00, sizeof (struct pl2303_private)); spin_lock_init(&priv->lock); + priv->buf = pl2303_buf_alloc(PL2303_BUF_SIZE); + if (priv->buf == NULL) { + kfree(priv); + goto cleanup; + } init_waitqueue_head(&priv->delta_msr_wait); priv->type = type; usb_set_serial_port_data(serial->port[i], priv); } return 0; + +cleanup: + for (--i; i>=0; --i) { + priv = usb_get_serial_port_data(serial->port[i]); + pl2303_buf_free(priv->buf); + kfree(priv); + usb_set_serial_port_data(serial->port[i], NULL); + } + return -ENOMEM; } static int set_control_lines (struct usb_device *dev, u8 value) @@ -224,40 +269,109 @@ static int pl2303_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count) { - int result; + struct pl2303_private *priv = usb_get_serial_port_data(port); + unsigned long flags; dbg("%s - port %d, %d bytes", __FUNCTION__, port->number, count); if (!count) return count; - if (port->write_urb->status == -EINPROGRESS) { - dbg("%s - already writing", __FUNCTION__); - return 0; - } - - count = (count > port->bulk_out_size) ? port->bulk_out_size : count; if (from_user) { - if (copy_from_user (port->write_urb->transfer_buffer, buf, count)) + if (count > PL2303_TMP_BUF_SIZE) + count = PL2303_TMP_BUF_SIZE; + down(&pl2303_tmp_buf_sem); + if (copy_from_user(pl2303_tmp_buf, buf, count)) { + up(&pl2303_tmp_buf_sem); return -EFAULT; - } else { - memcpy (port->write_urb->transfer_buffer, buf, count); + } + buf = pl2303_tmp_buf; } - + + spin_lock_irqsave(&priv->lock, flags); + count = pl2303_buf_put(priv->buf, buf, count); + spin_unlock_irqrestore(&priv->lock, flags); + + if (from_user) + up(&pl2303_tmp_buf_sem); + + pl2303_send(port); + + return count; +} + +static void pl2303_send(struct usb_serial_port *port) +{ + int count, result; + struct pl2303_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + + dbg("%s - port %d", __FUNCTION__, port->number); + + spin_lock_irqsave(&priv->lock, flags); + + if (priv->write_urb_in_use) { + spin_unlock_irqrestore(&priv->lock, flags); + return; + } + + count = pl2303_buf_get(priv->buf, port->write_urb->transfer_buffer, + port->bulk_out_size); + + if (count == 0) { + spin_unlock_irqrestore(&priv->lock, flags); + return; + } + + priv->write_urb_in_use = 1; + + spin_unlock_irqrestore(&priv->lock, flags); + usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, port->write_urb->transfer_buffer); port->write_urb->transfer_buffer_length = count; port->write_urb->dev = port->serial->dev; result = usb_submit_urb (port->write_urb, GFP_ATOMIC); - if (result) + if (result) { dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); - else - result = count; + priv->write_urb_in_use = 0; + // TODO: reschedule pl2303_send + } - return result; + schedule_work(&port->work); } +static int pl2303_write_room(struct usb_serial_port *port) +{ + struct pl2303_private *priv = usb_get_serial_port_data(port); + int room = 0; + unsigned long flags; + + dbg("%s - port %d", __FUNCTION__, port->number); + + spin_lock_irqsave(&priv->lock, flags); + room = pl2303_buf_space_avail(priv->buf); + spin_unlock_irqrestore(&priv->lock, flags); + + dbg("%s - returns %d", __FUNCTION__, room); + return room; +} + +static int pl2303_chars_in_buffer(struct usb_serial_port *port) +{ + struct pl2303_private *priv = usb_get_serial_port_data(port); + int chars = 0; + unsigned long flags; + + dbg("%s - port %d", __FUNCTION__, port->number); + + spin_lock_irqsave(&priv->lock, flags); + chars = pl2303_buf_data_avail(priv->buf); + spin_unlock_irqrestore(&priv->lock, flags); + dbg("%s - returns %d", __FUNCTION__, chars); + return chars; +} static void pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios) { @@ -422,7 +536,7 @@ } kfree (buf); -} +} static int pl2303_open (struct usb_serial_port *port, struct file *filp) { @@ -461,7 +575,7 @@ FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0); SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0, 1); SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 1, 0); - + if (priv->type == HX) { /* HX chip */ SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 0x44); @@ -504,45 +618,67 @@ static void pl2303_close (struct usb_serial_port *port, struct file *filp) { - struct pl2303_private *priv; + struct pl2303_private *priv = usb_get_serial_port_data(port); unsigned long flags; unsigned int c_cflag; - int result; + int bps; + long timeout; + wait_queue_t wait; \ dbg("%s - port %d", __FUNCTION__, port->number); - /* shutdown our urbs */ - dbg("%s - shutting down urbs", __FUNCTION__); - result = usb_unlink_urb (port->write_urb); - if (result) - dbg("%s - usb_unlink_urb (write_urb)" - " failed with reason: %d", __FUNCTION__, - result); + /* wait for data to drain from the buffer */ + spin_lock_irqsave(&priv->lock, flags); + timeout = PL2303_CLOSING_WAIT; + init_waitqueue_entry(&wait, current); + add_wait_queue(&port->tty->write_wait, &wait); + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + if (pl2303_buf_data_avail(priv->buf) == 0 + || timeout == 0 || signal_pending(current) + || !usb_get_intfdata(port->serial->interface)) /* disconnect */ + break; + spin_unlock_irqrestore(&priv->lock, flags); + timeout = schedule_timeout(timeout); + spin_lock_irqsave(&priv->lock, flags); + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&port->tty->write_wait, &wait); + /* clear out any remaining data in the buffer */ + pl2303_buf_clear(priv->buf); + spin_unlock_irqrestore(&priv->lock, flags); - result = usb_unlink_urb (port->read_urb); - if (result) - dbg("%s - usb_unlink_urb (read_urb) " - "failed with reason: %d", __FUNCTION__, - result); + /* wait for characters to drain from the device */ + /* (this is long enough for the entire 256 byte */ + /* pl2303 hardware buffer to drain with no flow */ + /* control for data rates of 1200 bps or more, */ + /* for lower rates we should really know how much */ + /* data is in the buffer to compute a delay */ + /* that is not unnecessarily long) */ + bps = tty_get_baud_rate(port->tty); + if (bps > 1200) + timeout = max((HZ*2560)/bps,HZ/10); + else + timeout = 2*HZ; + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(timeout); - result = usb_unlink_urb (port->interrupt_in_urb); - if (result) - dbg("%s - usb_unlink_urb (interrupt_in_urb)" - " failed with reason: %d", __FUNCTION__, - result); + /* shutdown our urbs */ + dbg("%s - shutting down urbs", __FUNCTION__); + usb_kill_urb(port->write_urb); + usb_kill_urb(port->read_urb); + usb_kill_urb(port->interrupt_in_urb); if (port->tty) { c_cflag = port->tty->termios->c_cflag; if (c_cflag & HUPCL) { /* drop DTR and RTS */ - priv = usb_get_serial_port_data(port); spin_lock_irqsave(&priv->lock, flags); priv->line_control = 0; spin_unlock_irqrestore (&priv->lock, flags); set_control_lines (port->serial->dev, 0); } } - } static int pl2303_tiocmset (struct usb_serial_port *port, struct file *file, @@ -672,12 +808,17 @@ static void pl2303_shutdown (struct usb_serial *serial) { int i; + struct pl2303_private *priv; dbg("%s", __FUNCTION__); for (i = 0; i < serial->num_ports; ++i) { - kfree (usb_get_serial_port_data(serial->port[i])); - usb_set_serial_port_data(serial->port[i], NULL); + priv = usb_get_serial_port_data(serial->port[i]); + if (priv) { + pl2303_buf_free(priv->buf); + kfree(priv); + usb_set_serial_port_data(serial->port[i], NULL); + } } } @@ -815,11 +956,23 @@ static void pl2303_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *) urb->context; + struct pl2303_private *priv = usb_get_serial_port_data(port); int result; dbg("%s - port %d", __FUNCTION__, port->number); - - if (urb->status) { + + switch (urb->status) { + case 0: + /* success */ + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); + priv->write_urb_in_use = 0; + return; + default: /* error in the urb, so we have to resubmit it */ dbg("%s - Overflow in write", __FUNCTION__); dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); @@ -828,13 +981,198 @@ result = usb_submit_urb (port->write_urb, GFP_ATOMIC); if (result) dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n", __FUNCTION__, result); + else + return; + } - return; + priv->write_urb_in_use = 0; + + /* send any buffered data */ + pl2303_send(port); +} + + +/* + * pl2303_buf_alloc + * + * Allocate a circular buffer and all associated memory. + */ + +static struct pl2303_buf *pl2303_buf_alloc(unsigned int size) +{ + + struct pl2303_buf *pb; + + + if (size == 0) + return NULL; + + pb = (struct pl2303_buf *)kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL); + if (pb == NULL) + return NULL; + + pb->buf_buf = kmalloc(size, GFP_KERNEL); + if (pb->buf_buf == NULL) { + kfree(pb); + return NULL; } - schedule_work(&port->work); + pb->buf_size = size; + pb->buf_get = pb->buf_put = pb->buf_buf; + + return pb; + +} + + +/* + * pl2303_buf_free + * + * Free the buffer and all associated memory. + */ + +static void pl2303_buf_free(struct pl2303_buf *pb) +{ + if (pb != NULL) { + if (pb->buf_buf != NULL) + kfree(pb->buf_buf); + kfree(pb); + } +} + + +/* + * pl2303_buf_clear + * + * Clear out all data in the circular buffer. + */ + +static void pl2303_buf_clear(struct pl2303_buf *pb) +{ + if (pb != NULL) + pb->buf_get = pb->buf_put; + /* equivalent to a get of all data available */ +} + + +/* + * pl2303_buf_data_avail + * + * Return the number of bytes of data available in the circular + * buffer. + */ + +static unsigned int pl2303_buf_data_avail(struct pl2303_buf *pb) +{ + if (pb != NULL) + return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size); + else + return 0; +} + + +/* + * pl2303_buf_space_avail + * + * Return the number of bytes of space available in the circular + * buffer. + */ + +static unsigned int pl2303_buf_space_avail(struct pl2303_buf *pb) +{ + if (pb != NULL) + return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size); + else + return 0; +} + + +/* + * pl2303_buf_put + * + * Copy data data from a user buffer and put it into the circular buffer. + * Restrict to the amount of space available. + * + * Return the number of bytes copied. + */ + +static unsigned int pl2303_buf_put(struct pl2303_buf *pb, const char *buf, + unsigned int count) +{ + + unsigned int len; + + + if (pb == NULL) + return 0; + + len = pl2303_buf_space_avail(pb); + if (count > len) + count = len; + + if (count == 0) + return 0; + + len = pb->buf_buf + pb->buf_size - pb->buf_put; + if (count > len) { + memcpy(pb->buf_put, buf, len); + memcpy(pb->buf_buf, buf+len, count - len); + pb->buf_put = pb->buf_buf + count - len; + } else { + memcpy(pb->buf_put, buf, count); + if (count < len) + pb->buf_put += count; + else /* count == len */ + pb->buf_put = pb->buf_buf; + } + + return count; + } + +/* + * pl2303_buf_get + * + * Get data from the circular buffer and copy to the given buffer. + * Restrict to the amount of data available. + * + * Return the number of bytes copied. + */ + +static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf, + unsigned int count) +{ + + unsigned int len; + + + if (pb == NULL) + return 0; + + len = pl2303_buf_data_avail(pb); + if (count > len) + count = len; + + if (count == 0) + return 0; + + len = pb->buf_buf + pb->buf_size - pb->buf_get; + if (count > len) { + memcpy(buf, pb->buf_get, len); + memcpy(buf+len, pb->buf_buf, count - len); + pb->buf_get = pb->buf_buf + count - len; + } else { + memcpy(buf, pb->buf_get, count); + if (count < len) + pb->buf_get += count; + else /* count == len */ + pb->buf_get = pb->buf_buf; + } + + return count; + +} static int __init pl2303_init (void) { diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c --- a/drivers/usb/serial/usb-serial.c 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/serial/usb-serial.c 2004-09-12 22:25:43 -07:00 @@ -388,7 +388,7 @@ good_spot = 1; for (j = 1; j <= num_ports-1; ++j) - if ((serial_table[i+j]) || (i+j >= SERIAL_TTY_MINORS)) { + if ((i+j >= SERIAL_TTY_MINORS) || (serial_table[i+j])) { good_spot = 0; i += j; break; @@ -455,15 +455,15 @@ if (!port) continue; if (port->read_urb) { - usb_unlink_urb(port->read_urb); + usb_kill_urb(port->read_urb); usb_free_urb(port->read_urb); } if (port->write_urb) { - usb_unlink_urb(port->write_urb); + usb_kill_urb(port->write_urb); usb_free_urb(port->write_urb); } if (port->interrupt_in_urb) { - usb_unlink_urb(port->interrupt_in_urb); + usb_kill_urb(port->interrupt_in_urb); usb_free_urb(port->interrupt_in_urb); } kfree(port->bulk_in_buffer); @@ -819,15 +819,15 @@ dbg ("%s - %s", __FUNCTION__, dev->bus_id); if (port->read_urb) { - usb_unlink_urb(port->read_urb); + usb_kill_urb(port->read_urb); usb_free_urb(port->read_urb); } if (port->write_urb) { - usb_unlink_urb(port->write_urb); + usb_kill_urb(port->write_urb); usb_free_urb(port->write_urb); } if (port->interrupt_in_urb) { - usb_unlink_urb(port->interrupt_in_urb); + usb_kill_urb(port->interrupt_in_urb); usb_free_urb(port->interrupt_in_urb); } kfree(port->bulk_in_buffer); diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c --- a/drivers/usb/serial/visor.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/serial/visor.c 2004-09-12 22:25:42 -07:00 @@ -446,9 +446,9 @@ dbg("%s - port %d", __FUNCTION__, port->number); /* shutdown our urbs */ - usb_unlink_urb (port->read_urb); + usb_kill_urb(port->read_urb); if (port->interrupt_in_urb) - usb_unlink_urb (port->interrupt_in_urb); + usb_kill_urb(port->interrupt_in_urb); /* Try to send shutdown message, if the device is gone, this will just fail. */ transfer_buffer = kmalloc (0x12, GFP_KERNEL); @@ -655,7 +655,7 @@ static void visor_throttle (struct usb_serial_port *port) { dbg("%s - port %d", __FUNCTION__, port->number); - usb_unlink_urb (port->read_urb); + usb_kill_urb(port->read_urb); } diff -Nru a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c --- a/drivers/usb/serial/whiteheat.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/serial/whiteheat.c 2004-09-12 22:25:42 -07:00 @@ -680,7 +680,7 @@ list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) { wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); urb = wrap->urb; - usb_unlink_urb(urb); + usb_kill_urb(urb); list_del(tmp); list_add(tmp, &info->rx_urbs_free); } @@ -691,7 +691,7 @@ list_for_each_safe(tmp, tmp2, &info->tx_urbs_submitted) { wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); urb = wrap->urb; - usb_unlink_urb(urb); + usb_kill_urb(urb); list_del(tmp); list_add(tmp, &info->tx_urbs_free); } @@ -1344,7 +1344,7 @@ spin_lock_irqsave(&command_info->lock, flags); command_info->port_running--; if (!command_info->port_running) - usb_unlink_urb(command_port->read_urb); + usb_kill_urb(command_port->read_urb); spin_unlock_irqrestore(&command_info->lock, flags); } @@ -1372,7 +1372,7 @@ list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) { wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); urb = wrap->urb; - usb_unlink_urb(urb); + usb_kill_urb(urb); list_del(tmp); list_add(tmp, &info->rx_urbs_free); } diff -Nru a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c --- a/drivers/usb/storage/isd200.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/storage/isd200.c 2004-09-12 22:25:42 -07:00 @@ -1052,12 +1052,6 @@ /* Standard IDE interface only supports disks */ info->InquiryData.DeviceType = DIRECT_ACCESS_DEVICE; - /* Fix-up the return data from an INQUIRY command to show - * ANSI SCSI rev 2 so we don't confuse the SCSI layers above us - * in Linux. - */ - info->InquiryData.Versions = 0x2; - /* The length must be at least 36 (5 + 31) */ info->InquiryData.AdditionalLength = 0x1F; diff -Nru a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c --- a/drivers/usb/storage/protocol.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/storage/protocol.c 2004-09-12 22:25:42 -07:00 @@ -58,38 +58,6 @@ ***********************************************************************/ /* - * Fix-up the return data from an INQUIRY command to show - * ANSI SCSI rev 2 so we don't confuse the SCSI layers above us - */ -static void fix_inquiry_data(struct scsi_cmnd *srb) -{ - unsigned char databuf[3]; - unsigned int index, offset; - - /* verify that it's an INQUIRY command */ - if (srb->cmnd[0] != INQUIRY) - return; - - index = offset = 0; - if (usb_stor_access_xfer_buf(databuf, sizeof(databuf), srb, - &index, &offset, FROM_XFER_BUF) != sizeof(databuf)) - return; - - if ((databuf[2] & 7) == 2) - return; - - US_DEBUGP("Fixing INQUIRY data to show SCSI rev 2 - was %d\n", - databuf[2] & 7); - - /* Change the SCSI revision number */ - databuf[2] = (databuf[2] & ~7) | 2; - - index = offset = 0; - usb_stor_access_xfer_buf(databuf, sizeof(databuf), srb, - &index, &offset, TO_XFER_BUF); -} - -/* * Fix-up the return data from a READ CAPACITY command. My Feiya reader * returns a value that is 1 too large. */ @@ -137,10 +105,6 @@ /* send the command to the transport layer */ usb_stor_invoke_transport(srb, us); - if (srb->result == SAM_STAT_GOOD) { - /* fix the INQUIRY data if necessary */ - fix_inquiry_data(srb); - } } void usb_stor_ATAPI_command(struct scsi_cmnd *srb, struct us_data *us) @@ -160,11 +124,6 @@ /* send the command to the transport layer */ usb_stor_invoke_transport(srb, us); - - if (srb->result == SAM_STAT_GOOD) { - /* fix the INQUIRY data if necessary */ - fix_inquiry_data(srb); - } } @@ -208,11 +167,6 @@ /* send the command to the transport layer */ usb_stor_invoke_transport(srb, us); - - if (srb->result == SAM_STAT_GOOD) { - /* Fix the data for an INQUIRY, if necessary */ - fix_inquiry_data(srb); - } } void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb, @@ -222,9 +176,6 @@ usb_stor_invoke_transport(srb, us); if (srb->result == SAM_STAT_GOOD) { - /* Fix the INQUIRY data if necessary */ - fix_inquiry_data(srb); - /* Fix the READ CAPACITY result if necessary */ if (us->flags & US_FL_FIX_CAPACITY) fix_read_capacity(srb); diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c --- a/drivers/usb/storage/scsiglue.c 2004-09-12 22:25:42 -07:00 +++ b/drivers/usb/storage/scsiglue.c 2004-09-12 22:25:42 -07:00 @@ -98,6 +98,23 @@ * the end, scatter-gather buffers follow page boundaries. */ blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); + /* Set the SCSI level to at least 2. We'll leave it at 3 if that's + * what is originally reported. We need this to avoid confusing + * the SCSI layer with devices that report 0 or 1, but need 10-byte + * commands (ala ATAPI devices behind certain bridges, or devices + * which simply have broken INQUIRY data). + * + * NOTE: This means /dev/sg programs (ala cdrecord) will get the + * actual information. This seems to be the preference for + * programs like that. + * + * NOTE: This also means that /proc/scsi/scsi and sysfs may report + * the actual value or the modified one, depending on where the + * data comes from. + */ + if (sdev->scsi_level < SCSI_2) + sdev->scsi_level = SCSI_2; + /* According to the technical support people at Genesys Logic, * devices using their chips have problems transferring more than * 32 KB at a time. In practice people have found that 64 KB diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h --- a/drivers/usb/storage/unusual_devs.h 2004-09-12 22:25:43 -07:00 +++ b/drivers/usb/storage/unusual_devs.h 2004-09-12 22:25:43 -07:00 @@ -36,13 +36,16 @@ /* If you edit this file, please try to keep it sorted first by VendorID, * then by ProductID. * - * If you want to add an entry for this file, please send the following - * to greg@kroah.com: - * - patch that adds the entry for your device which includes your - * email address right above the entry. + * If you want to add an entry for this file, be sure to include the + * following information: + * - a patch that adds the entry for your device, including your + * email address right above the entry (plus maybe a brief + * explanation of the reason for the entry), * - a copy of /proc/bus/usb/devices with your device plugged in * running with this patch. - * + * Send your submission to either Phil Dibowitz or + * Alan Stern , and don't forget to CC: the + * USB development list . */ UNUSUAL_DEV( 0x03ee, 0x6901, 0x0000, 0x0100, @@ -68,16 +71,6 @@ US_SC_8070, US_PR_SCM_ATAPI, init_8200e, 0), #endif -/* : I don't know the name of the bridge - * manufacturer, but I've got an external USB drive by the Revoltec company - * that needs this. otherwise the drive is recognized as /dev/sda, but any - * access to it blocks indefinitely. - */ -UNUSUAL_DEV( 0x0402, 0x5621, 0x0103, 0x0103, - "Revoltec", - "USB/IDE Bridge (ATA/ATAPI)", - US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), - /* Deduced by Jonathan Woithe * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message * always fails and confuses drive. @@ -179,6 +172,16 @@ "Sharp CE-CW05", "CD-R/RW Drive", US_SC_8070, US_PR_CB, NULL, 0), + +/* Reported by Adriaan Penning + * Note that these cameras report "Medium not present" after + * ALLOW_MEDIUM_REMOVAL, so they also need to be marked + * NOT_LOCKABLE in the SCSI blacklist (and the vendor is MATSHITA). */ +UNUSUAL_DEV( 0x04da, 0x2372, 0x0000, 0x9999, + "Panasonic", + "DMC-LCx Camera", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), /* Most of the following entries were developed with the help of * Shuttle/SCM directly. diff -Nru a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-i386/mach-summit/mach_mpparse.h --- a/include/asm-i386/mach-summit/mach_mpparse.h 2004-09-12 22:25:42 -07:00 +++ b/include/asm-i386/mach-summit/mach_mpparse.h 2004-09-12 22:25:42 -07:00 @@ -22,6 +22,7 @@ { } +extern int usb_early_handoff; static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid) { @@ -31,6 +32,7 @@ || !strncmp(productid, "RUTHLESS SMP", 12))){ use_cyclone = 1; /*enable cyclone-timer*/ setup_summit(); + usb_early_handoff = 1; return 1; } return 0; @@ -44,6 +46,7 @@ || !strncmp(oem_table_id, "EXA", 3))){ use_cyclone = 1; /*enable cyclone-timer*/ setup_summit(); + usb_early_handoff = 1; return 1; } return 0; diff -Nru a/include/linux/usb.h b/include/linux/usb.h --- a/include/linux/usb.h 2004-09-12 22:25:42 -07:00 +++ b/include/linux/usb.h 2004-09-12 22:25:42 -07:00 @@ -264,7 +264,6 @@ int bandwidth_isoc_reqs; /* number of Isoc. requests */ struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */ - struct dentry *usbdevfs_dentry; /* usbdevfs dentry entry for the bus */ struct class_device class_dev; /* class device for this bus */ void (*release)(struct usb_bus *bus); /* function to destroy this bus's memory */ @@ -315,7 +314,6 @@ struct list_head filelist; struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */ - struct dentry *usbdevfs_dentry; /* usbdevfs dentry entry for the device */ /* * Child devices - these can be either new devices diff -Nru a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h --- a/include/linux/usbdevice_fs.h 2004-09-12 22:25:42 -07:00 +++ b/include/linux/usbdevice_fs.h 2004-09-12 22:25:42 -07:00 @@ -166,16 +166,6 @@ unsigned long ifclaimed; }; -/* internal methods & data */ -extern struct usb_driver usbdevfs_driver; -extern struct file_operations usbdevfs_drivers_fops; -extern struct file_operations usbdevfs_devices_fops; -extern struct file_operations usbdevfs_device_file_operations; -extern struct inode_operations usbdevfs_device_inode_operations; -extern struct inode_operations usbdevfs_bus_inode_operations; -extern struct file_operations usbdevfs_bus_file_operations; -extern void usbdevfs_conn_disc_event(void); - #endif /* __KERNEL__ */ /* --------------------------------------------------------------------- */