Subject: Re: Device Properties: The Next Generation
To: None <cgd@sibyte.com, eeh@netbsd.org>
From: None <eeh@netbsd.org>
List: tech-kern
Date: 03/07/2001 23:25:27
	eeh@netbsd.org writes:
	> 	Looked at another way, CACHEABLE, LINEAR, etc., don't neceesarily have
	> 	to be stored.  STRING and CONST do (as far as I can tell).
	> 
	> Both PROP_STRING and PROP_CONST are used to control how a
	> property is created rather than stored in the property.

	Huh?  PROP_STRING and PROP_CONST both affect storage.

	PROP_STRING must at least be stored with the property, in some obvious
	form.

	PROP_CONST must also be stored, and also completely munges the
	underlying storage mechanism...

As I said, neither PROP_STRING nor PROP_CONST are stored in the
property.  And it is not possible to determine whether a property
was created with PROP_CONST or not after it has been created.

	> I disagree.  If it has a valid parent pointer it should be in
	> the tree.  If it's not in the tree then it shouldn't have a
	> valid parent pointer and we need to continue to pass in the
	> `parent' device pointer to both the match and attach functions.
	> Otherwise it's in a state of semi-insertion that really does
	> not make sense.

	So, there are a couple of things to say to this.

	I think the big problem here is that several things are being confused
	in this interface.

	(1) access to parent.  In general it's not appropriate, but some
	devices need it.  So they have to be accomodated in some manner.

	(2) property search chain.

	(3) timing / creation / use of new device.


	Right now, a new 'struct device' is created early as a dummy, and is
	the property container.  It's reasonably used for (1) and (2) if it's
	got a link to the parent made.

It is not a `property container'.  It is a device that has not completed
attaching.  The entire `property container' concept is used to handle
old-style devices with the device structure inside the softs.  In that
case the device structure needs to be reallocated so it can be resized.

New-style devices just allocate a separate softc and continue to use
the device structure.

	However, until it's attached, it should _not_ be linked into the tree
	of devices.  It's not a device.

It is a device.

	You may call that 'semi-insertion,' but I don't really think it is
	(any more than a separate property container making a reference to a
	parent property container would be).


	If you want to clean up this interface so that it doesn't do this
	"semi-insertion" the right way to do it is:

	(1) allocate a child only in config_attach().  There are advantages to
	this anyway, it'll avoid some confusion that the changes you're
	suggesting would introduce.

	(2) _not_ pass a child to the match routine, do pass the parent.

	(3) make property containers first-class objects.

There are no property containers.  Properties cannot be accessed
without a device.  If properties can disassociate themselves with
a particular device you have chaos.  You end up with a flat 
namespace and cannot distinguish between instances of the same
property associated with different devices.

	(4) pass one in to the match routine (like aux is now, in addition to
	aux), with the inheritance info pointing at the parent device's
	property container.

There is no `parent device's property container'.  There is an association
between the parent device and a set of properties.  If a device does not
have a parent, you cannot access its parents properties, so searching
will not work.

	Note that if you're trying to hang properties off of cfdata for
	locators, it's fairly obvious how you'd get them into the various
	functions, and use them as well.

You cannot use cfdata to hold properties because cfdata is not
unique among wildcarded devices.

	> 	uh oh, how do you nuke the device?  You pretty much have to -- if you
	> 	were doing a copy, the state is now ... not well defined.
	> 
	> 	dev_detach() isn't the right thing -- it's not an attached device yet.
	> 
	> It's in the tree in an unconfigured state,

	Nothing that has not been fully "configured" (config_attach()ed)
	should be (completely) linked into the tree.

This part you need to explain to me.  Why shouldn't anything
that isn't fully attached be linked into the tree?

	> but if you want a
	> separate dev_destroy() that would be simple to add.  But then
	> dev_detach() should not be destroying the device node if you 
	> want a nice orthogonal interface.

	That's an interesting point.  It could substantially complicate
	things.

	I really think i'm leaning back towards devices only being created in
	config_attach() or its equivalent, i.e. you don't pass devices around
	until they're devices.

