Source-Changes-HG archive

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

[src/nick-nhusb]: src/sys Parse the extended capabilies to and log each contr...



details:   https://anonhg.NetBSD.org/src/rev/d333fe012c9a
branches:  nick-nhusb
changeset: 334606:d333fe012c9a
user:      skrll <skrll%NetBSD.org@localhost>
date:      Mon Jan 02 16:55:50 2017 +0000

description:
Parse the extended capabilies to and log each controller port to SS/HS
bus root hub ports.

Create/attach the two buses and adapt the xhci_roothub_ctrl to deal with
both buses and sets of roothub ports.

XXX the roothub ub_devices entry needs work to interact with usbdevs(1)
XXX correctly

diffstat:

 sys/arch/arm/nvidia/tegra_xusb.c |    6 +-
 sys/dev/pci/xhci_pci.c           |   10 +-
 sys/dev/usb/usb.h                |    8 +-
 sys/dev/usb/xhci.c               |  287 ++++++++++++++++++++++++++++----------
 sys/dev/usb/xhcireg.h            |   27 +++-
 sys/dev/usb/xhcivar.h            |   27 ++-
 6 files changed, 267 insertions(+), 98 deletions(-)

diffs (truncated from 748 to 300 lines):

diff -r ec850915281b -r d333fe012c9a sys/arch/arm/nvidia/tegra_xusb.c
--- a/sys/arch/arm/nvidia/tegra_xusb.c  Mon Jan 02 16:54:15 2017 +0000
+++ b/sys/arch/arm/nvidia/tegra_xusb.c  Mon Jan 02 16:55:50 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_xusb.c,v 1.1.2.2 2016/10/05 20:55:25 skrll Exp $ */
+/* $NetBSD: tegra_xusb.c,v 1.1.2.3 2017/01/02 16:55:50 skrll Exp $ */
 
 /*
  * Copyright (c) 2016 Jonathan A. Kollasch
@@ -30,7 +30,7 @@
 #include "opt_tegra.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_xusb.c,v 1.1.2.2 2016/10/05 20:55:25 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_xusb.c,v 1.1.2.3 2017/01/02 16:55:50 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -349,6 +349,8 @@
 
        sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
 
+       sc->sc_child2 = config_found(self, &sc->sc_bus2, usbctlprint);
+
        error = xusb_mailbox_send(psc, 0x01000000);
        if (error) {
                aprint_error_dev(self, "send failed, error=%d\n", error);
diff -r ec850915281b -r d333fe012c9a sys/dev/pci/xhci_pci.c
--- a/sys/dev/pci/xhci_pci.c    Mon Jan 02 16:54:15 2017 +0000
+++ b/sys/dev/pci/xhci_pci.c    Mon Jan 02 16:55:50 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: xhci_pci.c,v 1.4.2.7 2016/12/05 10:55:16 skrll Exp $   */
+/*     $NetBSD: xhci_pci.c,v 1.4.2.8 2017/01/02 16:55:50 skrll Exp $   */
 /*     OpenBSD: xhci_pci.c,v 1.4 2014/07/12 17:38:51 yuo Exp   */
 
 /*
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.4.2.7 2016/12/05 10:55:16 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.4.2.8 2017/01/02 16:55:50 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -126,7 +126,6 @@
        char intrbuf[PCI_INTRSTR_LEN];
 
        sc->sc_dev = self;
-       sc->sc_bus.ub_hcpriv = sc;
 
        pci_aprint_devinfo(pa, "USB Controller");
 
@@ -219,8 +218,11 @@
                                  xhci_shutdown))
                aprint_error_dev(self, "couldn't establish power handler\n");
 
-       /* Attach usb device. */
+       /* Attach usb buses. */
        sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
+
+       sc->sc_child2 = config_found(self, &sc->sc_bus2, usbctlprint);
+
        return;
 
 fail:
diff -r ec850915281b -r d333fe012c9a sys/dev/usb/usb.h
--- a/sys/dev/usb/usb.h Mon Jan 02 16:54:15 2017 +0000
+++ b/sys/dev/usb/usb.h Mon Jan 02 16:55:50 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usb.h,v 1.111.2.10 2016/10/05 20:55:57 skrll Exp $     */
+/*     $NetBSD: usb.h,v 1.111.2.11 2017/01/02 16:55:50 skrll Exp $     */
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -53,9 +53,9 @@
 
 #define USB_STACK_VERSION 2
 
