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 root hub emulation.
details: https://anonhg.NetBSD.org/src/rev/f68b0a7db418
branches: trunk
changeset: 517604:f68b0a7db418
user: augustss <augustss%NetBSD.org@localhost>
date: Thu Nov 15 23:25:09 2001 +0000
description:
Add root hub emulation.
diffstat:
sys/dev/usb/ehci.c | 967 +++++++++++++++++++++++++++++++++++++++++++++++++-
sys/dev/usb/ehcireg.h | 8 +-
sys/dev/usb/ehcivar.h | 13 +-
3 files changed, 974 insertions(+), 14 deletions(-)
diffs (truncated from 1089 to 300 lines):
diff -r e19b8800375a -r f68b0a7db418 sys/dev/usb/ehci.c
--- a/sys/dev/usb/ehci.c Thu Nov 15 22:16:17 2001 +0000
+++ b/sys/dev/usb/ehci.c Thu Nov 15 23:25:09 2001 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: ehci.c,v 1.4 2001/11/13 06:24:53 lukem Exp $ */
+/* $NetBSD: ehci.c,v 1.5 2001/11/15 23:25:09 augustss Exp $ */
/*
- * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -39,13 +39,13 @@
/*
* USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
*
- * EHCI 0.96 spec can be found at
+ * The EHCI 0.96 spec can be found at
* http://developer.intel.com/technology/usb/download/ehci-r096.pdf
*
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.4 2001/11/13 06:24:53 lukem Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.5 2001/11/15 23:25:09 augustss Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -71,13 +71,141 @@
#ifdef EHCI_DEBUG
#define DPRINTF(x) if (ehcidebug) printf x
#define DPRINTFN(n,x) if (ehcidebug>(n)) printf x
-int ehcidebug = 1;
+int ehcidebug = 5;
#define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
#endif
+struct ehci_pipe {
+ struct usbd_pipe pipe;
+};
+
+Static void ehci_shutdown(void *);
+Static void ehci_power(int, void *);
+
+Static usbd_status ehci_open(usbd_pipe_handle);
+Static void ehci_poll(struct usbd_bus *);
+Static void ehci_softintr(void *);
+
+Static usbd_status ehci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
+Static void ehci_freem(struct usbd_bus *, usb_dma_t *);
+
+Static usbd_xfer_handle ehci_allocx(struct usbd_bus *);
+Static void ehci_freex(struct usbd_bus *, usbd_xfer_handle);
+
+Static usbd_status ehci_root_ctrl_transfer(usbd_xfer_handle);
+Static usbd_status ehci_root_ctrl_start(usbd_xfer_handle);
+Static void ehci_root_ctrl_abort(usbd_xfer_handle);
+Static void ehci_root_ctrl_close(usbd_pipe_handle);
+Static void ehci_root_ctrl_done(usbd_xfer_handle);
+
+Static usbd_status ehci_root_intr_transfer(usbd_xfer_handle);
+Static usbd_status ehci_root_intr_start(usbd_xfer_handle);
+Static void ehci_root_intr_abort(usbd_xfer_handle);
+Static void ehci_root_intr_close(usbd_pipe_handle);
+Static void ehci_root_intr_done(usbd_xfer_handle);
+
+Static usbd_status ehci_device_ctrl_transfer(usbd_xfer_handle);
+Static usbd_status ehci_device_ctrl_start(usbd_xfer_handle);
+Static void ehci_device_ctrl_abort(usbd_xfer_handle);
+Static void ehci_device_ctrl_close(usbd_pipe_handle);
+Static void ehci_device_ctrl_done(usbd_xfer_handle);
+
+Static usbd_status ehci_device_bulk_transfer(usbd_xfer_handle);
+Static usbd_status ehci_device_bulk_start(usbd_xfer_handle);
+Static void ehci_device_bulk_abort(usbd_xfer_handle);
+Static void ehci_device_bulk_close(usbd_pipe_handle);
+Static void ehci_device_bulk_done(usbd_xfer_handle);
+
+Static usbd_status ehci_device_intr_transfer(usbd_xfer_handle);
+Static usbd_status ehci_device_intr_start(usbd_xfer_handle);
+Static void ehci_device_intr_abort(usbd_xfer_handle);
+Static void ehci_device_intr_close(usbd_pipe_handle);
+Static void ehci_device_intr_done(usbd_xfer_handle);
+
+Static usbd_status ehci_device_isoc_transfer(usbd_xfer_handle);
+Static usbd_status ehci_device_isoc_start(usbd_xfer_handle);
+Static void ehci_device_isoc_abort(usbd_xfer_handle);
+Static void ehci_device_isoc_close(usbd_pipe_handle);
+Static void ehci_device_isoc_done(usbd_xfer_handle);
+
+Static void ehci_device_clear_toggle(usbd_pipe_handle pipe);
+Static void ehci_noop(usbd_pipe_handle pipe);
+
+Static int ehci_str(usb_string_descriptor_t *, int, char *);
+
+#ifdef EHCI_DEBUG
+Static void ehci_dumpregs(ehci_softc_t *);
+#endif
+
+#define EHCI_INTR_ENDPT 1
+
+Static struct usbd_bus_methods ehci_bus_methods = {
+ ehci_open,
+ ehci_softintr,
+ ehci_poll,
+ ehci_allocm,
+ ehci_freem,
+ ehci_allocx,
+ ehci_freex,
+};
+
+Static struct usbd_pipe_methods ehci_root_ctrl_methods = {
+ ehci_root_ctrl_transfer,
+ ehci_root_ctrl_start,
+ ehci_root_ctrl_abort,
+ ehci_root_ctrl_close,
+ ehci_noop,
+ ehci_root_ctrl_done,
+};
+
+Static struct usbd_pipe_methods ehci_root_intr_methods = {
+ ehci_root_intr_transfer,
+ ehci_root_intr_start,
+ ehci_root_intr_abort,
+ ehci_root_intr_close,
+ ehci_noop,
+ ehci_root_intr_done,
+};
+
+Static struct usbd_pipe_methods ehci_device_ctrl_methods = {
+ ehci_device_ctrl_transfer,
+ ehci_device_ctrl_start,
+ ehci_device_ctrl_abort,
+ ehci_device_ctrl_close,
+ ehci_noop,
+ ehci_device_ctrl_done,
+};
+
+Static struct usbd_pipe_methods ehci_device_intr_methods = {
+ ehci_device_intr_transfer,
+ ehci_device_intr_start,
+ ehci_device_intr_abort,
+ ehci_device_intr_close,
+ ehci_device_clear_toggle,
+ ehci_device_intr_done,
+};
+
+Static struct usbd_pipe_methods ehci_device_bulk_methods = {
+ ehci_device_bulk_transfer,
+ ehci_device_bulk_start,
+ ehci_device_bulk_abort,
+ ehci_device_bulk_close,
+ ehci_device_clear_toggle,
+ ehci_device_bulk_done,
+};
+
+Static struct usbd_pipe_methods ehci_device_isoc_methods = {
+ ehci_device_isoc_transfer,
+ ehci_device_isoc_start,
+ ehci_device_isoc_abort,
+ ehci_device_isoc_close,
+ ehci_noop,
+ ehci_device_isoc_done,
+};
+
usbd_status
ehci_init(ehci_softc_t *sc)
{
@@ -110,6 +238,7 @@
printf(" %s", USBDEVNAME(sc->sc_comps[i]->bdev));
printf("\n");
}
+ sc->sc_noport = EHCI_HCS_N_PORTS(sparams);
cparams = EREAD4(sc, EHCI_HCCPARAMS);
DPRINTF(("ehci_init: cparams=0x%x\n", cparams));
@@ -142,11 +271,16 @@
EHCI_FLALIGN_ALIGN, &sc->sc_fldma);
if (err)
return (err);
- //sc->sc_fl = (struct ohci_hcca *)KERNADDR(&sc->sc_hccadma);
DPRINTF(("%s: flsize=%d\n", USBDEVNAME(sc->sc_bus.bdev),sc->sc_flsize));
- printf("%s: EHCI not supported yet.\n", USBDEVNAME(sc->sc_bus.bdev));
- return (USBD_IOERROR);
+ /* Set up the bus struct. */
+ sc->sc_bus.methods = &ehci_bus_methods;
+ sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);
+
+ sc->sc_powerhook = powerhook_establish(ehci_power, sc);
+ sc->sc_shutdownhook = shutdownhook_establish(ehci_shutdown, sc);
+
+ return (USBD_NORMAL_COMPLETION);
}
int
@@ -155,6 +289,32 @@
return (0);
}
+void
+ehci_softintr(void *v)
+{
+ //ehci_softc_t *sc = v;
+}
+
+void
+ehci_poll(struct usbd_bus *bus)
+{
+#if 0
+ ehci_softc_t *sc = (ehci_softc_t *)bus;
+#ifdef EHCI_DEBUG
+ static int last;
+ int new;
+ new = OREAD4(sc, EHCI_INTERRUPT_STATUS);
+ if (new != last) {
+ DPRINTFN(10,("ehci_poll: intrs=0x%04x\n", new));
+ last = new;
+ }
+#endif
+
+ if (OREAD4(sc, EHCI_INTERRUPT_STATUS) & sc->sc_eintrs)
+ ehci_intr1(sc);
+#endif
+}
+
int
ehci_detach(struct ehci_softc *sc, int flags)
{
@@ -191,8 +351,799 @@
case DVACT_DEACTIVATE:
if (sc->sc_child != NULL)
rv = config_deactivate(sc->sc_child);
+ sc->sc_dying = 1;
break;
}
return (rv);
}
+/*
+ * Handle suspend/resume.
+ *
+ * We need to switch to polling mode here, because this routine is
+ * called from an intterupt context. This is all right since we
+ * are almost suspended anyway.
+ */
+void
+ehci_power(int why, void *v)
+{
+ ehci_softc_t *sc = v;
+ //u_int32_t ctl;
+ int s;
+
+#ifdef EHCI_DEBUG
+ DPRINTF(("ehci_power: sc=%p, why=%d\n", sc, why));
+ ehci_dumpregs(sc);
+#endif
+
+ s = splhardusb();
+ switch (why) {
+ case PWR_SUSPEND:
+ case PWR_STANDBY:
+ sc->sc_bus.use_polling++;
+#if 0
+OOO
+ ctl = OREAD4(sc, EHCI_CONTROL) & ~EHCI_HCFS_MASK;
+ if (sc->sc_control == 0) {
+ /*
+ * Preserve register values, in case that APM BIOS
+ * does not recover them.
+ */
+ sc->sc_control = ctl;
+ sc->sc_intre = OREAD4(sc, EHCI_INTERRUPT_ENABLE);
+ }
+ ctl |= EHCI_HCFS_SUSPEND;
+ OWRITE4(sc, EHCI_CONTROL, ctl);
+#endif
+ usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
+ sc->sc_bus.use_polling--;
+ break;
+ case PWR_RESUME:
+ sc->sc_bus.use_polling++;
+#if 0
+OOO
+ /* Some broken BIOSes do not recover these values */
+ OWRITE4(sc, EHCI_HCCA, DMAADDR(&sc->sc_hccadma));
+ OWRITE4(sc, EHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
+ OWRITE4(sc, EHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
+ if (sc->sc_intre)
+ OWRITE4(sc, EHCI_INTERRUPT_ENABLE,
+ sc->sc_intre & (EHCI_ALL_INTRS | EHCI_MIE));
+ if (sc->sc_control)
+ ctl = sc->sc_control;
+ else
+ ctl = OREAD4(sc, EHCI_CONTROL);
+ ctl |= EHCI_HCFS_RESUME;
Home |
Main Index |
Thread Index |
Old Index