Re: [PATCH v1 1/1] usb: xhci: do not create and register shared_hcd when USB3.0 is disabled

2018-01-18 Thread Mathias Nyman

On 18.01.2018 09:27, Tung Vuong Nguyen wrote:

On Tue, Jan 16, 2018 at 9:50 PM, Mathias Nyman
 wrote:


Hi, Sorry about the delay


On 04.01.2018 07:17, Thang Q. Nguyen wrote:


Hi,

On Sat, Dec 16, 2017 at 10:45 AM, Thang Q. Nguyen  wrote:


From: Tung Nguyen 

Currently, hcd->shared_hcd always creates and registers to the usb-core.
If, for some reasons, USB3 downstream port is disabled, no roothub port for
USB3.0 is found. This causes kernel to display an error:
hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
This patch checks, creates and registers shared_hcd if USB3.0 downstream
port is available.

Signed-off-by: Tung Nguyen 
Signed-off-by: Thang Q. Nguyen 
---
   drivers/usb/host/xhci-mem.c  |  2 +-
   drivers/usb/host/xhci-plat.c | 26 +++--
   drivers/usb/host/xhci.c  | 54 

   3 files changed, 54 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 554a8a5..157d1e7 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1067,7 +1067,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd 
*xhci,
  struct usb_device *top_dev;
  struct usb_hcd *hcd;

-   if (udev->speed >= USB_SPEED_SUPER)
+   if (udev->speed >= USB_SPEED_SUPER && xhci->shared_hcd)
  hcd = xhci->shared_hcd;
  else
  hcd = xhci->main_hcd;
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 6f03830..e812e3d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -253,12 +253,6 @@ static int xhci_plat_probe(struct platform_device *pdev)

  xhci->clk = clk;
  xhci->main_hcd = hcd;
-   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
-   dev_name(>dev), hcd);
-   if (!xhci->shared_hcd) {
-   ret = -ENOMEM;
-   goto disable_clk;
-   }

  if (device_property_read_bool(sysdev, "usb2-lpm-disable"))
  xhci->quirks |= XHCI_HW_LPM_DISABLE;
@@ -290,12 +284,20 @@ 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;
-
-   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
-   if (ret)
-   goto dealloc_usb2_hcd;
+   if (xhci->num_usb3_ports > 0) {
+   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
+   dev_name(>dev), hcd);
+   if (!xhci->shared_hcd) {
+   ret = -ENOMEM;
+   goto disable_clk;
+   }
+   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;
+   }

  device_enable_async_suspend(>dev);
  pm_runtime_put_noidle(>dev);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 05104bd..4824bf6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -417,12 +417,14 @@ static void compliance_mode_recovery(struct timer_list *t)
  i + 1);
  xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
  "Attempting compliance mode 
recovery");
-   hcd = xhci->shared_hcd;
+   if (xhci->shared_hcd) {
+   hcd = xhci->shared_hcd;

-   if (hcd->state == HC_STATE_SUSPENDED)
-   usb_hcd_resume_root_hub(hcd);
+   if (hcd->state == HC_STATE_SUSPENDED)
+   usb_hcd_resume_root_hub(hcd);

-   usb_hcd_poll_rh_status(hcd);
+   usb_hcd_poll_rh_status(hcd);
+   }
  }
  }

