PERFORCE change 155936 for review

Hans Petter Selasky hselasky at FreeBSD.org
Sat Jan 10 12:50:10 PST 2009


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

Change 155936 by hselasky at hselasky_laptop001 on 2009/01/10 20:49:20

	
	Save an USB transfer in UHUB driver by using
	the builtin clear-stall mechanism.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_hub.c#31 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_hub.c#31 (text+ko) ====

@@ -53,6 +53,7 @@
 #include <dev/usb2/controller/usb2_bus.h>
 
 #define	UHUB_INTR_INTERVAL 250		/* ms */
+#define	UHUB_N_TRANSFER 1
 
 #if USB_DEBUG
 static int uhub_debug = 0;
@@ -76,10 +77,9 @@
 	struct uhub_current_state sc_st;/* current state */
 	device_t sc_dev;		/* base device */
 	struct usb2_device *sc_udev;	/* USB device */
-	struct usb2_xfer *sc_xfer[2];	/* interrupt xfer */
+	struct usb2_xfer *sc_xfer[UHUB_N_TRANSFER];	/* interrupt xfer */
 	uint8_t	sc_flags;
 #define	UHUB_FLAG_DID_EXPLORE 0x01
-#define	UHUB_FLAG_INTR_STALL 0x02
 	char	sc_name[32];
 };
 
@@ -100,12 +100,11 @@
 static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string;
 
 static usb2_callback_t uhub_intr_callback;
-static usb2_callback_t uhub_intr_clear_stall_callback;
 
 static void usb2_dev_resume_peer(struct usb2_device *udev);
 static void usb2_dev_suspend_peer(struct usb2_device *udev);
 
-static const struct usb2_config uhub_config[2] = {
+static const struct usb2_config uhub_config[UHUB_N_TRANSFER] = {
 
 	[0] = {
 		.type = UE_INTERRUPT,
@@ -117,17 +116,6 @@
 		.mh.callback = &uhub_intr_callback,
 		.mh.interval = UHUB_INTR_INTERVAL,
 	},
-
-	[1] = {
-		.type = UE_CONTROL,
-		.endpoint = 0,
-		.direction = UE_DIR_ANY,
-		.mh.timeout = 1000,	/* 1 second */
-		.mh.interval = 50,	/* 50ms */
-		.mh.flags = {},
-		.mh.bufsize = sizeof(struct usb2_device_request),
-		.mh.callback = &uhub_intr_clear_stall_callback,
-	},
 };
 
 /*
@@ -160,19 +148,6 @@
 DRIVER_MODULE(ushub, ushub, uhub_driver, uhub_devclass, NULL, 0);
 
 static void
-uhub_intr_clear_stall_callback(struct usb2_xfer *xfer)
-{
-	struct uhub_softc *sc = xfer->priv_sc;
-	struct usb2_xfer *xfer_other = sc->sc_xfer[0];
-
-	if (usb2_clear_stall_callback(xfer, xfer_other)) {
-		DPRINTF("stall cleared\n");
-		sc->sc_flags &= ~UHUB_FLAG_INTR_STALL;
-		usb2_transfer_start(xfer_other);
-	}
-}
-
-static void
 uhub_intr_callback(struct usb2_xfer *xfer)
 {
 	struct uhub_softc *sc = xfer->priv_sc;
@@ -189,21 +164,22 @@
 		usb2_needs_explore(sc->sc_udev->bus, 0);
 
 	case USB_ST_SETUP:
-		if (sc->sc_flags & UHUB_FLAG_INTR_STALL) {
-			usb2_transfer_start(sc->sc_xfer[1]);
-		} else {
-			xfer->frlengths[0] = xfer->max_data_length;
-			usb2_start_hardware(xfer);
-		}
-		return;
+		xfer->frlengths[0] = xfer->max_data_length;
+		usb2_start_hardware(xfer);
+		break;
 
 	default:			/* Error */
 		if (xfer->error != USB_ERR_CANCELLED) {
-			/* start clear stall */
-			sc->sc_flags |= UHUB_FLAG_INTR_STALL;
-			usb2_transfer_start(sc->sc_xfer[1]);
+			/*
+			 * Do a clear-stall. The "stall_pipe" flag
+			 * will get cleared before next callback by
+			 * the USB stack.
+			 */
+			xfer->flags.stall_pipe = 1;
+			xfer->frlengths[0] = xfer->max_data_length;
+			usb2_start_hardware(xfer);
 		}
-		return;
+		break;
 	}
 }
 
@@ -736,7 +712,7 @@
 	/* set up interrupt pipe */
 	iface_index = 0;
 	err = usb2_transfer_setup(udev, &iface_index, sc->sc_xfer,
-	    uhub_config, 2, sc, &Giant);
+	    uhub_config, UHUB_N_TRANSFER, sc, &Giant);
 	if (err) {
 		DPRINTFN(0, "cannot setup interrupt transfer, "
 		    "errstr=%s!\n", usb2_errstr(err));
@@ -821,7 +797,7 @@
 	return (0);
 
 error:
-	usb2_transfer_unsetup(sc->sc_xfer, 2);
+	usb2_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
 
 	if (udev->hub) {
 		free(udev->hub, M_USBDEV);
@@ -864,7 +840,7 @@
 		child = NULL;
 	}
 
-	usb2_transfer_unsetup(sc->sc_xfer, 2);
+	usb2_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
 
 	free(hub, M_USBDEV);
 	sc->sc_udev->hub = NULL;


More information about the p4-projects mailing list