aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2022-03-08 18:57:38 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2022-03-08 18:59:23 +0000
commitc7cd6f809d2ce6b7d331717c31ce51c631ae00d7 (patch)
treef59d520a3345d5366f0683b4d77ccacd8e0a34b8 /sys/dev/usb
parentc03c5b1c80914ec656fbee84539355d1fad68bf9 (diff)
downloadsrc-c7cd6f809d2ce6b7d331717c31ce51c631ae00d7.tar.gz
src-c7cd6f809d2ce6b7d331717c31ce51c631ae00d7.zip
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. MFC after: 1 week Sponsored by: NVIDIA Networking
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/usb_hub.c38
1 files changed, 15 insertions, 23 deletions
diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c
index bdeee5e8d96c..77e519126567 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
@@ -997,6 +997,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;
@@ -1028,25 +1029,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)) {
/*
@@ -1059,10 +1057,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
@@ -1085,18 +1081,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) {
@@ -1111,7 +1103,7 @@ uhub_explore(struct usb_device *udev)
/* initial status checked */
sc->sc_flags |= UHUB_FLAG_DID_EXPLORE;
- return (err);
+ return (retval);
}
int