Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Jan 2012 09:32:06 -0500
From:      John Baldwin <jhb@freebsd.org>
To:        Marius Strobl <marius@alchemy.franken.de>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r193833 - in head: share/man/man9 sys/kern sys/sys
Message-ID:  <201201300932.06243.jhb@freebsd.org>
In-Reply-To: <20120129154124.GB18227@alchemy.franken.de>
References:  <200906091426.n59EQNRC074046@svn.freebsd.org> <20120129154124.GB18227@alchemy.franken.de>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sunday, January 29, 2012 10:41:24 am Marius Strobl wrote:
> On Tue, Jun 09, 2009 at 02:26:23PM +0000, John Baldwin wrote:
> > Author: jhb
> > Date: Tue Jun  9 14:26:23 2009
> > New Revision: 193833
> > URL: http://svn.freebsd.org/changeset/base/193833
> > 
> > Log:
> >   Add support for multiple passes of the device tree during the boot-time
> >   probe.  The current device order is unchanged.  This commit just adds the
> >   infrastructure and ABI changes so that it is easier to merge later changes
> >   into 8.x.
> >   - Driver attachments now have an associated pass level.  Attachments are
> >     not allowed to probe or attach to drivers until the system-wide pass level
> >     is >= the attachment's pass level.  By default driver attachments use the
> >     "last" pass level (BUS_PASS_DEFAULT).  Driver's that wish to probe during
> >     an earlier pass use EARLY_DRIVER_MODULE() instead of DRIVER_MODULE() which
> >     accepts the pass level as an additional parameter.
> >   - A new method BUS_NEW_PASS has been added to the bus interface.  This
> >     method is invoked when the system-wide pass level is changed to kick off
> >     a rescan of the device tree so that drivers that have just been made
> >     "eligible" can probe and attach.
> >   - The bus_generic_new_pass() function provides a default implementation of
> >     BUS_NEW_PASS().  It first allows drivers that were just made eligible for
> >     this pass to identify new child devices.  Then it propogates the rescan to
> >     child devices that already have an attached driver by invoking their
> >     BUS_NEW_PASS() method.  It also reprobes devices without a driver.
> >   - BUS_PROBE_NOMATCH() is only invoked for devices that do not have
> >     an attached driver after being scanned during the final pass.
> >   - The bus_set_pass() function is used during boot to raise the pass level.
> >     Currently it is only called once during root_bus_configure() to raise
> >     the pass level to BUS_PASS_DEFAULT.  This has the effect of probing all
> >     devices in a single pass identical to previous behavior.
> >   
> >   Reviewed by:	imp
> >   Approved by:	re (kib)
> > 
> 
> What would be necessary to finally enable support for multi-pass
> probing apart from the drivers also needing to set BUS_PASS_n if
> they want to take part earlier than BUS_PASS_DEFAULT)? My
> understanding is that this is should be as simple as changing
> root_bus_configure() to return BUS_PASS_ROOT instead of
> BUS_PASS_DEFAULT but the comment above that line actually talks
> about splitting the return value (?) up somehow ...

It will already work now without needing any changes.  I have some older
patches to make x86 probe ACPI and PCI busses and bridges early and they
required no changes to the root bus.  The reason for the comment is that I
eventually imagine the multiple passes being split up so that we can do other
actions after various passes are complete.  For example, we might rewrite
root_bus_configure() so that it looks something like:

void
root_bus_configure(void)
{

	/* Enumerate the device tree and reserve static resources. */
	bus_set_pass(BUS_PASS_RESOURCE);

	/*
     * Now scan devices to allocate dynamic resources, possibly
	 * rewriting BARs, etc.
	 */
	/* some code that doesn't exist yet */

	/* Now probe interrupt controllers. */
	bus_set_pass(BUS_PASS_INTERRUPT);

	/* Now kick off interrupt routing via some new bus method. */
	/* not written yet */

	/* Finish probing everything else. */
	bus_set_pass(BUS_PASS_DEFAULT);
}

This works because bus_set_pass() will do multiple scans of the tree, one
per configured pass level, to raise the system's pass level up to the
requested level.

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201300932.06243.jhb>