[PATCH 0/5] usb: xhci: Fix breakage on dual-role case

From: Roger Quadros
Date: Tue Aug 18 2015 - 06:42:58 EST


Hi,

Plugging and unplugging a USB-OTG adapter with a USB device into a
am437x-gp-evm dual-role port (USB1) causes XHCI to malfunction
and USB device to be no longer detected after a few iterations.

The triggering case is so
1) USB1 in peripheal mode
2) plug OTG adapter with USB device
3) USB1 switches to host mode
4) Detects new USB device
5) unplug OTG adapter
6) OTG core tries to remove host controller while new device
is being processed.

At 6 some races are observed in the XHCI driver causing it to
malfunction. See kernel log at the end of this mail.

This series tries to address some of the issues.
Althouth it is not 100% fool proof yet and XHCI can still get
stuck up for a few seconds occasionally, it did recover always
in a max of 10 seconds and the USB device was enumerated after
that.

During a dual-role switch, usb_remove_hcd() and usb_add_hcd()
will be called consecutively for both Shared and Primary
HCDs. This can happen asynchronously and we have to be prepared
for it.

--
cheers,
-roger

Roger Quadros (5):
usb: xhci: lock mutex on xhci_stop
usb: hcd: Initialize hcd->flags to 0
usb: xhci: Clear XHCI_STATE_DYING on start
usb: xhci: stop everything on the first call to xhci_stop
usb: xhci: exit early in xhci_setup_device() if we're halted or dying

drivers/usb/core/hcd.c | 1 +
drivers/usb/host/xhci.c | 24 +++++++++++-------------
2 files changed, 12 insertions(+), 13 deletions(-)

--
2.1.4

kernel log during dual-role switch.
Platform: am437x-gp-evm.
Test case: Repeatedly plug and unplug a USB-OTG adapter to/from a dual
role port (USB1 in this case) with Mass storage device attached to the
adapter all the while.

Adapter plugged

[ 112.720322] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[ 112.726209] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 3
[ 112.736919] xhci-hcd xhci-hcd.0.auto: hcc params 0x0238f06d hci version 0x100 quirks 0x00010010
[ 112.746162] xhci-hcd xhci-hcd.0.auto: irq 216, io mem 0x48390000
[ 112.754717] usb usb3: New USB device found, idVendor=1d6b, idProduct=0002
[ 112.761815] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 112.769423] usb usb3: Product: xHCI Host Controller
[ 112.774542] usb usb3: Manufacturer: Linux 4.2.0-rc6-00027-g26afc4a xhci-hcd
[ 112.781805] usb usb3: SerialNumber: xhci-hcd.0.auto
[ 112.791761] hub 3-0:1.0: USB hub found
[ 112.796374] hub 3-0:1.0: 1 port detected
[ 112.801893] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[ 112.807786] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 4
[ 112.828676] usb usb4: We don't know the algorithms for LPM for this host, disabling LPM.
[ 112.842572] usb usb4: New USB device found, idVendor=1d6b, idProduct=0003
[ 112.849911] usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 112.857537] usb usb4: Product: xHCI Host Controller
[ 112.862640] usb usb4: Manufacturer: Linux 4.2.0-rc6-00027-g26afc4a xhci-hcd
[ 112.869973] usb usb4: SerialNumber: xhci-hcd.0.auto
[ 112.888053] hub 4-0:1.0: USB hub found
[ 112.893454] hub 4-0:1.0: 1 port detected

adapter unplugged

[ 113.114023] usb 3-1: new high-speed USB device number 2 using xhci-hcd
[ 113.254855] usb 3-1: New USB device found, idVendor=0781, idProduct=5539
[ 113.261863] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 113.269374] usb 3-1: Product: Cruzer Micro
[ 113.273652] usb 3-1: Manufacturer: SanDisk
[ 113.277953] usb 3-1: SerialNumber: 173733160C524A8E
[ 113.288636] usb-storage 3-1:1.0: USB Mass Storage device detected
[ 113.296663] scsi host7: usb-storage 3-1:1.0
[ 113.368620] xhci-hcd xhci-hcd.0.auto: remove, state 4
[ 113.374142] usb usb4: USB disconnect, device number 1
[ 113.382381] usb 3-1: USB disconnect, device number 2
[ 113.405815] xhci-hcd xhci-hcd.0.auto: USB bus 4 deregistered
[ 113.411817] xhci-hcd xhci-hcd.0.auto: remove, state 1
[ 113.417278] usb usb3: USB disconnect, device number 1
[ 113.449219] xhci-hcd xhci-hcd.0.auto: USB bus 3 deregistered

