PERFORCE change 120880 for review

Hans Petter Selasky hselasky at FreeBSD.org
Mon Jun 4 06:56:53 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=120880

Change 120880 by hselasky at hselasky_mini_itx on 2007/06/04 06:56:26

	Updates to uhub.c. Make the code more style compliant. Make all
	debugging printouts go through DPRINTF(). Add a timer instead
	of looping when clearing of stall fails.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/uhub.c#11 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/uhub.c#11 (text+ko) ====

@@ -1,3 +1,6 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/usb/uhub.c,v 1.74 2007/02/03 21:11:11 flz Exp $");
+
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -39,7 +42,6 @@
  * USB spec: http://www.usb.org/developers/docs/usbspec.zip
  */
 
-#include <sys/cdefs.h>
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -50,31 +52,35 @@
 #include <dev/usb/usb.h>
 #include <dev/usb/usb_subr.h>
 
-__FBSDID("$FreeBSD: src/sys/dev/usb/uhub.c,v 1.74 2007/02/03 21:11:11 flz Exp $");
+#define	UHUB_INTR_INTERVAL 250	/* ms */
 
-#define UHUB_INTR_INTERVAL 250	/* ms */
+#ifdef USB_DEBUG
+#define DPRINTF(sc,n,fmt,...)	\
+  do { if (uhub_debug > (n)) {	     \
+      printf("%s:%s: " fmt, (sc)->sc_name, \
+	     __FUNCTION__,## __VA_ARGS__); } } while (0)
 
-#ifdef USB_DEBUG
-#undef DPRINTF
-#undef DPRINTFN
-#define DPRINTF(x)	{ if (uhubdebug) { printf("%s: ", __FUNCTION__); printf x; } }
-#define DPRINTFN(n,x)	{ if (uhubdebug>(n)) { printf("%s: ", __FUNCTION__); printf x; } }
-int	uhubdebug = 0;
+static int uhub_debug = 0;
 SYSCTL_NODE(_hw_usb, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB uhub");
-SYSCTL_INT(_hw_usb_uhub, OID_AUTO, debug, CTLFLAG_RW,
-	   &uhubdebug, 0, "uhub debug level");
+SYSCTL_INT(_hw_usb_uhub, OID_AUTO, debug, CTLFLAG_RW, &uhub_debug, 0,
+	   "uhub debug level");
+#else
+#define DPRINTF(...) do { } while (0)
 #endif
 
-struct uhub_softc
-{
-	device_t       		sc_dev;         /* base device */
-	struct usbd_device *	sc_hub;         /* USB device */
-	struct usbd_xfer *	sc_xfer[2];	/* interrupt xfer */
-	u_int8_t                sc_running;
+struct uhub_softc {
+	struct __callout	sc_watchdog;
+	device_t		sc_dev;		/* base device */
+	struct usbd_device	*sc_hub;	/* 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];
 };
-#define UHUB_PROTO(sc) ((sc)->sc_hub->ddesc.bDeviceProtocol)
-#define UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
-#define UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
+#define	UHUB_PROTO(sc) ((sc)->sc_hub->ddesc.bDeviceProtocol)
+#define	UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
+#define	UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
 
 /* prototypes for type checking: */
 
@@ -86,26 +92,136 @@
 static bus_child_location_str_t uhub_child_location_string;
 static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string;
 
+static usbd_callback_t uhub_intr_callback;
+static usbd_callback_t uhub_intr_clear_stall_callback;
+
+static void uhub_watchdog(void *arg);
+
+static const struct usbd_config uhub_config[2] = {
+
+    [0] = {
+      .type      = UE_INTERRUPT,
+      .endpoint  = UE_ADDR_ANY,
+      .direction = UE_DIR_ANY,
+      .timeout   = 0,
+      .flags     = USBD_SHORT_XFER_OK,
+      .bufsize   = 0, /* use wMaxPacketSize */
+      .callback  = &uhub_intr_callback,
+      .interval  = UHUB_INTR_INTERVAL,
+    },
+
+    [1] = {
+      .type      = UE_CONTROL,
+      .endpoint  = 0,
+      .direction = UE_DIR_ANY,
+      .timeout   = USBD_DEFAULT_TIMEOUT,
+      .flags     = 0,
+      .bufsize   = sizeof(usb_device_request_t),
+      .callback  = &uhub_intr_clear_stall_callback,
+    },
+};
+
 /*
- * Hub interrupt.
- * This an indication that some port has changed status.
- * Notify the bus event handler thread that we need
- * to be explored again.
+ * driver instance for "hub" connected to "usb" 
+ * and "hub" connected to "hub"
  */
+static devclass_t uhub_devclass;
+
+static driver_t uhub_driver =
+{
+	.name    = "uhub",
+	.methods = (device_method_t [])
+        {
+	  DEVMETHOD(device_probe, uhub_probe),
+	  DEVMETHOD(device_attach, uhub_attach),
+	  DEVMETHOD(device_detach, uhub_detach),
+
+	  DEVMETHOD(device_suspend, bus_generic_suspend),
+	  DEVMETHOD(device_resume, bus_generic_resume),
+	  DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+	  DEVMETHOD(bus_child_location_str, uhub_child_location_string),
+	  DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string),
+	  DEVMETHOD(bus_driver_added, uhub_driver_added),
+	  {0,0}
+	},
+	.size    = sizeof(struct uhub_softc)
+};
+
+DRIVER_MODULE(uhub, usb, uhub_driver, uhub_devclass, 0, 0);
+DRIVER_MODULE(uhub, uhub, uhub_driver, uhub_devclass, usbd_driver_load, 0);
+MODULE_DEPEND(uhub, usb, 1, 1, 1);
+
 static void
-uhub_interrupt(struct usbd_xfer *xfer)
+uhub_watchdog(void *arg)
+{
+	struct uhub_softc *sc = arg;
+	mtx_assert(&usb_global_lock, MA_OWNED);
+	usbd_transfer_start(sc->sc_xfer[0]);	
+	mtx_unlock(&usb_global_lock);
+	return;
+}
+
+static void
+uhub_intr_clear_stall_callback(struct usbd_xfer *xfer)
+{
+	struct uhub_softc *sc = xfer->priv_sc;
+	struct usbd_xfer *xfer_other = sc->sc_xfer[0];
+
+	USBD_CHECK_STATUS(xfer);
+
+ tr_setup:
+	/* start clear stall */
+	usbd_clear_stall_tr_setup(xfer, xfer_other);
+        return;
+
+ tr_transferred:
+	usbd_clear_stall_tr_transferred(xfer, xfer_other);
+
+	sc->sc_flags &= ~UHUB_FLAG_INTR_STALL;
+	usbd_transfer_start(xfer_other);
+	return;
+
+ tr_error:
+	sc->sc_flags &= ~UHUB_FLAG_INTR_STALL;
+	if (xfer->error != USBD_CANCELLED) {
+	    __callout_reset(&(sc->sc_watchdog), hz, &uhub_watchdog, sc);
+	    DPRINTF(sc, -1, "Interrupt pipe stopped! Watchdog started!\n");
+	}
+	return;
+}
+
+static void
+uhub_intr_callback(struct usbd_xfer *xfer)
 {
+	struct uhub_softc *sc = xfer->priv_sc;
+
 	USBD_CHECK_STATUS(xfer);
 
  tr_transferred:
-	usb_needs_explore(((struct uhub_softc *)(xfer->priv_sc))->sc_hub);
+	DPRINTF(sc, 1, "\n");
+	/*
+	 * This is an indication that some port
+	 * has changed status. Notify the bus
+	 * event handler thread that we need
+	 * to be explored again:
+	 */
+	usb_needs_explore(sc->sc_hub);
 
  tr_setup:
+	if (sc->sc_flags & UHUB_FLAG_INTR_STALL) {
+	    usbd_transfer_start(sc->sc_xfer[1]);
+	} else {
+	    usbd_start_hardware(xfer);
+	}
+	return;
+
  tr_error:
-	/* re-transfer xfer->buffer;
-	 * xfer->length is unchanged
-	 */
-	usbd_start_hardware(xfer);
+	if (xfer->error != USBD_CANCELLED) {
+	    /* start clear stall */
+	    sc->sc_flags |= UHUB_FLAG_INTR_STALL;
+	    usbd_transfer_start(sc->sc_xfer[1]);
+	}
 	return;
 }
 
@@ -116,13 +232,14 @@
 	struct uhub_softc *sc = udev->hub->hubsoftc;
 	struct usbd_port *up;
 	usbd_status err;
-	int speed;
-	int port;
-	int change, status;
+	uint16_t port;
+	uint16_t change;
+	uint16_t status;
+	uint8_t speed;
 
-	DPRINTFN(10, ("udev=%p addr=%d\n", udev, udev->address));
+	DPRINTF(sc, 10, "udev=%p addr=%d\n", udev, udev->address);
 
-	if (!sc->sc_running)
+	if (!(sc->sc_flags & UHUB_FLAG_RUNNING))
 	{
 		return (USBD_NOT_STARTED);
 	}
@@ -139,17 +256,17 @@
 		err = usbreq_get_port_status(udev, port, &up->status);
 		if (err)
 		{
-			DPRINTF(("get port status failed, "
-				 "error=%s\n", usbd_errstr(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);
-		DPRINTFN(3,("%s: port %d status 0x%04x 0x%04x\n",
-			    device_get_nameunit(sc->sc_dev), port, status, change));
+		DPRINTF(sc, 3, "port %d status 0x%04x 0x%04x\n",
+			port, status, change);
 		if(change & UPS_C_PORT_ENABLED)
 		{
-			DPRINTF(("C_PORT_ENABLED 0x%x\n", change));
+			DPRINTF(sc, 0, "C_PORT_ENABLED 0x%x\n", change);
 			usbreq_clear_port_feature(udev, port, UHF_C_PORT_ENABLE);
 			if(change & UPS_C_CONNECT_STATUS)
 			{
@@ -159,31 +276,30 @@
 			}
 			else if(status & UPS_PORT_ENABLED)
 			{
-				device_printf(sc->sc_dev,
-					      "illegal enable change, port %d\n", port);
+				DPRINTF(sc, -1, "illegal enable change, "
+					"port %d\n", port);
 			}
 			else
 			{
 				/* port error condition */
 				if(up->restartcnt) /* no message first time */
 				{
-					device_printf(sc->sc_dev,
-						      "port error, restarting "
-						      "port %d\n", port);
+					DPRINTF(sc, -1, "port error, restarting "
+						"port %d\n", port);
 				}
 
-				if(up->restartcnt++ < USBD_RESTART_MAX)
+				if(up->restartcnt++ < USBD_RESTART_MAX) {
 					goto disconnect;
-				else
-					device_printf(sc->sc_dev,
-						      "port error, giving up "
-						      "port %d\n", port);
+				} else {
+					DPRINTF(sc, -1, "port error, giving up "
+						"port %d\n", port);
+				}
 			}
 		}
 		if(!(change & UPS_C_CONNECT_STATUS))
 		{
-			DPRINTFN(3,("port=%d !C_CONNECT_"
-				    "STATUS\n", port));
+			DPRINTF(sc, 3, "port=%d !C_CONNECT_"
+				"STATUS\n", port);
 			/* no status change, just do recursive explore */
 			if(up->device != NULL)
 			{
@@ -202,21 +318,13 @@
 					}
 				}
 			}
-#if 0 && defined(DIAGNOSTIC)
-			if((up->device == NULL) &&
-			   (status & UPS_CURRENT_CONNECT_STATUS))
-			{
-				device_printf(sc->sc_dev,
-					      "connected, no device\n");
-			}
-#endif
 			continue;
 		}
 
 		/* we have a connect status change, handle it */
 
-		DPRINTF(("status change hub=%d port=%d\n",
-			 udev->address, port));
+		DPRINTF(sc, 0, "status change hub=%d port=%d\n",
+			udev->address, port);
 		usbreq_clear_port_feature(udev, port, UHF_C_PORT_CONNECTION);
 		/*usbreq_clear_port_feature(udev, port, UHF_C_PORT_ENABLE);*/
 		/*
@@ -230,8 +338,8 @@
 		if(up->device != NULL)
 		{
 			/* disconnected */
-			DPRINTF(("device addr=%d disappeared "
-				 "on port %d\n", up->device->address, port));
+			DPRINTF(sc, 0, "device addr=%d disappeared "
+				"on port %d\n", up->device->address, port);
 			usbd_free_device(up, 1);
 			usbreq_clear_port_feature(udev, port,
 						  UHF_C_PORT_CONNECTION);
@@ -239,8 +347,8 @@
 		if(!(status & UPS_CURRENT_CONNECT_STATUS))
 		{
 			/* nothing connected, just ignore it */
-			DPRINTFN(3,("port=%d !CURRENT_CONNECT_STATUS\n",
-				    port));
+			DPRINTF(sc, 3, "port=%d !CURRENT_CONNECT_STATUS\n",
+				port);
 			continue;
 		}
 
@@ -248,8 +356,8 @@
 
 		if(!(status & UPS_PORT_POWER))
 		{
-			device_printf(sc->sc_dev, "strange, connected port %d "
-				      "has no power\n", port);
+			DPRINTF(sc, -1, "strange, connected port %d "
+				"has no power\n", port);
 		}
 
 		/* wait for maximum device power up time */
@@ -258,8 +366,8 @@
 		/* reset port, which implies enabling it */
 		if(usbreq_reset_port(udev, port, &up->status))
 		{
-			device_printf(sc->sc_dev,
-				      "port %d reset failed\n", port);
+			DPRINTF(sc, -1, "port %d reset "
+				"failed\n", port);
 			continue;
 		}
 
@@ -267,8 +375,8 @@
 		err = usbreq_get_port_status(udev, port, &up->status);
 		if(err)
 		{
-			DPRINTF(("get port status failed, "
-				 "error=%s\n", usbd_errstr(err)));
+			DPRINTF(sc, 0, "get port status failed, "
+				"error=%s\n", usbd_errstr(err));
 			continue;
 		}
 		status = UGETW(up->status.wPortStatus);
@@ -276,11 +384,8 @@
 		if(!(status & UPS_CURRENT_CONNECT_STATUS))
 		{
 			/* nothing connected, just ignore it */
-#ifdef DIAGNOSTIC
-			device_printf(sc->sc_dev,
-				      "port %d, device disappeared "
-				      "after reset\n", port);
-#endif
+			DPRINTF(sc, 1, "port %d, device disappeared "
+				"after reset\n", port);
 			continue;
 		}
 
@@ -292,12 +397,10 @@
 		/* get device info and set its address */
 		err = usbd_new_device(sc->sc_dev, udev->bus,
 				      udev->depth + 1, speed, port, up);
-
-		/* XXX retry a few times? */
-		if(err)
+		if (err)
 		{
-			DPRINTFN(-1,("usb_new_device failed, "
-				     "error=%s\n", usbd_errstr(err)));
+			DPRINTF(sc, -1, "usb_new_device failed, "
+				"error=%s\n", usbd_errstr(err));
 			/* Avoid addressing problems by disabling. */
 			/* usbd_reset_port(udev, port, &up->status); */
 
@@ -306,8 +409,8 @@
 			 * some other serious problem.  Since we cannot leave
 			 * at 0 we have to disable the port instead.
 			 */
-			device_printf(sc->sc_dev, "device problem (%s), "
-				      "disabling port %d\n", usbd_errstr(err), port);
+			DPRINTF(sc, -1, "device problem (%s), "
+				"disabling port %d\n", usbd_errstr(err), port);
 			usbreq_clear_port_feature(udev, port, UHF_PORT_ENABLE);
 		}
 		else
@@ -330,7 +433,6 @@
         struct usb_attach_arg *uaa = device_get_ivars(dev);
 	usb_device_descriptor_t *dd = usbd_get_device_descriptor(uaa->device);
 
-	DPRINTFN(5,("dd=%p\n", dd));
 	/*
 	 * the subclass for hubs, is ignored,
 	 * because it is 0 for some
@@ -350,40 +452,52 @@
 	struct usb_attach_arg *uaa = device_get_ivars(dev);
 	struct usbd_device *udev = uaa->device;
 	struct usbd_hub *hub;
-	usbd_status err;
 	usb_device_request_t req;
 	usb_hub_descriptor_t hubdesc;
-	int port, nports, removable, pwrdly;
-	char devinfo[256];
+	uint16_t port;
+	uint16_t nports;
+	uint16_t removable;
+	uint16_t pwrdly;
+	usbd_status err;
 
-	DPRINTFN(1,("\n"));
+	if (sc == NULL) {
+	    return ENOMEM;
+	}
 
 	sc->sc_hub = udev;
 	sc->sc_dev = dev; 
 
+	snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
+		 device_get_nameunit(dev));
+
+	usbd_set_desc(dev, udev);
+
+        __callout_init_mtx(&(sc->sc_watchdog),
+                           &usb_global_lock, CALLOUT_RETURNUNLOCKED);
+
 	err = usbd_set_config_index(udev, 0, 1);
 	if(err)
 	{
-		DPRINTF(("%s: configuration failed, error=%s\n",
-			 device_get_nameunit(dev), usbd_errstr(err)));
+		DPRINTF(sc, -1, "configuration failed, error=%s\n",
+			usbd_errstr(err));
 		goto error;
 	}
 
 	/* NOTE: "usbd_set_config_index()" will change
 	 * variables in "udev" !
 	 */
-	DPRINTFN(1,("depth=%d selfpowered=%d, parent=%p, "
+	DPRINTF(sc, 1, "depth=%d selfpowered=%d, parent=%p, "
 		    "parent->selfpowered=%d\n",
 		    udev->depth,
 		    udev->self_powered, 
 		    udev->powersrc->parent,
 		    udev->powersrc->parent ?
-		    udev->powersrc->parent->self_powered : 0));
+		    udev->powersrc->parent->self_powered : 0);
 
 	if(udev->depth > USB_HUB_MAX_DEPTH)
 	{
-		device_printf(dev, "hub depth (%d) exceeded, hub ignored\n",
-			      USB_HUB_MAX_DEPTH);
+		DPRINTF(sc, -1, "hub depth, %d, exceeded. HUB ignored!\n",
+			USB_HUB_MAX_DEPTH);
 		goto error;
 	}
 
@@ -391,14 +505,14 @@
 	    (udev->powersrc->parent != NULL) &&
 	    (!udev->powersrc->parent->self_powered))
 	{
-		device_printf(dev, "bus powered hub connected to bus powered hub, "
-			      "ignored\n");
+		DPRINTF(sc, -1, "bus powered hub connected to "
+			"bus powered hub. HUB ignored!\n");
 		goto error;
 	}
 
 	/* get hub descriptor */
 
-	DPRINTFN(1,("getting hub descriptor\n"));
+	DPRINTF(sc, 1, "getting hub descriptor\n");
 
 	req.bmRequestType = UT_READ_CLASS_DEVICE;
 	req.bRequest = UR_GET_DESCRIPTOR;
@@ -412,90 +526,57 @@
 
 	if(!err && (nports >= 8))
 	{
-		u_int16_t len = (USB_HUB_DESCRIPTOR_SIZE-1) + ((nports+7) / 8);
+		uint16_t len = (USB_HUB_DESCRIPTOR_SIZE-1) + ((nports+7) / 8);
 		USETW(req.wLength, len);
 		err = usbd_do_request(udev, &req, &hubdesc);
 	}
 
 	if(err)
 	{
-		DPRINTF(("%s: getting hub descriptor failed, error=%s\n",
-			 device_get_nameunit(dev), usbd_errstr(err)));
+		DPRINTF(sc, -1, "getting hub descriptor failed,"
+			"error=%s\n", usbd_errstr(err));
 		goto error;
 	}
 
 	if(hubdesc.bNbrPorts != nports)
 	{
-		DPRINTF(("%s: number of ports changed!\n",
-			 device_get_nameunit(dev)));
+		DPRINTF(sc, -1, "number of ports changed!\n");
 		goto error;
 	}
 
 	if(nports == 0)
 	{
-		DPRINTF(("%s: portless HUB!\n", 
-			 device_get_nameunit(dev)));
+		DPRINTF(sc, -1, "portless HUB!\n");
 		goto error;
 	}
 
 	udev->hub = malloc((sizeof(hub[0]) + (sizeof(hub[0].ports[0]) * nports)),
-			   M_USBDEV, M_NOWAIT|M_ZERO);
+			   M_USBDEV, M_WAITOK|M_ZERO);
 
 	if(udev->hub == NULL)
 	{
 		goto error;
 	}
 
-	hub = udev->hub;
-
-	hub->hubsoftc = sc;
-	hub->explore = uhub_explore;
-	hub->hubdesc = hubdesc;
-
-	static const struct usbd_config usbd_config[2] =
-	{
-	  [0] = {
-	    .type      = UE_INTERRUPT,
-	    .endpoint  = -1, /* any pipe number */
-	    .direction = -1, /* any pipe direction */
-	    .timeout   = 0,
-	    .flags     = USBD_SHORT_XFER_OK,
-	    .bufsize   = 0x100 / 8,
-	    .callback  = uhub_interrupt,
-	    .interval  = UHUB_INTR_INTERVAL,
-	  },
-
-	  [1] = {
-	    .type      = UE_CONTROL,
-	    .endpoint  = 0,
-	    .direction = -1,
-	    .timeout   = USBD_DEFAULT_TIMEOUT,
-	    .flags     = 0,
-	    .bufsize   = sizeof(usb_device_request_t),
-	    .callback  = &usbd_clearstall_callback,
-	  },
-	};
-
 	/* set up interrupt pipe */
-	err = usbd_transfer_setup(udev, 0, &sc->sc_xfer[0], 
-				  &usbd_config[0], 2, sc, NULL);
+	err = usbd_transfer_setup(udev, 0, sc->sc_xfer, 
+				  uhub_config, 2, sc, &usb_global_lock);
 	if(err) 
 	{
-		device_printf(dev, "cannot open interrupt pipe\n");
+		DPRINTF(sc, -1, "cannot setup interrupt transfer, "
+			"errstr=%s!\n", usbd_errstr(err));
 		goto error;
 	}
 
-	/* setup clear stall */
-	sc->sc_xfer[0]->clearstall_xfer = 
-	  sc->sc_xfer[1];
+	hub = udev->hub;
 
-	usbd_transfer_start_safe(sc->sc_xfer[0]);
+	hub->hubsoftc = sc;
+	hub->explore = uhub_explore;
+	hub->hubdesc = hubdesc;
 
 	/* wait with power off for a while */
 	usbd_delay_ms(udev, USB_POWER_DOWN_TIME);
 
-	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, udev, dev);
-
 	/*
 	 * To have the best chance of success we do things in the exact same
 	 * order as Windoze98.  This should not be necessary, but some
@@ -524,8 +605,8 @@
 	/* XXX should check for none, individual, or ganged power? */
 
 	removable = 0;
-	pwrdly = (hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
-			USB_EXTRA_POWER_UP_TIME;
+	pwrdly = ((hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR) +
+		  USB_EXTRA_POWER_UP_TIME);
 
 	for(port = 1;
 	    port <= nports;
@@ -554,18 +635,15 @@
 		err = usbreq_set_port_feature(udev, port, UHF_PORT_POWER);
 		if(err)
 		{
-			device_printf(dev, "port %d power on failed, %s\n",
-				      port, usbd_errstr(err));
+			DPRINTF(sc, -1, "port %d power on failed, %s\n",
+				port, usbd_errstr(err));
 		}
-		DPRINTF(("turn on port %d power\n", port));
+		DPRINTF(sc, 0, "turn on port %d power\n", port);
 
 		/* wait for stable power */
 		usbd_delay_ms(udev, pwrdly);
 	}
 
-	usbd_devinfo(udev, 1, devinfo, sizeof(devinfo));
-	device_set_desc_copy(dev, devinfo);
-	device_printf(dev, "%s\n", devinfo);
 	device_printf(dev, "%d port%s with %d "
 		      "removable, %s powered\n",
 		      nports, (nports != 1) ? "s" : "",
@@ -573,15 +651,22 @@
 
 	/* the usual exploration will finish the setup */
 
-	sc->sc_running = 1;
+	sc->sc_flags |= UHUB_FLAG_RUNNING;
+
+	/* start the interrupt endpoint */
+
+	usbd_transfer_start_safe(sc->sc_xfer[0]);
+
 	return 0;
 
  error:
+	usbd_transfer_unsetup(sc->sc_xfer, 2);
+
 	if(udev->hub)
 	{
 		free(udev->hub, M_USBDEV);
+		udev->hub = NULL;
 	}
-	udev->hub = NULL;
 	return ENXIO;
 }
 
@@ -595,9 +680,8 @@
         struct uhub_softc *sc = device_get_softc(dev);
 	struct usbd_hub *hub = sc->sc_hub->hub;
 	struct usbd_port *up;
-	int port, nports;
-
-	DPRINTF(("sc=%port\n", sc));
+	uint16_t port;
+	uint16_t nports;
 
 	/* detach all children first */
 	bus_generic_detach(dev);
@@ -623,10 +707,13 @@
 		}
 	}
 
-	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_hub,
-			   sc->sc_dev);
+	usbd_transfer_unsetup(sc->sc_xfer, 2);
+
+	mtx_lock(&usb_global_lock);
+	__callout_stop(&(sc->sc_watchdog));
+	mtx_unlock(&usb_global_lock);
 
-	usbd_transfer_unsetup(&sc->sc_xfer[0], 2);
+	__callout_drain(&(sc->sc_watchdog));
 
 	free(hub, M_USBDEV);
 	sc->sc_hub->hub = NULL;
@@ -647,7 +734,9 @@
 	struct uhub_softc *sc = device_get_softc(parent);
 	struct usbd_hub *hub = sc->sc_hub->hub;
 	struct usbd_device *udev;
-	int port, nports, iface_index;
+	uint16_t port;
+	uint16_t nports;
+	uint8_t iface_index;
 
 	mtx_lock(&usb_global_lock);
 
@@ -681,7 +770,7 @@
 
 	mtx_unlock(&usb_global_lock);
 
-	DPRINTFN(0,("device not on hub\n"));
+	DPRINTF(sc, 0, "device not on hub\n");
 
 	if(buflen)
 	{
@@ -716,7 +805,9 @@
 	struct usbd_hub *hub = sc->sc_hub->hub;
         struct usbd_interface *iface;
 	struct usbd_device *udev;
-	int port, nports, iface_index;
+	uint16_t port;
+	uint16_t nports;
+	uint8_t iface_index;
 
 	mtx_lock(&usb_global_lock);
 
@@ -750,7 +841,7 @@
 
 	mtx_unlock(&usb_global_lock);
 
-	DPRINTFN(0,("device not on hub\n"));
+	DPRINTF(sc, 0, "device not on hub\n");
 
 	if(buflen)
 	{
@@ -794,35 +885,3 @@
 
         return (0);
 }
-
-/*
- * driver instance for "hub" connected to "usb" 
- * and "hub" connected to "hub"
- */
-static devclass_t uhub_devclass;
-
-static driver_t uhub_driver =
-{
-	.name    = "uhub",
-	.methods = (device_method_t [])
-        {
-	  DEVMETHOD(device_probe, uhub_probe),
-	  DEVMETHOD(device_attach, uhub_attach),
-	  DEVMETHOD(device_detach, uhub_detach),
-
-	  DEVMETHOD(device_suspend, bus_generic_suspend),
-	  DEVMETHOD(device_resume, bus_generic_resume),
-	  DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
-	  DEVMETHOD(bus_child_location_str, uhub_child_location_string),
-	  DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string),
-	  DEVMETHOD(bus_driver_added, uhub_driver_added),
-	  {0,0}
-	},
-	.size    = sizeof(struct uhub_softc)
-};
-
-DRIVER_MODULE(uhub, usb, uhub_driver, uhub_devclass, 0, 0);
-MODULE_DEPEND(uhub, usb, 1, 1, 1);
-
-DRIVER_MODULE(uhub, uhub, uhub_driver, uhub_devclass, usbd_driver_load, 0);


More information about the p4-projects mailing list