Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Add work-in-progress xhci(4) driver code. Currently...
details: https://anonhg.NetBSD.org/src/rev/a41f67701662
branches: trunk
changeset: 789950:a41f67701662
user: jakllsch <jakllsch%NetBSD.org@localhost>
date: Sat Sep 14 00:40:31 2013 +0000
description:
Add work-in-progress xhci(4) driver code. Currently (mostly) supports
interrupt-driven control, interrupt and bulk transfers at the three USB
2.0 speeds on root hub ports.
diffstat:
sys/dev/pci/xhci_pci.c | 230 +++
sys/dev/usb/usb_subr.c | 17 +-
sys/dev/usb/usbdivar.h | 13 +-
sys/dev/usb/xhci.c | 2841 ++++++++++++++++++++++++++++++++++++++++++++++++
sys/dev/usb/xhcireg.h | 426 +++++++
sys/dev/usb/xhcivar.h | 127 ++
6 files changed, 3645 insertions(+), 9 deletions(-)
diffs (truncated from 3748 to 300 lines):
diff -r 24afd829f0d5 -r a41f67701662 sys/dev/pci/xhci_pci.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pci/xhci_pci.c Sat Sep 14 00:40:31 2013 +0000
@@ -0,0 +1,230 @@
+/* $NetBSD: xhci_pci.c,v 1.1 2013/09/14 00:40:31 jakllsch Exp $ */
+
+/*
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lennart%augustsson.net@localhost) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.1 2013/09/14 00:40:31 jakllsch Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
+
+#include <sys/bus.h>
+
+#include <dev/pci/pcivar.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+#include <dev/usb/usb_mem.h>
+
+#include <dev/usb/xhcireg.h>
+#include <dev/usb/xhcivar.h>
+
+struct xhci_pci_softc {
+ struct xhci_softc sc_xhci;
+ pci_chipset_tag_t sc_pc;
+ pcitag_t sc_tag;
+};
+
+static int
+xhci_pci_match(device_t parent, cfdata_t match, void *aux)
+{
+ struct pci_attach_args *pa = (struct pci_attach_args *) aux;
+
+ if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SERIALBUS &&
+ PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SERIALBUS_USB &&
+ PCI_INTERFACE(pa->pa_class) == PCI_INTERFACE_XHCI)
+ return 1;
+
+ return 0;
+}
+
+static void
+xhci_pci_attach(device_t parent, device_t self, void *aux)
+{
+ struct xhci_pci_softc * const psc = device_private(self);
+ struct xhci_softc * const sc = &psc->sc_xhci;
+ struct pci_attach_args *const pa = (struct pci_attach_args *)aux;
+ const pci_chipset_tag_t pc = pa->pa_pc;
+ const pcitag_t tag = pa->pa_tag;
+ char const *intrstr;
+ pci_intr_handle_t ih;
+ pcireg_t csr, memtype;
+ usbd_status r;
+ //const char *vendor;
+ uint32_t hccparams;
+
+ sc->sc_dev = self;
+ sc->sc_bus.hci_private = sc;
+
+ pci_aprint_devinfo(pa, "USB Controller");
+
+ /* check if memory space access is enabled */
+ csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
+#ifdef DEBUG
+ printf("csr: %08x\n", csr);
+#endif
+ if ((csr & PCI_COMMAND_MEM_ENABLE) == 0) {
+ aprint_error_dev(self, "memory access is disabled\n");
+ return;
+ }
+
+ /* map MMIO registers */
+ memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_CBMEM);
+ switch (memtype) {
+ case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
+ case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
+ if (pci_mapreg_map(pa, PCI_CBMEM, memtype, 0,
+ &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios)) {
+ sc->sc_ios = 0;
+ aprint_error_dev(self, "can't map mem space\n");
+ return;
+ }
+ break;
+ default:
+ aprint_error_dev(self, "BAR not 64 or 32-bit MMIO\n");
+ return;
+ break;
+ }
+
+ psc->sc_pc = pc;
+ psc->sc_tag = tag;
+
+ hccparams = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 0x10);
+
+ if (pci_dma64_available(pa) && ((hccparams&1)==1))
+ sc->sc_bus.dmatag = pa->pa_dmat64;
+ else
+ sc->sc_bus.dmatag = pa->pa_dmat;
+
+ /* Enable the device. */
+ pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
+ csr | PCI_COMMAND_MASTER_ENABLE);
+
+ /* Map and establish the interrupt. */
+ if (pci_intr_map(pa, &ih)) {
+ aprint_error_dev(self, "couldn't map interrupt\n");
+ goto fail;
+ }
+
+ /*
+ * Allocate IRQ
+ */
+ intrstr = pci_intr_string(pc, ih);
+ sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, xhci_intr, sc);
+ if (sc->sc_ih == NULL) {
+ aprint_error_dev(self, "couldn't establish interrupt");
+ if (intrstr != NULL)
+ aprint_error(" at %s", intrstr);
+ aprint_error("\n");
+ goto fail;
+ }
+ aprint_normal_dev(self, "interrupting at %s\n", intrstr);
+
+#if 0
+ /* Figure out vendor for root hub descriptor. */
+ vendor = pci_findvendor(pa->pa_id);
+ sc->sc_id_vendor = PCI_VENDOR(pa->pa_id);
+ if (vendor)
+ strlcpy(sc->sc_vendor, vendor, sizeof(sc->sc_vendor));
+ else
+ snprintf(sc->sc_vendor, sizeof(sc->sc_vendor),
+ "vendor 0x%04x", PCI_VENDOR(pa->pa_id));
+#endif
+
+ r = xhci_init(sc);
+ if (r != USBD_NORMAL_COMPLETION) {
+ aprint_error_dev(self, "init failed, error=%d\n", r);
+ goto fail;
+ }
+
+ if (!pmf_device_register1(self, xhci_suspend, xhci_resume,
+ xhci_shutdown))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
+ /* Attach usb device. */
+ sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
+ return;
+
+fail:
+ if (sc->sc_ih) {
+ pci_intr_disestablish(psc->sc_pc, sc->sc_ih);
+ sc->sc_ih = NULL;
+ }
+ if (sc->sc_ios) {
+ bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
+ sc->sc_ios = 0;
+ }
+ return;
+}
+
+static int
+xhci_pci_detach(device_t self, int flags)
+{
+ struct xhci_pci_softc * const psc = device_private(self);
+ struct xhci_softc * const sc = &psc->sc_xhci;
+ int rv;
+
+ rv = xhci_detach(sc, flags);
+ if (rv)
+ return rv;
+
+ pmf_device_deregister(self);
+
+ xhci_shutdown(self, flags);
+
+ if (sc->sc_ios) {
+#if 0
+ /* Disable interrupts, so we don't get any spurious ones. */
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
+#endif
+ }
+
+ if (sc->sc_ih != NULL) {
+ pci_intr_disestablish(psc->sc_pc, sc->sc_ih);
+ sc->sc_ih = NULL;
+ }
+ if (sc->sc_ios) {
+ bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
+ sc->sc_ios = 0;
+ }
+
+ return 0;
+}
+
+CFATTACH_DECL3_NEW(xhci_pci, sizeof(struct xhci_pci_softc),
+ xhci_pci_match, xhci_pci_attach, xhci_pci_detach, xhci_activate, NULL,
+ xhci_childdet, DVF_DETACH_SHUTDOWN);
diff -r 24afd829f0d5 -r a41f67701662 sys/dev/usb/usb_subr.c
--- a/sys/dev/usb/usb_subr.c Fri Sep 13 23:42:12 2013 +0000
+++ b/sys/dev/usb/usb_subr.c Sat Sep 14 00:40:31 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: usb_subr.c,v 1.192 2013/09/07 16:39:15 skrll Exp $ */
+/* $NetBSD: usb_subr.c,v 1.193 2013/09/14 00:40:31 jakllsch Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
/*
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.192 2013/09/07 16:39:15 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.193 2013/09/14 00:40:31 jakllsch Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@@ -82,12 +82,8 @@
Static int usbd_print(void *, const char *);
Static int usbd_ifprint(void *, const char *);
Static void usbd_free_iface_data(usbd_device_handle, int);
-Static void usbd_kill_pipe(usbd_pipe_handle);
-usbd_status usbd_attach_roothub(device_t, usbd_device_handle);
-Static usbd_status usbd_probe_and_attach(device_t, usbd_device_handle, int,
- int);
-Static u_int32_t usb_cookie_no = 0;
+uint32_t usb_cookie_no = 0;
Static const char * const usbd_error_strs[] = {
"NORMAL_COMPLETION",
@@ -1064,7 +1060,7 @@
* recognize the initial descriptor fetch (before the control endpoint's
* MaxPacketSize is known by the host) by exactly this length.
*/
-static usbd_status
+usbd_status
usbd_get_initial_ddesc(usbd_device_handle dev, usb_device_descriptor_t *desc)
{
usb_device_request_t req;
@@ -1107,6 +1103,11 @@
DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
bus, port, depth, speed));
+
+ if (bus->methods->new_device != NULL)
+ return (bus->methods->new_device)(parent, bus, depth, speed,
+ port, up);
+
addr = usbd_getnewaddr(bus);
if (addr < 0) {
printf("%s: No free USB addresses, new device ignored.\n",
diff -r 24afd829f0d5 -r a41f67701662 sys/dev/usb/usbdivar.h
--- a/sys/dev/usb/usbdivar.h Fri Sep 13 23:42:12 2013 +0000
+++ b/sys/dev/usb/usbdivar.h Sat Sep 14 00:40:31 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: usbdivar.h,v 1.104 2013/09/07 16:47:23 skrll Exp $ */
+/* $NetBSD: usbdivar.h,v 1.105 2013/09/14 00:40:31 jakllsch Exp $ */
/*
* Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
@@ -48,6 +48,7 @@
* allocx -
* freex -
* get_lock - Called at attach time
Home |
Main Index |
Thread Index |
Old Index