aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/vmd/vmd_bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/vmd/vmd_bus.c')
-rw-r--r--sys/dev/vmd/vmd_bus.c73
1 files changed, 46 insertions, 27 deletions
diff --git a/sys/dev/vmd/vmd_bus.c b/sys/dev/vmd/vmd_bus.c
index 74a6faa812b1..5eed6176630f 100644
--- a/sys/dev/vmd/vmd_bus.c
+++ b/sys/dev/vmd/vmd_bus.c
@@ -71,32 +71,45 @@ vmd_bus_attach(device_t dev)
struct pci_devinfo *dinfo;
rman_res_t start, end;
int b, s, f;
+ int found;
sc = device_get_softc(device_get_parent(dev));
- /* Start at max PCI vmd_domain and work down */
- b = s = f = 0;
- dinfo = pci_read_device(device_get_parent(dev), dev,
- PCI_DOMAINMAX - device_get_unit(device_get_parent(dev)),
- b, s, f);
- if (dinfo == NULL) {
- device_printf(dev, "Cannot allocate dinfo!\n");
- return (ENOENT);
+ /*
+ * Start at max PCI vmd_domain and work down. Only VMD
+ * starting bus is connect to VMD device directly. Scan al
+ * lslots and function connected to starting bus.
+ */
+
+ b = sc->vmd_bus_start;
+
+ found = 0;
+ for (s = 0; s < PCI_SLOTMAX; s++) {
+ for (f = 0; f < PCI_FUNCMAX; f++) {
+ dinfo = pci_read_device(device_get_parent(dev), dev,
+ PCI_DOMAINMAX - device_get_unit(
+ device_get_parent(dev)), b, s, f);
+ if (dinfo != NULL) {
+ found = 1;
+ pci_add_child(dev, dinfo);
+
+ start = rman_get_start(sc->vmd_regs_resource[1]);
+ end = rman_get_end(sc->vmd_regs_resource[1]);
+ resource_list_add_next(&dinfo->resources,
+ SYS_RES_MEMORY, start, end, end - start + 1);
+
+ start = rman_get_start(sc->vmd_io_resource);
+ end = rman_get_end(sc->vmd_io_resource);
+ resource_list_add_next(&dinfo->resources,
+ SYS_RES_IOPORT, start, end, end - start + 1);
+
+ }
+ }
}
- pci_add_child(dev, dinfo);
-
- start = rman_get_start(sc->vmd_regs_resource[1]);
- end = rman_get_end(sc->vmd_regs_resource[1]);
- resource_list_add_next(&dinfo->resources, SYS_RES_MEMORY, start, end,
- end - start + 1);
-
- start = rman_get_start(sc->vmd_io_resource);
- end = rman_get_end(sc->vmd_io_resource);
- resource_list_add_next(&dinfo->resources, SYS_RES_IOPORT, start, end,
- end - start + 1);
-
- bus_generic_attach(dev);
+ if (found) {
+ bus_generic_attach(dev);
+ }
return (0);
}
@@ -104,17 +117,23 @@ vmd_bus_attach(device_t dev)
static int
vmd_bus_detach(device_t dev)
{
+ struct vmd_softc *sc;
struct pci_devinfo *dinfo;
int b, s, f;
device_delete_children(dev);
- b = s = f = 0;
- dinfo = pci_read_device(device_get_parent(dev), dev,
- PCI_DOMAINMAX - device_get_unit(device_get_parent(dev)),
- b, s, f);
- if (dinfo == NULL) {
- resource_list_free(&dinfo->resources);
+ sc = device_get_softc(device_get_parent(dev));
+ b = sc->vmd_bus_start;
+
+ for (s = 0; s < PCI_SLOTMAX; s++) {
+ for (f = 0; f < PCI_FUNCMAX; f++) {
+ dinfo = pci_read_device(device_get_parent(dev), dev,
+ PCI_DOMAINMAX - device_get_unit(
+ device_get_parent(dev)), b, s, f);
+ if (dinfo != NULL)
+ resource_list_free(&dinfo->resources);
+ }
}
return (0);
}