sysinit how does nexus find legacy's driver?
John Baldwin
jhb at freebsd.org
Mon Nov 21 18:28:40 GMT 2005
On Monday 21 November 2005 11:07 am, kylin wrote:
> The nexus_attach(device_t dev) will call
>
> int
> bus_generic_probe(device_t dev)
> {
> devclass_t dc = dev->devclass;
> driverlink_t dl;
>
> TAILQ_FOREACH(dl, &dc->drivers, link) {//here configure has point out
> the relation?
> DEVICE_IDENTIFY(dl->driver, dev);//here refer to the son's
> IDENTIFY,make son's device structure
> }
>
> return (0);
> }
> the question is
> in TAILQ_FOREACH(dl, &dc->drivers, link)
> how does nexus get legacy's driver in its devclass ?
> have it done in the SI_SUB_DRIVER part?of initialization?
>
> What happen during sSI_SUB_DRIVER ,does devclass for each driver
> initialized?
>
>
> May be the before SI_SUB_CONFIGURE, SI_SUB_DRIVER will first be
> implement ,and the relative drivers will connect to each other.
> I am sure that in autoconf.c ,the dl->link does not be add in ,so
> where does the nexus find legacy?
> In devclass_find_inernal
> TAILQ_FOREACH(dc, &devclasses, link) {
> if (!strcmp(dc->name, classname))
> break;
> }found nothing ,
>
> //////////////////
It's a lot of magic. :) Each driver is a kernel module declared via
DRIVER_MODULE():
#define DRIVER_MODULE(name, busname, driver, devclass, evh, arg) \
\
static struct driver_module_data name##_##busname##_driver_mod = { \
evh, arg, \
#busname, \
(kobj_class_t) &driver, \
&devclass \
}; \
\
static moduledata_t name##_##busname##_mod = { \
#busname "/" #name, \
driver_module_handler, \
&name##_##busname##_driver_mod \
}; \
DECLARE_MODULE(name##_##busname, name##_##busname##_mod, \
SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
This causes driver_module_handler() to be run at SI_SUB_DRIVERS for each
driver in the kernel. One of the things that function does is add the driver
to the parent driver's devclass:
int
driver_module_handler(module_t mod, int what, void *arg)
{
...
switch (what) {
case MOD_LOAD:
...
driver = dmd->dmd_driver;
PDEBUG(("Loading module: driver %s on bus %s",
DRIVERNAME(driver), dmd->dmd_busname));
error = devclass_add_driver(bus_devclass, driver);
if (error)
break;
...
}
That adds the driver to the dc_drivers list. Thus, when you see:
DRIVER_MODULE(legacy, nexus, legacy_driver, legacy_devclass, 0, 0);
in legacy.c, that results in legacy_driver being attached to the devclass for
the nexus driver.
--
John Baldwin <jhb at FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve" = http://www.FreeBSD.org
More information about the freebsd-hackers
mailing list