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]

 



On Wed, Nov 1, 2017 at 4:17 PM, Thang Q. Nguyen <tqnguyen@xxxxxxx> wrote:
> 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.
Hi Mathias,
Do you have any comment on my approach?

Regards,
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