USB: add reset endpoint operations

Wireless USB endpoint state has a sequence number and a current
window and not just a single toggle bit.  So allow HCDs to provide a
endpoint_reset method and call this or clear the software toggles as
required (after a clear halt, set configuration etc.).

usb_settoggle() and friends are then HCD internal and are moved into
core/hcd.h and all device drivers call usb_reset_endpoint() instead.

If the device endpoint state has been reset (with a clear halt) but
the host endpoint state has not then subsequent data transfers will
not complete. The device will only work again after it is reset or
disconnected.

Signed-off-by: David Vrabel <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
This commit is contained in:
David Vrabel 2009-04-08 17:36:28 +00:00 • committed by Greg Kroah-Hartman
commit 3444b26afa
10 changed files with 91 additions and 54 deletions

View file

@ -1025,6 +1025,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
{
struct urb *urb = &sc->work_urb;
struct bulk_cs_wrap *bcs;
int endp;
int len;
int rc;
@ -1033,6 +1034,10 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
return;
}
endp = usb_pipeendpoint(sc->last_pipe);
if (usb_pipein(sc->last_pipe))
endp |= USB_DIR_IN;
if (cmd->state == UB_CMDST_CLEAR) {
if (urb->status == -EPIPE) {
/*
@ -1048,9 +1053,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
* We ignore the result for the halt clear.
*/
/* reset the endpoint toggle */
usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
usb_pipeout(sc->last_pipe), 0);
usb_reset_endpoint(sc->dev, endp);
ub_state_sense(sc, cmd);
@ -1065,9 +1068,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
* We ignore the result for the halt clear.
*/
/* reset the endpoint toggle */
usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
usb_pipeout(sc->last_pipe), 0);
usb_reset_endpoint(sc->dev, endp);
ub_state_stat(sc, cmd);
@ -1082,9 +1083,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
* We ignore the result for the halt clear.
*/
/* reset the endpoint toggle */
usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
usb_pipeout(sc->last_pipe), 0);
usb_reset_endpoint(sc->dev, endp);
ub_state_stat_counted(sc, cmd);
@ -2119,8 +2118,7 @@ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe)
del_timer_sync(&timer);
usb_kill_urb(&sc->work_urb);
/* reset the endpoint toggle */
usb_settoggle(sc->dev, endp, usb_pipeout(sc->last_pipe), 0);
usb_reset_endpoint(sc->dev, endp);
return 0;
}