@@ -611,6 +613,18 @@ 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 the xhci->shared_hcd doesn't exist, no one triggers to start
+* the xhci which should be done before exitting run function
+*/
+   if (!xhci->shared_hcd) {
+   if (xhci_start(xhci)) {



This probably won't work as primary hcd was added before shared_hcd was created.
usb_add_hcd(hcd) calls xhci_run() before xhci->shared_hcd exists, so this will
cause the xHC to start before the shared_hcd is created or setup.

-Mathias


Hi Mathias
I 

Re: [PATCH v1 1/1] usb: xhci: do not create and register shared_hcd when USB3.0 is disabled

2018-01-18 Thread Mathias Nyman

On 18.01.2018 09:27, Tung Vuong Nguyen wrote:

On Tue, Jan 16, 2018 at 9:50 PM, Mathias Nyman
 wrote:


Hi, Sorry about the delay


On 04.01.2018 07:17, Thang Q. Nguyen wrote:


Hi,

On Sat, Dec 16, 2017 at 10:45 AM, Thang Q. Nguyen  wrote:


From: Tung Nguyen 

Currently, hcd->shared_hcd always creates and registers to the usb-core.
If, for some reasons, USB3 downstream port is disabled, no roothub port for
USB3.0 is found. This causes kernel to display an error:
hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
This patch checks, creates and registers shared_hcd if USB3.0 downstream
port is available.

Signed-off-by: Tung Nguyen 
Signed-off-by: Thang Q. Nguyen 
---
   drivers/usb/host/xhci-mem.c  |  2 +-
   drivers/usb/host/xhci-plat.c | 26 +++--
   drivers/usb/host/xhci.c  | 54 

   3 files changed, 54 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 554a8a5..157d1e7 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1067,7 +1067,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd 
*xhci,
  struct usb_device *top_dev;
  struct usb_hcd *hcd;

-   if (udev->speed >= USB_SPEED_SUPER)
+   if (udev->speed >= USB_SPEED_SUPER && xhci->shared_hcd)
  hcd = xhci->shared_hcd;
  else
  hcd = xhci->main_hcd;
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 6f03830..e812e3d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -253,12 +253,6 @@ static int xhci_plat_probe(struct platform_device *pdev)

  xhci->clk = clk;
  xhci->main_hcd = hcd;
-   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
-   dev_name(>dev), hcd);
-   if (!xhci->shared_hcd) {
-   ret = -ENOMEM;
-   goto disable_clk;
-   }

  if (device_property_read_bool(sysdev, "usb2-lpm-disable"))
  xhci->quirks |= XHCI_HW_LPM_DISABLE;
@@ -290,12 +284,20 @@ 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;
-
-   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
-   if (ret)
-   goto dealloc_usb2_hcd;
+   if (xhci->num_usb3_ports > 0) {
+   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
+   dev_name(>dev), hcd);
+   if (!xhci->shared_hcd) {
+   ret = -ENOMEM;
+   goto disable_clk;
+   }
+   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;
+   }

  device_enable_async_suspend(>dev);
  pm_runtime_put_noidle(>dev);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 05104bd..4824bf6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -417,12 +417,14 @@ static void compliance_mode_recovery(struct timer_list *t)
  i + 1);
  xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
  "Attempting compliance mode 
recovery");
-   hcd = xhci->shared_hcd;
+   if (xhci->shared_hcd) {
+   hcd = xhci->shared_hcd;

-   if (hcd->state == HC_STATE_SUSPENDED)
-   usb_hcd_resume_root_hub(hcd);
+   if (hcd->state == HC_STATE_SUSPENDED)
+   usb_hcd_resume_root_hub(hcd);

-   usb_hcd_poll_rh_status(hcd);
+   usb_hcd_poll_rh_status(hcd);
+   }
  }
  }

