summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_bus.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2008-11-18 21:01:54 +0000
committerjhb <jhb@FreeBSD.org>2008-11-18 21:01:54 +0000
commitc2251260be90b098d300f1452cc5cb46c5032282 (patch)
tree9f64d56b3288179bc04a3f77b610240093f70345 /sys/kern/subr_bus.c
parent7a676b30d156207340caf73e0c93ff42db650ffb (diff)
downloadFreeBSD-src-c2251260be90b098d300f1452cc5cb46c5032282.zip
FreeBSD-src-c2251260be90b098d300f1452cc5cb46c5032282.tar.gz
Allow device hints to wire the unit numbers of devices.
- An "at" hint now reserves a device name. - A new BUS_HINT_DEVICE_UNIT method is added to the bus interface. When determining the unit number of a device, this method is invoked to let the bus driver specify the unit of a device given a specific devclass. This is the only way a device can be given a name reserved via an "at" hint. - Implement BUS_HINT_DEVICE_UNIT() for the acpi(4) and isa(4) bus drivers. Both of these busses implement this by comparing the resources for a given hint device with the resources enumerated by ACPI/PnPBIOS and wire a unit if the hint resources are a subset of the "real" resources. - Use bus_hinted_children() for adding hinted devices on isa(4) busses now instead of doing it by hand. - Remove the unit kludging from sio(4) as it is no longer necessary. Prodding from: peter, imp OK'd by: marcel MFC after: 1 month
Diffstat (limited to 'sys/kern/subr_bus.c')
-rw-r--r--sys/kern/subr_bus.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 93a589a2..10fc81a 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -1315,12 +1315,18 @@ devclass_get_sysctl_tree(devclass_t dc)
* @retval ENOMEM memory allocation failure
*/
static int
-devclass_alloc_unit(devclass_t dc, int *unitp)
+devclass_alloc_unit(devclass_t dc, device_t dev, int *unitp)
{
+ const char *s;
int unit = *unitp;
PDEBUG(("unit %d in devclass %s", unit, DEVCLANAME(dc)));
+ /* Ask the parent bus if it wants to wire this device. */
+ if (unit == -1)
+ BUS_HINT_DEVICE_UNIT(device_get_parent(dev), dev, dc->name,
+ &unit);
+
/* If we were given a wired unit number, check for existing device */
/* XXX imp XXX */
if (unit != -1) {
@@ -1334,8 +1340,18 @@ devclass_alloc_unit(devclass_t dc, int *unitp)
} else {
/* Unwired device, find the next available slot for it */
unit = 0;
- while (unit < dc->maxunit && dc->devices[unit] != NULL)
- unit++;
+ for (unit = 0;; unit++) {
+ /* If there is an "at" hint for a unit then skip it. */
+ if (resource_string_value(dc->name, unit, "at", &s) ==
+ 0)
+ continue;
+
+ /* If this device slot is already in use, skip it. */
+ if (unit < dc->maxunit && dc->devices[unit] != NULL)
+ continue;
+
+ break;
+ }
}
/*
@@ -1397,7 +1413,7 @@ devclass_add_device(devclass_t dc, device_t dev)
if (!dev->nameunit)
return (ENOMEM);
- if ((error = devclass_alloc_unit(dc, &dev->unit)) != 0) {
+ if ((error = devclass_alloc_unit(dc, dev, &dev->unit)) != 0) {
free(dev->nameunit, M_BUS);
dev->nameunit = NULL;
return (error);
OpenPOWER on IntegriCloud