adapter plugged

[ 116.540119] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[ 116.545984] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 3
[ 116.555638] xhci-hcd xhci-hcd.0.auto: hcc params 0x0238f06d hci version 0x100 quirks 0x00010010
[ 116.564863] xhci-hcd xhci-hcd.0.auto: irq 216, io mem 0x48390000
[ 116.571860] usb usb3: New USB device found, idVendor=1d6b, idProduct=0002
[ 116.579005] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 116.586567] usb usb3: Product: xHCI Host Controller
[ 116.591655] usb usb3: Manufacturer: Linux 4.2.0-rc6-00027-g26afc4a xhci-hcd
[ 116.598940] usb usb3: SerialNumber: xhci-hcd.0.auto
[ 116.609018] hub 3-0:1.0: USB hub found
[ 116.613451] hub 3-0:1.0: 1 port detected
[ 116.619814] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[ 116.625711] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 4
[ 116.646673] usb usb4: We don't know the algorithms for LPM for this host, disabling LPM.
[ 116.657195] usb usb4: New USB device found, idVendor=1d6b, idProduct=0003
[ 116.664508] usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 116.672055] usb usb4: Product: xHCI Host Controller
[ 116.677213] usb usb4: Manufacturer: Linux 4.2.0-rc6-00027-g26afc4a xhci-hcd
[ 116.684505] usb usb4: SerialNumber: xhci-hcd.0.auto
[ 116.701494] hub 4-0:1.0: USB hub found
[ 116.707150] hub 4-0:1.0: 1 port detected

adapter unplugged

[ 116.934027] usb 3-1: new high-speed USB device number 2 using xhci-hcd
[ 117.059900] xhci-hcd xhci-hcd.0.auto: remove, state 4
[ 117.065290] usb usb4: USB disconnect, device number 1
[ 117.098888] xhci-hcd xhci-hcd.0.auto: Host not halted after 16000 microseconds.
[ 117.106745] xhci-hcd xhci-hcd.0.auto: USB bus 4 deregistered
[ 117.112725] xhci-hcd xhci-hcd.0.auto: remove, state 1
[ 117.118084] usb usb3: USB disconnect, device number 1

we're stuck now.


root@rockdesk:~# [ 127.084066] xhci-hcd xhci-hcd.0.auto: xHCI host not responding to stop endpoint command.
[ 127.092524] xhci-hcd xhci-hcd.0.auto: Assuming host is dying, halting host.
[ 127.100745] xhci-hcd xhci-hcd.0.auto: HC died; cleaning up
[ 127.107143] usb 3-1: device descriptor read/all, error -110
[ 127.113131] usb usb3-port1: couldn't allocate usb_device
[ 127.126927] xhci-hcd xhci-hcd.0.auto: USB bus 3 deregistered


adapter plugged

