Subject: Renovating autoconf(9)
To: None <>
From: Quentin Garnier <>
List: tech-kern
Date: 12/10/2007 20:39:43
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hi all,

I'm going to start a branch to renovate our autoconf(9) API.  Personally
I have two main grudges against its current incarnation:  it is
confusing (not only to me;  the way it is abused around the tree shows
it confused and still confuses people), and it shows its age by pretty
much expecting everything to happen while cold.

By that I imply the complete lack of locking (I believe that now we can
have a situation where two kernel threads might attach two new devices
on two CPUs, and if it's not the case, it will happen soon enough), and
the fact that a device cannot exist without a driver.

In a dynamic world, a driver for a known device can be loaded at a later
time;  that should not warrant a complete rescan.

Another issue the device =3D=3D driver assumption brings is the fact that it
is impractical to manipulate the device_t object before a driver gets
attached.  See for instance atapi_probe_device() in
dev/scsipi/atapiconf.c (scsi_probe_device() has the same issue).

The initial aims of that branch will be the following:

  - implement a new API for autoconfiguration which is clearer and
    allows buses to keep track of devices independently of drivers.

    The current state of that in my private tree includes two
    functions for direct configuration, and three for indirect

=3D=3D=3D Direct configuration (i.e., parent *knows* a device exists) =3D=

device_t    ac_alloc_child(device_t parent, locators_t locs);
bool        ac_found_device(device_t device, const char *ifattr,
                cfprint_t pr, cffilter_t filt, void *arg);

    The exact type of locators_t will be explained below.  The type
    cfprint_t will change, taking only a device_t (the child device
    of the bus), because that object will contain all the information
    the print function needs to know (whether a driver is about to
    attach, and what the locators are).

    cffilter_t is not only for direct configuration;  it is a callback
    that filters cfdata_t's (i.e., instances defined in the kernel
    configuration file) before they are considered for attachment.  In
    most cases for direct configuration, it's just a matter of checking
    locator values against what's in the configuration file.

    Note that the void * argument is passed to the cffilter_t callback
    but *not* to any function of the drivers for the child device.  I
    might even remove it eventually.  Yes, that means attach_args are
    killed (as far as direct configuration is concerned).

    The match function in the cfattach_t object has now a simpler

int         (*ca_match)(device_t device, cfdata_t);

   The device_t object is the device itself, not its parent.

   Attach is simpler, too, and has the ability to return a value.

bool        (*ca_attach)(device_t device);

=3D=3D=3D Indirect configuration (i.e., parent expects drivers to probe =3D=
=3D=3D=3D for devices                                                   =3D=

int         ac_iterate_config(cffilter_t iterator, device_t parent,
                 const char *ifattr, void *v);
device_t    ac_probe_device(device_t parent, cfdata_t child_cfdata,
                 void *v);
bool        ac_attach_device(device_t device, cfdata_t child_cfdata,

    I find the first function much more explicit about what it does than
    config_search(), as they do essentially the same thing.  But maybe
    that's just me.

    Note that ac_probe_device() will call a new member of cfattach_t:

int         (*ca_probe)(device_t parent, cfdata_t child_cfdata,
                void *v);

    Yes, this is the current ca_match.

    That API is very close to the current config_search/config_match/
    config_attach, but I might change my mind a bit and allow ca_probe
    call ac_attach_device by itself and return e.g., the number of
    devices found.  I'll probably need to add a callback so that the
    parent bus call keep track of the device_t object created.

=3D=3D=3D config_defer =3D=3D=3D

    That one really is confusing.  I'll change it to the following:

void        ac_defer_after(device_t dev, void (*)(device_t),
                device_t arg);

    That function defers a callback after "dev" is finished attaching,
    and "dev" can be any device known to the current code.  So the
    current config_defer(dev, func) would be replaced by
    ac_defer_after(dev->dv_parent, func, dev).  I want this because
    sometimes you want to defer something after a grand-parent has
    finished attaching, because you want to somehow communicate with a
    long lost cousin.

=3D=3D=3D About the API =3D=3D=3D

    I accept comments both for the API itself and the name of the
    functions, but I think this is the direction we want to go.

  - proplibifuckation of locators and instance configuration data.  I
    think it's time we introduce more types to locators than just an
    integer, and I think proplib is the right tool for that:  it has
    enough types for our needs, and it exists.

    In my local tree, that part depends on parts of the work Jachym
    Holecek did for the 2007 Summer of Code, so I'll integrate his
    work in the branch.

If you have more specific needs or rants about our currnet autoconf(9)
that I would not be aware of, this is your chance to see them

Quentin Garnier - -
"See the look on my face from staying too long in one place
[...] every time the morning breaks I know I'm closer to falling"
KT Tunstall, Saving My Face, Drastic Fantastic, 2007.

Content-Type: application/pgp-signature
Content-Disposition: inline

Version: GnuPG v1.4.6 (NetBSD)