Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb Add support for scratchpad buffers (required for...



details:   https://anonhg.NetBSD.org/src/rev/4f9db61fed6a
branches:  trunk
changeset: 790958:4f9db61fed6a
user:      matt <matt%NetBSD.org@localhost>
date:      Mon Oct 28 17:49:33 2013 +0000

description:
Add support for scratchpad buffers (required for some XHCI devices).
Fix an endian issue.

diffstat:

 sys/dev/usb/xhci.c    |  52 ++++++++++++++++++++++++++++++++++++++------------
 sys/dev/usb/xhcivar.h |   5 +++-
 2 files changed, 43 insertions(+), 14 deletions(-)

diffs (125 lines):

diff -r 33e4ebb74bc8 -r 4f9db61fed6a sys/dev/usb/xhci.c
--- a/sys/dev/usb/xhci.c        Mon Oct 28 17:40:43 2013 +0000
+++ b/sys/dev/usb/xhci.c        Mon Oct 28 17:49:33 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: xhci.c,v 1.4 2013/10/18 08:39:22 apb Exp $     */
+/*     $NetBSD: xhci.c,v 1.5 2013/10/28 17:49:33 matt Exp $    */
 
 /*
  * Copyright (c) 2013 Jonathan A. Kollasch
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.4 2013/10/18 08:39:22 apb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.5 2013/10/28 17:49:33 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -703,14 +703,6 @@
        if (i >= 100)
                return USBD_IOERROR;
 
-       device_printf(sc->sc_dev, "maxspbuf %d\n", XHCI_HCS2_MAXSPBUF(hcs2));
-       if (XHCI_HCS2_MAXSPBUF(hcs2) != 0) {
-               /* XXX */
-               aprint_error_dev(sc->sc_dev,
-                   "TODO implement scratchpad allocation\n");
-               return USBD_INVAL;
-       }
-
        pagesize = xhci_op_read_4(sc, XHCI_PAGESIZE);
        device_printf(sc->sc_dev, "PAGESIZE 0x%08x\n", pagesize);
        pagesize = ffs(pagesize);
@@ -721,13 +713,40 @@
        device_printf(sc->sc_dev, "sc_maxslots 0x%08x\n",
            (uint32_t)sc->sc_maxslots);
 
+       usbd_status err;
+
+       sc->sc_maxspbuf = XHCI_HCS2_MAXSPBUF(hcs2);
+       device_printf(sc->sc_dev, "sc_maxspbuf %d\n", sc->sc_maxspbuf);
+       if (sc->sc_maxspbuf != 0) {
+               err = usb_allocmem(&sc->sc_bus,
+                   sizeof(uint64_t) * sc->sc_maxspbuf, sizeof(uint64_t),
+                   &sc->sc_spbufarray_dma);
+               if (err)
+                       return err;
+               
+               sc->sc_spbuf_dma = kmem_zalloc(sizeof(*sc->sc_spbuf_dma) * sc->sc_maxspbuf, KM_SLEEP);
+               uint64_t *spbufarray = KERNADDR(&sc->sc_spbufarray_dma, 0);
+               for (i = 0; i < sc->sc_maxspbuf; i++) {
+                       usb_dma_t * const dma = &sc->sc_spbuf_dma[i];
+                       /* allocate contexts */
+                       err = usb_allocmem(&sc->sc_bus, sc->sc_pgsz,
+                           sc->sc_pgsz, dma);
+                       if (err)
+                               return err;
+                       spbufarray[i] = htole64(DMAADDR(dma, 0));
+                       usb_syncmem(dma, 0, sc->sc_pgsz,
+                           BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+               }
+
+               usb_syncmem(&sc->sc_spbufarray_dma, 0, 
+                   sizeof(uint64_t) * sc->sc_maxspbuf, BUS_DMASYNC_PREWRITE);
+       }
+
        config = xhci_op_read_4(sc, XHCI_CONFIG);
        config &= ~0xFF;
        config |= sc->sc_maxslots & 0xFF;
        xhci_op_write_4(sc, XHCI_CONFIG, config);
 
-       usbd_status err;
-
        err = xhci_ring_init(sc, &sc->sc_cr, XHCI_COMMAND_RING_TRBS,
            XHCI_COMMAND_RING_SEGMENTS_ALIGN);
        if (err) {
@@ -767,6 +786,13 @@
                align = XHCI_DEVICE_CONTEXT_BASE_ADDRESS_ARRAY_ALIGN;
                err = usb_allocmem(&sc->sc_bus, size, align, dma);
                memset(KERNADDR(dma, 0), 0, size);
+               if (sc->sc_maxspbuf != 0) {
+                       /*
+                        * DCBA entry 0 hold the scratchbuf array pointer.
+                        */
+                       *(uint64_t *)KERNADDR(dma, 0) =
+                           htole64(DMAADDR(&sc->sc_spbufarray_dma, 0));
+               }
                usb_syncmem(dma, 0, size, BUS_DMASYNC_PREWRITE);
                device_printf(sc->sc_dev, "dcbaa: %s %016jx %p %zx\n",
                    usbd_errstr(err),
@@ -1792,7 +1818,7 @@
        device_printf(sc->sc_dev, "dcbaa %p dc %016"PRIx64" slot %d\n",
            &dcbaa[si], dcba, si);
 
-       dcbaa[si] = dcba;
+       dcbaa[si] = htole64(dcba);
        usb_syncmem(&sc->sc_dcbaa_dma, si * sizeof(uint64_t), sizeof(uint64_t),
            BUS_DMASYNC_PREWRITE);
 }
diff -r 33e4ebb74bc8 -r 4f9db61fed6a sys/dev/usb/xhcivar.h
--- a/sys/dev/usb/xhcivar.h     Mon Oct 28 17:40:43 2013 +0000
+++ b/sys/dev/usb/xhcivar.h     Mon Oct 28 17:49:33 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: xhcivar.h,v 1.1 2013/09/14 00:40:31 jakllsch Exp $     */
+/*     $NetBSD: xhcivar.h,v 1.2 2013/10/28 17:49:33 matt Exp $ */
 
 /*
  * Copyright (c) 2013 Jonathan A. Kollasch
@@ -85,6 +85,7 @@
        int sc_maxslots;
        int sc_maxintrs;
        int sc_maxports;
+       int sc_maxspbuf;
 
        /* XXX suboptimal */
        int sc_hs_port_start;
@@ -99,6 +100,8 @@
 
        usb_dma_t sc_eventst_dma;
        usb_dma_t sc_dcbaa_dma;
+       usb_dma_t sc_spbufarray_dma;
+       usb_dma_t *sc_spbuf_dma;
 
        //struct usb_dma_reserve sc_dma_reserve;
 



Home | Main Index | Thread Index | Old Index