git: 081619a5070f - stable/13 - usb(4): Don't skip calling uhub_explore_sub() even on HUB port errors.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 09 Mar 2022 20:18:01 UTC
The branch stable/13 has been updated by hselasky: URL: https://cgit.FreeBSD.org/src/commit/?id=081619a5070f83f4435c4ea4f35f2252e36880f0 commit 081619a5070f83f4435c4ea4f35f2252e36880f0 Author: Hans Petter Selasky <hselasky@FreeBSD.org> AuthorDate: 2022-03-08 18:57:38 +0000 Commit: Hans Petter Selasky <hselasky@FreeBSD.org> CommitDate: 2022-03-09 20:05:43 +0000 usb(4): Don't skip calling uhub_explore_sub() even on HUB port errors. This should fix an issue where the "udev->re_enumerate_wait" field never gets processed and reset. In this case usbconfig will wait forever and never return. Sponsored by: NVIDIA Networking (cherry picked from commit c7cd6f809d2ce6b7d331717c31ce51c631ae00d7) --- sys/dev/usb/usb_hub.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index 17bdac68c465..00173a5d14d0 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -4,7 +4,7 @@ * * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved. * Copyright (c) 1998 Lennart Augustsson. All rights reserved. - * Copyright (c) 2008-2022 Hans Petter Selasky. All rights reserved. + * Copyright (c) 2008-2022 Hans Petter Selasky * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -995,6 +995,7 @@ uhub_explore(struct usb_device *udev) struct usb_hub *hub; struct uhub_softc *sc; struct usb_port *up; + usb_error_t retval; usb_error_t err; uint8_t portno; uint8_t x; @@ -1026,25 +1027,22 @@ uhub_explore(struct usb_device *udev) * Set default error code to avoid compiler warnings. * Note that hub->nports cannot be zero. */ - err = USB_ERR_NORMAL_COMPLETION; + retval = USB_ERR_NORMAL_COMPLETION; for (x = 0; x != hub->nports; x++) { up = hub->ports + x; portno = x + 1; err = uhub_read_port_status(sc, portno); - if (err) { - /* most likely the HUB is gone */ - break; - } + if (err != USB_ERR_NORMAL_COMPLETION) + retval = err; + if (sc->sc_st.port_change & UPS_C_OVERCURRENT_INDICATOR) { DPRINTF("Overcurrent on port %u.\n", portno); err = usbd_req_clear_port_feature( udev, NULL, portno, UHF_C_PORT_OVER_CURRENT); - if (err) { - /* most likely the HUB is gone */ - break; - } + if (err != USB_ERR_NORMAL_COMPLETION) + retval = err; } if (!(sc->sc_flags & UHUB_FLAG_DID_EXPLORE)) { /* @@ -1057,10 +1055,8 @@ uhub_explore(struct usb_device *udev) if (sc->sc_st.port_change & UPS_C_PORT_ENABLED) { err = usbd_req_clear_port_feature( udev, NULL, portno, UHF_C_PORT_ENABLE); - if (err) { - /* most likely the HUB is gone */ - break; - } + if (err != USB_ERR_NORMAL_COMPLETION) + retval = err; if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) { /* * Ignore the port error if the device @@ -1083,18 +1079,14 @@ uhub_explore(struct usb_device *udev) } if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) { err = uhub_reattach_port(sc, portno); - if (err) { - /* most likely the HUB is gone */ - break; - } + if (err != USB_ERR_NORMAL_COMPLETION) + retval = err; } if (sc->sc_st.port_change & (UPS_C_SUSPEND | UPS_C_PORT_LINK_STATE)) { err = uhub_suspend_resume_port(sc, portno); - if (err) { - /* most likely the HUB is gone */ - break; - } + if (err != USB_ERR_NORMAL_COMPLETION) + retval = err; } if (uhub_explore_sub(sc, up) == USB_ERR_NORMAL_COMPLETION) { @@ -1109,7 +1101,7 @@ uhub_explore(struct usb_device *udev) /* initial status checked */ sc->sc_flags |= UHUB_FLAG_DID_EXPLORE; - return (err); + return (retval); } int