@@ -611,6 +613,18 @@ 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 the xhci->shared_hcd doesn't exist, no one triggers to start
+* the xhci which should be done before exitting run function
+*/
+   if (!xhci->shared_hcd) {
+   if (xhci_start(xhci)) {



This probably won't work as primary hcd was added before shared_hcd was created.
usb_add_hcd(hcd) calls xhci_run() before xhci->shared_hcd exists, so this will
cause the xHC to start before the shared_hcd is created or setup.

-Mathias


Hi Mathias
I ran the test and saw the patch works fine in 2 cases:
xhci->num_usb3_ports = 0 and xhci->num_usb3_ports 

Re: [PATCH v1 1/1] usb: xhci: do not create and register shared_hcd when USB3.0 is disabled

2018-01-17 Thread Tung Vuong Nguyen
On Tue, Jan 16, 2018 at 9:50 PM, Mathias Nyman
 wrote:
>
> Hi, Sorry about the delay
>
>
> On 04.01.2018 07:17, Thang Q. Nguyen wrote:
>>
>> Hi,
>>
>> On Sat, Dec 16, 2017 at 10:45 AM, Thang Q. Nguyen  wrote:
>>>
>>> From: Tung Nguyen 
>>>
>>> Currently, hcd->shared_hcd always creates and registers to the usb-core.
>>> If, for some reasons, USB3 downstream port is disabled, no roothub port for
>>> USB3.0 is found. This causes kernel to display an error:
>>> hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
>>> This patch checks, creates and registers shared_hcd if USB3.0 downstream
>>> port is available.
>>>
>>> Signed-off-by: Tung Nguyen 
>>> Signed-off-by: Thang Q. Nguyen 
>>> ---
>>>   drivers/usb/host/xhci-mem.c  |  2 +-
>>>   drivers/usb/host/xhci-plat.c | 26 +++--
>>>   drivers/usb/host/xhci.c  | 54 
>>> 
>>>   3 files changed, 54 insertions(+), 28 deletions(-)
>>>
>>> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
>>> index 554a8a5..157d1e7 100644
>>> --- a/drivers/usb/host/xhci-mem.c
>>> +++ b/drivers/usb/host/xhci-mem.c
>>> @@ -1067,7 +1067,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd 
>>> *xhci,
>>>  struct usb_device *top_dev;
>>>  struct usb_hcd *hcd;
>>>
>>> -   if (udev->speed >= USB_SPEED_SUPER)
>>> +   if (udev->speed >= USB_SPEED_SUPER && xhci->shared_hcd)
>>>  hcd = xhci->shared_hcd;
>>>  else
>>>  hcd = xhci->main_hcd;
>>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>>> index 6f03830..e812e3d 100644
>>> --- a/drivers/usb/host/xhci-plat.c
>>> +++ b/drivers/usb/host/xhci-plat.c
>>> @@ -253,12 +253,6 @@ static int xhci_plat_probe(struct platform_device 
>>> *pdev)
>>>
>>>  xhci->clk = clk;
>>>  xhci->main_hcd = hcd;
>>> -   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
>>> -   dev_name(>dev), hcd);
>>> -   if (!xhci->shared_hcd) {
>>> -   ret = -ENOMEM;
>>> -   goto disable_clk;
>>> -   }
>>>
>>>  if (device_property_read_bool(sysdev, "usb2-lpm-disable"))
>>>  xhci->quirks |= XHCI_HW_LPM_DISABLE;
>>> @@ -290,12 +284,20 @@ 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;
>>> -
>>> -   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
>>> -   if (ret)
>>> -   goto dealloc_usb2_hcd;
>>> +   if (xhci->num_usb3_ports > 0) {
>>> +   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, 
>>> >dev,
>>> +   dev_name(>dev), hcd);
>>> +   if (!xhci->shared_hcd) {
>>> +   ret = -ENOMEM;
>>> +   goto disable_clk;
>>> +   }
>>> +   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;
>>> +   }
>>>
>>>  device_enable_async_suspend(>dev);
>>>  pm_runtime_put_noidle(>dev);
>>> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
>>> index 05104bd..4824bf6 100644
>>> --- a/drivers/usb/host/xhci.c
>>> +++ b/drivers/usb/host/xhci.c
>>> @@ -417,12 +417,14 @@ static void compliance_mode_recovery(struct 
>>> timer_list *t)
>>>  i + 1);
>>>  xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
>>>  "Attempting compliance mode 
>>> recovery");
>>> -   hcd = xhci->shared_hcd;
>>> +   if (xhci->shared_hcd) {
>>> +   hcd = xhci->shared_hcd;
>>>
>>> -   if (hcd->state == HC_STATE_SUSPENDED)
>>> -   usb_hcd_resume_root_hub(hcd);
>>> +   if (hcd->state == HC_STATE_SUSPENDED)
>>> +   usb_hcd_resume_root_hub(hcd);
>>>
>>> -   usb_hcd_poll_rh_status(hcd);
>>> +   usb_hcd_poll_rh_status(hcd);
>>> +   }
>>>  }
>>>  }
>>>
>>> @@ -611,6 +613,18 @@ 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 the xhci->shared_hcd doesn't exist, no one triggers to start
>>> +* the xhci 

Re: [PATCH v1 1/1] usb: xhci: do not create and register shared_hcd when USB3.0 is disabled

2018-01-17 Thread Tung Vuong Nguyen
On Tue, Jan 16, 2018 at 9:50 PM, Mathias Nyman
 wrote:
