summaryrefslogtreecommitdiffstats
path: root/sys/isa/isa_common.c
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2000-06-25 09:19:02 +0000
committerdfr <dfr@FreeBSD.org>2000-06-25 09:19:02 +0000
commit398e95c5d2a73ce4a1a216fc23ede28349fcbeb3 (patch)
tree163406c9abac55a1a4487b2a76d77f6c6b328688 /sys/isa/isa_common.c
parentc740c026d9c94b58a2ff127870ff13c58df438e7 (diff)
downloadFreeBSD-src-398e95c5d2a73ce4a1a216fc23ede28349fcbeb3.zip
FreeBSD-src-398e95c5d2a73ce4a1a216fc23ede28349fcbeb3.tar.gz
Replace the unknown driver with a nomatch method in the isa driver.
This allows ISA PnP drivers to be dynamically loaded after the kernel has booted.
Diffstat (limited to 'sys/isa/isa_common.c')
-rw-r--r--sys/isa/isa_common.c141
1 files changed, 70 insertions, 71 deletions
diff --git a/sys/isa/isa_common.c b/sys/isa/isa_common.c
index c528b7b..4e8a624 100644
--- a/sys/isa/isa_common.c
+++ b/sys/isa/isa_common.c
@@ -501,8 +501,7 @@ isa_probe_children(device_t dev)
resource_list_alloc(rl, dev, child,
rle->type,
&rid,
- 0, ~0, 1,
- 0 /* !RF_ACTIVE */);
+ 0, ~0, 1, 0);
}
}
}
@@ -536,59 +535,85 @@ isa_add_child(device_t dev, int order, const char *name, int unit)
return child;
}
-static void
+static int
isa_print_resources(struct resource_list *rl, const char *name, int type,
int count, const char *format)
{
struct resource_list_entry *rle;
int printed;
- int i;
+ int i, retval = 0;;
printed = 0;
for (i = 0; i < count; i++) {
rle = resource_list_find(rl, type, i);
if (rle) {
if (printed == 0)
- printf(" %s ", name);
+ retval += printf(" %s ", name);
else if (printed > 0)
- printf(",");
+ retval += printf(",");
printed++;
- printf(format, rle->start);
+ retval += printf(format, rle->start);
if (rle->count > 1) {
- printf("-");
- printf(format, rle->start + rle->count - 1);
+ retval += printf("-");
+ retval += printf(format,
+ rle->start + rle->count - 1);
}
} else if (i > 3) {
/* check the first few regardless */
break;
}
}
+ return retval;
}
static int
-isa_print_child(device_t bus, device_t dev)
+isa_print_all_resources(device_t dev)
{
struct isa_device *idev = DEVTOISA(dev);
struct resource_list *rl = &idev->id_resources;
int retval = 0;
- retval += bus_print_child_header(bus, dev);
-
if (SLIST_FIRST(rl) || device_get_flags(dev))
retval += printf(" at");
- isa_print_resources(rl, "port", SYS_RES_IOPORT, ISA_NPORT, "%#lx");
- isa_print_resources(rl, "iomem", SYS_RES_MEMORY, ISA_NMEM, "%#lx");
- isa_print_resources(rl, "irq", SYS_RES_IRQ, ISA_NIRQ, "%ld");
- isa_print_resources(rl, "drq", SYS_RES_DRQ, ISA_NDRQ, "%ld");
+ retval += isa_print_resources(rl, "port", SYS_RES_IOPORT,
+ ISA_NPORT, "%#lx");
+ retval += isa_print_resources(rl, "iomem", SYS_RES_MEMORY,
+ ISA_NMEM, "%#lx");
+ retval += isa_print_resources(rl, "irq", SYS_RES_IRQ,
+ ISA_NIRQ, "%ld");
+ retval += isa_print_resources(rl, "drq", SYS_RES_DRQ,
+ ISA_NDRQ, "%ld");
if (device_get_flags(dev))
retval += printf(" flags %#x", device_get_flags(dev));
+ return retval;
+}
+
+static int
+isa_print_child(device_t bus, device_t dev)
+{
+ int retval = 0;
+
+ retval += bus_print_child_header(bus, dev);
+ retval += isa_print_all_resources(dev);
retval += bus_print_child_footer(bus, dev);
return (retval);
}
+static void
+isa_probe_nomatch(device_t dev, device_t child)
+{
+ device_printf(dev, "<%s> found",
+ pnp_eisaformat(isa_get_logicalid(child)));
+ if (bootverbose)
+ isa_print_all_resources(child);
+ printf("\n");
+
+ return;
+}
+
static int
isa_read_ivar(device_t bus, device_t dev, int index, uintptr_t * result)
{
@@ -771,12 +796,19 @@ isa_child_detached(device_t dev, device_t child)
struct resource_list *rl = &idev->id_resources;
struct resource_list_entry *rle;
- SLIST_FOREACH(rle, &idev->id_resources, link) {
- if (rle->res)
- resource_list_release(rl, dev, child,
- rle->type,
- rle->rid,
- rle->res);
+ if (TAILQ_FIRST(&idev->id_configs)) {
+ /*
+ * Claim any unallocated resources to keep other
+ * devices from using them.
+ */
+ SLIST_FOREACH(rle, rl, link) {
+ if (!rle->res) {
+ int rid = rle->rid;
+ resource_list_alloc(rl, dev, child,
+ rle->type,
+ &rid, 0, ~0, 1, 0);
+ }
+ }
}
}
@@ -807,6 +839,20 @@ isa_driver_added(device_t dev, driver_t *driver)
if (device_get_state(child) != DS_NOTPRESENT)
continue;
+ if (!device_is_enabled(child))
+ continue;
+
+ /*
+ * Free resources which we were holding on behalf of
+ * the device.
+ */
+ SLIST_FOREACH(rle, &idev->id_resources, link) {
+ if (rle->res)
+ resource_list_release(rl, dev, child,
+ rle->type,
+ rle->rid,
+ rle->res);
+ }
if (TAILQ_FIRST(&idev->id_configs))
if (!isa_assign_resources(child))
@@ -824,9 +870,7 @@ isa_driver_added(device_t dev, driver_t *driver)
int rid = rle->rid;
resource_list_alloc(rl, dev, child,
rle->type,
- &rid,
- 0, ~0, 1,
- 0 /* !RF_ACTIVE */);
+ &rid, 0, ~0, 1, 0);
}
}
}
@@ -961,6 +1005,7 @@ static device_method_t isa_methods[] = {
/* Bus interface */
DEVMETHOD(bus_add_child, isa_add_child),
DEVMETHOD(bus_print_child, isa_print_child),
+ DEVMETHOD(bus_probe_nomatch, isa_probe_nomatch),
DEVMETHOD(bus_read_ivar, isa_read_ivar),
DEVMETHOD(bus_write_ivar, isa_write_ivar),
DEVMETHOD(bus_child_detached, isa_child_detached),
@@ -996,49 +1041,3 @@ DRIVER_MODULE(isa, isab, isa_driver, isa_devclass, 0, 0);
#ifdef __i386__
DRIVER_MODULE(isa, nexus, isa_driver, isa_devclass, 0, 0);
#endif
-
-/*
- * A fallback driver for reporting un-matched pnp devices.
- */
-
-static int
-unknown_probe(device_t dev)
-{
- /*
- * Only match pnp devices.
- */
- if (isa_get_vendorid(dev) != 0)
- return -100;
- return ENXIO;
-}
-
-static int
-unknown_attach(device_t dev)
-{
- return 0;
-}
-
-static int
-unknown_detach(device_t dev)
-{
- return 0;
-}
-
-static device_method_t unknown_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, unknown_probe),
- DEVMETHOD(device_attach, unknown_attach),
- DEVMETHOD(device_detach, unknown_detach),
-
- { 0, 0 }
-};
-
-static driver_t unknown_driver = {
- "unknown",
- unknown_methods,
- 1, /* no softc */
-};
-
-static devclass_t unknown_devclass;
-
-DRIVER_MODULE(unknown, isa, unknown_driver, unknown_devclass, 0, 0);
OpenPOWER on IntegriCloud