Message ID | 20220816083854.1491886-2-raychi@google.com |
---|---|
State | New |
Headers | show |
Series | Provide a hook to check port init status | expand |
On Tue, Aug 16, 2022 at 04:38:53PM +0800, Ray Chi wrote: > This patch add a hook to check the port init status. Currently, only > usbcore knows port init status even if the result is bad. It will cause > a USB host keep doing USB enumeration for a long time when the USB host > connects to a broken USB accessory. > > The hc_driver could use the hook to know port init status and do possible > error handling according to platform requirements or limitations. > > Signed-off-by: Ray Chi <raychi@google.com> > --- > drivers/usb/core/hub.c | 14 ++++++++++++++ > include/linux/usb/hcd.h | 8 ++++++++ > 2 files changed, 22 insertions(+) > > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c > index 2633acde7ac1..6ce6092816cb 100644 > --- a/drivers/usb/core/hub.c > +++ b/drivers/usb/core/hub.c > @@ -4855,6 +4865,10 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, > buf->bMaxPacketSize0; > kfree(buf); > > + retval = hub_port_check_init_status(udev, r); > + if (retval < 0) > + goto fail; For future reference, you should be aware that this code won't get executed if do_new_scheme is false. Alan Stern
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2633acde7ac1..6ce6092816cb 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4659,6 +4659,16 @@ static int hub_enable_device(struct usb_device *udev) return hcd->driver->enable_device(hcd, udev); } +static int hub_port_check_init_status(struct usb_device *udev, int r) +{ + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + + if (!hcd->driver->check_init_status) + return 0; + + return hcd->driver->check_init_status(hcd, udev, r); +} + /* Reset device, (re)assign address, get device descriptor. * Device connection must be stable, no more debouncing needed. * Returns device in USB_STATE_ADDRESS, except on error. @@ -4855,6 +4865,10 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, buf->bMaxPacketSize0; kfree(buf); + retval = hub_port_check_init_status(udev, r); + if (retval < 0) + goto fail; + retval = hub_port_reset(hub, port1, udev, delay, false); if (retval < 0) /* error or disconnect */ goto fail; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 67f8713d3fa3..8fa30b4a6b7d 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -297,6 +297,14 @@ struct hc_driver { gfp_t mem_flags); void (*unmap_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb); + /* + * (optional) HCD could get the information of GET_DESCRIPTOR by this hook. + * In general, it is not necessary unless the enumeration takes long + * time to do. The host controller could know the enumeration status by + * this hook and do some error handlings. + */ + int (*check_init_status)(struct usb_hcd *hcd, struct usb_device *udev, int r); + /* hw synch, freeing endpoint resources that urb_dequeue can't */ void (*endpoint_disable)(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
This patch add a hook to check the port init status. Currently, only usbcore knows port init status even if the result is bad. It will cause a USB host keep doing USB enumeration for a long time when the USB host connects to a broken USB accessory. The hc_driver could use the hook to know port init status and do possible error handling according to platform requirements or limitations. Signed-off-by: Ray Chi <raychi@google.com> --- drivers/usb/core/hub.c | 14 ++++++++++++++ include/linux/usb/hcd.h | 8 ++++++++ 2 files changed, 22 insertions(+)