>
> Hi, Sorry about the delay
>
>
> On 04.01.2018 07:17, Thang Q. Nguyen wrote:
>>
>> Hi,
>>
>> On Sat, Dec 16, 2017 at 10:45 AM, Thang Q. Nguyen  wrote:
>>>
>>> From: Tung Nguyen 
>>>
>>> Currently, hcd->shared_hcd always creates and registers to the usb-core.
>>> If, for some reasons, USB3 downstream port is disabled, no roothub port for
>>> USB3.0 is found. This causes kernel to display an error:
>>> hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
>>> This patch checks, creates and registers shared_hcd if USB3.0 downstream
>>> port is available.
>>>
>>> Signed-off-by: Tung Nguyen 
>>> Signed-off-by: Thang Q. Nguyen 
>>> ---
>>>   drivers/usb/host/xhci-mem.c  |  2 +-
>>>   drivers/usb/host/xhci-plat.c | 26 +++--
>>>   drivers/usb/host/xhci.c  | 54 
>>> 
>>>   3 files changed, 54 insertions(+), 28 deletions(-)
>>>
>>> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
>>> index 554a8a5..157d1e7 100644
>>> --- a/drivers/usb/host/xhci-mem.c
>>> +++ b/drivers/usb/host/xhci-mem.c
>>> @@ -1067,7 +1067,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd 
>>> *xhci,
>>>  struct usb_device *top_dev;
>>>  struct usb_hcd *hcd;
>>>
>>> -   if (udev->speed >= USB_SPEED_SUPER)
>>> +   if (udev->speed >= USB_SPEED_SUPER && xhci->shared_hcd)
>>>  hcd = xhci->shared_hcd;
>>>  else
>>>  hcd = xhci->main_hcd;
>>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>>> index 6f03830..e812e3d 100644
>>> --- a/drivers/usb/host/xhci-plat.c
>>> +++ b/drivers/usb/host/xhci-plat.c
>>> @@ -253,12 +253,6 @@ static int xhci_plat_probe(struct platform_device 
>>> *pdev)
>>>
>>>  xhci->clk = clk;
>>>  xhci->main_hcd = hcd;
>>> -   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
>>> -   dev_name(>dev), hcd);
>>> -   if (!xhci->shared_hcd) {
>>> -   ret = -ENOMEM;
>>> -   goto disable_clk;
>>> -   }
>>>
>>>  if (device_property_read_bool(sysdev, "usb2-lpm-disable"))
>>>  xhci->quirks |= XHCI_HW_LPM_DISABLE;
>>> @@ -290,12 +284,20 @@ 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;
>>> -
>>> -   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
>>> -   if (ret)
>>> -   goto dealloc_usb2_hcd;
>>> +   if (xhci->num_usb3_ports > 0) {
>>> +   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, 
>>> >dev,
>>> +   dev_name(>dev), hcd);
>>> +   if (!xhci->shared_hcd) {
>>> +   ret = -ENOMEM;
>>> +   goto disable_clk;
>>> +   }
>>> +   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;
>>> +   }
>>>
>>>  device_enable_async_suspend(>dev);
>>>  pm_runtime_put_noidle(>dev);
>>> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
>>> index 05104bd..4824bf6 100644
>>> --- a/drivers/usb/host/xhci.c
>>> +++ b/drivers/usb/host/xhci.c
>>> @@ -417,12 +417,14 @@ static void compliance_mode_recovery(struct 
>>> timer_list *t)
>>>  i + 1);
>>>  xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
>>>  "Attempting compliance mode 
>>> recovery");
>>> -   hcd = xhci->shared_hcd;
>>> +   if (xhci->shared_hcd) {
>>> +   hcd = xhci->shared_hcd;
>>>
>>> -   if (hcd->state == HC_STATE_SUSPENDED)
>>> -   usb_hcd_resume_root_hub(hcd);
>>> +   if (hcd->state == HC_STATE_SUSPENDED)
>>> +   usb_hcd_resume_root_hub(hcd);
>>>
>>> -   usb_hcd_poll_rh_status(hcd);
>>> +   usb_hcd_poll_rh_status(hcd);
>>> +   }
>>>  }
>>>  }
>>>
>>> @@ -611,6 +613,18 @@ 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 the xhci->shared_hcd doesn't exist, no one triggers to start
>>> +* the xhci which should be done before exitting run function
>>> +*/
>>> +   if (!xhci->shared_hcd) {
>>> 

Re: [PATCH v1 1/1] usb: xhci: do not create and register shared_hcd when USB3.0 is disabled

2018-01-16 Thread Mathias Nyman

Hi, Sorry about the delay

On 04.01.2018 07:17, Thang Q. Nguyen wrote:

Hi,

On Sat, Dec 16, 2017 at 10:45 AM, Thang Q. Nguyen  wrote:

From: Tung Nguyen 

Currently, hcd->shared_hcd always creates and registers to the usb-core.
If, for some reasons, USB3 downstream port is disabled, no roothub port for
USB3.0 is found. This causes kernel to display an error:
hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
This patch checks, creates and registers shared_hcd if USB3.0 downstream
port is available.

Signed-off-by: Tung Nguyen 
Signed-off-by: Thang Q. Nguyen 
---
  drivers/usb/host/xhci-mem.c  |  2 +-
  drivers/usb/host/xhci-plat.c | 26 +++--
  drivers/usb/host/xhci.c  | 54 
  3 files changed, 54 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 554a8a5..157d1e7 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1067,7 +1067,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd 
*xhci,
 struct usb_device *top_dev;
 struct usb_hcd *hcd;

-   if (udev->speed >= USB_SPEED_SUPER)
+   if (udev->speed >= USB_SPEED_SUPER && xhci->shared_hcd)
 hcd = xhci->shared_hcd;
 else
 hcd = xhci->main_hcd;
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 6f03830..e812e3d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -253,12 +253,6 @@ static int xhci_plat_probe(struct platform_device *pdev)

 xhci->clk = clk;
 xhci->main_hcd = hcd;
-   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
-   dev_name(>dev), hcd);
-   if (!xhci->shared_hcd) {
-   ret = -ENOMEM;
-   goto disable_clk;
-   }

 if (device_property_read_bool(sysdev, "usb2-lpm-disable"))
 xhci->quirks |= XHCI_HW_LPM_DISABLE;
