ChangeSet 1.1254.1.5, 2003/05/29 15:19:51-07:00, mdharm-usb@one-eyed-alien.net [PATCH] USB: storage: collapse one-use functions This patch collapses some one-use functions into their callers. It also clones some code for control transfers so we can implement abortable control transfers with timeout. This patch is from Alan Stern. Remove usb_stor_bulk_msg() and usb_stor_interrupt_msg(). Move their functionality into usb_stor_bulk_transfer_buf() and usb_stor_intr_transfer(). Move the functionality of usb_stor_control_msg() into usb_stor_ctrl_transfer(). Remove the unused act_len parameter from usb_stor_intr_transfer(). drivers/usb/storage/transport.c | 172 +++++++++++++++------------------------- drivers/usb/storage/transport.h | 6 - 2 files changed, 68 insertions(+), 110 deletions(-) diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c --- a/drivers/usb/storage/transport.c Fri May 30 11:35:30 2003 +++ b/drivers/usb/storage/transport.c Fri May 30 11:35:30 2003 @@ -192,53 +192,6 @@ return status; } -/* This is our function to emulate usb_bulk_msg() with enough control - * to make aborts/resets/timeouts work - */ -int usb_stor_bulk_msg(struct us_data *us, void *data, unsigned int pipe, - unsigned int len, unsigned int *act_len) -{ - int status; - - /* fill and submit the URB */ - usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, data, len, - usb_stor_blocking_completion, NULL); - status = usb_stor_msg_common(us); - - /* store the actual length of the data transferred */ - *act_len = us->current_urb->actual_length; - return status; -} - -/* This is our function to submit interrupt URBs with enough control - * to make aborts/resets/timeouts work - * - * This routine always uses us->recv_intr_pipe as the pipe and - * us->ep_bInterval as the interrupt interval. - */ -int usb_stor_interrupt_msg(struct us_data *us, void *data, - unsigned int len, unsigned int *act_len) -{ - unsigned int pipe = us->recv_intr_pipe; - unsigned int maxp; - int status; - - /* calculate the max packet size */ - maxp = usb_maxpacket(us->pusb_dev, pipe, usb_pipeout(pipe)); - if (maxp > len) - maxp = len; - - /* fill and submit the URB */ - usb_fill_int_urb(us->current_urb, us->pusb_dev, pipe, data, - maxp, usb_stor_blocking_completion, NULL, - us->ep_bInterval); - status = usb_stor_msg_common(us); - - /* store the actual length of the data transferred */ - *act_len = us->current_urb->actual_length; - return status; -} - /* This is a version of usb_clear_halt() that doesn't read the status from * the device -- this is because some devices crash their internal firmware * when the status is requested after a halt. @@ -282,12 +235,12 @@ * 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 + * non-control 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) { - + unsigned int length, int result, unsigned int partial) +{ US_DEBUGP("Status code %d; transferred %u/%u\n", result, partial, length); switch (result) { @@ -340,77 +293,88 @@ } /* - * Transfer one control message - * - * This function does basically the same thing as usb_stor_control_msg() - * above, except that return codes are USB_STOR_XFER_xxx rather than the - * urb status or transfer length. + * Transfer one control message, without timeouts, but allowing early + * termination. Return codes are USB_STOR_XFER_xxx. */ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, u8 request, u8 requesttype, u16 value, u16 index, - void *data, u16 size) { + 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); - - if (result > 0) { /* Separate out the amount transferred */ - partial = result; - result = 0; - } - return interpret_urb_result(us, pipe, size, result, partial); + US_DEBUGP("%s: rq=%02x rqtype=%02x value=%04x index=%02x len=%u\n", + __FUNCTION__, request, requesttype, + value, index, size); + + /* fill in the devrequest structure */ + us->dr->bRequestType = requesttype; + us->dr->bRequest = request; + us->dr->wValue = cpu_to_le16(value); + us->dr->wIndex = cpu_to_le16(index); + us->dr->wLength = cpu_to_le16(size); + + /* fill and submit the URB */ + usb_fill_control_urb(us->current_urb, us->pusb_dev, pipe, + (unsigned char*) us->dr, data, size, + usb_stor_blocking_completion, NULL); + result = usb_stor_msg_common(us); + + return interpret_urb_result(us, pipe, size, result, + us->current_urb->actual_length); } /* - * Receive one buffer via interrupt transfer + * Receive one interrupt buffer, without timeouts, but allowing early + * termination. Return codes are USB_STOR_XFER_xxx. * - * This function does basically the same thing as usb_stor_interrupt_msg() - * above, except that return codes are USB_STOR_XFER_xxx rather than the - * urb status. + * This routine always uses us->recv_intr_pipe as the pipe and + * us->ep_bInterval as the interrupt interval. */ -int usb_stor_intr_transfer(struct us_data *us, void *buf, - unsigned int length, unsigned int *act_len) +int usb_stor_intr_transfer(struct us_data *us, void *buf, unsigned int length) { int result; - unsigned int partial; + unsigned int pipe = us->recv_intr_pipe; + unsigned int maxp; - /* transfer the data */ - US_DEBUGP("usb_stor_intr_transfer(): xfer %u bytes\n", length); - result = usb_stor_interrupt_msg(us, buf, length, &partial); - if (act_len) - *act_len = partial; + US_DEBUGP("%s: xfer %u bytes\n", __FUNCTION__, length); + + /* calculate the max packet size */ + maxp = usb_maxpacket(us->pusb_dev, pipe, usb_pipeout(pipe)); + if (maxp > length) + maxp = length; - return interpret_urb_result(us, us->recv_intr_pipe, - length, result, partial); + /* fill and submit the URB */ + usb_fill_int_urb(us->current_urb, us->pusb_dev, pipe, buf, + maxp, usb_stor_blocking_completion, NULL, + us->ep_bInterval); + result = usb_stor_msg_common(us); + + return interpret_urb_result(us, pipe, length, result, + us->current_urb->actual_length); } /* - * Transfer one buffer via bulk transfer - * - * This function does basically the same thing as usb_stor_bulk_msg() - * above, except that: - * - * 1. If the bulk pipe stalls during the transfer, the halt is - * automatically cleared; - * 2. Return codes are USB_STOR_XFER_xxx rather than the - * urb status or transfer length. + * Transfer one buffer via bulk pipe, without timeouts, but allowing early + * termination. Return codes are USB_STOR_XFER_xxx. If the bulk pipe + * stalls during the transfer, the halt is automatically cleared. */ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, void *buf, unsigned int length, unsigned int *act_len) { int result; - unsigned int partial; - /* 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("%s: xfer %u bytes\n", __FUNCTION__, length); + + /* fill and submit the URB */ + usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, buf, length, + usb_stor_blocking_completion, NULL); + result = usb_stor_msg_common(us); + + /* store the actual length of the data transferred */ if (act_len) - *act_len = partial; - return interpret_urb_result(us, pipe, length, result, partial); + *act_len = us->current_urb->actual_length; + return interpret_urb_result(us, pipe, length, result, + us->current_urb->actual_length); } /* @@ -424,15 +388,14 @@ unsigned int *act_len) { int result; - unsigned int partial; /* don't submit s-g requests during abort/disconnect processing */ if (us->flags & DONT_SUBMIT) return USB_STOR_XFER_ERROR; /* initialize the scatter-gather request block */ - US_DEBUGP("usb_stor_bulk_transfer_sglist(): xfer %u bytes, " - "%d entries\n", length, num_sg); + US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__, + length, num_sg); result = usb_sg_init(us->current_sg, us->pusb_dev, pipe, 0, sg, num_sg, length, SLAB_NOIO); if (result) { @@ -459,10 +422,10 @@ clear_bit(US_FLIDX_SG_ACTIVE, &us->flags); result = us->current_sg->status; - partial = us->current_sg->bytes; if (act_len) - *act_len = partial; - return interpret_urb_result(us, pipe, length, result, partial); + *act_len = us->current_sg->bytes; + return interpret_urb_result(us, pipe, length, result, + us->current_sg->bytes); } /* @@ -775,8 +738,7 @@ } /* STATUS STAGE */ - result = usb_stor_intr_transfer(us, us->irqdata, - sizeof(us->irqdata), NULL); + result = usb_stor_intr_transfer(us, us->irqdata, sizeof(us->irqdata)); US_DEBUGP("Got interrupt data (0x%x, 0x%x)\n", us->irqdata[0], us->irqdata[1]); if (result != USB_STOR_XFER_GOOD) diff -Nru a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h --- a/drivers/usb/storage/transport.h Fri May 30 11:35:30 2003 +++ b/drivers/usb/storage/transport.h Fri May 30 11:35:30 2003 @@ -158,20 +158,16 @@ extern void usb_stor_invoke_transport(Scsi_Cmnd*, struct us_data*); extern void usb_stor_stop_transport(struct us_data*); -extern int usb_stor_bulk_msg(struct us_data *us, void *data, - unsigned int pipe, unsigned int len, unsigned int *act_len); extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe, u8 request, u8 requesttype, u16 value, u16 index, void *data, u16 size); -extern int usb_stor_interrupt_msg(struct us_data *us, void *data, - unsigned int len, unsigned int *act_len); extern int usb_stor_clear_halt(struct us_data*, unsigned int pipe); extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, u8 request, u8 requesttype, u16 value, u16 index, void *data, u16 size); extern int usb_stor_intr_transfer(struct us_data *us, void *buf, - unsigned int length, unsigned int *act_len); + unsigned int length); extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, void *buf, unsigned int length, unsigned int *act_len); extern int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,