summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/uhci.c')
-rw-r--r--sys/dev/usb/uhci.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index 1dcd8691c544..5d68f1891ea6 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: uhci.c,v 1.153 2002/02/11 11:40:33 augustss Exp $ */
+/* $NetBSD: uhci.c,v 1.154 2002/02/27 12:12:45 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -1886,9 +1886,14 @@ uhci_device_bulk_abort(usbd_xfer_handle xfer)
}
/*
- * XXX This way of aborting is neither safe, nor good.
- * But it will have to do until I figure out what to do.
- * I apologize for the delay().
+ * Abort a device request.
+ * If this routine is called at splusb() it guarantees that the request
+ * will be removed from the hardware scheduling and that the callback
+ * for it will be called with USBD_CANCELLED status.
+ * It's impossible to guarantee that the requested transfer will not
+ * have happened since the hardware runs concurrently.
+ * If the transaction has already happened we rely on the ordinary
+ * interrupt processing to process it.
*/
void
uhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
@@ -1914,8 +1919,6 @@ uhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
if (xfer->device->bus->intr_context || !curproc)
panic("ohci_abort_xfer: not in process context\n");
- s = splusb();
-
/*
* Step 1: Make interrupt routine and hardware ignore xfer.
*/
@@ -1932,10 +1935,11 @@ uhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
* use of the xfer. Also make sure the soft interrupt routine
* has run.
*/
- usb_delay_ms(upipe->pipe.device->bus, 20); /* Hardware finishes in 1ms */
+ usb_delay_ms(upipe->pipe.device->bus, 2); /* Hardware finishes in 1ms */
s = splusb();
sc->sc_softwake = 1;
usb_schedsoftintr(&sc->sc_bus);
+ DPRINTFN(1,("uhci_abort_xfer: tsleep\n"));
tsleep(&sc->sc_softwake, PZERO, "uhciab", 0);
splx(s);
@@ -1944,6 +1948,7 @@ uhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
*/
xfer->hcpriv = ii;
+ DPRINTFN(1,("uhci_abort_xfer: callback\n"));
s = splusb();
#ifdef DIAGNOSTIC
ii->isdone = 1;
@@ -2111,7 +2116,7 @@ uhci_device_intr_abort(usbd_xfer_handle xfer)
DPRINTFN(1,("uhci_device_intr_abort: xfer=%p\n", xfer));
if (xfer->pipe->intrxfer == xfer) {
DPRINTFN(1,("uhci_device_intr_abort: remove\n"));
- xfer->pipe->intrxfer = 0;
+ xfer->pipe->intrxfer = NULL;
}
uhci_abort_xfer(xfer, USBD_CANCELLED);
}