Re: "hub doesn't have any ports" error message on the disabled USB addressable root hub port

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

 



Hi,

On Mon, Oct 23, 2017 at 5:27 PM, Mathias Nyman
<mathias.nyman@xxxxxxxxxxxxxxx> wrote:
> On 23.10.2017 12:37, Thang Q. Nguyen wrote:
>>
>> Hi,
>> In our latest ARM64-based CPU, we use the DesignWare USB which is
>> xHCI-compatible. For some reasons, we disable USB3.0 support so remove the
>> unnecessary USB3.0 capability structure information as specified in the
>> xHCI specification 1.1, section 7.2:
>> "At least one of these capability structures is required for all xHCI
>> implementations. More than one may be defined for implementations that
>> support more that one bus protocol."
>>
>
> So there is no supported protocol capability with revision major == 3, in
> your case.
>
>
>> When booting kernel, linux kernel displays an error message to claim about
>> no USB port on the USB3.0 roothub:
>> [    3.497767] hub 2-0:1.0: config failed, hub doesn't have any ports!
>> (err -19)
>> Although the error message does not affect USB functionality, error
>> message will make users confused.
>>
>> Looking into the XHCI driver, there are always two USB hub ports
>> implemented. This implements the xHCI specification as in 4.19.7:
>> "In a USB3 hub, two independently addressable hub ports exist for each
>> physical down stream connector; a USB2 compatible port accessed through
>> the USB2 connection and a USB3 compatible port accessed through the
>> SuperSpeed connection. The Root Hub of the xHCI emulates this operation by
>> defining a Root Hub PORTSC register for each connection type; USB2
>> (Low-/Full-/High-Speed) or USB3 (SuperSpeed)."
>>
>> But the problem is that, xhci-hcd always pass both USB hub ports to
>> usb-core driver. In case any of USB2 or USB3 compatible port is missing,
>> there is no port on the corresponding hub and kernel will displays the
>> error message.
>>
>> Below are some approaches we suggest to overcome the issue:
>> Approach 1: Allow roothub has no port. The change will look like:
>>         diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
>>         index b5c7336..995d62d 100644
>>         --- a/drivers/usb/core/hub.c
>>         +++ b/drivers/usb/core/hub.c
>>         @@ -1347,6 +1347,9 @@ static int hub_configure(struct usb_hub
>> *hub,
>>                                         ret = -ENODEV;
>>                                         goto fail;
>>                         } else if (hub->descriptor->bNbrPorts == 0) {
>>         +               if (hdev->parent)
>>         +                       return -ENODEV;
>>         +
>>                                         message = "hub doesn't have any
>> ports!";
>>                                         ret = -ENODEV;
>>                                         goto fail;
>> Approach 2: do not pass a USB hub port to usb-core if it has no port.
>> Don't know if this approach is feasible or not.
>> Approach 3: implement maximum-speed attribute support and this will be set
>> to high-speed in case of missing USB3 support. But this works only for the
>> case of USB3.0 disabled.
>>
>> Can you help review and suggest what approach should be used to fix this
>> issue?
>
>
> Current xhci driver design assumes there are two hcds available.
> Several functions assume a shared hcd exists.
>
> Creating a hcd with a roothub with zero ports is probably a faster way to
> get
> things running, but I think we should redesign parts of the xhci driver to
> work with only one hcd.
>
> So best would be to never add the secodary hcd if there are no USB 3 ports,
> meaning no:
>   xhci->shared_hcd = usb_create_shared_hcd(..);
>   usb_add_hcd(xhci->shared_hcd, dev->irq,
Below code is to not add shared_hcd if no USB 3 port:
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 1cb6eae..0881fb5 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -285,12 +285,14 @@ static int xhci_plat_probe(struct platform_device *pdev)
        if (ret)
                goto disable_usb_phy;

-       if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
-               xhci->shared_hcd->can_do_streams = 1;
+       if (xhci->num_usb3_ports > 0) {
+               if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
+                       xhci->shared_hcd->can_do_streams = 1;

-       ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
-       if (ret)
-               goto dealloc_usb2_hcd;
+               ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
+               if (ret)
+                       goto dealloc_usb2_hcd;
+       }

        device_enable_async_suspend(&pdev->dev);
        pm_runtime_put_noidle(&pdev->dev);

Then, the xhci_run should execute xhci_start() in case no USB 3 port
(xhci->shared_hcd->run() will execute xhci_run_finished() which run
xhci_start().
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 51535ba..3ad41aa 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -630,6 +630,16 @@ int xhci_run(struct usb_hcd *hcd)
                if (ret)
                        xhci_free_command(xhci, command);
        }
+
+       /* Execute xhci_start() in case xhci->shared_hcd is not registered */
+       if (xhci->num_usb3_ports > 0) {
+               if (xhci_start(xhci)) {
+                       xhci_halt(xhci);
+                       return -ENODEV;
+               }
+               xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
+       }
+
        xhci_dbg_trace(xhci, trace_xhci_dbg_init,
                        "Finished xhci_run for USB2 roothub");
        return 0;

>
> Instead we need to make sure xhci->shared_hcd is set to NULL,
> and modify at least the following functions to work with only one xhci hcd:
Do we really need to set xhci->shared_hcd to NULL? when
xhci->shared_hcd is not registered to usb_core, no operation work on
it.
>
> xhci_run()
> xhci_stop()
> xhci_suspend()
> xhci_resume()
> xhci_gen_setup()
>
> More changes are very likely needed,  but this is a place to start
>
> -Mathias
>
>
- ThangQ.
--
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