@@ -290,12 +284,20 @@ 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;
-
-   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
-   if (ret)
-   goto dealloc_usb2_hcd;
+   if (xhci->num_usb3_ports > 0) {
+   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
+   dev_name(>dev), hcd);
+   if (!xhci->shared_hcd) {
+   ret = -ENOMEM;
+   goto disable_clk;
+   }
+   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;
+   }

 device_enable_async_suspend(>dev);
 pm_runtime_put_noidle(>dev);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 05104bd..4824bf6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -417,12 +417,14 @@ static void compliance_mode_recovery(struct timer_list *t)
 i + 1);
 xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
 "Attempting compliance mode recovery");
-   hcd = xhci->shared_hcd;
+   if (xhci->shared_hcd) {
+   hcd = xhci->shared_hcd;

-   if (hcd->state == HC_STATE_SUSPENDED)
-   usb_hcd_resume_root_hub(hcd);
+   if (hcd->state == HC_STATE_SUSPENDED)
+   usb_hcd_resume_root_hub(hcd);

-   usb_hcd_poll_rh_status(hcd);
+   usb_hcd_poll_rh_status(hcd);
+   }
 }
 }

@@ -611,6 +613,18 @@ 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 the xhci->shared_hcd doesn't exist, no one triggers to start
+* the xhci which should be done before exitting run function
+*/
+   if (!xhci->shared_hcd) {
+   if (xhci_start(xhci)) {


This probably won't work as primary hcd was added before shared_hcd was created.
usb_add_hcd(hcd) calls xhci_run() before xhci->shared_hcd exists, so this will
cause the xHC to start before the shared_hcd is created or setup.

-Mathias


Re: [PATCH v1 1/1] usb: xhci: do not create and register shared_hcd when USB3.0 is disabled

2018-01-16 Thread Mathias Nyman

Hi, Sorry about the delay

On 04.01.2018 07:17, Thang Q. Nguyen wrote:

Hi,

On Sat, Dec 16, 2017 at 10:45 AM, Thang Q. Nguyen  wrote:

From: Tung Nguyen 

Currently, hcd->shared_hcd always creates and registers to the usb-core.
If, for some reasons, USB3 downstream port is disabled, no roothub port for
USB3.0 is found. This causes kernel to display an error:
hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
This patch checks, creates and registers shared_hcd if USB3.0 downstream
port is available.

Signed-off-by: Tung Nguyen 
Signed-off-by: Thang Q. Nguyen 
---
  drivers/usb/host/xhci-mem.c  |  2 +-
  drivers/usb/host/xhci-plat.c | 26 +++--
  drivers/usb/host/xhci.c  | 54 
  3 files changed, 54 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 554a8a5..157d1e7 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1067,7 +1067,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd 
*xhci,
 struct usb_device *top_dev;
 struct usb_hcd *hcd;

-   if (udev->speed >= USB_SPEED_SUPER)
+   if (udev->speed >= USB_SPEED_SUPER && xhci->shared_hcd)
 hcd = xhci->shared_hcd;
 else
 hcd = xhci->main_hcd;
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 6f03830..e812e3d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -253,12 +253,6 @@ static int xhci_plat_probe(struct platform_device *pdev)

 xhci->clk = clk;
 xhci->main_hcd = hcd;
-   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
-   dev_name(>dev), hcd);
-   if (!xhci->shared_hcd) {
-   ret = -ENOMEM;
-   goto disable_clk;
-   }

 if (device_property_read_bool(sysdev, "usb2-lpm-disable"))
 xhci->quirks |= XHCI_HW_LPM_DISABLE;
@@ -290,12 +284,20 @@ 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;
-
-   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
-   if (ret)
-   goto dealloc_usb2_hcd;
+   if (xhci->num_usb3_ports > 0) {
+   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
+   dev_name(>dev), hcd);
+   if (!xhci->shared_hcd) {
+   ret = -ENOMEM;
+   goto disable_clk;
+   }
+   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;
+   }

 device_enable_async_suspend(>dev);
 pm_runtime_put_noidle(>dev);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 05104bd..4824bf6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -417,12 +417,14 @@ static void compliance_mode_recovery(struct timer_list *t)
 i + 1);
 xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
 "Attempting compliance mode recovery");
-   hcd = xhci->shared_hcd;
+   if (xhci->shared_hcd) {
+   hcd = xhci->shared_hcd;

-   if (hcd->state == HC_STATE_SUSPENDED)
-   usb_hcd_resume_root_hub(hcd);
+   if (hcd->state == HC_STATE_SUSPENDED)
+   usb_hcd_resume_root_hub(hcd);

-   usb_hcd_poll_rh_status(hcd);
+   usb_hcd_poll_rh_status(hcd);
+   }
 }
 }

