Subject: Re: Device Properties: The Next Generation
To: None <cgd@sibyte.com, eeh@netbsd.org>
From: None <eeh@netbsd.org>
List: tech-kern
Date: 02/26/2001 17:11:53
	> If I understand this correctly, the argument boils down to:
	> 
	> You argue that if you have complete control over where properties
	> are allowed to be placed and how they are used, you do not need
	> the ability to query a particular node for a property.  Since
	> the protocols in use will dictate where a property is allowed
	> to reside, you can infer its location by its presence or absence.
	> 
	> I argue that that level of control over placement of properties
	> is unduly limiting and would prevent the use of (what I consider
	> useful) semantics of determining the associateion of a property
	> with a specific node.
	> 
	> Is that correct?

	I think that could be, yes.

O.K.  Then arguing about PROP_SEARCH will resolve nothing
since it dances around the issue of contention.  

First, to quote the language that has been in the device
properties proposal from the beginning:

	3	Description

	A property is a tuple that consists of a pointer to a device node (struct
	device *), string, and an arbitrary amount of data.

So a device property is (dev, name, value).  In a strict 
implementation, specifying `dev' and `name' will return `val'.
PROP_SEARCH violates this, but is provided to allow reduced
memory consumption by sharing a property between related
devices on the device tree.

Your proposal to disallow a query on a specific property
removes the device from the property definition, which 
means you can no longer associate a property with a specific
device.  Instead, you end up with just (name, value).

But this argument also fails to address the issue directly.

The fundamental problem has to do with properties that
are layered upon the property framework from outside, and
the complexity of dev_mdgetprop().  

You want to be able to control exacly what properties
dev_mdgetprop() generates and at what point it so as
not to conflict with any of the protocols currently
in use for device attachement.  I don't think that
will be possible, or even desireable.  

First of all, that means that dev_mdgetprop() needs to be
aware of all the details of all the protocols that could
be in use anywhere in the device tree.  This will make the
maintenance of dev_mdgetprop() a large issue.  Every time a
new device is added there may be needs to amend the attach
protocol to add or modify properties.  These changes may need
to be different for each bus to which the device may be attached.

Secondly, if you need to control properties to such an extent,
translating a device-specific property from the firmware to
may require specific knowledge of the particular model of device
being queried, and may require a full device tree traversal
to be able to solve such conflicts in the information that the
firmware provides.  If recursion is required for all device
property this may result in full device tree traversals for
each node that is searched, resulting in abysmal performance.

My plan for machines that use OpenFirmware is to simply pass
the queries directly to the firmware and not do any translation.
Property translation is guaranteed to lose in such an environment.

The issue of conflicting properties can be solved by restricting
the query to the particular device the driver knows the property
must reside in.  This is almost always limited to either the device
itself, or very seldom, the direct parent.


	If that's the true expression of your belief, your proposal hasn't
	done it justice: the only way it does give you to determine the
	association of a property with a specific node (other than the current
	one) is rather inefficient.  (you need to search up the tree node by
	node.)  If you want to determine assocation of a property with a
	specific node, or a node within a certain 'distance' of you, you need
	to either return the node it's associated with, or pass an indicator
	of how far up you'd like to search.

While the query could be enhanced to return a pointer to the
node the property was retrieved from, that information lacks
meaningful semantics.  A pointer does not convey the type of
device or its relationship to other devices in the tree.  If
a driver needs to know this, there are only two ways to get
the information.  

The name of the device could be examined in the device node, 
but that requires the driver know the mappings of device names 
to types of devices or specific drivers.

The tree could be traversed upwards, examining each device node
for the specific type or device, until the driver finds a device 
node that matches the one returned.  But this could be done much
more efficiently by traversing the device tree and querying 
individual device nodes.

	I could see the latter as being a useful tool to make definition of
	property-passing protocols a bit more loose, but not in the 0/infinite
	form, and if you're going to loosen the protocols then you _really_
	need to be careful with this.

"0" is necessary for a complete interface.  All other queries can
be built on top of it.

"infinite" is provided to simplify the general case.


	An example of what I mean: if you're talking about searching from an
	'sd' device, it might be OK to use 0, 1, or 2 to mean "myself only,"
	"myself and my scsi bus" only, or "myself, my SCSI bus, and my
	controller only"...  But depending on how things are defined you might

Until you add the SCSI<->SCSI bridge, RAID controller, etc.  Then
the relation between device nodes becomes unclear.

	only need 0 or 1 (and I can see little use in using just 0)... and you
	should almost certainly never need a search depth >2 but less than
	"infinite."

Are you agreeing with me here?

	Also, if you do decide to e.g. make targets be real devices, i.e. have
	bus, target, lun represented by different layers, then: (a) if you
	define your protocols well and are always using "search everywhere"
	you can make things compatible, i.e. not have to hack use of
	properties at all for drivers which drive luns, and (b) if you do
	specifically name depths, you will have to go in and hack things.

In general you only do two queries: "0" to check for your own property
(or if you are a bus controller the property of your direct child for 
such things as SYNC, TQ, etc.) for properties that affect the behavior
of that specific device, and "infinite" for properties that are used to
attach.  In some extreme circumstances it may be necessary to query
your direct parent, but I can't think of any instance where those
queries cannot use inheritance.

Both "0" and "infinite" (as well as any other query you can think of)
can be built from "0", but "0" cannot be built from any other types of
queries.

Eduardo