Subject: Re: PCI setup problem
To: None <augustss@cs.chalmers.se>
From: Chris Torek <torek@BSDI.COM>
List: tech-kern
Date: 08/06/1998 17:59:48
Aaargh.

I had just composed a nice message with various thoughts I had had
about this stuff long ago, and ran most of it through "fmt", but
mis-typed the command as "f,t" (in vi) and lost it all because
instead of "u"ndo, my hand was still off by one and I hit "i",
which clobbered the undo buffer.

Anyway, yes, there should be some way to defer config_search and/or
config_found ops.  Whether this should be done in the caller (e.g.,
the pci bus scanning code that knows for sure there is a device in
slot 3, but does not know for sure what that device *is*, and just
wants to say "I found something, manufacturer ID is in the aux
data") or the callee, or both, is one question.

Another thing that would be useful is a way to cut down on the
call stack.  Currently (you may have seen this in a debugger) you
can get a very deep stack that looks like, e.g.,

	#0  sdattach()
	#1  config_attach()
	#2  config_found()
	#3  targattach()
	#4  config_attach()
	#5  config_found()
	#6  scsi_probe()
	#7  scsiadapterattach()
	#8  config_attach()
	#9  config_found()
	#10 foobusattach()
	#11 config_attach()
	#12 config_found()
	#13 zorblebusattach()
	#14 config_attach()
	#15 config_found()
	#16 gronktozorbleadapterattach()
	#17 config_attach()
		.
		.
		.
	#96 config_found()
	#97 mainbus_scan()
	#98 configure()
	#99 main()

Most of these stack frames are unnecessary in a strict sense, unless
they hold local variables that are passed by address as the "aux"
parameter to the next layer.  That is, while the zorblebusattach()
routine might be in the middle of scanning for foobus'es and such,
it could easily scan for them all, pile up a list of those that
are there, and then return to frame 10 (config_found) and have it
loop over the list of found devices now that the scanning is done.
The only requirement to make this work (besides being able to defer
`config_found's) is that zorblebusattach() not pass the address of
any automatic variables.  This might in turn mean that zorblebusattach
needs to get control again once the deferred config_found's are
done, so that it can free space it malloc'ed.  (On the other hand,
if zorblebusses have hot-pluggable devices, zorblebusattach should
not free this space after all, but this is a matter for individual
drivers to decide.)

In addition to being able to defer, then, we may want a way to
place a callback function into the list, to be done after all the
deferred ops.

This would collapse most of the above stack frames away entirely.
But, it is not a backwards-compatible change (because of the new
rule disallowing &autovar), so it probably requires a new function.
(It is also a lot of work just to get rid of those stack frames,
and there is no reason main() *has* to run on an ordinary u. area
type kernel stack of some small size, so it may not be worth the
effort.)

If there is to be a deferred-ops list, this presents a few other
questions:

 - Can one shuffle or sort the list?  If so, how?  How does this
   interact with callbacks?
 - Can one "activate" the list early, e.g., "we found all the
   devices whose cfdata->cf_driver->cd_aux tells us that they need
   to be done on pass 1, so now go back and do pass 2", or does
   it always wait until we return into the config_whatever routine?

Incidentally, the latter points out that one can in fact "defer"
already, e.g., in an isa-bus scanner, one could have isa devices
have a "cd_aux" that says whether they can dynamically allocate
IRQs (and/or which IRQs they can use); the isa probing code can
then make use of this to call config_attach() in the right order
(making up its own deferred-attach lists).

Chris