From c2251260be90b098d300f1452cc5cb46c5032282 Mon Sep 17 00:00:00 2001 From: jhb Date: Tue, 18 Nov 2008 21:01:54 +0000 Subject: 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 --- sys/kern/subr_bus.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'sys/kern/subr_bus.c') 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); -- cgit v1.1