Subject: Re: Device Properties: The Next Generation
To: None <eeh@netbsd.org>
From: Chris G. Demetriou <cgd@sibyte.com>
List: tech-kern
Date: 02/15/2001 23:04:49
[ I hope you're not too annoyed by discussion of this... but I think
  the goal here really is to come up with the right interface... ]

eeh@netbsd.org writes:
> Ideally, it is not a create-and-hand-off interface, but a
> create-and-give-me-an-early-peak interface.  Solaris uses
> callbacks for this, which causes problems when trying to
> pass state around.  I think returning a pointer to it is
> better than a callback.

we already return a pointer (or not) based on whether the device is
configured, right?  if it's gonna be like this, the caller should
never have to destroy.


> 	> No.  A device does not have parents until it's linked into
> 	> the device tree.  If an attach routine wants to query its
> 	> parent's properties it is passed in the pointer to its
> 	> parent and can query it directly.
> 
> 	I guess this fits in with the notion that inheritance is ~never to be
> 	used.
> 
> 	(I find that kind of unfortunate, since it means that a _lot_ of
> 	memory will be wasted for inheritable things...  *sigh*)
> 
> Well, at attach time the device is in the tree so inheritence
> will work.  And the parent device is always in the tree and
> can be queried using inheritence at any time.

Right, but by your description, inheritance really isn't so useful
except in fairly abnormal cases.  (That seems like a mistake.)


> It would be possible to pass the parent device node in to
> dev_create() so it is attached in the right place on creation.
> That would make inheritance work, but then you have issues
> about empty device nodes in the device tree.

Really?  you've got a pointer to a device in the tree from the fake
property holder, but you don't have to insert the fake property holder
into the device tree until it's been made real.


> The reason you need to be careful about inheritence is that
> you don't know where the property is coming from.  If it comes
> from the wrong place it could be the wrong property.  If you
> want to query your "frequency" but you don't have the property
> and mainbus does, and you enable inheritence, you will get the
> mainbus "frequency" property which may be completely different
> from your property.

Right, exactly.  That's how I got to the question of, can you delete
things, whiteout them, or mark a device as 'stopping' the inheritance.


> You do not want to use inheritence when searching to decide what
> type of bus you're attached to because you may search too far and
> thing you're on a different type of bus altogether.

If you can stop the inheritance, it's _Exactly_ what you want to do.

If a bus is a SCSI bus or has _any_ other device-specific property
(e.g. chipset info), why should each child have to be told that
information separately?  it's wasteful, unnecessary, and puts the data
in the wrong place.

If the data's associated with the bus, it should be associated with
the bus.  If it's associated with the individual children, it should
be with them.


> 	Actually, right now, bus speed is something passed down via aux on at
> 	least some busses, because it's "important enough."
> 
> Just as `aux' is a protocol that must be designed for
> each set of parent and child devices, properties need
> to be used in an appropriate protocol.

the problem is, because of the issue of inheritance:

(1) either you have to waste a bunch of space providing extra
properties where they really don't make sense (e.g. bus chipset tag
attached as a device property), or

(2) you have to provide a way of stopping inheritance at a given level
where it ceases to make sense, or to delete certain properties.

One way to do (2) would be to provide a limited form of inheritance,
like:

	parent			child		child child
	  | props	    props | props      props |   
	  | for		     from | for         from |
	  | children	   parent | children  parent |

where each | can be (perhaps "must be") a barrier that stops
inheritance.


Personally, I think (2) is the more useful behaviour; it presents the
appropriate information at the appropriate levels, without undue
duplication.  It also lets you know that the data that you're getting
is the data that applies to you.

Do you have any examples where you _really_ need to go over the head
of a device's parent?



> 	This use of inheritance seems inconsistent.  If you're going to get
> 	bus speed via inheritance, why wouldn't you also get other bus chipset
> 	information of various varieties?  It's absolutely unchanging, and you
> 	may not know the distance between you and the bus bridge...  I don't
> 	understand how it's different than 'speed,' except that it happens to
> 	be used more often.
> 
> It depends on:
> 
> 1) How important it is to you.
> 
> 2) How important the parent device thinks it is.
> 
> 3) Where the property is located with respect to you.

Except, (1) is irrelevant.  If the parent device doesn't provide it
directly, for all you know martians are beaming it into the system.
It's either given directly to you, or you inherit it from who knows
where.

I'm thinking that, except as described above (where busses can provide
values to all of their children), inheritance just isn't so useful...


> 	Also, it seems that several of your suggestions so far have assumed a
> 	set of expected properties that would be used.  Can you provide a
> 	list?  (such a list should come with the documentation for a change
> 	like this anyway... 8-)
> 
> O.K.  The way properties are used on Solaris is to provide
> devices with things like their SCSI ID, SBus slot, physical
> address, etc.

Right, sure.

We need much more than that though if you're going to replace the
'aux' structures.  (e.g. pointers that don't correspond to real
hardware stuff, kernel internal stuff, bus_space_tags which may not be
obviously hardware related...)


> Let's take a typical excerpt from a SPARC's device properties
> as an example.  Now Solaris likes to use properties to display
> state information, which I consider a particularly evil thing
> to do, so ignore those bits:

Most of this seems to be chaff...  (I think OFW is interesting, but
way overblown, and the sparc properties seem quite interrelated with
it.  we should _not_ be attempting to emulate its semantics, if
they're what you originally described.  8-)


> Here we have a SCSI disk.  The properties
> provide the TARGET ID, LUN, class, etc.
> 
>                     System properties:
>                         name <lun> length <4>
>                             value <0x00000000>.
>                         name <target> length <4>
>                             value <0x00000000>.

right, OK, target & lun integers, not surprising...


> The following are interesting.  Driver classes
> are used to sort between different buses and bus
> protocols.  We could do similarly by specifying
> the type of the parent bus with a property.  That
> way a device could quickly sort out what type of
> bus it's attached to and what properties it needs 
> to find.

You could certainly do that, but I think you're better off doing it
with separate bus attachments.

(what if a port doesn't supply headers for all busses?  what if a
kernel config doesn't include all busses?  what if you want to provide
a new bus attachment via a loadable module?  etc.)

I think there's code size savings, as well as more flexibility, by
keeping bus attachments independent of each other.


cgd