@@ -611,6 +613,18 @@ 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 the xhci->shared_hcd doesn't exist, no one triggers to start
+* the xhci which should be done before exitting run function
+*/
+   if (!xhci->shared_hcd) {
+   if (xhci_start(xhci)) {


This probably won't work as primary hcd was added before shared_hcd was created.
usb_add_hcd(hcd) calls xhci_run() before xhci->shared_hcd exists, so this will
cause the xHC to start before the shared_hcd is created or setup.

-Mathias


Re: [PATCH v1 1/1] usb: xhci: do not create and register shared_hcd when USB3.0 is disabled

2018-01-03 Thread Thang Q. Nguyen
Hi,

On Sat, Dec 16, 2017 at 10:45 AM, Thang Q. Nguyen  wrote:
> From: Tung Nguyen 
>
> Currently, hcd->shared_hcd always creates and registers to the usb-core.
> If, for some reasons, USB3 downstream port is disabled, no roothub port for
> USB3.0 is found. This causes kernel to display an error:
> hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
> This patch checks, creates and registers shared_hcd if USB3.0 downstream
> port is available.
>
> Signed-off-by: Tung Nguyen 
> Signed-off-by: Thang Q. Nguyen 
> ---
>  drivers/usb/host/xhci-mem.c  |  2 +-
>  drivers/usb/host/xhci-plat.c | 26 +++--
>  drivers/usb/host/xhci.c  | 54 
> 
>  3 files changed, 54 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
> index 554a8a5..157d1e7 100644
> --- a/drivers/usb/host/xhci-mem.c
> +++ b/drivers/usb/host/xhci-mem.c
> @@ -1067,7 +1067,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd 
> *xhci,
> struct usb_device *top_dev;
> struct usb_hcd *hcd;
>
> -   if (udev->speed >= USB_SPEED_SUPER)
> +   if (udev->speed >= USB_SPEED_SUPER && xhci->shared_hcd)
> hcd = xhci->shared_hcd;
> else
> hcd = xhci->main_hcd;
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 6f03830..e812e3d 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -253,12 +253,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
>
> xhci->clk = clk;
> xhci->main_hcd = hcd;
> -   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
> -   dev_name(>dev), hcd);
> -   if (!xhci->shared_hcd) {
> -   ret = -ENOMEM;
> -   goto disable_clk;
> -   }
>
> if (device_property_read_bool(sysdev, "usb2-lpm-disable"))
> xhci->quirks |= XHCI_HW_LPM_DISABLE;
> @@ -290,12 +284,20 @@ 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;
> -
> -   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
> -   if (ret)
> -   goto dealloc_usb2_hcd;
> +   if (xhci->num_usb3_ports > 0) {
> +   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, 
> >dev,
> +   dev_name(>dev), hcd);
> +   if (!xhci->shared_hcd) {
> +   ret = -ENOMEM;
> +   goto disable_clk;
> +   }
> +   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;
> +   }
>
> device_enable_async_suspend(>dev);
> pm_runtime_put_noidle(>dev);
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 05104bd..4824bf6 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -417,12 +417,14 @@ static void compliance_mode_recovery(struct timer_list 
> *t)
> i + 1);
> xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
> "Attempting compliance mode 
> recovery");
> -   hcd = xhci->shared_hcd;
> +   if (xhci->shared_hcd) {
> +   hcd = xhci->shared_hcd;
>
> -   if (hcd->state == HC_STATE_SUSPENDED)
> -   usb_hcd_resume_root_hub(hcd);
> +   if (hcd->state == HC_STATE_SUSPENDED)
> +   usb_hcd_resume_root_hub(hcd);
>
> -   usb_hcd_poll_rh_status(hcd);
> +   usb_hcd_poll_rh_status(hcd);
> +   }
> }
> }
>
> @@ -611,6 +613,18 @@ 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 the xhci->shared_hcd doesn't exist, no one triggers to start
> +* the xhci which should be done before exitting run function
> +*/
> +   if (!xhci->shared_hcd) {
> +   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");

Re: [PATCH v1 1/1] usb: xhci: do not create and register shared_hcd when USB3.0 is disabled

2018-01-03 Thread Thang Q. Nguyen
Hi,

On Sat, Dec 16, 2017 at 10:45 AM, Thang Q. Nguyen  wrote:
> From: Tung Nguyen 
>
> Currently, hcd->shared_hcd always creates and registers to the usb-core.
> If, for some reasons, USB3 downstream port is disabled, no roothub port for
> USB3.0 is found. This causes kernel to display an error:
> hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
> This patch checks, creates and registers shared_hcd if USB3.0 downstream
> port is available.
>
> Signed-off-by: Tung Nguyen 
> Signed-off-by: Thang Q. Nguyen 
> ---
>  drivers/usb/host/xhci-mem.c  |  2 +-
>  drivers/usb/host/xhci-plat.c | 26 +++--
>  drivers/usb/host/xhci.c  | 54 
> 
>  3 files changed, 54 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
> index 554a8a5..157d1e7 100644
> --- a/drivers/usb/host/xhci-mem.c
> +++ b/drivers/usb/host/xhci-mem.c
> @@ -1067,7 +1067,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd 
> *xhci,
> struct usb_device *top_dev;
> struct usb_hcd *hcd;
>
> -   if (udev->speed >= USB_SPEED_SUPER)
> +   if (udev->speed >= USB_SPEED_SUPER && xhci->shared_hcd)
> hcd = xhci->shared_hcd;
> else
> hcd = xhci->main_hcd;
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 6f03830..e812e3d 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -253,12 +253,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
>
> xhci->clk = clk;
> xhci->main_hcd = hcd;
> -   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
> -   dev_name(>dev), hcd);
> -   if (!xhci->shared_hcd) {
> -   ret = -ENOMEM;
> -   goto disable_clk;
> -   }
>
> if (device_property_read_bool(sysdev, "usb2-lpm-disable"))
> xhci->quirks |= XHCI_HW_LPM_DISABLE;
> @@ -290,12 +284,20 @@ 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;
> -
> -   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
> -   if (ret)
> -   goto dealloc_usb2_hcd;
> +   if (xhci->num_usb3_ports > 0) {
> +   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, 
> >dev,
> +   dev_name(>dev), hcd);
> +   if (!xhci->shared_hcd) {
> +   ret = -ENOMEM;
> +   goto disable_clk;
> +   }
> +   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;
> +   }
>
> device_enable_async_suspend(>dev);
> pm_runtime_put_noidle(>dev);
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 05104bd..4824bf6 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -417,12 +417,14 @@ static void compliance_mode_recovery(struct timer_list 
> *t)
> i + 1);
> xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
> "Attempting compliance mode 
> recovery");
> -   hcd = xhci->shared_hcd;
> +   if (xhci->shared_hcd) {
> +   hcd = xhci->shared_hcd;
>
> -   if (hcd->state == HC_STATE_SUSPENDED)
> -   usb_hcd_resume_root_hub(hcd);
> +   if (hcd->state == HC_STATE_SUSPENDED)
> +   usb_hcd_resume_root_hub(hcd);
>
> -   usb_hcd_poll_rh_status(hcd);
> +   usb_hcd_poll_rh_status(hcd);
> +   }
> }
> }
>
> @@ -611,6 +613,18 @@ 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 the xhci->shared_hcd doesn't exist, no one triggers to start
> +* the xhci which should be done before exitting run function
> +*/
> +   if (!xhci->shared_hcd) {
> +   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");
>
> @@ -861,8 +875,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool 

[PATCH v1 1/1] usb: xhci: do not create and register shared_hcd when USB3.0 is disabled

2017-12-15 Thread Thang Q. Nguyen
From: Tung Nguyen 

Currently, hcd->shared_hcd always creates and registers to the usb-core.
If, for some reasons, USB3 downstream port is disabled, no roothub port for
USB3.0 is found. This causes kernel to display an error:
hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
This patch checks, creates and registers shared_hcd if USB3.0 downstream
port is available.

Signed-off-by: Tung Nguyen 
Signed-off-by: Thang Q. Nguyen 
---
 drivers/usb/host/xhci-mem.c  |  2 +-
 drivers/usb/host/xhci-plat.c | 26 +++--
 drivers/usb/host/xhci.c  | 54 
 3 files changed, 54 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 554a8a5..157d1e7 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1067,7 +1067,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd 
*xhci,
struct usb_device *top_dev;
struct usb_hcd *hcd;
 
-   if (udev->speed >= USB_SPEED_SUPER)
+   if (udev->speed >= USB_SPEED_SUPER && xhci->shared_hcd)
hcd = xhci->shared_hcd;
else
hcd = xhci->main_hcd;
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 6f03830..e812e3d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -253,12 +253,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
 
xhci->clk = clk;
xhci->main_hcd = hcd;
-   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
-   dev_name(>dev), hcd);
-   if (!xhci->shared_hcd) {
-   ret = -ENOMEM;
-   goto disable_clk;
-   }
 