Won't work for oh so many reasons. [Previously discussed.]

	> 	> I think calling config_search() directly is
	> 	> a Bad Thing.  I would be happy to make config_search() an internal
	> 	> interface only.
	> 
	> 	uh... how would you implement indirect-config busses, except via
	> 	config_search()?
	> 
	> I thought that the submatch function was added to config_found()
	> specifically to support indirect-config through config_found().
	> Or are there problems with doing that?

	That is not correct.  Indirect config would work fine with the
	interfaces that were originally designed/implemented by Chris T.

	config_found() is _never_ used for indirect config devices.
	submatch is used to do a check of the config-supplied locators against
	the ones actually supplied by the bus.  You can think of submatch
	functions for direct config as code which would otherwise have to be
	in every single driver attached to a given direct config bus.

	It just doesn't make sense to try to use config_found() for indirect
	config.  direct config / config_found says "I have found this device,
	find me a driver which matches it."

Er, no, the current implementation is more like "I have found 
this slot, scan over the list of all devices specified in the 
config file as children of this bus, checking to see if they're 
there."  If what you said above is really supposed to happen then 
the code to scan for a particular driver before calling the match
routine seems to be missing.

	Indirect config says "Scan over the list of all devices specified in
	the config file as children of this bus, checking to see if they're
	there."

The only real differences I see between direct and indirect config
is that direct config calls config_found() and indirect config rolls
its own version of config_found().  Oh, and direct config calls
config_search() (through config_found()) once for each slot, while
indirect config only calls it once for the entire bus.

	Certainly, there's common code that's shared (in particular,
	config_search() 8-), but the end result and the level of control
	that's needed are just different for each.

Could you be a bit more specific about what the difference between
direct and indirect config?  Looking at the code, it would seem
that isa could be implemented easily using direct config.  Or
does it have something to do with indirect config buses not knowing
how many slots they have?

	[...]

	> cfprintt_t is caled from config_found() and config_attach().  Both
	> of those routines know what the parent bus is and what form of 
	> form of arguments should be appropriate to the print function.
	> 
	> Calling a *print() routine from a child driver is an extremely
	> questionable practice.

	So, say you're _in_ the print routine.

	If all you get are a void * and a parent name pointer, how do you know
	what that void * is (if it could be a 'struct device *' or an aux
	ptr)?

It's obviously whatever you are supposed to be called with.
If you're using config_found() then config_found() will determine
if you belong to a new device or old device and use the appropriate
parameter.  If you use indirect config, then it's whatever the 
indirect config function passes.

	[...]
	> For the most part, comparing a locator to a property on the
	> device node could easily be delegated to MI code rather than
	> the sbmatch function.

	For the most part?  It's one of those things where, either you provide
	the hook or you don't.

It depends on how complicated a wildcard matching scheme you need.

	I think I agree, actually.  It's probably possible for MI code to do
	the property sanity check that is normally done by direct-config
	submatch functions.


	> In fact, we self-identifying buses could
	> provide a specific device identifier to the MI code to allow 
	> config_search() to determine the exact match without calling
	> submatch functions.  But the increased search speed gained
	> by doing somethi like that is probably not worth the effort.

	I'm not sure what you mean.

If you break locators out into easily identified data structures
then the MI code could do the necessary comparisons for you before
ever calling the device's match routine.

	[...]

	However, match also (arguably) has the responsibility to check for
	resource availability, etc.  A non-device-specific match routine can't
	really satisfy that.

I don't think that can be done in the match routine.  In many cases
only way you can be sure that you have all the resources you need 
is to claim them.  And if you do that in the match routine you may 
allocate resources that will never be used because a better match
is found later and that particular instance never attaches.  If you
are concerned about resource availability, that should be handled
in the attach routine, not the match routine.

	> O.K.  No locators added automagically.  Should they be compared automagically?

	There's something to be said for this.  I think i understand how this
	might work (see earlier this mail or previous -- i got distracted by
	other stuff, and had to stop responding for a bit).

I suppose this would only be a coding change, not really an
interface or change in detectable functionality.

	> We're making `parent' go away?  O.K.  If we do that it should
	> be handled in the initial conversion rather than later where
	> it will cause more breakage.  If `parent' will not be needed
	> in the future then it should not be needed right now.

	(1) see comments in other mail,

	(2) you still need backward compat for not-converted drivers, but I
	think we all know that.  8-)

If the child will not be linked into the tree until config_attach(),
we will need to pass the parent in to the match routine.  If the
child is linked in when it's created then we can nuke the parent for
both match and attach.  I don't care which option we chose, but we
need to chose one.

Eduardo