bk://kernel.bkbits.net/gregkh/linux/usb-2.6
stern@rowland.harvard.edu|ChangeSet|20040525193350|22947 stern

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/05/25 13:48:31-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/input/hiddev.c
#   2004/05/25 13:48:27-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/usb.c
#   2004/05/25 13:48:27-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/message.c
#   2004/05/25 13:48:27-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/25 13:47:38-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# MAINTAINERS
#   2004/05/25 13:47:34-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/25 12:33:50-07:00 stern@rowland.harvard.edu 
#   [PATCH] USB: Gonzo variable renaming in hub.c
#   
#   As part of the cleanup effort, I wanted to name all the variables in hub.c
#   uniformly.  Currently there are different names for the same thing in
#   different routines, and the same names are used for different things --
#   it's impossible to keep things straight.  I also wanted to step away from
#   the deplorable practice of naming everything "dev".  It is not an
#   exaggeration that up until relatively recently one of the drivers (not the
#   hub driver, fortunately!) contained a line which looked basically like
#   this:
#   
#   	dev->dev.dev = &intf->dev;
#   
#   If you can make sense out of that, you're a better code reader than I am!
#   
#   Ranting aside, this patch institutes the following name scheme for local
#   variables in hub.c:
#   
#   	hub:		struct usb_hub
#   	hdev:		hub's corresponding struct usb_device
#   	hub_dev:	hub interface's embedded struct device
#   	udev:		general struct usb_device
#   
#   There are a couple of genuine code changes hidden in there too.  Just
#   trivial things, like creating a local hub_dev variable for use in place of
#   &hub->intf->dev.
# 
# drivers/usb/core/hub.c
#   2004/05/24 08:54:24-07:00 stern@rowland.harvard.edu +276 -269
#   USB: Gonzo variable renaming in hub.c
# 
# ChangeSet
#   2004/05/25 12:33:17-07:00 stern@rowland.harvard.edu 
#   [PATCH] USB: Make usb_choose_configuration() a separate subroutine
#   
#   This patch creates a separate subroutine to encapsulate the work required
#   in choosing an initial configuration for a device.  In my opinion that
#   reflects a policy decision that should be kept apart from all the other
#   work involved in creating a new device structure.  The existing code in
#   usb_new_device() is simply moved into usb_choose_configuration().
# 
# drivers/usb/core/usb.c
#   2004/05/24 03:37:01-07:00 stern@rowland.harvard.edu +35 -30
#   USB: Make usb_choose_configuration() a separate subroutine
# 
# ChangeSet
#   2004/05/25 12:27:47-07:00 stern@rowland.harvard.edu 
#   [PATCH] USB: Add usb_release_address() and move usb_set_address()
#   
#   This patch adds usb_release_address() as a complement to
#   usb_choose_address(), to centralize the work required when freeing an
#   allocated device address.  It also moves the usb_set_address() routine
#   from usb.c to hub.c -- which is the only place it is ever used -- and
#   renames it to hub_set_address().
# 
# drivers/usb/core/usb.c
#   2004/05/24 03:29:23-07:00 stern@rowland.harvard.edu +18 -22
#   USB: Add usb_release_address() and move usb_set_address()
# 
# drivers/usb/core/hub.c
#   2004/05/24 03:29:23-07:00 stern@rowland.harvard.edu +17 -3
#   USB: Add usb_release_address() and move usb_set_address()
# 
# drivers/usb/core/hcd.h
#   2004/05/24 03:29:23-07:00 stern@rowland.harvard.edu +2 -2
#   USB: Add usb_release_address() and move usb_set_address()
# 
# ChangeSet
#   2004/05/25 11:50:29-07:00 stern@rowland.harvard.edu 
#   [PATCH] USB: Change "driverfs" to "sysfs" in usbcore
#   
#   Before fixing up the device locking and device reset code, I want to do
#   some cleanups of the hub driver and related areas.  This is the first of a
#   series of patches for that purpose.
#   
#   This patch changes all the occurrences of "driverfs" in usbcore to "sysfs"
#   -- I just couldn't stand seeing the out-of-date name any more (and I kept
#   confusing it with usbfs, don't know why).
#   
#   Although I did a "bk mv driverfs.c sysfs.c" when creating the patch, the
#   exported patch file itself doesn't reflect that very well.  It looks like
#   driverfs.c was deleted and sysfs.c created from scratch.  If you prefer, I
#   can resubmit this in a slightly different form, with the file name
#   unchanged so that you can issue the "bk mv" command in your repository
#   after applying the patch.
# 
# drivers/usb/core/usb.h
#   2004/05/24 03:23:37-07:00 stern@rowland.harvard.edu +2 -2
#   USB: Change "driverfs" to "sysfs" in usbcore
# 
# drivers/usb/core/usb.c
#   2004/05/24 03:23:37-07:00 stern@rowland.harvard.edu +1 -1
#   USB: Change "driverfs" to "sysfs" in usbcore
# 
# drivers/usb/core/message.c
#   2004/05/24 03:23:37-07:00 stern@rowland.harvard.edu +1 -1
#   USB: Change "driverfs" to "sysfs" in usbcore
# 
# drivers/usb/core/sysfs.c
#   2004/05/24 03:23:37-07:00 stern@rowland.harvard.edu +4 -4
#   USB: Change "driverfs" to "sysfs" in usbcore
# 
# drivers/usb/core/Makefile
#   2004/05/24 03:23:37-07:00 stern@rowland.harvard.edu +1 -1
#   USB: Change "driverfs" to "sysfs" in usbcore
# 
# ChangeSet
#   2004/05/25 11:38:39-07:00 stern@rowland.harvard.edu 
#   [PATCH] USB UHCI: allow URBs to be unlinked when IRQs don't work
#   
#   A lot of people with USB controllers made by VIA have been suffering from
#   the fact that these controllers stop working when they receive a babble
#   packet.  In particular, they stop generating interrupt requests.  Since
#   the UHCI driver relies on IRQs from the controller for proper timing and
#   interlocking of unlink requests, this means that those broken controllers
#   will hang the UHCI driver and drivers for any device connected through it.
#   
#   This patch, written by Herbert Xu, gives the UCHI driver the ability to
#   manage the unlink procedure using timer interrupts as well as controller
#   interrupts.  (It also fixes a race in the UHCI irq handler.)  Although it
#   won't prevent the VIA controllers from flaking out when they encounter
#   babble, at least now users will be able to rmmod the uhci-hcd driver and
#   then reload it, restoring their systems back to normal operation (until
#   the next babble!).
#   
#   P.S.: Herbert, there's one loose end I still want to tie up.  When the
#   controller isn't running (i.e., is suspended) the frame number won't
#   change, but unlinks still need to work.  It's a small point, not too
#   likely to come up in normal usage.  I'll fix it later on when I update the
#   state-changing part of the driver.
# 
# drivers/usb/host/uhci-hcd.h
#   2004/05/19 16:25:26-07:00 stern@rowland.harvard.edu +3 -0
#   USB UHCI: allow URBs to be unlinked when IRQs don't work
# 
# drivers/usb/host/uhci-hcd.c
#   2004/05/19 16:41:50-07:00 stern@rowland.harvard.edu +46 -5
#   USB UHCI: allow URBs to be unlinked when IRQs don't work
# 
# ChangeSet
#   2004/05/25 11:37:59-07:00 stern@rowland.harvard.edu 
#   [PATCH] USB: Initially read 9 bytes of config descriptor
#   
#   This patch reads the full 9 bytes of a configuration descriptor during
#   enumeration rather than just the first 8 bytes.  That's how Windows does
#   it, and today I ran across a device that doesn't work properly when asked
#   to send only 8 bytes worth.  I doubt very much this will cause any
#   problems with currently-working devices; since the descriptor itself is 9
#   bytes long and since the devices are most likely to expect a 9-byte
#   request, anything that can handle an 8-byte request should have no
#   difficulty.  (Also, some debugging messages have been slightly improved.)
#   
#   Incidentally, USB traces taken from Windows 2000 and Windows XP show that
#   when those operating systems retrieve a string descriptor during
#   enumeration, they do so by requesting a 255-byte transfer.  They do not
#   first ask just for the initial 2 bytes (which contain the actual length)
#   and then ask for the actual length, which is what we do.  Interestingly,
#   back in 2.4 we _did_ do things the same as Windows.
# 
# drivers/usb/core/config.c
#   2004/05/21 03:00:23-07:00 stern@rowland.harvard.edu +9 -8
#   USB: Initially read 9 bytes of config descriptor
# 
# ChangeSet
#   2004/05/25 11:31:08-07:00 jnardelli@infosciences.com 
#   [PATCH] USB: visor: Fix Oops on disconnect
#   
#   This fixes http://bugme.osdl.org/show_bug.cgi?id=2289
#   
#   This patch has been tweaked by greg@kroah.com
# 
# drivers/usb/serial/visor.c
#   2004/05/25 11:19:19-07:00 jnardelli@infosciences.com +64 -59
#   USB: visor: Fix Oops on disconnect
# 
# ChangeSet
#   2004/05/25 11:00:57-07:00 olh@suse.de 
#   [PATCH] USB: out of bounds access in hiddev_cleanup
#   
#   hiddev_table[] is an array of pointers.  the minor number is used as an
#   offset.  hiddev minors start either with zero, or with 96.  If they start
#   with 96, the offset must be reduced by HIDDEV_MINOR_BASE because only 16
#   minors are available.  unplugging a hiddevice will zero data outside the
#   hiddev_table array.
#   
#   this was spotted by Takashi Iwai.
# 
# drivers/usb/input/hiddev.c
#   2004/05/19 07:48:16-07:00 olh@suse.de +1 -1
#   USB: out of bounds access in hiddev_cleanup
# 
# ChangeSet
#   2004/05/25 11:00:18-07:00 jamesl@appliedminds.com 
#   [PATCH] USB: Fix down() in hard IRQ in powermate driver
#   
#   Fixes this warning:
#   
#   May 18 06:56:01 Knoppix kernel: Debug: sleeping function called from
#   invalid context at include/asm/semaphore.h:119
#   May 18 06:56:01 Knoppix kernel: in_atomic():1, irqs_disabled():0
#   May 18 06:56:01 Knoppix kernel: Call Trace:
#   May 18 06:56:01 Knoppix kernel:  [<c0117083>] __might_sleep+0xb2/0xd3
#   May 18 06:56:01 Knoppix kernel:  [<f88b92f4>] powermate_config_complete+0x33/0x77 [powermate]
#   May 18 06:56:01 Knoppix kernel:  [<c02c6760>] usb_hcd_giveback_urb+0x25/0x39
#   May 18 06:56:01 Knoppix kernel:  [<c02d7194>] uhci_finish_urb+0x54/0xa1
#   May 18 06:56:01 Knoppix kernel:  [<c02d7224>] uhci_finish_completion+0x43/0x55
#   May 18 06:56:01 Knoppix kernel:  [<c02d737d>] uhci_irq+0xf8/0x179
#   May 18 06:56:01 Knoppix kernel:  [<c02c67aa>] usb_hcd_irq+0x36/0x67
#   May 18 06:56:01 Knoppix kernel:  [<c01060c6>] handle_IRQ_event+0x3a/0x64
#   May 18 06:56:01 Knoppix kernel:  [<c0106479>] do_IRQ+0xb8/0x192
#   May 18 06:56:01 Knoppix kernel:  [<c0104850>] common_interrupt+0x18/0x20
#   
#   Attached patch uses spinlocks instead of a semaphore so that we can't sleep
#   when in_atomic().
# 
# drivers/usb/input/powermate.c
#   2004/05/24 08:48:15-07:00 jamesl@appliedminds.com +12 -8
#   USB: Fix down() in hard IRQ in powermate driver
# 
# ChangeSet
#   2004/05/24 17:06:48-07:00 Thomas.Wahrenbruch@kobil.com 
#   [PATCH] USB: Fix kobil_sct with uhci
#   
#   the kobil_sct didn't work with uhci hcds.
#   It used usb_fill_bulk_urb instead of usb_fill_int_urb.
#   The attached patch fixes this.
#   
#   It starts reading in open now - this gives apps (CT-API) the chance to
#   detect the p'n'p string correctly.
# 
# drivers/usb/serial/kobil_sct.c
#   2004/05/24 09:56:30-07:00 Thomas.Wahrenbruch@kobil.com +31 -12
#   USB: Fix kobil_sct with uhci
# 
# drivers/usb/serial/Kconfig
#   2004/05/24 09:54:50-07:00 Thomas.Wahrenbruch@kobil.com +2 -2
#   USB: Fix kobil_sct with uhci
# 
# ChangeSet
#   2004/05/24 17:06:06-07:00 movits@bloomberg.com 
#   [PATCH] USB: add support for MS adapter to usb pegasus net driver
#   
#   I took the relevant parts from the patch (not some PHY stuff that was
#   irrelevant).  Attached is the patch against stock 2.6.6.
# 
# drivers/usb/net/pegasus.h
#   2004/05/20 15:09:36-07:00 movits@bloomberg.com +3 -0
#   USB: add support for MS adapter to usb pegasus net driver
# 
# ChangeSet
#   2004/05/24 17:05:26-07:00 david-b@pacbell.net 
#   [PATCH] USB: PXA 2xx UDC and RNDIS g_ether
#   
#   I noticed some problems with the PXA 2xx UDC and the
#   RNDIS version of the ethernet-over-usb link:
#   
#     - Static linking needs more than just two endpoints now
#   
#     - The endpoint autoconfig misbehaves (sounds like what
#       Stefan reported a couple weeks ago)
#   
#   This patch fixes those two problems, though there are
#   a couple others lurking too.
# 
# drivers/usb/gadget/Kconfig
#   2004/05/19 13:52:50-07:00 david-b@pacbell.net +1 -0
#   USB: PXA 2xx UDC and RNDIS g_ether
# 
# drivers/usb/gadget/epautoconf.c
#   2004/05/19 13:52:55-07:00 david-b@pacbell.net +2 -1
#   USB: PXA 2xx UDC and RNDIS g_ether
# 
# ChangeSet
#   2004/05/24 17:04:38-07:00 lcapitulino@prefeitura.sp.gov.br 
#   [PATCH] USB: /usb/gadget/serial.c warning fix.
#   
#    that code is generating the fallowing warning:
#   
#   drivers/usb/gadget/serial.c:162: warning: `debug' defined but not used
#   
#    When G_SERIAL_DEBUG is not defined, `debug' is not used, because
#   the gs_debug() function is compiled only when G_SERIAL_DEBUG is
#   defined.
#   
#    Thus, a solution is to define `debug' only when G_SERIAL_DEBUG
#   is defined. That includes the use of `debug' as a module parameter
#   (this last part I'm not sure).
#   
#    The patch bellow does that (compiles ok, not tested because I don't
#   have that hardware):
# 
# drivers/usb/gadget/serial.c
#   2004/05/19 15:17:03-07:00 lcapitulino@prefeitura.sp.gov.br +3 -6
#   USB: /usb/gadget/serial.c warning fix.
# 
# ChangeSet
#   2004/05/24 17:03:52-07:00 oliver@neukum.org 
#   [PATCH] USB: fix fix to kaweth.c
#   
#   the previous patch was buggy. The state must be set _before_ the
#   condition is checked, or there's a window missing a wakeup.
#   This incremental change set fixes that.
#   
#     - fix race condition with current->state
# 
# drivers/usb/net/kaweth.c
#   2004/05/19 11:13:49-07:00 oliver@neukum.org +2 -1
#   USB: fix fix to kaweth.c
# 
# ChangeSet
#   2004/05/24 17:03:19-07:00 oliver@neukum.org 
#   [PATCH] USB: waitqueue related problem in kaweth
#   
#   this was buggy for the same reason that the old msleep was buggy.
#   
#     - safe waiting in case we are left on other wait queues
# 
# drivers/usb/net/kaweth.c
#   2004/05/19 10:33:39-07:00 oliver@neukum.org +4 -4
#   USB: waitqueue related problem in kaweth
# 
# ChangeSet
#   2004/05/24 17:02:47-07:00 oliver@neukum.org 
#   [PATCH] USB: yet another place for msleep
#   
#   this is in kobil_sct.
#   It uses msleep() and replaces needless GFP_ATOMICs with GFP_NOIO
#   as this function can sleep.
#   
#     - no need for GFP_ATOMIC
#     - use msleep()
# 
# drivers/usb/serial/kobil_sct.c
#   2004/05/19 10:21:50-07:00 oliver@neukum.org +3 -5
#   USB: yet another place for msleep
# 
# ChangeSet
#   2004/05/24 17:02:10-07:00 oliver@neukum.org 
#   [PATCH] USB: clean delays for ehci
#   
#   Here's one you overlooked.
#   
#     - safe sleep helper
# 
# drivers/usb/storage/transport.c
#   2004/05/19 08:53:06-07:00 oliver@neukum.org +1 -2
#   USB: clean delays for ehci
# 
# ChangeSet
#   2004/05/24 17:01:41-07:00 errandir_news@mph.eclipse.co.uk 
#   [PATCH] USB: usblp printer GET_DEVICE_ID fix
#   
#   There is a problem in the usblp GET_DEVICE_ID ioctl() implementation. The patch
#   below (against 2.6 current) fixes the code to be according to the official usb
#   printer spec.
#   
#   Most printers are not affected by this fix, as they use interface 0 and
#   alternate 0. For those, nothing changes. But my printer/scanner uses interface
#   1 for the printer.
# 
# drivers/usb/class/usblp.c
#   2004/04/02 19:18:19-08:00 errandir_news@mph.eclipse.co.uk +17 -4
#   USB: usblp printer GET_DEVICE_ID fix
# 
# ChangeSet
#   2004/05/24 11:48:01-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# include/linux/pci_ids.h
#   2004/05/24 11:47:57-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/22 23:48:51-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# include/linux/pci_ids.h
#   2004/05/22 23:48:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# MAINTAINERS
#   2004/05/22 23:48:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/21 19:09:03-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# arch/ia64/defconfig
#   2004/05/21 19:09:00-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# MAINTAINERS
#   2004/05/21 19:09:00-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/19 18:31:55-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# MAINTAINERS
#   2004/05/19 18:31:52-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/19 00:07:04-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# include/linux/usb.h
#   2004/05/19 00:07:01-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/pci_ids.h
#   2004/05/19 00:07:01-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/usb.c
#   2004/05/19 00:07:01-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc/defconfig
#   2004/05/19 00:07:01-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc/configs/pmac_defconfig
#   2004/05/19 00:07:01-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc/configs/common_defconfig
#   2004/05/19 00:07:01-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/18 14:54:09-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# include/linux/usb.h
#   2004/05/18 14:54:06-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/pci_ids.h
#   2004/05/18 14:54:06-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/input/hid-core.c
#   2004/05/18 14:54:06-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/usb.c
#   2004/05/18 14:54:06-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# CREDITS
#   2004/05/18 14:54:06-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/16 01:52:25-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# include/linux/pci_ids.h
#   2004/05/16 01:52:22-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/14 21:45:47-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# include/linux/pci_ids.h
#   2004/05/14 21:45:43-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/14 09:41:12-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/input/hid-core.c
#   2004/05/14 09:41:09-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/usb.c
#   2004/05/14 09:41:09-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/message.c
#   2004/05/14 09:41:09-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/12 20:32:44-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/core/inode.c
#   2004/05/12 20:32:41-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# MAINTAINERS
#   2004/05/12 20:32:41-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/12 01:26:11-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/input/wacom.c
#   2004/05/12 01:26:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/input/hid-core.c
#   2004/05/12 01:26:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/12 01:25:17-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# include/linux/pci_ids.h
#   2004/05/12 01:25:14-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/parisc/configs/c3000_defconfig
#   2004/05/12 01:25:14-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# MAINTAINERS
#   2004/05/12 01:25:14-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/05 14:52:58-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/core/message.c
#   2004/05/05 14:52:55-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/05 14:52:11-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# CREDITS
#   2004/05/05 14:52:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/04 14:13:11-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# include/linux/usb.h
#   2004/05/04 14:13:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/01 15:23:25-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# MAINTAINERS
#   2004/05/01 15:23:22-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/30 22:06:45-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/core/inode.c
#   2004/04/30 22:06:42-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/29 16:00:47-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# include/linux/pci_ids.h
#   2004/04/29 16:00:44-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# MAINTAINERS
#   2004/04/29 16:00:44-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/28 13:38:52-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/input/hid-core.c
#   2004/04/28 13:38:49-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/27 19:39:13-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# include/linux/usb.h
#   2004/04/27 19:39:10-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/usb.c
#   2004/04/27 19:39:10-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/message.c
#   2004/04/27 19:39:10-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/26 18:31:48-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# include/linux/usb.h
#   2004/04/26 18:31:45-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/usb.c
#   2004/04/26 18:31:45-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/25 23:06:05-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# include/linux/pci_ids.h
#   2004/04/25 23:06:02-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/24 23:51:05-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/core/usb.c
#   2004/04/24 23:51:02-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/23 12:58:38-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# CREDITS
#   2004/04/23 12:58:35-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/19 19:45:10-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# include/linux/pci_ids.h
#   2004/04/19 19:45:07-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# MAINTAINERS
#   2004/04/19 19:45:07-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# CREDITS
#   2004/04/19 19:45:06-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/07 20:17:13-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/core/message.c
#   2004/04/07 20:17:11-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/02 11:35:28-08:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# include/linux/pci_ids.h
#   2004/04/02 11:35:25-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/01 15:16:14-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# CREDITS
#   2004/04/01 15:16:11-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/31 19:24:39-08:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# include/linux/usb.h
#   2004/03/31 19:24:37-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/usb.c
#   2004/03/31 19:24:37-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/message.c
#   2004/03/31 19:24:37-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc64/defconfig
#   2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc64/configs/pSeries_defconfig
#   2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc/defconfig
#   2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc/configs/pmac_defconfig
#   2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc/configs/common_defconfig
#   2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/parisc/configs/c3000_defconfig
#   2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ia64/defconfig
#   2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ia64/configs/zx1_defconfig
#   2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ia64/configs/generic_defconfig
#   2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/arm/configs/neponset_defconfig
#   2004/03/31 19:24:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/30 20:18:36-08:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# arch/ppc64/defconfig
#   2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc64/configs/pSeries_defconfig
#   2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc/defconfig
#   2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc/configs/pmac_defconfig
#   2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc/configs/common_defconfig
#   2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/parisc/configs/c3000_defconfig
#   2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ia64/defconfig
#   2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ia64/configs/zx1_defconfig
#   2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ia64/configs/generic_defconfig
#   2004/03/30 20:18:33-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/arm/configs/neponset_defconfig
#   2004/03/30 20:18:32-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/30 12:09:32-08:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# include/linux/usb.h
#   2004/03/30 12:09:29-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/usb.c
#   2004/03/30 12:09:29-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/message.c
#   2004/03/30 12:09:29-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/29 18:05:43-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# MAINTAINERS
#   2004/03/29 18:05:41-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/29 13:51:58-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# CREDITS
#   2004/03/29 13:51:56-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/28 12:29:41-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/core/message.c
#   2004/03/28 12:29:38-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/27 02:28:18-08:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/input/wacom.c
#   2004/03/27 02:28:16-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/26 12:24:49-08:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# include/linux/usb_gadget.h
#   2004/03/26 12:24:46-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/usb.c
#   2004/03/26 12:24:46-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/20 13:26:55-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# CREDITS
#   2004/03/20 13:26:53-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/16 21:53:42-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/input/wacom.c
#   2004/03/16 21:53:39-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/input/hid-core.c
#   2004/03/16 21:53:39-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/16 12:59:58-08:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6
#   into bix.(none):/usr/src/bk-usb
# 
# include/linux/usb_gadget.h
#   2004/03/16 12:59:47-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/usb.h
#   2004/03/16 12:59:47-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/usb.c
#   2004/03/16 12:59:46-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# MAINTAINERS
#   2004/03/16 12:59:46-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# CREDITS
#   2004/03/16 12:59:46-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/16 12:58:57-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# drivers/usb/input/wacom.c
#   2004/03/16 12:58:47-08:00 akpm@bix.(none) +0 -4
#   Auto merged
# 
# drivers/usb/input/hid-core.c
#   2004/03/16 12:58:47-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# CREDITS
#   2004/03/16 12:58:46-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/14 11:03:00-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# include/linux/usb_gadget.h
#   2004/03/14 11:02:47-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/usb.h
#   2004/03/14 11:02:47-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/usb.c
#   2004/03/14 11:02:47-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# MAINTAINERS
#   2004/03/14 11:02:47-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/12 10:57:17-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb
# 
# MAINTAINERS
#   2004/03/12 10:57:02-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# CREDITS
#   2004/03/12 10:57:01-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
--- a/drivers/usb/class/usblp.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/class/usblp.c	2004-05-25 21:38:09 -07:00
@@ -226,11 +226,21 @@
 
 static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, int recip, int value, void *buf, int len)
 {
-	int retval = usb_control_msg(usblp->dev,
+	int retval;
+	int index = usblp->ifnum;
+
+	/* High byte has the interface index.
+	   Low byte has the alternate setting.
+	 */
+	if ((request == USBLP_REQ_GET_ID) && (type == USB_TYPE_CLASS)) {
+	  index = (usblp->ifnum<<8)|usblp->protocol[usblp->current_protocol].alt_setting;
+	}
+
+	retval = usb_control_msg(usblp->dev,
 		dir ? usb_rcvctrlpipe(usblp->dev, 0) : usb_sndctrlpipe(usblp->dev, 0),
-		request, type | dir | recip, value, usblp->ifnum, buf, len, USBLP_WRITE_TIMEOUT);
-	dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d len: %#x result: %d",
-		request, !!dir, recip, value, len, retval);
+		request, type | dir | recip, value, index, buf, len, USBLP_WRITE_TIMEOUT);
+	dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d idx: %d len: %#x result: %d",
+		request, !!dir, recip, value, index, len, retval);
 	return retval < 0 ? retval : 0;
 }
 
