Bug #15502
openBug #15270: Boot from USB 3.0 HD stops in usb_pipe_xopen with notice "driver scsa2usb attempting to open non-default of a USB 3.0 ..."
'Device is gone' error when booting from USB3.0+ disks
0%
Description
Booting from a rpool located on a USB disk will end up in the following error:
WARNING: /pci@0,0/pci1028,a19@14/storage@11/disk@0,0 (sd0): Command failed to complete...Device is gone WARNING: Pool 'rpool' has encountered an uncorrectable I/O failure and has been suspended; `zpool clear` will be required before the pool can be written to. WARNING: Pool 'rpool' has encountered an uncorrectable I/O failure and has been suspended; `zpool clear` will be required before the pool can be written to. NOTICE: driver scsa2usb attempting to open non-default of a USB 3.0 or newer device through usb_pipe_open(). scsa2usb must be updated to use usb_pipe_xopen() to work with USB device Western Digital My Passport 0748. usba_device fffffe5930807580 ep_xdesc fffffe0078f8e8d0 NOTICE: descriptor: flags 0, cmp 1, status 4 WARNING: /pci@0,0/pci1028,a19@14/storage@11 (scsa2usb0): Reinserted device is accessible again. NOTICE: driver scsa2usb attempting to open non-default of a USB 3.0 or newer device through usb_pipe_open(). scsa2usb must be updated to use usb_pipe_xopen() to work with USB device Western Digital My Passport 0748. usba_device fffffe5930807580 ep_xdesc fffffe0078f8e8d0 NOTICE: descriptor: flags 0, cmp 1, status 4 WARNING: /pci@0,0/pci1028,a19@14/storage@11 (scsa2usb0): Reinserted device is accessible again. WARNING: Pool 'rpool' has encountered an uncorrectable I/O failure and has been suspended; `zpool clear` will be required before the pool can be written to. WARNING: Pool 'rpool' has encountered an uncorrectable I/O failure and has been suspended; `zpool clear` will be required before the pool can be written to.
At time of boot the usba driver discovers the already connected devices. It seems that for USB3.0+ (Super Speed Devices) on boot, a state change which hasn't happened is noticed. This leads to a disconnect through the hotplug thread.
The expected reconnect does not take place.
Updated by Carsten Grzemba 2 months ago
The USB devices on test are:
> ::prtusb INDEX DRIVER INST NODE GEN VID.PID PRODUCT 1 xhci 0 pci15d9,1b58 3.0 0000.0000 No Product String 2 hubd 0 hub 2.0 1d6b.0107 USB Virtual Hub 3 scsa2usb 0 storage 2.0 05e3.0715 SD Card Reader 4 scsa2usb 1 storage 3.0 152d.0579 External USB 3.0 5 usb_mid 0 device 2.0 0557.9241 SMCI HID KM 6 usb_mid 1 miscellaneous 2.0 0b1f.03ee RNDIS/Ethernet Gadget
know for xhci
> ::xhci_device Aspeed - USB Virtual Hub Port 01 | Slot 01 | # Endpoints 02 EP Type State Head Tail 0 CONTROL Running 0x8c 0x8c 2 INTR IN Running 0x23 0x1b Hama - SD Card Reader Port 11 | Slot 02 | # Endpoints 03 EP Type State Head Tail 0 CONTROL Running 0x2a 0x2a 2 BULK IN Running 0x8c 0x8c 3 BULK OUT Running 0xa7 0xa7 Intenso - External USB 3.0 Port 18 | Slot 03 | # Endpoints 03 EP Type State Head Tail 0 CONTROL Running 0x32 0x32 2 BULK IN Running 0xfd 0xfd 3 BULK OUT Running 0xec 0xec Linux 5.4.62 with aspeed_vhub - SMCI HID KM Port 01 | Slot 04 | # Endpoints 03 EP Type State Head Tail 0 CONTROL Stopped 0x44 0x44 2 INTR IN Running 0x8 0x0 4 INTR IN Running 0x8 0x0 Linux 5.4.62 with aspeed_vhub - RNDIS/Ethernet Gadget Port 02 | Slot 05 | # Endpoints 01 EP Type State Head Tail 0 CONTROL Running 0x1d 0x1d
At the moment of disconnecting the boot device ::usba_debug_buf reports (hubdi.c:3947)
hubd_hotplug_thread: port 18 mask=0x40000 change=0x7fc0000 connected=0x1
0x40000 stands for port 18, 0x7fc0000 reports a change on port 18
then
hubd_determine_port_status: port=18, state=0x103 ack=0xff hubd_determine_port_status: port 18 read status=0x1103, change=0x0
then (hubdi.c:3966)
handle port 18: new status=0x1103 change=0x0 was_conn=0x1
no change, status 0x1103.
So the new status has the change in 0x1000. For USB 2.0 we have defined
#define PORT_STATUS_PIC 0x1000 /* port indicator control */
for USB3.0 we have a bit maks
#define PORT_STATUS_SPMASK_SS 0x1c00
Corresponding the USB3 specification, the bits 10-12 represents the negotiated speed. Unfortunately the spec in table 10.16.2.6.1 is here not helpfull: mentions only reserved ???
Can we mask out the change of the speed bits and so get rid of the disconnect problem?
Updated by Carsten Grzemba 2 months ago
I would revoke my first attempt (2731) and suggest the following change to prevent the disconnect the bootdevice:
diff --git a/usr/src/uts/common/io/usb/usba/hubdi.c b/usr/src/uts/common/io/usb/usba/hubdi.c
index 5207a51490..7cc90ccb8a 100644
--- a/usr/src/uts/common/io/usb/usba/hubdi.c
+++ b/usr/src/uts/common/io/usb/usba/hubdi.c
@@ -3938,6 +3938,7 @@ hubd_hotplug_thread(void *arg)
for (port = 1; port <= nports; port++) {
usb_port_mask_t port_mask;
boolean_t was_connected;
+ uint16_t prevstate = hubd->h_port_state[port];
port_mask = 1 << port;
was_connected =
@@ -3992,7 +3993,17 @@ hubd_hotplug_thread(void *arg)
* Now check what changed on the port
*/
if ((change & PORT_CHANGE_CSC) || attach_flg) {
- if ((status & PORT_STATUS_CCS) &&
+ if (attach_flg && change == 0 &&
+ hubd->h_usba_device->usb_port_status >= USBA_SUPER_SPEED_DEV &&
+ (status & ~PORT_STATUS_SPMASK_SS) == prevstate)
+ {
+ cmn_err(CE_WARN,
+ "port=%d status=%x ignore change - "
+ "status=0x%x, change=0x%x",
+ port,
+ hubd->h_usba_device->usb_port_status,
+ status, change);
+ } else if ((status & PORT_STATUS_CCS) &&
(!was_connected)) {
/* new device plugged in */
online_child |=
This change prevents the disconnect of the boot device on usba driver attach, if the detected port status change is related only to the USB3 speed bits.