Changeset View
Standalone View
sys/kern/subr_bus.c
Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||||||||||
struct devclass { | struct devclass { | ||||||||||||
TAILQ_ENTRY(devclass) link; | TAILQ_ENTRY(devclass) link; | ||||||||||||
devclass_t parent; /* parent in devclass hierarchy */ | devclass_t parent; /* parent in devclass hierarchy */ | ||||||||||||
driver_list_t drivers; /* bus devclasses store drivers for bus */ | driver_list_t drivers; /* bus devclasses store drivers for bus */ | ||||||||||||
char *name; | char *name; | ||||||||||||
device_t *devices; /* array of devices indexed by unit */ | device_t *devices; /* array of devices indexed by unit */ | ||||||||||||
int maxunit; /* size of devices array */ | int maxunit; /* size of devices array */ | ||||||||||||
int probe_bias; /* User configured "bonus" for probe order */ | |||||||||||||
int flags; | int flags; | ||||||||||||
#define DC_HAS_CHILDREN 1 | #define DC_HAS_CHILDREN 1 | ||||||||||||
struct sysctl_ctx_list sysctl_ctx; | struct sysctl_ctx_list sysctl_ctx; | ||||||||||||
struct sysctl_oid *sysctl_tree; | struct sysctl_oid *sysctl_tree; | ||||||||||||
}; | }; | ||||||||||||
/** | /** | ||||||||||||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | devclass_sysctl_init(devclass_t dc) | ||||||||||||
dc->sysctl_tree = SYSCTL_ADD_NODE(&dc->sysctl_ctx, | dc->sysctl_tree = SYSCTL_ADD_NODE(&dc->sysctl_ctx, | ||||||||||||
SYSCTL_STATIC_CHILDREN(_dev), OID_AUTO, dc->name, | SYSCTL_STATIC_CHILDREN(_dev), OID_AUTO, dc->name, | ||||||||||||
CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, ""); | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, ""); | ||||||||||||
SYSCTL_ADD_PROC(&dc->sysctl_ctx, SYSCTL_CHILDREN(dc->sysctl_tree), | SYSCTL_ADD_PROC(&dc->sysctl_ctx, SYSCTL_CHILDREN(dc->sysctl_tree), | ||||||||||||
OID_AUTO, "%parent", | OID_AUTO, "%parent", | ||||||||||||
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, | CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, | ||||||||||||
dc, DEVCLASS_SYSCTL_PARENT, devclass_sysctl_handler, "A", | dc, DEVCLASS_SYSCTL_PARENT, devclass_sysctl_handler, "A", | ||||||||||||
"parent class"); | "parent class"); | ||||||||||||
SYSCTL_ADD_INT(&dc->sysctl_ctx, | |||||||||||||
SYSCTL_CHILDREN(dc->sysctl_tree), OID_AUTO, "%probe_bias", | |||||||||||||
CTLFLAG_RWTUN | CTLFLAG_MPSAFE, &dc->probe_bias, 0, | |||||||||||||
"Bonus added probe values"); | |||||||||||||
} | } | ||||||||||||
enum { | enum { | ||||||||||||
DEVICE_SYSCTL_DESC, | DEVICE_SYSCTL_DESC, | ||||||||||||
DEVICE_SYSCTL_DRIVER, | DEVICE_SYSCTL_DRIVER, | ||||||||||||
DEVICE_SYSCTL_LOCATION, | DEVICE_SYSCTL_LOCATION, | ||||||||||||
DEVICE_SYSCTL_PNPINFO, | DEVICE_SYSCTL_PNPINFO, | ||||||||||||
DEVICE_SYSCTL_PARENT, | DEVICE_SYSCTL_PARENT, | ||||||||||||
▲ Show 20 Lines • Show All 1,350 Lines • ▼ Show 20 Lines | |||||||||||||
* @internal | * @internal | ||||||||||||
*/ | */ | ||||||||||||
int | int | ||||||||||||
device_probe_child(device_t dev, device_t child) | device_probe_child(device_t dev, device_t child) | ||||||||||||
{ | { | ||||||||||||
devclass_t dc; | devclass_t dc; | ||||||||||||
driverlink_t best = NULL; | driverlink_t best = NULL; | ||||||||||||
driverlink_t dl; | driverlink_t dl; | ||||||||||||
int result, pri = 0; | int result, bias, pri = 0; | ||||||||||||
/* We should preserve the devclass (or lack of) set by the bus. */ | /* We should preserve the devclass (or lack of) set by the bus. */ | ||||||||||||
int hasclass = (child->devclass != NULL); | int hasclass = (child->devclass != NULL); | ||||||||||||
bus_topo_assert(); | bus_topo_assert(); | ||||||||||||
dc = dev->devclass; | dc = dev->devclass; | ||||||||||||
if (!dc) | if (!dc) | ||||||||||||
panic("device_probe_child: parent device has no devclass"); | panic("device_probe_child: parent device has no devclass"); | ||||||||||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | for (dl = first_matching_driver(dc, child); | ||||||||||||
/* | /* | ||||||||||||
* If the driver returns SUCCESS, there can be | * If the driver returns SUCCESS, there can be | ||||||||||||
* no higher match for this device. | * no higher match for this device. | ||||||||||||
*/ | */ | ||||||||||||
if (result == 0) { | if (result == 0) { | ||||||||||||
best = dl; | best = dl; | ||||||||||||
pri = 0; | pri = 0; | ||||||||||||
break; | break; | ||||||||||||
} | } | ||||||||||||
imp: "above here" in comment below. | |||||||||||||
/* | |||||||||||||
* Remember the probe bias for this devclass the user | |||||||||||||
* configured. This is added to the result to give the | |||||||||||||
jhbUnsubmitted Not Done Inline Actions
jhb: | |||||||||||||
* final priority for this driver and to break ties | |||||||||||||
* differently than default. | |||||||||||||
*/ | |||||||||||||
bias = child->devclass->probe_bias; | |||||||||||||
/* Reset flags and devclass before the next probe. */ | /* Reset flags and devclass before the next probe. */ | ||||||||||||
child->devflags = 0; | child->devflags = 0; | ||||||||||||
if (!hasclass) | if (!hasclass) | ||||||||||||
(void)device_set_devclass(child, NULL); | (void)device_set_devclass(child, NULL); | ||||||||||||
/* | /* | ||||||||||||
* Reset DF_QUIET in case this driver doesn't | * Reset DF_QUIET in case this driver doesn't | ||||||||||||
* end up as the best driver. | * end up as the best driver. | ||||||||||||
Show All 17 Lines | for (dl = first_matching_driver(dc, child); | ||||||||||||
if (result > 0) { | if (result > 0) { | ||||||||||||
(void)device_set_driver(child, NULL); | (void)device_set_driver(child, NULL); | ||||||||||||
continue; | continue; | ||||||||||||
} | } | ||||||||||||
/* | /* | ||||||||||||
* A priority lower than SUCCESS, remember the | * A priority lower than SUCCESS, remember the | ||||||||||||
* best matching driver. Initialise the value | * best matching driver. Initialise the value | ||||||||||||
* of pri for the first match. | * of pri for the first match. Add in the %probe_bias | ||||||||||||
* value, if any, to allow the user to break ties or | |||||||||||||
* boost non-preferred drivers. | |||||||||||||
*/ | */ | ||||||||||||
if (best == NULL || result > pri) { | if (best == NULL || result + bias > pri) { | ||||||||||||
Not Done Inline ActionsDo we need to cap this at 0 (or handle > 0 in line 1734)? jrtc27: Do we need to cap this at 0 (or handle > 0 in line 1734)? | |||||||||||||
Done Inline ActionsNo. I don't think so. I originally did cap it based on logic higher in this loop... imp: No. I don't think so. I originally did cap it based on logic higher in this loop...
But it does… | |||||||||||||
Not Done Inline ActionsWell what happens if result is -1 and I bias it by 2? Should that not be the same as 0? jrtc27: Well what happens if result is -1 and I bias it by 2? Should that not be the same as 0? | |||||||||||||
Done Inline Actionsno. It shouldn't. I've reworked the subsequent code so it no longer matters. return == 0 is a special case due to really old drivers that did that and expected softc to live between probe and attach. I don't think we've killed all of those in the tree yet. imp: no. It shouldn't. I've reworked the subsequent code so it no longer matters.
return == 0 is a… | |||||||||||||
best = dl; | best = dl; | ||||||||||||
pri = result; | pri = result + bias; | ||||||||||||
continue; | continue; | ||||||||||||
} | } | ||||||||||||
} | } | ||||||||||||
} | } | ||||||||||||
Done Inline Actionsthis whole block is redunant; we already checked == 0 where I flagged it as "above here" so I should delete this code since it is dead. imp: this whole block is redunant; we already checked == 0 where I flagged it as "above here" so I… | |||||||||||||
Not Done Inline ActionsThat was the inner loop; this is to make that case also break out of the outer loop. jrtc27: That was the inner loop; this is to make that case also break out of the outer loop. | |||||||||||||
Done Inline Actionscorrect... I've updated the prior patch to fix this issue. imp: correct... I've updated the prior patch to fix this issue. | |||||||||||||
if (best == NULL) | if (best == NULL) | ||||||||||||
return (ENXIO); | return (ENXIO); | ||||||||||||
/* | /* | ||||||||||||
* If we found a driver, change state and initialise the devclass. | * If we found a driver, change state and initialise the devclass. | ||||||||||||
*/ | */ | ||||||||||||
if (pri < 0) { | if (pri < 0) { | ||||||||||||
▲ Show 20 Lines • Show All 4,341 Lines • Show Last 20 Lines |
"above here" in comment below.