root@rockdesk:~# [ 139.871074] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[ 139.876974] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 3
[ 139.894434] xhci-hcd xhci-hcd.0.auto: hcc params 0x0238f06d hci version 0x100 quirks 0x00010010
[ 139.903587] xhci-hcd xhci-hcd.0.auto: irq 216, io mem 0x48390000
[ 139.916843] usb usb3: New USB device found, idVendor=1d6b, idProduct=0002
[ 139.923996] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 139.931540] usb usb3: Product: xHCI Host Controller
[ 139.936668] usb usb3: Manufacturer: Linux 4.2.0-rc6-00027-g26afc4a xhci-hcd
[ 139.943922] usb usb3: SerialNumber: xhci-hcd.0.auto
[ 139.954144] hub 3-0:1.0: USB hub found
[ 139.958632] hub 3-0:1.0: 1 port detected
[ 139.969142] xhci-hcd xhci-hcd.0.auto: HC died; cleaning up
[ 139.976289] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[ 139.982065] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 4
[ 140.235596] irq 216: nobody cared (try booting with the "irqpoll" option)
[ 140.242725] CPU: 0 PID: 2293 Comm: getty Not tainted 4.2.0-rc6-00027-g26afc4a #129
[ 140.250644] Hardware name: Generic AM43 (Flattened Device Tree)
[ 140.256869] [<c0016614>] (unwind_backtrace) from [<c0012b10>] (show_stack+0x10/0x14)
[ 140.264977] [<c0012b10>] (show_stack) from [<c05eb9f4>] (dump_stack+0x80/0x9c)
[ 140.272546] [<c05eb9f4>] (dump_stack) from [<c009b3d8>] (__report_bad_irq+0x20/0xc0)
[ 140.280645] [<c009b3d8>] (__report_bad_irq) from [<c009b97c>] (note_interrupt+0x250/0x2b0)
[ 140.289301] [<c009b97c>] (note_interrupt) from [<c009916c>] (handle_irq_event_percpu+0xd4/0x204)
[ 140.298499] [<c009916c>] (handle_irq_event_percpu) from [<c00992dc>] (handle_irq_event+0x40/0x64)
[ 140.307780] [<c00992dc>] (handle_irq_event) from [<c009c1e8>] (handle_fasteoi_irq+0xcc/0x1a8)
[ 140.316693] [<c009c1e8>] (handle_fasteoi_irq) from [<c00989ac>] (generic_handle_irq+0x20/0x30)
[ 140.325697] [<c00989ac>] (generic_handle_irq) from [<c0098ac0>] (__handle_domain_irq+0x64/0xdc)
[ 140.334794] [<c0098ac0>] (__handle_domain_irq) from [<c00094c4>] (gic_handle_irq+0x20/0x60)
[ 140.343534] [<c00094c4>] (gic_handle_irq) from [<c05f2864>] (__irq_svc+0x44/0x5c)
[ 140.351349] Exception stack(0xed2b1d38 to 0xed2b1d80)
[ 140.356630] 1d20: 00000001 00000000
[ 140.365183] 1d40: 00000000 ed6f6dc0 00000000 c08bd5c4 00000202 c096fd6c 00000001 ed2b0000
[ 140.373734] 1d60: ee008800 00000001 00000000 ed2b1d80 c008e870 c00439c8 60000113 ffffffff
[ 140.382274] [<c05f2864>] (__irq_svc) from [<c00439c8>] (__do_softirq+0xb4/0x350)
[ 140.389995] [<c00439c8>] (__do_softirq) from [<c0043f84>] (irq_exit+0xbc/0x130)
[ 140.397622] [<c0043f84>] (irq_exit) from [<c0098ac8>] (__handle_domain_irq+0x6c/0xdc)
[ 140.405785] [<c0098ac8>] (__handle_domain_irq) from [<c00094c4>] (gic_handle_irq+0x20/0x60)
[ 140.414508] [<c00094c4>] (gic_handle_irq) from [<c05f2864>] (__irq_svc+0x44/0x5c)
[ 140.422326] Exception stack(0xed2b1e00 to 0xed2b1e48)
[ 140.427599] 1e00: ed089d04 c0784128 c1156414 ed089d28 ed089cc0 00000000 c08bd7fc 00000005
[ 140.436140] 1e20: ed2b1f74 ed2b0000 00000000 00000001 00000000 ed2b1e48 c0166418 c0088b70
[ 140.444675] 1e40: 60000013 ffffffff
[ 140.448325] [<c05f2864>] (__irq_svc) from [<c0088b70>] (debug_mutex_init+0x0/0x34)
[ 140.456228] [<c0088b70>] (debug_mutex_init) from [<ed2b1f74>] (0xed2b1f74)
[ 140.463409] handlers:
[ 140.465951] [<bf14e7c0>] usb_hcd_irq [usbcore]
[ 140.470601] Disabling IRQ #216

Message from syslogd@rockdesk at Jan 1 00:02:20 ...
kernel:[ 140.470601] Disabling IRQ #216
[ 140.518776] usb usb4: We don't know the algorithms for LPM for this host, disabling LPM.
[ 140.556446] usb usb4: New USB device found, idVendor=1d6b, idProduct=0003
[ 140.563551] usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 140.571211] usb usb4: Product: xHCI Host Controller
[ 140.576412] usb usb4: Manufacturer: Linux 4.2.0-rc6-00027-g26afc4a xhci-hcd
[ 140.583669] usb usb4: SerialNumber: xhci-hcd.0.auto
[ 140.619169] hub 4-0:1.0: USB hub found
[ 140.626027] hub 4-0:1.0: 1 port detected

Mass storage device wasn't enumerated.

root@rockdesk:~# [ 146.714445] xhci-hcd xhci-hcd.0.auto: remove, state 4
[ 146.719787] usb usb4: USB disconnect, device number 1
[ 146.753175] xhci-hcd xhci-hcd.0.auto: Host not halted after 16000 microseconds.
[ 146.761035] xhci-hcd xhci-hcd.0.auto: USB bus 4 deregistered
[ 146.767041] xhci-hcd xhci-hcd.0.auto: remove, state 1
[ 146.772353] usb usb3: USB disconnect, device number 1
[ 146.786007] xhci-hcd xhci-hcd.0.auto: USB bus 3 deregistered



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/