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); } /*