Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Dec 2007 22:24:00 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 131546 for review
Message-ID:  <200712242224.lBOMO0tN037799@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=131546

Change 131546 by hselasky@hselasky_laptop001 on 2007/12/24 22:23:44

	
	Bugfixes related to USB device side mode.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#84 edit

Differences ...

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

@@ -1389,12 +1389,8 @@
 {
 	uint32_t len;
 
-	/*
-	 * USB control endpoints are not just straight forward ...
-	 * Check for STALL:
-	 */
-	if (xfer->flags.stall_pipe &&
-	    (xfer->flags_int.usb_mode == USB_MODE_DEVICE)) {
+	/* Check for control endpoint stall */
+	if (xfer->flags.stall_pipe) {
 		/* no longer active */
 		xfer->flags_int.control_act = 0;
 	}
@@ -1464,9 +1460,23 @@
 	/* check if there is a length mismatch */
 
 	if (len > xfer->flags_int.control_rem) {
+		PRINTFN(-1, ("Length greater than remaining length!\n"));
 		goto error;
 	}
-	xfer->flags_int.control_rem -= len;
+	/* check if we are doing a short transfer */
+
+	if (xfer->flags.force_short_xfer) {
+		xfer->flags_int.control_rem = 0;
+	} else {
+		if ((len != xfer->max_data_length) &&
+		    (len != xfer->flags_int.control_rem) &&
+		    (xfer->nframes != 1)) {
+			PRINTFN(-1, ("Short control transfer without "
+			    "force_short_xfer set!\n"));
+			goto error;
+		}
+		xfer->flags_int.control_rem -= len;
+	}
 
 	/* the status part is executed when "control_act" is 0 */
 
@@ -1524,9 +1534,8 @@
 	uint32_t x;
 
 	PRINTFN(0, ("xfer=%p, pipe=%p, nframes=%d, dir=%s\n",
-	    xfer, xfer->pipe, xfer->nframes,
-	    ((xfer->endpoint & (UE_DIR_IN | UE_DIR_OUT)) ==
-	    UE_DIR_IN) ? "in" : "out"));
+	    xfer, xfer->pipe, xfer->nframes, USBD_GET_DATA_ISREAD(xfer) ?
+	    "read" : "write"));
 
 #ifdef USB_DEBUG
 	if (usbdebug > 0) {
@@ -2511,10 +2520,11 @@
 	if (xfer->flags.stall_pipe &&
 	    (xfer->flags_int.usb_mode == USB_MODE_DEVICE)) {
 		/*
-	         * We can not stall ISOCHRONOUS endpoints !
-	         */
+		 * Only stall BULK and INTERRUPT endpoints.
+		 */
 		type = (xfer->pipe->edesc->bmAttributes & UE_XFERTYPE);
-		if (type != UE_ISOCHRONOUS) {
+		if ((type == UE_BULK) ||
+		    (type == UE_INTERRUPT)) {
 			xfer->pipe->is_stalled = 1;
 			(xfer->udev->bus->methods->set_stall) (
 			    xfer->udev, NULL, xfer->pipe);
@@ -3053,15 +3063,16 @@
 
 	usbd_copy_out(xfer->frbuffers + 0, 0, &req, sizeof(req));
 
-	/* get the remainder of the control transfer */
+	if (xfer->flags_int.control_rem == 0xFFFF) {
+		/* first time - not initialised */
+		rem = UGETW(req.wLength);
+		off = 0;
+	} else {
+		/* not first time - initialised */
+		rem = xfer->flags_int.control_rem;
+		off = UGETW(req.wLength) - rem;
+	}
 
-	rem = (xfer->flags_int.control_rem == 0xFFFF) ? 0 :
-	    xfer->flags_int.control_rem;
-
-	/* compute the current offset */
-
-	off = UGETW(req.wLength) - rem;
-
 	/* set some defaults */
 
 	max_len = 0;
@@ -3271,10 +3282,10 @@
 tr_handle_set_interface:
 	if (state == ST_DATA) {
 		goto tr_bad_context;
-	} else if ((state == ST_CONTEXT_START) &&
-		    usbd_handle_set_alt_setting(
-	    xfer, wValue, wIndex)) {
-		goto tr_stalled;
+	} else if (state == ST_CONTEXT_START) {
+		if (usbd_handle_set_alt_setting(xfer, wIndex - 1, wValue)) {
+			goto tr_stalled;
+		}
 	}
 	goto tr_valid;
 
@@ -3329,6 +3340,7 @@
 		xfer->flags.manual_status = 0;
 		xfer->frlengths[1] = 0;
 	}
+	xfer->flags.stall_pipe = 0;	/* do not stall pipe */
 	return (0);			/* success */
 
 tr_stalled:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712242224.lBOMO0tN037799>