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 <[EMAIL PROTECTED]>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to