Re: [PATCH v1 1/1] usb: xhci: do not create and register shared_hcd when USB3.0 is disabled
On 18.01.2018 09:27, Tung Vuong Nguyen wrote: On Tue, Jan 16, 2018 at 9:50 PM, Mathias Nymanwrote: 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
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
On Tue, Jan 16, 2018 at 9:50 PM, Mathias Nymanwrote: > > 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
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
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. Nguyenwrote: 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
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
Hi, On Sat, Dec 16, 2017 at 10:45 AM, Thang Q. Nguyenwrote: > 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
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
From: Tung NguyenCurrently, 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
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 && +