Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb Disable NAK timeout on bulk transfers, I couldn'...
details: https://anonhg.NetBSD.org/src/rev/d82f13f950fe
branches: trunk
changeset: 330744:d82f13f950fe
user: bouyer <bouyer%NetBSD.org@localhost>
date: Sat Jul 19 22:08:54 2014 +0000
description:
Disable NAK timeout on bulk transfers, I couldn't find a way to clear
the NAK bit not the FIFO.
Make xfer aborts more robust to races, by setting proper status and flags
in xfer.
diffstat:
sys/dev/usb/motg.c | 264 ++++++++++++++++++++++++++++++----------------------
1 files changed, 153 insertions(+), 111 deletions(-)
diffs (truncated from 608 to 300 lines):
diff -r 86eb3842af2d -r d82f13f950fe sys/dev/usb/motg.c
--- a/sys/dev/usb/motg.c Sat Jul 19 21:22:58 2014 +0000
+++ b/sys/dev/usb/motg.c Sat Jul 19 22:08:54 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: motg.c,v 1.2 2014/07/17 19:58:18 bouyer Exp $ */
+/* $NetBSD: motg.c,v 1.3 2014/07/19 22:08:54 bouyer Exp $ */
/*
* Copyright (c) 1998, 2004, 2011, 2012, 2014 The NetBSD Foundation, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.2 2014/07/17 19:58:18 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.3 2014/07/19 22:08:54 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -90,8 +90,8 @@
#define POLL_TO_HIGH 10 /* 100 microframes, about 0.12s */
/* bulk NAK timeouts */
-#define NAK_TO_BULK 255 /* 255 frames, about 0.25s */
-#define NAK_TO_BULK_HIGH 13 /* 8k microframes, about 1s */
+#define NAK_TO_BULK 0 /* disabled */
+#define NAK_TO_BULK_HIGH 0
static void motg_hub_change(struct motg_softc *);
static usbd_status motg_root_ctrl_transfer(usbd_xfer_handle);
@@ -140,7 +140,8 @@
static void motg_device_data_write(usbd_xfer_handle);
static void motg_waitintr(struct motg_softc *, usbd_xfer_handle);
-static void motg_device_clear_toggle(usbd_pipe_handle pipe);
+static void motg_device_clear_toggle(usbd_pipe_handle);
+static void motg_device_xfer_abort(usbd_xfer_handle);
#define MOTG_INTR_ENDPT 1
#define UBARR(sc) bus_space_barrier((sc)->sc_iot, (sc)->sc_ioh, 0, (sc)->sc_size, \
@@ -352,13 +353,17 @@
if (fiforx_size && (i <= nrx)) {
fiforx_size = fifo_size;
if (fifo_size > 7) {
+#if 0
UWRITE1(sc, MUSB2_REG_RXFIFOSZ,
MUSB2_VAL_FIFOSZ(fifo_size) |
MUSB2_MASK_FIFODB);
+#else
+ UWRITE1(sc, MUSB2_REG_RXFIFOSZ,
+ MUSB2_VAL_FIFOSZ(fifo_size));
+#endif
} else {
UWRITE1(sc, MUSB2_REG_RXFIFOSZ,
- MUSB2_VAL_FIFOSZ(fifo_size) |
- MUSB2_MASK_FIFODB);
+ MUSB2_VAL_FIFOSZ(fifo_size));
}
UWRITE2(sc, MUSB2_REG_RXFIFOADD,
offset >> 3);
@@ -367,9 +372,14 @@
if (fifotx_size && (i <= ntx)) {
fifotx_size = fifo_size;
if (fifo_size > 7) {
+#if 0
UWRITE1(sc, MUSB2_REG_TXFIFOSZ,
MUSB2_VAL_FIFOSZ(fifo_size) |
MUSB2_MASK_FIFODB);
+#else
+ UWRITE1(sc, MUSB2_REG_TXFIFOSZ,
+ MUSB2_VAL_FIFOSZ(fifo_size));
+#endif
} else {
UWRITE1(sc, MUSB2_REG_TXFIFOSZ,
MUSB2_VAL_FIFOSZ(fifo_size));
@@ -639,7 +649,6 @@
if (tx_status & (0x01 << i))
motg_device_intr_tx(sc, i);
}
-
return;
}
@@ -1075,12 +1084,6 @@
change |= UPS_C_PORT_ENABLED;
sc->sc_port_enabled_changed = 0;
}
-#if 0 /*XXX*/
- if (x & MOTG_PORTSC_OCI)
- status |= UPS_OVERCURRENT_INDICATOR;
- if (x & MOTG_PORTSC_OCIC)
- change |= UPS_C_OVERCURRENT_INDICATOR;
-#endif
if (sc->sc_port_suspended)
status |= UPS_SUSPEND;
if (sc->sc_high_speed)
@@ -1448,6 +1451,7 @@
/* Insert last in queue. */
mutex_enter(&sc->sc_lock);
err = usb_insert_transfer(xfer);
+ xfer->status = USBD_NOT_STARTED;
mutex_exit(&sc->sc_lock);
if (err)
return (err);
@@ -1478,7 +1482,7 @@
motg_device_ctrl_start1(struct motg_softc *sc)
{
struct motg_hw_ep *ep = &sc->sc_in_ep[0];
- usbd_xfer_handle xfer;
+ usbd_xfer_handle xfer = NULL;
struct motg_pipe *otgpipe;
usbd_status err = 0;
@@ -1496,6 +1500,10 @@
/* locate the first pipe with work to do */
SIMPLEQ_FOREACH(otgpipe, &ep->ep_pipes, ep_pipe_list) {
xfer = SIMPLEQ_FIRST(&otgpipe->pipe.queue);
+ DPRINTFN(MD_CTRL,
+ ("motg_device_ctrl_start1 pipe %p xfer %p status %d\n",
+ otgpipe, xfer, (xfer != NULL) ? xfer->status : 0));
+
if (xfer != NULL) {
/* move this pipe to the end of the list */
SIMPLEQ_REMOVE(&ep->ep_pipes, otgpipe,
@@ -1509,7 +1517,7 @@
err = USBD_NOT_STARTED;
goto end;
}
- KASSERT(xfer != NULL);
+ xfer->status = USBD_IN_PROGRESS;
KASSERT(otgpipe == (struct motg_pipe *)xfer->pipe);
KASSERT(otgpipe->hw_ep == ep);
#ifdef DIAGNOSTIC
@@ -1580,6 +1588,7 @@
int datalen, max_datalen;
char *data;
bool got_short;
+ usbd_status new_status = USBD_IN_PROGRESS;
KASSERT(mutex_owned(&sc->sc_lock));
@@ -1594,8 +1603,8 @@
/* read out FIFO status */
csr = UREAD1(sc, MUSB2_REG_TXCSRL);
DPRINTFN(MD_CTRL,
- ("motg_device_ctrl_intr_rx phase %d csr 0x%x\n",
- ep->phase, csr));
+ ("motg_device_ctrl_intr_rx phase %d csr 0x%x xfer %p status %d\n",
+ ep->phase, csr, xfer, (xfer != NULL) ? xfer->status : 0));
if (csr & MUSB2_MASK_CSR0L_NAKTIMO) {
csr &= ~MUSB2_MASK_CSR0L_REQPKT;
@@ -1603,17 +1612,14 @@
csr &= ~MUSB2_MASK_CSR0L_NAKTIMO;
UWRITE1(sc, MUSB2_REG_TXCSRL, csr);
- if (xfer)
- xfer->status = USBD_TIMEOUT; /* XXX */
+ new_status = USBD_TIMEOUT; /* XXX */
goto complete;
}
if (csr & (MUSB2_MASK_CSR0L_RXSTALL | MUSB2_MASK_CSR0L_ERROR)) {
- if (xfer) {
- if (csr & MUSB2_MASK_CSR0L_RXSTALL)
- xfer->status = USBD_STALLED;
- else
- xfer->status = USBD_IOERROR;
- }
+ if (csr & MUSB2_MASK_CSR0L_RXSTALL)
+ new_status = USBD_STALLED;
+ else
+ new_status = USBD_IOERROR;
/* clear status */
UWRITE1(sc, MUSB2_REG_TXCSRL, 0);
goto complete;
@@ -1621,11 +1627,11 @@
if ((csr & MUSB2_MASK_CSR0L_RXPKTRDY) == 0)
return; /* no data yet */
- if (xfer == NULL)
+ if (xfer == NULL || xfer->status != USBD_IN_PROGRESS)
goto complete;
if (ep->phase == STATUS_IN) {
- xfer->status = USBD_NORMAL_COMPLETION;
+ new_status = USBD_NORMAL_COMPLETION;
UWRITE1(sc, MUSB2_REG_TXCSRL, 0);
goto complete;
}
@@ -1637,7 +1643,7 @@
max_datalen = min(UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize),
ep->datalen);
if (datalen > max_datalen) {
- xfer->status = USBD_IOERROR;
+ new_status = USBD_IOERROR;
UWRITE1(sc, MUSB2_REG_TXCSRL, 0);
goto complete;
}
@@ -1687,8 +1693,11 @@
complete:
ep->phase = IDLE;
ep->xfer = NULL;
- if (xfer)
+ if (xfer && xfer->status == USBD_IN_PROGRESS) {
+ KASSERT(new_status != USBD_IN_PROGRESS);
+ xfer->status = new_status;
usb_transfer_complete(xfer);
+ }
motg_device_ctrl_start1(sc);
}
@@ -1700,6 +1709,7 @@
uint8_t csr;
int datalen;
char *data;
+ usbd_status new_status = USBD_IN_PROGRESS;
KASSERT(mutex_owned(&sc->sc_lock));
if (ep->phase == DATA_IN || ep->phase == STATUS_IN) {
@@ -1717,20 +1727,18 @@
csr = UREAD1(sc, MUSB2_REG_TXCSRL);
DPRINTFN(MD_CTRL,
- ("motg_device_ctrl_intr_tx phase %d csr 0x%x\n",
- ep->phase, csr));
+ ("motg_device_ctrl_intr_tx phase %d csr 0x%x xfer %p status %d\n",
+ ep->phase, csr, xfer, (xfer != NULL) ? xfer->status : 0));
if (csr & MUSB2_MASK_CSR0L_RXSTALL) {
/* command not accepted */
- if (xfer)
- xfer->status = USBD_STALLED;
+ new_status = USBD_STALLED;
/* clear status */
UWRITE1(sc, MUSB2_REG_TXCSRL, 0);
goto complete;
}
if (csr & MUSB2_MASK_CSR0L_NAKTIMO) {
- if (xfer)
- xfer->status = USBD_TIMEOUT; /* XXX */
+ new_status = USBD_TIMEOUT; /* XXX */
/* flush fifo */
while (csr & MUSB2_MASK_CSR0L_TXFIFONEMPTY) {
UWRITE1(sc, MUSB2_REG_TXCSRH,
@@ -1743,8 +1751,7 @@
goto complete;
}
if (csr & MUSB2_MASK_CSR0L_ERROR) {
- if (xfer)
- xfer->status = USBD_IOERROR;
+ new_status = USBD_IOERROR;
/* clear status */
UWRITE1(sc, MUSB2_REG_TXCSRL, 0);
goto complete;
@@ -1761,8 +1768,9 @@
* declare transfer complete
*/
DPRINTFN(MD_CTRL,
- ("motg_device_ctrl_intr_tx %p complete\n", xfer));
- xfer->status = USBD_NORMAL_COMPLETION;
+ ("motg_device_ctrl_intr_tx %p status %d complete\n",
+ xfer, xfer->status));
+ new_status = USBD_NORMAL_COMPLETION;
goto complete;
}
if (ep->datalen == 0) {
@@ -1826,8 +1834,11 @@
complete:
ep->phase = IDLE;
ep->xfer = NULL;
- if (xfer)
+ if (xfer && xfer->status == USBD_IN_PROGRESS) {
+ KASSERT(new_status != USBD_IN_PROGRESS);
+ xfer->status = new_status;
usb_transfer_complete(xfer);
+ }
motg_device_ctrl_start1(sc);
}
@@ -1835,17 +1846,8 @@
void
motg_device_ctrl_abort(usbd_xfer_handle xfer)
{
-#ifdef DIAGNOSTIC
- struct motg_softc *sc = xfer->pipe->device->bus->hci_private;
-#endif
- struct motg_pipe *otgpipe = (struct motg_pipe *)xfer->pipe;
- KASSERT(mutex_owned(&sc->sc_lock));
-
DPRINTFN(MD_CTRL, ("motg_device_ctrl_abort:\n"));
- if (otgpipe->hw_ep->xfer == xfer)
- otgpipe->hw_ep->xfer = NULL;
- xfer->status = USBD_CANCELLED;
- usb_transfer_complete(xfer);
+ motg_device_xfer_abort(xfer);
}
/* Close a device control pipe */
@@ -1890,7 +1892,10 @@
/* Insert last in queue. */
Home |
Main Index |
Thread Index |
Old Index