@@ -439,6 +449,9 @@
 		retval = -ENODEV;
 		goto done;
 	}
+
+	dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", cmd, _IOC_TYPE(cmd),
+		_IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd) );
 
 	if (_IOC_TYPE(cmd) == 'P')	/* new-style ioctl number */
 
diff -Nru a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
--- a/drivers/usb/core/Makefile	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/core/Makefile	2004-05-25 21:38:09 -07:00
@@ -3,7 +3,7 @@
 #
 
 usbcore-objs	:= usb.o hub.o hcd.o urb.o message.o \
-			config.o file.o buffer.o driverfs.o
+			config.o file.o buffer.o sysfs.o
 
 ifeq ($(CONFIG_PCI),y)
 	usbcore-objs	+= hcd-pci.o
diff -Nru a/drivers/usb/core/config.c b/drivers/usb/core/config.c
--- a/drivers/usb/core/config.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/core/config.c	2004-05-25 21:38:09 -07:00
@@ -465,23 +465,24 @@
 		goto err2;
 	memset(dev->rawdescriptors, 0, length);
 
-	buffer = kmalloc(8, GFP_KERNEL);
+	buffer = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
 	if (!buffer)
 		goto err2;
 	desc = (struct usb_config_descriptor *)buffer;
 
 	for (cfgno = 0; cfgno < ncfg; cfgno++) {
-		/* We grab the first 8 bytes so we know how long the whole */
-		/* configuration is */
+		/* We grab just the first descriptor so we know how long
+		 * the whole configuration is */
 		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
-		    buffer, 8);
+		    buffer, USB_DT_CONFIG_SIZE);
 		if (result < 0) {
 			dev_err(ddev, "unable to read config index %d "
-			    "descriptor\n", cfgno);
+			    "descriptor/%s\n", cfgno, "start");
 			goto err;
-		} else if (result < 8) {
+		} else if (result < 4) {
 			dev_err(ddev, "config index %d descriptor too short "
-			    "(expected %i, got %i)\n", cfgno, 8, result);
+			    "(expected %i, got %i)\n", cfgno,
+			    USB_DT_CONFIG_SIZE, result);
 			result = -EINVAL;
 			goto err;
 		}
@@ -498,7 +499,7 @@
 		    bigbuffer, length);
 		if (result < 0) {
 			dev_err(ddev, "unable to read config index %d "
-			    "descriptor\n", cfgno);
+			    "descriptor/%s\n", cfgno, "all");
 			kfree(bigbuffer);
 			goto err;
 		}
