USB: reorganize urb->status use in sl811-hcd

This patch (as976) reorganizes the way sl811-hcd sets urb->status.  It
now keeps the information in a local variable until the last moment.

The patch also improves the handling of faults during the status stage
of a control transfer, since it no longer needs to retain the error
information from the earlier stages.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: David Brownell <david-b@pacbell.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Alan Stern 2007-08-24 15:40:47 -04:00 committed by Greg Kroah-Hartman
parent 55d8496837
commit 65e51098d9
1 changed files with 11 additions and 21 deletions

View File

@ -435,11 +435,8 @@ static void finish_request(
if (usb_pipecontrol(urb->pipe)) if (usb_pipecontrol(urb->pipe))
ep->nextpid = USB_PID_SETUP; ep->nextpid = USB_PID_SETUP;
spin_lock(&urb->lock);
urb->status = status;
spin_unlock(&urb->lock);
usb_hcd_unlink_urb_from_ep(sl811_to_hcd(sl811), urb); usb_hcd_unlink_urb_from_ep(sl811_to_hcd(sl811), urb);
urb->status = status;
spin_unlock(&sl811->lock); spin_unlock(&sl811->lock);
usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb); usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb);
spin_lock(&sl811->lock); spin_lock(&sl811->lock);
@ -537,27 +534,20 @@ done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank)
bank + SL11H_XFERCNTREG); bank + SL11H_XFERCNTREG);
if (len > ep->length) { if (len > ep->length) {
len = ep->length; len = ep->length;
urb->status = -EOVERFLOW; urbstat = -EOVERFLOW;
} }
urb->actual_length += len; urb->actual_length += len;
sl811_read_buf(sl811, SL811HS_PACKET_BUF(bank == 0), sl811_read_buf(sl811, SL811HS_PACKET_BUF(bank == 0),
buf, len); buf, len);
usb_dotoggle(udev, ep->epnum, 0); usb_dotoggle(udev, ep->epnum, 0);
if (urb->actual_length == urb->transfer_buffer_length if (urbstat == -EINPROGRESS &&
|| len < ep->maxpacket) (len < ep->maxpacket ||
urbstat = 0; urb->actual_length ==
if (usb_pipecontrol(urb->pipe) && urbstat == 0) { urb->transfer_buffer_length)) {
if (usb_pipecontrol(urb->pipe))
/* NOTE if the status stage STALLs (why?),
* this reports the wrong urb status.
*/
spin_lock(&urb->lock);
if (urb->status == -EINPROGRESS)
urb->status = urbstat;
spin_unlock(&urb->lock);
urb = NULL;
ep->nextpid = USB_PID_ACK; ep->nextpid = USB_PID_ACK;
else
urbstat = 0;
} }
break; break;
case USB_PID_SETUP: case USB_PID_SETUP:
@ -597,7 +587,7 @@ done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank)
bank, status, ep, urbstat); bank, status, ep, urbstat);
} }
if (urb && (urbstat != -EINPROGRESS || urb->unlinked)) if (urbstat != -EINPROGRESS || urb->unlinked)
finish_request(sl811, ep, urb, urbstat); finish_request(sl811, ep, urb, urbstat);
} }