ChangeSet 1.872.3.5, 2002/11/18 17:08:42-08:00, mdharm-usb@one-eyed-alien.net

[PATCH] usb-storage: code consolidation

This patch puts all the code to interpret the result code from an URB into
a single place, instead of copying it everywhere throughout transport.c


diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c	Wed Nov 20 01:01:07 2002
+++ b/drivers/usb/storage/transport.c	Wed Nov 20 01:01:07 2002
@@ -479,7 +479,7 @@
 			 usb_stor_blocking_completion, NULL);
 	status = usb_stor_msg_common(us);
 
-	/* return the actual length of the data transferred if no error*/
+	/* return the actual length of the data transferred if no error */
 	if (status >= 0)
 		status = us->current_urb->actual_length;
 	return status;
@@ -543,6 +543,65 @@
 	return 0;
 }
 
+
+/*
+ * Interpret the results of a URB transfer
+ *
+ * This function prints appropriate debugging messages, clears halts on
+ * bulk endpoints, and translates the status to the corresponding
+ * USB_STOR_XFER_xxx return code.
+ */
+static int interpret_urb_result(struct us_data *us, unsigned int pipe,
+		unsigned int length, int result, unsigned int partial) {
+
+	US_DEBUGP("Status code %d; transferred %u/%u\n",
+			result, partial, length);
+
+	/* stalled */
+	if (result == -EPIPE) {
+
+		/* for non-bulk (i.e., control) endpoints, a stall indicates
+		 * a protocol error */
+		if (!usb_pipebulk(pipe)) {
+			US_DEBUGP("-- stall on control pipe\n");
+			return USB_STOR_XFER_ERROR;
+		}
+
+		/* for a bulk endpoint, clear the stall */
+		US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
+		if (usb_stor_clear_halt(us, pipe) < 0)
+			return USB_STOR_XFER_ERROR;
+		return USB_STOR_XFER_STALLED;
+	}
+
+	/* NAK - that means we've retried this a few times already */
+	if (result == -ETIMEDOUT) {
+		US_DEBUGP("-- device NAKed\n");
+		return USB_STOR_XFER_ERROR;
+	}
+
+	/* the transfer was cancelled, presumably by an abort */
+	if (result == -ENODEV) {
+		US_DEBUGP("-- transfer cancelled\n");
+		return USB_STOR_XFER_ERROR;
+	}
+
+	/* the catch-all error case */
+	if (result < 0) {
+		US_DEBUGP("-- unknown error\n");
+		return USB_STOR_XFER_ERROR;
+	}
+
+	/* no error code; did we send all the data? */
+	if (partial != length) {
+		US_DEBUGP("-- transferred only %u bytes\n", partial);
+		return USB_STOR_XFER_SHORT;
+	}
+
+	US_DEBUGP("-- transfer complete\n");
+	return USB_STOR_XFER_GOOD;
+}
+
 /*
  * Transfer one control message
  *
@@ -554,34 +613,19 @@
 		u8 request, u8 requesttype, u16 value, u16 index,
 		void *data, u16 size) {
 	int result;
+	unsigned int partial = 0;
 
 	US_DEBUGP("usb_stor_ctrl_transfer(): rq=%02x rqtype=%02x "
 			"value=%04x index=%02x len=%u\n",
 			request, requesttype, value, index, size);
 	result = usb_stor_control_msg(us, pipe, request, requesttype,
 			value, index, data, size);
-	US_DEBUGP("usb_stor_control_msg returned %d\n", result);
 
-	/* a stall indicates a protocol error */
-	if (result == -EPIPE) {
-		US_DEBUGP("-- stall on control pipe\n");
-		return USB_STOR_XFER_ERROR;
+	if (result > 0) {	/* Separate out the amount transferred */
+		partial = result;
+		result = 0;
 	}
-
-	/* some other serious problem here */
-	if (result < 0) {
-		US_DEBUGP("-- unknown error\n");
-		return USB_STOR_XFER_ERROR;
-	}
-
-	/* was the entire command transferred? */
-	if (result < size) {
-		US_DEBUGP("-- transferred only %d bytes\n", result);
-		return USB_STOR_XFER_SHORT;
-	}
-
-	US_DEBUGP("-- transfer completed successfully\n");
-	return USB_STOR_XFER_GOOD;
+	return interpret_urb_result(us, pipe, size, result, partial);
 }
 
 /*
@@ -604,42 +648,9 @@
 	/* transfer the data */
 	US_DEBUGP("usb_stor_bulk_transfer_buf(): xfer %u bytes\n", length);
 	result = usb_stor_bulk_msg(us, buf, pipe, length, &partial);
-	US_DEBUGP("usb_stor_bulk_msg() returned %d xferred %u/%u\n",
-		  result, partial, length);
 	if (act_len)
 		*act_len = partial;
-
-	/* if we stall, we need to clear it before we go on */
-	if (result == -EPIPE) {
-		US_DEBUGP("clearing endpoint halt for pipe 0x%x,"
-				" stalled at %u bytes\n", pipe, partial);
-		if (usb_stor_clear_halt(us, pipe) < 0)
-			return USB_STOR_XFER_ERROR;
-		return USB_STOR_XFER_STALLED;
-	}
-
-	/* NAK - that means we've retried a few times already */
-	if (result == -ETIMEDOUT) {
-		US_DEBUGP("-- device NAKed\n");
-		return USB_STOR_XFER_ERROR;
-	}
-
-	/* the catch-all error case */
-	if (result) {
-		US_DEBUGP("-- unknown error\n");
-		return USB_STOR_XFER_ERROR;
-	}
-
-	/* did we send all the data? */
-	if (partial == length) {
-		US_DEBUGP("-- transfer complete\n");
-		return USB_STOR_XFER_GOOD;
-	}
-
-	/* no error code, so we must have transferred some data, 
-	 * just not all of it */
-	US_DEBUGP("-- transferred only %u bytes\n", partial);
-	return USB_STOR_XFER_SHORT;
+	return interpret_urb_result(us, pipe, length, result, partial);
 }
 
 /*
@@ -653,7 +664,7 @@
 		unsigned int *act_len)
 {
 	int result;
-	int partial;
+	unsigned int partial;
 
 	/* initialize the scatter-gather request block */
 	US_DEBUGP("usb_stor_bulk_transfer_sglist(): xfer %u bytes, "
@@ -685,42 +696,9 @@
 
 	result = us->current_sg->status;
 	partial = us->current_sg->bytes;
-	US_DEBUGP("usb_sg_wait() returned %d xferred %u/%u\n",
-			result, partial, length);
 	if (act_len)
 		*act_len = partial;
-
-	/* if we stall, we need to clear it before we go on */
-	if (result == -EPIPE) {
-		US_DEBUGP("clearing endpoint halt for pipe 0x%x, "
-				"stalled at %u bytes\n", pipe, partial);
-		if (usb_stor_clear_halt(us, pipe) < 0)
-			return USB_STOR_XFER_ERROR;
-		return USB_STOR_XFER_STALLED;
-	}
-
-	/* NAK - that means we've retried this a few times already */
-	if (result == -ETIMEDOUT) {
-		US_DEBUGP("-- device NAKed\n");
-		return USB_STOR_XFER_ERROR;
-	}
-
-	/* the catch-all error case */
-	if (result) {
-		US_DEBUGP("-- unknown error\n");
-		return USB_STOR_XFER_ERROR;
-	}
-
-	/* did we send all the data? */
-	if (partial == length) {
-		US_DEBUGP("-- transfer complete\n");
-		return USB_STOR_XFER_GOOD;
-	}
-
-	/* no error code, so we must have transferred some data,
-	 * just not all of it */
-	US_DEBUGP("-- transferred only %u bytes\n", partial);
-	return USB_STOR_XFER_SHORT;
+	return interpret_urb_result(us, pipe, length, result, partial);
 }
 
 /*