-#define USB_MAX_DEVICES 128
-#define USB_MIN_DEVICES 2               /* unused + root HUB */
-#define USB_START_ADDR 0
+#define USB_MAX_DEVICES        (128 + 1)       /* 0, root, and 1->127 */
+#define USB_MIN_DEVICES        2               /* unused + root HUB */
+#define USB_START_ADDR 0
 
 #define USB_CONTROL_ENDPOINT 0
 #define USB_MAX_ENDPOINTS 16
diff -r ec850915281b -r d333fe012c9a sys/dev/usb/xhci.c
--- a/sys/dev/usb/xhci.c        Mon Jan 02 16:54:15 2017 +0000
+++ b/sys/dev/usb/xhci.c        Mon Jan 02 16:55:50 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: xhci.c,v 1.28.2.82 2017/01/02 16:54:15 skrll Exp $     */
+/*     $NetBSD: xhci.c,v 1.28.2.83 2017/01/02 16:55:50 skrll Exp $     */
 
 /*
  * Copyright (c) 2013 Jonathan A. Kollasch
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.82 2017/01/02 16:54:15 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.83 2017/01/02 16:55:50 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -531,6 +531,36 @@
        return XHCI_EPCTX_0_EPSTATE_GET(le32toh(cp[0]));
 }
 
+static inline unsigned int
+xhci_ctlrport2bus(struct xhci_softc * const sc, unsigned int ctlrport)
+{
+       const unsigned int port = ctlrport - 1;
+       const uint8_t bit = __BIT(port % NBBY);
+
+       return __SHIFTOUT(sc->sc_ctlrportbus[port / NBBY], bit);
+}
+
+/*
+ * Return the roothub port for a controller port.  Both are 1..n.
+ */
+static inline unsigned int
+xhci_ctlrport2rhport(struct xhci_softc * const sc, unsigned int ctrlport)
+{
+
+       return sc->sc_ctlrportmap[ctrlport - 1];
+}
+
+/*
+ * Return the controller port for a bus roothub port.  Both are 1..n.
+ */
+static inline unsigned int
+xhci_rhport2ctlrport(struct xhci_softc * const sc, unsigned int bn,
+    unsigned int rhport)
+{
+
+       return sc->sc_rhportmap[bn][rhport - 1];
+}
+
 /* --- */
 
 void
@@ -548,11 +578,17 @@
 {
        int rv = 0;
 
-       if (sc->sc_child != NULL)
+       if (sc->sc_child2 != NULL) {
+               rv = config_detach(sc->sc_child2, flags);
+               if (rv != 0)
+                       return rv;
+       }
+
+       if (sc->sc_child != NULL) {
                rv = config_detach(sc->sc_child, flags);
-
-       if (rv != 0)
-               return rv;
+               if (rv != 0)
+                       return rv;
+       }
 
        /* XXX unconfigure/free slots */
 
@@ -578,6 +614,13 @@
 
        kmem_free(sc->sc_slots, sizeof(*sc->sc_slots) * sc->sc_maxslots);
 
+       kmem_free(sc->sc_ctlrportbus, sc->sc_maxports * sizeof(uint8_t) / NBBY);
+       kmem_free(sc->sc_ctlrportmap, sc->sc_maxports * sizeof(int));
+
+       for (size_t j = 0; j < __arraycount(sc->sc_rhportmap); j++) {
+               kmem_free(sc->sc_rhportmap[j], sc->sc_maxports * sizeof(int));
+       }
+
        mutex_destroy(&sc->sc_lock);
        mutex_destroy(&sc->sc_intr_lock);
 
@@ -701,37 +744,79 @@
 #endif
 }
 
