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:
parent
55d8496837
commit
65e51098d9
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue