Message ID | 20221118110116.20165-1-chunfeng.yun@mediatek.com (mailing list archive) |
---|---|
State | Accepted |
Commit | e99e1a7d6f88b9c54dc32671bac29f26e58bde80 |
Headers | show |
Series | usb: host: xhci-mtk: omit shared hcd if either root hub has no ports | expand |
Il 18/11/22 12:01, Chunfeng Yun ha scritto: > There is error log when add a usb3 root hub without ports: > "hub 4-0:1.0: config failed, hub doesn't have any ports! (err -19)" > > so omit the shared hcd if either of the root hubs has no ports, but > usually there is no usb3 port. > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
On 18.11.2022 13.01, Chunfeng Yun wrote: > There is error log when add a usb3 root hub without ports: > "hub 4-0:1.0: config failed, hub doesn't have any ports! (err -19)" > > so omit the shared hcd if either of the root hubs has no ports, but > usually there is no usb3 port. > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > drivers/usb/host/xhci-mtk.c | 72 +++++++++++++++++++++++-------------- > 1 file changed, 46 insertions(+), 26 deletions(-) > > diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c > index 01705e559c42..cff3c4aea036 100644 > --- a/drivers/usb/host/xhci-mtk.c > +++ b/drivers/usb/host/xhci-mtk.c > @@ -485,6 +485,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) > const struct hc_driver *driver; > struct xhci_hcd *xhci; > struct resource *res; > + struct usb_hcd *usb3_hcd; > struct usb_hcd *hcd; > int ret = -ENODEV; > int wakeup_irq; > @@ -593,6 +594,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) > > xhci = hcd_to_xhci(hcd); > xhci->main_hcd = hcd; > + xhci->allow_single_roothub = 1; > > /* > * imod_interval is the interrupt moderation value in nanoseconds. > @@ -602,24 +604,29 @@ static int xhci_mtk_probe(struct platform_device *pdev) > xhci->imod_interval = 5000; > device_property_read_u32(dev, "imod-interval-ns", &xhci->imod_interval); > > - xhci->shared_hcd = usb_create_shared_hcd(driver, dev, > - dev_name(dev), hcd); > - if (!xhci->shared_hcd) { > - ret = -ENOMEM; > - goto disable_device_wakeup; > - } > - > ret = usb_add_hcd(hcd, irq, IRQF_SHARED); > if (ret) > - goto put_usb3_hcd; > + goto disable_device_wakeup; > > - if (HCC_MAX_PSA(xhci->hcc_params) >= 4 && > + if (!xhci_has_one_roothub(xhci)) { > + xhci->shared_hcd = usb_create_shared_hcd(driver, dev, > + dev_name(dev), hcd); > + if (!xhci->shared_hcd) { > + ret = -ENOMEM; > + goto dealloc_usb2_hcd; > + } > + } > + > + usb3_hcd = xhci_get_usb3_hcd(xhci); > + if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4 && > !(xhci->quirks & XHCI_BROKEN_STREAMS)) > - xhci->shared_hcd->can_do_streams = 1; > + usb3_hcd->can_do_streams = 1; > > - ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); > - if (ret) > - goto dealloc_usb2_hcd; > + if (xhci->shared_hcd) { > + ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); > + if (ret) > + goto put_usb3_hcd; > + } > > if (wakeup_irq > 0) { > ret = dev_pm_set_dedicated_wake_irq_reverse(dev, wakeup_irq); dev_pm_set_dedicated_wake_irq_reverse() can be called with just one hcd, if it fails it will goto dealloc_usb3_hcd: dealloc_usb3_hcd: usb_remove_hcd(xhci->shared_hcd); // xhci->shared_hcd may be null xhci->shared_hcd = NULL; // causes usb_put_hcd() issues if shared_hcd exists put_usb3_hcd: usb_put_hcd(xhci->shared_hcd); // shared_hcd may be set NULL above -Mathias
On Wed, 2022-11-23 at 13:10 +0200, Mathias Nyman wrote: > On 18.11.2022 13.01, Chunfeng Yun wrote: > > There is error log when add a usb3 root hub without ports: > > "hub 4-0:1.0: config failed, hub doesn't have any ports! (err -19)" > > > > so omit the shared hcd if either of the root hubs has no ports, but > > usually there is no usb3 port. > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > drivers/usb/host/xhci-mtk.c | 72 +++++++++++++++++++++++--------- > > ----- > > 1 file changed, 46 insertions(+), 26 deletions(-) > > > > diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci- > > mtk.c > > index 01705e559c42..cff3c4aea036 100644 > > --- a/drivers/usb/host/xhci-mtk.c > > +++ b/drivers/usb/host/xhci-mtk.c > > @@ -485,6 +485,7 @@ static int xhci_mtk_probe(struct > > platform_device *pdev) > > const struct hc_driver *driver; > > struct xhci_hcd *xhci; > > struct resource *res; > > + struct usb_hcd *usb3_hcd; > > struct usb_hcd *hcd; > > int ret = -ENODEV; > > int wakeup_irq; > > @@ -593,6 +594,7 @@ static int xhci_mtk_probe(struct > > platform_device *pdev) > > > > xhci = hcd_to_xhci(hcd); > > xhci->main_hcd = hcd; > > + xhci->allow_single_roothub = 1; > > > > /* > > * imod_interval is the interrupt moderation value in > > nanoseconds. > > @@ -602,24 +604,29 @@ static int xhci_mtk_probe(struct > > platform_device *pdev) > > xhci->imod_interval = 5000; > > device_property_read_u32(dev, "imod-interval-ns", &xhci- > > >imod_interval); > > > > - xhci->shared_hcd = usb_create_shared_hcd(driver, dev, > > - dev_name(dev), hcd); > > - if (!xhci->shared_hcd) { > > - ret = -ENOMEM; > > - goto disable_device_wakeup; > > - } > > - > > ret = usb_add_hcd(hcd, irq, IRQF_SHARED); > > if (ret) > > - goto put_usb3_hcd; > > + goto disable_device_wakeup; > > > > - if (HCC_MAX_PSA(xhci->hcc_params) >= 4 && > > + if (!xhci_has_one_roothub(xhci)) { > > + xhci->shared_hcd = usb_create_shared_hcd(driver, dev, > > + dev_name(dev), > > hcd); > > + if (!xhci->shared_hcd) { > > + ret = -ENOMEM; > > + goto dealloc_usb2_hcd; > > + } > > + } > > + > > + usb3_hcd = xhci_get_usb3_hcd(xhci); > > + if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4 && > > !(xhci->quirks & XHCI_BROKEN_STREAMS)) > > - xhci->shared_hcd->can_do_streams = 1; > > + usb3_hcd->can_do_streams = 1; > > > > - ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); > > - if (ret) > > - goto dealloc_usb2_hcd; > > + if (xhci->shared_hcd) { > > + ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); > > + if (ret) > > + goto put_usb3_hcd; > > + } > > > > if (wakeup_irq > 0) { > > ret = dev_pm_set_dedicated_wake_irq_reverse(dev, > > wakeup_irq); > > > dev_pm_set_dedicated_wake_irq_reverse() can be called with just one > hcd, if it fails > it will goto dealloc_usb3_hcd: > > dealloc_usb3_hcd: > usb_remove_hcd(xhci->shared_hcd); // xhci->shared_hcd may be > null > xhci->shared_hcd = NULL; // causes usb_put_hcd() issues if > shared_hcd exists > > put_usb3_hcd: > usb_put_hcd(xhci->shared_hcd); // shared_hcd may be set NULL > above I'll check it again, thanks > > -Mathias >
On Wed, 2022-11-23 at 13:10 +0200, Mathias Nyman wrote: > On 18.11.2022 13.01, Chunfeng Yun wrote: > > There is error log when add a usb3 root hub without ports: > > "hub 4-0:1.0: config failed, hub doesn't have any ports! (err -19)" > > > > so omit the shared hcd if either of the root hubs has no ports, but > > usually there is no usb3 port. > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > drivers/usb/host/xhci-mtk.c | 72 +++++++++++++++++++++++--------- > > ----- > > 1 file changed, 46 insertions(+), 26 deletions(-) > > > > diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci- > > mtk.c > > index 01705e559c42..cff3c4aea036 100644 > > --- a/drivers/usb/host/xhci-mtk.c > > +++ b/drivers/usb/host/xhci-mtk.c > > @@ -485,6 +485,7 @@ static int xhci_mtk_probe(struct > > platform_device *pdev) > > const struct hc_driver *driver; > > struct xhci_hcd *xhci; > > struct resource *res; > > + struct usb_hcd *usb3_hcd; > > struct usb_hcd *hcd; > > int ret = -ENODEV; > > int wakeup_irq; > > @@ -593,6 +594,7 @@ static int xhci_mtk_probe(struct > > platform_device *pdev) > > > > xhci = hcd_to_xhci(hcd); > > xhci->main_hcd = hcd; > > + xhci->allow_single_roothub = 1; > > > > /* > > * imod_interval is the interrupt moderation value in > > nanoseconds. > > @@ -602,24 +604,29 @@ static int xhci_mtk_probe(struct > > platform_device *pdev) > > xhci->imod_interval = 5000; > > device_property_read_u32(dev, "imod-interval-ns", &xhci- > > >imod_interval); > > > > - xhci->shared_hcd = usb_create_shared_hcd(driver, dev, > > - dev_name(dev), hcd); > > - if (!xhci->shared_hcd) { > > - ret = -ENOMEM; > > - goto disable_device_wakeup; > > - } > > - > > ret = usb_add_hcd(hcd, irq, IRQF_SHARED); > > if (ret) > > - goto put_usb3_hcd; > > + goto disable_device_wakeup; > > > > - if (HCC_MAX_PSA(xhci->hcc_params) >= 4 && > > + if (!xhci_has_one_roothub(xhci)) { > > + xhci->shared_hcd = usb_create_shared_hcd(driver, dev, > > + dev_name(dev), > > hcd); > > + if (!xhci->shared_hcd) { > > + ret = -ENOMEM; > > + goto dealloc_usb2_hcd; > > + } > > + } > > + > > + usb3_hcd = xhci_get_usb3_hcd(xhci); > > + if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4 && > > !(xhci->quirks & XHCI_BROKEN_STREAMS)) > > - xhci->shared_hcd->can_do_streams = 1; > > + usb3_hcd->can_do_streams = 1; > > > > - ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); > > - if (ret) > > - goto dealloc_usb2_hcd; > > + if (xhci->shared_hcd) { > > + ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); > > + if (ret) > > + goto put_usb3_hcd; > > + } > > > > if (wakeup_irq > 0) { > > ret = dev_pm_set_dedicated_wake_irq_reverse(dev, > > wakeup_irq); > > > dev_pm_set_dedicated_wake_irq_reverse() can be called with just one > hcd, if it fails > it will goto dealloc_usb3_hcd: > > dealloc_usb3_hcd: > usb_remove_hcd(xhci->shared_hcd); // xhci->shared_hcd may be > null usb_remove_hcd() has handled NULL argument, no need check it here > xhci->shared_hcd = NULL; // causes usb_put_hcd() issues if > shared_hcd exists This line shall be removed, I'll prepare a patch. > > put_usb3_hcd: > usb_put_hcd(xhci->shared_hcd); // shared_hcd may be set NULL > above usb_put_hcd() has handled NULL argument, no need check it here Thanks a lot > > -Mathias >
On 11/24/22 18:38, Chunfeng Yun (云春峰) wrote: > On Wed, 2022-11-23 at 13:10 +0200, Mathias Nyman wrote: >> On 18.11.2022 13.01, Chunfeng Yun wrote: >>> There is error log when add a usb3 root hub without ports: >>> "hub 4-0:1.0: config failed, hub doesn't have any ports! (err -19)" >>> >>> so omit the shared hcd if either of the root hubs has no ports, but >>> usually there is no usb3 port. >>> >>> Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> >>> --- >>> drivers/usb/host/xhci-mtk.c | 72 +++++++++++++++++++++++--------- [deleted...] Dear Chunfeng, Since this issue has been reported by Canonical as a ticket on launchpad (sorry, it has been reported as a private ticket...), could you please to check if add "Cc: stable@vger.kernel.org" and "Fixes:" tags are valid? If it is possible, please help to list dependent patches to backport to stable tree also. Is it possible to include this patch in recent LTS tree? Thanks Macpaul Lin
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 01705e559c42..cff3c4aea036 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -485,6 +485,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) const struct hc_driver *driver; struct xhci_hcd *xhci; struct resource *res; + struct usb_hcd *usb3_hcd; struct usb_hcd *hcd; int ret = -ENODEV; int wakeup_irq; @@ -593,6 +594,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) xhci = hcd_to_xhci(hcd); xhci->main_hcd = hcd; + xhci->allow_single_roothub = 1; /* * imod_interval is the interrupt moderation value in nanoseconds. @@ -602,24 +604,29 @@ static int xhci_mtk_probe(struct platform_device *pdev) xhci->imod_interval = 5000; device_property_read_u32(dev, "imod-interval-ns", &xhci->imod_interval); - xhci->shared_hcd = usb_create_shared_hcd(driver, dev, - dev_name(dev), hcd); - if (!xhci->shared_hcd) { - ret = -ENOMEM; - goto disable_device_wakeup; - } - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) - goto put_usb3_hcd; + goto disable_device_wakeup; - if (HCC_MAX_PSA(xhci->hcc_params) >= 4 && + if (!xhci_has_one_roothub(xhci)) { + xhci->shared_hcd = usb_create_shared_hcd(driver, dev, + dev_name(dev), hcd); + if (!xhci->shared_hcd) { + ret = -ENOMEM; + goto dealloc_usb2_hcd; + } + } + + usb3_hcd = xhci_get_usb3_hcd(xhci); + if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4 && !(xhci->quirks & XHCI_BROKEN_STREAMS)) - xhci->shared_hcd->can_do_streams = 1; + usb3_hcd->can_do_streams = 1; - ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); - if (ret) - goto dealloc_usb2_hcd; + if (xhci->shared_hcd) { + ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); + if (ret) + goto put_usb3_hcd; + } if (wakeup_irq > 0) { ret = dev_pm_set_dedicated_wake_irq_reverse(dev, wakeup_irq); @@ -641,13 +648,13 @@ static int xhci_mtk_probe(struct platform_device *pdev) usb_remove_hcd(xhci->shared_hcd); xhci->shared_hcd = NULL; -dealloc_usb2_hcd: - usb_remove_hcd(hcd); - put_usb3_hcd: - xhci_mtk_sch_exit(mtk); usb_put_hcd(xhci->shared_hcd); +dealloc_usb2_hcd: + xhci_mtk_sch_exit(mtk); + usb_remove_hcd(hcd); + disable_device_wakeup: device_init_wakeup(dev, false); @@ -679,10 +686,15 @@ static int xhci_mtk_remove(struct platform_device *pdev) dev_pm_clear_wake_irq(dev); device_init_wakeup(dev, false); - usb_remove_hcd(shared_hcd); - xhci->shared_hcd = NULL; + if (shared_hcd) { + usb_remove_hcd(shared_hcd); + xhci->shared_hcd = NULL; + } usb_remove_hcd(hcd); - usb_put_hcd(shared_hcd); + + if (shared_hcd) + usb_put_hcd(shared_hcd); + usb_put_hcd(hcd); xhci_mtk_sch_exit(mtk); clk_bulk_disable_unprepare(BULK_CLKS_NUM, mtk->clks); @@ -700,13 +712,16 @@ static int __maybe_unused xhci_mtk_suspend(struct device *dev) struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); struct usb_hcd *hcd = mtk->hcd; struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct usb_hcd *shared_hcd = xhci->shared_hcd; int ret; xhci_dbg(xhci, "%s: stop port polling\n", __func__); clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); del_timer_sync(&hcd->rh_timer); - clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); - del_timer_sync(&xhci->shared_hcd->rh_timer); + if (shared_hcd) { + clear_bit(HCD_FLAG_POLL_RH, &shared_hcd->flags); + del_timer_sync(&shared_hcd->rh_timer); + } ret = xhci_mtk_host_disable(mtk); if (ret) @@ -718,8 +733,10 @@ static int __maybe_unused xhci_mtk_suspend(struct device *dev) restart_poll_rh: xhci_dbg(xhci, "%s: restart port polling\n", __func__); - set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); - usb_hcd_poll_rh_status(xhci->shared_hcd); + if (shared_hcd) { + set_bit(HCD_FLAG_POLL_RH, &shared_hcd->flags); + usb_hcd_poll_rh_status(shared_hcd); + } set_bit(HCD_FLAG_POLL_RH, &hcd->flags); usb_hcd_poll_rh_status(hcd); return ret; @@ -730,6 +747,7 @@ static int __maybe_unused xhci_mtk_resume(struct device *dev) struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); struct usb_hcd *hcd = mtk->hcd; struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct usb_hcd *shared_hcd = xhci->shared_hcd; int ret; usb_wakeup_set(mtk, false); @@ -742,8 +760,10 @@ static int __maybe_unused xhci_mtk_resume(struct device *dev) goto disable_clks; xhci_dbg(xhci, "%s: restart port polling\n", __func__); - set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); - usb_hcd_poll_rh_status(xhci->shared_hcd); + if (shared_hcd) { + set_bit(HCD_FLAG_POLL_RH, &shared_hcd->flags); + usb_hcd_poll_rh_status(shared_hcd); + } set_bit(HCD_FLAG_POLL_RH, &hcd->flags); usb_hcd_poll_rh_status(hcd); return 0;
There is error log when add a usb3 root hub without ports: "hub 4-0:1.0: config failed, hub doesn't have any ports! (err -19)" so omit the shared hcd if either of the root hubs has no ports, but usually there is no usb3 port. Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- drivers/usb/host/xhci-mtk.c | 72 +++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 26 deletions(-)