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