linux/drivers/usb/core
Sarah Sharp 04a723ea9c USB: Fix duplicate sysfs problem after device reset.
Borislav Petkov reports issues with duplicate sysfs endpoint files after a
resume from a hibernate.  It turns out that the code to support alternate
settings under xHCI has issues when a device with a non-default alternate
setting is reset during the hibernate:

[  427.681810] Restarting tasks ...
[  427.681995] hub 1-0:1.0: state 7 ports 6 chg 0004 evt 0000
[  427.682019] usb usb3: usb resume
[  427.682030] ohci_hcd 0000:00:12.0: wakeup root hub
[  427.682191] hub 1-0:1.0: port 2, status 0501, change 0000, 480 Mb/s
[  427.682205] usb 1-2: usb wakeup-resume
[  427.682226] usb 1-2: finish reset-resume
[  427.682886] done.
[  427.734658] ehci_hcd 0000:00:12.2: port 2 high speed
[  427.734663] ehci_hcd 0000:00:12.2: GetStatus port 2 status 001005 POWER sig=se0 PE CONNECT
[  427.746682] hub 3-0:1.0: hub_reset_resume
[  427.746693] hub 3-0:1.0: trying to enable port power on non-switchable hub
[  427.786715] usb 1-2: reset high speed USB device using ehci_hcd and address 2
[  427.839653] ehci_hcd 0000:00:12.2: port 2 high speed
[  427.839666] ehci_hcd 0000:00:12.2: GetStatus port 2 status 001005 POWER sig=se0 PE CONNECT
[  427.847717] ohci_hcd 0000:00:12.0: GetStatus roothub.portstatus [1] = 0x00010100 CSC PPS
[  427.915497] hub 1-2:1.0: remove_intf_ep_devs: if: ffff88022f9e8800 ->ep_devs_created: 1
[  427.915774] hub 1-2:1.0: remove_intf_ep_devs: bNumEndpoints: 1
[  427.915934] hub 1-2:1.0: if: ffff88022f9e8800: endpoint devs removed.
[  427.916158] hub 1-2:1.0: create_intf_ep_devs: if: ffff88022f9e8800 ->ep_devs_created: 0, ->unregistering: 0
[  427.916434] hub 1-2:1.0: create_intf_ep_devs: bNumEndpoints: 1
[  427.916609]  ep_81: create, parent hub
[  427.916632] ------------[ cut here ]------------
[  427.916644] WARNING: at fs/sysfs/dir.c:477 sysfs_add_one+0x82/0x96()
[  427.916649] Hardware name: System Product Name
[  427.916653] sysfs: cannot create duplicate filename '/devices/pci0000:00/0000:00:12.2/usb1/1-2/1-2:1.0/ep_81'
[  427.916658] Modules linked in: binfmt_misc kvm_amd kvm powernow_k8 cpufreq_ondemand cpufreq_powersave cpufreq_userspace freq_table cpufreq_conservative ipv6 vfat fat
+8250_pnp 8250 pcspkr ohci_hcd serial_core k10temp edac_core
[  427.916694] Pid: 278, comm: khubd Not tainted 2.6.33-rc2-00187-g08d869a-dirty #13
[  427.916699] Call Trace:

The problem is caused by a mismatch between the USB core's view of the
device state and the USB device and xHCI host's view of the device state.

After the device reset and re-configuration, the device and the xHCI host
think they are using alternate setting 0 of all interfaces.  However, the
USB core keeps track of the old state, which may include non-zero
alternate settings.  It uses intf->cur_altsetting to keep the endpoint
sysfs files for the old state across the reset.

The bandwidth allocation functions need to know what the xHCI host thinks
the current alternate settings are, so original patch set
intf->cur_altsetting to the alternate setting 0.  This caused duplicate
endpoint files to be created.

The solution is to not set intf->cur_altsetting before calling
usb_set_interface() in usb_reset_and_verify_device().  Instead, we add a
new flag to struct usb_interface to tell usb_hcd_alloc_bandwidth() to use
alternate setting 0 as the currently installed alternate setting.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Tested-by: Borislav Petkov <petkovbb@googlemail.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-01-20 15:24:35 -08:00
..
buffer.c USB: pass mem_flags to dma_alloc_coherent 2009-04-23 14:15:28 -07:00
config.c USB: Fix SS endpoint companion descriptor parsing. 2009-09-23 06:46:18 -07:00
devices.c USB: Don't use GFP_KERNEL while we cannot reset a storage device 2010-01-20 15:24:34 -08:00
devio.c usbdevfs: move compat_ioctl handling to devio.c 2009-12-10 22:55:37 +01:00
driver.c USB: add remove_id sysfs attr for usb drivers 2009-12-11 11:55:26 -08:00
endpoint.c driver model: constify attribute groups 2009-09-15 09:50:47 -07:00
file.c USB: fix possible null deref in init_usb_class() 2009-12-11 11:55:22 -08:00
generic.c USB: Convert a dev_info to a dev_dbg 2009-12-11 11:55:13 -08:00
hcd-pci.c const: constify remaining dev_pm_ops 2009-12-15 08:53:25 -08:00
hcd.c USB: Fix duplicate sysfs problem after device reset. 2010-01-20 15:24:35 -08:00
hcd.h const: constify remaining dev_pm_ops 2009-12-15 08:53:25 -08:00
hub.c USB: Fix duplicate sysfs problem after device reset. 2010-01-20 15:24:35 -08:00
hub.h USB: fix the clear_tt_buffer interface 2009-07-12 15:16:38 -07:00
inode.c const: mark remaining super_operations const 2009-09-22 07:17:24 -07:00
Kconfig Revert USB: usbfs: deprecate and hide option for !embedded 2009-07-12 15:16:39 -07:00
Makefile USB: add the usbfs devices file to debugfs 2009-06-15 21:44:43 -07:00
message.c USB: Don't use GFP_KERNEL while we cannot reset a storage device 2010-01-20 15:24:34 -08:00
notify.c USB : correct comments in usb/core/notify.c 2008-02-01 14:34:44 -08:00
otg_whitelist.h USB: fix codingstyle issues in drivers/usb/core/*.h 2008-02-01 14:35:07 -08:00
quirks.c USB: add quirk to avoid config and interface strings 2009-03-24 16:20:25 -07:00
sysfs.c USB: add speed values for USB 3.0 and wireless controllers 2010-01-20 15:24:35 -08:00
urb.c USB: allow interrupt transfers to WUSB devices 2009-12-11 11:55:14 -08:00
usb.c USB core: fix recent kernel-doc warnings 2009-12-23 11:34:12 -08:00
usb.h USB: add a "remove hardware" sysfs attribute 2009-12-11 11:55:18 -08:00