diff options
Diffstat (limited to 'freebsd/sys/dev/usb/usb_hub.c')
-rw-r--r-- | freebsd/sys/dev/usb/usb_hub.c | 76 |
1 files changed, 26 insertions, 50 deletions
diff --git a/freebsd/sys/dev/usb/usb_hub.c b/freebsd/sys/dev/usb/usb_hub.c index a0ad462f..b3543a8f 100644 --- a/freebsd/sys/dev/usb/usb_hub.c +++ b/freebsd/sys/dev/usb/usb_hub.c @@ -77,14 +77,9 @@ #include <dev/usb/usb_bus.h> #endif /* USB_GLOBAL_INCLUDE_FILE */ -#define UHUB_INTR_INTERVAL 250 /* ms */ -enum { - UHUB_INTR_TRANSFER, -#if USB_HAVE_TT_SUPPORT - UHUB_RESET_TT_TRANSFER, -#endif - UHUB_N_TRANSFER, -}; + +#include <dev/usb/usb_hub_private.h> + #ifdef USB_DEBUG static int uhub_debug = 0; @@ -113,27 +108,6 @@ SYSCTL_INT(_hw_usb, OID_AUTO, disable_port_power, CTLFLAG_RWTUN, &usb_disable_port_power, 0, "Set to disable all USB port power."); #endif -struct uhub_current_state { - uint16_t port_change; - uint16_t port_status; -}; - -struct uhub_softc { - struct uhub_current_state sc_st;/* current state */ -#if (USB_HAVE_FIXED_PORT != 0) - struct usb_hub sc_hub; -#endif - device_t sc_dev; /* base device */ - struct mtx sc_mtx; /* our mutex */ - struct usb_device *sc_udev; /* USB device */ - struct usb_xfer *sc_xfer[UHUB_N_TRANSFER]; /* interrupt xfer */ -#if USB_HAVE_DISABLE_ENUM - int sc_disable_enumeration; - int sc_disable_port_power; -#endif - uint8_t sc_flags; -#define UHUB_FLAG_DID_EXPLORE 0x01 -}; #define UHUB_PROTO(sc) ((sc)->sc_udev->ddesc.bDeviceProtocol) #define UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB) @@ -143,14 +117,10 @@ struct uhub_softc { /* prototypes for type checking: */ -static device_probe_t uhub_probe; -static device_attach_t uhub_attach; -static device_detach_t uhub_detach; static device_suspend_t uhub_suspend; static device_resume_t uhub_resume; static bus_driver_added_t uhub_driver_added; -static bus_child_location_str_t uhub_child_location_string; static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string; static usb_callback_t uhub_intr_callback; @@ -207,7 +177,7 @@ static device_method_t uhub_methods[] = { DEVMETHOD_END }; -static driver_t uhub_driver = { +driver_t uhub_driver = { .name = "uhub", .methods = uhub_methods, .size = sizeof(struct uhub_softc) @@ -589,13 +559,25 @@ uhub_read_port_status(struct uhub_softc *sc, uint8_t portno) struct usb_port_status ps; usb_error_t err; + if (sc->sc_usb_port_errors >= UHUB_USB_PORT_ERRORS_MAX) { + DPRINTFN(4, "port %d, HUB looks dead, too many errors\n", portno); + sc->sc_st.port_status = 0; + sc->sc_st.port_change = 0; + return (USB_ERR_TIMEOUT); + } + err = usbd_req_get_port_status( sc->sc_udev, NULL, &ps, portno); - /* update status regardless of error */ - - sc->sc_st.port_status = UGETW(ps.wPortStatus); - sc->sc_st.port_change = UGETW(ps.wPortChange); + if (err == 0) { + sc->sc_st.port_status = UGETW(ps.wPortStatus); + sc->sc_st.port_change = UGETW(ps.wPortChange); + sc->sc_usb_port_errors = 0; + } else { + sc->sc_st.port_status = 0; + sc->sc_st.port_change = 0; + sc->sc_usb_port_errors++; + } /* debugging print */ @@ -1126,7 +1108,7 @@ uhub_explore(struct usb_device *udev) return (USB_ERR_NORMAL_COMPLETION); } -static int +int uhub_probe(device_t dev) { struct usb_attach_arg *uaa = device_get_ivars(dev); @@ -1140,7 +1122,7 @@ uhub_probe(device_t dev) */ if (uaa->info.bConfigIndex == 0 && uaa->info.bDeviceClass == UDCLASS_HUB) - return (0); + return (BUS_PROBE_DEFAULT); return (ENXIO); } @@ -1206,7 +1188,7 @@ uhub_query_info(struct usb_device *udev, uint8_t *pnports, uint8_t *ptt) return (err); } -static int +int uhub_attach(device_t dev) { struct uhub_softc *sc = device_get_softc(dev); @@ -1552,7 +1534,7 @@ error: * Called from process context when the hub is gone. * Detach all devices on active ports. */ -static int +int uhub_detach(device_t dev) { struct uhub_softc *sc = device_get_softc(dev); @@ -1622,13 +1604,7 @@ uhub_driver_added(device_t dev, driver_t *driver) usb_needs_explore_all(); } -struct hub_result { - struct usb_device *udev; - uint8_t portno; - uint8_t iface_index; -}; - -static void +void uhub_find_iface_index(struct usb_hub *hub, device_t child, struct hub_result *res) { @@ -1661,7 +1637,7 @@ uhub_find_iface_index(struct usb_hub *hub, device_t child, res->portno = 0; } -static int +int uhub_child_location_string(device_t parent, device_t child, char *buf, size_t buflen) { |