[resend] Questions about "usb usb8-port1: cannot disable (err = -32)"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I resent this email with adding Mathias, Alan and Greg as CC.

-----Original Message-----
From: Yoshihiro Shimoda, Sent: Thursday, January 18, 2018 6:03 PM
To: linux-usb@xxxxxxxxxxxxxxx
Subject: Questions about "usb usb8-port1: cannot disable (err = -32)"

Hi,

My environment (R-Car H3) outputs the following error when I disconnected
a usb 3.0 SSD device from the xhci host controller.

[  267.755777] xhci-hcd ee000000.usb: Cannot set link state.
[  267.761188] usb usb8-port1: cannot disable (err = -32)
[  267.772166] usb 8-1: USB disconnect, device number 2

But, the environment can detect connection again.

I investigate this issue and found the following commit is related:
  37be6676 usb: hub: Fix auto-remount of safely removed or ejected USB-3 devices

The xhci-hub.c has the following code:
                        if ((temp & PORT_PE) == 0 ||
                                (link_state > USB_SS_PORT_LS_U3)) {
                                xhci_warn(xhci, "Cannot set link state.\n");
                                goto error;
                        }

And, the code above will be called by hub_set_port_link_state(..., USB_SS_PORT_LS_U3)
in hub_port_disable():
/*
 * USB-3 does not have a similar link state as USB-2 that will avoid negotiating
 * a connection with a plugged-in cable but will signal the host when the cable
 * is unplugged. Disable remote wake and set link state to U3 for USB-3 devices
 */
static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
{
        struct usb_port *port_dev = hub->ports[port1 - 1];
        struct usb_device *hdev = hub->hdev;
        int ret = 0;

        if (!hub->error) {
                if (hub_is_superspeed(hub->hdev)) {
                        hub_usb3_port_prepare_disable(hub, port_dev);
                        ret = hub_set_port_link_state(hub, port_dev->portnum,
                                                      USB_SS_PORT_LS_U3);

The hub_port_disable() will be called by port_event():
       /*
         * Warm reset a USB3 protocol port if it's in
         * SS.Inactive state.
         */
        if (hub_port_warm_reset_required(hub, port1, portstatus)) {
                dev_dbg(&port_dev->dev, "do warm reset\n");
                if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION)
                                || udev->state == USB_STATE_NOTATTACHED) {
                        if (hub_port_reset(hub, port1, NULL,
                                        HUB_BH_RESET_TIME, true) < 0)
                                hub_port_disable(hub, port1, 1);

However, according to Figure 35 in xhci spec, the PED will be set to 0
after the usb3 root hub enters "Error" or "Disconnected" state.
So, IIUC, a usb driver should not call hub_set_port_link_state() in such a case.

Question 1:
 - Is my understanding correct?

Question 2:
 - How do I resolve the issue? (I don't have any idea for now...)

Best regards,
Yoshihiro Shimoda

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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux