Commit 77212fff authored by Matthew Dharm's avatar Matthew Dharm Committed by Greg Kroah-Hartman

[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
parent c0f800ef
...@@ -479,7 +479,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, ...@@ -479,7 +479,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
usb_stor_blocking_completion, NULL); usb_stor_blocking_completion, NULL);
status = usb_stor_msg_common(us); 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) if (status >= 0)
status = us->current_urb->actual_length; status = us->current_urb->actual_length;
return status; return status;
...@@ -543,6 +543,65 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe) ...@@ -543,6 +543,65 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
return 0; 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 * Transfer one control message
* *
...@@ -554,34 +613,19 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, ...@@ -554,34 +613,19 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
u8 request, u8 requesttype, u16 value, u16 index, u8 request, u8 requesttype, u16 value, u16 index,
void *data, u16 size) { void *data, u16 size) {
int result; int result;
unsigned int partial = 0;
US_DEBUGP("usb_stor_ctrl_transfer(): rq=%02x rqtype=%02x " US_DEBUGP("usb_stor_ctrl_transfer(): rq=%02x rqtype=%02x "
"value=%04x index=%02x len=%u\n", "value=%04x index=%02x len=%u\n",
request, requesttype, value, index, size); request, requesttype, value, index, size);
result = usb_stor_control_msg(us, pipe, request, requesttype, result = usb_stor_control_msg(us, pipe, request, requesttype,
value, index, data, size); value, index, data, size);
US_DEBUGP("usb_stor_control_msg returned %d\n", result);
/* a stall indicates a protocol error */ if (result > 0) { /* Separate out the amount transferred */
if (result == -EPIPE) { partial = result;
US_DEBUGP("-- stall on control pipe\n"); result = 0;
return USB_STOR_XFER_ERROR;
} }
return interpret_urb_result(us, pipe, size, result, partial);
/* 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;
} }
/* /*
...@@ -604,42 +648,9 @@ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, ...@@ -604,42 +648,9 @@ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
/* transfer the data */ /* transfer the data */
US_DEBUGP("usb_stor_bulk_transfer_buf(): xfer %u bytes\n", length); US_DEBUGP("usb_stor_bulk_transfer_buf(): xfer %u bytes\n", length);
result = usb_stor_bulk_msg(us, buf, pipe, length, &partial); 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) if (act_len)
*act_len = partial; *act_len = partial;
return interpret_urb_result(us, pipe, length, result, 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;
} }
/* /*
...@@ -653,7 +664,7 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, ...@@ -653,7 +664,7 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
unsigned int *act_len) unsigned int *act_len)
{ {
int result; int result;
int partial; unsigned int partial;
/* initialize the scatter-gather request block */ /* initialize the scatter-gather request block */
US_DEBUGP("usb_stor_bulk_transfer_sglist(): xfer %u bytes, " US_DEBUGP("usb_stor_bulk_transfer_sglist(): xfer %u bytes, "
...@@ -685,42 +696,9 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, ...@@ -685,42 +696,9 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
result = us->current_sg->status; result = us->current_sg->status;
partial = us->current_sg->bytes; partial = us->current_sg->bytes;
US_DEBUGP("usb_sg_wait() returned %d xferred %u/%u\n",
result, partial, length);
if (act_len) if (act_len)
*act_len = partial; *act_len = partial;
return interpret_urb_result(us, pipe, length, result, 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;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment