Add another parameter to BUS_ADD_CHILD to allow children to inherit
authorMatthew Dillon <dillon@dragonflybsd.org>
Sun, 30 Oct 2005 04:41:15 +0000 (04:41 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sun, 30 Oct 2005 04:41:15 +0000 (04:41 +0000)
code from grandparents.

Formalize and document the IDENTIFY mechanism and actually use it properly
to add PCI busses rather then the severe hacks that existed before.

Instead of attaching PCI busses (pcib) directly to nexus, create a pass-through
bus layer under nexus called 'legacypci' and attach the PCI busses to that.
Use the new BUS_ADD_CHILD and IVARS recursion capability to still allow
the pcib's under legacypci to get nexus generated IVARS.

NOTE ON IVARS:  These can be utterly confusing because a BUS device may
manage and control the IVARS attached to its children.  In addition, if the
BUS method for the device accessing the IVARs does not properly match up
with or recurse to the device that actually created the ivars, mass
confusion can result.  I have attempted to document the issue but XXX it
needs some sanity check code.

Add a 'pcib_owner' global that is used to determine which of the several
possible PCI mainbus subsystems actually own the PCI mainbus.  This is not
yet tied into ACPI but will be soon.  No longer add legacy "pcib" busses
if it is detected that another subsystem controls the mainbus.  Before
the busses were added but then simply not scanned later on, creating
confusing pcibX designations.  Now the busses aren't added... legacypci
stops cold if it doesn't own the PCI mainbus.  Get rid of the twisted
checks for "pci" devices that used to handle this job.

Document many aspects of the PCI code and redo some of the APIs slightly
to make them more obvious.  In particular, document the odd fact that
pci_*() accessor function actually operate on a pci function code based
sub-device of the "pci" driver and call device_get_parent() to get to the
pci" driver layer.  This sub layer really needs its own formal designation.

Change "pciX" attachments to "pcibY" busses.  Use the secondary bus id
for 'X' and require it to be unique.  Also reorder "pcibY" attachments
so the physical bus number tends to (but is not guarenteed to be) the
same 'Y' in pcibY.

Change IVARS access for bridges.  Require that the device representing the
"pcib" device be passed to pcib_get/set_*() routines instead of children
of said device.

Add a function devclass_find_unit() to shortcut the more complex operation
of locating the devclass by name and then getting the device relative to
the devclass.

Add numerous bus_generic_*() BUS methods which now recurse through the
parent instead of terminate with an error.

25 files changed:
sys/bus/firewire/firewire.c
sys/bus/firewire/fwohci_pci.c
sys/bus/isa/isa_common.c
sys/bus/isa/isahint.c
sys/bus/isa/pnp.c
sys/bus/pci/i386/pcibus.c
sys/bus/pci/pci.c
sys/bus/pci/pci_pcib.c
sys/bus/pci/pcivar.h
sys/bus/ppbus/ppbconf.c
sys/dev/acpica5/acpi.c
sys/dev/acpica5/acpi_ec.c
sys/dev/acpica5/acpi_pci.c
sys/dev/acpica5/acpi_timer.c
sys/dev/misc/orm/orm.c
sys/dev/netif/ep/if_ep_isa.c
sys/dev/netif/ex/if_ex_isa.c
sys/dev/sound/isa/es1888.c
sys/i386/i386/nexus.c
sys/i386/i386/pnpbios.c
sys/kern/bus_if.m
sys/kern/subr_bus.c
sys/platform/pc32/i386/nexus.c
sys/platform/pc32/i386/pnpbios.c
sys/sys/bus.h

index a6c0e8c..1ea3afc 100644 (file)
@@ -32,7 +32,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  * 
  * $FreeBSD: src/sys/dev/firewire/firewire.c,v 1.68 2004/01/08 14:58:09 simokawa Exp $
- * $DragonFly: src/sys/bus/firewire/firewire.c,v 1.12 2005/10/28 03:25:33 dillon Exp $
+ * $DragonFly: src/sys/bus/firewire/firewire.c,v 1.13 2005/10/30 04:41:08 dillon Exp $
  *
  */
 
@@ -97,7 +97,7 @@ static int firewire_resume      (device_t);
 #if 0
 static int firewire_shutdown    (device_t);
 #endif
-static device_t firewire_add_child   (device_t, int, const char *, int);
+static device_t firewire_add_child (device_t, device_t, int, const char *, int);
 static void fw_try_bmr (void *);
 static void fw_try_bmr_callback (struct fw_xfer *);
 static void fw_asystart (struct fw_xfer *);
@@ -435,13 +435,13 @@ firewire_attach(device_t dev)
  * Attach it as child.
  */
 static device_t
-firewire_add_child(device_t dev, int order, const char *name, int unit)
+firewire_add_child(device_t bus, device_t parent, int order, const char *name, int unit)
 {
         device_t child;
        struct firewire_softc *sc;
 
-       sc = (struct firewire_softc *)device_get_softc(dev);
-       child = device_add_child(dev, name, unit);
+       sc = (struct firewire_softc *)device_get_softc(parent);
+       child = device_add_child(parent, name, unit);
        if (child) {
                device_set_ivars(child, sc->fc);
                device_probe_and_attach(child);
index d8eed4c..a97f1da 100644 (file)
@@ -32,7 +32,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  * 
  * $FreeBSD: src/sys/dev/firewire/fwohci_pci.c,v 1.38 2004/01/23 17:37:09 simokawa Exp $
- * $DragonFly: src/sys/bus/firewire/fwohci_pci.c,v 1.19 2005/10/12 17:35:45 dillon Exp $
+ * $DragonFly: src/sys/bus/firewire/fwohci_pci.c,v 1.20 2005/10/30 04:41:08 dillon Exp $
  */
 
 #define BOUNCE_BUFFER_TEST     0
@@ -474,14 +474,14 @@ fwohci_pci_shutdown(device_t dev)
 }
 
 static device_t
-fwohci_pci_add_child(device_t dev, int order, const char *name, int unit)
+fwohci_pci_add_child(device_t bus, device_t parent, int order, const char *name, int unit)
 {
        struct fwohci_softc *sc;
        device_t child;
        int err = 0;
 
-       sc = (struct fwohci_softc *)device_get_softc(dev);
-       child = device_add_child(dev, name, unit);
+       sc = (struct fwohci_softc *)device_get_softc(bus);
+       child = device_add_child(parent, name, unit);
        if (child == NULL)
                return (child);
 
@@ -490,10 +490,10 @@ fwohci_pci_add_child(device_t dev, int order, const char *name, int unit)
 
        err = device_probe_and_attach(child);
        if (err) {
-               device_printf(dev, "probe_and_attach failed with err=%d\n",
+               device_printf(parent, "probe_and_attach failed with err=%d\n",
                    err);
-               fwohci_pci_detach(dev);
-               device_delete_child(dev, child);
+               fwohci_pci_detach(parent);
+               device_delete_child(parent, child);
                return NULL;
        }
 
index 36f8f16..2c31bbd 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/isa/isa_common.c,v 1.16.2.1 2000/09/16 15:49:52 roger Exp $
- * $DragonFly: src/sys/bus/isa/isa_common.c,v 1.8 2005/10/28 03:25:35 dillon Exp $
+ * $DragonFly: src/sys/bus/isa/isa_common.c,v 1.9 2005/10/30 04:41:09 dillon Exp $
  */
 /*
  * Modifications for Intel architecture by Garrett A. Wollman.
@@ -525,7 +525,7 @@ isa_probe_children(device_t dev)
  * Add a new child with default ivars.
  */
 static device_t
-isa_add_child(device_t dev, int order, const char *name, int unit)
+isa_add_child(device_t bus, device_t parent, int order, const char *name, int unit)
 {
        device_t child;
        struct  isa_device *idev;
@@ -535,7 +535,7 @@ isa_add_child(device_t dev, int order, const char *name, int unit)
        resource_list_init(&idev->id_resources);
        TAILQ_INIT(&idev->id_configs);
 
-       child = device_add_child_ordered(dev, order, name, unit);
+       child = device_add_child_ordered(parent, order, name, unit);
        device_set_ivars(child, idev);
 
        return child;
index 376e449..b51c291 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/isa/isahint.c,v 1.8.2.1 2001/03/21 11:18:25 nyan Exp $
- * $DragonFly: src/sys/bus/isa/isahint.c,v 1.4 2005/10/28 03:25:35 dillon Exp $
+ * $DragonFly: src/sys/bus/isa/isahint.c,v 1.5 2005/10/30 04:41:09 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -52,7 +52,7 @@ isahint_add_device(device_t parent, const char *name, int unit)
        else
                order = ISA_ORDER_SPECULATIVE;
 
-       child = BUS_ADD_CHILD(parent, order, name, unit);
+       child = BUS_ADD_CHILD(parent, parent, order, name, unit);
        if (child == 0)
                return;
 
index 264fd52..308cab4 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  *     $FreeBSD: src/sys/isa/pnp.c,v 1.5.2.1 2002/10/14 09:31:09 nyan Exp $
- *     $DragonFly: src/sys/bus/isa/pnp.c,v 1.7 2005/10/28 03:25:35 dillon Exp $
+ *     $DragonFly: src/sys/bus/isa/pnp.c,v 1.8 2005/10/30 04:41:09 dillon Exp $
  *      from: pnp.c,v 1.11 1999/05/06 22:11:19 peter Exp
  */
 
@@ -520,7 +520,8 @@ pnp_create_devices(device_t parent, pnp_id *p, int csn,
                        bcopy(resinfo, &logical_id, 4);
                        pnp_check_quirks(p->vendor_id, logical_id, ldn, NULL);
                        compat_id = 0;
-                       dev = BUS_ADD_CHILD(parent, ISA_ORDER_PNP, NULL, -1);
+                       dev = BUS_ADD_CHILD(parent, parent, ISA_ORDER_PNP,
+                                           NULL, -1);
                        if (desc)
                                device_set_desc_copy(dev, desc);
                        isa_set_vendorid(dev, p->vendor_id);
index 4aa2948..8a9ecf0 100644 (file)
@@ -24,7 +24,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/isa/pcibus.c,v 1.57.2.12 2003/08/07 06:19:26 imp Exp $
- * $DragonFly: src/sys/bus/pci/i386/pcibus.c,v 1.13 2005/10/28 03:25:36 dillon Exp $
+ * $DragonFly: src/sys/bus/pci/i386/pcibus.c,v 1.14 2005/10/30 04:41:12 dillon Exp $
  *
  */
 
 
 #include "pcib_if.h"
 
-static int
-nexus_pcib_maxslots(device_t dev)
-{
-       return 31;
-}
-
-/*
- * Read configuration space register.
- */
-static u_int32_t
-nexus_pcib_read_config(device_t dev, int bus, int slot, int func,
-                      int reg, int bytes)
-{
-       return (pci_cfgregread(bus, slot, func, reg, bytes));
-}
+static u_int32_t nexus_pcib_read_config(device_t, int, int, int, int, int);
 
 /*
- * Write configuration space register.
+ * Figure out if a PCI entity is a host bridge, return its name or NULL.
  */
-static void
-nexus_pcib_write_config(device_t dev, int bus, int slot, int func,
-                       int reg, u_int32_t data, int bytes)
-{
-       pci_cfgregwrite(bus, slot, func, reg, data, bytes);
-}
-
-static devclass_t      pcib_devclass;
-
 static const char *
-nexus_pcib_is_host_bridge(int bus, int slot, int func,
+nexus_legacypci_is_host_bridge(int bus, int slot, int func,
                          u_int32_t id, u_int8_t class, u_int8_t subclass,
                          u_int8_t *busnum)
 {
@@ -286,12 +263,38 @@ nexus_pcib_is_host_bridge(int bus, int slot, int func,
        return s;
 }
 
+/*
+ * Identify the existance of the first pci bus and install a child to
+ * nexus if we find it.  Use an order of 1 so it gets probed after
+ * any ACPI device installed under nexus.  To avoid boot-time confusion,
+ * we do not install any 'pcib' devices at this time.
+ *
+ * The identify method coupled with the driver spec of the same name
+ * automatically installs it under the nexus.
+ */
+static int
+nexus_legacypci_identify(driver_t *driver, device_t parent)
+{
+       /*
+        * Basically a static device, there's no point reinstalling it
+        * on rescan.
+        */
+       if (device_get_state(parent) == DS_ATTACHED)
+               return (0);
+
+       if (pci_cfgregopen() == 0)
+               return (ENXIO);
+
+       BUS_ADD_CHILD(parent, parent, 100, "legacypci", 0);
+       return (0);
+}
+
 /*
  * Scan the first pci bus for host-pci bridges and add pcib instances
  * to the nexus for each bridge.
  */
 static int
-nexus_pcib_identify(driver_t *driver, device_t parent)
+nexus_legacypci_probe(device_t dev)
 {
        int bus, slot, func;
        u_int8_t  hdrtype;
@@ -299,27 +302,24 @@ nexus_pcib_identify(driver_t *driver, device_t parent)
        int pcifunchigh;
        int found824xx = 0;
        device_t child;
-       devclass_t pci_devclass;
 
        /*
-        * XXX currently do not support rescanning the pci bus
+        * Do not install any pci busses ('pcib' devices) if the PCI
+        * subsystem has already been claimed by someone else.
         */
-       if (device_get_state(parent) == DS_ATTACHED)
-               return (0);
+       if (pcib_owner != NULL) {
+               device_printf(dev, "PCI subsystem owned by %s, skipping scan\n",
+                             pcib_owner);
+               return (ENXIO);
+       }
+       pcib_owner = "legacypci";
 
        if (pci_cfgregopen() == 0)
                return (ENXIO);
 
        /*
-        * Check to see if we haven't already had a PCI bus added
-        * via some other means. If we have, bail since otherwise
-        * we're going to end up duplicating it.
+        * Scan away!
         */
-       if ((pci_devclass = devclass_find("pci")) &&
-           devclass_get_device(pci_devclass,0)) {
-               return (ENXIO);
-       }
-       
        bus = 0;
  retry:
        for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
@@ -351,7 +351,7 @@ nexus_pcib_identify(driver_t *driver, device_t parent)
                        subclass = nexus_pcib_read_config(0, bus, slot, func,
                                                          PCIR_SUBCLASS, 1);
 
-                       s = nexus_pcib_is_host_bridge(bus, slot, func,
+                       s = nexus_legacypci_is_host_bridge(bus, slot, func,
                                                      id, class, subclass,
                                                      &busnum);
                        if (s == NULL)
@@ -362,11 +362,12 @@ nexus_pcib_identify(driver_t *driver, device_t parent)
                         * been seen. Eg: hybrid 32 and 64 bit host
                         * bridges to the same logical bus.
                         */
-                       if (device_get_children(parent, &devs, &ndevs) == 0) {
+                       if (device_get_children(dev, &devs, &ndevs) == 0) {
                                for (i = 0; s != NULL && i < ndevs; i++) {
                                        if (strcmp(device_get_name(devs[i]),
                                            "pcib") != 0)
                                                continue;
+                                       printf("compare %d\n", nexus_get_pcibus(devs[i]));
                                        if (nexus_get_pcibus(devs[i]) == busnum)
                                                s = NULL;
                                }
@@ -376,12 +377,10 @@ nexus_pcib_identify(driver_t *driver, device_t parent)
                        if (s == NULL)
                                continue;
                        /*
-                        * Add at priority 100+busnum to make sure we
-                        * go after any motherboard resources.  This also
-                        * causes us to scan the pci bridges in bus order,
-                        * for debug output sanity.
+                        * Add at priority 100+busnum to keep the scanning
+                        * order sane in the boot dmesg output.
                         */
-                       child = BUS_ADD_CHILD(parent, 100 + busnum,
+                       child = BUS_ADD_CHILD(dev, dev, 100 + busnum, 
                                              "pcib", busnum);
                        device_set_desc(child, s);
                        nexus_set_pcibus(child, busnum);
@@ -396,70 +395,127 @@ nexus_pcib_identify(driver_t *driver, device_t parent)
                goto retry;
        }
 
+#if 0
+       /*
+        * Now that we have installed the main PCI bridges, go
+        * probe and attach each one.
+        */
+       bus_generic_attach(dev);
+#endif
+
        /*
         * Make sure we add at least one bridge since some old
         * hardware doesn't actually have a host-pci bridge device.
         * Note that pci_cfgregopen() thinks we have PCI devices..
         */
        if (!found) {
-               if (bootverbose)
-                       printf(
-       "nexus_pcib_identify: no bridge found, adding pcib0 anyway\n");
-               child = BUS_ADD_CHILD(parent, 100, "pcib", 0);
+               if (bootverbose) {
+                       printf("nexus_pcib_identify: no bridge found, "
+                              "adding pcib0 anyway\n");
+               }
+               child = BUS_ADD_CHILD(dev, dev, 100, "pcib", 0);
                nexus_set_pcibus(child, 0);
        }
        return (0);
 }
 
 static int
-nexus_pcib_probe(device_t dev)
+nexus_legacypci_attach(device_t dev)
 {
-       devclass_t pci_devclass;
+       bus_generic_attach(dev);
+       return (0);
+}
+
+static device_method_t legacypci_methods[] = {
+       /* Device interface */
+       DEVMETHOD(device_identify,      nexus_legacypci_identify),
+       DEVMETHOD(device_probe,         nexus_legacypci_probe),
+       DEVMETHOD(device_attach,        nexus_legacypci_attach),
+       DEVMETHOD(device_shutdown,      bus_generic_shutdown),
+       DEVMETHOD(device_suspend,       bus_generic_suspend),
+       DEVMETHOD(device_resume,        bus_generic_resume),
 
-       if (pci_cfgregopen() == 0)
-               return (ENXIO);
        /*
-        * Check to see if we haven't already had a PCI bus added
-        * via some other means.  If we have, bail since otherwise
-        * we're going to end up duplicating it.
+        * Bus interface - propogate through to the nexus.  Note that
+        * this means devices under us will have nexus ivars.
         */
-       if ((pci_devclass = devclass_find("pci")) && 
-               devclass_get_device(pci_devclass, device_get_unit(dev)))
-               return (ENXIO);
+       DEVMETHOD(bus_add_child,        bus_generic_add_child),
+       DEVMETHOD(bus_print_child,      bus_generic_print_child),
+       DEVMETHOD(bus_read_ivar,        bus_generic_read_ivar),
+       DEVMETHOD(bus_write_ivar,       bus_generic_write_ivar),
+       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),
+        DEVMETHOD(bus_set_resource,     bus_generic_set_resource),
+        DEVMETHOD(bus_get_resource,     bus_generic_get_resource),
+        DEVMETHOD(bus_delete_resource,  bus_generic_delete_resource),
+       { 0, 0 }
+};
 
-       return (0);
-}
+static driver_t legacypci_driver = {
+       "legacypci",
+       legacypci_methods,
+       1,
+};
+
+static devclass_t legacypci_devclass;
+
+DRIVER_MODULE(legacypci, nexus, legacypci_driver, legacypci_devclass, 0, 0);
 
+/*
+ * Legacypci Host-Bridge PCI BUS support.  The underlying pcib devices
+ * will only exist if we actually control the PCI bus.  The actual PCI
+ * bus driver is attached in our attach routine.
+ *
+ * There is no identify function because the legacypci placeholder will
+ * have already scanned and added PCIB devices for the host-bridges found.
+ */
 static int
-nexus_pcib_attach(device_t dev)
+nexus_pcib_maxslots(device_t dev)
 {
-       device_t child;
+       return 31;
+}
 
-       child = device_add_child(dev, "pci", device_get_unit(dev));
+/*
+ * Read configuration space register.
+ */
+static u_int32_t
+nexus_pcib_read_config(device_t dev, int bus, int slot, int func,
+                      int reg, int bytes)
+{
+       return (pci_cfgregread(bus, slot, func, reg, bytes));
+}
 
-       return (bus_generic_attach(dev));
+/*
+ * Write configuration space register.
+ */
+static void
+nexus_pcib_write_config(device_t dev, int bus, int slot, int func,
+                       int reg, u_int32_t data, int bytes)
+{
+       pci_cfgregwrite(bus, slot, func, reg, data, bytes);
 }
 
+/*
+ * Stack a pci device on top of the pci bridge bus device.
+ */
 static int
-nexus_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+nexus_pcib_probe(device_t dev)
 {
-       switch (which) {
-       case  PCIB_IVAR_BUS:
-               *result = nexus_get_pcibus(dev);
-               return (0);
-       }
-       return (ENOENT);
+       BUS_ADD_CHILD(dev, dev, 0, "pci", device_get_unit(dev));
+       return (0);
 }
 
 static int
-nexus_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+nexus_pcib_attach(device_t dev)
 {
-       switch (which) {
-       case  PCIB_IVAR_BUS:
-               nexus_set_pcibus(dev, value);
-               return (0);
-       }
-       return (ENOENT);
+       int error;
+
+       error = bus_generic_attach(dev);
+       return (error);
 }
 
 /* route interrupt */
@@ -473,17 +529,20 @@ nexus_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
 
 static device_method_t nexus_pcib_methods[] = {
        /* Device interface */
-       DEVMETHOD(device_identify,      nexus_pcib_identify),
        DEVMETHOD(device_probe,         nexus_pcib_probe),
        DEVMETHOD(device_attach,        nexus_pcib_attach),
        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
        DEVMETHOD(device_suspend,       bus_generic_suspend),
        DEVMETHOD(device_resume,        bus_generic_resume),
 
-       /* Bus interface */
+       /*
+        * Bus interface - propogate through to the nexus.  Note
+        * that this means we will get nexus-managed ivars.
+        */
+       DEVMETHOD(bus_add_child,        bus_generic_add_child),
        DEVMETHOD(bus_print_child,      bus_generic_print_child),
-       DEVMETHOD(bus_read_ivar,        nexus_pcib_read_ivar),
-       DEVMETHOD(bus_write_ivar,       nexus_pcib_write_ivar),
+       DEVMETHOD(bus_read_ivar,        bus_generic_read_ivar),
+       DEVMETHOD(bus_write_ivar,       bus_generic_write_ivar),
        DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
        DEVMETHOD(bus_release_resource, bus_generic_release_resource),
        DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
@@ -500,29 +559,27 @@ static device_method_t nexus_pcib_methods[] = {
        { 0, 0 }
 };
 
-/*
- * This causes nexus_pcib_identify() to automatically be called when
- * nexus is attaching.  
- */
 static driver_t nexus_pcib_driver = {
        "pcib",
        nexus_pcib_methods,
        1,
 };
 
-DRIVER_MODULE(pcib, nexus, nexus_pcib_driver, pcib_devclass, 0, 0);
+static devclass_t      pcib_devclass;
+
+DRIVER_MODULE(pcib, legacypci, nexus_pcib_driver, pcib_devclass, 0, 0);
 
 
 /*
- * XXX may have to disable the registration entirely to support module-loaded
- * bridges such as agp.ko.
- * 
  * Provide a device to "eat" the host->pci bridges that we dug up above
  * and stop them showing up twice on the probes.  This also stops them
  * showing up as 'none' in pciconf -l.
  *
  * Return an ultra-low priority so other devices can attach the bus before
  * our dummy attach.
+ *
+ * XXX may have to disable the registration entirely to support module-loaded
+ * bridges such as agp.ko.
  */
 static int
 pci_hostb_probe(device_t dev)
@@ -613,3 +670,4 @@ static driver_t pcibus_pnp_driver = {
 static devclass_t pcibus_pnp_devclass;
 
 DRIVER_MODULE(pcibus_pnp, isa, pcibus_pnp_driver, pcibus_pnp_devclass, 0, 0);
+
index d892b30..a071177 100644 (file)
@@ -24,7 +24,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/pci.c,v 1.141.2.15 2002/04/30 17:48:18 tmm Exp $
- * $DragonFly: src/sys/bus/pci/pci.c,v 1.27 2005/06/14 16:35:42 joerg Exp $
+ * $DragonFly: src/sys/bus/pci/pci.c,v 1.28 2005/10/30 04:41:10 dillon Exp $
  *
  */
 
@@ -70,6 +70,7 @@
 #endif /* APIC_IO */
 
 devclass_t     pci_devclass;
+const char     *pcib_owner;
 
 static void            pci_read_extcap(device_t dev, pcicfgregs *cfg);
 
@@ -1068,8 +1069,16 @@ pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
                        pci = devclass_get_device(pci_devclass,
                                                  io->pi_sel.pc_bus);
                        if (pci) {
-                               int b = pcib_get_bus(pci);
+                               /*
+                                * pci is the pci device and may contain
+                                * several children (for each function code).
+                                * The governing pci bus is the parent to
+                                * the pci device.
+                                */
+                               int b;
+
                                pcib = device_get_parent(pci);
+                               b = pcib_get_bus(pcib);
                                io->pi_data = 
                                        PCIB_READ_CONFIG(pcib,
                                                         b,
@@ -1102,8 +1111,16 @@ pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
                        pci = devclass_get_device(pci_devclass,
                                                  io->pi_sel.pc_bus);
                        if (pci) {
-                               int b = pcib_get_bus(pci);
+                               /*
+                                * pci is the pci device and may contain
+                                * several children (for each function code).
+                                * The governing pci bus is the parent to
+                                * the pci device.
+                                */
+                               int b;
+
                                pcib = device_get_parent(pci);
+                               b = pcib_get_bus(pcib);
                                PCIB_WRITE_CONFIG(pcib,
                                                  b,
                                                  io->pi_sel.pc_dev,
@@ -1409,6 +1426,10 @@ pci_add_children(device_t dev, int busno, size_t dinfo_size)
 #undef REG
 }
 
+/*
+ * The actual PCI child that we add has a NULL driver whos parent
+ * device will be "pci".  The child contains the ivars, not the parent.
+ */
 void
 pci_add_child(device_t bus, struct pci_devinfo *dinfo)
 {
@@ -1448,8 +1469,12 @@ pci_attach(device_t dev)
          * busses on some large alpha systems, we can't use the unit
          * number to decide what bus we are probing. We ask the parent
          * pcib what our bus number is.
+        *
+        * pcib_get_bus() must act on the pci bus device, not on the pci
+        * device, because it uses badly hacked nexus-based ivars to 
+        * store and retrieve the physical bus number.  XXX
          */
-        busno = pcib_get_bus(dev);
+        busno = pcib_get_bus(device_get_parent(dev));
         if (bootverbose)
                 device_printf(dev, "pci_attach() physical bus=%d\n", busno);
 
index 1ea2b5c..a1dfab0 100644 (file)
@@ -26,7 +26,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $DragonFly: src/sys/bus/pci/pci_pcib.c,v 1.4 2005/01/17 20:24:46 joerg Exp $
+ * $DragonFly: src/sys/bus/pci/pci_pcib.c,v 1.5 2005/10/30 04:41:10 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -44,6 +44,8 @@
 #include "pcib_if.h"
 #include "pcib_private.h"
 
+static devclass_t pcib_devclass;
+
 /*
  * Attach a pci bus device to a motherboard or pci-to-pci bridge bus.
  * Due to probe recursion it is possible for pci-to-pci bridges (such as
  *
  * Bridges will cause recursions or duplicate attach attempts.  If
  * we have already attached this bus we don't do it again!
+ *
+ * NOTE THE DEVICE TOPOLOGY!   
+ *
+ *     [pcibX]->[pciX]->[pciX.Y]
+ *                      [pcibZ]
+ *
+ * When attaching a new bus device note that the PCI methods are
+ * based in the parent device, but the device ivars for those methods
+ * are based in our sub-device.  The PCI accessor functions all assume
+ * you are passing-in the sub-device.
  */
-
 void
 pcib_attach_common(device_t dev)
 {
@@ -174,8 +185,12 @@ pcib_attach_common(device_t dev)
      */
 }
 
-static const char*
-pcib_match(device_t dev)
+/*
+ * Called with the bridge candidate, which is under a PCI slot device.
+ * Note that the ivars are stored in the candidate.
+ */
+static const char *
+pci_match_bridge(device_t dev)
 {
        switch (pci_get_devid(dev)) {
        /* Intel -- vendor 0x8086 */
@@ -259,17 +274,26 @@ pcib_match(device_t dev)
        };
 
        if (pci_get_class(dev) == PCIC_BRIDGE
-           && pci_get_subclass(dev) == PCIS_BRIDGE_PCI)
+           && pci_get_subclass(dev) == PCIS_BRIDGE_PCI) {
                return pci_bridge_type(dev);
+       }
 
        return NULL;
 }
 
-static int pcib_probe(device_t dev)
+/*
+ * bus/pci/i386/pcibus.c added "pcib" devices under "pci" (slot) devices,
+ * causing us to probe and attach here.
+ *
+ * Note that the parent "pci" device has stored ivars in our device.  We
+ * are both a "pci" device and potentially a "pcib" device.
+ */
+static int
+pcib_probe(device_t dev)
 {
        const char *desc;
 
-       desc = pcib_match(dev);
+       desc = pci_match_bridge(dev);
        if (desc) {
                device_set_desc_copy(dev, desc);
                return -1000;
@@ -278,6 +302,11 @@ static int pcib_probe(device_t dev)
        return ENXIO;
 }
 
+/*
+ * Note that the "pci" device ivars are stored in the ivar data field
+ * for our device.  The "pcib" device ivars are stored in the softc
+ * structure.
+ */
 int
 pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
 {
@@ -308,16 +337,30 @@ int
 pcib_attach(device_t dev)
 {
        struct pcib_softc *sc;
-       device_t child;
 
        pcib_attach_common(dev);
        sc = device_get_softc(dev);
        /*chipset_attach(dev, device_get_unit(dev));*/
 
+       /*
+        * The pcib unit is not really under our control because
+        * we have are not (XXX) using the identify interface to
+        * assign the bridge driver, instead letting subr_bus do
+        * it via the probe mechanism.  However, we *do* directly
+        * create the "pci" children and we can control the unit
+        * number we assign for those.  We assign the secondary bus
+        * id as the unit number.
+        */
        if (sc->secbus != 0) {
-               child = device_add_child(dev, "pci", sc->secbus);
-               if (child != NULL)
-                   return bus_generic_attach(dev);
+               if (devclass_find_unit("pci", sc->secbus)) {
+                       device_printf(dev, "Duplicate secondary bus %d, "
+                                          "cannot attach bridge\n",
+                                          sc->secbus);
+
+               } else {
+                       device_add_child(dev, "pci", sc->secbus);
+                       bus_generic_attach(dev);
+               }
        } 
        return 0;
 }
@@ -478,11 +521,10 @@ pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
        return (bus_generic_alloc_resource(dev, child, type, rid, start, end, count, flags));
 }
 
-
 int
 pcib_maxslots(device_t dev)
 {
-       return 31;
+       return (31);
 }
 
 u_int32_t
@@ -492,6 +534,11 @@ pcib_read_config(device_t dev, int b, int s, int f,
        /*
         * Pass through to the next ppb up the chain (i.e. our
         * grandparent).
+        *
+        * [pcibX]->[pciX]->[pciX.Y]
+        *                  [pcibY]
+        *   ^
+        * getting back to this point.
         */
        return PCIB_READ_CONFIG(device_get_parent(device_get_parent(dev)),
                                b, s, f, reg, width);
@@ -511,6 +558,9 @@ pcib_write_config(device_t dev, int b, int s, int f,
 
 /*
  * Route an interrupt across a PCI bridge.
+ *
+ * pcib - is the pci bridge device
+ * dev  - is the device
  */
 int
 pcib_route_interrupt(device_t pcib, device_t dev, int pin)
@@ -519,8 +569,6 @@ pcib_route_interrupt(device_t pcib, device_t dev, int pin)
        int             parent_intpin;
        int             intnum;
 
-       device_printf(pcib, "Hi!\n");
-
        /*      
         *
         * The PCI standard defines a swizzle of the child-side device/intpin
@@ -661,6 +709,4 @@ static driver_t pcib_driver = {
        sizeof(struct pcib_softc)
 };
 
-devclass_t pcib_devclass;
-
 DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, 0, 0);
index 00db93d..bc943c4 100644 (file)
@@ -24,7 +24,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/pcivar.h,v 1.48 2000/09/28 00:37:32 peter Exp $
- * $DragonFly: src/sys/bus/pci/pcivar.h,v 1.9 2005/06/16 21:12:25 dillon Exp $
+ * $DragonFly: src/sys/bus/pci/pcivar.h,v 1.10 2005/10/30 04:41:10 dillon Exp $
  *
  */
 
@@ -139,6 +139,7 @@ typedef struct {
 } pcih2cfgregs;
 
 extern u_int32_t pci_numdevs;
+extern const char *pcib_owner;  /* arbitrate who owns the pci device arch */
 
 /* Only if the prerequisites are present */
 #if defined(_SYS_BUS_H_) && defined(_SYS_PCIIO_H_)
@@ -198,6 +199,10 @@ enum pci_device_ivars {
 
 /*
  * Simplified accessors for pci devices
+ *
+ * The PCI device passed in actually represents a PCI function number 
+ * for the current slot.  The parent of dev is the "pci" slot device.
+ * Each function number has its own set of ivars.
  */
 #define PCI_ACCESSOR(A, B, T)                                          \
                                                                        \
@@ -311,8 +316,12 @@ pci_get_powerstate(device_t dev)
 
 /*
  * Ivars for pci bridges.
+ *
+ * Whereas PCI devices are arranged [pciX]->[pciX.Y] with the pci driver
+ * functions in [pciX] but the individual ivars in [pciX.Y], PCI bridges
+ * are installed in [pciX.Y] and store their ivars in a softc.  This
+ * is why the accessor functions for a bridge do not call device_get_parent().
  */
-
 /*typedef enum pci_device_ivars pcib_device_ivars;*/
 enum pcib_device_ivars {
        PCIB_IVAR_BUS,
@@ -323,14 +332,14 @@ enum pcib_device_ivars {
 static __inline T pcib_get_ ## A(device_t dev)                          \
 {                                                                       \
        uintptr_t v;                                                     \
-       BUS_READ_IVAR(device_get_parent(dev), dev, PCIB_IVAR_ ## B, &v); \
+       BUS_READ_IVAR(dev, dev, PCIB_IVAR_ ## B, &v); \
        return (T) v;                                                    \
 }                                                                       \
                                                                         \
 static __inline void pcib_set_ ## A(device_t dev, T t)                  \
 {                                                                       \
        uintptr_t v = (uintptr_t) t;                                             \
-       BUS_WRITE_IVAR(device_get_parent(dev), dev, PCIB_IVAR_ ## B, v); \
+       BUS_WRITE_IVAR(dev, dev, PCIB_IVAR_ ## B, v); \
 }
 
 PCIB_ACCESSOR(bus,             BUS,            u_int32_t)
index dc5570d..a8383ea 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/ppbus/ppbconf.c,v 1.17.2.1 2000/05/24 00:20:57 n_hibma Exp $
- * $DragonFly: src/sys/bus/ppbus/ppbconf.c,v 1.8 2005/10/26 17:12:32 dillon Exp $
+ * $DragonFly: src/sys/bus/ppbus/ppbconf.c,v 1.9 2005/10/30 04:41:14 dillon Exp $
  *
  */
 #include "opt_ppb_1284.h"
@@ -82,7 +82,7 @@ ppbus_probe(device_t dev)
  * Add a ppbus device, allocate/initialize the ivars
  */
 static device_t
-ppbus_add_child(device_t dev, int order, const char *name, int unit)
+ppbus_add_child(device_t bus, device_t parent, int order, const char *name, int unit)
 {
        struct ppb_device *ppbdev;
        device_t child;
@@ -95,7 +95,7 @@ ppbus_add_child(device_t dev, int order, const char *name, int unit)
 
        /* add the device as a child to the ppbus bus with the allocated
         * ivars */
-       child = device_add_child_ordered(dev, order, name, unit);
+       child = device_add_child_ordered(parent, order, name, unit);
        device_set_ivars(child, ppbdev);
 
        return child;
index 80f83d5..5cce7b5 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *     $FreeBSD: src/sys/dev/acpica/acpi.c,v 1.157 2004/06/05 09:56:04 njl Exp $
- *     $DragonFly: src/sys/dev/acpica5/acpi.c,v 1.16 2005/10/30 04:20:49 y0netan1 Exp $
+ *     $DragonFly: src/sys/dev/acpica5/acpi.c,v 1.17 2005/10/30 04:41:15 dillon Exp $
  */
 
 #include "opt_acpi.h"
@@ -108,8 +108,8 @@ static int  acpi_probe(device_t dev);
 static int     acpi_attach(device_t dev);
 static int     acpi_shutdown(device_t dev);
 static void    acpi_quirks_set(void);
-static device_t        acpi_add_child(device_t bus, int order, const char *name,
-                       int unit);
+static device_t        acpi_add_child(device_t bus, device_t parent, int order,
+                       const char *name, int unit);
 static int     acpi_print_child(device_t bus, device_t child);
 static int     acpi_read_ivar(device_t dev, device_t child, int index,
                        uintptr_t *result);
@@ -337,7 +337,7 @@ acpi_identify(driver_t *driver, device_t parent)
     snprintf(acpi_ca_version, sizeof(acpi_ca_version), "%#x", ACPI_CA_VERSION);
 
     /* Attach the actual ACPI device. */
-    if ((child = BUS_ADD_CHILD(parent, 0, "acpi", 0)) == NULL) {
+    if ((child = BUS_ADD_CHILD(parent, parent, 0, "acpi", 0)) == NULL) {
        device_printf(parent, "ACPI: could not attach\n");
        return (ENXIO);
     }
@@ -694,7 +694,8 @@ out:
  * Handle a new device being added
  */
 static device_t
-acpi_add_child(device_t bus, int order, const char *name, int unit)
+acpi_add_child(device_t bus, device_t parent, int order,
+               const char *name, int unit)
 {
     struct acpi_device *ad;
     device_t           child;
@@ -703,7 +704,7 @@ acpi_add_child(device_t bus, int order, const char *name, int unit)
 
     resource_list_init(&ad->ad_rl);
 
-    child = device_add_child_ordered(bus, order, name, unit);
+    child = device_add_child_ordered(parent, order, name, unit);
     if (child != NULL)
        device_set_ivars(child, ad);
     return (child);
@@ -1140,7 +1141,7 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
             */
            ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "scanning '%s'\n",
                             acpi_name(handle)));
-           child = BUS_ADD_CHILD(bus, level * 10, NULL, -1);
+           child = BUS_ADD_CHILD(bus, bus, level * 10, NULL, -1);
            if (child == NULL)
                break;
            acpi_set_handle(child, handle);
index cc44d83..362f711 100644 (file)
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/acpica/acpi_ec.c,v 1.51 2004/05/30 20:08:23 phk Exp $
- * $DragonFly: src/sys/dev/acpica5/acpi_ec.c,v 1.5 2005/03/06 05:39:26 y0netan1 Exp $
+ * $DragonFly: src/sys/dev/acpica5/acpi_ec.c,v 1.6 2005/10/30 04:41:15 dillon Exp $
  */
 /******************************************************************************
  *
  *****************************************************************************/
  /*
   * $FreeBSD: src/sys/dev/acpica/acpi_ec.c,v 1.51 2004/05/30 20:08:23 phk Exp $
-  * $DragonFly: src/sys/dev/acpica5/acpi_ec.c,v 1.5 2005/03/06 05:39:26 y0netan1 Exp $
+  * $DragonFly: src/sys/dev/acpica5/acpi_ec.c,v 1.6 2005/10/30 04:41:15 dillon Exp $
   *
   */
 
@@ -385,7 +385,7 @@ acpi_ec_ecdt_probe(device_t parent)
     }
 
     /* Create the child device with the given unit number. */
-    child = BUS_ADD_CHILD(parent, 0, "acpi_ec", ecdt->uid);
+    child = BUS_ADD_CHILD(parent, parent, 0, "acpi_ec", ecdt->uid);
     if (child == NULL) {
        printf("%s: can't add child\n", __func__);
        return;
index 3bf22c7..52b5846 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/acpica/acpi_pci.c,v 1.16 2004/05/29 04:32:50 njl Exp $
- * $DragonFly: src/sys/dev/acpica5/acpi_pci.c,v 1.3 2004/07/05 00:07:35 dillon Exp $
+ * $DragonFly: src/sys/dev/acpica5/acpi_pci.c,v 1.4 2005/10/30 04:41:15 dillon Exp $
  */
 
 #include "opt_bus.h"
@@ -242,8 +242,7 @@ acpi_pci_save_handle(ACPI_HANDLE handle, UINT32 level, void *context,
 static int
 acpi_pci_probe(device_t dev)
 {
-
-       if (pcib_get_bus(dev) < 0)
+       if (pcib_get_bus(device_get_parent(dev)) < 0)
                return (ENXIO);
        if (acpi_get_handle(dev) == NULL)
                return (ENXIO);
@@ -262,7 +261,7 @@ acpi_pci_attach(device_t dev)
         * number to decide what bus we are probing. We ask the parent 
         * pcib what our bus number is.
         */
-       busno = pcib_get_bus(dev);
+       busno = pcib_get_bus(device_get_parent(dev));
        if (bootverbose)
                device_printf(dev, "physical bus=%d\n", busno);
 
index 6718491..ed1530e 100644 (file)
@@ -25,7 +25,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/acpica/acpi_timer.c,v 1.33 2004/05/30 20:08:23 phk Exp $
- * $DragonFly: src/sys/dev/acpica5/acpi_timer.c,v 1.6 2005/10/28 03:25:37 dillon Exp $
+ * $DragonFly: src/sys/dev/acpica5/acpi_timer.c,v 1.7 2005/10/30 04:41:15 dillon Exp $
  */
 #include "opt_acpi.h"
 #include <sys/param.h>
@@ -137,7 +137,7 @@ acpi_timer_identify(driver_t *driver, device_t parent)
     if (acpi_disabled("timer") || AcpiGbl_FADT == NULL)
        return (ENXIO);
 
-    if ((dev = BUS_ADD_CHILD(parent, 0, "acpi_timer", 0)) == NULL) {
+    if ((dev = BUS_ADD_CHILD(parent, parent, 0, "acpi_timer", 0)) == NULL) {
        device_printf(parent, "could not add acpi_timer0\n");
        return (ENXIO);
     }
index a04702a..06b15c1 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  *     $FreeBSD: src/sys/isa/orm.c,v 1.1.2.1 2001/06/19 05:48:29 imp Exp $
- *     $DragonFly: src/sys/dev/misc/orm/orm.c,v 1.4 2005/10/28 03:25:47 dillon Exp $
+ *     $DragonFly: src/sys/dev/misc/orm/orm.c,v 1.5 2005/10/30 04:41:15 dillon Exp $
  */
 
 /*
@@ -100,7 +100,7 @@ orm_identify(driver_t* driver, device_t parent)
        /*
         * Otherwise see if it exists
         */
-       child = BUS_ADD_CHILD(parent, ISA_ORDER_SENSITIVE, "orm", -1);
+       child = BUS_ADD_CHILD(parent, parent, ISA_ORDER_SENSITIVE, "orm", -1);
        device_set_driver(child, driver);
        isa_set_logicalid(child, ORM_ID);
        isa_set_vendorid(child, ORM_ID);
index 87d28fb..efad310 100644 (file)
@@ -28,7 +28,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/ep/if_ep_isa.c,v 1.8.2.1 2000/12/16 03:47:57 nyan Exp $
- * $DragonFly: src/sys/dev/netif/ep/if_ep_isa.c,v 1.8 2005/10/28 03:25:51 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/ep/if_ep_isa.c,v 1.9 2005/10/30 04:41:15 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -262,7 +262,8 @@ ep_isa_identify (driver_t *driver, device_t parent)
                        continue;
                }
 
-               child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ep", -1);
+               child = BUS_ADD_CHILD(parent, parent,
+                                     ISA_ORDER_SPECULATIVE, "ep", -1);
                device_set_desc_copy(child, desc);
                device_set_driver(child, driver);
                bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
index cedcc43..86fc2f8 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  *     $FreeBSD: src/sys/dev/ex/if_ex_isa.c,v 1.3.2.1 2001/03/05 05:33:20 imp Exp $
- *     $DragonFly: src/sys/dev/netif/ex/if_ex_isa.c,v 1.9 2005/10/28 03:25:52 dillon Exp $
+ *     $DragonFly: src/sys/dev/netif/ex/if_ex_isa.c,v 1.10 2005/10/30 04:41:15 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -177,7 +177,8 @@ ex_isa_identify (driver_t *driver, device_t parent)
                        desc = "Intel Pro/10";
                }
 
-               child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ex", -1);
+               child = BUS_ADD_CHILD(parent, parent,
+                                     ISA_ORDER_SPECULATIVE, "ex", -1);
                device_set_desc_copy(child, desc);
                device_set_driver(child, driver);
                bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
index 2d43213..6caaba8 100644 (file)
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/sound/isa/es1888.c,v 1.5.2.5 2002/04/22 15:49:30 cg Exp $
- * $DragonFly: src/sys/dev/sound/isa/Attic/es1888.c,v 1.3 2005/10/28 03:25:55 dillon Exp $
+ * $DragonFly: src/sys/dev/sound/isa/Attic/es1888.c,v 1.4 2005/10/30 04:41:15 dillon Exp $
  */
 
 #include <dev/sound/pcm/sound.h>
 #include <dev/sound/isa/sb.h>
 
-SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/isa/Attic/es1888.c,v 1.3 2005/10/28 03:25:55 dillon Exp $");
+SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/isa/Attic/es1888.c,v 1.4 2005/10/30 04:41:15 dillon Exp $");
 
 #ifdef __alpha__
 static int
@@ -155,7 +155,7 @@ es1888_identify(driver_t *driver, device_t parent)
        /*
         * Create the device and program its resources.
         */
-       dev = BUS_ADD_CHILD(parent, ISA_ORDER_PNP, NULL, -1);
+       dev = BUS_ADD_CHILD(parent, parent, ISA_ORDER_PNP, NULL, -1);
        bus_set_resource(dev, SYS_RES_IOPORT, 0, 0x220, 0x10);
        bus_set_resource(dev, SYS_RES_IRQ, 0, 5, 1);
        bus_set_resource(dev, SYS_RES_DRQ, 0, 1, 1);
index 3eab8a1..fcb0f08 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/i386/nexus.c,v 1.26.2.10 2003/02/22 13:16:45 imp Exp $
- * $DragonFly: src/sys/i386/i386/Attic/nexus.c,v 1.19 2005/10/28 03:25:57 dillon Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/nexus.c,v 1.20 2005/10/30 04:41:15 dillon Exp $
  */
 
 /*
@@ -80,8 +80,8 @@ static        int nexus_probe(device_t);
 static int nexus_attach(device_t);
 static int nexus_print_all_resources(device_t dev);
 static int nexus_print_child(device_t, device_t);
-static device_t nexus_add_child(device_t bus, int order, const char *name,
-                               int unit);
+static device_t nexus_add_child(device_t bus, device_t parent, int order,
+                               const char *name, int unit);
 static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
                                              u_long, u_long, u_long, u_int);
 static int nexus_read_ivar(device_t, device_t, int, uintptr_t *);
@@ -145,19 +145,6 @@ DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
 static int
 nexus_probe(device_t dev)
 {
-#if 0  /* FUTURE */
-       device_t acpi;
-#endif
-
-#if 0  /* FUTURE */
-       /*
-        * Fail to probe if ACPI is ok.
-        */
-       acpi = devclass_get_device(devclass_find("acpi"), 0);
-       if (acpi != NULL && device_is_alive(acpi))
-               return(ENXIO);
-#endif
-
        device_quiet(dev);      /* suppress attach message for neatness */
 
        /*
@@ -244,13 +231,13 @@ nexus_attach(device_t dev)
         * connection points now so they show up "on motherboard".
         */
        if (!devclass_get_device(devclass_find("eisa"), 0)) {
-               child = BUS_ADD_CHILD(dev, 0, "eisa", 0);
+               child = BUS_ADD_CHILD(dev, dev, 0, "eisa", 0);
                if (child == NULL)
                        panic("nexus_attach eisa");
                device_probe_and_attach(child);
        }
        if (!devclass_get_device(devclass_find("isa"), 0)) {
-               child = BUS_ADD_CHILD(dev, 0, "isa", 0);
+               child = BUS_ADD_CHILD(dev, dev, 0, "isa", 0);
                if (child == NULL)
                        panic("nexus_attach isa");
                device_probe_and_attach(child);
@@ -292,7 +279,8 @@ nexus_print_child(device_t bus, device_t child)
 }
 
 static device_t
-nexus_add_child(device_t bus, int order, const char *name, int unit)
+nexus_add_child(device_t bus, device_t parent, int order,
+               const char *name, int unit)
 {
        device_t                child;
        struct nexus_device     *ndev;
@@ -303,7 +291,7 @@ nexus_add_child(device_t bus, int order, const char *name, int unit)
        resource_list_init(&ndev->nx_resources);
        ndev->nx_pcibus = -1;
 
-       child = device_add_child_ordered(bus, order, name, unit); 
+       child = device_add_child_ordered(parent, order, name, unit); 
 
        /* should we free this in nexus_child_detached? */
        device_set_ivars(child, ndev);
@@ -498,16 +486,12 @@ nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
                panic("nexus_setup_intr: NULL irq resource!");
 
        *cookiep = 0;
-       if (irq->r_flags & RF_SHAREABLE)
-               icflags = 0;
-       else
-               icflags = INTR_EXCL;
+       icflags = flags;
+       if ((irq->r_flags & RF_SHAREABLE) == 0)
+               icflags |= INTR_EXCL;
 
        driver = device_get_driver(child);
 
-       if (flags & INTR_FAST)
-               icflags |= INTR_FAST;
-
        /*
         * We depend here on rman_activate_resource() being idempotent.
         */
index 6b8c812..ec4e080 100644 (file)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/i386/i386/Attic/pnpbios.c,v 1.3 2005/10/28 03:25:57 dillon Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/pnpbios.c,v 1.4 2005/10/30 04:41:15 dillon Exp $
  */
 
 /*
@@ -177,7 +177,7 @@ pnpbios_identify(driver_t *driver, device_t parent)
            continue;
 
        /* Add the device and parse its resources */
-       dev = BUS_ADD_CHILD(parent, ISA_ORDER_PNP, NULL, -1);
+       dev = BUS_ADD_CHILD(parent, parent, ISA_ORDER_PNP, NULL, -1);
        isa_set_vendorid(dev, pd->devid);
        isa_set_logicalid(dev, pd->devid);
 
index 5f76af3..6fb1938 100644 (file)
@@ -24,7 +24,7 @@
 # SUCH DAMAGE.
 #
 # $FreeBSD: src/sys/kern/bus_if.m,v 1.16 1999/10/12 21:35:50 dfr Exp $
-# $DragonFly: src/sys/kern/bus_if.m,v 1.7 2005/05/24 20:58:41 dillon Exp $
+# $DragonFly: src/sys/kern/bus_if.m,v 1.8 2005/10/30 04:41:15 dillon Exp $
 #
 
 #include <sys/bus.h>
@@ -124,8 +124,13 @@ METHOD void driver_added {
 # device instances. If place is non-NULL, the new device will be
 # added after the last existing child with the same order.
 #
+# bus is an entity which may iterate up through the bus heirarchy
+# while parent is the parent device under which the child should be
+# added.
+#
 METHOD device_t add_child {
-       device_t dev;
+       device_t bus;
+       device_t parent;
        int order;
        const char *name;
        int unit;
index 6bbf073..b9e0adb 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/kern/subr_bus.c,v 1.54.2.9 2002/10/10 15:13:32 jhb Exp $
- * $DragonFly: src/sys/kern/subr_bus.c,v 1.28 2005/10/28 03:25:57 dillon Exp $
+ * $DragonFly: src/sys/kern/subr_bus.c,v 1.29 2005/10/30 04:41:15 dillon Exp $
  */
 
 #include "opt_bus.h"
@@ -152,6 +152,16 @@ devclass_find(const char *classname)
        return(devclass_find_internal(classname, NULL, FALSE));
 }
 
+device_t
+devclass_find_unit(const char *classname, int unit)
+{
+       devclass_t dc;
+
+       if ((dc = devclass_find(classname)) != NULL)
+           return(devclass_get_device(dc, unit));
+       return (NULL);
+}
+
 int
 devclass_add_driver(devclass_t dc, driver_t *driver)
 {
@@ -1807,7 +1817,7 @@ bus_generic_identify(driver_t *driver, device_t parent)
 {
        if (parent->state == DS_ATTACHED)
                return (0);
-       BUS_ADD_CHILD(parent, 0, driver->name, -1);
+       BUS_ADD_CHILD(parent, parent, 0, driver->name, -1);
        return (0);
 }
 
@@ -1816,7 +1826,7 @@ bus_generic_identify_sameunit(driver_t *driver, device_t parent)
 {
        if (parent->state == DS_ATTACHED)
                return (0);
-       BUS_ADD_CHILD(parent, 0, driver->name, device_get_unit(parent));
+       BUS_ADD_CHILD(parent, parent, 0, driver->name, device_get_unit(parent));
        return (0);
 }
 
@@ -1950,6 +1960,18 @@ bus_print_child_footer(device_t dev, device_t child)
        return(printf(" on %s\n", device_get_nameunit(dev)));
 }
 
+device_t
+bus_generic_add_child(device_t dev, device_t child, int order,
+                     const char *name, int unit)
+{
+       if (dev->parent)
+               dev = BUS_ADD_CHILD(dev->parent, child, order, name, unit);
+       else
+               dev = device_add_child_ordered(child, order, name, unit);
+       return(dev);
+               
+}
+
 int
 bus_generic_print_child(device_t dev, device_t child)
 {
@@ -1965,20 +1987,38 @@ int
 bus_generic_read_ivar(device_t dev, device_t child, int index, 
                      uintptr_t * result)
 {
-    return(ENOENT);
+       int error;
+
+       if (dev->parent)
+               error = BUS_READ_IVAR(dev->parent, child, index, result);
+       else
+               error = ENOENT;
+       return (error);
 }
 
 int
 bus_generic_write_ivar(device_t dev, device_t child, int index, 
                       uintptr_t value)
 {
-    return(ENOENT);
+       int error;
+
+       if (dev->parent)
+               error = BUS_WRITE_IVAR(dev->parent, child, index, value);
+       else
+               error = ENOENT;
+       return (error);
 }
 
 struct resource_list *
 bus_generic_get_resource_list(device_t dev, device_t child)
 {
-    return(NULL);
+       struct resource_list *rl;
+
+       if (dev->parent)
+               rl = BUS_GET_RESOURCE_LIST(dev->parent, child);
+       else
+               rl = NULL;
+       return (rl);
 }
 
 void
@@ -2033,6 +2073,17 @@ bus_generic_enable_intr(device_t dev, device_t child, void *cookie)
                BUS_ENABLE_INTR(dev->parent, child, cookie);
 }
 
+int
+bus_generic_config_intr(device_t dev, int irq, enum intr_trigger trig,
+    enum intr_polarity pol)
+{
+       /* Propagate up the bus hierarchy until someone handles it. */
+       if (dev->parent)
+               return(BUS_CONFIG_INTR(dev->parent, irq, trig, pol));
+       else
+               return(EINVAL);
+}
+
 struct resource *
 bus_generic_alloc_resource(device_t dev, device_t child, int type, int *rid,
                           u_long start, u_long end, u_long count, u_int flags)
@@ -2080,14 +2131,38 @@ bus_generic_deactivate_resource(device_t dev, device_t child, int type,
 }
 
 int
-bus_generic_config_intr(device_t dev, int irq, enum intr_trigger trig,
-    enum intr_polarity pol)
+bus_generic_get_resource(device_t dev, device_t child, int type, int rid,
+                        u_long *startp, u_long *countp)
+{
+       int error;
+
+       error = ENOENT;
+       if (dev->parent) {
+               error = BUS_GET_RESOURCE(dev->parent, child, type, rid, 
+                                        startp, countp);
+       }
+       return (error);
+}
+
+int
+bus_generic_set_resource(device_t dev, device_t child, int type, int rid,
+                       u_long start, u_long count)
+{
+       int error;
+
+       error = EINVAL;
+       if (dev->parent) {
+               error = BUS_SET_RESOURCE(dev->parent, child, type, rid, 
+                                        start, count);
+       }
+       return (error);
+}
+
+void
+bus_generic_delete_resource(device_t dev, device_t child, int type, int rid)
 {
-       /* Propagate up the bus hierarchy until someone handles it. */
        if (dev->parent)
-               return(BUS_CONFIG_INTR(dev->parent, irq, trig, pol));
-       else
-               return(EINVAL);
+               BUS_DELETE_RESOURCE(dev, child, type, rid);
 }
 
 int
@@ -2369,7 +2444,7 @@ static kobj_method_t root_methods[] = {
        KOBJMETHOD(device_resume,       bus_generic_resume),
 
        /* Bus interface */
-       KOBJMETHOD(bus_add_child,       device_add_child_ordered),
+       KOBJMETHOD(bus_add_child,       bus_generic_add_child),
        KOBJMETHOD(bus_print_child,     root_print_child),
        KOBJMETHOD(bus_read_ivar,       bus_generic_read_ivar),
        KOBJMETHOD(bus_write_ivar,      bus_generic_write_ivar),
index aeca720..e2adcd6 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/i386/nexus.c,v 1.26.2.10 2003/02/22 13:16:45 imp Exp $
- * $DragonFly: src/sys/platform/pc32/i386/nexus.c,v 1.19 2005/10/28 03:25:57 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/nexus.c,v 1.20 2005/10/30 04:41:15 dillon Exp $
  */
 
 /*
@@ -80,8 +80,8 @@ static        int nexus_probe(device_t);
 static int nexus_attach(device_t);
 static int nexus_print_all_resources(device_t dev);
 static int nexus_print_child(device_t, device_t);
-static device_t nexus_add_child(device_t bus, int order, const char *name,
-                               int unit);
+static device_t nexus_add_child(device_t bus, device_t parent, int order,
+                               const char *name, int unit);
 static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
                                              u_long, u_long, u_long, u_int);
 static int nexus_read_ivar(device_t, device_t, int, uintptr_t *);
@@ -145,19 +145,6 @@ DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
 static int
 nexus_probe(device_t dev)
 {
-#if 0  /* FUTURE */
-       device_t acpi;
-#endif
-
-#if 0  /* FUTURE */
-       /*
-        * Fail to probe if ACPI is ok.
-        */
-       acpi = devclass_get_device(devclass_find("acpi"), 0);
-       if (acpi != NULL && device_is_alive(acpi))
-               return(ENXIO);
-#endif
-
        device_quiet(dev);      /* suppress attach message for neatness */
 
        /*
@@ -244,13 +231,13 @@ nexus_attach(device_t dev)
         * connection points now so they show up "on motherboard".
         */
        if (!devclass_get_device(devclass_find("eisa"), 0)) {
-               child = BUS_ADD_CHILD(dev, 0, "eisa", 0);
+               child = BUS_ADD_CHILD(dev, dev, 0, "eisa", 0);
                if (child == NULL)
                        panic("nexus_attach eisa");
                device_probe_and_attach(child);
        }
        if (!devclass_get_device(devclass_find("isa"), 0)) {
-               child = BUS_ADD_CHILD(dev, 0, "isa", 0);
+               child = BUS_ADD_CHILD(dev, dev, 0, "isa", 0);
                if (child == NULL)
                        panic("nexus_attach isa");
                device_probe_and_attach(child);
@@ -292,7 +279,8 @@ nexus_print_child(device_t bus, device_t child)
 }
 
 static device_t
-nexus_add_child(device_t bus, int order, const char *name, int unit)
+nexus_add_child(device_t bus, device_t parent, int order,
+               const char *name, int unit)
 {
        device_t                child;
        struct nexus_device     *ndev;
@@ -303,7 +291,7 @@ nexus_add_child(device_t bus, int order, const char *name, int unit)
        resource_list_init(&ndev->nx_resources);
        ndev->nx_pcibus = -1;
 
-       child = device_add_child_ordered(bus, order, name, unit); 
+       child = device_add_child_ordered(parent, order, name, unit); 
 
        /* should we free this in nexus_child_detached? */
        device_set_ivars(child, ndev);
@@ -498,16 +486,12 @@ nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
                panic("nexus_setup_intr: NULL irq resource!");
 
        *cookiep = 0;
-       if (irq->r_flags & RF_SHAREABLE)
-               icflags = 0;
-       else
-               icflags = INTR_EXCL;
+       icflags = flags;
+       if ((irq->r_flags & RF_SHAREABLE) == 0)
+               icflags |= INTR_EXCL;
 
        driver = device_get_driver(child);
 
-       if (flags & INTR_FAST)
-               icflags |= INTR_FAST;
-
        /*
         * We depend here on rman_activate_resource() being idempotent.
         */
index 37e651c..a7e53b2 100644 (file)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/platform/pc32/i386/pnpbios.c,v 1.3 2005/10/28 03:25:57 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/pnpbios.c,v 1.4 2005/10/30 04:41:15 dillon Exp $
  */
 
 /*
@@ -177,7 +177,7 @@ pnpbios_identify(driver_t *driver, device_t parent)
            continue;
 
        /* Add the device and parse its resources */
-       dev = BUS_ADD_CHILD(parent, ISA_ORDER_PNP, NULL, -1);
+       dev = BUS_ADD_CHILD(parent, parent, ISA_ORDER_PNP, NULL, -1);
        isa_set_vendorid(dev, pd->devid);
        isa_set_logicalid(dev, pd->devid);
 
index a4a3631..73d297b 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/sys/bus.h,v 1.30.2.5 2004/03/17 17:54:25 njl Exp $
- * $DragonFly: src/sys/sys/bus.h,v 1.17 2005/10/28 03:25:57 dillon Exp $
+ * $DragonFly: src/sys/sys/bus.h,v 1.18 2005/10/30 04:41:15 dillon Exp $
  */
 
 #ifndef _SYS_BUS_H_
@@ -193,10 +193,17 @@ int       bus_generic_identify(driver_t *driver, device_t parent);
 int    bus_generic_identify_sameunit(driver_t *driver, device_t parent);
 int    bus_generic_probe(device_t dev);
 int    bus_generic_probe_hack(device_t dev);
+device_t bus_generic_add_child(device_t, device_t, int, const char *, int);
 int    bus_generic_read_ivar(device_t dev, device_t child, int which,
                              uintptr_t *result);
 int    bus_generic_release_resource(device_t bus, device_t child,
                                     int type, int rid, struct resource *r);
+int    bus_generic_get_resource(device_t dev, device_t child, int type, 
+                                    int rid, u_long *startp, u_long *countp);
+int    bus_generic_set_resource(device_t dev, device_t child, int type,
+                                    int rid, u_long start, u_long count);
+void   bus_generic_delete_resource(device_t dev, device_t child, 
+                                    int type, int rid);
 int    bus_generic_resume(device_t dev);
 int    bus_generic_setup_intr(device_t dev, device_t child,
                               struct resource *irq, int flags,
@@ -308,6 +315,7 @@ int devclass_add_driver(devclass_t dc, kobj_class_t driver);
 int    devclass_delete_driver(devclass_t dc, kobj_class_t driver);
 devclass_t     devclass_create(const char *classname);
 devclass_t     devclass_find(const char *classname);
+device_t       devclass_find_unit(const char *classname, int unit);
 kobj_class_t   devclass_find_driver(devclass_t dc, const char *classname);
 const char     *devclass_get_name(devclass_t dc);
 device_t       devclass_get_device(devclass_t dc, int unit);