diff -Nru a/drivers/usb/core/driverfs.c b/drivers/usb/core/driverfs.c
--- a/drivers/usb/core/driverfs.c	2004-05-25 21:38:09 -07:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,229 +0,0 @@
-/*
- * drivers/usb/core/driverfs.c
- *
- * (C) Copyright 2002 David Brownell
- * (C) Copyright 2002 Greg Kroah-Hartman
- * (C) Copyright 2002 IBM Corp.
- *
- * All of the driverfs file attributes for usb devices and interfaces.
- *
- */
-
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-
-#ifdef CONFIG_USB_DEBUG
-	#define DEBUG
-#else
-	#undef DEBUG
-#endif
-#include <linux/usb.h>
-
-#include "usb.h"
-
-/* Active configuration fields */
-#define usb_actconfig_show(field, multiplier, format_string)		\
-static ssize_t  show_##field (struct device *dev, char *buf)		\
-{									\
-	struct usb_device *udev;					\
-									\
-	udev = to_usb_device (dev);					\
-	if (udev->actconfig)						\
-		return sprintf (buf, format_string,			\
-				udev->actconfig->desc.field * multiplier);	\
-	else								\
-		return 0;						\
-}									\
-
-#define usb_actconfig_attr(field, multiplier, format_string)		\
-usb_actconfig_show(field, multiplier, format_string)			\
-static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
-
-usb_actconfig_attr (bNumInterfaces, 1, "%2d\n")
-usb_actconfig_attr (bmAttributes, 1, "%2x\n")
-usb_actconfig_attr (bMaxPower, 2, "%3dmA\n")
-
-/* configuration value is always present, and r/w */
-usb_actconfig_show(bConfigurationValue, 1, "%u\n");
-
-static ssize_t
-set_bConfigurationValue (struct device *dev, const char *buf, size_t count)
-{
-	struct usb_device	*udev = udev = to_usb_device (dev);
-	int			config, value;
-
-	if (sscanf (buf, "%u", &config) != 1 || config > 255)
-		return -EINVAL;
-	down(&udev->serialize);
-	value = usb_set_configuration (udev, config);
-	up(&udev->serialize);
-	return (value < 0) ? value : count;
-}
-
-static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, 
-		show_bConfigurationValue, set_bConfigurationValue);
-
-/* String fields */
-#define usb_string_attr(name, field)		\
-static ssize_t  show_##name(struct device *dev, char *buf)		\
-{									\
-	struct usb_device *udev;					\
-	int len;							\
-									\
-	udev = to_usb_device (dev);					\
-	len = usb_string(udev, udev->descriptor.field, buf, PAGE_SIZE);	\
-	if (len < 0)							\
-		return 0;						\
-	buf[len] = '\n';						\
-	buf[len+1] = 0;							\
-	return len+1;							\
-}									\
-static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
-
-usb_string_attr(product, iProduct);
-usb_string_attr(manufacturer, iManufacturer);
-usb_string_attr(serial, iSerialNumber);
-
-static ssize_t
-show_speed (struct device *dev, char *buf)
-{
-	struct usb_device *udev;
-	char *speed;
-
-	udev = to_usb_device (dev);
-
-	switch (udev->speed) {
-	case USB_SPEED_LOW:
-		speed = "1.5";
-		break;
-	case USB_SPEED_UNKNOWN:
-	case USB_SPEED_FULL:
-		speed = "12";
-		break;
-	case USB_SPEED_HIGH:
-		speed = "480";
-		break;
-	default:
-		speed = "unknown";
-	}
-	return sprintf (buf, "%s\n", speed);
-}
-static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL);
-
-static ssize_t
-show_devnum (struct device *dev, char *buf)
-{
-	struct usb_device *udev;
-
-	udev = to_usb_device (dev);
-	return sprintf (buf, "%d\n", udev->devnum);
-}
-static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL);
-
-static ssize_t
-show_version (struct device *dev, char *buf)
-{
-	struct usb_device *udev;
-
-	udev = to_usb_device (dev);
-	return sprintf (buf, "%2x.%02x\n", udev->descriptor.bcdUSB >> 8, 
-			udev->descriptor.bcdUSB & 0xff);
-}
-static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
-
-static ssize_t
-show_maxchild (struct device *dev, char *buf)
-{
-	struct usb_device *udev;
-
-	udev = to_usb_device (dev);
-	return sprintf (buf, "%d\n", udev->maxchild);
-}
-static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
-
-/* Descriptor fields */
-#define usb_descriptor_attr(field, format_string)			\
-static ssize_t								\
-show_##field (struct device *dev, char *buf)				\
-{									\
-	struct usb_device *udev;					\
-									\
-	udev = to_usb_device (dev);					\
-	return sprintf (buf, format_string, udev->descriptor.field);	\
-}									\
-static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
-
-usb_descriptor_attr (idVendor, "%04x\n")
-usb_descriptor_attr (idProduct, "%04x\n")
-usb_descriptor_attr (bcdDevice, "%04x\n")
-usb_descriptor_attr (bDeviceClass, "%02x\n")
-usb_descriptor_attr (bDeviceSubClass, "%02x\n")
-usb_descriptor_attr (bDeviceProtocol, "%02x\n")
-usb_descriptor_attr (bNumConfigurations, "%d\n")
-
-
-void usb_create_driverfs_dev_files (struct usb_device *udev)
-{
-	struct device *dev = &udev->dev;
-
-	/* current configuration's attributes */
-	device_create_file (dev, &dev_attr_bNumInterfaces);
-	device_create_file (dev, &dev_attr_bConfigurationValue);
-	device_create_file (dev, &dev_attr_bmAttributes);
-	device_create_file (dev, &dev_attr_bMaxPower);
-
-	/* device attributes */
-	device_create_file (dev, &dev_attr_idVendor);
-	device_create_file (dev, &dev_attr_idProduct);
-	device_create_file (dev, &dev_attr_bcdDevice);
-	device_create_file (dev, &dev_attr_bDeviceClass);
-	device_create_file (dev, &dev_attr_bDeviceSubClass);
-	device_create_file (dev, &dev_attr_bDeviceProtocol);
-	device_create_file (dev, &dev_attr_bNumConfigurations);
-
-	/* speed varies depending on how you connect the device */
-	device_create_file (dev, &dev_attr_speed);
-	// FIXME iff there are other speed configs, show how many
-
-	if (udev->descriptor.iManufacturer)
-		device_create_file (dev, &dev_attr_manufacturer);
-	if (udev->descriptor.iProduct)
-		device_create_file (dev, &dev_attr_product);
-	if (udev->descriptor.iSerialNumber)
-		device_create_file (dev, &dev_attr_serial);
-
-	device_create_file (dev, &dev_attr_devnum);
-	device_create_file (dev, &dev_attr_version);
-	device_create_file (dev, &dev_attr_maxchild);
-}
-
-/* Interface fields */
-#define usb_intf_attr(field, format_string)				\
-static ssize_t								\
-show_##field (struct device *dev, char *buf)				\
-{									\
-	struct usb_interface *intf = to_usb_interface (dev);		\
-									\
-	return sprintf (buf, format_string, intf->cur_altsetting->desc.field); \
-}									\
-static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
-
-usb_intf_attr (bInterfaceNumber, "%02x\n")
-usb_intf_attr (bAlternateSetting, "%2d\n")
-usb_intf_attr (bNumEndpoints, "%02x\n")
-usb_intf_attr (bInterfaceClass, "%02x\n")
-usb_intf_attr (bInterfaceSubClass, "%02x\n")
-usb_intf_attr (bInterfaceProtocol, "%02x\n")
-usb_intf_attr (iInterface, "%02x\n")
-
-void usb_create_driverfs_intf_files (struct usb_interface *intf)
-{
-	device_create_file (&intf->dev, &dev_attr_bInterfaceNumber);
-	device_create_file (&intf->dev, &dev_attr_bAlternateSetting);
-	device_create_file (&intf->dev, &dev_attr_bNumEndpoints);
-	device_create_file (&intf->dev, &dev_attr_bInterfaceClass);
-	device_create_file (&intf->dev, &dev_attr_bInterfaceSubClass);
-	device_create_file (&intf->dev, &dev_attr_bInterfaceProtocol);
-	device_create_file (&intf->dev, &dev_attr_iInterface);
-}
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/core/hcd.h	2004-05-25 21:38:09 -07:00
@@ -243,13 +243,13 @@
 extern struct usb_device *usb_alloc_dev(struct usb_device *parent,
 					struct usb_bus *, unsigned port);
 extern int usb_new_device(struct usb_device *dev);
-extern void usb_choose_address(struct usb_device *dev);
 extern void usb_disconnect(struct usb_device **);
+extern void usb_choose_address(struct usb_device *dev);
+extern void usb_release_address(struct usb_device *dev);
 
 /* exported to hub driver ONLY to support usb_reset_device () */
 extern int usb_get_configuration(struct usb_device *dev);
 extern void usb_destroy_configuration(struct usb_device *dev);
-extern int usb_set_address(struct usb_device *dev);
 
 /* use these only before the device's address has been set */
 #define usb_snddefctrl(dev)		((PIPE_CONTROL << 30))
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/core/hub.c	2004-05-25 21:38:09 -07:00
@@ -65,15 +65,15 @@
 #endif
 
 /* for dev_info, dev_dbg, etc */
-static inline struct device *hubdev (struct usb_device *dev)
+static inline struct device *hubdev (struct usb_device *hdev)
 {
-	return &dev->actconfig->interface[0]->dev;
+	return &hdev->actconfig->interface[0]->dev;
 }
 
 /* USB 2.0 spec Section 11.24.4.5 */
-static int get_hub_descriptor(struct usb_device *dev, void *data, int size)
+static int get_hub_descriptor(struct usb_device *hdev, void *data, int size)
 {
-	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+	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);
 }
@@ -81,27 +81,27 @@
 /*
  * USB 2.0 spec Section 11.24.2.1
  */
-static int clear_hub_feature(struct usb_device *dev, int feature)
+static int clear_hub_feature(struct usb_device *hdev, int feature)
 {
-	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+	return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
 		USB_REQ_CLEAR_FEATURE, USB_RT_HUB, feature, 0, NULL, 0, HZ);
 }
 
 /*
  * USB 2.0 spec Section 11.24.2.2
  */
-static int clear_port_feature(struct usb_device *dev, int port, int feature)
+static int clear_port_feature(struct usb_device *hdev, int port, int feature)
 {
-	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+	return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
 		USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
 }
 
 /*
  * USB 2.0 spec Section 11.24.2.13
  */
-static int set_port_feature(struct usb_device *dev, int port, int feature)
+static int set_port_feature(struct usb_device *hdev, int port, int feature)
 {
-	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+	return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
 		USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
 }
 