+/* 7.2 xHCI Support Protocol Capability */
+static void
+xhci_id_protocols(struct xhci_softc *sc, bus_size_t ecp)
+{
+       /* XXX Cache this lot */
+
+       const uint32_t w0 = xhci_read_4(sc, ecp);
+       const uint32_t w4 = xhci_read_4(sc, ecp + 4);
+       const uint32_t w8 = xhci_read_4(sc, ecp + 8);
+       const uint32_t wc = xhci_read_4(sc, ecp + 0xc);
+
+       aprint_debug_dev(sc->sc_dev,
+           " SP: %08x %08x %08x %08x\n", w0, w4, w8, wc);
+
+       if (w4 != XHCI_XECP_USBID)
+               return;
+
+       const int major = XHCI_XECP_SP_W0_MAJOR(w0);
+       const int minor = XHCI_XECP_SP_W0_MINOR(w0);
+       const uint8_t cpo = XHCI_XECP_SP_W8_CPO(w8);
+       const uint8_t cpc = XHCI_XECP_SP_W8_CPC(w8);
+
+       const uint16_t mm = __SHIFTOUT(w0, __BITS(31, 16));
+       switch (mm) {
+       case 0x0200:
+       case 0x0300:
+       case 0x0301:
+               aprint_debug_dev(sc->sc_dev, " %s ports %d - %d\n",
+                   major == 3 ? "ss" : "hs", cpo, cpo + cpc -1);
+               break;
+       default:
+               aprint_debug_dev(sc->sc_dev, " unknown major/minor (%d/%d)\n",
+                   major, minor);
+               return;
+       }
+
+       const size_t bus = (major == 3) ? 0 : 1;
+
+       /* Index arrays with 0..n-1 where ports are numbered 1..n */
+       for (size_t cp = cpo - 1; cp < cpo + cpc - 1; cp++) {
+               if (sc->sc_ctlrportmap[cp] != 0) {
+                       aprint_error_dev(sc->sc_dev, "contoller port %zu "
+                           "already assigned", cp);
+                       continue;
+               }
+
+               sc->sc_ctlrportbus[cp / NBBY] |=
+                   bus == 0 ? 0 : __BIT(cp % NBBY);
+
+               const size_t rhp = sc->sc_rhportcount[bus]++;
+
+               KASSERTMSG(sc->sc_rhportmap[bus][rhp] == 0,
+                   "bus %zu rhp %zu is %d", bus, rhp,
+                   sc->sc_rhportmap[bus][rhp]);
+
+               sc->sc_rhportmap[bus][rhp] = cp + 1;
+               sc->sc_ctlrportmap[cp] = rhp + 1;
+       }
+}
+
 /* Process extended capabilities */
 static void
 xhci_ecp(struct xhci_softc *sc, uint32_t hcc)
 {
-       uint32_t ecp, ecr;
-
        XHCIHIST_FUNC(); XHCIHIST_CALLED();
 
-       ecp = XHCI_HCC_XECP(hcc) * 4;
+       bus_size_t ecp = XHCI_HCC_XECP(hcc) * 4;
        while (ecp != 0) {
-               ecr = xhci_read_4(sc, ecp);
-               aprint_debug_dev(sc->sc_dev, "ECR %x: %08x\n", ecp, ecr);
+               uint32_t ecr = xhci_read_4(sc, ecp);
+               aprint_debug_dev(sc->sc_dev, "ECR %lx: %08x\n", ecp, ecr);
                switch (XHCI_XECP_ID(ecr)) {
                case XHCI_ID_PROTOCOLS: {
-                       uint32_t w4, w8, wc;
-                       uint16_t w2;
-                       w2 = (ecr >> 16) & 0xffff;
-                       w4 = xhci_read_4(sc, ecp + 4);
-                       w8 = xhci_read_4(sc, ecp + 8);
-                       wc = xhci_read_4(sc, ecp + 0xc);
-                       aprint_debug_dev(sc->sc_dev,
-                           " SP: %08x %08x %08x %08x\n", ecr, w4, w8, wc);
-                       /* unused */
-                       if (w4 == 0x20425355 && (w2 & 0xff00) == 0x0300) {
-                               sc->sc_ss_port_start = (w8 >> 0) & 0xff;;
-                               sc->sc_ss_port_count = (w8 >> 8) & 0xff;;
-                       }
-                       if (w4 == 0x20425355 && (w2 & 0xff00) == 0x0200) {
-                               sc->sc_hs_port_start = (w8 >> 0) & 0xff;
-                               sc->sc_hs_port_count = (w8 >> 8) & 0xff;
-                       }
+                       xhci_id_protocols(sc, ecp);
                        break;
                }
                case XHCI_ID_USB_LEGACY: {
@@ -817,8 +902,19 @@
 
        XHCIHIST_FUNC(); XHCIHIST_CALLED();
 
+       /* Set up the bus struct for the usb 3 and usb 2 buses */
+       sc->sc_bus.ub_methods = &xhci_bus_methods;
+       sc->sc_bus.ub_pipesize = sizeof(struct xhci_pipe);
        sc->sc_bus.ub_revision = USBREV_3_0;
        sc->sc_bus.ub_usedma = true;
+       sc->sc_bus.ub_hcpriv = sc;
+
+       sc->sc_bus2.ub_methods = &xhci_bus_methods;
+       sc->sc_bus2.ub_pipesize = sizeof(struct xhci_pipe);
+       sc->sc_bus2.ub_revision = USBREV_2_0;
+       sc->sc_bus2.ub_usedma = true;
+       sc->sc_bus2.ub_hcpriv = sc;
+       sc->sc_bus2.ub_dmatag = sc->sc_bus.ub_dmatag;
 
        cap = xhci_read_4(sc, XHCI_CAPLENGTH);



Home | Main Index | Thread Index | Old Index