tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Inter-driver #if dependencies
My crusade for modularity has arrived at the pcppi(4) driver, and I've
discovered that there are a number of places in the code where a #if is
used to determine whether or not some _other_ driver is available to
provide certain routines. For pcppi(4), these dependencies are for the
attimer(4) and pckbd(4) drivers. (While I haven't yet gone searching,
I'd be willing to wager that there are other similar examples in other
drivers.)
These #if constructs make it very difficult to modularize these drivers.
I'd like to propose the following new kernel mechanism that will allow
us to remove these #if dependencies.
1. Extend the struct cfattach to have an additional member, and create
a new CFATTACH_DECL4_NEW macro to initialize it (and updates to the
existing CFATTACH_* family to default the value to NULL).
int (*ca_callback)(device_t, int, void *);
(This will require a kernel version bump.)
2. In kern/subr_device.c (or kern/subr_autoconfig) add a new routine
to call the callback routines for a driver until something handles
the request. Note that the caller provides a device_t to identify
itself to the callback routine.
int
config_device_callback(device_t caller, const char *name,
int cb, void *args)
{
struct cfdriver *cd;
struct cfattach *ca;
cd = config_cfdriver_lookup(name);
if (cd == NULL)
return ENODEV;
LIST_FOREACH(ca, &cd->cd_attach, ca_list) {
if (ca->ca_callback != NULL) {
rv = (*lca->callback)(caller, cb, args);
if (rv != EPASSTHROUGH)
return rv;
}
}
/* No driver attachment handled the request - punt */
return ENODEV;
}
3. Replace all of the #if code with callbacks. For example, in pcppi.c
we can replace
...
#if NPCKBD > 0
pckbd_unhook_bell(pcppi_pckbd_bell, sc);
#endif
...
...
#if NPCKBD > 0
pckbd_hookup_bell(pcppi_pckbd_bell, sc);
#endif
...
with
...
config_device_callback(self, "pckbd", 1, NULL);
...
...
config_device_callback(self, "pckbd", 2, NULL);
...
and in the pckbd driver code we have
...
struct pcppi_softc *sc = device_private(caller);
...
switch (cmd) {
case 1:
pckbd_unhook_bell(pcppi_pckbd_bell, sc);
break;
case 2:
pckbd_hookup_bell(pcppi_pckbd_bell, sc);
break;
...
This mechanism still requires the two drivers to coordinate with each
other (for defining the "cmd" values, and the contents of "args" for
each cmd), but it no longer requires compile-time checking to see if
another driver exists.
Comments? Alternative methods of unravelling the #if's?
-------------------------------------------------------------------------
| Paul Goyette | PGP Key fingerprint: | E-mail addresses: |
| (Retired) | FA29 0E3B 35AF E8AE 6651 | paul at whooppee.com |
| Kernel Developer | 0786 F758 55DE 53BA 7731 | pgoyette at netbsd.org |
-------------------------------------------------------------------------
Home |
Main Index |
Thread Index |
Old Index