if (device_property_read_bool(sysdev, "usb2-lpm-disable"))
xhci->quirks |= XHCI_HW_LPM_DISABLE;
@@ -290,12 +284,20 @@ 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;
-
-   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
-   if (ret)
-   goto dealloc_usb2_hcd;
+   if (xhci->num_usb3_ports > 0) {
+   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
+   dev_name(>dev), hcd);
+   if (!xhci->shared_hcd) {
+   ret = -ENOMEM;
+   goto disable_clk;
+   }
+   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;
+   }
 
device_enable_async_suspend(>dev);
pm_runtime_put_noidle(>dev);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 05104bd..4824bf6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -417,12 +417,14 @@ static void compliance_mode_recovery(struct timer_list *t)
i + 1);
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"Attempting compliance mode recovery");
-   hcd = xhci->shared_hcd;
+   if (xhci->shared_hcd) {
+   hcd = xhci->shared_hcd;
 
-   if (hcd->state == HC_STATE_SUSPENDED)
-   usb_hcd_resume_root_hub(hcd);
+   if (hcd->state == HC_STATE_SUSPENDED)
+   usb_hcd_resume_root_hub(hcd);
 
-   usb_hcd_poll_rh_status(hcd);
+   usb_hcd_poll_rh_status(hcd);
+   }
}
}
 
