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