svn commit: r190721 - head/sys/dev/usb/controller
Andrew Thompson
thompsa at FreeBSD.org
Sun Apr 5 11:18:22 PDT 2009
Author: thompsa
Date: Sun Apr 5 18:18:16 2009
New Revision: 190721
URL: http://svn.freebsd.org/changeset/base/190721
Log:
MFp4 //depot/projects/usb at 159673
Fix a corner case around stalling SETUP packets in device side mode.
Submitted by: Hans Petter Selasky
Modified:
head/sys/dev/usb/controller/at91dci.c
head/sys/dev/usb/controller/atmegadci.c
head/sys/dev/usb/controller/musb_otg.c
head/sys/dev/usb/controller/uss820dci.c
Modified: head/sys/dev/usb/controller/at91dci.c
==============================================================================
--- head/sys/dev/usb/controller/at91dci.c Sun Apr 5 18:18:07 2009 (r190720)
+++ head/sys/dev/usb/controller/at91dci.c Sun Apr 5 18:18:16 2009 (r190721)
@@ -305,14 +305,11 @@ at91dci_setup_rx(struct at91dci_td *td)
AT91_UDP_CSR_TXCOMP);
if (!(csr & AT91_UDP_CSR_RXSETUP)) {
- /* abort any ongoing transfer */
- if (!td->did_stall) {
- DPRINTFN(5, "stalling\n");
- temp |= AT91_UDP_CSR_FORCESTALL;
- td->did_stall = 1;
- }
goto not_complete;
}
+ /* clear did stall */
+ td->did_stall = 0;
+
/* get the packet byte count */
count = (csr & AT91_UDP_CSR_RXBYTECNT) >> 16;
@@ -362,6 +359,13 @@ at91dci_setup_rx(struct at91dci_td *td)
return (0); /* complete */
not_complete:
+ /* abort any ongoing transfer */
+ if (!td->did_stall) {
+ DPRINTFN(5, "stalling\n");
+ temp |= AT91_UDP_CSR_FORCESTALL;
+ td->did_stall = 1;
+ }
+
/* clear interrupts, if any */
if (temp) {
DPRINTFN(5, "clearing 0x%08x\n", temp);
Modified: head/sys/dev/usb/controller/atmegadci.c
==============================================================================
--- head/sys/dev/usb/controller/atmegadci.c Sun Apr 5 18:18:07 2009 (r190720)
+++ head/sys/dev/usb/controller/atmegadci.c Sun Apr 5 18:18:16 2009 (r190721)
@@ -250,16 +250,10 @@ atmegadci_setup_rx(struct atmegadci_td *
DPRINTFN(5, "UEINTX=0x%02x\n", temp);
if (!(temp & ATMEGA_UEINTX_RXSTPI)) {
- /* abort any ongoing transfer */
- if (!td->did_stall) {
- DPRINTFN(5, "stalling\n");
- ATMEGA_WRITE_1(sc, ATMEGA_UECONX,
- ATMEGA_UECONX_EPEN |
- ATMEGA_UECONX_STALLRQ);
- td->did_stall = 1;
- }
goto not_complete;
}
+ /* clear did stall */
+ td->did_stall = 0;
/* get the packet byte count */
count =
(ATMEGA_READ_1(sc, ATMEGA_UEBCHX) << 8) |
@@ -304,6 +298,15 @@ atmegadci_setup_rx(struct atmegadci_td *
return (0); /* complete */
not_complete:
+ /* abort any ongoing transfer */
+ if (!td->did_stall) {
+ DPRINTFN(5, "stalling\n");
+ ATMEGA_WRITE_1(sc, ATMEGA_UECONX,
+ ATMEGA_UECONX_EPEN |
+ ATMEGA_UECONX_STALLRQ);
+ td->did_stall = 1;
+ }
+
/* we only want to know if there is a SETUP packet */
ATMEGA_WRITE_1(sc, ATMEGA_UEIENX, ATMEGA_UEIENX_RXSTPE);
return (1); /* not complete */
Modified: head/sys/dev/usb/controller/musb_otg.c
==============================================================================
--- head/sys/dev/usb/controller/musb_otg.c Sun Apr 5 18:18:07 2009 (r190720)
+++ head/sys/dev/usb/controller/musb_otg.c Sun Apr 5 18:18:16 2009 (r190721)
@@ -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 */
}
Modified: head/sys/dev/usb/controller/uss820dci.c
==============================================================================
--- head/sys/dev/usb/controller/uss820dci.c Sun Apr 5 18:18:07 2009 (r190720)
+++ head/sys/dev/usb/controller/uss820dci.c Sun Apr 5 18:18:16 2009 (r190721)
@@ -248,19 +248,11 @@ uss820dci_setup_rx(struct uss820dci_td *
DPRINTFN(5, "rx_stat=0x%02x rem=%u\n", rx_stat, td->remainder);
if (!(rx_stat & USS820_RXSTAT_RXSETUP)) {
- /* abort any ongoing transfer */
- if (!td->did_stall) {
- DPRINTFN(5, "stalling\n");
-
- /* set stall */
-
- uss820dci_update_shared_1(sc, USS820_EPCON, 0xFF,
- (USS820_EPCON_TXSTL | USS820_EPCON_RXSTL));
-
- td->did_stall = 1;
- }
goto not_complete;
}
+ /* clear did stall */
+ td->did_stall = 0;
+
/* clear stall and all I/O */
uss820dci_update_shared_1(sc, USS820_EPCON,
0xFF ^ (USS820_EPCON_TXSTL |
@@ -332,6 +324,18 @@ uss820dci_setup_rx(struct uss820dci_td *
return (0); /* complete */
not_complete:
+ /* abort any ongoing transfer */
+ if (!td->did_stall) {
+ DPRINTFN(5, "stalling\n");
+
+ /* set stall */
+
+ uss820dci_update_shared_1(sc, USS820_EPCON, 0xFF,
+ (USS820_EPCON_TXSTL | USS820_EPCON_RXSTL));
+
+ td->did_stall = 1;
+ }
+
/* clear end overwrite flag, if any */
if (rx_stat & USS820_RXSTAT_RXSETUP) {
uss820dci_update_shared_1(sc, USS820_RXSTAT,
More information about the svn-src-all
mailing list