summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/controller/musb_otg.c
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2009-04-05 18:18:16 +0000
committerthompsa <thompsa@FreeBSD.org>2009-04-05 18:18:16 +0000
commitda86d5814edc3c040ec8b32c0433bc58f79a0d02 (patch)
tree67b47e6b44aa7e337d832537ee1f429eb3c13517 /sys/dev/usb/controller/musb_otg.c
parent782adcb07d18f6d3dd00a93b67897ba313ec04c8 (diff)
downloadFreeBSD-src-da86d5814edc3c040ec8b32c0433bc58f79a0d02.zip
FreeBSD-src-da86d5814edc3c040ec8b32c0433bc58f79a0d02.tar.gz
MFp4 //depot/projects/usb@159673
Fix a corner case around stalling SETUP packets in device side mode. Submitted by: Hans Petter Selasky
Diffstat (limited to 'sys/dev/usb/controller/musb_otg.c')
-rw-r--r--sys/dev/usb/controller/musb_otg.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c
index 6e41bc6..ac63aab 100644
--- a/sys/dev/usb/controller/musb_otg.c
+++ b/sys/dev/usb/controller/musb_otg.c
@@ -255,6 +255,8 @@ musbotg_setup_rx(struct musbotg_td *td)
* callback, hence the status stage is not complete.
*/
if (csr & MUSB2_MASK_CSR0L_DATAEND) {
+ /* do not stall at this point */
+ td->did_stall = 1;
/* wait for interrupt */
goto not_complete;
}
@@ -276,18 +278,13 @@ musbotg_setup_rx(struct musbotg_td *td)
sc->sc_ep0_busy = 0;
}
if (sc->sc_ep0_busy) {
- /* abort any ongoing transfer */
- if (!td->did_stall) {
- DPRINTFN(4, "stalling\n");
- MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
- MUSB2_MASK_CSR0L_SENDSTALL);
- td->did_stall = 1;
- }
goto not_complete;
}
if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
goto not_complete;
}
+ /* clear did stall flag */
+ td->did_stall = 0;
/* get the packet byte count */
count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
@@ -328,6 +325,13 @@ musbotg_setup_rx(struct musbotg_td *td)
return (0); /* complete */
not_complete:
+ /* abort any ongoing transfer */
+ if (!td->did_stall) {
+ DPRINTFN(4, "stalling\n");
+ MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
+ MUSB2_MASK_CSR0L_SENDSTALL);
+ td->did_stall = 1;
+ }
return (1); /* not complete */
}
OpenPOWER on IntegriCloud