bk://kernel.bkbits.net/gregkh/linux/usb-2.6 stern@rowland.harvard.edu|ChangeSet|20041021203140|06978 stern # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/10/21 14:29:54-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/serial/visor.c # 2004/10/21 14:29:50-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/usb-serial.c # 2004/10/21 14:29:50-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/pl2303.c # 2004/10/21 14:29:50-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/cyberjack.c # 2004/10/21 14:29:50-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/gadget/net2280.c # 2004/10/21 14:29:50-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/21 14:28:27-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/serial/visor.c # 2004/10/21 14:28:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/usb-serial.c # 2004/10/21 14:28:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/pl2303.c # 2004/10/21 14:28:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/io_ti.c # 2004/10/21 14:28:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/io_edgeport.c # 2004/10/21 14:28:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/empeg.c # 2004/10/21 14:28:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/digi_acceleport.c # 2004/10/21 14:28:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/cyberjack.c # 2004/10/21 14:28:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/cdc-acm.c # 2004/10/21 14:28:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/bluetty.c # 2004/10/21 14:28:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/21 13:31:40-07:00 stern@rowland.harvard.edu # [PATCH] USB file-storage gadget: clean up endian issues # # This patch adds the __le16 data types to the file-storage gadget and # removes some erroneous conversions to little-endian order. # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/file_storage.c # 2004/10/20 07:25:24-07:00 stern@rowland.harvard.edu +15 -15 # USB file-storage gadget: clean up endian issues # # ChangeSet # 2004/10/21 13:29:33-07:00 david-b@pacbell.net # [PATCH] USB: net2280 compile fixes # # Fix some compiler warnings that came up with net2280 on processors with # 64bit dma_addr-t ... one of them would have been a bug on big-endian CPUs. # (Thanks to Randy Dunlap for reporting these.) # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/net2280.h # 2004/10/15 13:26:59-07:00 david-b@pacbell.net +4 -4 # USB: net2280 compile fixes # # drivers/usb/gadget/net2280.c # 2004/10/15 13:34:35-07:00 david-b@pacbell.net +6 -3 # USB: net2280 compile fixes # # ChangeSet # 2004/10/21 13:29:21-07:00 david-b@pacbell.net # [PATCH] USB: omap_udc updates # # This is a collection of updates to the OMAP UDC driver. # # - OMAP-1510 support, including DMA (the DMA controller isn't quite # the same as on newer chips) but not double buffering. # # - Some PIO work: # # * fix some races that showed up on OMAP-1510 # # * tracking down annoying PIO-OUT lossage and making double buffering # start to behave (needed as fallback if all DMA channels are in use). # # - DMA-IN works on both 1510 and 16xx # # Plus minor cleanups. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/omap_udc.h # 2004/10/21 09:19:33-07:00 david-b@pacbell.net +4 -2 # USB: omap_udc updates # # drivers/usb/gadget/omap_udc.c # 2004/10/21 09:19:33-07:00 david-b@pacbell.net +245 -90 # USB: omap_udc updates # # ChangeSet # 2004/10/21 13:29:07-07:00 david-b@pacbell.net # [PATCH] USB: ohci module param for broken bios # # This patch provides a way to work around especially broken BIOS/SMM # implementations which claim they support the OS-handoff handshake # but actually don't. It's confirmed that this resolves some OSDL bug # (ID isn't handy just now). # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/ohci-hcd.c # 2004/10/12 06:24:03-07:00 david-b@pacbell.net +6 -1 # USB: ohci module param for broken bios # # ChangeSet # 2004/10/21 13:28:54-07:00 david-b@pacbell.net # [PATCH] USB: usb error code docs # # This has various updates to the USB error code documentation that I've # had floating around. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # Documentation/usb/error-codes.txt # 2004/10/21 11:17:34-07:00 david-b@pacbell.net +28 -15 # USB: usb error code docs # # ChangeSet # 2004/10/21 13:28:41-07:00 david-b@pacbell.net # [PATCH] USB: usb/hcd kconfig updates # # This updates the dependencies of the HCDs and host-side USB so that: # # - Options for PCI-only HCDs (UHCI and, for now, EHCI) only appear # systems that actually have PCI. # # - Adding non-PCI bus glue support for another OHCI adapter doesn't # need involve changing the main USB Kconfig anymore. # # - Minor tweaks to the OMAP support, so OMAP 17xx and 24xx don't need # additional Kconfig changes and so the H3/17xx gets the ISP1301 too. # # This still tries to hide host-side USB config options on systems that # don't offer USB. While currently convenient, that's a losing proposition # in the long term: host controllers on chips like SL811 and TD243 can be # put onto any custom board. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/Kconfig # 2004/10/21 10:36:59-07:00 david-b@pacbell.net +22 -4 # USB: usb/hcd kconfig updates # # drivers/usb/Kconfig # 2004/10/21 10:13:54-07:00 david-b@pacbell.net +1 -1 # USB: usb/hcd kconfig updates # # ChangeSet # 2004/10/21 13:28:29-07:00 david-b@pacbell.net # [PATCH] USB: goku_udc sparse updates # # This is a bunch of "sparse" fixes for goku_udc. One of these might be # an issue on some systems for code that explicitly halts IN endpoints # (like file_storage) if normal memory access doesn't work for PCI. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/goku_udc.h # 2004/10/21 09:19:33-07:00 david-b@pacbell.net +4 -4 # USB: goku_udc sparse updates # # drivers/usb/gadget/goku_udc.c # 2004/10/21 09:19:33-07:00 david-b@pacbell.net +76 -73 # USB: goku_udc sparse updates # # ChangeSet # 2004/10/21 12:51:05-07:00 greg@kroah.com # Merge gregkh@kernel.bkbits.net:linux/usb-2.6 # into kroah.com:/home/greg/linux/BK/usb-2.6 # # drivers/usb/serial/visor.c # 2004/10/21 12:51:02-07:00 greg@kroah.com +0 -0 # Auto merged # # drivers/usb/serial/usb-serial.c # 2004/10/21 12:51:02-07:00 greg@kroah.com +0 -0 # Auto merged # # drivers/usb/serial/pl2303.c # 2004/10/21 12:51:02-07:00 greg@kroah.com +0 -0 # Auto merged # # drivers/usb/serial/cyberjack.c # 2004/10/21 12:51:02-07:00 greg@kroah.com +0 -0 # Auto merged # # ChangeSet # 2004/10/21 00:30:07-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/net/usbnet.c # 2004/10/21 00:30:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/net/kaweth.c # 2004/10/21 00:30:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/hid-core.c # 2004/10/21 00:30:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/uhci-hcd.c # 2004/10/21 00:30:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/usblp.c # 2004/10/21 00:30:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/10/21 00:30:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/21 00:28:34-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/net/catc.c # 2004/10/21 00:28:30-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/media/ov511.c # 2004/10/21 00:28:30-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/uhci-hcd.c # 2004/10/21 00:28:30-07:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/21 00:28:30-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/20 16:49:07-07:00 stern@rowland.harvard.edu # [PATCH] USB Gadget: Use proper BCD values # # This updates an earlier patch that added bcdDevice values for a new # USB peripheral controller. The values weren't valid BCD numbers. # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/zero.c # 2004/10/20 07:01:08-07:00 stern@rowland.harvard.edu +1 -1 # USB Gadget: Use proper BCD values # # drivers/usb/gadget/file_storage.c # 2004/10/20 07:00:56-07:00 stern@rowland.harvard.edu +1 -1 # USB Gadget: Use proper BCD values # # drivers/usb/gadget/ether.c # 2004/10/20 07:01:03-07:00 stern@rowland.harvard.edu +1 -1 # USB Gadget: Use proper BCD values # # ChangeSet # 2004/10/20 16:37:46-07:00 shemminger@osdl.org # [PATCH] USB kaweth: use alloc_etherdev to allocate device private data - fix # # Goof found by compile warning. # # # From: Stephen Hemminger # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/kaweth.c # 2004/10/19 15:07:25-07:00 shemminger@osdl.org +1 -1 # USB kaweth: use alloc_etherdev to allocate device private data - fix # # ChangeSet # 2004/10/20 16:37:27-07:00 david-b@pacbell.net # [PATCH] USB: usbnet patch (new ax8817x device) # # This patch enables usage of another USB2 100BASE-T adapter. # http://www.corega.co.jp/product/list/lanadp/feusb2tx.htm # # From: Naoki Shibata # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/usbnet.c # 2004/10/20 16:30:29-07:00 david-b@pacbell.net +4 -0 # USB: usbnet patch (new ax8817x device) # # ChangeSet # 2004/10/20 16:37:08-07:00 dale@farnsworth.org # [PATCH] USB: USB fixes for non-cache-coherent processors # # I posted this before, but didn't see any discussion. # # This patch fixes a couple of places where the usb subsystem # DMAs to/from local (stack) variables. This doesn't work on # non-cache-coherent processors. I'm testing on PPC 4xx systems. # # Signed-off-by: Dale Farnsworth # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/message.c # 2004/10/01 12:16:40-07:00 dale@farnsworth.org +13 -3 # USB: USB fixes for non-cache-coherent processors # # drivers/usb/class/audio.c # 2004/10/01 12:16:40-07:00 dale@farnsworth.org +11 -2 # USB: USB fixes for non-cache-coherent processors # # ChangeSet # 2004/10/20 16:36:50-07:00 stern@rowland.harvard.edu # [PATCH] UHCI: No bandwidth reclamation during enumeration # # A few devices prefer not to have full-speed bandwidth reclamation turned # on while they are being enumerated. In particular this seems to be true # for the USB Bluetooth adapters built in to some laptop models (used for # remote keyboards). This patch alters the UHCI driver so that control URBs # for devices still in the USB_STATE_DEFAULT state will be placed on the # low-speed queue rather than the full-speed queue. Since the low-speed # queue isn't subject to bandwidth reclamation the devices will work # properly. The negative impact on other devices is minimal; the process of # device initialization will be slowed down by a few milliseconds. # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/uhci-hcd.c # 2004/10/14 10:25:46-07:00 stern@rowland.harvard.edu +6 -2 # UHCI: No bandwidth reclamation during enumeration # # ChangeSet # 2004/10/20 16:36:31-07:00 shemminger@osdl.org # [PATCH] usbnet: use alloc_etherdev to allocate private data # # In order for network device lifetime stuff to work properly, it is necessary # for devices to allocate private data as part of alloc_etherdev. # Also, netdev_priv() is improvement over dereferencing netdev->priv # # Signed-off-by: Stephen Hemminger # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/usbnet.c # 2004/10/19 09:44:03-07:00 shemminger@osdl.org +31 -35 # usbnet: use alloc_etherdev to allocate private data # # ChangeSet # 2004/10/20 16:36:12-07:00 shemminger@osdl.org # [PATCH] kaweth: use alloc_etherdev to allocate device private # # Change other usb network driver to use alloc_etherdev to allocate the # private data structure. And use netdev_priv to find it. # # Signed-off-by: Stephen Hemminger # Signed-off-by: Oliver Neukum # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/kaweth.c # 2004/10/19 10:39:56-07:00 shemminger@osdl.org +47 -72 # kaweth: use alloc_etherdev to allocate device private # # ChangeSet # 2004/10/20 16:14:25-07:00 david-b@pacbell.net # [PATCH] USB: usb suspend support for hid-core # # Basic HID driver support for USB suspend/resume. At least one keyboard # works OK as a remote wakeup source ... unless you write the sysfs # power/state attribute using that USB keyboard, in which case the input # subsystem reports an endless stream of newlines! :) # # Someone still needs to implement some configurable timer to support the # "suspend idle mice/keyboards/..." policy for devices that can issue # wakeup events. In conjunction with autosuspend policies in hub and # HCD (UHCI) code, that could allegedly save 2W of power by enabling the # C3 state on Centrino laptops that use USB mice. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/input/hid-core.c # 2004/10/01 12:12:41-07:00 david-b@pacbell.net +27 -0 # USB: usb suspend support for hid-core # # ChangeSet # 2004/10/20 16:14:05-07:00 david-b@pacbell.net # [PATCH] USB: usb hub descriptor fetch needs retries # # Some of the recent changes to change how descriptors are read have managed # to confuse one USB keyboard. It recovers OK with a few retries though. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/10/01 10:18:19-07:00 david-b@pacbell.net +11 -3 # USB: usb hub descriptor fetch needs retries # # ChangeSet # 2004/10/20 16:13:46-07:00 lkml@lievin.net # [PATCH] USB: tiglusb.c: add direct USB support on some new TI handhelds # # I have extended my driver to add support of the embedded USB port provided by # some new Texas Instruments' handhelds. Things are the same except for the # maximum packet size. # # Description: add support of the USB port embedded on some new TI handhelds (TI84+ and TI89 Titanium). # # Thanks, Romain. # # Signed-off-by: Romain Lievin # Signed-off-by: Greg Kroah-Hartman # # include/linux/ticable.h # 2004/09/26 06:25:53-07:00 lkml@lievin.net +2 -0 # USB: tiglusb.c: add direct USB support on some new TI handhelds # # drivers/usb/misc/tiglusb.h # 2004/09/26 06:27:17-07:00 lkml@lievin.net +2 -6 # USB: tiglusb.c: add direct USB support on some new TI handhelds # # drivers/usb/misc/tiglusb.c # 2004/09/26 06:39:34-07:00 lkml@lievin.net +42 -16 # USB: tiglusb.c: add direct USB support on some new TI handhelds # # Documentation/usb/silverlink.txt # 2004/09/26 06:16:15-07:00 lkml@lievin.net +4 -2 # USB: tiglusb.c: add direct USB support on some new TI handhelds # # ChangeSet # 2004/10/20 16:13:25-07:00 lcapitulino@conectiva.com.br # [PATCH] USB: Module version info for Belkin_sa. # # Add module version information for usb/serial/belkin_sa.c. # # # Signed-off-by: Luiz Capitulino # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/belkin_sa.c # 2004/09/25 13:27:57-07:00 lcapitulino@conectiva.com.br +1 -0 # USB: Module version info for Belkin_sa. # # ChangeSet # 2004/10/20 16:13:07-07:00 lcapitulino@conectiva.com.br # [PATCH] USB: Module version info for PL2303. # # Add module version information for usb/serial/pl2303.c. # # # Signed-off-by: Luiz Capitulino # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/pl2303.c # 2004/09/25 13:16:56-07:00 lcapitulino@conectiva.com.br +1 -0 # USB: Module version info for PL2303. # # ChangeSet # 2004/10/20 16:12:48-07:00 lcapitulino@conectiva.com.br # [PATCH] USB: Module version info for CyberJack. # # Add module version information for drivers/usb/serial/cyberjack.c. # # # Signed-off-by: Luiz Capitulino # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/cyberjack.c # 2004/09/27 17:51:53-07:00 lcapitulino@conectiva.com.br +1 -0 # USB: Module version info for CyberJack. # # ChangeSet # 2004/10/20 16:12:29-07:00 zaitcev@redhat.com # [PATCH] USB: usblp BKL removal # # the appended patch is not in yet, what gives? I sent it to Marcelo with # an understanding that it would be in Linus tree any day now. It was a couple # of months ago. It's not just BKL witchhunt either. I remember that it fixed # an oops, although I do not remember the precise scenario by now (it had # something to do with a race between ->release and ->disconnect). # # # From: Pete Zaitcev # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/usblp.c # 2004/10/04 17:15:43-07:00 zaitcev@redhat.com +8 -8 # USB: usblp BKL removal # # ChangeSet # 2004/10/20 16:12:08-07:00 rco3@2005dauphin.org # [PATCH] USB: PL2303 - PharosGPS patch # # This patch adds recognition/support for the PharosGPS puck, as included with # Microsoft's Streets and Trips package. The device has an inline # USB-to-serial converter which functions as a PL2303 but with different # VENDOR_ID and PRODUCT_ID, and so the PL2303 driver is modified to recognize # this additional device. # # Signed-off by: Robert C. Olsen, III [pl2303@2005dauphin.org] # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/pl2303.h # 2004/10/01 06:53:56-07:00 rco3@2005dauphin.org +3 -0 # USB: PL2303 - PharosGPS patch # # drivers/usb/serial/pl2303.c # 2004/10/01 06:50:59-07:00 rco3@2005dauphin.org +1 -0 # USB: PL2303 - PharosGPS patch # # ChangeSet # 2004/10/20 16:11:49-07:00 philippe.bertin@pandora.be # [PATCH] USB: Superfluous statement in usb.c # # drivers/usb/core/usb.c # 2004/10/06 12:46:34-07:00 philippe.bertin@pandora.be +0 -2 # USB: Superfluous statement in usb.c # # ChangeSet # 2004/10/20 16:11:28-07:00 luca.risolia@studio.unibo.it # [PATCH] USB: W996[87]CF driver updates # # Small W996[87]CF documentation updates. # # Signed-off-by: Luca Risolia # # drivers/usb/media/w9968cf.h # 2004/10/08 06:03:21-07:00 luca.risolia@studio.unibo.it +1 -1 # USB: W996[87]CF driver updates # # MAINTAINERS # 2004/10/08 06:04:18-07:00 luca.risolia@studio.unibo.it +2 -2 # USB: W996[87]CF driver updates # # Documentation/usb/w9968cf.txt # 2004/10/08 06:19:58-07:00 luca.risolia@studio.unibo.it +27 -24 # USB: W996[87]CF driver updates # # ChangeSet # 2004/10/20 16:11:09-07:00 stern@rowland.harvard.edu # [PATCH] usbcore: drop reference to bus on allocation error # # A recent patch introduced this reference counting leak. # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # # ===== drivers/usb/core/usb.c 1.293 vs edited ===== # # drivers/usb/core/usb.c # 2004/10/08 10:05:23-07:00 stern@rowland.harvard.edu +1 -0 # usbcore: drop reference to bus on allocation error # # ChangeSet # 2004/10/20 16:10:49-07:00 mdharm-usb@one-eyed-alien.net # [PATCH] USB Storage: Fix queuecommand() for disconnected devices # # Following the recommendation of James Bottomley (of SCSI fame), this patch # changes the queuecommand() routine so that when a command is received for a # disconnected device, instead of accepting the command and then ignoring it, # we fail the command immediately with DID_NO_CONNECT. # # This fixes a timeout-abort-oops sequence that would occur when the # higher-level drivers (mostly the CD driver) try to queue a SYNCHRONIZE # CACHE command during scsi_remove_host(). # # # Signed-off-by: Alan Stern # Signed-off-by: Matthew Dharm # Signed-off-by: Greg Kroah-Hartman # # # ===== drivers/usb/storage/scsiglue.c 1.84 vs edited ===== # # drivers/usb/storage/scsiglue.c # 2004/09/30 13:07:33-07:00 mdharm-usb@one-eyed-alien.net +10 -3 # USB Storage: Fix queuecommand() for disconnected devices # # ChangeSet # 2004/10/20 15:33:03-07:00 greg@kroah.com # USB: fix DoS in the visor driver by rate limiting sends. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/visor.c # 2004/10/20 15:32:53-07:00 greg@kroah.com +69 -12 # USB: fix DoS in the visor driver by rate limiting sends. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/10/20 15:32:01-07:00 greg@kroah.com # USB: fix build error in the USB core if CONFIG_PROCFS is disabled # # Signed-off-by: Greg Kroah-Hartman # # include/linux/proc_fs.h # 2004/10/20 15:31:50-07:00 greg@kroah.com +1 -0 # USB: fix build error in the USB core if CONFIG_PROCFS is disabled # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/10/20 15:31:02-07:00 greg@kroah.com # USB: remove unneeded checks in the usb-serial core. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/usb-serial.c # 2004/10/20 15:30:52-07:00 greg@kroah.com +12 -24 # USB: remove unneeded checks in the usb-serial core. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/10/20 15:30:06-07:00 greg@kroah.com # USB: add phidgetkit driver. # # originally written by Sean Young but with LED additions and # cleanups from me. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/misc/phidgetkit.c # 2004/10/20 15:29:55-07:00 greg@kroah.com +581 -0 # # drivers/usb/misc/phidgetkit.c # 2004/10/20 15:29:55-07:00 greg@kroah.com +0 -0 # BitKeeper file /home/greg/linux/BK/usb-2.6/drivers/usb/misc/phidgetkit.c # # drivers/usb/misc/Makefile # 2004/10/20 15:29:55-07:00 greg@kroah.com +2 -1 # USB: add phidgetkit driver. # # originally written by Sean Young but with LED additions and # cleanups from me. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/misc/Kconfig # 2004/10/20 15:29:55-07:00 greg@kroah.com +10 -0 # USB: add phidgetkit driver. # # originally written by Sean Young but with LED additions and # cleanups from me. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/10/20 15:28:22-07:00 greg@kroah.com # USB: update devices.txt with the proper USB minor number information. # # Signed-off-by: Greg Kroah-Hartman # # Documentation/devices.txt # 2004/10/20 15:28:12-07:00 greg@kroah.com +17 -6 # USB: update devices.txt with the proper USB minor number information. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/10/19 22:18:43-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/net/rtl8150.c # 2004/10/19 22:18:40-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/net/kaweth.c # 2004/10/19 22:18:40-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/net/catc.c # 2004/10/19 22:18:40-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/uhci-hcd.c # 2004/10/19 22:18:40-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ehci-hcd.c # 2004/10/19 22:18:40-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/gadget/net2280.c # 2004/10/19 22:18:40-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/19 17:42:42-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/serial/digi_acceleport.c # 2004/10/19 17:42:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/media/konicawc.c # 2004/10/19 17:42:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/hid-core.c # 2004/10/19 17:42:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ehci.h # 2004/10/19 17:42:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ehci-hcd.c # 2004/10/19 17:42:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/gadget/net2280.c # 2004/10/19 17:42:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/usblp.c # 2004/10/19 17:42:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/19 17:42:38-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/18 20:41:07-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/net/usbnet.c # 2004/10/18 20:41:04-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/net/kaweth.c # 2004/10/18 20:41:04-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/cdc-acm.c # 2004/10/18 20:41:04-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/18 20:40:03-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/input/hid-core.c # 2004/10/18 20:40:00-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/15 22:48:29-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # Documentation/kernel-parameters.txt # 2004/10/15 22:48:26-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/15 22:47:28-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # drivers/usb/serial/digi_acceleport.c # 2004/10/15 22:47:24-07:00 akpm@bix.(none) +0 -6 # Auto merged # # drivers/usb/media/konicawc.c # 2004/10/15 22:47:24-07:00 akpm@bix.(none) +0 -1 # Auto merged # # drivers/usb/input/hid-core.c # 2004/10/15 22:47:24-07:00 akpm@bix.(none) +0 -1 # Auto merged # # drivers/usb/host/ehci.h # 2004/10/15 22:47:24-07:00 akpm@bix.(none) +0 -1 # Auto merged # # drivers/usb/host/ehci-hcd.c # 2004/10/15 22:47:24-07:00 akpm@bix.(none) +0 -9 # Auto merged # # drivers/usb/gadget/net2280.c # 2004/10/15 22:47:24-07:00 akpm@bix.(none) +0 -10 # Auto merged # # drivers/usb/class/usblp.c # 2004/10/15 22:47:24-07:00 akpm@bix.(none) +0 -4 # Auto merged # # ChangeSet # 2004/10/09 14:45:27-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # Documentation/kernel-parameters.txt # 2004/10/09 14:45:23-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/08 12:14:08-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/serial/empeg.c # 2004/10/08 12:14:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/hcd.c # 2004/10/08 12:14:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/bluetty.c # 2004/10/08 12:14:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/10/08 12:14:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/08 12:14:03-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/06 20:17:39-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/storage/protocol.c # 2004/10/06 20:17:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/storage/isd200.c # 2004/10/06 20:17:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/io_ti.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/io_edgeport.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/empeg.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/net/usbnet.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/net/rtl8150.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/net/kaweth.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/net/catc.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/misc/legousbtower.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/misc/auerswald.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/media/ov511.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/wacom.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/kbtab.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/hid-core.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/aiptek.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/uhci-hub.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/uhci-hcd.h # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/uhci-hcd.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ohci.h # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ohci-hub.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ohci-dbg.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ehci.h # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ehci-hub.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/hcd.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/usblp.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/cdc-acm.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/bluetty.c # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/06 20:17:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/10/06 20:17:34-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/10/06 14:34:47-07:00 akpm@bix.(none) # foo # # drivers/usb/host/uhci-hub.c # 2004/10/06 14:34:41-07:00 akpm@bix.(none) +0 -3 # foo # # drivers/usb/storage/protocol.c # 2004/10/06 14:31:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/storage/isd200.c # 2004/10/06 14:31:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/io_ti.c # 2004/10/06 14:31:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/io_edgeport.c # 2004/10/06 14:31:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/serial/empeg.c # 2004/10/06 14:31:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/net/usbnet.c # 2004/10/06 14:31:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/net/rtl8150.c # 2004/10/06 14:31:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/net/kaweth.c # 2004/10/06 14:31:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/net/catc.c # 2004/10/06 14:31:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/misc/legousbtower.c # 2004/10/06 14:31:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/misc/auerswald.c # 2004/10/06 14:31:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/media/ov511.c # 2004/10/06 14:31:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/wacom.c # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/kbtab.c # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/hid-core.c # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/input/aiptek.c # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/uhci-hcd.h # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/uhci-hcd.c # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ohci.h # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ohci-hub.c # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ohci-dbg.c # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ehci.h # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/host/ehci-hub.c # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/core/hcd.c # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/usblp.c # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/cdc-acm.c # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/class/bluetty.c # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/06 14:31:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # diff -Nru a/Documentation/devices.txt b/Documentation/devices.txt --- a/Documentation/devices.txt 2004-10-21 14:31:01 -07:00 +++ b/Documentation/devices.txt 2004-10-21 14:31:02 -07:00 @@ -2546,12 +2546,7 @@ 0 = /dev/usb/lp0 First USB printer ... 15 = /dev/usb/lp15 16th USB printer - 16 = /dev/usb/mouse0 First USB mouse - ... - 31 = /dev/usb/mouse15 16th USB mouse - 32 = /dev/usb/ez0 First USB firmware loader - ... - 47 = /dev/usb/ez15 16th USB firmware loader + 32 = /dev/usb/mdc800 MDC800 USB camera 48 = /dev/usb/scanner0 First USB scanner ... 63 = /dev/usb/scanner15 16th USB scanner @@ -2559,6 +2554,22 @@ 65 = /dev/usb/usblcd USBLCD Interface (info@usblcd.de) 66 = /dev/usb/cpad0 Synaptics cPad (mouse/LCD) + 96 = /dev/usb/hiddev0 1st USB HID device + ... + 111 = /dev/usb/hiddev15 16th USB HID device + 112 = /dev/usb/auer0 1st auerswald ISDN device + ... + 127 = /dev/usb/auer15 16th auerswald ISDN device + 128 = /dev/usb/brlvgr0 First Braille Voyager device + ... + 131 = /dev/usb/brlvgr3 Fourth Braille Voyager device + 144 = /dev/usb/lcd USB LCD device + 160 = /dev/usb/legousbtower0 1st USB Legotower device + ... + 175 = /dev/usb/legousbtower15 16th USB Legotower device + 240 = /dev/usb/dabusb0 First daubusb device + ... + 243 = /dev/usb/dabusb3 Fourth dabusb device 181 char Conrad Electronic parallel port radio clocks 0 = /dev/pcfclock0 First Conrad radio clock diff -Nru a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt --- a/Documentation/usb/error-codes.txt 2004-10-21 14:31:01 -07:00 +++ b/Documentation/usb/error-codes.txt 2004-10-21 14:31:01 -07:00 @@ -1,11 +1,12 @@ -Revised: 2002-Feb-09. +Revised: 2004-Oct-21 This is the documentation of (hopefully) all possible error codes (and their interpretation) that can be returned from usbcore. Some of them are returned by the Host Controller Drivers (HCDs), which device drivers only see through usbcore. As a rule, all the HCDs should -behave the same except for transfer speed dependent behaviors. +behave the same except for transfer speed dependent behaviors and the +way certain faults are reported. ************************************************************************** @@ -26,29 +27,35 @@ of urb. (treat as a host controller bug.) -EINVAL a) Invalid transfer type specified (or not supported) - b) Invalid interrupt interval (0<=n<256) - c) more than one interrupt packet requested + b) Invalid or unsupported periodic transfer interval + c) ISO: attempted to change transfer interval d) ISO: number_of_packets is < 0 + e) various other cases -EAGAIN a) specified ISO start frame too early b) (using ISO-ASAP) too much scheduled for the future wait some time and try again. --EFBIG too much ISO frames requested (currently uhci>900) +-EFBIG Host controller driver can't schedule that many ISO frames. -EPIPE Specified endpoint is stalled. For non-control endpoints, reset this status with usb_clear_halt(). --EMSGSIZE endpoint message size is zero, do interface/alternate setting +-EMSGSIZE (a) endpoint maxpacket size is zero; it is not usable + in the current interface altsetting. + (b) ISO packet is biger than endpoint maxpacket + (c) requested data transfer size is invalid (negative) --ENOSPC The host controller's bandwidth is already consumed and - this request would push it past its allowed limit. +-ENOSPC This request would overcommit the usb bandwidth reserved + for periodic transfers (interrupt, isochronous). --ESHUTDOWN The host controller has been disabled due to some +-ESHUTDOWN The device or host controller has been disabled due to some problem that could not be worked around. -EPERM Submission failed because urb->reject was set. +-EHOSTUNREACH URB was rejected because the device is suspended. + ************************************************************************** * Error codes returned by in urb->status * @@ -71,14 +78,14 @@ -EINPROGRESS URB still pending, no results yet (That is, if drivers see this it's a bug.) --EPROTO (*) a) bitstuff error +-EPROTO (*, **) a) bitstuff error b) no response packet received within the prescribed bus turn-around time c) unknown USB error --EILSEQ (*) CRC mismatch +-EILSEQ (*, **) CRC mismatch --EPIPE Endpoint stalled. For non-control endpoints, +-EPIPE (**) Endpoint stalled. For non-control endpoints, reset this status with usb_clear_halt(). -ECOMM During an IN transfer, the host controller @@ -97,7 +104,7 @@ specified buffer, and URB_SHORT_NOT_OK was set in urb->transfer_flags. --ETIMEDOUT transfer timed out, NAK +-ETIMEDOUT (**) transfer timed out, NAK -ENODEV Device was removed. Often preceded by a burst of other errors, since the hub driver does't detect @@ -110,12 +117,18 @@ -ECONNRESET URB was asynchronously unlinked by usb_unlink_urb --ESHUTDOWN The host controller has been disabled due to some - problem that could not be worked around. +-ESHUTDOWN The device or host controller has been disabled due + to some problem that could not be worked around, + such as a physical disconnect. (*) Error codes like -EPROTO, -EILSEQ and -EOVERFLOW normally indicate hardware problems such as bad devices (including firmware) or cables. + +(**) This is also one of several codes that different kinds of host +controller use to to indicate a transfer has failed because of device +disconnect. In the interval before the hub driver starts disconnect +processing, devices may receive such fault reports for every request. diff -Nru a/Documentation/usb/silverlink.txt b/Documentation/usb/silverlink.txt --- a/Documentation/usb/silverlink.txt 2004-10-21 14:31:01 -07:00 +++ b/Documentation/usb/silverlink.txt 2004-10-21 14:31:01 -07:00 @@ -1,5 +1,6 @@ ------------------------------------------------------------------------- Readme for Linux device driver for the Texas Instruments SilverLink cable +and direct USB cable provided by some TI's handhelds. ------------------------------------------------------------------------- Author: Romain Liévin & Julien Blache @@ -9,7 +10,8 @@ This is a driver for the TI-GRAPH LINK USB (aka SilverLink) cable, a cable designed by TI for connecting their TI8x/9x calculators to a computer -(PC or Mac usually). +(PC or Mac usually). It has been extended to support the USB port offered by +some latest TI handhelds (TI84+ and TI89 Titanium). If you need more information, please visit the 'SilverLink drivers' homepage at the above URL. @@ -73,4 +75,4 @@ CREDITS: The code is based on dabusb.c, printer.c and scanner.c ! -The driver has been developed independently of Texas Instruments. +The driver has been developed independently of Texas Instruments Inc. diff -Nru a/Documentation/usb/w9968cf.txt b/Documentation/usb/w9968cf.txt --- a/Documentation/usb/w9968cf.txt 2004-10-21 14:31:02 -07:00 +++ b/Documentation/usb/w9968cf.txt 2004-10-21 14:31:02 -07:00 @@ -8,26 +8,30 @@ Index ===== -1. Copyright -2. License -3. Overview -4. Supported devices -5. Module dependencies -6. Module loading -7. Module paramaters -8. Contact information -9. Credits +1. Copyright +2. Disclaimer +3. License +4. Overview +5. Supported devices +6. Module dependencies +7. Module loading +8. Module paramaters +9. Contact information +10. Credits 1. Copyright ============ Copyright (C) 2002-2004 by Luca Risolia + +2. Disclaimer +============= Winbond is a trademark of Winbond Electronics Corporation. -This driver is not sponsored or developed by Winbond. +This software is not sponsored or developed by Winbond. -2. License +3. License ========== 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 @@ -44,7 +48,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -3. Overview +4. Overview =========== This driver supports the video streaming capabilities of the devices mounting Winbond W9967CF and Winbond W9968CF JPEG USB Dual Mode Camera Chips. OV681 @@ -57,7 +61,7 @@ every time an application tries to open a recognized device, "w9968cf" checks the presence of the "w9968cf-vpp" module and loads it automatically by default. -Please keep in mind that official kernels do NOT include the second module for +Please keep in mind that official kernels do not include the second module for performance purposes. However it is always recommended to download and install the latest and complete release of the driver, replacing the existing one, if present: it will be still even possible not to load the "w9968cf-vpp" module at @@ -65,7 +69,7 @@ the official Linux 2.4 kernels is the writeable /proc filesystem interface. The latest and full-featured version of the W996[87]CF driver can be found at: -http://go.lamarinapunto.com/ . Please refer to the documentation included in +http://www.linux-projects.org. Please refer to the documentation included in that package, if you are going to use it. Up to 32 cameras can be handled at the same time. They can be connected and @@ -83,7 +87,7 @@ compiled with the automatic module loading option). -4. Supported devices +5. Supported devices ==================== At the moment, known W996[87]CF and OV681 based devices are: - Aroma Digi Pen VGA Dual Mode ADG-5000 (unknown image sensor) @@ -99,11 +103,9 @@ If you know any other W996[87]CF or OV681 based cameras, please contact me. -The list above does NOT imply that all those devices work with this driver: up +The list above does not imply that all those devices work with this driver: up until now only webcams that have an image sensor supported by the "ovcamchip" -module work. -For a list of supported image sensors, please visit the author's homepage on -this module: http://alpha.dyndns.org/ov511/ +module work. Kernel messages will always tell you whether this is case. Possible external microcontrollers of those webcams are not supported: this means that still images cannot be downloaded from the device memory. @@ -113,7 +115,7 @@ additional testing and full support, would be much appreciated. -5. Module dependencies +6. Module dependencies ====================== For it to work properly, the driver needs kernel support for Video4Linux, USB and I2C, and the "ovcamchip" module for the image sensor. Make sure you are not @@ -157,7 +159,7 @@ CONFIG_USB_W9968CF=m -6. Module loading +7. Module loading ================= To use the driver, it is necessary to load the "w9968cf" module into memory after every other module required. @@ -166,6 +168,7 @@ [root@localhost home]# modprobe usbcore [root@localhost home]# modprobe i2c-core + [root@localhost home]# modprobe videodev [root@localhost home]# modprobe w9968cf At this point the pertinent devices should be recognized: "dmesg" can be used @@ -181,7 +184,7 @@ [root@locahost home]# modinfo w9968cf -7. Module parameters +8. Module parameters ==================== Module parameters are listed below: ------------------------------------------------------------------------------- @@ -452,7 +455,7 @@ ------------------------------------------------------------------------------- -8. Contact information +9. Contact information ====================== I may be contacted by e-mail at . @@ -461,7 +464,7 @@ is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'. -9. Credits +10. Credits ========== The development would not have proceed much further without having looked at the source code of other drivers and without the help of several persons; in diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS 2004-10-21 14:31:02 -07:00 +++ b/MAINTAINERS 2004-10-21 14:31:02 -07:00 @@ -2371,7 +2371,7 @@ P: Luca Risolia M: luca.risolia@studio.unibo.it L: linux-usb-devel@lists.sourceforge.net -W: http://go.lamarinapunto.com +W: http://www.linux-projects.org S: Maintained USB SUBSYSTEM @@ -2399,7 +2399,7 @@ P: Luca Risolia M: luca.risolia@studio.unibo.it L: linux-usb-devel@lists.sourceforge.net -W: http://go.lamarinapunto.com +W: http://www.linux-projects.org S: Maintained USER-MODE LINUX diff -Nru a/drivers/usb/Kconfig b/drivers/usb/Kconfig --- a/drivers/usb/Kconfig 2004-10-21 14:31:01 -07:00 +++ b/drivers/usb/Kconfig 2004-10-21 14:31:01 -07:00 @@ -7,7 +7,7 @@ # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. config USB tristate "Support for Host-side USB" - depends on PCI || SA1111 || ARCH_OMAP1510 || ARCH_OMAP1610 || ARCH_LH7A404 || PXA27x + depends on USB_ARCH_HAS_HCD ---help--- Universal Serial Bus (USB) is a specification for a serial bus subsystem which offers higher speeds and more features than the diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c --- a/drivers/usb/class/audio.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/class/audio.c 2004-10-21 14:31:02 -07:00 @@ -3119,12 +3119,18 @@ { struct usb_device *dev = state->s->usbdev; struct mixerchannel *ch; - unsigned char buf[2]; + unsigned char *buf; __s16 v1; unsigned int v2, v3; if (!state->nrmixch || state->nrmixch > SOUND_MIXER_NRDEVICES) return; + buf = kmalloc(sizeof(*buf) * 2, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "prepmixch: out of memory\n") ; + return; + } + ch = &state->mixch[state->nrmixch-1]; switch (ch->selector) { case 0: /* mixer unit request */ @@ -3236,13 +3242,16 @@ default: goto err; } - return; + freebuf: + kfree(buf); + return; err: printk(KERN_ERR "usbaudio: mixer request device %u if %u unit %u ch %u selector %u failed\n", dev->devnum, state->ctrlif, ch->unitid, ch->chnum, ch->selector); if (state->nrmixch) state->nrmixch--; + goto freebuf; } diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c --- a/drivers/usb/class/usblp.c 2004-10-21 14:31:01 -07:00 +++ b/drivers/usb/class/usblp.c 2004-10-21 14:31:01 -07:00 @@ -222,6 +222,7 @@ /* forward reference to make our lives easier */ static struct usb_driver usblp_driver; +static DECLARE_MUTEX(usblp_sem); /* locks the existence of usblp's */ /* * Functions for usblp control messages. @@ -343,7 +344,7 @@ if (minor < 0) return -ENODEV; - lock_kernel(); + down (&usblp_sem); retval = -ENODEV; intf = usb_find_interface(&usblp_driver, minor); @@ -389,7 +390,7 @@ } } out: - unlock_kernel(); + up (&usblp_sem); return retval; } @@ -415,13 +416,13 @@ { struct usblp *usblp = file->private_data; - down (&usblp->sem); + down (&usblp_sem); usblp->used = 0; if (usblp->present) { usblp_unlink_urbs(usblp); - up(&usblp->sem); } else /* finish cleanup from disconnect */ usblp_cleanup (usblp); + up (&usblp_sem); return 0; } @@ -1149,8 +1150,8 @@ BUG (); } + down (&usblp_sem); down (&usblp->sem); - lock_kernel(); usblp->present = 0; usb_set_intfdata (intf, NULL); @@ -1159,12 +1160,11 @@ usblp->writebuf, usblp->writeurb->transfer_dma); usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, usblp->readbuf, usblp->readurb->transfer_dma); + up (&usblp->sem); if (!usblp->used) usblp_cleanup (usblp); - else /* cleanup later, on release */ - up (&usblp->sem); - unlock_kernel(); + up (&usblp_sem); } static struct usb_device_id usblp_ids [] = { diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c --- a/drivers/usb/core/hub.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/core/hub.c 2004-10-21 14:31:02 -07:00 @@ -78,9 +78,17 @@ /* USB 2.0 spec Section 11.24.4.5 */ static int get_hub_descriptor(struct usb_device *hdev, void *data, int size) { - return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0), - USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB, - USB_DT_HUB << 8, 0, data, size, HZ * USB_CTRL_GET_TIMEOUT); + int i, ret; + + for (i = 0; i < 3; i++) { + ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0), + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB, + USB_DT_HUB << 8, 0, data, size, + HZ * USB_CTRL_GET_TIMEOUT); + if (ret >= (USB_DT_HUB_NONVAR_SIZE + 2)) + return ret; + } + return -EINVAL; } /* diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c --- a/drivers/usb/core/message.c 2004-10-21 14:31:01 -07:00 +++ b/drivers/usb/core/message.c 2004-10-21 14:31:01 -07:00 @@ -823,9 +823,19 @@ */ int usb_get_status(struct usb_device *dev, int type, int target, void *data) { - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2, - HZ * USB_CTRL_GET_TIMEOUT); + int ret; + u16 *status = kmalloc(sizeof(*status), GFP_KERNEL); + + if (!status) + return -ENOMEM; + + ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, status, + sizeof(*status), HZ * USB_CTRL_GET_TIMEOUT); + + *(u16 *)data = *status; + kfree(status); + return ret; } /** diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/core/usb.c 2004-10-21 14:31:02 -07:00 @@ -550,9 +550,7 @@ return 0; intf = to_usb_interface(dev); - usb_drv = to_usb_driver(drv); - id = usb_drv->id_table; id = usb_match_id (intf, usb_drv->id_table); if (id) @@ -765,6 +763,7 @@ if (dev->bus->op->allocate) if (dev->bus->op->allocate(dev)) { + usb_bus_put(bus); kfree(dev); return NULL; } diff -Nru a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c --- a/drivers/usb/gadget/ether.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/gadget/ether.c 2004-10-21 14:31:02 -07:00 @@ -2320,7 +2320,7 @@ } 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); + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210); } 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-10-21 14:31:02 -07:00 +++ b/drivers/usb/gadget/file_storage.c 2004-10-21 14:31:02 -07:00 @@ -250,7 +250,7 @@ #define DRIVER_DESC "File-backed Storage Gadget" #define DRIVER_NAME "g_file_storage" -#define DRIVER_VERSION "31 August 2004" +#define DRIVER_VERSION "20 October 2004" static const char longname[] = DRIVER_DESC; static const char shortname[] = DRIVER_NAME; @@ -430,9 +430,9 @@ /* Command Block Wrapper */ struct bulk_cb_wrap { - u32 Signature; // Contains 'USBC' + __le32 Signature; // Contains 'USBC' u32 Tag; // Unique per command id - u32 DataTransferLength; // Size of the data + __le32 DataTransferLength; // Size of the data u8 Flags; // Direction in bit 7 u8 Lun; // LUN (normally 0) u8 Length; // Of the CDB, <= MAX_COMMAND_SIZE @@ -445,9 +445,9 @@ /* Command Status Wrapper */ struct bulk_cs_wrap { - u32 Signature; // Should = 'USBS' + __le32 Signature; // Should = 'USBS' u32 Tag; // Same as original command - u32 Residue; // Amount not transferred + __le32 Residue; // Amount not transferred u8 Status; // See below }; @@ -3717,30 +3717,30 @@ if (mod_data.release == 0xffff) { // Parameter wasn't set if (gadget_is_net2280(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0301); + mod_data.release = 0x0301; else if (gadget_is_dummy(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0302); + mod_data.release = 0x0302; else if (gadget_is_pxa(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0303); + mod_data.release = 0x0303; else if (gadget_is_sh(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0304); + mod_data.release = 0x0304; /* The sa1100 controller is not supported */ else if (gadget_is_goku(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0306); + mod_data.release = 0x0306; else if (gadget_is_mq11xx(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0307); + mod_data.release = 0x0307; else if (gadget_is_omap(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0308); + mod_data.release = 0x0308; else if (gadget_is_lh7a40x(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16 (0x0309); + mod_data.release = 0x0309; else if (gadget_is_n9604(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16 (0x030a); + mod_data.release = 0x0310; else { WARN(fsg, "controller '%s' not recognized\n", fsg->gadget->name); - mod_data.release = __constant_cpu_to_le16(0x0399); + mod_data.release = 0x0399; } } diff -Nru a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c --- a/drivers/usb/gadget/goku_udc.c 2004-10-21 14:31:01 -07:00 +++ b/drivers/usb/gadget/goku_udc.c 2004-10-21 14:31:01 -07:00 @@ -90,7 +90,7 @@ static void nuke(struct goku_ep *, int status); static inline void -command(struct goku_udc_regs *regs, int command, unsigned epnum) +command(struct goku_udc_regs __iomem *regs, int command, unsigned epnum) { writel(COMMAND_EP(epnum) | command, ®s->Command); udelay(300); @@ -161,8 +161,8 @@ /* ep1 and ep2 can do double buffering and/or dma */ if (ep->num < 3) { - struct goku_udc_regs *regs = ep->dev->regs; - u32 tmp; + struct goku_udc_regs __iomem *regs = ep->dev->regs; + u32 tmp; /* double buffer except (for now) with pio in */ tmp = ((ep->dma || !ep->is_in) @@ -191,7 +191,7 @@ return 0; } -static void ep_reset(struct goku_udc_regs *regs, struct goku_ep *ep) +static void ep_reset(struct goku_udc_regs __iomem *regs, struct goku_ep *ep) { struct goku_udc *dev = ep->dev; @@ -209,16 +209,16 @@ writel(dev->int_enable, ®s->int_enable); readl(®s->int_enable); if (ep->num < 3) { - struct goku_udc_regs *regs = ep->dev->regs; - u32 tmp; + struct goku_udc_regs __iomem *r = ep->dev->regs; + u32 tmp; - tmp = readl(®s->EPxSingle); + tmp = readl(&r->EPxSingle); tmp &= ~(0x11 << ep->num); - writel(tmp, ®s->EPxSingle); + writel(tmp, &r->EPxSingle); - tmp = readl(®s->EPxBCS); + tmp = readl(&r->EPxBCS); tmp &= ~(0x11 << ep->num); - writel(tmp, ®s->EPxBCS); + writel(tmp, &r->EPxBCS); } /* reset dma in case we're still using it */ if (ep->dma) { @@ -237,7 +237,7 @@ } ep->ep.maxpacket = MAX_FIFO_SIZE; - ep->desc = 0; + ep->desc = NULL; ep->stopped = 1; ep->irqs = 0; ep->dma = 0; @@ -274,10 +274,10 @@ struct goku_request *req; if (!_ep) - return 0; + return NULL; req = kmalloc(sizeof *req, gfp_flags); if (!req) - return 0; + return NULL; memset(req, 0, sizeof *req); req->req.dma = DMA_ADDR_INVALID; @@ -334,7 +334,7 @@ ep = container_of(_ep, struct goku_ep, ep); if (!_ep) - return 0; + return NULL; *dma = DMA_ADDR_INVALID; #if defined(USE_KMALLOC) @@ -413,7 +413,7 @@ /*-------------------------------------------------------------------------*/ static inline int -write_packet(u32 *fifo, u8 *buf, struct goku_request *req, unsigned max) +write_packet(u32 __iomem *fifo, u8 *buf, struct goku_request *req, unsigned max) { unsigned length, count; @@ -488,10 +488,10 @@ static int read_fifo(struct goku_ep *ep, struct goku_request *req) { - struct goku_udc_regs *regs; - u32 size, set; - u8 *buf; - unsigned bufferspace, is_short, dbuff; + struct goku_udc_regs __iomem *regs; + u32 size, set; + u8 *buf; + unsigned bufferspace, is_short, dbuff; regs = ep->dev->regs; top: @@ -581,7 +581,8 @@ } static inline void -pio_irq_enable(struct goku_udc *dev, struct goku_udc_regs *regs, int epnum) +pio_irq_enable(struct goku_udc *dev, + struct goku_udc_regs __iomem *regs, int epnum) { dev->int_enable |= INT_EPxDATASET (epnum); writel(dev->int_enable, ®s->int_enable); @@ -589,7 +590,8 @@ } static inline void -pio_irq_disable(struct goku_udc *dev, struct goku_udc_regs *regs, int epnum) +pio_irq_disable(struct goku_udc *dev, + struct goku_udc_regs __iomem *regs, int epnum) { dev->int_enable &= ~INT_EPxDATASET (epnum); writel(dev->int_enable, ®s->int_enable); @@ -613,10 +615,10 @@ // return: 0 = q running, 1 = q stopped, negative = errno static int start_dma(struct goku_ep *ep, struct goku_request *req) { - struct goku_udc_regs *regs = ep->dev->regs; - u32 master; - u32 start = req->req.dma; - u32 end = start + req->req.length - 1; + struct goku_udc_regs __iomem *regs = ep->dev->regs; + u32 master; + u32 start = req->req.dma; + u32 end = start + req->req.length - 1; master = readl(®s->dma_master) & MST_RW_BITS; @@ -668,9 +670,9 @@ static void dma_advance(struct goku_udc *dev, struct goku_ep *ep) { - struct goku_request *req; - struct goku_udc_regs *regs = ep->dev->regs; - u32 master; + struct goku_request *req; + struct goku_udc_regs __iomem *regs = ep->dev->regs; + u32 master; master = readl(®s->dma_master); @@ -716,9 +718,9 @@ static void abort_dma(struct goku_ep *ep, int status) { - struct goku_udc_regs *regs = ep->dev->regs; - struct goku_request *req; - u32 curr, master; + struct goku_udc_regs __iomem *regs = ep->dev->regs; + struct goku_request *req; + u32 curr, master; /* NAK future host requests, hoping the implicit delay lets the * dma engine finish reading (or writing) its latest packet and @@ -848,7 +850,7 @@ if (unlikely(status != 0)) { if (status > 0) status = 0; - req = 0; + req = NULL; } } /* else pio or dma irq handler advances the queue. */ @@ -927,7 +929,7 @@ } else if (!list_empty(&req->queue)) done(ep, req, -ECONNRESET); else - req = 0; + req = NULL; spin_unlock_irqrestore(&dev->lock, flags); return req ? 0 : -EOPNOTSUPP; @@ -984,7 +986,8 @@ retval = -EAGAIN; else if (ep->is_in && value /* data in (either) packet buffer? */ - && (ep->dev->regs->DataSet & DATASET_AB(ep->num))) + && (readl(&ep->dev->regs->DataSet) + & DATASET_AB(ep->num))) retval = -EAGAIN; else if (!value) goku_clear_halt(ep); @@ -1000,9 +1003,9 @@ static int goku_fifo_status(struct usb_ep *_ep) { - struct goku_ep *ep; - struct goku_udc_regs *regs; - u32 size; + struct goku_ep *ep; + struct goku_udc_regs __iomem *regs; + u32 size; if (!_ep) return -ENODEV; @@ -1022,9 +1025,9 @@ static void goku_fifo_flush(struct usb_ep *_ep) { - struct goku_ep *ep; - struct goku_udc_regs *regs; - u32 size; + struct goku_ep *ep; + struct goku_udc_regs __iomem *regs; + u32 size; if (!_ep) return; @@ -1141,14 +1144,14 @@ udc_proc_read(char *buffer, char **start, off_t off, int count, int *eof, void *_dev) { - char *buf = buffer; - struct goku_udc *dev = _dev; - struct goku_udc_regs *regs = dev->regs; - char *next = buf; - unsigned size = count; - unsigned long flags; - int i, t, is_usb_connected; - u32 tmp; + char *buf = buffer; + struct goku_udc *dev = _dev; + struct goku_udc_regs __iomem *regs = dev->regs; + char *next = buf; + unsigned size = count; + unsigned long flags; + int i, t, is_usb_connected; + u32 tmp; if (off != 0) return 0; @@ -1336,17 +1339,17 @@ ep->dev = dev; INIT_LIST_HEAD (&ep->queue); - ep_reset(0, ep); + ep_reset(NULL, ep); } - dev->ep[0].reg_mode = 0; + dev->ep[0].reg_mode = NULL; dev->ep[0].ep.maxpacket = MAX_EP0_SIZE; list_del_init (&dev->ep[0].ep.ep_list); } static void udc_reset(struct goku_udc *dev) { - struct goku_udc_regs *regs = dev->regs; + struct goku_udc_regs __iomem *regs = dev->regs; writel(0, ®s->power_detect); writel(0, ®s->int_enable); @@ -1363,8 +1366,8 @@ static void ep0_start(struct goku_udc *dev) { - struct goku_udc_regs *regs = dev->regs; - unsigned i; + struct goku_udc_regs __iomem *regs = dev->regs; + unsigned i; VDBG(dev, "%s\n", __FUNCTION__); @@ -1441,15 +1444,15 @@ return -EBUSY; /* hook up the driver */ - driver->driver.bus = 0; + driver->driver.bus = NULL; dev->driver = driver; dev->gadget.dev.driver = &driver->driver; retval = driver->bind(&dev->gadget); if (retval) { DBG(dev, "bind to driver %s --> error %d\n", driver->driver.name, retval); - dev->driver = 0; - dev->gadget.dev.driver = 0; + dev->driver = NULL; + dev->gadget.dev.driver = NULL; return retval; } @@ -1471,7 +1474,7 @@ DBG (dev, "%s\n", __FUNCTION__); if (dev->gadget.speed == USB_SPEED_UNKNOWN) - driver = 0; + driver = NULL; /* disconnect gadget driver after quiesceing hw and the driver */ udc_reset (dev); @@ -1498,7 +1501,7 @@ return -EINVAL; spin_lock_irqsave(&dev->lock, flags); - dev->driver = 0; + dev->driver = NULL; stop_activity(dev, driver); spin_unlock_irqrestore(&dev->lock, flags); @@ -1514,9 +1517,9 @@ static void ep0_setup(struct goku_udc *dev) { - struct goku_udc_regs *regs = dev->regs; - struct usb_ctrlrequest ctrl; - int tmp; + struct goku_udc_regs __iomem *regs = dev->regs; + struct usb_ctrlrequest ctrl; + int tmp; /* read SETUP packet and enter DATA stage */ ctrl.bRequestType = readl(®s->bRequestType); @@ -1623,11 +1626,11 @@ static irqreturn_t goku_irq(int irq, void *_dev, struct pt_regs *r) { - struct goku_udc *dev = _dev; - struct goku_udc_regs *regs = dev->regs; - struct goku_ep *ep; - u32 stat, handled = 0; - unsigned i, rescans = 5; + struct goku_udc *dev = _dev; + struct goku_udc_regs __iomem *regs = dev->regs; + struct goku_ep *ep; + u32 stat, handled = 0; + unsigned i, rescans = 5; spin_lock(&dev->lock); @@ -1645,7 +1648,7 @@ stat = 0; handled = 1; // FIXME have a neater way to prevent re-enumeration - dev->driver = 0; + dev->driver = NULL; goto done; } if (stat & INT_PWRDETECT) { @@ -1825,9 +1828,9 @@ pci_disable_device(pdev); device_unregister(&dev->gadget.dev); - pci_set_drvdata(pdev, 0); - dev->regs = 0; - the_controller = 0; + pci_set_drvdata(pdev, NULL); + dev->regs = NULL; + the_controller = NULL; INFO(dev, "unbind\n"); } @@ -1838,9 +1841,9 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - struct goku_udc *dev = 0; + struct goku_udc *dev = NULL; unsigned long resource, len; - void *base = 0; + void __iomem *base = NULL; int retval; char buf [8], *bufp; @@ -1900,7 +1903,7 @@ retval = -EFAULT; goto done; } - dev->regs = (struct goku_udc_regs *) base; + dev->regs = (struct goku_udc_regs __iomem *) base; pci_set_drvdata(pdev, dev); INFO(dev, "%s\n", driver_desc); diff -Nru a/drivers/usb/gadget/goku_udc.h b/drivers/usb/gadget/goku_udc.h --- a/drivers/usb/gadget/goku_udc.h 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/gadget/goku_udc.h 2004-10-21 14:31:02 -07:00 @@ -216,9 +216,9 @@ struct list_head queue; const struct usb_endpoint_descriptor *desc; - u32 *reg_fifo; - u32 *reg_mode; - u32 *reg_status; + u32 __iomem *reg_fifo; + u32 __iomem *reg_mode; + u32 __iomem *reg_status; }; struct goku_request { @@ -253,7 +253,7 @@ /* pci state used to access those endpoints */ struct pci_dev *pdev; - struct goku_udc_regs *regs; + struct goku_udc_regs __iomem *regs; u32 int_enable; /* statistics... */ diff -Nru a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c --- a/drivers/usb/gadget/net2280.c 2004-10-21 14:31:01 -07:00 +++ b/drivers/usb/gadget/net2280.c 2004-10-21 14:31:01 -07:00 @@ -717,7 +717,7 @@ dmacount |= (1 << DMA_DONE_INTERRUPT_ENABLE); /* td->dmadesc = previously set by caller */ - td->dmaaddr = cpu_to_le32p (&req->req.dma); + td->dmaaddr = cpu_to_le32 (req->req.dma); /* 2280 may be polling VALID_BIT through ep->dma->dmadesc */ wmb (); @@ -1707,8 +1707,10 @@ td = req->td; t = scnprintf (next, size, "\t td %08x " " count %08x buf %08x desc %08x\n", - req->td_dma, td->dmacount, - td->dmaaddr, td->dmadesc); + (u32) req->td_dma, + le32_to_cpu (td->dmacount), + le32_to_cpu (td->dmaaddr), + le32_to_cpu (td->dmadesc)); if (t <= 0 || t > size) goto done; size -= t; @@ -2845,6 +2847,7 @@ dev->got_irq = 1; /* DMA setup */ + /* NOTE: we know only the 32 LSBs of dma addresses may be nonzero */ dev->requests = pci_pool_create ("requests", pdev, sizeof (struct net2280_dma), 0 /* no alignment requirements */, diff -Nru a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h --- a/drivers/usb/gadget/net2280.h 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/gadget/net2280.h 2004-10-21 14:31:02 -07:00 @@ -495,10 +495,10 @@ * use struct net2280_dma_regs bitfields */ struct net2280_dma { - u32 dmacount; - u32 dmaaddr; /* the buffer */ - u32 dmadesc; /* next dma descriptor */ - u32 _reserved; + __le32 dmacount; + __le32 dmaaddr; /* the buffer */ + __le32 dmadesc; /* next dma descriptor */ + __le32 _reserved; } __attribute__ ((aligned (16))); /*-------------------------------------------------------------------------*/ diff -Nru a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c --- a/drivers/usb/gadget/omap_udc.c 2004-10-21 14:31:01 -07:00 +++ b/drivers/usb/gadget/omap_udc.c 2004-10-21 14:31:01 -07:00 @@ -59,15 +59,14 @@ #undef USB_TRACE -/* OUT-dma seems to be behaving */ +/* bulk DMA seems to be behaving for both IN and OUT */ #define USE_DMA /* ISO too */ #define USE_ISO - #define DRIVER_DESC "OMAP UDC driver" -#define DRIVER_VERSION "24 August 2004" +#define DRIVER_VERSION "4 October 2004" #define DMA_ADDR_INVALID (~(dma_addr_t)0) @@ -104,7 +103,6 @@ module_param (fifo_mode, uint, 0); MODULE_PARM_DESC (fifo_mode, "endpoint setup (0 == default)"); - #ifdef USE_DMA static unsigned use_dma = 1; @@ -224,18 +222,17 @@ list_add(&ep->iso, &udc->iso); /* maybe assign a DMA channel to this endpoint */ - if (use_dma && desc->bmAttributes == USB_ENDPOINT_XFER_BULK - && !(ep->bEndpointAddress & USB_DIR_IN)) - /* FIXME ISO can dma, but prefers first channel. - * IN can dma, but lacks debugging. - */ + if (use_dma && desc->bmAttributes == USB_ENDPOINT_XFER_BULK) + /* FIXME ISO can dma, but prefers first channel */ dma_channel_claim(ep, 0); /* PIO OUT may RX packets */ if (desc->bmAttributes != USB_ENDPOINT_XFER_ISOC && !ep->has_dma - && !(ep->bEndpointAddress & USB_DIR_IN)) + && !(ep->bEndpointAddress & USB_DIR_IN)) { UDC_CTRL_REG = UDC_SET_FIFO_EN; + ep->ackwait = 1 + ep->double_buf; + } spin_unlock_irqrestore(&udc->lock, flags); VDBG("%s enabled\n", _ep->name); @@ -262,6 +259,7 @@ ep->has_dma = 0; UDC_CTRL_REG = UDC_SET_HALT; list_del_init(&ep->iso); + del_timer(&ep->timer); spin_unlock_irqrestore(&ep->udc->lock, flags); @@ -498,17 +496,22 @@ u16 ep_stat = UDC_STAT_FLG_REG; is_last = 0; - if (ep_stat & FIFO_UNREADABLE) + if (ep_stat & FIFO_EMPTY) { + if (!ep->double_buf) + break; + ep->fnf = 1; + } + if (ep_stat & UDC_EP_HALTED) break; - if (ep_stat & (UDC_NON_ISO_FIFO_FULL|UDC_ISO_FIFO_FULL)) + if (ep_stat & FIFO_FULL) avail = ep->ep.maxpacket; - else + else { avail = UDC_RXFSTAT_REG; + ep->fnf = ep->double_buf; + } count = read_packet(buf, req, avail); - // FIXME double buffered PIO OUT wasn't behaving... - /* partial packet reads may not be errors */ if (count < ep->ep.maxpacket) { is_last = 1; @@ -526,26 +529,56 @@ if (!ep->bEndpointAddress) break; - if (!ep->double_buf) { - UDC_CTRL_REG = UDC_SET_FIFO_EN; - if (!is_last) - break; - } - - if (is_last) { + if (is_last) done(ep, req, 0); - if (list_empty(&ep->queue) || !ep->double_buf) - break; - req = container_of(ep->queue.next, - struct omap_req, queue); - is_last = 0; - } + break; } return is_last; } /*-------------------------------------------------------------------------*/ +static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) +{ + dma_addr_t end; + + /* IN-DMA needs this on fault/cancel paths, so 15xx misreports + * the last transfer's bytecount by more than a FIFO's worth. + */ + if (cpu_is_omap15xx()) + return 0; + + end = omap_readw(OMAP_DMA_CSAC(ep->lch)); + if (end == ep->dma_counter) + return 0; + + end |= start & (0xffff << 16); + if (end < start) + end += 0x10000; + return end - start; +} + +#define DMA_DEST_LAST(x) (cpu_is_omap15xx() \ + ? OMAP_DMA_CSAC(x) /* really: CPC */ \ + : OMAP_DMA_CDAC(x)) + +static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start) +{ + dma_addr_t end; + + end = omap_readw(DMA_DEST_LAST(ep->lch)); + if (end == ep->dma_counter) + return 0; + + end |= start & (0xffff << 16); + if (cpu_is_omap15xx()) + end++; + if (end < start) + end += 0x10000; + return end - start; +} + + /* Each USB transfer request using DMA maps to one or more DMA transfers. * When DMA completion isn't request completion, the UDC continues with * the next DMA transfer for that USB transfer. @@ -555,26 +588,29 @@ { u16 txdma_ctrl; unsigned length = req->req.length - req->req.actual; + const int sync_mode = cpu_is_omap15xx() + ? OMAP_DMA_SYNC_FRAME + : OMAP_DMA_SYNC_ELEMENT; /* measure length in either bytes or packets */ - if (length <= (UDC_TXN_TSC + 1)) { + if ((cpu_is_omap16xx() && length <= (UDC_TXN_TSC + 1)) + || (cpu_is_omap15xx() && length < ep->maxpacket)) { txdma_ctrl = UDC_TXN_EOT | length; omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, - length, 1, OMAP_DMA_SYNC_ELEMENT); + length, 1, sync_mode); } else { - length = max(length / ep->maxpacket, + length = min(length / ep->maxpacket, (unsigned) UDC_TXN_TSC + 1); txdma_ctrl = length; omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, - ep->ep.maxpacket, length, - OMAP_DMA_SYNC_ELEMENT); + ep->ep.maxpacket, length, sync_mode); length *= ep->maxpacket; } - omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual); omap_start_dma(ep->lch); + ep->dma_counter = omap_readw(OMAP_DMA_CSAC(ep->lch)); UDC_DMA_IRQ_EN_REG |= UDC_TX_DONE_IE(ep->dma_channel); UDC_TXDMA_REG(ep->dma_channel) = UDC_TXN_START | txdma_ctrl; req->dma_bytes = length; @@ -592,14 +628,9 @@ && req->dma_bytes != 0 && (req->req.actual % ep->maxpacket) == 0) return; - } else { - u32 last; - - // FIXME this surely isn't #bytes transferred - last = (omap_readw(OMAP_DMA_CSSA_U(ep->lch)) << 16) - | omap_readw(OMAP_DMA_CSSA_L(ep->lch)); - req->req.actual = last - req->req.dma; - } + } else + req->req.actual += dma_src_len(ep, req->req.dma + + req->req.actual); /* tx completion */ omap_stop_dma(ep->lch); @@ -624,6 +655,7 @@ OMAP_DMA_SYNC_ELEMENT); omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual); + ep->dma_counter = omap_readw(DMA_DEST_LAST(ep->lch)); UDC_RXDMA_REG(ep->dma_channel) = UDC_RXN_STOP | (packets - 1); UDC_DMA_IRQ_EN_REG |= UDC_RX_EOT_IE(ep->dma_channel); @@ -638,15 +670,13 @@ { u16 count; - /* FIXME must be a better way to see how much dma - * happened, even when it never got going... - */ - count = omap_readw(OMAP_DMA_CDAC(ep->lch)); - count -= 0xffff & (req->req.dma + req->req.actual); + if (status == 0) + ep->dma_counter = (u16) (req->req.dma + req->req.actual); + count = dma_dest_len(ep, req->req.dma + req->req.actual); count += req->req.actual; if (count <= req->req.length) req->req.actual = count; - + if (count != req->dma_bytes || status) omap_stop_dma(ep->lch); @@ -705,7 +735,9 @@ if (irq_src & UDC_RXN_CNT) { ep = &udc->ep[UDC_DMA_RX_SRC(dman_stat)]; - DBG("%s, RX_CNT irq?\n", ep->ep.name); + ep->irqs++; + /* omap15xx does this unasked... */ + VDBG("%s, RX_CNT irq?\n", ep->ep.name); UDC_IRQ_SRC_REG = UDC_RXN_CNT; } } @@ -778,7 +810,8 @@ omap_disable_dma_irq(ep->lch, OMAP_DMA_BLOCK_IRQ); /* channel type P: hw synch (fifo) */ - omap_writew(2, OMAP_DMA_LCH_CTRL(ep->lch)); + if (!cpu_is_omap15xx()) + omap_writew(2, OMAP_DMA_LCH_CTRL(ep->lch)); } just_restart: @@ -803,6 +836,10 @@ use_ep(ep, UDC_EP_SEL); (is_in ? write_fifo : read_fifo)(ep, req); deselect_ep(); + if (!is_in) { + UDC_CTRL_REG = UDC_SET_FIFO_EN; + ep->ackwait = 1 + ep->double_buf; + } /* IN: 6 wait states before it'll tx */ } } @@ -833,24 +870,21 @@ UDC_TXDMA_CFG_REG &= ~mask; if (req) { - if (active) - udelay(50); finish_in_dma(ep, req, -ECONNRESET); - if (UDC_TXDMA_CFG_REG & mask) - WARN("%s, SPIN abort TX dma\n", ep->ep.name); - } - /* host may empty the fifo (or not...) */ + /* clear FIFO; hosts probably won't empty it */ + use_ep(ep, UDC_EP_SEL); + UDC_CTRL_REG = UDC_CLR_EP; + deselect_ep(); + } while (UDC_TXDMA_CFG_REG & mask) udelay(10); - } else { UDC_RXDMA_CFG_REG &= ~mask; /* dma empties the fifo */ - while (active && (UDC_RXDMA_CFG_REG & mask)) + while (UDC_RXDMA_CFG_REG & mask) udelay(10); - omap_stop_dma(ep->lch); if (req) finish_out_dma(ep, req, -ECONNRESET); } @@ -997,6 +1031,10 @@ if ((is_in ? write_fifo : read_fifo)(ep, req) == 1) req = 0; deselect_ep(); + if (!is_in) { + UDC_CTRL_REG = UDC_SET_FIFO_EN; + ep->ackwait = 1 + ep->double_buf; + } /* IN: 6 wait states before it'll tx */ } } @@ -1034,7 +1072,7 @@ if (use_dma && ep->dma_channel && ep->queue.next == &req->queue) { int channel = ep->dma_channel; - /* releasing the dma completion cancels the request, + /* releasing the channel cancels the request, * reclaiming the channel restarts the queue */ dma_channel_release(ep); @@ -1104,8 +1142,10 @@ use_ep(ep, 0); UDC_CTRL_REG = UDC_RESET_EP; ep->ackwait = 0; - if (!(ep->bEndpointAddress & USB_DIR_IN)) + if (!(ep->bEndpointAddress & USB_DIR_IN)) { UDC_CTRL_REG = UDC_SET_FIFO_EN; + ep->ackwait = 1 + ep->double_buf; + } } } done: @@ -1218,7 +1258,7 @@ /* * Called by whatever detects VBUS sessions: external transceiver - * driver, or maybe GPIO0 VBUS IRQ. + * driver, or maybe GPIO0 VBUS IRQ. May request 48 MHz clock. */ static int omap_vbus_session(struct usb_gadget *gadget, int is_active) { @@ -1229,6 +1269,13 @@ spin_lock_irqsave(&udc->lock, flags); VDBG("VBUS %s\n", is_active ? "on" : "off"); udc->vbus_active = (is_active != 0); + if (cpu_is_omap15xx()) { + /* "software" detect, ignored if !VBUS_MODE_1510 */ + if (is_active) + FUNC_MUX_CTRL_0_REG |= VBUS_CTRL_1510; + else + FUNC_MUX_CTRL_0_REG &= ~VBUS_CTRL_1510; + } if (can_pullup(udc)) pullup_enable(udc); else @@ -1342,8 +1389,15 @@ /* Clear any pending requests and then scrub any rx/tx state * before starting to handle the SETUP request. */ - if (irq_src & UDC_SETUP) + if (irq_src & UDC_SETUP) { + u16 ack = irq_src & (UDC_EP0_TX|UDC_EP0_RX); + nuke(ep0, 0); + if (ack) { + UDC_IRQ_SRC_REG = ack; + irq_src = UDC_SETUP; + } + } /* IN/OUT packets mean we're in the DATA or STATUS stage. * This driver uses only uses protocol stalls (ep0 never halts), @@ -1508,8 +1562,10 @@ use_ep(ep, 0); UDC_CTRL_REG = UDC_RESET_EP; ep->ackwait = 0; - if (!(ep->bEndpointAddress & USB_DIR_IN)) + if (!(ep->bEndpointAddress & USB_DIR_IN)) { UDC_CTRL_REG = UDC_SET_FIFO_EN; + ep->ackwait = 1 + ep->double_buf; + } } VDBG("%s halt cleared by host\n", ep->name); goto ep0out_status_stage; @@ -1743,6 +1799,39 @@ return status; } +/* workaround for seemingly-lost IRQs for RX ACKs... */ +#define PIO_OUT_TIMEOUT (jiffies + HZ/3) +#define HALF_FULL(f) (!((f)&(UDC_NON_ISO_FIFO_FULL|UDC_NON_ISO_FIFO_EMPTY))) + +static void pio_out_timer(unsigned long _ep) +{ + struct omap_ep *ep = (void *) _ep; + unsigned long flags; + u16 stat_flg; + + spin_lock_irqsave(&ep->udc->lock, flags); + if (!list_empty(&ep->queue) && ep->ackwait) { + use_ep(ep, 0); + stat_flg = UDC_STAT_FLG_REG; + + if ((stat_flg & UDC_ACK) && (!(stat_flg & UDC_FIFO_EN) + || (ep->double_buf && HALF_FULL(stat_flg)))) { + struct omap_req *req; + + VDBG("%s: lose, %04x\n", ep->ep.name, stat_flg); + req = container_of(ep->queue.next, + struct omap_req, queue); + UDC_EP_NUM_REG = ep->bEndpointAddress | UDC_EP_SEL; + (void) read_fifo(ep, req); + UDC_EP_NUM_REG = ep->bEndpointAddress; + UDC_CTRL_REG = UDC_SET_FIFO_EN; + ep->ackwait = 1 + ep->double_buf; + } + } + mod_timer(&ep->timer, PIO_OUT_TIMEOUT); + spin_unlock_irqrestore(&ep->udc->lock, flags); +} + static irqreturn_t omap_udc_pio_irq(int irq, void *_dev, struct pt_regs *r) { @@ -1766,38 +1855,56 @@ ep = &udc->ep[epnum]; ep->irqs++; - if (!list_empty(&ep->queue)) { - UDC_EP_NUM_REG = epnum | UDC_EP_SEL; - if ((UDC_STAT_FLG_REG & UDC_ACK)) { + UDC_EP_NUM_REG = epnum | UDC_EP_SEL; + ep->fnf = 0; + if ((UDC_STAT_FLG_REG & UDC_ACK)) { + ep->ackwait--; + if (!list_empty(&ep->queue)) { int stat; req = container_of(ep->queue.next, struct omap_req, queue); stat = read_fifo(ep, req); - // FIXME double buffered PIO OUT should work + if (!ep->double_buf) + ep->fnf = 1; } - UDC_EP_NUM_REG = epnum; } + /* min 6 clock delay before clearing EP_SEL ... */ + epn_stat = UDC_EPN_STAT_REG; + epn_stat = UDC_EPN_STAT_REG; + UDC_EP_NUM_REG = epnum; + + /* enabling fifo _after_ clearing ACK, contrary to docs, + * reduces lossage; timer still needed though (sigh). + */ + if (ep->fnf) { + UDC_CTRL_REG = UDC_SET_FIFO_EN; + ep->ackwait = 1 + ep->double_buf; + } + mod_timer(&ep->timer, PIO_OUT_TIMEOUT); } /* then IN transfers */ - if (irq_src & UDC_EPN_TX) { + else if (irq_src & UDC_EPN_TX) { epnum = epn_stat & 0x0f; UDC_IRQ_SRC_REG = UDC_EPN_TX; status = IRQ_HANDLED; ep = &udc->ep[16 + epnum]; ep->irqs++; - ep->ackwait = 0; - if (!list_empty(&ep->queue)) { - UDC_EP_NUM_REG = epnum | UDC_EP_DIR | UDC_EP_SEL; - if ((UDC_STAT_FLG_REG & UDC_ACK)) { + UDC_EP_NUM_REG = epnum | UDC_EP_DIR | UDC_EP_SEL; + if ((UDC_STAT_FLG_REG & UDC_ACK)) { + ep->ackwait = 0; + if (!list_empty(&ep->queue)) { req = container_of(ep->queue.next, struct omap_req, queue); (void) write_fifo(ep, req); } - UDC_EP_NUM_REG = epnum | UDC_EP_DIR; - /* 6 wait states before it'll tx */ } + /* min 6 clock delay before clearing EP_SEL ... */ + epn_stat = UDC_EPN_STAT_REG; + epn_stat = UDC_EPN_STAT_REG; + UDC_EP_NUM_REG = epnum | UDC_EP_DIR; + /* then 6 clocks before it'd tx */ } spin_unlock_irqrestore(&udc->lock, flags); @@ -1939,6 +2046,9 @@ pullup_disable (udc); } + if (machine_is_omap_innovator()) + omap_vbus_session(&udc->gadget, 1); + done: return status; } @@ -1954,6 +2064,9 @@ if (!driver || driver != udc->driver) return -EINVAL; + if (machine_is_omap_innovator()) + omap_vbus_session(&udc->gadget, 0); + if (udc->transceiver) (void) otg_set_peripheral(udc->transceiver, 0); else @@ -2002,8 +2115,16 @@ stat_flg = UDC_STAT_FLG_REG; seq_printf(s, - "\n%s %sirqs %ld stat %04x " EIGHTBITS FOURBITS "%s\n", - ep->name, buf, ep->irqs, stat_flg, + "\n%s %s%s%sirqs %ld stat %04x " EIGHTBITS FOURBITS "%s\n", + ep->name, buf, + ep->double_buf ? "dbuf " : "", + ({char *s; switch(ep->ackwait){ + case 0: s = ""; break; + case 1: s = "(ackw) "; break; + case 2: s = "(ackw2) "; break; + default: s = "(?) "; break; + } s;}), + ep->irqs, stat_flg, (stat_flg & UDC_NO_RXPACKET) ? "no_rxpacket " : "", (stat_flg & UDC_MISS_IN) ? "miss_in " : "", (stat_flg & UDC_DATA_FLUSH) ? "data_flush " : "", @@ -2021,10 +2142,19 @@ if (list_empty (&ep->queue)) seq_printf(s, "\t(queue empty)\n"); else - list_for_each_entry (req, &ep->queue, queue) + list_for_each_entry (req, &ep->queue, queue) { + unsigned length = req->req.actual; + + if (use_dma && buf[0]) { + length += ((ep->bEndpointAddress & USB_DIR_IN) + ? dma_src_len : dma_dest_len) + (ep, req->req.dma + length); + buf[0] = 0; + } seq_printf(s, "\treq %p len %d/%d buf %p\n", - &req->req, req->req.actual, + &req->req, length, req->req.length, req->req.buf); + } } static char *trx_mode(unsigned m) @@ -2125,7 +2255,11 @@ fifo_mode, udc->driver ? udc->driver->driver.name : "(none)", HMC, - udc->transceiver ? udc->transceiver->label : ""); + udc->transceiver ? udc->transceiver->label : "(none)"); + seq_printf(s, "ULPD control %04x req %04x status %04x\n", + __REG16(ULPD_CLOCK_CTRL), + __REG16(ULPD_SOFT_REQ), + __REG16(ULPD_STATUS_REQ)); /* OTG controller registers */ if (!cpu_is_omap15xx()) @@ -2305,10 +2439,10 @@ epn_rxtx |= UDC_EPN_RX_ISO; dbuf = 1; } else { - /* pio-out could potentially double-buffer, - * as can (should!) DMA-IN + /* double-buffering "not supported" on 15xx, + * and ignored for PIO-IN on 16xx */ - if (!use_dma || (addr & USB_DIR_IN)) + if (!use_dma || cpu_is_omap15xx()) dbuf = 0; switch (maxp) { @@ -2320,6 +2454,9 @@ } if (dbuf && addr) epn_rxtx |= UDC_EPN_RX_DB; + init_timer(&ep->timer); + ep->timer.function = pio_out_timer; + ep->timer.data = (unsigned long) ep; } if (addr) epn_rxtx |= UDC_EPN_RX_VALID; @@ -2509,23 +2646,35 @@ return -EBUSY; } - INFO("OMAP UDC rev %d.%d, %s receptacle\n", + INFO("OMAP UDC rev %d.%d%s\n", UDC_REV_REG >> 4, UDC_REV_REG & 0xf, - config->otg ? "Mini-AB" : "B/Mini-B"); + config->otg ? ", Mini-AB" : ""); /* use the mode given to us by board init code */ if (cpu_is_omap15xx()) { hmc = HMC_1510; type = "(unknown)"; - /* FIXME may need a GPIO-0 handler to call - * usb_gadget_vbus_{dis,}connect() on us... - */ + if (machine_is_omap_innovator()) { + /* just set up software VBUS detect, and then + * later rig it so we always report VBUS. + * FIXME without really sensing VBUS, we can't + * know when to turn PULLUP_EN on/off; and that + * means we always "need" the 48MHz clock. + */ + u32 tmp = FUNC_MUX_CTRL_0_REG; + + FUNC_MUX_CTRL_0_REG &= ~VBUS_CTRL_1510; + tmp |= VBUS_MODE_1510; + tmp &= ~VBUS_CTRL_1510; + FUNC_MUX_CTRL_0_REG = tmp; + } } else { hmc = HMC_1610; switch (hmc) { case 3: case 11: + case 16: case 19: case 25: xceiv = otg_get_transceiver(); @@ -2565,7 +2714,9 @@ xceiv = 0; // "udc" is now valid pullup_disable(udc); +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) udc->gadget.is_otg = (config->otg != 0); +#endif /* USB general purpose IRQ: ep0, state changes, dma, etc */ status = request_irq(odev->resource[1].start, omap_udc_irq, @@ -2694,7 +2845,11 @@ static int __init udc_init(void) { - INFO("%s, version: " DRIVER_VERSION "%s\n", driver_desc, + INFO("%s, version: " DRIVER_VERSION +#ifdef USE_ISO + " (iso)" +#endif + "%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-10-21 14:31:01 -07:00 +++ b/drivers/usb/gadget/omap_udc.h 2004-10-21 14:31:01 -07:00 @@ -146,11 +146,14 @@ u8 bmAttributes; unsigned double_buf:1; unsigned stopped:1; - unsigned ackwait:1; + unsigned fnf:1; unsigned has_dma:1; + u8 ackwait; u8 dma_channel; + u16 dma_counter; int lch; struct omap_udc *udc; + struct timer_list timer; }; struct omap_udc { @@ -168,7 +171,6 @@ unsigned ep0_set_config:1; unsigned ep0_reset_config:1; unsigned ep0_setup:1; - unsigned hmc:6; struct completion *done; }; diff -Nru a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c --- a/drivers/usb/gadget/zero.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/gadget/zero.c 2004-10-21 14:31:02 -07:00 @@ -1189,7 +1189,7 @@ } 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); + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210); } 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/Kconfig b/drivers/usb/host/Kconfig --- a/drivers/usb/host/Kconfig 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/host/Kconfig 2004-10-21 14:31:02 -07:00 @@ -1,3 +1,21 @@ +# Host-side USB depends on having a host controller +# NOTE: dummy_hcd is always an option, but it's ignored here ... +# NOTE: SL-811 option should be board-specific ... +config USB_ARCH_HAS_HCD + boolean + default y if USB_ARCH_HAS_OHCI + default y if ARM # SL-811 + default PCI + +# many non-PCI hcds implement OHCI +config USB_ARCH_HAS_OHCI + boolean + default y if SA1111 + default y if ARCH_OMAP + default y if ARCH_LH7A404 + default y if PXA27x + default PCI + # # USB Host Controller Drivers # @@ -6,7 +24,7 @@ config USB_EHCI_HCD tristate "EHCI HCD (USB 2.0) support" - depends on USB + depends on USB && PCI ---help--- The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0 "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware. @@ -51,8 +69,8 @@ config USB_OHCI_HCD tristate "OHCI HCD support" - depends on USB - select ISP1301_OMAP if MACH_OMAP_H2 + depends on USB && USB_ARCH_HAS_OHCI + select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 ---help--- The Open Host Controller Interface (OHCI) is a standard for accessing USB 1.1 host controller hardware. It does more in hardware than Intel's @@ -68,7 +86,7 @@ config USB_UHCI_HCD tristate "UHCI HCD (most Intel and VIA) support" - depends on USB + depends on USB && PCI ---help--- The Universal Host Controller Interface is a standard by Intel for accessing the USB hardware in the PC (which is also called the USB diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c --- a/drivers/usb/host/ohci-hcd.c 2004-10-21 14:31:01 -07:00 +++ b/drivers/usb/host/ohci-hcd.c 2004-10-21 14:31:01 -07:00 @@ -154,6 +154,11 @@ module_param (power_switching, bool, 0); MODULE_PARM_DESC (power_switching, "true (not default) to switch port power"); +/* Some boards leave IR set wrongly, since they fail BIOS/SMM handshakes */ +static int no_handshake = 0; +module_param (no_handshake, bool, 0); +MODULE_PARM_DESC (no_handshake, "true (not default) disables BIOS handshake"); + /*-------------------------------------------------------------------------*/ /* @@ -426,7 +431,7 @@ #ifndef IR_DISABLE /* SMM owns the HC? not for long! */ - if (ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) { + if (!no_handshake && ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) { ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n"); /* this timeout is arbitrary. we make it long, so systems diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c --- a/drivers/usb/host/uhci-hcd.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/host/uhci-hcd.c 2004-10-21 14:31:02 -07:00 @@ -765,8 +765,12 @@ uhci_insert_tds_in_qh(qh, urb, UHCI_PTR_BREADTH); - /* Low-speed transfers get a different queue, and won't hog the bus */ - if (urb->dev->speed == USB_SPEED_LOW) + /* Low-speed transfers get a different queue, and won't hog the bus. + * Also, some devices enumerate better without FSBR; the easiest way + * to do that is to put URBs on the low-speed queue while the device + * is in the DEFAULT state. */ + if (urb->dev->speed == USB_SPEED_LOW || + urb->dev->state == USB_STATE_DEFAULT) skelqh = uhci->skel_ls_control_qh; else { skelqh = uhci->skel_fs_control_qh; diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c --- a/drivers/usb/input/hid-core.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/input/hid-core.c 2004-10-21 14:31:02 -07:00 @@ -925,6 +925,7 @@ case -ECONNRESET: /* unlink */ case -ENOENT: case -ESHUTDOWN: + case -EPERM: return; case -ETIMEDOUT: /* NAK */ break; @@ -1833,6 +1834,30 @@ return 0; } +static int hid_suspend(struct usb_interface *intf, u32 state) +{ + struct hid_device *hid = usb_get_intfdata (intf); + + usb_kill_urb(hid->urbin); + intf->dev.power.power_state = state; + dev_dbg(&intf->dev, "suspend\n"); + return 0; +} + +static int hid_resume(struct usb_interface *intf) +{ + struct hid_device *hid = usb_get_intfdata (intf); + int status; + + intf->dev.power.power_state = PM_SUSPEND_ON; + if (hid->open) + status = usb_submit_urb(hid->urbin, GFP_NOIO); + else + status = 0; + dev_dbg(&intf->dev, "resume status %d\n", status); + return status; +} + static struct usb_device_id hid_usb_ids [] = { { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, .bInterfaceClass = USB_INTERFACE_CLASS_HID }, @@ -1846,6 +1871,8 @@ .name = "usbhid", .probe = hid_probe, .disconnect = hid_disconnect, + .suspend = hid_suspend, + .resume = hid_resume, .id_table = hid_usb_ids, }; diff -Nru a/drivers/usb/media/w9968cf.h b/drivers/usb/media/w9968cf.h --- a/drivers/usb/media/w9968cf.h 2004-10-21 14:31:01 -07:00 +++ b/drivers/usb/media/w9968cf.h 2004-10-21 14:31:01 -07:00 @@ -135,7 +135,7 @@ #define W9968CF_MODULE_NAME "V4L driver for W996[87]CF JPEG USB " \ "Dual Mode Camera Chip" -#define W9968CF_MODULE_VERSION "1:1.32-basic" +#define W9968CF_MODULE_VERSION "1:1.33-basic" #define W9968CF_MODULE_AUTHOR "(C) 2002-2004 Luca Risolia" #define W9968CF_AUTHOR_EMAIL "" #define W9968CF_MODULE_LICENSE "GPL" diff -Nru a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig --- a/drivers/usb/misc/Kconfig 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/misc/Kconfig 2004-10-21 14:31:02 -07:00 @@ -121,6 +121,16 @@ To compile this driver as a module, choose M here: the module will be called cytherm. +config USB_PHIDGETKIT + tristate "USB PhidgetKit support" + depends on USB + help + Say Y here if you want to connect a PhidgetKit USB device from + Phidgets Inc. + + To compile this driver as a module, choose M here: the + module will be called phidgetkit. + config USB_PHIDGETSERVO tristate "USB PhidgetServo support" depends on USB diff -Nru a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile --- a/drivers/usb/misc/Makefile 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/misc/Makefile 2004-10-21 14:31:02 -07:00 @@ -10,8 +10,9 @@ obj-$(CONFIG_USB_LCD) += usblcd.o obj-$(CONFIG_USB_LED) += usbled.o obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o +obj-$(CONFIG_USB_PHIDGETKIT) += phidgetkit.o +obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o obj-$(CONFIG_USB_RIO500) += rio500.o obj-$(CONFIG_USB_TEST) += usbtest.o obj-$(CONFIG_USB_TIGL) += tiglusb.o obj-$(CONFIG_USB_USS720) += uss720.o -obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o diff -Nru a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/usb/misc/phidgetkit.c 2004-10-21 14:31:02 -07:00 @@ -0,0 +1,581 @@ +/* + * USB PhidgetInterfaceKit driver 1.0 + * + * Copyright (C) 2004 Sean Young + * Copyright (C) 2004 Greg Kroah-Hartman + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This is a driver for the USB PhidgetInterfaceKit. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_AUTHOR "Sean Young " +#define DRIVER_DESC "USB PhidgetInterfaceKit Driver" + +#define USB_VENDOR_ID_GLAB 0x06c2 +#define USB_DEVICE_ID_INTERFACEKIT004 0x0040 +#define USB_DEVICE_ID_INTERFACEKIT888 0x0045 +#define USB_DEVICE_ID_INTERFACEKIT047 0x0051 +#define USB_DEVICE_ID_INTERFACEKIT088 0x0053 + +#define USB_VENDOR_ID_WISEGROUP 0x0925 +#define USB_DEVICE_ID_INTERFACEKIT884 0x8201 + +#define MAX_INTERFACES 8 + +struct driver_interfacekit { + int sensors; + int inputs; + int outputs; + int has_lcd; +}; +#define ifkit(_sensors, _inputs, _outputs, _lcd) \ +static struct driver_interfacekit ph_##_sensors##_inputs##_outputs = { \ + .sensors = _sensors, \ + .inputs = _inputs, \ + .outputs = _outputs, \ + .has_lcd = _lcd, \ +}; +ifkit(0, 0, 4, 0); +ifkit(8, 8, 8, 0); +ifkit(0, 4, 7, 1); +ifkit(8, 8, 4, 0); +ifkit(0, 8, 8, 1); + +struct phidget_interfacekit { + struct usb_device *udev; + struct usb_interface *intf; + struct driver_interfacekit *ifkit; + int outputs[MAX_INTERFACES]; + int inputs[MAX_INTERFACES]; + int sensors[MAX_INTERFACES]; + u8 lcd_files_on; + + struct urb *irq; + unsigned char *data; + dma_addr_t data_dma; +}; + +static struct usb_device_id id_table[] = { + {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT004), + .driver_info = (kernel_ulong_t)&ph_004}, + {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888), + .driver_info = (kernel_ulong_t)&ph_888}, + {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT047), + .driver_info = (kernel_ulong_t)&ph_047}, + {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088), + .driver_info = (kernel_ulong_t)&ph_088}, + {USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_INTERFACEKIT884), + .driver_info = (kernel_ulong_t)&ph_884}, + {} +}; +MODULE_DEVICE_TABLE(usb, id_table); + +static int change_outputs(struct phidget_interfacekit *kit, int output_num, int enable) +{ + unsigned char *buffer; + int retval; + int n; + + buffer = kmalloc(4, GFP_KERNEL); + if (!buffer) { + dev_err(&kit->udev->dev, "%s - out of memory\n", + __FUNCTION__); + return -ENOMEM; + } + + kit->outputs[output_num] = enable; + memset(buffer, 0, 4); + for (n=0; n<8; n++) { + if (kit->outputs[n]) { + buffer[0] |= 1 << n; + } + } + + dev_dbg(&kit->udev->dev, "data: %02x %02x\n", buffer[0], buffer[1]); + + retval = usb_control_msg(kit->udev, + usb_sndctrlpipe(kit->udev, 0), + 0x09, 0x21, 0x0200, 0x0000, buffer, 4, 2 * HZ); + + if (retval != 4) + dev_err(&kit->udev->dev, "retval = %d\n", retval); + kfree(buffer); + + return retval < 0 ? retval : 0; +} + +static int change_string(struct phidget_interfacekit *kit, const char *display, unsigned char row) +{ + unsigned char *buffer; + unsigned char *form_buffer; + int retval = -ENOMEM; + int i,j, len, buf_ptr; + + buffer = kmalloc(8, GFP_KERNEL); + form_buffer = kmalloc(30, GFP_KERNEL); + if ((!buffer) || (!form_buffer)) { + dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__); + goto exit; + } + + len = strlen(display); + if (len > 20) + len = 20; + + dev_dbg(&kit->udev->dev, "Setting LCD line %d to %s\n", row, display); + + form_buffer[0] = row * 0x40 + 0x80; + form_buffer[1] = 0x02; + buf_ptr = 2; + for (i = 0; i 7) + len = 7; + else + len = (buf_ptr - i); + for (j = 0; j < len; j++) + buffer[j] = form_buffer[i + j]; + buffer[7] = len; + + retval = usb_control_msg(kit->udev, + usb_sndctrlpipe(kit->udev, 0), + 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2 * HZ); + if (retval < 0) + goto exit; + } + + retval = 0; +exit: + kfree(buffer); + kfree(form_buffer); + + return retval; +} + +#define set_lcd_line(number) \ +static ssize_t lcd_line_##number(struct device *dev, const char *buf, size_t count) \ +{ \ + struct usb_interface *intf = to_usb_interface(dev); \ + struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ + change_string(kit, buf, number - 1); \ + return count; \ +} \ +static DEVICE_ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number); +set_lcd_line(1); +set_lcd_line(2); + +static ssize_t set_backlight(struct device *dev, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct phidget_interfacekit *kit = usb_get_intfdata(intf); + int enabled; + unsigned char *buffer; + int retval = -ENOMEM; + + buffer = kmalloc(8, GFP_KERNEL); + if (!buffer) { + dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__); + goto exit; + } + + if (sscanf(buf, "%d", &enabled) < 1) { + retval = -EINVAL; + goto exit; + } + memset(buffer, 0x00, 8); + if (enabled) + buffer[0] = 0x01; + buffer[7] = 0x11; + + dev_dbg(&kit->udev->dev, "Setting backlight to %s\n", enabled ? "on" : "off"); + + retval = usb_control_msg(kit->udev, + usb_sndctrlpipe(kit->udev, 0), + 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2 * HZ); + if (retval < 0) + goto exit; + + retval = count; +exit: + kfree(buffer); + return retval; +} +static DEVICE_ATTR(backlight, S_IWUGO, NULL, set_backlight); + +static void remove_lcd_files(struct phidget_interfacekit *kit) +{ + if (kit->lcd_files_on) { + dev_dbg(&kit->udev->dev, "Removing lcd files\n"); + device_remove_file(&kit->intf->dev, &dev_attr_lcd_line_1); + device_remove_file(&kit->intf->dev, &dev_attr_lcd_line_2); + device_remove_file(&kit->intf->dev, &dev_attr_backlight); + } +} + +static ssize_t enable_lcd_files(struct device *dev, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct phidget_interfacekit *kit = usb_get_intfdata(intf); + int enable; + + if (kit->ifkit->has_lcd == 0) + return -ENODEV; + + if (sscanf(buf, "%d", &enable) < 1) + return -EINVAL; + + if (enable) { + if (!kit->lcd_files_on) { + dev_dbg(&kit->udev->dev, "Adding lcd files\n"); + device_create_file(&kit->intf->dev, &dev_attr_lcd_line_1); + device_create_file(&kit->intf->dev, &dev_attr_lcd_line_2); + device_create_file(&kit->intf->dev, &dev_attr_backlight); + kit->lcd_files_on = 1; + } + } else { + if (kit->lcd_files_on) { + remove_lcd_files(kit); + kit->lcd_files_on = 0; + } + } + + return count; +} +static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files); + +static void interfacekit_irq(struct urb *urb, struct pt_regs *regs) +{ + struct phidget_interfacekit *kit = urb->context; + unsigned char *buffer = kit->data; + int status; + int n; + + switch (urb->status) { + case 0: /* success */ + break; + case -ECONNRESET: /* unlink */ + case -ENOENT: + case -ESHUTDOWN: + return; + /* -EPIPE: should clear the halt */ + default: /* error */ + goto resubmit; + } + + for (n=0; n<8; n++) { + kit->inputs[n] = buffer[1] & (1 << n) ? 1 : 0; + } + + if (buffer[0] & 1) { + kit->sensors[4] = buffer[2] + (buffer[3] & 0x0f) * 256; + kit->sensors[5] = buffer[4] + (buffer[3] & 0xf0) * 16; + kit->sensors[6] = buffer[5] + (buffer[6] & 0x0f) * 256; + kit->sensors[7] = buffer[7] + (buffer[6] & 0xf0) * 16; + } else { + kit->sensors[0] = buffer[2] + (buffer[3] & 0x0f) * 256; + kit->sensors[1] = buffer[4] + (buffer[3] & 0xf0) * 16; + kit->sensors[2] = buffer[5] + (buffer[6] & 0x0f) * 256; + kit->sensors[3] = buffer[7] + (buffer[6] & 0xf0) * 16; + } + +resubmit: + status = usb_submit_urb(urb, SLAB_ATOMIC); + if (status) + err("can't resubmit intr, %s-%s/interfacekit0, status %d", + kit->udev->bus->bus_name, + kit->udev->devpath, status); +} + +#define show_set_output(value) \ +static ssize_t set_output##value(struct device *dev, const char *buf, \ + size_t count) \ +{ \ + struct usb_interface *intf = to_usb_interface(dev); \ + struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ + int enabled; \ + int retval; \ + \ + if (sscanf(buf, "%d", &enabled) < 1) { \ + return -EINVAL; \ + } \ + \ + retval = change_outputs(kit, value - 1, enabled ? 1 : 0); \ + \ + return retval ? retval : count; \ +} \ + \ +static ssize_t show_output##value(struct device *dev, char *buf) \ +{ \ + struct usb_interface *intf = to_usb_interface(dev); \ + struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ + \ + return sprintf(buf, "%d\n", kit->outputs[value - 1 ]); \ +} \ +static DEVICE_ATTR(output##value, S_IWUGO | S_IRUGO, \ + show_output##value, set_output##value); +show_set_output(1); +show_set_output(2); +show_set_output(3); +show_set_output(4); +show_set_output(5); +show_set_output(6); +show_set_output(7); +show_set_output(8); /* should be MAX_INTERFACES - 1 */ + +#define show_input(value) \ +static ssize_t show_input##value(struct device *dev, char *buf) \ +{ \ + struct usb_interface *intf = to_usb_interface(dev); \ + struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ + \ + return sprintf(buf, "%d\n", kit->inputs[value - 1]); \ +} \ +static DEVICE_ATTR(input##value, S_IRUGO, show_input##value, NULL); + +show_input(1); +show_input(2); +show_input(3); +show_input(4); +show_input(5); +show_input(6); +show_input(7); +show_input(8); /* should be MAX_INTERFACES - 1 */ + +#define show_sensor(value) \ +static ssize_t show_sensor##value(struct device *dev, char *buf) \ +{ \ + struct usb_interface *intf = to_usb_interface(dev); \ + struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ + \ + return sprintf(buf, "%d\n", kit->sensors[value - 1]); \ +} \ +static DEVICE_ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL); + +show_sensor(1); +show_sensor(2); +show_sensor(3); +show_sensor(4); +show_sensor(5); +show_sensor(6); +show_sensor(7); +show_sensor(8); /* should be MAX_INTERFACES - 1 */ + +static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_host_interface *interface; + struct usb_endpoint_descriptor *endpoint; + struct phidget_interfacekit *kit; + struct driver_interfacekit *ifkit; + int pipe, maxp; + + ifkit = (struct driver_interfacekit *)id->driver_info; + if (!ifkit) + return -ENODEV; + + interface = intf->cur_altsetting; + if (interface->desc.bNumEndpoints != 1) + return -ENODEV; + + endpoint = &interface->endpoint[0].desc; + if (!(endpoint->bEndpointAddress & 0x80)) + return -ENODEV; + /* + * bmAttributes + */ + pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + + kit = kmalloc(sizeof(*kit), GFP_KERNEL); + if (kit == NULL) { + dev_err(&intf->dev, "%s - out of memory\n", __FUNCTION__); + return -ENOMEM; + } + memset(kit, 0, sizeof(*kit)); + kit->ifkit = ifkit; + + kit->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kit->data_dma); + if (!kit->data) { + kfree(kit); + return -ENOMEM; + } + + kit->irq = usb_alloc_urb(0, GFP_KERNEL); + if (!kit->irq) { + usb_buffer_free(dev, 8, kit->data, kit->data_dma); + kfree(kit); + return -ENOMEM; + } + + kit->udev = usb_get_dev(dev); + kit->intf = intf; + usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data, + (maxp > 8 ? 8 : maxp), + interfacekit_irq, kit, endpoint->bInterval); + kit->irq->transfer_dma = kit->data_dma; + kit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + usb_set_intfdata(intf, kit); + + if (usb_submit_urb(kit->irq, GFP_KERNEL)) { + return -EIO; + } + + if (ifkit->outputs == 8) { + device_create_file(&intf->dev, &dev_attr_output1); + device_create_file(&intf->dev, &dev_attr_output2); + device_create_file(&intf->dev, &dev_attr_output3); + device_create_file(&intf->dev, &dev_attr_output4); + device_create_file(&intf->dev, &dev_attr_output5); + device_create_file(&intf->dev, &dev_attr_output6); + device_create_file(&intf->dev, &dev_attr_output7); + device_create_file(&intf->dev, &dev_attr_output8); + } + + if (ifkit->inputs >= 4) { + device_create_file(&intf->dev, &dev_attr_input1); + device_create_file(&intf->dev, &dev_attr_input2); + device_create_file(&intf->dev, &dev_attr_input3); + device_create_file(&intf->dev, &dev_attr_input4); + } + if (ifkit->inputs == 8) { + device_create_file(&intf->dev, &dev_attr_input5); + device_create_file(&intf->dev, &dev_attr_input6); + device_create_file(&intf->dev, &dev_attr_input7); + device_create_file(&intf->dev, &dev_attr_input8); + } + + if (ifkit->sensors >= 4) { + device_create_file(&intf->dev, &dev_attr_sensor1); + device_create_file(&intf->dev, &dev_attr_sensor2); + device_create_file(&intf->dev, &dev_attr_sensor3); + device_create_file(&intf->dev, &dev_attr_sensor4); + } + if (ifkit->sensors >= 7) { + device_create_file(&intf->dev, &dev_attr_sensor5); + device_create_file(&intf->dev, &dev_attr_sensor6); + device_create_file(&intf->dev, &dev_attr_sensor7); + } + if (ifkit->sensors == 8) { + device_create_file(&intf->dev, &dev_attr_sensor8); + } + + if (ifkit->has_lcd) + device_create_file(&intf->dev, &dev_attr_lcd); + + dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n", + ifkit->inputs, ifkit->outputs, ifkit->sensors); + + return 0; +} + +static void interfacekit_disconnect(struct usb_interface *interface) +{ + struct phidget_interfacekit *kit; + + kit = usb_get_intfdata(interface); + usb_set_intfdata(interface, NULL); + if (!kit) + return; + + if (kit->ifkit->outputs == MAX_INTERFACES) { + device_remove_file(&interface->dev, &dev_attr_output1); + device_remove_file(&interface->dev, &dev_attr_output2); + device_remove_file(&interface->dev, &dev_attr_output3); + device_remove_file(&interface->dev, &dev_attr_output4); + device_remove_file(&interface->dev, &dev_attr_output5); + device_remove_file(&interface->dev, &dev_attr_output6); + device_remove_file(&interface->dev, &dev_attr_output7); + device_remove_file(&interface->dev, &dev_attr_output7); + } + + if (kit->ifkit->inputs >= 4) { + device_remove_file(&interface->dev, &dev_attr_input1); + device_remove_file(&interface->dev, &dev_attr_input2); + device_remove_file(&interface->dev, &dev_attr_input3); + device_remove_file(&interface->dev, &dev_attr_input4); + } + if (kit->ifkit->inputs == 8) { + device_remove_file(&interface->dev, &dev_attr_input5); + device_remove_file(&interface->dev, &dev_attr_input6); + device_remove_file(&interface->dev, &dev_attr_input7); + device_remove_file(&interface->dev, &dev_attr_input8); + } + + if (kit->ifkit->sensors >= 4) { + device_remove_file(&interface->dev, &dev_attr_sensor1); + device_remove_file(&interface->dev, &dev_attr_sensor2); + device_remove_file(&interface->dev, &dev_attr_sensor3); + device_remove_file(&interface->dev, &dev_attr_sensor4); + } + if (kit->ifkit->sensors >= 7) { + device_remove_file(&interface->dev, &dev_attr_sensor5); + device_remove_file(&interface->dev, &dev_attr_sensor6); + device_remove_file(&interface->dev, &dev_attr_sensor7); + } + if (kit->ifkit->sensors == 8) { + device_remove_file(&interface->dev, &dev_attr_sensor8); + } + if (kit->ifkit->has_lcd) + device_create_file(&interface->dev, &dev_attr_lcd); + + dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n", + kit->ifkit->inputs, kit->ifkit->outputs, kit->ifkit->sensors); + + usb_kill_urb(kit->irq); + usb_free_urb(kit->irq); + usb_buffer_free(kit->udev, 8, kit->data, kit->data_dma); + + usb_put_dev(kit->udev); + kfree(kit); +} + +static struct usb_driver interfacekit_driver = { + .owner = THIS_MODULE, + .name = "phidgetkit", + .probe = interfacekit_probe, + .disconnect = interfacekit_disconnect, + .id_table = id_table +}; + +static int __init interfacekit_init(void) +{ + int retval = 0; + + retval = usb_register(&interfacekit_driver); + if (retval) + err("usb_register failed. Error number %d", retval); + + return retval; +} + +static void __exit interfacekit_exit(void) +{ + usb_deregister(&interfacekit_driver); +} + +module_init(interfacekit_init); +module_exit(interfacekit_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); diff -Nru a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c --- a/drivers/usb/misc/tiglusb.c 2004-10-21 14:31:01 -07:00 +++ b/drivers/usb/misc/tiglusb.c 2004-10-21 14:31:01 -07:00 @@ -4,7 +4,7 @@ * Target: Texas Instruments graphing calculators (http://lpg.ticalc.org). * * Copyright (C) 2001-2004: - * Romain Lievin + * Romain Lievin * Julien BLACHE * under the terms of the GNU General Public License. * @@ -14,7 +14,7 @@ * and the website at: http://lpg.ticalc.org/prj_usb/ * for more info. * - * History : + * History: * 1.0x, Romain & Julien: initial submit. * 1.03, Greg Kroah: modifications. * 1.04, Julien: clean-up & fixes; Romain: 2.4 backport. @@ -22,6 +22,7 @@ * 1.06, Romain: synched with 2.5, version/firmware changed (confusing). * 1.07, Romain: fixed bad use of usb_clear_halt (invalid argument); * timeout argument checked in ioctl + clean-up. + * 1.08, Romain: added support of USB port embedded on some TI's handhelds. */ #include @@ -41,7 +42,7 @@ /* * Version Information */ -#define DRIVER_VERSION "1.07" +#define DRIVER_VERSION "1.08" #define DRIVER_AUTHOR "Romain Lievin & Julien Blache " #define DRIVER_DESC "TI-GRAPH LINK USB (aka SilverLink) driver" #define DRIVER_LICENSE "GPL" @@ -178,11 +179,11 @@ if (!s->dev) return -EIO; - buffer = kmalloc(BULK_RCV_MAX, GFP_KERNEL); + buffer = kmalloc (s->max_ps, GFP_KERNEL); if (!buffer) return -ENOMEM; - bytes_to_read = (count >= BULK_RCV_MAX) ? BULK_RCV_MAX : count; + bytes_to_read = (count >= s->max_ps) ? s->max_ps : count; pipe = usb_rcvbulkpipe (s->dev, 1); result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_read, @@ -235,11 +236,11 @@ if (!s->dev) return -EIO; - buffer = kmalloc(BULK_SND_MAX, GFP_KERNEL); + buffer = kmalloc (s->max_ps, GFP_KERNEL); if (!buffer) return -ENOMEM; - bytes_to_write = (count >= BULK_SND_MAX) ? BULK_SND_MAX : count; + bytes_to_write = (count >= s->max_ps) ? s->max_ps : count; if (copy_from_user (buffer, buf, bytes_to_write)) { ret = -EFAULT; goto out; @@ -309,6 +310,15 @@ if (clear_pipes (s->dev)) ret = -EIO; break; + case IOCTL_TIUSB_GET_MAXPS: + if (copy_to_user((int *) arg, &s->max_ps, sizeof(int))) + return -EFAULT; + break; + case IOCTL_TIUSB_GET_DEVID: + if (copy_to_user((int *) arg, &s->dev->descriptor.idProduct, + sizeof(int))) + return -EFAULT; + break; default: ret = -ENOTTY; break; @@ -341,6 +351,9 @@ int minor = -1; int i, err = 0; ptiglusb_t s; + struct usb_host_config *conf; + struct usb_host_interface *ifdata = NULL; + int max_ps; dbg ("probing vendor id 0x%x, device id 0x%x", dev->descriptor.idVendor, dev->descriptor.idProduct); @@ -355,19 +368,31 @@ goto out; } - if ((dev->descriptor.idProduct != 0xe001) - && (dev->descriptor.idVendor != 0x451)) { + if (dev->descriptor.idVendor != 0x451) { err = -ENODEV; goto out; } - // NOTE: it's already in this config, this shouldn't be needed. - // is this working around some hardware bug? - if (usb_reset_configuration (dev) < 0) { - err ("tiglusb_probe: reset_configuration failed"); - err = -ENODEV; - goto out; - } + if ((dev->descriptor.idProduct != 0xe001) && + (dev->descriptor.idProduct != 0xe004) && + (dev->descriptor.idProduct != 0xe008)) { + err = -ENODEV; + goto out; + } + + /* + * TI introduced some new handhelds with embedded USB port. + * Port advertises same config as SilverLink cable but with a + * different maximum packet size (64 rather than 32). + */ + + conf = dev->actconfig; + ifdata = conf->interface[0]->cur_altsetting; + max_ps = ifdata->endpoint[0].desc.wMaxPacketSize; + + info("max packet size of %d/%d bytes\n", + ifdata->endpoint[0].desc.wMaxPacketSize, + ifdata->endpoint[1].desc.wMaxPacketSize); /* * Find a tiglusb struct @@ -390,6 +415,7 @@ down (&s->mutex); s->remove_pending = 0; s->dev = dev; + s->max_ps = max_ps; up (&s->mutex); dbg ("bound to interface"); diff -Nru a/drivers/usb/misc/tiglusb.h b/drivers/usb/misc/tiglusb.h --- a/drivers/usb/misc/tiglusb.h 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/misc/tiglusb.h 2004-10-21 14:31:02 -07:00 @@ -18,12 +18,6 @@ #define MAXTIGL 16 /* - * Max. packetsize for IN and OUT pipes - */ -#define BULK_RCV_MAX 32 -#define BULK_SND_MAX 32 - -/* * The driver context... */ @@ -42,6 +36,8 @@ driver_state_t state; /* started/stopped */ int opened; /* tru if open */ int remove_pending; + + int max_ps; /* max packet size */ } tiglusb_t, *ptiglusb_t; #endif diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c --- a/drivers/usb/net/kaweth.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/net/kaweth.c 2004-10-21 14:31:02 -07:00 @@ -651,7 +651,7 @@ ****************************************************************/ static int kaweth_open(struct net_device *net) { - struct kaweth_device *kaweth = (struct kaweth_device *)net->priv; + struct kaweth_device *kaweth = netdev_priv(net); int res; kaweth_dbg("Opening network device."); @@ -689,7 +689,7 @@ ****************************************************************/ static int kaweth_close(struct net_device *net) { - struct kaweth_device *kaweth = net->priv; + struct kaweth_device *kaweth = netdev_priv(net); netif_stop_queue(net); @@ -740,7 +740,7 @@ ****************************************************************/ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) { - struct kaweth_device *kaweth = net->priv; + struct kaweth_device *kaweth = netdev_priv(net); __le16 *private_header; int res; @@ -811,7 +811,7 @@ ****************************************************************/ static void kaweth_set_rx_mode(struct net_device *net) { - struct kaweth_device *kaweth = net->priv; + struct kaweth_device *kaweth = netdev_priv(net); __u16 packet_filter_bitmap = KAWETH_PACKET_FILTER_DIRECTED | KAWETH_PACKET_FILTER_BROADCAST | @@ -868,7 +868,8 @@ ****************************************************************/ static struct net_device_stats *kaweth_netdev_stats(struct net_device *dev) { - return &((struct kaweth_device *)dev->priv)->stats; + struct kaweth_device *kaweth = netdev_priv(dev); + return &kaweth->stats; } /**************************************************************** @@ -876,7 +877,7 @@ ****************************************************************/ static void kaweth_tx_timeout(struct net_device *net) { - struct kaweth_device *kaweth = net->priv; + struct kaweth_device *kaweth = netdev_priv(net); kaweth_warn("%s: Tx timed out. Resetting.", net->name); kaweth->stats.tx_errors++; @@ -911,12 +912,14 @@ (int)dev->descriptor.bLength, (int)dev->descriptor.bDescriptorType); - if(!(kaweth = kmalloc(sizeof(struct kaweth_device), GFP_KERNEL))) + netdev = alloc_etherdev(sizeof(*kaweth)); + if (!netdev) return -ENOMEM; - memset(kaweth, 0, sizeof(struct kaweth_device)); - + kaweth = netdev_priv(netdev); kaweth->dev = dev; + kaweth->net = netdev; + spin_lock_init(&kaweth->device_lock); init_waitqueue_head(&kaweth->term_wait); @@ -941,9 +944,7 @@ 100, 2)) < 0) { kaweth_err("Error downloading firmware (%d)", result); - free_page((unsigned long)kaweth->firmware_buf); - kfree(kaweth); - return -EIO; + goto err_fw; } if ((result = kaweth_download_firmware(kaweth, @@ -952,9 +953,7 @@ 100, 3)) < 0) { kaweth_err("Error downloading firmware fix (%d)", result); - free_page((unsigned long)kaweth->firmware_buf); - kfree(kaweth); - return -EIO; + goto err_fw; } if ((result = kaweth_download_firmware(kaweth, @@ -963,9 +962,8 @@ 126, 2)) < 0) { kaweth_err("Error downloading trigger code (%d)", result); - free_page((unsigned long)kaweth->firmware_buf); - kfree(kaweth); - return -EIO; + goto err_fw; + } if ((result = kaweth_download_firmware(kaweth, @@ -974,23 +972,20 @@ 126, 3)) < 0) { kaweth_err("Error downloading trigger code fix (%d)", result); - free_page((unsigned long)kaweth->firmware_buf); - kfree(kaweth); - return -EIO; + goto err_fw; } if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) { kaweth_err("Error triggering firmware (%d)", result); - free_page((unsigned long)kaweth->firmware_buf); - kfree(kaweth); - return -EIO; + goto err_fw; } /* Device will now disappear for a moment... */ kaweth_info("Firmware loaded. I'll be back..."); +err_fw: free_page((unsigned long)kaweth->firmware_buf); - kfree(kaweth); + free_netdev(netdev); return -EIO; } @@ -998,8 +993,7 @@ if(result < 0) { kaweth_err("Error reading configuration (%d), no net device created", result); - kfree(kaweth); - return -EIO; + goto err_free_netdev; } kaweth_info("Statistics collection: %x", kaweth->configuration.statistics_mask); @@ -1017,18 +1011,17 @@ &bcast_addr, sizeof(bcast_addr))) { kaweth_err("Firmware not functioning properly, no net device created"); - kfree(kaweth); - return -EIO; + goto err_free_netdev; } if(kaweth_set_urb_size(kaweth, KAWETH_BUF_SIZE) < 0) { kaweth_dbg("Error setting URB size"); - goto err_no_netdev; + goto err_free_netdev; } if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) { kaweth_err("Error setting SOFS wait"); - goto err_no_netdev; + goto err_free_netdev; } result = kaweth_set_receive_filter(kaweth, @@ -1038,20 +1031,14 @@ if(result < 0) { kaweth_err("Error setting receive filter"); - kfree(kaweth); - return -EIO; + goto err_free_netdev; } kaweth_dbg("Initializing net device."); - if (!(netdev = alloc_etherdev(0))) { - kfree(kaweth); - return -ENOMEM; - } - kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!kaweth->tx_urb) - goto err_no_urb; + goto err_free_netdev; kaweth->rx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!kaweth->rx_urb) goto err_only_tx; @@ -1072,26 +1059,23 @@ if (!kaweth->rx_buf) goto err_all_but_rxbuf; - kaweth->net = netdev; - memcpy(kaweth->net->broadcast, &bcast_addr, sizeof(bcast_addr)); - memcpy(kaweth->net->dev_addr, - &kaweth->configuration.hw_addr, + memcpy(netdev->broadcast, &bcast_addr, sizeof(bcast_addr)); + memcpy(netdev->dev_addr, &kaweth->configuration.hw_addr, sizeof(kaweth->configuration.hw_addr)); - kaweth->net->priv = kaweth; - kaweth->net->open = kaweth_open; - kaweth->net->stop = kaweth_close; - - kaweth->net->watchdog_timeo = KAWETH_TX_TIMEOUT; - kaweth->net->tx_timeout = kaweth_tx_timeout; - - kaweth->net->hard_start_xmit = kaweth_start_xmit; - kaweth->net->set_multicast_list = kaweth_set_rx_mode; - kaweth->net->get_stats = kaweth_netdev_stats; - kaweth->net->mtu = le16_to_cpu(kaweth->configuration.segment_size); - SET_ETHTOOL_OPS(kaweth->net, &ops); + netdev->open = kaweth_open; + netdev->stop = kaweth_close; - memset(&kaweth->stats, 0, sizeof(kaweth->stats)); + netdev->watchdog_timeo = KAWETH_TX_TIMEOUT; + netdev->tx_timeout = kaweth_tx_timeout; + + netdev->hard_start_xmit = kaweth_start_xmit; + netdev->set_multicast_list = kaweth_set_rx_mode; + netdev->get_stats = kaweth_netdev_stats; + netdev->mtu = le16_to_cpu(kaweth->configuration.segment_size); + SET_ETHTOOL_OPS(netdev, &ops); + + /* kaweth is zeroed as part of alloc_netdev */ INIT_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl, (void *)kaweth); @@ -1128,10 +1112,9 @@ usb_free_urb(kaweth->rx_urb); err_only_tx: usb_free_urb(kaweth->tx_urb); -err_no_urb: +err_free_netdev: free_netdev(netdev); -err_no_netdev: - kfree(kaweth); + return -EIO; } @@ -1141,6 +1124,7 @@ static void kaweth_disconnect(struct usb_interface *intf) { struct kaweth_device *kaweth = usb_get_intfdata(intf); + struct net_device *netdev; kaweth_info("Unregistering"); @@ -1149,7 +1133,7 @@ kaweth_warn("unregistering non-existant device"); return; } - + netdev = kaweth->net; kaweth->removed = 1; usb_kill_urb(kaweth->irq_urb); usb_kill_urb(kaweth->rx_urb); @@ -1163,26 +1147,17 @@ spin_unlock(&kaweth->device_lock); } - if(kaweth->net) { - if(kaweth->net->flags & IFF_UP) { - kaweth_dbg("Closing net device"); - dev_close(kaweth->net); - } - - kaweth_dbg("Unregistering net device"); - unregister_netdev(kaweth->net); - free_netdev(kaweth->net); - } + kaweth_dbg("Unregistering net device"); + unregister_netdev(netdev); usb_free_urb(kaweth->rx_urb); usb_free_urb(kaweth->tx_urb); usb_free_urb(kaweth->irq_urb); - usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle); usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle); - kfree(kaweth); + free_netdev(netdev); } diff -Nru a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c --- a/drivers/usb/net/usbnet.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/net/usbnet.c 2004-10-21 14:31:02 -07:00 @@ -567,7 +567,7 @@ static void ax8817x_set_multicast(struct net_device *net) { - struct usbnet *dev = (struct usbnet *) net->priv; + struct usbnet *dev = netdev_priv(net); struct ax8817x_data *data = (struct ax8817x_data *)&dev->data; u8 rx_ctl = 0x8c; @@ -610,7 +610,7 @@ static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc) { - struct usbnet *dev = netdev->priv; + struct usbnet *dev = netdev_priv(netdev); u16 res; u8 buf[1]; @@ -623,7 +623,7 @@ static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) { - struct usbnet *dev = netdev->priv; + struct usbnet *dev = netdev_priv(netdev); u16 res = val; u8 buf[1]; @@ -634,7 +634,7 @@ static void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) { - struct usbnet *dev = (struct usbnet *)net->priv; + struct usbnet *dev = netdev_priv(net); u8 opt; if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { @@ -654,7 +654,7 @@ static int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) { - struct usbnet *dev = (struct usbnet *)net->priv; + struct usbnet *dev = netdev_priv(net); u8 opt = 0; u8 buf[1]; @@ -675,7 +675,7 @@ static int ax8817x_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, u8 *data) { - struct usbnet *dev = (struct usbnet *)net->priv; + struct usbnet *dev = netdev_priv(net); u16 *ebuf = (u16 *)data; int i; @@ -704,14 +704,14 @@ static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd) { - struct usbnet *dev = (struct usbnet *)net->priv; + struct usbnet *dev = netdev_priv(net); return mii_ethtool_gset(&dev->mii,cmd); } static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd) { - struct usbnet *dev = (struct usbnet *)net->priv; + struct usbnet *dev = netdev_priv(net); return mii_ethtool_sset(&dev->mii,cmd); } @@ -2276,7 +2276,7 @@ static int usbnet_change_mtu (struct net_device *net, int new_mtu) { - struct usbnet *dev = (struct usbnet *) net->priv; + struct usbnet *dev = netdev_priv(net); if (new_mtu <= MIN_PACKET || new_mtu > MAX_PACKET) return -EINVAL; @@ -2302,7 +2302,8 @@ static struct net_device_stats *usbnet_get_stats (struct net_device *net) { - return &((struct usbnet *) net->priv)->stats; + struct usbnet *dev = netdev_priv(net); + return &dev->stats; } /*-------------------------------------------------------------------------*/ @@ -2569,7 +2570,7 @@ static int usbnet_stop (struct net_device *net) { - struct usbnet *dev = (struct usbnet *) net->priv; + struct usbnet *dev = netdev_priv(net); int temp; DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); DECLARE_WAITQUEUE (wait, current); @@ -2616,7 +2617,7 @@ static int usbnet_open (struct net_device *net) { - struct usbnet *dev = (struct usbnet *) net->priv; + struct usbnet *dev = netdev_priv(net); int retval = 0; struct driver_info *info = dev->driver_info; @@ -2666,7 +2667,7 @@ static void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) { - struct usbnet *dev = net->priv; + struct usbnet *dev = netdev_priv(net); strncpy (info->driver, driver_name, sizeof info->driver); strncpy (info->version, DRIVER_VERSION, sizeof info->version); @@ -2677,7 +2678,7 @@ static u32 usbnet_get_link (struct net_device *net) { - struct usbnet *dev = net->priv; + struct usbnet *dev = netdev_priv(net); /* If a check_connect is defined, return it's results */ if (dev->driver_info->check_connect) @@ -2689,14 +2690,14 @@ static u32 usbnet_get_msglevel (struct net_device *net) { - struct usbnet *dev = net->priv; + struct usbnet *dev = netdev_priv(net); return dev->msg_level; } static void usbnet_set_msglevel (struct net_device *net, u32 level) { - struct usbnet *dev = net->priv; + struct usbnet *dev = netdev_priv(net); dev->msg_level = level; } @@ -2705,7 +2706,7 @@ { #ifdef NEED_MII { - struct usbnet *dev = (struct usbnet *)net->priv; + struct usbnet *dev = netdev_priv(net); if (dev->mii.mdio_read != NULL && dev->mii.mdio_write != NULL) return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); @@ -2817,7 +2818,7 @@ static void usbnet_tx_timeout (struct net_device *net) { - struct usbnet *dev = (struct usbnet *) net->priv; + struct usbnet *dev = netdev_priv(net); unlink_urbs (dev, &dev->txq); tasklet_schedule (&dev->bh); @@ -2829,7 +2830,7 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) { - struct usbnet *dev = (struct usbnet *) net->priv; + struct usbnet *dev = netdev_priv(net); int length; int retval = NET_XMIT_SUCCESS; struct urb *urb = NULL; @@ -3014,6 +3015,7 @@ { struct usbnet *dev; struct usb_device *xdev; + struct net_device *net; dev = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); @@ -3026,7 +3028,8 @@ xdev->bus->bus_name, xdev->devpath, dev->driver_info->description); - unregister_netdev (dev->net); + net = dev->net; + unregister_netdev (net); /* we don't hold rtnl here ... */ flush_scheduled_work (); @@ -3034,8 +3037,7 @@ if (dev->driver_info->unbind) dev->driver_info->unbind (dev, intf); - free_netdev(dev->net); - kfree (dev); + free_netdev(net); usb_put_dev (xdev); } @@ -3069,12 +3071,13 @@ status = -ENOMEM; // set up our own records - if (!(dev = kmalloc (sizeof *dev, GFP_KERNEL))) { + net = alloc_etherdev(sizeof(*dev)); + if (!net) { dbg ("can't kmalloc dev"); goto out; } - memset (dev, 0, sizeof *dev); + dev = netdev_priv(net); dev->udev = xdev; dev->driver_info = info; dev->msg_level = msg_level; @@ -3088,14 +3091,8 @@ dev->delay.data = (unsigned long) dev; init_timer (&dev->delay); - // set up network interface records - net = alloc_etherdev(0); - if (!net) - goto out1; - SET_MODULE_OWNER (net); dev->net = net; - net->priv = dev; strcpy (net->name, "usb%d"); memcpy (net->dev_addr, node_id, sizeof node_id); @@ -3144,8 +3141,8 @@ dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); - SET_NETDEV_DEV(dev->net, &udev->dev); - status = register_netdev (dev->net); + SET_NETDEV_DEV(net, &udev->dev); + status = register_netdev (net); if (status) goto out3; devinfo (dev, "register usbnet at usb-%s-%s, %s", @@ -3156,16 +3153,15 @@ usb_set_intfdata (udev, dev); // start as if the link is up - netif_device_attach (dev->net); + netif_device_attach (net); return 0; out3: if (info->unbind) info->unbind (dev, udev); - free_netdev(net); out1: - kfree(dev); + free_netdev(net); out: usb_put_dev(xdev); return status; @@ -3251,6 +3247,10 @@ }, { // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter" USB_DEVICE (0x6189, 0x182d), + .driver_info = (unsigned long) &ax8817x_info, +}, { + // corega FEther USB2-TX + USB_DEVICE (0x07aa, 0x0017), .driver_info = (unsigned long) &ax8817x_info, }, { // Surecom EP-1427X-2 diff -Nru a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c --- a/drivers/usb/serial/belkin_sa.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/serial/belkin_sa.c 2004-10-21 14:31:02 -07:00 @@ -607,6 +607,7 @@ MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_VERSION( DRIVER_VERSION ); MODULE_LICENSE("GPL"); module_param(debug, bool, S_IRUGO | S_IWUSR); diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c --- a/drivers/usb/serial/cyberjack.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/serial/cyberjack.c 2004-10-21 14:31:02 -07:00 @@ -502,6 +502,7 @@ MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_VERSION( DRIVER_VERSION ); MODULE_LICENSE("GPL"); module_param(debug, bool, S_IRUGO | S_IWUSR); diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c --- a/drivers/usb/serial/pl2303.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/serial/pl2303.c 2004-10-21 14:31:02 -07:00 @@ -90,6 +90,7 @@ { USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) }, + { USB_DEVICE(PHAROS_VENDOR_ID, PHAROS_PRODUCT_ID) }, { } /* Terminating entry */ }; @@ -1188,6 +1189,7 @@ module_exit(pl2303_exit); MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); module_param(debug, bool, S_IRUGO | S_IWUSR); diff -Nru a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h --- a/drivers/usb/serial/pl2303.h 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/serial/pl2303.h 2004-10-21 14:31:02 -07:00 @@ -50,3 +50,6 @@ #define SAMSUNG_VENDOR_ID 0x04e8 #define SAMSUNG_PRODUCT_ID 0x8001 +/* Pharos / Microsoft GPS puck */ +#define PHAROS_VENDOR_ID 0x067b +#define PHAROS_PRODUCT_ID 0xaaa0 diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c --- a/drivers/usb/serial/usb-serial.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/serial/usb-serial.c 2004-10-21 14:31:02 -07:00 @@ -452,18 +452,12 @@ port = serial->port[i]; if (!port) continue; - if (port->read_urb) { - usb_kill_urb(port->read_urb); - usb_free_urb(port->read_urb); - } - if (port->write_urb) { - usb_kill_urb(port->write_urb); - usb_free_urb(port->write_urb); - } - if (port->interrupt_in_urb) { - usb_kill_urb(port->interrupt_in_urb); - usb_free_urb(port->interrupt_in_urb); - } + usb_kill_urb(port->read_urb); + usb_free_urb(port->read_urb); + usb_kill_urb(port->write_urb); + usb_free_urb(port->write_urb); + usb_kill_urb(port->interrupt_in_urb); + usb_free_urb(port->interrupt_in_urb); kfree(port->bulk_in_buffer); kfree(port->bulk_out_buffer); kfree(port->interrupt_in_buffer); @@ -799,18 +793,12 @@ struct usb_serial_port *port = to_usb_serial_port(dev); dbg ("%s - %s", __FUNCTION__, dev->bus_id); - if (port->read_urb) { - usb_kill_urb(port->read_urb); - usb_free_urb(port->read_urb); - } - if (port->write_urb) { - usb_kill_urb(port->write_urb); - usb_free_urb(port->write_urb); - } - if (port->interrupt_in_urb) { - usb_kill_urb(port->interrupt_in_urb); - usb_free_urb(port->interrupt_in_urb); - } + usb_kill_urb(port->read_urb); + usb_free_urb(port->read_urb); + usb_kill_urb(port->write_urb); + usb_free_urb(port->write_urb); + usb_kill_urb(port->interrupt_in_urb); + usb_free_urb(port->interrupt_in_urb); kfree(port->bulk_in_buffer); kfree(port->bulk_out_buffer); kfree(port->interrupt_in_buffer); diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c --- a/drivers/usb/serial/visor.c 2004-10-21 14:31:01 -07:00 +++ b/drivers/usb/serial/visor.c 2004-10-21 14:31:01 -07:00 @@ -381,10 +381,17 @@ .read_bulk_callback = visor_read_bulk_callback, }; +struct visor_private { + spinlock_t lock; + int bytes_in; + int bytes_out; + int outstanding_urbs; +}; -static int bytes_in; -static int bytes_out; +/* number of outstanding urbs to prevent userspace DoS from happening */ +#define URB_UPPER_LIMIT 42 +static int stats; /****************************************************************************** * Handspring Visor specific driver functions @@ -392,6 +399,8 @@ static int visor_open (struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial = port->serial; + struct visor_private *priv = usb_get_serial_port_data(port); + unsigned long flags; int result = 0; dbg("%s - port %d", __FUNCTION__, port->number); @@ -402,8 +411,11 @@ return -ENODEV; } - bytes_in = 0; - bytes_out = 0; + spin_lock_irqsave(&priv->lock, flags); + priv->bytes_in = 0; + priv->bytes_out = 0; + priv->outstanding_urbs = 0; + spin_unlock_irqrestore(&priv->lock, flags); /* * Force low_latency on so that our tty_push actually forces the data @@ -441,6 +453,7 @@ static void visor_close (struct usb_serial_port *port, struct file * filp) { + struct visor_private *priv = usb_get_serial_port_data(port); unsigned char *transfer_buffer; dbg("%s - port %d", __FUNCTION__, port->number); @@ -461,20 +474,32 @@ kfree (transfer_buffer); } - /* 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); */ + if (stats) + dev_info(&port->dev, "Bytes In = %d Bytes Out = %d\n", + priv->bytes_in, priv->bytes_out); } static int visor_write (struct usb_serial_port *port, const unsigned char *buf, int count) { + struct visor_private *priv = usb_get_serial_port_data(port); struct usb_serial *serial = port->serial; struct urb *urb; unsigned char *buffer; + unsigned long flags; int status; dbg("%s - port %d", __FUNCTION__, port->number); + spin_lock_irqsave(&priv->lock, flags); + if (priv->outstanding_urbs > URB_UPPER_LIMIT) { + spin_unlock_irqrestore(&priv->lock, flags); + dev_dbg(&port->dev, "write limit hit\n"); + return 0; + } + ++priv->outstanding_urbs; + spin_unlock_irqrestore(&priv->lock, flags); + buffer = kmalloc (count, GFP_ATOMIC); if (!buffer) { dev_err(&port->dev, "out of memory\n"); @@ -506,7 +531,10 @@ count = status; kfree (buffer); } else { - bytes_out += count; + spin_lock_irqsave(&priv->lock, flags); + ++priv->outstanding_urbs; + priv->bytes_out += count; + spin_unlock_irqrestore(&priv->lock, flags); } /* we are done with this urb, so let the host driver @@ -547,6 +575,8 @@ static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct visor_private *priv = usb_get_serial_port_data(port); + unsigned long flags; /* free up the transfer buffer, as usb_free_urb() does not do this */ kfree (urb->transfer_buffer); @@ -557,6 +587,10 @@ dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); + spin_lock_irqsave(&priv->lock, flags); + --priv->outstanding_urbs; + spin_unlock_irqrestore(&priv->lock, flags); + schedule_work(&port->work); } @@ -564,8 +598,10 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; - struct tty_struct *tty; + struct visor_private *priv = usb_get_serial_port_data(port); unsigned char *data = urb->transfer_buffer; + struct tty_struct *tty; + unsigned long flags; int i; int result; @@ -590,7 +626,9 @@ } tty_flip_buffer_push(tty); } - bytes_in += urb->actual_length; + spin_lock_irqsave(&priv->lock, flags); + priv->bytes_in += urb->actual_length; + spin_unlock_irqrestore(&priv->lock, flags); /* Continue trying to always read */ usb_fill_bulk_urb (port->read_urb, port->serial->dev, @@ -825,6 +863,22 @@ return num_ports; } +static int generic_startup(struct usb_serial *serial) +{ + struct visor_private *priv; + int i; + + for (i = 0; i < serial->num_ports; ++i) { + priv = kmalloc (sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + memset (priv, 0x00, sizeof(*priv)); + spin_lock_init(&priv->lock); + usb_set_serial_port_data(serial->port[i], priv); + } + return 0; +} + static int clie_3_5_startup (struct usb_serial *serial) { struct device *dev = &serial->dev->dev; @@ -864,7 +918,7 @@ return -EIO; } - return 0; + return generic_startup(serial); } static int treo_attach (struct usb_serial *serial) @@ -903,7 +957,7 @@ COPY_PORT(serial->port[1], swap_port); kfree(swap_port); - return 0; + return generic_startup(serial); } static int clie_5_attach (struct usb_serial *serial) @@ -924,7 +978,7 @@ /* port 0 now uses the modified endpoint Address */ serial->port[0]->bulk_out_endpointAddress = serial->port[1]->bulk_out_endpointAddress; - return 0; + return generic_startup(serial); } static void visor_shutdown (struct usb_serial *serial) @@ -1080,8 +1134,11 @@ module_param(debug, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug enabled or not"); +module_param(stats, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(stats, "Enables statistics or not"); module_param(vendor, ushort, 0); MODULE_PARM_DESC(vendor, "User specified vendor ID"); module_param(product, ushort, 0); MODULE_PARM_DESC(product, "User specified product ID"); + diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c --- a/drivers/usb/storage/scsiglue.c 2004-10-21 14:31:02 -07:00 +++ b/drivers/usb/storage/scsiglue.c 2004-10-21 14:31:02 -07:00 @@ -175,7 +175,7 @@ US_DEBUGP("%s called\n", __FUNCTION__); srb->host_scribble = (unsigned char *)us; - /* enqueue the command */ + /* check for state-transition errors */ if (us->sm_state != US_STATE_IDLE || us->srb != NULL) { printk(KERN_ERR USB_STORAGE "Error in %s: " "state = %d, us->srb = %p\n", @@ -183,10 +183,17 @@ return SCSI_MLQUEUE_HOST_BUSY; } + /* fail the command if we are disconnecting */ + if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { + US_DEBUGP("Fail command during disconnect\n"); + srb->result = DID_NO_CONNECT << 16; + done(srb); + return 0; + } + + /* enqueue the command and wake up the control thread */ srb->scsi_done = done; us->srb = srb; - - /* wake up the process task */ up(&(us->sema)); return 0; diff -Nru a/include/linux/proc_fs.h b/include/linux/proc_fs.h --- a/include/linux/proc_fs.h 2004-10-21 14:31:02 -07:00 +++ b/include/linux/proc_fs.h 2004-10-21 14:31:02 -07:00 @@ -193,6 +193,7 @@ #define proc_root_driver NULL #define proc_net NULL +#define proc_bus NULL #define proc_net_fops_create(name, mode, fops) ({ (void)(mode), NULL; }) #define proc_net_create(name, mode, info) ({ (void)(mode), NULL; }) diff -Nru a/include/linux/ticable.h b/include/linux/ticable.h --- a/include/linux/ticable.h 2004-10-21 14:31:02 -07:00 +++ b/include/linux/ticable.h 2004-10-21 14:31:02 -07:00 @@ -38,5 +38,7 @@ #define IOCTL_TIUSB_TIMEOUT _IOW('N', 0x20, int) /* set timeout */ #define IOCTL_TIUSB_RESET_DEVICE _IOW('N', 0x21, int) /* reset device */ #define IOCTL_TIUSB_RESET_PIPES _IOW('N', 0x22, int) /* reset both pipes*/ +#define IOCTL_TIUSB_GET_MAXPS _IOR('N', 0x23, int) /* max packet size */ +#define IOCTL_TIUSB_GET_DEVID _IOR('N', 0x24, int) /* get device type */ #endif /* TICABLE_H */