Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb Implement bulk transfers.
details: https://anonhg.NetBSD.org/src/rev/a3150bb899d5
branches: trunk
changeset: 517918:a3150bb899d5
user: augustss <augustss%NetBSD.org@localhost>
date: Wed Nov 21 13:04:50 2001 +0000
description:
Implement bulk transfers.
diffstat:
sys/dev/usb/ehci.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 132 insertions(+), 13 deletions(-)
diffs (186 lines):
diff -r 5ae8cd8115ab -r a3150bb899d5 sys/dev/usb/ehci.c
--- a/sys/dev/usb/ehci.c Wed Nov 21 12:28:23 2001 +0000
+++ b/sys/dev/usb/ehci.c Wed Nov 21 13:04:50 2001 +0000
@@ -1,7 +1,4 @@
-/* TODO
-Add intrinfo.
-*/
-/* $NetBSD: ehci.c,v 1.18 2001/11/21 12:28:23 augustss Exp $ */
+/* $NetBSD: ehci.c,v 1.19 2001/11/21 13:04:50 augustss Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -50,7 +47,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.18 2001/11/21 12:28:23 augustss Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.19 2001/11/21 13:04:50 augustss Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -97,14 +94,13 @@
struct {
usb_dma_t reqdma;
u_int length;
- ehci_soft_qtd_t *setup, *data, *stat;
+ /*ehci_soft_qtd_t *setup, *data, *stat;*/
} ctl;
/* Interrupt pipe */
/* XXX */
/* Bulk pipe */
struct {
u_int length;
- int isread;
} bulk;
/* Iso pipe */
/* XXX */
@@ -2290,7 +2286,7 @@
ehci_del_intr_list(ex); /* remove from active list */
if (epipe->u.ctl.length != 0)
- ehci_free_std_chain(sc, ex->sqtdstart, ex->sqtdend);
+ ehci_free_std_chain(sc, ex->sqtdstart, NULL);
DPRINTFN(5, ("uhci_ctrl_done: length=%d\n", xfer->actlen));
}
@@ -2472,11 +2468,134 @@
/************************/
-Static usbd_status ehci_device_bulk_transfer(usbd_xfer_handle xfer) { return USBD_IOERROR; }
-Static usbd_status ehci_device_bulk_start(usbd_xfer_handle xfer) { return USBD_IOERROR; }
-Static void ehci_device_bulk_abort(usbd_xfer_handle xfer) { }
-Static void ehci_device_bulk_close(usbd_pipe_handle pipe) { }
-Static void ehci_device_bulk_done(usbd_xfer_handle xfer) { }
+Static usbd_status
+ehci_device_bulk_transfer(usbd_xfer_handle xfer)
+{
+ usbd_status err;
+
+ /* Insert last in queue. */
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return (err);
+
+ /* Pipe isn't running, start first */
+ return (ehci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
+}
+
+usbd_status
+ehci_device_bulk_start(usbd_xfer_handle xfer)
+{
+#define exfer EXFER(xfer)
+ struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
+ usbd_device_handle dev = epipe->pipe.device;
+ ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
+ ehci_soft_qtd_t *data, *dataend;
+ ehci_soft_qh_t *sqh;
+ usbd_status err;
+ int len, isread, endpt;
+ int s;
+
+ DPRINTFN(3, ("ehci_device_bulk_transfer: xfer=%p len=%d flags=%d\n",
+ xfer, xfer->length, xfer->flags));
+
+ if (sc->sc_dying)
+ return (USBD_IOERROR);
+
+#ifdef DIAGNOSTIC
+ if (xfer->rqflags & URQ_REQUEST)
+ panic("ehci_device_bulk_transfer: a request\n");
+#endif
+
+ len = xfer->length;
+ endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
+ isread = UE_GET_DIR(endpt) == UE_DIR_IN;
+ sqh = epipe->sqh;
+
+ epipe->u.bulk.length = len;
+
+ err = ehci_alloc_std_chain(epipe, sc, len, isread, xfer, &data,
+ &dataend);
+ if (err)
+ return (err);
+
+#ifdef EHCI_DEBUG
+ if (ehcidebug > 8) {
+ DPRINTF(("ehci_device_bulk_transfer: data(1)\n"));
+ ehci_dump_sqtds(data);
+ }
+#endif
+
+ /* Set up interrupt info. */
+ exfer->sqtdstart = data;
+ exfer->sqtdend = dataend;
+#ifdef DIAGNOSTIC
+ if (!exfer->isdone) {
+ printf("ehci_device_bulk_transfer: not done, ex=%p\n", exfer);
+ }
+ exfer->isdone = 0;
+#endif
+
+ s = splusb();
+ sqh->qh.qh_curqtd = 0;
+ sqh->qh.qh_qtd.qtd_next = htole32(data->physaddr);
+ sqh->sqtd = data;
+ if (xfer->timeout && !sc->sc_bus.use_polling) {
+ usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
+ ehci_timeout, xfer);
+ }
+ ehci_add_intr_list(sc, exfer);
+ xfer->status = USBD_IN_PROGRESS;
+ splx(s);
+
+#ifdef EHCI_DEBUG
+ if (ehcidebug > 10) {
+ DPRINTF(("ehci_device_bulk_transfer: data(2)\n"));
+ ehci_dump_sqtds(data);
+ }
+#endif
+
+ if (sc->sc_bus.use_polling)
+ ehci_waitintr(sc, xfer);
+
+ return (USBD_IN_PROGRESS);
+#undef exfer
+}
+
+Static void
+ehci_device_bulk_abort(usbd_xfer_handle xfer)
+{
+ DPRINTF(("ehci_device_bulk_abort: xfer=%p\n", xfer));
+ ehci_abort_xfer(xfer, USBD_CANCELLED);
+}
+
+/*
+ * Close a device bulk pipe.
+ */
+Static void
+ehci_device_bulk_close(usbd_pipe_handle pipe)
+{
+ ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
+
+ DPRINTF(("ehci_device_bulk_close: pipe=%p\n", pipe));
+ ehci_close_pipe(pipe, sc->sc_async_head);
+}
+
+void
+ehci_device_bulk_done(usbd_xfer_handle xfer)
+{
+ struct ehci_xfer *ex = EXFER(xfer);
+ ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
+ /*struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;*/
+
+ DPRINTFN(10,("ehci_bulk_done: xfer=%p, actlen=%d\n",
+ xfer, xfer->actlen));
+
+ ehci_del_intr_list(ex); /* remove from active list */
+
+ ehci_free_std_chain(sc, ex->sqtdstart, 0);
+
+ DPRINTFN(5, ("ehci_bulk_done: length=%d\n", xfer->actlen));
+}
/************************/
Home |
Main Index |
Thread Index |
Old Index