@@ -110,16 +110,15 @@
  * for info about using port indicators
  */
 static void set_port_led(
-	struct usb_device *dev,
-	struct usb_hub *hub,
+	struct usb_device *hdev,
 	int port,
 	int selector
 )
 {
-	int status = set_port_feature(dev, (selector << 8) | port,
+	int status = set_port_feature(hdev, (selector << 8) | port,
 			USB_PORT_FEAT_INDICATOR);
 	if (status < 0)
-		dev_dbg (&hub->intf->dev,
+		dev_dbg (hubdev (hdev),
 			"port %d indicator %s status %d\n",
 			port,
 			({ char *s; switch (selector) {
@@ -137,12 +136,12 @@
 static void led_work (void *__hub)
 {
 	struct usb_hub		*hub = __hub;
-	struct usb_device	*dev = interface_to_usbdev (hub->intf);
+	struct usb_device	*hdev = interface_to_usbdev (hub->intf);
 	unsigned		i;
 	unsigned		changed = 0;
 	int			cursor = -1;
 
-	if (dev->state != USB_STATE_CONFIGURED)
+	if (hdev->state != USB_STATE_CONFIGURED)
 		return;
 
 	for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
@@ -189,13 +188,13 @@
 		}
 		if (selector != HUB_LED_AUTO)
 			changed = 1;
-		set_port_led(dev, hub, i + 1, selector);
+		set_port_led(hdev, i + 1, selector);
 		hub->indicator[i] = mode;
 	}
 	if (!changed && blinkenlights) {
 		cursor++;
 		cursor %= hub->descriptor->bNbrPorts;
-		set_port_led(dev, hub, cursor + 1, HUB_LED_GREEN);
+		set_port_led(hdev, cursor + 1, HUB_LED_GREEN);
 		hub->indicator[cursor] = INDICATOR_CYCLE;
 		changed++;
 	}
@@ -206,10 +205,10 @@
 /*
  * USB 2.0 spec Section 11.24.2.6
  */
-static int get_hub_status(struct usb_device *dev,
+static int get_hub_status(struct usb_device *hdev,
 		struct usb_hub_status *data)
 {
-	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+	return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
 		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
 		data, sizeof(*data), HZ * USB_CTRL_GET_TIMEOUT);
 }
@@ -217,10 +216,10 @@
 /*
  * USB 2.0 spec Section 11.24.2.7
  */
-static int get_port_status(struct usb_device *dev, int port,
+static int get_port_status(struct usb_device *hdev, int port,
 		struct usb_port_status *data)
 {
-	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+	return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
 		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
 		data, sizeof(*data), HZ * USB_CTRL_GET_TIMEOUT);
 }
@@ -278,9 +277,9 @@
 
 /* USB 2.0 spec Section 11.24.2.3 */
 static inline int
-hub_clear_tt_buffer (struct usb_device *hub, u16 devinfo, u16 tt)
+hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
 {
-	return usb_control_msg (hub, usb_rcvctrlpipe (hub, 0),
+	return usb_control_msg (hdev, usb_rcvctrlpipe (hdev, 0),
 		HUB_CLEAR_TT_BUFFER, USB_RT_PORT,
 		devinfo, tt, 0, 0, HZ);
 }
@@ -300,7 +299,7 @@
 	while (!list_empty (&hub->tt.clear_list)) {
 		struct list_head	*temp;
 		struct usb_tt_clear	*clear;
-		struct usb_device	*dev;
+		struct usb_device	*hdev;
 		int			status;
 
 		temp = hub->tt.clear_list.next;
@@ -309,12 +308,13 @@
 
 		/* drop lock so HCD can concurrently report other TT errors */
 		spin_unlock_irqrestore (&hub->tt.lock, flags);
-		dev = interface_to_usbdev (hub->intf);
-		status = hub_clear_tt_buffer (dev, clear->devinfo, clear->tt);
+		hdev = interface_to_usbdev (hub->intf);
+		status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt);
 		spin_lock_irqsave (&hub->tt.lock, flags);
 
 		if (status)
-			dev_err (&dev->dev, "clear tt %d (%04x) error %d\n",
+			dev_err (&hdev->dev,
+				"clear tt %d (%04x) error %d\n",
 				clear->tt, clear->devinfo, status);
 		kfree (clear);
 	}
@@ -334,9 +334,9 @@
  * It may not be possible for that hub to handle additional full (or low)
  * speed transactions until that state is fully cleared out.
  */
-void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe)
+void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
 {
-	struct usb_tt		*tt = dev->tt;
+	struct usb_tt		*tt = udev->tt;
 	unsigned long		flags;
 	struct usb_tt_clear	*clear;
 
@@ -345,15 +345,15 @@
 	 * there can be many TTs per hub).  even if they're uncommon.
 	 */
 	if ((clear = kmalloc (sizeof *clear, SLAB_ATOMIC)) == 0) {
-		dev_err (&dev->dev, "can't save CLEAR_TT_BUFFER state\n");
+		dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
 		/* FIXME recover somehow ... RESET_TT? */
 		return;
 	}
 
 	/* info that CLEAR_TT_BUFFER needs */
-	clear->tt = tt->multi ? dev->ttport : 1;
+	clear->tt = tt->multi ? udev->ttport : 1;
 	clear->devinfo = usb_pipeendpoint (pipe);
-	clear->devinfo |= dev->devnum << 4;
+	clear->devinfo |= udev->devnum << 4;
 	clear->devinfo |= usb_pipecontrol (pipe)
 			? (USB_ENDPOINT_XFER_CONTROL << 11)
 			: (USB_ENDPOINT_XFER_BULK << 11);
@@ -369,15 +369,15 @@
 
 static void hub_power_on(struct usb_hub *hub)
 {
-	struct usb_device *dev;
+	struct usb_device *hdev;
 	int i;
 
 	/* if hub supports power switching, enable power on each port */
 	if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) < 2) {
 		dev_dbg(&hub->intf->dev, "enabling power on all ports\n");
-		dev = interface_to_usbdev(hub->intf);
+		hdev = interface_to_usbdev(hub->intf);
 		for (i = 0; i < hub->descriptor->bNbrPorts; i++)
-			set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
+			set_port_feature(hdev, i + 1, USB_PORT_FEAT_POWER);
 	}
 
 	/* Wait for power to be enabled */
@@ -387,12 +387,12 @@
 static int hub_hub_status(struct usb_hub *hub,
 		u16 *status, u16 *change)
 {
-	struct usb_device *dev = interface_to_usbdev (hub->intf);
+	struct usb_device *hdev = interface_to_usbdev (hub->intf);
 	int ret;
 
-	ret = get_hub_status(dev, &hub->status->hub);
+	ret = get_hub_status(hdev, &hub->status->hub);
 	if (ret < 0)
-		dev_err (hubdev (dev),
+		dev_err (&hub->intf->dev,
 			"%s failed (err = %d)\n", __FUNCTION__, ret);
 	else {
 		*status = le16_to_cpu(hub->status->hub.wHubStatus);
@@ -405,14 +405,14 @@
 static int hub_configure(struct usb_hub *hub,
 	struct usb_endpoint_descriptor *endpoint)
 {
-	struct usb_device *dev = interface_to_usbdev (hub->intf);
-	struct device *hub_dev;
+	struct usb_device *hdev = interface_to_usbdev (hub->intf);
+	struct device *hub_dev = &hub->intf->dev;
 	u16 hubstatus, hubchange;
 	unsigned int pipe;
 	int maxp, ret;
 	char *message;
 
-	hub->buffer = usb_buffer_alloc(dev, sizeof(*hub->buffer), GFP_KERNEL,
+	hub->buffer = usb_buffer_alloc(hdev, sizeof(*hub->buffer), GFP_KERNEL,
 			&hub->buffer_dma);
 	if (!hub->buffer) {
 		message = "can't allocate hub irq buffer";
@@ -438,7 +438,7 @@
 	 * hub->descriptor can handle USB_MAXCHILDREN ports,
 	 * but the hub can/will return fewer bytes here.
 	 */
-	ret = get_hub_descriptor(dev, hub->descriptor,
+	ret = get_hub_descriptor(hdev, hub->descriptor,
 			sizeof(*hub->descriptor));
 	if (ret < 0) {
 		message = "can't read hub descriptor";
@@ -449,10 +449,9 @@
 		goto fail;
 	}
 
-	hub_dev = hubdev(dev);
-	dev->maxchild = hub->descriptor->bNbrPorts;
-	dev_info (hub_dev, "%d port%s detected\n", dev->maxchild,
-		(dev->maxchild == 1) ? "" : "s");
+	hdev->maxchild = hub->descriptor->bNbrPorts;
+	dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild,
+		(hdev->maxchild == 1) ? "" : "s");
 
 	le16_to_cpus(&hub->descriptor->wHubCharacteristics);
 
@@ -460,11 +459,11 @@
 		int	i;
 		char	portstr [USB_MAXCHILDREN + 1];
 
-		for (i = 0; i < dev->maxchild; i++)
+		for (i = 0; i < hdev->maxchild; i++)
 			portstr[i] = hub->descriptor->DeviceRemovable
 				    [((i + 1) / 8)] & (1 << ((i + 1) % 8))
 				? 'F' : 'R';
-		portstr[dev->maxchild] = 0;
+		portstr[hdev->maxchild] = 0;
 		dev_dbg(hub_dev, "compound device; port removable status: %s\n", portstr);
 	} else
 		dev_dbg(hub_dev, "standalone hub\n");
@@ -498,32 +497,32 @@
 	spin_lock_init (&hub->tt.lock);
 	INIT_LIST_HEAD (&hub->tt.clear_list);
 	INIT_WORK (&hub->tt.kevent, hub_tt_kevent, hub);
-	switch (dev->descriptor.bDeviceProtocol) {
+	switch (hdev->descriptor.bDeviceProtocol) {
 		case 0:
 			break;
 		case 1:
 			dev_dbg(hub_dev, "Single TT\n");
-			hub->tt.hub = dev;
+			hub->tt.hub = hdev;
 			break;
 		case 2:
-			ret = usb_set_interface(dev, 0, 1);
+			ret = usb_set_interface(hdev, 0, 1);
 			if (ret == 0) {
 				dev_dbg(hub_dev, "TT per port\n");
 				hub->tt.multi = 1;
 			} else
 				dev_err(hub_dev, "Using single TT (err %d)\n",
 					ret);
-			hub->tt.hub = dev;
+			hub->tt.hub = hdev;
 			break;
 		default:
 			dev_dbg(hub_dev, "Unrecognized hub protocol %d\n",
-				dev->descriptor.bDeviceProtocol);
+				hdev->descriptor.bDeviceProtocol);
 			break;
 	}
 
 	switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) {
 		case 0x00:
-			if (dev->descriptor.bDeviceProtocol != 0)
+			if (hdev->descriptor.bDeviceProtocol != 0)
 				dev_dbg(hub_dev, "TT requires at most 8 FS bit times\n");
 			break;
 		case 0x20:
@@ -549,9 +548,9 @@
 	/* power budgeting mostly matters with bus-powered hubs,
 	 * and battery-powered root hubs (may provide just 8 mA).
 	 */
-	ret = usb_get_status(dev, USB_RECIP_DEVICE, 0, &hubstatus);
+	ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus);
 	if (ret < 0) {
-		message = "can't get hubdev status";
+		message = "can't get hub status";
 		goto fail;
 	}
 	cpu_to_le16s(&hubstatus);
@@ -572,7 +571,7 @@
 	}
 
 	/* local power status reports aren't always correct */
-	if (dev->actconfig->desc.bmAttributes & USB_CONFIG_ATT_SELFPOWER)
+	if (hdev->actconfig->desc.bmAttributes & USB_CONFIG_ATT_SELFPOWER)
 		dev_dbg(hub_dev, "local power source is %s\n",
 			(hubstatus & HUB_STATUS_LOCAL_POWER)
 			? "lost (inactive)" : "good");
@@ -582,8 +581,8 @@
 			(hubstatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
 
 	/* Start the interrupt endpoint */
-	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
-	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+	pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress);
+	maxp = usb_maxpacket(hdev, pipe, usb_pipeout(pipe));
 
 	if (maxp > sizeof(*hub->buffer))
 		maxp = sizeof(*hub->buffer);
@@ -595,7 +594,7 @@
 		goto fail;
 	}
 
-	usb_fill_int_urb(hub->urb, dev, pipe, *hub->buffer, maxp, hub_irq,
+	usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,
 		hub, endpoint->bInterval);
 	hub->urb->transfer_dma = hub->buffer_dma;
 	hub->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -611,7 +610,7 @@
 
 	/* maybe start cycling the hub leds */
 	if (hub->has_indicators && blinkenlights) {
-		set_port_led(dev, hub, 1, HUB_LED_GREEN);
+		set_port_led(hdev, 1, HUB_LED_GREEN);
 		hub->indicator [0] = INDICATOR_CYCLE;
 		schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
 	}
@@ -621,7 +620,7 @@
 	return 0;
 
 fail:
-	dev_err (&hub->intf->dev, "config failed, %s (err %d)\n",
+	dev_err (hub_dev, "config failed, %s (err %d)\n",
 			message, ret);
 	/* hub_disconnect() frees urb and descriptor */
 	return ret;
@@ -693,19 +692,21 @@
 {
 	struct usb_host_interface *desc;
 	struct usb_endpoint_descriptor *endpoint;
-	struct usb_device *dev;
+	struct usb_device *hdev;
 	struct usb_hub *hub;
+	struct device *hub_dev;
 	unsigned long flags;
 
 	desc = intf->cur_altsetting;
-	dev = interface_to_usbdev(intf);
+	hdev = interface_to_usbdev(intf);
+	hub_dev = &intf->dev;
 
 	/* Some hubs have a subclass of 1, which AFAICT according to the */
 	/*  specs is not defined, but it works */
 	if ((desc->desc.bInterfaceSubClass != 0) &&
 	    (desc->desc.bInterfaceSubClass != 1)) {
 descriptor_error:
-		dev_err (&intf->dev, "bad descriptor, ignoring hub\n");
+		dev_err (hub_dev, "bad descriptor, ignoring hub\n");
 		return -EIO;
 	}
 
@@ -729,11 +730,11 @@
 	}
 
 	/* We found a hub */
-	dev_info (hubdev (dev), "USB hub found\n");
+	dev_info (hub_dev, "USB hub found\n");
 
 	hub = kmalloc(sizeof(*hub), GFP_KERNEL);
 	if (!hub) {
-		dev_dbg (hubdev(dev), "couldn't kmalloc hub struct\n");
+		dev_dbg (hub_dev, "couldn't kmalloc hub struct\n");
 		return -ENOMEM;
 	}
 
@@ -752,7 +753,7 @@
 
 	usb_set_intfdata (intf, hub);
 
-	if (dev->speed == USB_SPEED_HIGH)
+	if (hdev->speed == USB_SPEED_HIGH)
 		highspeed_hubs++;
 
 	if (hub_configure(hub, endpoint) >= 0)
@@ -765,7 +766,7 @@
 static int
 hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
 {
-	struct usb_device *hub = interface_to_usbdev (intf);
+	struct usb_device *hdev = interface_to_usbdev (intf);
 
 	/* assert ifno == 0 (part of hub spec) */
 	switch (code) {
@@ -775,16 +776,16 @@
 		int i;
 
 		spin_lock_irqsave(&hub_event_lock, flags);
-		if (hub->devnum <= 0)
+		if (hdev->devnum <= 0)
 			info->nports = 0;
 		else {
-			info->nports = hub->maxchild;
+			info->nports = hdev->maxchild;
 			for (i = 0; i < info->nports; i++) {
-				if (hub->children[i] == NULL)
+				if (hdev->children[i] == NULL)
 					info->port[i] = 0;
 				else
 					info->port[i] =
-						hub->children[i]->devnum;
+						hdev->children[i]->devnum;
 			}
 		}
 		spin_unlock_irqrestore(&hub_event_lock, flags);
@@ -799,13 +800,13 @@
 
 static int hub_reset(struct usb_hub *hub)
 {
-	struct usb_device *dev = interface_to_usbdev(hub->intf);
+	struct usb_device *hdev = interface_to_usbdev(hub->intf);
 	int i;
 
 	/* Disconnect any attached devices */
 	for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
-		if (dev->children[i])
-			usb_disconnect(&dev->children[i]);
+		if (hdev->children[i])
+			usb_disconnect(&hdev->children[i]);
 	}
 
 	/* Attempt to reset the hub */
@@ -814,10 +815,10 @@
 	else
 		return -1;
 
-	if (usb_reset_device(dev))
+	if (usb_reset_device(hdev))
 		return -1;
 
-	hub->urb->dev = dev;                                                    
+	hub->urb->dev = hdev;                                                    
 	if (usb_submit_urb(hub->urb, GFP_KERNEL))
 		return -1;
 
@@ -826,36 +827,36 @@
 	return 0;
 }
 
-static void hub_start_disconnect(struct usb_device *dev)
+static void hub_start_disconnect(struct usb_device *hdev)
 {
-	struct usb_device *parent = dev->parent;
+	struct usb_device *parent = hdev->parent;
 	int i;
 
 	/* Find the device pointer to disconnect */
 	if (parent) {
 		for (i = 0; i < parent->maxchild; i++) {
-			if (parent->children[i] == dev) {
+			if (parent->children[i] == hdev) {
 				usb_disconnect(&parent->children[i]);
 				return;
 			}
 		}
 	}
 
-	dev_err(&dev->dev, "cannot disconnect hub!\n");
+	dev_err(&hdev->dev, "cannot disconnect hub!\n");
 }
 
-static int hub_port_status(struct usb_device *dev, int port,
+static int hub_port_status(struct usb_device *hdev, int port,
 			       u16 *status, u16 *change)
 {
-	struct usb_hub *hub = usb_get_intfdata(dev->actconfig->interface[0]);
+	struct usb_hub *hub = usb_get_intfdata(hdev->actconfig->interface[0]);
 	int ret;
 
 	if (!hub)
 		return -ENODEV;
 
-	ret = get_port_status(dev, port + 1, &hub->status->port);
+	ret = get_port_status(hdev, port + 1, &hub->status->port);
 	if (ret < 0)
-		dev_err (hubdev (dev),
+		dev_err (&hub->intf->dev,
 			"%s failed (err = %d)\n", __FUNCTION__, ret);
 	else {
 		*status = le16_to_cpu(hub->status->port.wPortStatus);
@@ -876,8 +877,8 @@
 #define HUB_RESET_TIMEOUT	500
 
 /* return: -1 on error, 0 on success, 1 on disconnect.  */
-static int hub_port_wait_reset(struct usb_device *hub, int port,
-				struct usb_device *dev, unsigned int delay)
+static int hub_port_wait_reset(struct usb_device *hdev, int port,
+				struct usb_device *udev, unsigned int delay)
 {
 	int delay_time, ret;
 	u16 portstatus;
@@ -890,7 +891,7 @@
 		msleep(delay);
 
 		/* read and decode port status */
-		ret = hub_port_status(hub, port, &portstatus, &portchange);
+		ret = hub_port_status(hdev, port, &portstatus, &portchange);
 		if (ret < 0) {
 			return -1;
 		}
@@ -907,11 +908,11 @@
 		if (!(portstatus & USB_PORT_STAT_RESET) &&
 		    (portstatus & USB_PORT_STAT_ENABLE)) {
 			if (portstatus & USB_PORT_STAT_HIGH_SPEED)
-				dev->speed = USB_SPEED_HIGH;
+				udev->speed = USB_SPEED_HIGH;
 			else if (portstatus & USB_PORT_STAT_LOW_SPEED)
-				dev->speed = USB_SPEED_LOW;
+				udev->speed = USB_SPEED_LOW;
 			else
-				dev->speed = USB_SPEED_FULL;
+				udev->speed = USB_SPEED_FULL;
 			return 0;
 		}
 
@@ -919,7 +920,7 @@
 		if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
 			delay = HUB_LONG_RESET_TIME;
 
-		dev_dbg (hubdev (hub),
+		dev_dbg (hubdev (hdev),
 			"port %d not reset yet, waiting %dms\n",
 			port + 1, delay);
 	}
@@ -928,46 +929,47 @@
 }
 
 /* return: -1 on error, 0 on success, 1 on disconnect.  */
-static int hub_port_reset(struct usb_device *hub, int port,
-				struct usb_device *dev, unsigned int delay)
+static int hub_port_reset(struct usb_device *hdev, int port,
+				struct usb_device *udev, unsigned int delay)
 {
 	int i, status;
+	struct device *hub_dev = hubdev (hdev);
 
 	/* Reset the port */
 	for (i = 0; i < PORT_RESET_TRIES; i++) {
-		set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET);
+		set_port_feature(hdev, port + 1, USB_PORT_FEAT_RESET);
 
 		/* return on disconnect or reset */
-		status = hub_port_wait_reset(hub, port, dev, delay);
+		status = hub_port_wait_reset(hdev, port, udev, delay);
 		if (status != -1) {
-			clear_port_feature(hub,
+			clear_port_feature(hdev,
 				port + 1, USB_PORT_FEAT_C_RESET);
-			dev->state = status
+			udev->state = status
 					? USB_STATE_NOTATTACHED
 					: USB_STATE_DEFAULT;
 			return status;
 		}
 
-		dev_dbg (hubdev (hub),
+		dev_dbg (hub_dev,
 			"port %d not enabled, trying reset again...\n",
 			port + 1);
 		delay = HUB_LONG_RESET_TIME;
 	}
 
-	dev_err (hubdev (hub),
+	dev_err (hub_dev,
 		"Cannot enable port %i.  Maybe the USB cable is bad?\n",
 		port + 1);
 
 	return -1;
 }
 
-static int hub_port_disable(struct usb_device *hub, int port)
+static int hub_port_disable(struct usb_device *hdev, int port)
 {
 	int ret;
 
-	ret = clear_port_feature(hub, port + 1, USB_PORT_FEAT_ENABLE);
+	ret = clear_port_feature(hdev, port + 1, USB_PORT_FEAT_ENABLE);
 	if (ret)
-		dev_err(hubdev(hub), "cannot disable port %d (err = %d)\n",
+		dev_err(hubdev(hdev), "cannot disable port %d (err = %d)\n",
 			port + 1, ret);
 
 	return ret;
@@ -992,7 +994,7 @@
 #define HUB_DEBOUNCE_STABLE	  4
 
 /* return: -1 on error, 0 on success, 1 on disconnect.  */
-static int hub_port_debounce(struct usb_device *hub, int port)
+static int hub_port_debounce(struct usb_device *hdev, int port)
 {
 	int ret;
 	int delay_time, stable_count;
@@ -1004,7 +1006,7 @@
 	for (delay_time = 0; delay_time < HUB_DEBOUNCE_TIMEOUT; delay_time += HUB_DEBOUNCE_STEP) {
 		msleep(HUB_DEBOUNCE_STEP);
 
-		ret = hub_port_status(hub, port, &portstatus, &portchange);
+		ret = hub_port_status(hdev, port, &portstatus, &portchange);
 		if (ret < 0)
 			return -1;
 
@@ -1019,17 +1021,34 @@
 		connection = portstatus & USB_PORT_STAT_CONNECTION;
 
 		if ((portchange & USB_PORT_STAT_C_CONNECTION)) {
-			clear_port_feature(hub, port+1, USB_PORT_FEAT_C_CONNECTION);
+			clear_port_feature(hdev, port+1, USB_PORT_FEAT_C_CONNECTION);
 		}
 	}
 
-	dev_dbg (hubdev (hub),
+	dev_dbg (hubdev (hdev),
 		"debounce: port %d: delay %dms stable %d status 0x%x\n",
 		port + 1, delay_time, stable_count, portstatus);
 
 	return ((portstatus&USB_PORT_STAT_CONNECTION)) ? 0 : 1;
 }
 
+static int hub_set_address(struct usb_device *udev)
+{
+	int retval;
+
+	if (udev->devnum == 0)
+		return -EINVAL;
+	if (udev->state != USB_STATE_DEFAULT &&
+			udev->state != USB_STATE_ADDRESS)
+		return -EINVAL;
+	retval = usb_control_msg(udev, usb_snddefctrl(udev),
+		USB_REQ_SET_ADDRESS, 0, udev->devnum, 0,
+		NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+	if (retval == 0)
+		udev->state = USB_STATE_ADDRESS;
+	return retval;
+}
+
 /* reset device, (re)assign address, get device descriptor.
  * device connection is stable, no more debouncing needed.
  * returns device in USB_STATE_ADDRESS, except on error.
@@ -1039,18 +1058,18 @@
  * config changes and disconnect processing.
  */
 static int
-hub_port_init (struct usb_device *hub, struct usb_device *dev, int port)
+hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port)
 {
 	static DECLARE_MUTEX(usb_address0_sem);
 
 	int			i, j, retval = -ENODEV;
 	unsigned		delay = HUB_SHORT_RESET_TIME;
-	enum usb_device_speed	oldspeed = dev->speed;
+	enum usb_device_speed	oldspeed = udev->speed;
 
 	/* root hub ports have a slightly longer reset period
 	 * (from USB 2.0 spec, section 7.1.7.5)
 	 */
-	if (!hub->parent)
+	if (!hdev->parent)
 		delay = HUB_ROOT_RESET_TIME;
 
 	/* Some low speed devices have problems with the quick delay, so */
@@ -1061,7 +1080,7 @@
 	down(&usb_address0_sem);
 
 	/* Reset the device; full speed may morph to high speed */
-	switch (hub_port_reset(hub, port, dev, delay)) {
+	switch (hub_port_reset(hdev, port, udev, delay)) {
 	case 0:			/* success, speed is known */
 		break;
 	case 1:			/* disconnect, give to companion */
@@ -1070,15 +1089,15 @@
 	default:		/* error */
 		goto fail;
 	}
-	if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != dev->speed) {
-		dev_dbg(&dev->dev, "device reset changed speed!\n");
+	if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) {
+		dev_dbg(&udev->dev, "device reset changed speed!\n");
 		goto fail;
 	}
   
 	/* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
 	 * it's fixed size except for full speed devices.
 	 */
-	switch (dev->speed) {
+	switch (udev->speed) {
 	case USB_SPEED_HIGH:		/* fixed at 64 */
 		i = 64;
 		break;
@@ -1094,43 +1113,43 @@
 	default:
 		goto fail;
 	}
-	dev->epmaxpacketin [0] = i;
-	dev->epmaxpacketout[0] = i;
+	udev->epmaxpacketin [0] = i;
+	udev->epmaxpacketout[0] = i;
  
 	/* set the address */
-	if (dev->devnum <= 0) {
-		usb_choose_address(dev);
-		if (dev->devnum <= 0)
+	if (udev->devnum <= 0) {
+		usb_choose_address(udev);
+		if (udev->devnum <= 0)
 			goto fail;
 
 		/* Set up TT records, if needed  */
-		if (hub->tt) {
-			dev->tt = hub->tt;
-			dev->ttport = hub->ttport;
-		} else if (dev->speed != USB_SPEED_HIGH
-				&& hub->speed == USB_SPEED_HIGH) {
-			struct usb_hub	*hubstate;
+		if (hdev->tt) {
+			udev->tt = hdev->tt;
+			udev->ttport = hdev->ttport;
+		} else if (udev->speed != USB_SPEED_HIGH
+				&& hdev->speed == USB_SPEED_HIGH) {
+			struct usb_hub	*hub;
  
-			hubstate = usb_get_intfdata (hub->actconfig
+			hub = usb_get_intfdata (hdev->actconfig
 							->interface[0]);
-			dev->tt = &hubstate->tt;
-			dev->ttport = port + 1;
+			udev->tt = &hub->tt;
+			udev->ttport = port + 1;
 		}
 
 		/* force the right log message (below) at low speed */
 		oldspeed = USB_SPEED_UNKNOWN;
 	}
  
-	dev_info (&dev->dev,
+	dev_info (&udev->dev,
 			"%s %s speed USB device using address %d\n",
 			(oldspeed == USB_SPEED_UNKNOWN) ? "new" : "reset",
-			({ char *speed; switch (dev->speed) {
+			({ char *speed; switch (udev->speed) {
 			case USB_SPEED_LOW:	speed = "low";	break;
 			case USB_SPEED_FULL:	speed = "full";	break;
 			case USB_SPEED_HIGH:	speed = "high";	break;
 			default: 		speed = "?";	break;
 			}; speed;}),
-			dev->devnum);
+			udev->devnum);
  
 	/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
 	 * Because device hardware and firmware is sometimes buggy in
@@ -1143,20 +1162,19 @@
 	 */
 	for (i = 0; i < GET_DESCRIPTOR_TRIES; ++i) {
 		for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
-			retval = usb_set_address(dev);
+			retval = hub_set_address(udev);
 			if (retval >= 0)
 				break;
 			msleep(200);
 		}
 		if (retval < 0) {
-			dev_err(&dev->dev,
+			dev_err(&udev->dev,
 				"device not accepting address %d, error %d\n",
-				dev->devnum, retval);
+				udev->devnum, retval);
  fail:
-			hub_port_disable(hub, port);
-			clear_bit(dev->devnum, dev->bus->devmap.devicemap);
-			dev->devnum = -1;
-			usb_put_dev(dev);
+			hub_port_disable(hdev, port);
+			usb_release_address(udev);
+			usb_put_dev(udev);
 			up(&usb_address0_sem);
 			return retval;
 		}
@@ -1166,31 +1184,31 @@
 		 *  - read ep0 maxpacket even for high and low speed,
   		 */
 		msleep(10);
-		retval = usb_get_device_descriptor(dev, 8);
+		retval = usb_get_device_descriptor(udev, 8);
 		if (retval >= 8)
 			break;
 		msleep(100);
 	}
 	if (retval != 8) {
-		dev_err(&dev->dev, "device descriptor read/%s, error %d\n",
+		dev_err(&udev->dev, "device descriptor read/%s, error %d\n",
 				"8", retval);
 		if (retval >= 0)
 			retval = -EMSGSIZE;
 		goto fail;
 	}
-	if (dev->speed == USB_SPEED_FULL
-			&& (dev->epmaxpacketin [0]
-				!= dev->descriptor.bMaxPacketSize0)) {
-		usb_disable_endpoint(dev, 0);
-		usb_endpoint_running(dev, 0, 1);
-		usb_endpoint_running(dev, 0, 0);
-		dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;
-		dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
+	if (udev->speed == USB_SPEED_FULL
+			&& (udev->epmaxpacketin [0]
+				!= udev->descriptor.bMaxPacketSize0)) {
+		usb_disable_endpoint(udev, 0);
+		usb_endpoint_running(udev, 0, 1);
+		usb_endpoint_running(udev, 0, 0);
+		udev->epmaxpacketin [0] = udev->descriptor.bMaxPacketSize0;
+		udev->epmaxpacketout[0] = udev->descriptor.bMaxPacketSize0;
 	}
   
-	retval = usb_get_device_descriptor(dev, USB_DT_DEVICE_SIZE);
-	if (retval < (signed)sizeof(dev->descriptor)) {
-		dev_err(&dev->dev, "device descriptor read/%s, error %d\n",
+	retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
+	if (retval < (signed)sizeof(udev->descriptor)) {
+		dev_err(&udev->dev, "device descriptor read/%s, error %d\n",
 			"all", retval);
 		if (retval >= 0)
 			retval = -ENOMSG;
@@ -1198,14 +1216,14 @@
 	}
 
 	/* now dev is visible to other tasks */
-	hub->children[port] = dev;
+	hdev->children[port] = udev;
 
 	up(&usb_address0_sem);
 	return 0;
 }
 
 static void
-check_highspeed (struct usb_hub *hub, struct usb_device *dev, int port)
+check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port)
 {
 	struct usb_qualifier_descriptor	*qual;
 	int				status;
@@ -1214,10 +1232,10 @@
 	if (qual == 0)
 		return;
 
-	status = usb_get_descriptor (dev, USB_DT_DEVICE_QUALIFIER, 0,
+	status = usb_get_descriptor (udev, USB_DT_DEVICE_QUALIFIER, 0,
 			qual, sizeof *qual);
 	if (status == sizeof *qual) {
-		dev_info(&dev->dev, "not running at top speed; "
+		dev_info(&udev->dev, "not running at top speed; "
 			"connect to a high speed hub\n");
 		/* hub LEDs are probably harder to miss than syslog */
 		if (hub->has_indicators) {
@@ -1229,31 +1247,31 @@
 }
 
 static unsigned
-hub_power_remaining (struct usb_hub *hubstate, struct usb_device *hub)
+hub_power_remaining (struct usb_hub *hub, struct usb_device *hdev)
 {
 	int remaining;
 	unsigned i;
 
-	remaining = hubstate->power_budget;
+	remaining = hub->power_budget;
 	if (!remaining)		/* self-powered */
 		return 0;
 
-	for (i = 0; i < hub->maxchild; i++) {
-		struct usb_device	*dev = hub->children[i];
+	for (i = 0; i < hdev->maxchild; i++) {
+		struct usb_device	*udev = hdev->children[i];
 		int			delta;
 
-		if (!dev)
+		if (!udev)
 			continue;
 
-		if (dev->actconfig)
-			delta = dev->actconfig->desc.bMaxPower;
+		if (udev->actconfig)
+			delta = udev->actconfig->desc.bMaxPower;
 		else
 			delta = 50;
-		// dev_dbg(&dev->dev, "budgeted %dmA\n", 2 * delta);
+		// dev_dbg(&udev->dev, "budgeted %dmA\n", 2 * delta);
 		remaining -= delta;
 	}
 	if (remaining < 0) {
-		dev_warn(&hubstate->intf->dev,
+		dev_warn(&hub->intf->dev,
 			"%dmA over power budget!\n",
 			-2 * remaining);
 		remaining = 0;
@@ -1261,72 +1279,73 @@
 	return remaining;
 }
  
-static void hub_port_connect_change(struct usb_hub *hubstate, int port,
+static void hub_port_connect_change(struct usb_hub *hub, int port,
 					u16 portstatus, u16 portchange)
 {
-	struct usb_device *hub = interface_to_usbdev(hubstate->intf);
+	struct usb_device *hdev = interface_to_usbdev(hub->intf);
+	struct device *hub_dev = &hub->intf->dev;
 	int status, i;
  
-	dev_dbg (&hubstate->intf->dev,
+	dev_dbg (hub_dev,
 		"port %d, status %04x, change %04x, %s\n",
 		port + 1, portstatus, portchange, portspeed (portstatus));
  
 	/* Clear the connection change status */
-	clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);
+	clear_port_feature(hdev, port + 1, USB_PORT_FEAT_C_CONNECTION);
 
-	if (hubstate->has_indicators) {
-		set_port_led(hub, hubstate, port + 1, HUB_LED_AUTO);
-		hubstate->indicator[port] = INDICATOR_AUTO;
+	if (hub->has_indicators) {
+		set_port_led(hdev, port + 1, HUB_LED_AUTO);
+		hub->indicator[port] = INDICATOR_AUTO;
 	}
  
 	/* Disconnect any existing devices under this port */
-	if (hub->children[port])
-		usb_disconnect(&hub->children[port]);
+	if (hdev->children[port])
+		usb_disconnect(&hdev->children[port]);
 
 	/* Return now if nothing is connected */
 	if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
 
 		/* maybe switch power back on (e.g. root hub was reset) */
-		if ((hubstate->descriptor->wHubCharacteristics
+		if ((hub->descriptor->wHubCharacteristics
 					& HUB_CHAR_LPSM) < 2
 				&& !(portstatus & (1 << USB_PORT_FEAT_POWER)))
-			set_port_feature(hub, port + 1, USB_PORT_FEAT_POWER);
+			set_port_feature(hdev, port + 1, USB_PORT_FEAT_POWER);
  
 		if (portstatus & USB_PORT_STAT_ENABLE)
   			goto done;
 		return;
 	}
   
-	if (hub_port_debounce(hub, port)) {
-		dev_err (&hubstate->intf->dev,
+	if (hub_port_debounce(hdev, port)) {
+		dev_err (hub_dev,
 			"connect-debounce failed, port %d disabled\n",
 			port+1);
 		goto done;
 	}
 
 	for (i = 0; i < SET_CONFIG_TRIES; i++) {
-		struct usb_device *dev;
+		struct usb_device *udev;
 
 		/* reallocate for each attempt, since references
 		 * to the previous one can escape in various ways
 		 */
-		dev = usb_alloc_dev(hub, hub->bus, port);
-		if (!dev) {
-			dev_err (&hubstate->intf->dev,
+		udev = usb_alloc_dev(hdev, hdev->bus, port);
+		if (!udev) {
+			dev_err (hub_dev,
 				"couldn't allocate port %d usb_device\n", port+1);
 			goto done;
 		}
-		dev->state = USB_STATE_POWERED;
+		udev->state = USB_STATE_POWERED;
 	  
 		/* hub can tell if it's lowspeed already:  D- pullup (not D+) */
 		if (portstatus & USB_PORT_STAT_LOW_SPEED)
-			dev->speed = USB_SPEED_LOW;
+			udev->speed = USB_SPEED_LOW;
 		else
-			dev->speed = USB_SPEED_UNKNOWN;
+			udev->speed = USB_SPEED_UNKNOWN;
 
 		/* reset, set address, get descriptor, add to hub's children */
-		down (&dev->serialize);
-		status = hub_port_init(hub, dev, port);
+		down (&udev->serialize);
+		status = hub_port_init(hdev, udev, port);
 		if (status == -EBUSY)
 			break;
 		if (status < 0)
@@ -1338,50 +1357,50 @@
 		 * (without reading syslog), even without per-port LEDs
 		 * on the parent.
 		 */
-		if (dev->descriptor.bDeviceClass == USB_CLASS_HUB
-				&& hubstate->power_budget) {
+		if (udev->descriptor.bDeviceClass == USB_CLASS_HUB
+				&& hub->power_budget) {
 			u16	devstat;
 
-			status = usb_get_status(dev, USB_RECIP_DEVICE, 0,
+			status = usb_get_status(udev, USB_RECIP_DEVICE, 0,
 					&devstat);
 			if (status < 0) {
-				dev_dbg(&dev->dev, "get status %d ?\n", status);
+				dev_dbg(&udev->dev, "get status %d ?\n", status);
 				continue;
 			}
 			cpu_to_le16s(&devstat);
 			if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
-				dev_err(&dev->dev,
+				dev_err(&udev->dev,
 					"can't connect bus-powered hub "
 					"to this port\n");
-				if (hubstate->has_indicators) {
-					hubstate->indicator[port] =
+				if (hub->has_indicators) {
+					hub->indicator[port] =
 						INDICATOR_AMBER_BLINK;
-					schedule_work (&hubstate->leds);
+					schedule_work (&hub->leds);
 				}
-				hub->children[port] = NULL;
-				usb_put_dev(dev);
-				hub_port_disable(hub, port);
+				hdev->children[port] = NULL;
+				usb_put_dev(udev);
+				hub_port_disable(hdev, port);
 				return;
 			}
 		}
  
 		/* check for devices running slower than they could */
-		if (dev->descriptor.bcdUSB >= 0x0200
-				&& dev->speed == USB_SPEED_FULL
+		if (udev->descriptor.bcdUSB >= 0x0200
+				&& udev->speed == USB_SPEED_FULL
 				&& highspeed_hubs != 0)
-			check_highspeed (hubstate, dev, port);
+			check_highspeed (hub, udev, port);
 
 		/* Run it through the hoops (find a driver, etc) */
-		status = usb_new_device(dev);
+		status = usb_new_device(udev);
 		if (status != 0) {
-			hub->children[port] = NULL;
+			hdev->children[port] = NULL;
 			continue;
 		}
-		up (&dev->serialize);
+		up (&udev->serialize);
 
-		status = hub_power_remaining(hubstate, hub);
+		status = hub_power_remaining(hub, hdev);
 		if (status)
-			dev_dbg(&hubstate->intf->dev,
+			dev_dbg(hub_dev,
 				"%dmA power budget left\n",
 				2 * status);
 
@@ -1389,15 +1408,16 @@
 	}
  
 done:
-	hub_port_disable(hub, port);
+	hub_port_disable(hdev, port);
 }
 
 static void hub_events(void)
 {
 	unsigned long flags;
 	struct list_head *tmp;
-	struct usb_device *dev;
+	struct usb_device *hdev;
 	struct usb_hub *hub;
+	struct device *hub_dev;
 	u16 hubstatus;
 	u16 hubchange;
 	u16 portstatus;
@@ -1420,7 +1440,8 @@
 		tmp = hub_event_list.next;
 
 		hub = list_entry(tmp, struct usb_hub, event_list);
-		dev = interface_to_usbdev(hub->intf);
+		hdev = interface_to_usbdev(hub->intf);
+		hub_dev = &hub->intf->dev;
 
 		list_del_init(tmp);
 
@@ -1430,14 +1451,14 @@
 		spin_unlock_irqrestore(&hub_event_lock, flags);
 
 		if (hub->error) {
-			dev_dbg (&hub->intf->dev, "resetting for error %d\n",
+			dev_dbg (hub_dev, "resetting for error %d\n",
 				hub->error);
 
 			if (hub_reset(hub)) {
-				dev_dbg (&hub->intf->dev,
+				dev_dbg (hub_dev,
 					"can't reset; disconnecting\n");
 				up(&hub->khubd_sem);
-				hub_start_disconnect(dev);
+				hub_start_disconnect(hdev);
 				continue;
 			}
 
@@ -1446,7 +1467,7 @@
 		}
 
 		for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
-			ret = hub_port_status(dev, i, &portstatus, &portchange);
+			ret = hub_port_status(hdev, i, &portstatus, &portchange);
 			if (ret < 0) {
 				continue;
 			}
@@ -1454,10 +1475,10 @@
 			if (portchange & USB_PORT_STAT_C_CONNECTION) {
 				hub_port_connect_change(hub, i, portstatus, portchange);
 			} else if (portchange & USB_PORT_STAT_C_ENABLE) {
-				dev_dbg (hubdev (dev),
+				dev_dbg (hub_dev,
 					"port %d enable change, status %08x\n",
 					i + 1, portstatus);
-				clear_port_feature(dev,
+				clear_port_feature(hdev,
 					i + 1, USB_PORT_FEAT_C_ENABLE);
 
 				/*
@@ -1468,8 +1489,8 @@
 				 */
 				if (!(portstatus & USB_PORT_STAT_ENABLE)
 				    && (portstatus & USB_PORT_STAT_CONNECTION)
-				    && (dev->children[i])) {
-					dev_err (&hub->intf->dev,
+				    && (hdev->children[i])) {
+					dev_err (hub_dev,
 					    "port %i "
 					    "disabled by hub (EMI?), "
 					    "re-enabling...",
@@ -1480,43 +1501,43 @@
 			}
 
 			if (portchange & USB_PORT_STAT_C_SUSPEND) {
-				dev_dbg (&hub->intf->dev,
+				dev_dbg (hub_dev,
 					"suspend change on port %d\n",
 					i + 1);
-				clear_port_feature(dev,
+				clear_port_feature(hdev,
 					i + 1,  USB_PORT_FEAT_C_SUSPEND);
 			}
 			
 			if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
-				dev_err (&hub->intf->dev,
+				dev_err (hub_dev,
 					"over-current change on port %d\n",
 					i + 1);
-				clear_port_feature(dev,
+				clear_port_feature(hdev,
 					i + 1, USB_PORT_FEAT_C_OVER_CURRENT);
 				hub_power_on(hub);
 			}
 
 			if (portchange & USB_PORT_STAT_C_RESET) {
-				dev_dbg (&hub->intf->dev,
+				dev_dbg (hub_dev,
 					"reset change on port %d\n",
 					i + 1);
-				clear_port_feature(dev,
+				clear_port_feature(hdev,
 					i + 1, USB_PORT_FEAT_C_RESET);
 			}
 		} /* end for i */
 
 		/* deal with hub status changes */
 		if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
-			dev_err (&hub->intf->dev, "get_hub_status failed\n");
+			dev_err (hub_dev, "get_hub_status failed\n");
 		else {
 			if (hubchange & HUB_CHANGE_LOCAL_POWER) {
-				dev_dbg (&hub->intf->dev, "power change\n");
-				clear_hub_feature(dev, C_HUB_LOCAL_POWER);
+				dev_dbg (hub_dev, "power change\n");
+				clear_hub_feature(hdev, C_HUB_LOCAL_POWER);
 			}
 			if (hubchange & HUB_CHANGE_OVERCURRENT) {
-				dev_dbg (&hub->intf->dev, "overcurrent change\n");
+				dev_dbg (hub_dev, "overcurrent change\n");
 				msleep(500);	/* Cool down */
-				clear_hub_feature(dev, C_HUB_OVER_CURRENT);
+				clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
                         	hub_power_on(hub);
 			}
 		}
@@ -1526,7 +1547,7 @@
 	spin_unlock_irqrestore(&hub_event_lock, flags);
 }
 
-static int hub_thread(void *__hub)
+static int hub_thread(void *__unused)
 {
 	/*
 	 * This thread doesn't need any user-level access,
@@ -1614,36 +1635,36 @@
 } /* usb_hub_cleanup() */
 
 
-static int config_descriptors_changed(struct usb_device *dev)
+static int config_descriptors_changed(struct usb_device *udev)
 {
 	unsigned			index;
 	unsigned			len = 0;
 	struct usb_config_descriptor	*buf;
 
-	for (index = 0; index < dev->descriptor.bNumConfigurations; index++) {
-		if (len < dev->config[index].desc.wTotalLength)
-			len = dev->config[index].desc.wTotalLength;
+	for (index = 0; index < udev->descriptor.bNumConfigurations; index++) {
+		if (len < udev->config[index].desc.wTotalLength)
+			len = udev->config[index].desc.wTotalLength;
 	}
 	buf = kmalloc (len, SLAB_KERNEL);
 	if (buf == 0) {
-		dev_err(&dev->dev, "no mem to re-read configs after reset\n");
+		dev_err(&udev->dev, "no mem to re-read configs after reset\n");
 		/* assume the worst */
 		return 1;
 	}
-	for (index = 0; index < dev->descriptor.bNumConfigurations; index++) {
+	for (index = 0; index < udev->descriptor.bNumConfigurations; index++) {
 		int length;
-		int old_length = dev->config[index].desc.wTotalLength;
+		int old_length = udev->config[index].desc.wTotalLength;
 
-		length = usb_get_descriptor(dev, USB_DT_CONFIG, index, buf,
+		length = usb_get_descriptor(udev, USB_DT_CONFIG, index, buf,
 				old_length);
 		if (length < old_length) {
-			dev_dbg(&dev->dev, "config index %d, error %d\n",
+			dev_dbg(&udev->dev, "config index %d, error %d\n",
 					index, length);
 			break;
 		}
-		if (memcmp (buf, dev->rawdescriptors[index], old_length)
+		if (memcmp (buf, udev->rawdescriptors[index], old_length)
 				!= 0) {
-			dev_dbg(&dev->dev, "config index %d changed (#%d)\n",
+			dev_dbg(&udev->dev, "config index %d changed (#%d)\n",
 				index, buf->bConfigurationValue);
 /* FIXME enable this when we can re-enumerate after reset;
  * until then DFU-ish drivers need this and other workarounds
@@ -1652,7 +1673,7 @@
 		}
 	}
 	kfree(buf);
-	return index != dev->descriptor.bNumConfigurations;
+	return index != udev->descriptor.bNumConfigurations;
 }
 
 /*
@@ -1664,22 +1685,22 @@
  * already holds dev->serialize.  For example, it's safe to use
  * this from a driver probe() routine after downloading new firmware.
  */
-int __usb_reset_device(struct usb_device *dev)
+int __usb_reset_device(struct usb_device *udev)
 {
-	struct usb_device *parent = dev->parent;
-	struct usb_device_descriptor descriptor = dev->descriptor;
+	struct usb_device *parent = udev->parent;
+	struct usb_device_descriptor descriptor = udev->descriptor;
 	int i, ret, port = -1;
 
-	if (dev->maxchild) {
+	if (udev->maxchild) {
 		/* this requires hub- or hcd-specific logic;
 		 * see hub_reset() and OHCI hc_restart()
 		 */
-		dev_dbg(&dev->dev, "%s for hub!\n", __FUNCTION__);
+		dev_dbg(&udev->dev, "%s for hub!\n", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	for (i = 0; i < parent->maxchild; i++)
-		if (parent->children[i] == dev) {
+		if (parent->children[i] == udev) {
 			port = i;
 			break;
 		}
@@ -1687,45 +1708,45 @@
 	if (port < 0)
 		return -ENOENT;
 
-	ret = hub_port_init(parent, dev, port);
+	ret = hub_port_init(parent, udev, port);
 	if (ret < 0)
 		goto re_enumerate;
  
 	/* Device might have changed firmware (DFU or similar) */
-	if (memcmp(&dev->descriptor, &descriptor, sizeof descriptor)
-			|| config_descriptors_changed (dev)) {
-		dev_info(&dev->dev, "device firmware changed\n");
-		dev->descriptor = descriptor;	/* for disconnect() calls */
+	if (memcmp(&udev->descriptor, &descriptor, sizeof descriptor)
+			|| config_descriptors_changed (udev)) {
+		dev_info(&udev->dev, "device firmware changed\n");
+		udev->descriptor = descriptor;	/* for disconnect() calls */
 		goto re_enumerate;
   	}
   
-	if (!dev->actconfig)
+	if (!udev->actconfig)
 		return 0;
 
-	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			USB_REQ_SET_CONFIGURATION, 0,
-			dev->actconfig->desc.bConfigurationValue, 0,
+			udev->actconfig->desc.bConfigurationValue, 0,
 			NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
 	if (ret < 0) {
-		dev_err(&dev->dev,
+		dev_err(&udev->dev,
 			"can't restore configuration #%d (error=%d)\n",
-			dev->actconfig->desc.bConfigurationValue, ret);
+			udev->actconfig->desc.bConfigurationValue, ret);
 		goto re_enumerate;
   	}
-	dev->state = USB_STATE_CONFIGURED;
+	udev->state = USB_STATE_CONFIGURED;
 
-	for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
-		struct usb_interface *intf = dev->actconfig->interface[i];
+	for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
+		struct usb_interface *intf = udev->actconfig->interface[i];
 		struct usb_interface_descriptor *desc;
 
 		/* set_interface resets host side toggle and halt status even
 		 * for altsetting zero.  the interface may have no driver.
 		 */
 		desc = &intf->cur_altsetting->desc;
-		ret = usb_set_interface(dev, desc->bInterfaceNumber,
+		ret = usb_set_interface(udev, desc->bInterfaceNumber,
 			desc->bAlternateSetting);
 		if (ret < 0) {
-			dev_err(&dev->dev, "failed to restore interface %d "
+			dev_err(&udev->dev, "failed to restore interface %d "
 				"altsetting %d (error=%d)\n",
 				desc->bInterfaceNumber,
 				desc->bAlternateSetting,
@@ -1738,7 +1759,7 @@
  
 re_enumerate:
 	/* FIXME make some task re-enumerate; don't just mark unusable */
-	dev->state = USB_STATE_NOTATTACHED;
+	udev->state = USB_STATE_NOTATTACHED;
 	return -ENODEV;
 }
 EXPORT_SYMBOL(__usb_reset_device);
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/core/message.c	2004-05-25 21:38:09 -07:00
@@ -1252,7 +1252,7 @@
 					ret);
 				continue;
 			}
-			usb_create_driverfs_intf_files (intf);
+			usb_create_sysfs_intf_files (intf);
 		}
 	}
 
diff -Nru a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/core/sysfs.c	2004-05-25 21:38:09 -07:00
@@ -0,0 +1,229 @@
+/*
+ * drivers/usb/core/sysfs.c
+ *
+ * (C) Copyright 2002 David Brownell
+ * (C) Copyright 2002 Greg Kroah-Hartman
+ * (C) Copyright 2002 IBM Corp.
+ *
+ * All of the sysfs file attributes for usb devices and interfaces.
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+
+#ifdef CONFIG_USB_DEBUG
+	#define DEBUG
+#else
+	#undef DEBUG
+#endif
+#include <linux/usb.h>
+
+#include "usb.h"
+
+/* Active configuration fields */
+#define usb_actconfig_show(field, multiplier, format_string)		\
+static ssize_t  show_##field (struct device *dev, char *buf)		\
+{									\
+	struct usb_device *udev;					\
+									\
+	udev = to_usb_device (dev);					\
+	if (udev->actconfig)						\
+		return sprintf (buf, format_string,			\
+				udev->actconfig->desc.field * multiplier);	\
+	else								\
+		return 0;						\
+}									\
+
+#define usb_actconfig_attr(field, multiplier, format_string)		\
+usb_actconfig_show(field, multiplier, format_string)			\
+static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+
+usb_actconfig_attr (bNumInterfaces, 1, "%2d\n")
+usb_actconfig_attr (bmAttributes, 1, "%2x\n")
+usb_actconfig_attr (bMaxPower, 2, "%3dmA\n")
+
+/* configuration value is always present, and r/w */
+usb_actconfig_show(bConfigurationValue, 1, "%u\n");
+
+static ssize_t
+set_bConfigurationValue (struct device *dev, const char *buf, size_t count)
+{
+	struct usb_device	*udev = udev = to_usb_device (dev);
+	int			config, value;
+
+	if (sscanf (buf, "%u", &config) != 1 || config > 255)
+		return -EINVAL;
+	down(&udev->serialize);
+	value = usb_set_configuration (udev, config);
+	up(&udev->serialize);
+	return (value < 0) ? value : count;
+}
+
+static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, 
+		show_bConfigurationValue, set_bConfigurationValue);
+
+/* String fields */
+#define usb_string_attr(name, field)		\
+static ssize_t  show_##name(struct device *dev, char *buf)		\
+{									\
+	struct usb_device *udev;					\
+	int len;							\
+									\
+	udev = to_usb_device (dev);					\
+	len = usb_string(udev, udev->descriptor.field, buf, PAGE_SIZE);	\
+	if (len < 0)							\
+		return 0;						\
+	buf[len] = '\n';						\
+	buf[len+1] = 0;							\
+	return len+1;							\
+}									\
+static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
+
+usb_string_attr(product, iProduct);
+usb_string_attr(manufacturer, iManufacturer);
+usb_string_attr(serial, iSerialNumber);
+
+static ssize_t
+show_speed (struct device *dev, char *buf)
+{
+	struct usb_device *udev;
+	char *speed;
+
+	udev = to_usb_device (dev);
+
+	switch (udev->speed) {
+	case USB_SPEED_LOW:
+		speed = "1.5";
+		break;
+	case USB_SPEED_UNKNOWN:
+	case USB_SPEED_FULL:
+		speed = "12";
+		break;
+	case USB_SPEED_HIGH:
+		speed = "480";
+		break;
+	default:
+		speed = "unknown";
+	}
+	return sprintf (buf, "%s\n", speed);
+}
+static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL);
+
+static ssize_t
+show_devnum (struct device *dev, char *buf)
+{
+	struct usb_device *udev;
+
+	udev = to_usb_device (dev);
+	return sprintf (buf, "%d\n", udev->devnum);
+}
+static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL);
+
+static ssize_t
+show_version (struct device *dev, char *buf)
+{
+	struct usb_device *udev;
+
+	udev = to_usb_device (dev);
+	return sprintf (buf, "%2x.%02x\n", udev->descriptor.bcdUSB >> 8, 
+			udev->descriptor.bcdUSB & 0xff);
+}
+static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
+
+static ssize_t
+show_maxchild (struct device *dev, char *buf)
+{
+	struct usb_device *udev;
+
+	udev = to_usb_device (dev);
+	return sprintf (buf, "%d\n", udev->maxchild);
+}
+static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
+
+/* Descriptor fields */
+#define usb_descriptor_attr(field, format_string)			\
+static ssize_t								\
+show_##field (struct device *dev, char *buf)				\
+{									\
+	struct usb_device *udev;					\
+									\
+	udev = to_usb_device (dev);					\
+	return sprintf (buf, format_string, udev->descriptor.field);	\
+}									\
+static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+
+usb_descriptor_attr (idVendor, "%04x\n")
+usb_descriptor_attr (idProduct, "%04x\n")
+usb_descriptor_attr (bcdDevice, "%04x\n")
+usb_descriptor_attr (bDeviceClass, "%02x\n")
+usb_descriptor_attr (bDeviceSubClass, "%02x\n")
+usb_descriptor_attr (bDeviceProtocol, "%02x\n")
+usb_descriptor_attr (bNumConfigurations, "%d\n")
+
+
+void usb_create_sysfs_dev_files (struct usb_device *udev)
+{
+	struct device *dev = &udev->dev;
+
+	/* current configuration's attributes */
+	device_create_file (dev, &dev_attr_bNumInterfaces);
+	device_create_file (dev, &dev_attr_bConfigurationValue);
+	device_create_file (dev, &dev_attr_bmAttributes);
+	device_create_file (dev, &dev_attr_bMaxPower);
+
+	/* device attributes */
+	device_create_file (dev, &dev_attr_idVendor);
+	device_create_file (dev, &dev_attr_idProduct);
+	device_create_file (dev, &dev_attr_bcdDevice);
+	device_create_file (dev, &dev_attr_bDeviceClass);
+	device_create_file (dev, &dev_attr_bDeviceSubClass);
+	device_create_file (dev, &dev_attr_bDeviceProtocol);
+	device_create_file (dev, &dev_attr_bNumConfigurations);
+
+	/* speed varies depending on how you connect the device */
+	device_create_file (dev, &dev_attr_speed);
+	// FIXME iff there are other speed configs, show how many
+
+	if (udev->descriptor.iManufacturer)
+		device_create_file (dev, &dev_attr_manufacturer);
+	if (udev->descriptor.iProduct)
+		device_create_file (dev, &dev_attr_product);
+	if (udev->descriptor.iSerialNumber)
+		device_create_file (dev, &dev_attr_serial);
+
+	device_create_file (dev, &dev_attr_devnum);
+	device_create_file (dev, &dev_attr_version);
+	device_create_file (dev, &dev_attr_maxchild);
+}
+
+/* Interface fields */
+#define usb_intf_attr(field, format_string)				\
+static ssize_t								\
+show_##field (struct device *dev, char *buf)				\
+{									\
+	struct usb_interface *intf = to_usb_interface (dev);		\
+									\
+	return sprintf (buf, format_string, intf->cur_altsetting->desc.field); \
+}									\
+static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+
+usb_intf_attr (bInterfaceNumber, "%02x\n")
+usb_intf_attr (bAlternateSetting, "%2d\n")
+usb_intf_attr (bNumEndpoints, "%02x\n")
+usb_intf_attr (bInterfaceClass, "%02x\n")
+usb_intf_attr (bInterfaceSubClass, "%02x\n")
+usb_intf_attr (bInterfaceProtocol, "%02x\n")
+usb_intf_attr (iInterface, "%02x\n")
+
+void usb_create_sysfs_intf_files (struct usb_interface *intf)
+{
+	device_create_file (&intf->dev, &dev_attr_bInterfaceNumber);
+	device_create_file (&intf->dev, &dev_attr_bAlternateSetting);
+	device_create_file (&intf->dev, &dev_attr_bNumEndpoints);
+	device_create_file (&intf->dev, &dev_attr_bInterfaceClass);
+	device_create_file (&intf->dev, &dev_attr_bInterfaceSubClass);
+	device_create_file (&intf->dev, &dev_attr_bInterfaceProtocol);
+	device_create_file (&intf->dev, &dev_attr_iInterface);
+}
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/core/usb.c	2004-05-25 21:38:09 -07:00
@@ -998,12 +998,10 @@
 	 */
 	usb_disable_device(dev, 0);
 
-	dev_dbg (&dev->dev, "unregistering device\n");
 	/* Free the device number and remove the /proc/bus/usb entry */
-	if (dev->devnum > 0) {
-		clear_bit(dev->devnum, dev->bus->devmap.devicemap);
-		usbfs_remove_device(dev);
-	}
+	dev_dbg (&dev->dev, "unregistering device\n");
+	usb_release_address(dev);
+	usbfs_remove_device(dev);
 	up(&dev->serialize);
 	device_unregister(&dev->dev);
 }
@@ -1038,24 +1036,23 @@
 	}
 }
 
-
-// hub-only!! ... and only exported for reset/reinit path.
-// otherwise used internally, for usb_new_device()
-int usb_set_address(struct usb_device *dev)
+/**
+ * usb_release_address - deallocate device address (usbcore-internal)
+ * @dev: newly removed device
+ *
+ * Removes and deallocates the address assigned to a device.
+ * Only hub drivers (but not virtual root hub drivers for host
+ * controllers) should ever call this.
+ */
+void usb_release_address(struct usb_device *dev)
 {
-	int retval;
-
-	if (dev->devnum == 0)
-		return -EINVAL;
-	if (dev->state != USB_STATE_DEFAULT && dev->state != USB_STATE_ADDRESS)
-		return -EINVAL;
-	retval = usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS,
-		0, dev->devnum, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
-	if (retval == 0)
-		dev->state = USB_STATE_ADDRESS;
-	return retval;
+	if (dev->devnum > 0) {
+		clear_bit(dev->devnum, dev->bus->devmap.devicemap);
+		dev->devnum = -1;
+	}
 }
 
+
 static inline void usb_show_string(struct usb_device *dev, char *id, int index)
 {
 	char *buf;
@@ -1069,6 +1066,37 @@
 	kfree(buf);
 }
 
+static int usb_choose_configuration(struct usb_device *dev)
+{
+	int c, i;
+
+	c = dev->config[0].desc.bConfigurationValue;
+	if (dev->descriptor.bNumConfigurations != 1) {
+		for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
+			struct usb_interface_descriptor	*desc;
+
+			/* heuristic:  Linux is more likely to have class
+			 * drivers, so avoid vendor-specific interfaces.
+			 */
+			desc = &dev->config[i].intf_cache[0]
+					->altsetting->desc;
+			if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
+				continue;
+			/* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */
+			if (desc->bInterfaceClass == USB_CLASS_COMM
+					&& desc->bInterfaceSubClass == 2
+					&& desc->bInterfaceProtocol == 0xff)
+				continue;
+			c = dev->config[i].desc.bConfigurationValue;
+			break;
+		}
+		dev_info(&dev->dev,
+			"configuration #%d chosen from %d choices\n",
+			c, dev->descriptor.bNumConfigurations);
+	}
+	return c;
+}
+
 /*
  * usb_new_device - perform initial device setup (usbcore-internal)
  * @dev: newly addressed device (in ADDRESS state)
@@ -1090,8 +1118,7 @@
 int usb_new_device(struct usb_device *dev)
 {
 	int err;
-	int i;
-	int config;
+	int c;
 
 	err = usb_get_configuration(dev);
 	if (err < 0) {
@@ -1119,41 +1146,16 @@
 		dev_err(&dev->dev, "can't device_add, error %d\n", err);
 		goto fail;
 	}
-	usb_create_driverfs_dev_files (dev);
+	usb_create_sysfs_dev_files (dev);
 
 	/* choose and set the configuration. that registers the interfaces
 	 * with the driver core, and lets usb device drivers bind to them.
 	 * NOTE:  should interact with hub power budgeting.
 	 */
-	config = dev->config[0].desc.bConfigurationValue;
-	if (dev->descriptor.bNumConfigurations != 1) {
-		for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
-			struct usb_interface_descriptor	*desc;
-
-			/* heuristic:  Linux is more likely to have class
-			 * drivers, so avoid vendor-specific interfaces.
-			 */
-			desc = &dev->config[i].intf_cache[0]
-					->altsetting->desc;
-			if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
-				continue;
-			/* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */
-			if (desc->bInterfaceClass == USB_CLASS_COMM
-					&& desc->bInterfaceSubClass == 2
-					&& desc->bInterfaceProtocol == 0xff)
-				continue;
-			config = dev->config[i].desc.bConfigurationValue;
-			break;
-		}
-		dev_info(&dev->dev,
-			"configuration #%d chosen from %d choices\n",
-			config,
-			dev->descriptor.bNumConfigurations);
-	}
-	err = usb_set_configuration(dev, config);
+	c = usb_choose_configuration(dev);
+	err = usb_set_configuration(dev, c);
 	if (err) {
-		dev_err(&dev->dev, "can't set config #%d, error %d\n",
-			config, err);
+		dev_err(&dev->dev, "can't set config #%d, error %d\n", c, err);
 		device_del(&dev->dev);
 		goto fail;
 	}
@@ -1166,8 +1168,7 @@
 	return 0;
 fail:
 	dev->state = USB_STATE_NOTATTACHED;
-	clear_bit(dev->devnum, dev->bus->devmap.devicemap);
-	dev->devnum = -1;
+	usb_release_address(dev);
 	usb_put_dev(dev);
 	return err;
 }
diff -Nru a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
--- a/drivers/usb/core/usb.h	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/core/usb.h	2004-05-25 21:38:09 -07:00
@@ -1,7 +1,7 @@
 /* Functions local to drivers/usb/core/ */
 
-extern void usb_create_driverfs_dev_files (struct usb_device *dev);
-extern void usb_create_driverfs_intf_files (struct usb_interface *intf);
+extern void usb_create_sysfs_dev_files (struct usb_device *dev);
+extern void usb_create_sysfs_intf_files (struct usb_interface *intf);
 extern int usb_probe_interface (struct device *dev);
 extern int usb_unbind_interface (struct device *dev);
 
diff -Nru a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
--- a/drivers/usb/gadget/Kconfig	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/gadget/Kconfig	2004-05-25 21:38:09 -07:00
@@ -95,6 +95,7 @@
 config USB_PXA2XX_SMALL
 	depends on USB_GADGET_PXA2XX
 	bool
+	default n if USB_ETH_RNDIS
 	default y if USB_ZERO
 	default y if USB_ETH
 	default y if USB_G_SERIAL
diff -Nru a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
--- a/drivers/usb/gadget/epautoconf.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/gadget/epautoconf.c	2004-05-25 21:38:09 -07:00
@@ -96,7 +96,8 @@
 				/* for now, avoid PXA "interrupt-in";
 				 * it's documented as never using DATA1.
 				 */
-				if (gadget_is_pxa (gadget))
+				if (gadget_is_pxa (gadget)
+						&& 'i' == tmp [1])
 					return 0;
 				break;
 			case USB_ENDPOINT_XFER_BULK:
diff -Nru a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
--- a/drivers/usb/gadget/serial.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/gadget/serial.c	2004-05-25 21:38:09 -07:00
@@ -154,14 +154,9 @@
 
 #define GS_CLOSE_TIMEOUT		15
 
-/* debug macro */
+/* debug settings */
 #if G_SERIAL_DEBUG
 static int debug = G_SERIAL_DEBUG;
-#else
-static int debug = 0;
-#endif
-
-#if G_SERIAL_DEBUG
 
 #define gs_debug(format, arg...) \
 	do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0)
@@ -598,8 +593,10 @@
 MODULE_AUTHOR("Al Borchers");
 MODULE_LICENSE("GPL");
 
+#if G_SERIAL_DEBUG
 MODULE_PARM(debug, "i");
 MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on");
+#endif
 
 MODULE_PARM(read_q_size, "i");
 MODULE_PARM_DESC(read_q_size, "Read request queue size, default=32");
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/host/uhci-hcd.c	2004-05-25 21:38:09 -07:00
@@ -95,6 +95,10 @@
 static int uhci_get_current_frame_number(struct uhci_hcd *uhci);
 static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb);
 static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb);
+static void uhci_remove_pending_urbps(struct uhci_hcd *uhci);
+static void uhci_finish_completion(struct usb_hcd *hcd, struct pt_regs *regs);
+static void uhci_free_pending_qhs(struct uhci_hcd *uhci);
+static void uhci_free_pending_tds(struct uhci_hcd *uhci);
 
 static void hc_state_transitions(struct uhci_hcd *uhci);
 
@@ -373,6 +377,7 @@
 {
 	struct uhci_qh *pqh;
 	u32 newlink;
+	unsigned int age;
 
 	if (!qh)
 		return;
@@ -425,6 +430,12 @@
 	list_del_init(&qh->urbp->queue_list);
 	qh->urbp = NULL;
 
+	age = uhci_get_current_frame_number(uhci);
+	if (age != uhci->qh_remove_age) {
+		uhci_free_pending_qhs(uhci);
+		uhci->qh_remove_age = age;
+	}
+
 	/* Check to see if the remove list is empty. Set the IOC bit */
 	/* to force an interrupt so we can remove the QH */
 	if (list_empty(&uhci->qh_remove_list))
@@ -628,6 +639,7 @@
 {
 	struct list_head *head, *tmp;
 	struct urb_priv *urbp;
+	unsigned int age;
 
 	urbp = (struct urb_priv *)urb->hcpriv;
 	if (!urbp)
@@ -637,6 +649,12 @@
 		dev_warn(uhci_dev(uhci), "urb %p still on uhci->urb_list "
 				"or uhci->remove_list!\n", urb);
 
+	age = uhci_get_current_frame_number(uhci);
+	if (age != uhci->td_remove_age) {
+		uhci_free_pending_tds(uhci);
+		uhci->td_remove_age = age;
+	}
+
 	/* Check to see if the remove list is empty. Set the IOC bit */
 	/* to force an interrupt so we can remove the TD's*/
 	if (list_empty(&uhci->td_remove_list))
@@ -1512,6 +1530,7 @@
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
 	unsigned long flags;
 	struct urb_priv *urbp;
+	unsigned int age;
 
 	spin_lock_irqsave(&uhci->schedule_lock, flags);
 	urbp = urb->hcpriv;
@@ -1521,6 +1540,12 @@
 
 	uhci_unlink_generic(uhci, urb);
 
+	age = uhci_get_current_frame_number(uhci);
+	if (age != uhci->urb_remove_age) {
+		uhci_remove_pending_urbps(uhci);
+		uhci->urb_remove_age = age;
+	}
+
 	/* If we're the first, set the next interrupt bit */
 	if (list_empty(&uhci->urb_remove_list))
 		uhci_set_next_interrupt(uhci);
@@ -1590,6 +1615,12 @@
 	INIT_LIST_HEAD(&list);
 
 	spin_lock_irqsave(&uhci->schedule_lock, flags);
+	if (!list_empty(&uhci->urb_remove_list) &&
+	    uhci_get_current_frame_number(uhci) != uhci->urb_remove_age) {
+		uhci_remove_pending_urbps(uhci);
+		uhci_finish_completion(hcd, NULL);
+	}
+
 	head = &uhci->urb_list;
 	tmp = head->next;
 	while (tmp != head) {
@@ -1728,6 +1759,7 @@
 	unsigned int io_addr = uhci->io_addr;
 	unsigned short status;
 	struct list_head *tmp, *head;
+	unsigned int age;
 
 	/*
 	 * Read the interrupt status, and write it back to clear the
@@ -1758,11 +1790,20 @@
 
 	spin_lock(&uhci->schedule_lock);
 
-	uhci_free_pending_qhs(uhci);
-	uhci_free_pending_tds(uhci);
-	uhci_remove_pending_urbps(uhci);
-
-	uhci_clear_next_interrupt(uhci);
+	age = uhci_get_current_frame_number(uhci);
+	if (age != uhci->qh_remove_age)
+		uhci_free_pending_qhs(uhci);
+	if (age != uhci->td_remove_age)
+		uhci_free_pending_tds(uhci);
+	if (age != uhci->urb_remove_age)
+		uhci_remove_pending_urbps(uhci);
+
+	if (list_empty(&uhci->urb_remove_list) &&
+	    list_empty(&uhci->td_remove_list) &&
+	    list_empty(&uhci->qh_remove_list))
+		uhci_clear_next_interrupt(uhci);
+	else
+		uhci_set_next_interrupt(uhci);
 
 	/* Walk the list of pending URB's to see which ones completed */
 	head = &uhci->urb_list;
diff -Nru a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
--- a/drivers/usb/host/uhci-hcd.h	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/host/uhci-hcd.h	2004-05-25 21:38:09 -07:00
@@ -357,12 +357,15 @@
 
 	/* List of QH's that are done, but waiting to be unlinked (race) */
 	struct list_head qh_remove_list;	/* P: uhci->schedule_lock */
+	unsigned int qh_remove_age;		/* Age in frames */
 
 	/* List of TD's that are done, but waiting to be freed (race) */
 	struct list_head td_remove_list;	/* P: uhci->schedule_lock */
+	unsigned int td_remove_age;		/* Age in frames */
 
 	/* List of asynchronously unlinked URB's */
 	struct list_head urb_remove_list;	/* P: uhci->schedule_lock */
+	unsigned int urb_remove_age;		/* Age in frames */
 
 	/* List of URB's awaiting completion callback */
 	struct list_head complete_list;		/* P: uhci->schedule_lock */
diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/input/hiddev.c	2004-05-25 21:38:09 -07:00
@@ -232,7 +232,7 @@
 static struct usb_class_driver hiddev_class;
 static void hiddev_cleanup(struct hiddev *hiddev)
 {
-	hiddev_table[hiddev->hid->minor] = NULL;
+	hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
 	usb_deregister_dev(hiddev->hid->intf, &hiddev_class);
 	kfree(hiddev);
 }
diff -Nru a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
--- a/drivers/usb/input/powermate.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/input/powermate.c	2004-05-25 21:38:09 -07:00
@@ -33,6 +33,7 @@
 #include <linux/input.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/spinlock.h>
 #include <linux/usb.h>
 
 #define POWERMATE_VENDOR	0x077d	/* Griffin Technology, Inc. */
@@ -67,7 +68,7 @@
 	dma_addr_t configcr_dma;
 	struct usb_device *udev;
 	struct input_dev input;
-	struct semaphore lock;
+	spinlock_t lock;
 	int static_brightness;
 	int pulse_speed;
 	int pulse_table;
@@ -116,7 +117,7 @@
 		     __FUNCTION__, retval);
 }
 
-/* Decide if we need to issue a control message and do so. Must be called with pm->lock down */
+/* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */
 static void powermate_sync_state(struct powermate_device *pm)
 {
 	if (pm->requires_update == 0) 
@@ -194,19 +195,22 @@
 static void powermate_config_complete(struct urb *urb, struct pt_regs *regs)
 {
 	struct powermate_device *pm = urb->context;
+	unsigned long flags;
 
 	if (urb->status)
 		printk(KERN_ERR "powermate: config urb returned %d\n", urb->status);
 	
-	down(&pm->lock);
+	spin_lock_irqsave(&pm->lock, flags);
 	powermate_sync_state(pm);
-	up(&pm->lock);
+	spin_unlock_irqrestore(&pm->lock, flags);
 }
 
 /* Set the LED up as described and begin the sync with the hardware if required */
 static void powermate_pulse_led(struct powermate_device *pm, int static_brightness, int pulse_speed, 
 				int pulse_table, int pulse_asleep, int pulse_awake)
 {
+	unsigned long flags;
+
 	if (pulse_speed < 0)
 		pulse_speed = 0;
 	if (pulse_table < 0)
@@ -219,7 +223,8 @@
 	pulse_asleep = !!pulse_asleep;
 	pulse_awake = !!pulse_awake;
 
-	down(&pm->lock);
+
+	spin_lock_irqsave(&pm->lock, flags);
 
 	/* mark state updates which are required */
 	if (static_brightness != pm->static_brightness){
@@ -242,7 +247,7 @@
 
 	powermate_sync_state(pm);
    
-	up(&pm->lock);
+	spin_unlock_irqrestore(&pm->lock, flags);
 }
 
 /* Callback from the Input layer when an event arrives from userspace to configure the LED */
@@ -344,7 +349,7 @@
 		return -ENOMEM;
 	}
 
-	init_MUTEX(&pm->lock);
+	pm->lock = SPIN_LOCK_UNLOCKED;
 	init_input_dev(&pm->input);
 
 	/* get a handle to the interrupt data pipe */
@@ -411,7 +416,6 @@
 
 	usb_set_intfdata(intf, NULL);
 	if (pm) {
-		down(&pm->lock);
 		pm->requires_update = 0;
 		usb_unlink_urb(pm->irq);
 		input_unregister_device(&pm->input);
diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
--- a/drivers/usb/net/kaweth.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/net/kaweth.c	2004-05-25 21:38:09 -07:00
@@ -1240,20 +1240,21 @@
         init_waitqueue_head(&awd.wqh);
         awd.done = 0;
 
-        set_current_state(TASK_INTERRUPTIBLE);
         add_wait_queue(&awd.wqh, &wait);
         urb->context = &awd;
-        status = usb_submit_urb(urb, GFP_ATOMIC);
+        status = usb_submit_urb(urb, GFP_NOIO);
         if (status) {
                 // something went wrong
                 usb_free_urb(urb);
-                set_current_state(TASK_RUNNING);
                 remove_wait_queue(&awd.wqh, &wait);
                 return status;
         }
 
-	while (timeout && !awd.done)
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	while (timeout && !awd.done) {
 		timeout = schedule_timeout(timeout);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+	}
 
         set_current_state(TASK_RUNNING);
         remove_wait_queue(&awd.wqh, &wait);
diff -Nru a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h
--- a/drivers/usb/net/pegasus.h	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/net/pegasus.h	2004-05-25 21:38:09 -07:00
@@ -136,6 +136,7 @@
 #define	VENDOR_LANEED		0x056e
 #define	VENDOR_LINKSYS		0x066b
 #define	VENDOR_MELCO		0x0411
+#define	VENDOR_MICROSOFT	0x045e
 #define	VENDOR_MOBILITY		0x1342
 #define	VENDOR_NETGEAR		0x0846
 #define	VENDOR_OCT		0x0b39
@@ -264,6 +265,8 @@
 PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "Microsoft MN-110", VENDOR_MICROSOFT, 0x007a,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "NETGEAR FA101", VENDOR_NETGEAR, 0x1020,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
diff -Nru a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
--- a/drivers/usb/serial/Kconfig	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/serial/Kconfig	2004-05-25 21:38:09 -07:00
@@ -314,8 +314,8 @@
 	  module will be called kl5kusb105.
 
 config USB_SERIAL_KOBIL_SCT
-        tristate "USB KOBIL chipcard reader (EXPERIMENTAL)"
-        depends on USB_SERIAL && EXPERIMENTAL
+        tristate "USB KOBIL chipcard reader"
+        depends on USB_SERIAL
         ---help---
           Say Y here if you want to use one of the following KOBIL USB chipcard
           readers:
diff -Nru a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
--- a/drivers/usb/serial/kobil_sct.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/serial/kobil_sct.c	2004-05-25 21:38:09 -07:00
@@ -21,6 +21,9 @@
  * Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus
  * (Adapter K), B1 Professional and KAAN Professional (Adapter B)
  * 
+ * (21/05/2004) tw
+ *      Fix bug with P'n'P readers
+ *
  * (28/05/2003) tw
  *      Add support for KAAN SIM
  *
@@ -59,7 +62,7 @@
 #include "usb-serial.h"
 
 /* Version Information */
-#define DRIVER_VERSION "28/05/2003"
+#define DRIVER_VERSION "21/05/2004"
 #define DRIVER_AUTHOR "KOBIL Systems GmbH - http://www.kobil.com"
 #define DRIVER_DESC "KOBIL USB Smart Card Terminal Driver (experimental)"
 
@@ -339,6 +342,12 @@
 			);
 		dbg("%s - port %d Send reset_all_queues URB returns: %i", __FUNCTION__, port->number, result);
 	}
+	if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
+	    priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
+		// start reading (Adapter B 'cause PNP string)
+		result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC  ); 
+		dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
+	}
 
 	kfree(transfer_buffer);
 	return 0;
@@ -456,6 +465,11 @@
 	if ( ((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) || 
 	     ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4))) ) {
 		
+		// stop reading (except TWIN and KAAN SIM)
+		if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) ) {
+			usb_unlink_urb( port->interrupt_in_urb );
+		}
+
 		todo = priv->filled - priv->cur_pos;
 
 		while(todo > 0) {
@@ -463,25 +477,23 @@
 			length = (todo < 8) ? todo : 8;
 			// copy data to transfer buffer
 			memcpy(port->write_urb->transfer_buffer, priv->buf + priv->cur_pos, length );
-			
-			usb_fill_bulk_urb( port->write_urb,
-					   port->serial->dev,
-					   usb_sndbulkpipe( port->serial->dev, priv->write_int_endpoint_address),
-					   port->write_urb->transfer_buffer,
-					   length,
-					   kobil_write_callback,
-					   port
+			usb_fill_int_urb( port->write_urb,
+					  port->serial->dev,
+					  usb_sndintpipe(port->serial->dev, priv->write_int_endpoint_address),
+					  port->write_urb->transfer_buffer,
+					  length,
+					  kobil_write_callback,
+					  port,
+					  8
 				);
 
 			priv->cur_pos = priv->cur_pos + length;
-			result = usb_submit_urb( port->write_urb, GFP_ATOMIC );
+			result = usb_submit_urb( port->write_urb, GFP_NOIO );
 			dbg("%s - port %d Send write URB returns: %i", __FUNCTION__, port->number, result);
 			todo = priv->filled - priv->cur_pos;
 
 			if (todo > 0) {
-				//mdelay(16);
-				set_current_state(TASK_UNINTERRUPTIBLE);
-				schedule_timeout(24 * HZ / 1000);
+				msleep(24);
 			}
 
 		} // end while
@@ -492,9 +504,14 @@
 		// someone sets the dev to 0 if the close method has been called
 		port->interrupt_in_urb->dev = port->serial->dev;
 		
-		// start reading
-		result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC ); 
-		dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
+		// start reading (except TWIN and KAAN SIM)
+		if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) ) {
+			// someone sets the dev to 0 if the close method has been called
+			port->interrupt_in_urb->dev = port->serial->dev;
+			
+			result = usb_submit_urb( port->interrupt_in_urb, GFP_NOIO ); 
+			dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
+		}
 	}
 	return count;
 }
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/serial/visor.c	2004-05-25 21:38:09 -07:00
@@ -680,7 +680,7 @@
 	char *string;
 	int retval = 0;
 	int i;
-	int num_ports;
+	int num_ports = 0;
 
 	dbg("%s", __FUNCTION__);
 
@@ -702,41 +702,50 @@
 			__FUNCTION__, retval);
 		goto exit;
 	}
-		
-	connection_info = (struct visor_connection_info *)transfer_buffer;
 
-	le16_to_cpus(&connection_info->num_ports);
-	num_ports = connection_info->num_ports;
-	/* handle devices that report invalid stuff here */
-	if (num_ports > 2)
-		num_ports = 2;
-	dev_info(dev, "%s: Number of ports: %d\n", serial->type->name,
-		connection_info->num_ports);
+	if (retval == sizeof(*connection_info)) {
+	        connection_info = (struct visor_connection_info *)transfer_buffer;
+
+		le16_to_cpus(&connection_info->num_ports);
+		num_ports = connection_info->num_ports;
 
-	for (i = 0; i < num_ports; ++i) {
-		switch (connection_info->connections[i].port_function_id) {
-			case VISOR_FUNCTION_GENERIC:
-				string = "Generic";
-				break;
-			case VISOR_FUNCTION_DEBUGGER:
-				string = "Debugger";
-				break;
-			case VISOR_FUNCTION_HOTSYNC:
-				string = "HotSync";
-				break;
-			case VISOR_FUNCTION_CONSOLE:
-				string = "Console";
-				break;
-			case VISOR_FUNCTION_REMOTE_FILE_SYS:
-				string = "Remote File System";
-				break;
-			default:
-				string = "unknown";
-				break;	
+		for (i = 0; i < num_ports; ++i) {
+			switch (connection_info->connections[i].port_function_id) {
+				case VISOR_FUNCTION_GENERIC:
+					string = "Generic";
+					break;
+				case VISOR_FUNCTION_DEBUGGER:
+					string = "Debugger";
+					break;
+				case VISOR_FUNCTION_HOTSYNC:
+					string = "HotSync";
+					break;
+				case VISOR_FUNCTION_CONSOLE:
+					string = "Console";
+					break;
+				case VISOR_FUNCTION_REMOTE_FILE_SYS:
+					string = "Remote File System";
+					break;
+				default:
+					string = "unknown";
+					break;
+			}
+			dev_info(dev, "%s: port %d, is for %s use\n",
+				serial->type->name,
+				connection_info->connections[i].port, string);
 		}
-		dev_info(dev, "%s: port %d, is for %s use\n", serial->type->name,
-			 connection_info->connections[i].port, string);
 	}
+	/*
+	* Handle devices that report invalid stuff here.
+	*/
+	if (num_ports == 0 || num_ports > 2) {
+		dev_warn (dev, "%s: No valid connect info available\n",
+			serial->type->name);
+		num_ports = 2;
+	}
+  
+	dev_info(dev, "%s: Number of ports: %d\n", serial->type->name,
+		num_ports);
 
 	/*
 	 * save off our num_ports info so that we can use it in the
@@ -868,8 +877,7 @@
  
 static int treo_attach (struct usb_serial *serial)
 {
-	struct usb_serial_port *port;
-	int i;
+	struct usb_serial_port *swap_port;
 
 	/* Only do this endpoint hack for the Handspring devices with
 	 * interrupt in endpoints, which for now are the Treo devices. */
@@ -879,31 +887,28 @@
 
 	dbg("%s", __FUNCTION__);
 
-	/* Ok, this is pretty ugly, but these devices want to use the
-	 * interrupt endpoint as paired up with a bulk endpoint for a
-	 * "virtual serial port".  So let's force the endpoints to be
-	 * where we want them to be. */
-	for (i = serial->num_bulk_in; i < serial->num_ports; ++i) {
-		port = serial->port[i];
-		port->read_urb = serial->port[0]->read_urb;
-		port->bulk_in_endpointAddress = serial->port[0]->bulk_in_endpointAddress;
-		port->bulk_in_buffer = serial->port[0]->bulk_in_buffer;
-	}
-
-	for (i = serial->num_bulk_out; i < serial->num_ports; ++i) {
-		port = serial->port[i];
-		port->write_urb = serial->port[0]->write_urb;
-		port->bulk_out_size = serial->port[0]->bulk_out_size;
-		port->bulk_out_endpointAddress = serial->port[0]->bulk_out_endpointAddress;
-		port->bulk_out_buffer = serial->port[0]->bulk_out_buffer;
-	}
-
-	for (i = serial->num_interrupt_in; i < serial->num_ports; ++i) {
-		port = serial->port[i];
-		port->interrupt_in_urb = serial->port[0]->interrupt_in_urb;
-		port->interrupt_in_endpointAddress = serial->port[0]->interrupt_in_endpointAddress;
-		port->interrupt_in_buffer = serial->port[0]->interrupt_in_buffer;
-	}
+	/*
+	* It appears that Treos want to use the 1st interrupt endpoint to
+	* communicate with the 2nd bulk out endpoint, so let's swap the 1st
+	* and 2nd bulk in and interrupt endpoints.  Note that swapping the
+	* bulk out endpoints would break lots of apps that want to communicate
+	* on the second port.
+	*/
+#define COPY_PORT(dest, src)						\
+	dest->read_urb = src->read_urb;					\
+	dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;	\
+	dest->bulk_in_buffer = src->bulk_in_buffer;			\
+	dest->interrupt_in_urb = src->interrupt_in_urb;			\
+	dest->interrupt_in_endpointAddress = src->interrupt_in_endpointAddress;	\
+	dest->interrupt_in_buffer = src->interrupt_in_buffer;
+
+	swap_port = kmalloc(sizeof(*swap_port), GFP_KERNEL);
+	if (!swap_port)
+		return -ENOMEM;
+	COPY_PORT(swap_port, serial->port[0]);
+	COPY_PORT(serial->port[0], serial->port[1]);
+	COPY_PORT(serial->port[1], swap_port);
+	kfree(swap_port);
 
 	return 0;
 }
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c	2004-05-25 21:38:09 -07:00
+++ b/drivers/usb/storage/transport.c	2004-05-25 21:38:09 -07:00
@@ -1112,8 +1112,7 @@
 
 	/* long wait for reset, so unlock to allow disconnects */
 	up(&us->dev_semaphore);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ*6);
+	msleep(6000);
 	down(&us->dev_semaphore);
 	if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
 		US_DEBUGP("Reset interrupted by disconnect\n");
