Subject: Re: softc
To: Michael L. VanLoon -- HeadCandy.com <michaelv@HeadCandy.com>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: tech-kern
Date: 06/04/1996 12:50:05
On Sun, 02 Jun 1996 23:30:18 -0700 
 "Michael L. VanLoon -- HeadCandy.com" <michaelv@HeadCandy.com> wrote:

 > Please help me get a better understanding: what exactly is a softc,
 > and how exactly is it supposed to be allocated, filled in, and used?

Ok ... There are 4 discrete questions here :-)

	Q - "What exactly is a softc?"

	A - A softc is basically just miscellaneous software state
	    for a device driver.


	Q - "How exactly is it supposed to be allocated?"

	A - Under new config NetBSD ports (all but hp300), storage
	    for the softc is automatically dynamically allocated by
	    the MI autoconfiguration code (see subr_autoconf.c) when
	    a device is found (probe/match returned non-0).

	    Under the NetBSD model, the generic device structure is
	    tightly coupled with a device's softc.  Every device on
	    the system has a "struct device" associated with it.
	    Most devices on the system also have a softc (some drivers
	    are so simple, they just don't need any extra state
	    information).

	    When Chris Torek architected the new config model for
	    4.4BSD/sparc (which is what NetBSD's config model is
	    derived from), he provided a mechanism for drivers to
	    tell the configuration code how much storage to allocate
	    for a softc.  Under NetBSD, this is kept in the `cfattach'
	    structure:

		struct cfattach foo_ca = {
			sizeof(struct foo_softc),	/* size of softc */
			foo_match,			/* match/probe func */
			foo_attach,			/* attach func */
		};

	    Under the NetBSD model, a softc for an autoconfigured device
	    _must_ contain a "struct device" as its first member:

		struct foo_softc {
			struct	device sc_dev;	/* generic device glue */
			void	*sc_reg;	/* pointer to device regs */
		};

	    This is so a struct foo_softc * can be cast to a
	    struct device *, and vice-versa.

	    The allocated softcs are placed in the cfdriver for the
	    device, indexed by unit number...i.e. to get the softc
	    for unit number 0 of a foo, you'd do:

		struct foo_softc *sc = foo_cd.cd_devs[0];

	    They're placed in that array for you, automatically.


	Q - "How is it supposed to be filled in?"

	A - The "struct device" portion is filled in for you by the
	    MI autoconfiguration code.  In that chunk, you'll find the
	    external name, unit number, pointer to parent, etc.
	    The rest of how it's filled in is really up to you.  For
	    example, you might keep a bus_io_handle_t in the softc
	    for use in doing bus i/o.  That sort of thing would be
	    filled in by the driver in the attach function.  You might
	    also keep the current state of a state machine, like the
	    ncr5380sbc driver does.  It's really up to you.


	Q - "How do I use it?"

	A - See previous.  :-)


 > Is it supposed to be some place where all the state for a particular
 > instance of a device resides, or something like that?  What is the

*ding*

 > ultimate prototype for all softc's?  Is there such a thing?

Well, really, all softc's do have a generic template: they all contain
a struct device as their first member (that is, if the device is
autoconfigured ... most (all?) pseudo-devices, like the ccd, do not,
since they don't use the autoconfiguration subsystem at all).

Hope this helps!

----save the ancient forests - http://www.bayarea.net/~thorpej/forest/----
Jason R. Thorpe                                       thorpej@nas.nasa.gov
NASA Ames Research Center                               Home: 408.866.1912
NAS: M/S 258-6                                          Work: 415.604.0935
Moffett Field, CA 94035                                Pager: 415.428.6939