Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/dev/pci/ehci_pci.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/dev/pci/ehci_pci.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.3 retrieving revision 1.3.6.4 diff -u -p -r1.3 -r1.3.6.4 --- src/sys/dev/pci/ehci_pci.c 2000/12/28 22:59:12 1.3 +++ src/sys/dev/pci/ehci_pci.c 2002/10/10 18:40:33 1.3.6.4 @@ -1,7 +1,7 @@ -/* $NetBSD: ehci_pci.c,v 1.3 2000/12/28 22:59:12 sommerfeld Exp $ */ +/* $NetBSD: ehci_pci.c,v 1.3.6.4 2002/10/10 18:40:33 jdolecek Exp $ */ /* - * Copyright (c) 2000 The NetBSD Foundation, Inc. + * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -36,6 +36,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +__KERNEL_RCSID(0, "$NetBSD: ehci_pci.c,v 1.3.6.4 2002/10/10 18:40:33 jdolecek Exp $"); + #include #include #include @@ -46,6 +49,7 @@ #include #include +#include #include #include @@ -55,6 +59,13 @@ #include #include +#ifdef EHCI_DEBUG +#define DPRINTF(x) if (ehcidebug) printf x +extern int ehcidebug; +#else +#define DPRINTF(x) +#endif + int ehci_pci_match(struct device *, struct cfdata *, void *); void ehci_pci_attach(struct device *, struct device *, void *); int ehci_pci_detach(device_ptr_t, int); @@ -66,10 +77,8 @@ struct ehci_pci_softc { void *sc_ih; /* interrupt vectoring */ }; -struct cfattach ehci_pci_ca = { - sizeof(struct ehci_pci_softc), ehci_pci_match, ehci_pci_attach, - ehci_pci_detach, ehci_activate -}; +CFATTACH_DECL(ehci_pci, sizeof(struct ehci_pci_softc), + ehci_pci_match, ehci_pci_attach, ehci_pci_detach, ehci_activate); int ehci_pci_match(struct device *parent, struct cfdata *match, void *aux) @@ -98,6 +107,8 @@ ehci_pci_attach(struct device *parent, s char *devname = sc->sc.sc_bus.bdev.dv_xname; char devinfo[256]; usbd_status r; + int ncomp; + struct usb_pci *up; pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo); printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); @@ -105,13 +116,10 @@ ehci_pci_attach(struct device *parent, s /* Map I/O registers */ if (pci_mapreg_map(pa, PCI_CBMEM, PCI_MAPREG_TYPE_MEM, 0, &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) { - printf("%s: can't map i/o space\n", devname); + printf("%s: can't map memory space\n", devname); return; } - /* Disable interrupts, so we don't get any spurious ones. */ - /* bus_space_write_2(sc->sc.iot, sc->sc.ioh, EHCI_INTR, 0); */ - sc->sc_pc = pc; sc->sc_tag = tag; sc->sc.sc_bus.dmatag = pa->pa_dmat; @@ -121,6 +129,11 @@ ehci_pci_attach(struct device *parent, s pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr | PCI_COMMAND_MASTER_ENABLE); + /* Disable interrupts, so we don't get any spurious ones. */ + sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); + DPRINTF(("%s: offs=%d\n", devname, sc->sc.sc_offs)); + EOWRITE2(&sc->sc, EHCI_USBINTR, 0); + /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih)) { printf("%s: couldn't map interrupt\n", devname); @@ -139,14 +152,11 @@ ehci_pci_attach(struct device *parent, s switch(pci_conf_read(pc, tag, PCI_USBREV) & PCI_USBREV_MASK) { case PCI_USBREV_PRE_1_0: - sc->sc.sc_bus.usbrev = USBREV_PRE_1_0; - break; case PCI_USBREV_1_0: - sc->sc.sc_bus.usbrev = USBREV_1_0; - break; case PCI_USBREV_1_1: - sc->sc.sc_bus.usbrev = USBREV_1_1; - break; + sc->sc.sc_bus.usbrev = USBREV_UNKNOWN; + printf("%s: pre-2.0 USB rev\n", devname); + return; case PCI_USBREV_2_0: sc->sc.sc_bus.usbrev = USBREV_2_0; break; @@ -165,6 +175,22 @@ ehci_pci_attach(struct device *parent, s sprintf(sc->sc.sc_vendor, "vendor 0x%04x", PCI_VENDOR(pa->pa_id)); + /* + * Find companion controllers. According to the spec they always + * have lower function numbers so they should be enumerated already. + */ + ncomp = 0; + TAILQ_FOREACH(up, &ehci_pci_alldevs, next) { + if (up->bus == pa->pa_bus && up->device == pa->pa_device) { + DPRINTF(("ehci_pci_attach: companion %s\n", + USBDEVNAME(up->usb->bdev))); + sc->sc.sc_comps[ncomp++] = up->usb; + if (ncomp >= EHCI_COMPANION_MAX) + break; + } + } + sc->sc.sc_ncomp = ncomp; + r = ehci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", devname, r);