summaryrefslogtreecommitdiffstats
path: root/sys/pci/ohci_pci.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1999-04-16 21:22:55 +0000
committerpeter <peter@FreeBSD.org>1999-04-16 21:22:55 +0000
commit087d4857e56f150a8f549600150404f273efb895 (patch)
treecf4e27432c59d956f4e5784207180115ee8fef9d /sys/pci/ohci_pci.c
parentc5fe612b8411a32a8e6e426fc1a70cba0cca3d31 (diff)
downloadFreeBSD-src-087d4857e56f150a8f549600150404f273efb895.zip
FreeBSD-src-087d4857e56f150a8f549600150404f273efb895.tar.gz
Bring the 'new-bus' to the i386. This extensively changes the way the
i386 platform boots, it is no longer ISA-centric, and is fully dynamic. Most old drivers compile and run without modification via 'compatability shims' to enable a smoother transition. eisa, isapnp and pccard* are not yet using the new resource manager. Once fully converted, all drivers will be loadable, including PCI and ISA. (Some other changes appear to have snuck in, including a port of Soren's ATA driver to the Alpha. Soren, back this out if you need to.) This is a checkpoint of work-in-progress, but is quite functional. The bulk of the work was done over the last few years by Doug Rabson and Garrett Wollman. Approved by: core
Diffstat (limited to 'sys/pci/ohci_pci.c')
-rw-r--r--sys/pci/ohci_pci.c154
1 files changed, 88 insertions, 66 deletions
diff --git a/sys/pci/ohci_pci.c b/sys/pci/ohci_pci.c
index 3c20ff7..1aea5f1 100644
--- a/sys/pci/ohci_pci.c
+++ b/sys/pci/ohci_pci.c
@@ -44,6 +44,8 @@
* USB spec: http://www.teleport.com/cgi-bin/mailmerge.cgi/~usb/cgiform.tpl
*/
+#include "opt_bus.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -52,23 +54,13 @@
#include <sys/device.h>
#include <sys/proc.h>
#include <sys/queue.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
-#define PCI_CLASS_SERIALBUS 0x0c000000
-#define PCI_SUBCLASS_COMMUNICATIONS_SERIAL 0x00000000
-#define PCI_SUBCLASS_SERIALBUS_FIREWIRE 0x00000000
-#define PCI_SUBCLASS_SERIALBUS_ACCESS 0x00010000
-#define PCI_SUBCLASS_SERIALBUS_SSA 0x00020000
-#define PCI_SUBCLASS_SERIALBUS_USB 0x00030000
-#define PCI_SUBCLASS_SERIALBUS_FIBER 0x00040000
-
-#define PCI_INTERFACE(d) (((d) >> 8) & 0xff)
-#define PCI_SUBCLASS(d) ((d) & PCI_SUBCLASS_MASK)
-#define PCI_CLASS(d) ((d) & PCI_CLASS_MASK)
-
-
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
@@ -77,7 +69,6 @@
#include <dev/usb/ohcireg.h>
#include <dev/usb/ohcivar.h>
-
#define PCI_OHCI_VENDORID_ALI 0x10b9
#define PCI_OHCI_VENDORID_CMDTECH 0x1095
#define PCI_OHCI_VENDORID_COMPAQ 0x0e11
@@ -98,27 +89,12 @@ static const char *ohci_device_usb0673 = "CMD Tech 673 (USB0673) USB Host Contr
static const char *ohci_device_generic = "OHCI (generic) USB Host Controller";
-
-static const char *ohci_pci_probe __P((pcici_t, pcidi_t));
-static void ohci_pci_attach __P((pcici_t, int));
-
-static u_long ohci_count = 0;
-
-static struct pci_device ohci_pci_device = {
- "ohci",
- ohci_pci_probe,
- ohci_pci_attach,
- &ohci_count,
- NULL
-};
-
-DATA_SET(pcidevice_set, ohci_pci_device);
-
+#define PCI_OHCI_BASE_REG 0x10
static const char *
-ohci_pci_probe(pcici_t config_id, pcidi_t device_id)
+ohci_pci_match(device_t dev)
{
- u_int32_t class;
+ u_int32_t device_id = pci_get_devid(dev);
switch(device_id) {
case PCI_OHCI_DEVICEID_ALADDIN_V:
@@ -132,54 +108,72 @@ ohci_pci_probe(pcici_t config_id, pcidi_t device_id)
case PCI_OHCI_DEVICEID_NEC:
return (ohci_device_nec);
default:
- class = pci_conf_read(config_id, PCI_CLASS_REG);
- if ( (PCI_CLASS(class) == PCI_CLASS_SERIALBUS)
- && (PCI_SUBCLASS(class) == PCI_SUBCLASS_SERIALBUS_USB)
- && (PCI_INTERFACE(class) == PCI_INTERFACE_OHCI)) {
- return(ohci_device_generic);
+ if ( pci_get_class(dev) == PCIC_SERIALBUS
+ && pci_get_subclass(dev) == PCIS_SERIALBUS_USB
+ && pci_get_progif(dev) == PCI_INTERFACE_OHCI) {
+ return (ohci_device_generic);
}
}
return NULL; /* dunno */
}
-static void
-ohci_pci_attach(pcici_t config_id, int unit)
+static int
+ohci_pci_probe(device_t dev)
{
- vm_offset_t pbase;
+ const char *desc = ohci_pci_match(dev);
+ if (desc) {
+ device_set_desc(dev, desc);
+ return 0;
+ } else {
+ return ENXIO;
+ }
+}
+
+static int
+ohci_pci_attach(device_t dev)
+{
+ int unit = device_get_unit(dev);
+ ohci_softc_t *sc = device_get_softc(dev);
device_t usbus;
- ohci_softc_t *sc;
usbd_status err;
- int id;
+ int rid;
+ struct resource *res;
+ void *ih;
+ int error;
+
+ rid = PCI_CBMEM;
+ res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!res) {
+ device_printf(dev, "could not map memory\n");
+ return ENXIO;
+ }
- sc = malloc(sizeof(ohci_softc_t), M_DEVBUF, M_NOWAIT);
- /* Do not free it below, intr might use the sc */
- if ( sc == NULL ) {
- printf("ohci%d: could not allocate memory", unit);
- return;
- }
- memset(sc, 0, sizeof(ohci_softc_t));
+ sc->iot = rman_get_bustag(res);
+ sc->ioh = rman_get_bushandle(res);
- if(!pci_map_mem(config_id, PCI_CBMEM,
- (vm_offset_t *)&sc->sc_iobase, &pbase)) {
- printf("ohci%d: could not map memory\n", unit);
- return;
- }
+ rid = 0;
+ res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (res == NULL) {
+ device_printf(dev, "could not allocate irq\n");
+ return ENOMEM;
+ }
- if ( !pci_map_int(config_id, (pci_inthand_t *)ohci_intr,
- (void *) sc, &bio_imask)) {
- printf("ohci%d: could not map irq\n", unit);
- return;
+ error = bus_setup_intr(dev, res, (driver_intr_t *) ohci_intr, sc, &ih);
+ if (error) {
+ device_printf(dev, "could not setup irq\n");
+ return error;
}
- usbus = device_add_child(root_bus, "usb", -1, sc);
+ usbus = device_add_child(dev, "usb", -1, sc);
if (!usbus) {
- printf("ohci%d: could not add USB device to root bus\n", unit);
- return;
+ printf("ohci%d: could not add USB device\n", unit);
+ return ENOMEM;
}
- id = pci_conf_read(config_id, PCI_ID_REG);
- switch(id) {
+ switch (pci_get_devid(dev)) {
case PCI_OHCI_DEVICEID_ALADDIN_V:
device_set_desc(usbus, ohci_device_aladdin_v);
sprintf(sc->sc_vendor, "AcerLabs");
@@ -202,7 +196,7 @@ ohci_pci_attach(pcici_t config_id, int unit)
break;
default:
if (bootverbose)
- printf("(New OHCI DeviceId=0x%08x)\n", id);
+ printf("(New OHCI DeviceId=0x%08x)\n", pci_get_devid(dev));
device_set_desc(usbus, ohci_device_generic);
sprintf(sc->sc_vendor, "(unknown)");
}
@@ -211,8 +205,36 @@ ohci_pci_attach(pcici_t config_id, int unit)
err = ohci_init(sc);
if (err != USBD_NORMAL_COMPLETION) {
printf("ohci%d: init failed, error=%d\n", unit, err);
- device_delete_child(root_bus, usbus);
+ device_delete_child(dev, usbus);
}
- return;
+ return device_probe_and_attach(sc->sc_bus.bdev);
}
+
+static device_method_t ohci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ohci_pci_probe),
+ DEVMETHOD(device_attach, ohci_pci_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t ohci_driver = {
+ "ohci",
+ ohci_methods,
+ DRIVER_TYPE_BIO,
+ sizeof(ohci_softc_t),
+};
+
+static devclass_t ohci_devclass;
+
+DRIVER_MODULE(ohci, pci, ohci_driver, ohci_devclass, 0, 0);
OpenPOWER on IntegriCloud