Subject: Re: Device driver softc questions
To: Steven Grunza <steven_grunza@ieee.org>
From: David Querbach <querbach@realtime.bc.ca>
List: tech-kern
Date: 03/15/2001 15:25:22
> In the attach() routine, the second parameter is a pointer to a
> structure that appears to be called a softc.  This structure appears to
> hold information for the driver.  Where (in the source code) is the
> memory for this structure allocated?

A "softc" is the structure holding data required by a driver.  Each driver
has its own softc structure, which is based on struct device:

struct puc_softc {				// dev/pci/puc.c, line 68
        struct device           sc_dev;		// "base class" object

	... device-dependent data
};

An instance of a softc structure is created during auto-configuration for
each device whose match function (in your case, puc_match()) returns
non-zero.  (Actually, that's just an approximation.  If more than one match
function returns non-zero, the highest return value "wins".)

> For instance in /sys/dev/pci/puc.c line 63 the definition for "struct
> puc_softc" is created.  In line 147 of puc_attach() a local pointer
> called sc is created on the stack and set to point to the second
> parameter passed into the puc_attach() function.  This local stack
> pointer is then used to update this puc_softc structure.
 
Once a device is matched, the auto-configuration system malloc's space for
the device softc as specified in the cfattach structure for the device,
then passes it to the attach routine.  In your case:

struct cfattach puc_ca = {			// dev/pci/puc.c, line 99
        sizeof(struct puc_softc), puc_match, puc_attach
};

Note that this structure also lists the match and attach routines.

> But where is a pointer to this struct puc_softc saved so the driver can
> get to it later?  This driver doesn't have puc_open() and
> puc_close() calls but how would they figure out where the struct
> puc_softc is located?

The softc pointers are stored in an array pointed to by the struct cfdriver
for the device in question.  These structures are described in sys/device.h,
and are actually found in ioconf.c in your kernel compilation directory. 
The file ioconf.c is created by config(8) at kernel build time.

> For now I'm going to just use a global pointer to it but there's got to
> be a better (more correct) way....

Have a look at dev/ic/com.c for an example of how to find a softc:

extern struct cfdriver com_cd;					// line 177

  struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));	// line 965

You might also want to read the auto-configuration papers.  Look on the
netbsd.org documentation page.

Regards,

David Querbach
Real-Time Systems Inc.