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 <stern@rowland.harvard.edu>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <dbrownell@users.sourceforge.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <dbrownell@users.sourceforge.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <dbrownell@users.sourceforge.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <dbrownell@users.sourceforge.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <dbrownell@users.sourceforge.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <dbrownell@users.sourceforge.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <stern@rowland.harvard.edu>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <shemminger@osdl.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <zupae234@yahoo.co.jp>
#   Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <dale@farnsworth.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <stern@rowland.harvard.edu>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <shemminger@osdl.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <shemminger@osdl.org>
#   Signed-off-by: Oliver Neukum <oliver@neukum.name>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <dbrownell@users.sourceforge.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <dbrownell@users.sourceforge.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <lkml@lievin.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <lcapitulino@conectiva.com.br>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <lcapitulino@conectiva.com.br>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <lcapitulino@conectiva.com.br>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <zaitcev@redhat.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <greg@kroah.com>
# 
# 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 <luca.risolia@studio.unibo.it>
# 
# 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 <stern@rowland.harvard.edu>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
#   
#   
#   ===== 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 <stern@rowland.harvard.edu>
#   Signed-off-by: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
#   
#   
#   ===== 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 <greg@kroah.com>
# 
# 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 <greg@kroah.com>
# 
# 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 <greg@kroah.com>
# 
# 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 <greg@kroah.com>
# 
# 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 <greg@kroah.com>
# 
# 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 <greg@kroah.com>
# 
# ChangeSet
#   2004/10/20 15:30:06-07:00 greg@kroah.com 
#   USB: add phidgetkit driver.
#   
#   originally written by Sean Young <sean@mess.org> but with LED additions and
#   cleanups from me.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <sean@mess.org> but with LED additions and
#   cleanups from me.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <sean@mess.org> but with LED additions and
#   cleanups from me.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# 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 <greg@kroah.com>
# 
# 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 <greg@kroah.com>
# 
# 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 <luca.risolia@studio.unibo.it>
 
+
+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 <luca.risolia@studio.unibo.it>.
 
@@ -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, &regs->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, &regs->int_enable);
 		readl(&regs->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(&regs->EPxSingle);
+			tmp = readl(&r->EPxSingle);
 			tmp &= ~(0x11 << ep->num);
-			writel(tmp, &regs->EPxSingle);
+			writel(tmp, &r->EPxSingle);
 
-			tmp = readl(&regs->EPxBCS);
+			tmp = readl(&r->EPxBCS);
 			tmp &= ~(0x11 << ep->num);
-			writel(tmp, &regs->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, &regs->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, &regs->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(&regs->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(&regs->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, &regs->power_detect);
 	writel(0, &regs->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(&regs->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    "<luca.risolia@studio.unibo.it>"
 #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 <sean@mess.org>
+ * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * 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 <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
+#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<len; i++)
+		form_buffer[buf_ptr++] = display[i];
+
+	for (i = 0; i < (20 - len); i++)
+		form_buffer[buf_ptr++] = 0x20;
+	form_buffer[buf_ptr++] = 0x01;
+	form_buffer[buf_ptr++] = row * 0x40 + 0x80 + strlen(display);
+
+	for (i = 0; i < buf_ptr; i += 7) {
+		if ((buf_ptr - 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 <roms@lpg.ticalc.org>
+ *   Romain Lievin <roms@tilp.info>
  *   Julien BLACHE <jb@technologeek.org>
  * 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 <linux/module.h>
@@ -41,7 +42,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "1.07"
+#define DRIVER_VERSION "1.08"
 #define DRIVER_AUTHOR  "Romain Lievin <roms@tilp.info> & Julien Blache <jb@jblache.org>"
 #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 */
