PERFORCE change 130745 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Wed Dec 12 14:45:27 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=130745
Change 130745 by hselasky at hselasky_laptop001 on 2007/12/12 22:45:07
This commit is related to USB device side support.
o In general: The code does almost the same like
before only that some functions have been
refactored.
o Some small changes to support USB Device Mode.
See use of "USB_MODE_DEVICE" in the code.
o Number of ports is now stored in "hub->nports".
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/uhub.c#25 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/uhub.c#25 (text+ko) ====
@@ -69,12 +69,17 @@
#define DPRINTF(...) do { } while (0)
#endif
+struct uhub_current_state {
+ uint16_t port_change;
+ uint16_t port_status;
+};
+
struct uhub_softc {
+ struct uhub_current_state sc_st;/* current state */
device_t sc_dev; /* base device */
struct usbd_device *sc_udev; /* USB device */
struct usbd_xfer *sc_xfer[2]; /* interrupt xfer */
uint8_t sc_flags;
-#define UHUB_FLAG_RUNNING 0x01
#define UHUB_FLAG_INTR_STALL 0x02
uint8_t sc_name[32];
};
@@ -179,7 +184,8 @@
* event handler thread that we need
* to be explored again:
*/
- usb_needs_explore(sc->sc_udev);
+ usb_needs_explore(sc->sc_udev->bus,
+ USB_BUS_EXPLORE_TREE);
case USBD_ST_SETUP:
if (sc->sc_flags & UHUB_FLAG_INTR_STALL) {
@@ -200,225 +206,306 @@
}
}
-static struct usbd_device *
-uhub_port_to_sub_device(struct usbd_device *udev, struct usbd_port *up)
-{
- if ((udev == NULL) || (up == NULL)) {
- /* be NULL safe */
- return (NULL);
- }
- if (up->device_addr == USB_START_ADDR) {
- /* nothing to do */
- return (NULL);
- }
- return (udev->bus->devices[up->device_addr]);
-}
-
+/*------------------------------------------------------------------------*
+ * uhub_explore_sub - subroutine
+ *
+ * Return values:
+ * 0: Success
+ * Else: A control transaction failed
+ *------------------------------------------------------------------------*/
static usbd_status_t
-uhub_explore_sub(device_t dev, struct usbd_device *udev, struct usbd_port *up)
+uhub_explore_sub(struct uhub_softc *sc, struct usbd_port *up)
{
+ struct usbd_bus *bus;
struct usbd_device *child;
- uint8_t refcount = usb_driver_added_refcount;
- usbd_status_t err = 0;
+ uint8_t refcount;
+ usbd_status_t err;
+
+ bus = sc->sc_udev->bus;
+ err = 0;
- child = uhub_port_to_sub_device(udev, up);
+ /* get driver added refcount from USB bus */
+ refcount = bus->driver_added_refcount;
+ /* get device assosiated with the given port */
+ child = usbd_bus_port_get_device(bus, up);
if (child == NULL) {
/* nothing to do */
- return (0);
+ goto done;
}
/* check if probe and attach should be done */
if (child->driver_added_refcount != refcount) {
child->driver_added_refcount = refcount;
- err = usbd_probe_and_attach(dev, child);
+ err = usbd_probe_and_attach(child,
+ USB_IFACE_INDEX_ANY);
+ if (err) {
+ goto done;
+ }
+ }
+ /* start control transfer, if device mode */
+
+ if (child->flags.usb_mode == USB_MODE_DEVICE) {
+ usbd_default_transfer_setup(child);
}
/* if a HUB becomes present, do a recursive HUB explore */
if (child->hub) {
- (child->hub->explore) (child);
+ err = (child->hub->explore) (child);
}
+done:
+ return (err);
+}
+
+/*------------------------------------------------------------------------*
+ * uhub_read_port_status - factored out code
+ *------------------------------------------------------------------------*/
+static usbd_status_t
+uhub_read_port_status(struct uhub_softc *sc, uint8_t portno)
+{
+ usb_port_status_t ps;
+ usbd_status_t err;
+
+ err = usbreq_get_port_status(
+ sc->sc_udev, &usb_global_lock, &ps, portno);
+
+ /* update status regardless of error */
+
+ sc->sc_st.port_status = UGETW(ps.wPortStatus);
+ sc->sc_st.port_change = UGETW(ps.wPortChange);
+
+ /* debugging print */
+
+ DPRINTF(sc, 3, "port %d, wPortStatus=0x%04x, "
+ "wPortChange=0x%04x, err=%s\n",
+ portno, sc->sc_st.port_status,
+ sc->sc_st.port_change, usbd_errstr(err));
return (err);
}
+/*------------------------------------------------------------------------*
+ * uhub_reattach_port
+ *
+ * Returns:
+ * 0: Success
+ * Else: A control transaction failed
+ *------------------------------------------------------------------------*/
static usbd_status_t
-uhub_explore(struct usbd_device *udev)
+uhub_reattach_port(struct uhub_softc *sc, uint8_t portno)
{
- usb_hub_descriptor_t *hd = &udev->hub->hubdesc;
- struct uhub_softc *sc = udev->hub->hubsoftc;
struct usbd_device *child;
- struct usbd_port *up;
+ struct usbd_device *udev;
usbd_status_t err;
- uint16_t change;
- uint16_t status;
- uint8_t portno;
+ uint8_t timeout;
uint8_t speed;
- uint8_t x;
+ uint8_t usb_mode;
+
+ DPRINTF(sc, 0, "reattaching port %d\n", portno);
+
+ err = 0;
+ timeout = 0;
+ udev = sc->sc_udev;
+ child = usbd_bus_port_get_device(udev->bus,
+ udev->hub->ports + portno - 1);
+
+repeat:
+
+ /* first clear the port connection change bit */
+
+ err = usbreq_clear_port_feature
+ (udev, &usb_global_lock, portno, UHF_C_PORT_CONNECTION);
+
+ if (err) {
+ goto error;
+ }
+ /* detach any existing devices */
+
+ if (child) {
+ usbd_detach_device(child, USB_IFACE_INDEX_ANY, 1);
+ usbd_free_device(child);
+ child = NULL;
+ }
+ /* get fresh status */
- DPRINTF(sc, 10, "udev=%p addr=%d\n", udev, udev->address);
+ err = uhub_read_port_status(sc, portno);
+ if (err) {
+ goto error;
+ }
+ /* check if nothing is connected to the port */
- if (!(sc->sc_flags & UHUB_FLAG_RUNNING)) {
- return (USBD_NOT_STARTED);
+ if (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS)) {
+ goto error;
}
- /* ignore hubs that are too deep */
- if (udev->depth > USB_HUB_MAX_DEPTH) {
- return (USBD_TOO_DEEP);
+ /* check if there is no power on the port and print a warning */
+
+ if (!(sc->sc_st.port_status & UPS_PORT_POWER)) {
+ DPRINTF(sc, 0, "WARNING: strange, connected port %d "
+ "has no power\n", portno);
}
- for (x = 0; x < hd->bNbrPorts; x++) {
- up = udev->hub->ports + x;
- portno = x + 1;
- err = usbreq_get_port_status
- (udev, &usb_global_lock, &up->status, portno);
- if (err) {
- DPRINTF(sc, 0, "get port status failed, "
- "error=%s\n", usbd_errstr(err));
- continue;
- }
- status = UGETW(up->status.wPortStatus);
- change = UGETW(up->status.wPortChange);
- DPRINTF(sc, 3, "port %d status 0x%04x 0x%04x\n",
- portno, status, change);
- if (change & UPS_C_PORT_ENABLED) {
- DPRINTF(sc, 0, "C_PORT_ENABLED 0x%x\n", change);
- usbreq_clear_port_feature
- (udev, &usb_global_lock, portno, UHF_C_PORT_ENABLE);
- if (change & UPS_C_CONNECT_STATUS) {
- /*
- * ignore the port error if the device
- * vanished
- */
- } else if (status & UPS_PORT_ENABLED) {
- DPRINTF(sc, -1, "illegal enable change, "
- "port %d\n", portno);
- } else {
- /* port error condition */
- if (up->restartcnt) { /* no message first time */
- DPRINTF(sc, -1, "port error, restarting "
- "port %d\n", portno);
- }
- if (up->restartcnt++ < USBD_RESTART_MAX) {
- goto disconnect;
- } else {
- DPRINTF(sc, -1, "port error, giving up "
- "port %d\n", portno);
- }
- }
- }
- if (!(change & UPS_C_CONNECT_STATUS)) {
- DPRINTF(sc, 3, "port=%d !C_CONNECT_"
- "STATUS\n", portno);
+ /* check if the device is in Host Mode */
+
+ if (!(sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)) {
- /* no status change, just do recursive explore */
- err = uhub_explore_sub(sc->sc_dev, udev, up);
- continue;
- }
- /* we have a connect status change, handle it */
+ DPRINTF(sc, 0, "Port %d is in Host Mode\n", portno);
- DPRINTF(sc, 0, "status change hub=%d port=%d\n",
- udev->address, portno);
- usbreq_clear_port_feature
- (udev, &usb_global_lock, portno, UHF_C_PORT_CONNECTION);
- /*
- * usbreq_clear_port_feature (udev, &usb_global_lock,
- * portno, UHF_C_PORT_ENABLE);
- */
- /*
- * If there is already a device on the port the change status
- * must mean that is has disconnected. Looking at the
- * current connect status is not enough to figure this out
- * since a new unit may have been connected before we handle
- * the disconnect.
- */
-disconnect:
- child = uhub_port_to_sub_device(udev, up);
- if (child) {
- /* disconnected */
- DPRINTF(sc, 0, "device addr=%d disappeared "
- "on port %d\n", child->address,
- portno);
- usbd_free_device(child, 1);
- usbreq_clear_port_feature
- (udev, &usb_global_lock, portno, UHF_C_PORT_CONNECTION);
- }
- if (!(status & UPS_CURRENT_CONNECT_STATUS)) {
- /* nothing connected, just ignore it */
- DPRINTF(sc, 3, "port=%d !CURRENT_CONNECT_STATUS\n",
- portno);
- continue;
- }
- /* connected */
+ /* USB Host Mode */
- if (!(status & UPS_PORT_POWER)) {
- DPRINTF(sc, -1, "strange, connected port %d "
- "has no power\n", portno);
- }
/* wait for maximum device power up time */
+
usbd_delay_ms(udev, USB_PORT_POWERUP_DELAY);
/* reset port, which implies enabling it */
+
err = usbreq_reset_port
- (udev, &usb_global_lock, &up->status, portno);
+ (udev, &usb_global_lock, portno);
if (err) {
DPRINTF(sc, -1, "port %d reset "
"failed, error=%s\n",
portno, usbd_errstr(err));
- continue;
+ goto error;
}
/* get port status again, it might have changed during reset */
- err = usbreq_get_port_status
- (udev, &usb_global_lock, &up->status, portno);
+ err = uhub_read_port_status(sc, portno);
if (err) {
- DPRINTF(sc, 0, "get port status failed, "
- "error=%s\n", usbd_errstr(err));
- continue;
+ goto error;
+ }
+ /* check if something changed during port reset */
+
+ if ((sc->sc_st.port_change & UPS_C_CONNECT_STATUS) ||
+ (!(sc->sc_st.port_status & UPS_CURRENT_CONNECT_STATUS))) {
+ if (timeout) {
+ DPRINTF(sc, -1, "giving up port reset "
+ "- device vanished!\n");
+ goto error;
+ }
+ timeout = 1;
+ goto repeat;
}
- status = UGETW(up->status.wPortStatus);
- change = UGETW(up->status.wPortChange);
- if (!(status & UPS_CURRENT_CONNECT_STATUS)) {
- /* nothing connected, just ignore it */
- DPRINTF(sc, 1, "port %d, device disappeared "
- "after reset\n", portno);
- continue;
+ } else {
+ DPRINTF(sc, 0, "Port %d is in Device Mode\n", portno);
+ }
+
+ /*
+ * Figure out the device speed
+ */
+ speed =
+ (sc->sc_st.port_status & UPS_HIGH_SPEED) ? USB_SPEED_HIGH :
+ (sc->sc_st.port_status & UPS_LOW_SPEED) ? USB_SPEED_LOW : USB_SPEED_FULL;
+
+ /*
+ * Figure out the device mode
+ *
+ * NOTE: This part is currently FreeBSD specific.
+ */
+ usb_mode =
+ (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE) ?
+ USB_MODE_DEVICE : USB_MODE_HOST;
+
+ /* need to create a new child */
+
+ child = usbd_alloc_device(sc->sc_dev, udev->bus, udev,
+ udev->depth + 1, portno - 1, portno, speed, usb_mode);
+ if (child == NULL) {
+ DPRINTF(sc, -1, "could not allocate new device!\n");
+ goto error;
+ }
+ return (0); /* success */
+
+error:
+ if (child) {
+ usbd_detach_device(child, USB_IFACE_INDEX_ANY, 1);
+ usbd_free_device(child);
+ child = NULL;
+ }
+ if (err == 0) {
+ err = usbreq_clear_port_feature
+ (sc->sc_udev, &usb_global_lock, portno, UHF_PORT_ENABLE);
+ }
+ if (err) {
+ DPRINTF(sc, -1, "device problem (%s), "
+ "disabling port %d\n", usbd_errstr(err), portno);
+ }
+ return (err);
+}
+
+/*------------------------------------------------------------------------*
+ * uhub_explore
+ *
+ * Returns:
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+static usbd_status_t
+uhub_explore(struct usbd_device *udev)
+{
+ struct usbd_hub *hub;
+ struct uhub_softc *sc;
+ struct usbd_port *up;
+ usbd_status_t err;
+ uint8_t portno;
+ uint8_t x;
+
+ hub = udev->hub;
+ sc = hub->hubsoftc;
+
+ DPRINTF(sc, 10, "udev=%p addr=%d\n", udev, udev->address);
+
+ /* ignore hubs that are too deep */
+ if (udev->depth > USB_HUB_MAX_DEPTH) {
+ return (USBD_TOO_DEEP);
+ }
+ 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;
}
- /* figure out device speed */
- speed =
- (status & UPS_HIGH_SPEED) ? USB_SPEED_HIGH :
- (status & UPS_LOW_SPEED) ? USB_SPEED_LOW : USB_SPEED_FULL;
+ if (sc->sc_st.port_change & UPS_C_PORT_ENABLED) {
+ err = usbreq_clear_port_feature(
+ udev, &usb_global_lock, portno, UHF_C_PORT_ENABLE);
+ if (err) {
+ /* most likely the HUB is gone */
+ break;
+ }
+ if (sc->sc_st.port_change & UPS_C_CONNECT_STATUS) {
+ /*
+ * Ignore the port error if the device
+ * has vanished !
+ */
+ } else if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
+ DPRINTF(sc, -1, "illegal enable change, "
+ "port %d\n", portno);
+ } else {
- /* get device info and set its address */
- err = usbd_new_device(sc->sc_dev, udev->bus, udev,
- udev->depth + 1, speed, x, portno);
- if (err == 0) {
- err = uhub_explore_sub(sc->sc_dev, udev, up);
+ if (up->restartcnt == USBD_RESTART_MAX) {
+ /* XXX could try another speed ? */
+ DPRINTF(sc, -1, "port error, giving up "
+ "port %d\n", portno);
+ } else {
+ sc->sc_st.port_change |= UPS_C_CONNECT_STATUS;
+ up->restartcnt++;
+ }
+ }
+ }
+ 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;
+ }
}
+ err = uhub_explore_sub(sc, up);
if (err) {
- DPRINTF(sc, -1, "usb_new_device failed, "
- "error=%s\n", usbd_errstr(err));
- /* Avoid addressing problems by disabling. */
- /*
- * usbreq_reset_port (udev, &usb_global_lock,
- * &up->status, portno);
- */
-
- /*
- * The unit refused to accept a new address, or had
- * some other serious problem. Since we cannot leave
- * at 0 we have to disable the port instead.
- */
- DPRINTF(sc, -1, "device problem (%s), "
- "disabling port %d\n", usbd_errstr(err), portno);
- usbreq_clear_port_feature
- (udev, &usb_global_lock, portno, UHF_PORT_ENABLE);
+ /* no device(s) present */
continue;
}
- /*
- * The port setup succeeded, reset error count and do
- * recursive explore, if any:
- */
+ /* explore succeeded - reset restart counter */
up->restartcnt = 0;
-
}
return (USBD_NORMAL_COMPLETION);
}
@@ -433,9 +520,8 @@
return (UMATCH_NONE);
}
/*
- * the subclass for hubs, is ignored,
- * because it is 0 for some
- * and 1 for others
+ * The subclass for USB HUBs is ignored because it is 0 for some
+ * and 1 for others.
*/
if ((uaa->iface == NULL) && (dd->bDeviceClass == UDCLASS_HUB)) {
@@ -484,18 +570,18 @@
DPRINTF(sc, 1, "depth=%d selfpowered=%d, parent=%p, "
"parent->selfpowered=%d\n",
udev->depth,
- udev->self_powered,
+ udev->flags.self_powered,
parent_hub,
parent_hub ?
- parent_hub->self_powered : 0);
+ parent_hub->flags.self_powered : 0);
if (udev->depth > USB_HUB_MAX_DEPTH) {
DPRINTF(sc, -1, "hub depth, %d, exceeded. HUB ignored!\n",
USB_HUB_MAX_DEPTH);
goto error;
}
- if (!udev->self_powered && parent_hub &&
- (!parent_hub->self_powered)) {
+ if (!udev->flags.self_powered && parent_hub &&
+ (!parent_hub->flags.self_powered)) {
DPRINTF(sc, -1, "bus powered hub connected to "
"bus powered hub. HUB ignored!\n");
goto error;
@@ -547,11 +633,11 @@
/* initialize HUB structure */
hub->hubsoftc = sc;
hub->explore = &uhub_explore;
- hub->hubdesc = hubdesc;
+ hub->nports = hubdesc.bNbrPorts;
hub->hubudev = udev;
/* if self powered hub, give ports maximum current */
- if (udev->self_powered) {
+ if (udev->flags.self_powered) {
hub->portpower = USB_MAX_POWER;
} else {
hub->portpower = USB_MIN_POWER;
@@ -599,11 +685,11 @@
pwrdly = ((hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
USB_EXTRA_POWER_UP_TIME);
- for (x = 0; x < nports; x++) {
+ for (x = 0; x != nports; x++) {
/* set up data structures */
struct usbd_port *up = hub->ports + x;
- up->device_addr = USB_START_ADDR;
+ up->device_index = 0;
up->restartcnt = 0;
portno = x + 1;
@@ -628,11 +714,7 @@
device_printf(dev, "%d port%s with %d "
"removable, %s powered\n", nports, (nports != 1) ? "s" : "",
- removable, udev->self_powered ? "self" : "bus");
-
- /* the usual exploration will finish the setup */
-
- sc->sc_flags |= UHUB_FLAG_RUNNING;
+ removable, udev->flags.self_powered ? "self" : "bus");
/* start the interrupt endpoint */
@@ -670,16 +752,17 @@
if (hub == NULL) { /* must be partially working */
return (0);
}
- for (x = 0; x < hub->hubdesc.bNbrPorts; x++) {
+ for (x = 0; x != hub->nports; x++) {
- child = uhub_port_to_sub_device(sc->sc_udev, hub->ports + x);
+ child = usbd_bus_port_get_device(sc->sc_udev->bus, hub->ports + x);
/*
* Subdevices are not freed, because the caller of
- * uhub_detach() will do that. The function we are calling
- * is NULL safe.
+ * uhub_detach() will do that. The function we are
+ * calling is NULL safe.
*/
- usbd_free_device(child, 0);
+ usbd_detach_device(child, USB_IFACE_INDEX_ANY, 0);
+ usbd_free_device(child);
}
usbd_transfer_unsetup(sc->sc_xfer, 2);
@@ -696,59 +779,77 @@
return;
}
+struct hub_result {
+ struct usbd_device *udev;
+ uint8_t portno;
+ uint8_t iface_index;
+};
+
+static void
+uhub_find_iface_index(struct usbd_hub *hub, device_t child,
+ struct hub_result *res)
+{
+ struct usbd_interface *iface;
+ struct usbd_device *udev;
+ uint8_t nports;
+ uint8_t x;
+ uint8_t i;
+
+ nports = hub->nports;
+ for (x = 0; x != nports; x++) {
+ udev = usbd_bus_port_get_device(hub->hubudev->bus,
+ hub->ports + x);
+ if (!udev) {
+ continue;
+ }
+ if (udev->global_dev == child) {
+ res->iface_index = 0;
+ res->udev = udev;
+ res->portno = x + 1;
+ return;
+ }
+ for (i = 0; i != USB_MAX_INTERFACES; i++) {
+ iface = usbd_get_iface(udev, i);
+ if (iface &&
+ (iface->subdev == child)) {
+ res->iface_index = i;
+ res->udev = udev;
+ res->portno = x + 1;
+ return;
+ }
+ }
+ }
+ res->iface_index = 0;
+ res->udev = NULL;
+ res->portno = 0;
+ return;
+}
+
static int
uhub_child_location_string(device_t parent, device_t child,
char *buf, size_t buflen)
{
struct uhub_softc *sc = device_get_softc(parent);
struct usbd_hub *hub = sc->sc_udev->hub;
- struct usbd_device *udev;
- uint8_t x;
- uint8_t nports;
- uint8_t iface_index;
+ struct hub_result res;
mtx_lock(&usb_global_lock);
-
- nports = hub->hubdesc.bNbrPorts;
- for (x = 0; x < nports; x++) {
- udev = uhub_port_to_sub_device(sc->sc_udev, hub->ports + x);
- if (udev) {
- device_t *subdev =
- &udev->subdevs[0];
- device_t *subdev_end =
- &udev->subdevs_end[0];
-
- iface_index = 0;
-
- while (subdev < subdev_end) {
- if (subdev[0] == child) {
- goto found;
- }
- subdev++;
- iface_index++;
- }
+ uhub_find_iface_index(hub, child, &res);
+ if (!res.udev) {
+ DPRINTF(sc, 0, "device not on hub\n");
+ if (buflen) {
+ buf[0] = '\0';
}
+ goto done;
}
-
- mtx_unlock(&usb_global_lock);
-
- DPRINTF(sc, 0, "device not on hub\n");
-
- if (buflen) {
- buf[0] = '\0';
- }
- return (0);
-
-
-found:
-
- if (udev->probed == USBD_PROBED_IFACE_AND_FOUND) {
+ if (res.udev->probed == USBD_PROBED_IFACE_AND_FOUND) {
snprintf(buf, buflen, "port=%i interface=%i",
- x + 1, iface_index);
+ res.portno, res.iface_index);
} else {
- snprintf(buf, buflen, "port=%i", x + 1);
+ snprintf(buf, buflen, "port=%i", res.portno);
}
+done:
mtx_unlock(&usb_global_lock);
return (0);
@@ -761,71 +862,44 @@
struct uhub_softc *sc = device_get_softc(parent);
struct usbd_hub *hub = sc->sc_udev->hub;
struct usbd_interface *iface;
- struct usbd_device *udev;
- uint8_t x;
- uint8_t nports;
- uint8_t iface_index;
+ struct hub_result res;
mtx_lock(&usb_global_lock);
-
- nports = hub->hubdesc.bNbrPorts;
- for (x = 0; x < nports; x++) {
- udev = uhub_port_to_sub_device(sc->sc_udev, hub->ports + x);
- if (udev) {
- device_t *subdev =
- &udev->subdevs[0];
- device_t *subdev_end =
- &udev->subdevs_end[0];
-
- iface_index = 0;
-
- while (subdev < subdev_end) {
- if (subdev[0] == child) {
- goto found;
- }
- subdev++;
- iface_index++;
- }
+ uhub_find_iface_index(hub, child, &res);
+ if (!res.udev) {
+ DPRINTF(sc, 0, "device not on hub\n");
+ if (buflen) {
+ buf[0] = '\0';
}
+ goto done;
}
+ iface = usbd_get_iface(res.udev, res.iface_index);
- mtx_unlock(&usb_global_lock);
-
- DPRINTF(sc, 0, "device not on hub\n");
-
- if (buflen) {
- buf[0] = '\0';
- }
- return (0);
-
-found:
-
- iface = usbd_get_iface(udev, iface_index);
-
- if ((udev->probed == USBD_PROBED_IFACE_AND_FOUND) &&
+ if ((res.udev->probed == USBD_PROBED_IFACE_AND_FOUND) &&
iface && iface->idesc) {
snprintf(buf, buflen, "vendor=0x%04x product=0x%04x "
"devclass=0x%02x devsubclass=0x%02x "
"sernum=\"%s\" "
"intclass=0x%02x intsubclass=0x%02x",
- UGETW(udev->ddesc.idVendor),
- UGETW(udev->ddesc.idProduct),
- udev->ddesc.bDeviceClass,
- udev->ddesc.bDeviceSubClass,
- &udev->serial[0],
+ UGETW(res.udev->ddesc.idVendor),
+ UGETW(res.udev->ddesc.idProduct),
+ res.udev->ddesc.bDeviceClass,
+ res.udev->ddesc.bDeviceSubClass,
+ res.udev->serial,
iface->idesc->bInterfaceClass,
iface->idesc->bInterfaceSubClass);
} else {
snprintf(buf, buflen, "vendor=0x%04x product=0x%04x "
"devclass=0x%02x devsubclass=0x%02x "
"sernum=\"%s\"",
- UGETW(udev->ddesc.idVendor),
- UGETW(udev->ddesc.idProduct),
- udev->ddesc.bDeviceClass,
- udev->ddesc.bDeviceSubClass,
- &udev->serial[0]);
+ UGETW(res.udev->ddesc.idVendor),
+ UGETW(res.udev->ddesc.idProduct),
+ res.udev->ddesc.bDeviceClass,
+ res.udev->ddesc.bDeviceSubClass,
+ res.udev->serial);
}
+done:
mtx_unlock(&usb_global_lock);
return (0);
More information about the p4-projects
mailing list