@@ -611,6 +613,18 @@ 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 the xhci->shared_hcd doesn't exist, no one triggers to start
+* the xhci which should be done before exitting run function
+*/
+   if (!xhci->shared_hcd) {
+   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");
 
@@ -861,8 +875,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
if (!hcd->state)
return 0;
 
-   if (hcd->state != HC_STATE_SUSPENDED ||
-   xhci->shared_hcd->state != HC_STATE_SUSPENDED)
+   if (hcd->state != HC_STATE_SUSPENDED || 

[PATCH v1 1/1] usb: xhci: do not create and register shared_hcd when USB3.0 is disabled

2017-12-15 Thread Thang Q. Nguyen
From: Tung Nguyen 

Currently, hcd->shared_hcd always creates and registers to the usb-core.
If, for some reasons, USB3 downstream port is disabled, no roothub port for
USB3.0 is found. This causes kernel to display an error:
hub 2-0:1.0: config failed, hub doesn't have any ports! (err -19)
This patch checks, creates and registers shared_hcd if USB3.0 downstream
port is available.

Signed-off-by: Tung Nguyen 
Signed-off-by: Thang Q. Nguyen 
---
 drivers/usb/host/xhci-mem.c  |  2 +-
 drivers/usb/host/xhci-plat.c | 26 +++--
 drivers/usb/host/xhci.c  | 54 
 3 files changed, 54 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 554a8a5..157d1e7 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1067,7 +1067,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd 
*xhci,
struct usb_device *top_dev;
struct usb_hcd *hcd;
 
-   if (udev->speed >= USB_SPEED_SUPER)
+   if (udev->speed >= USB_SPEED_SUPER && xhci->shared_hcd)
hcd = xhci->shared_hcd;
else
hcd = xhci->main_hcd;
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 6f03830..e812e3d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -253,12 +253,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
 
xhci->clk = clk;
xhci->main_hcd = hcd;
-   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
-   dev_name(>dev), hcd);
-   if (!xhci->shared_hcd) {
-   ret = -ENOMEM;
-   goto disable_clk;
-   }
 
if (device_property_read_bool(sysdev, "usb2-lpm-disable"))
xhci->quirks |= XHCI_HW_LPM_DISABLE;
@@ -290,12 +284,20 @@ 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;
-
-   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
-   if (ret)
-   goto dealloc_usb2_hcd;
+   if (xhci->num_usb3_ports > 0) {
+   xhci->shared_hcd = __usb_create_hcd(driver, sysdev, >dev,
+   dev_name(>dev), hcd);
+   if (!xhci->shared_hcd) {
+   ret = -ENOMEM;
+   goto disable_clk;
+   }
+   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;
+   }
 
device_enable_async_suspend(>dev);
pm_runtime_put_noidle(>dev);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 05104bd..4824bf6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -417,12 +417,14 @@ static void compliance_mode_recovery(struct timer_list *t)
i + 1);
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"Attempting compliance mode recovery");
-   hcd = xhci->shared_hcd;
+   if (xhci->shared_hcd) {
+   hcd = xhci->shared_hcd;
 
-   if (hcd->state == HC_STATE_SUSPENDED)
-   usb_hcd_resume_root_hub(hcd);
+   if (hcd->state == HC_STATE_SUSPENDED)
+   usb_hcd_resume_root_hub(hcd);
 
-   usb_hcd_poll_rh_status(hcd);
+   usb_hcd_poll_rh_status(hcd);
+   }
}
}
 
@@ -611,6 +613,18 @@ 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 the xhci->shared_hcd doesn't exist, no one triggers to start
+* the xhci which should be done before exitting run function
+*/
+   if (!xhci->shared_hcd) {
+   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");
 
@@ -861,8 +875,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
if (!hcd->state)
return 0;
 
-   if (hcd->state != HC_STATE_SUSPENDED ||
-   xhci->shared_hcd->state != HC_STATE_SUSPENDED)
+   if (hcd->state != HC_STATE_SUSPENDED || (xhci->shared_hcd &&
+