Project

General

Profile

Actions

Bug #15502

open

Bug #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

Added by Carsten Grzemba 2 months ago. Updated 2 months ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
-
Start date:
Due date:
% Done:

0%

Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:
External Bug:

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.

Actions #1

Updated by Electric Monk 2 months ago

  • Gerrit CR set to 2731
Actions #2

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?

Actions #3

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.

Actions

Also available in: Atom PDF