Re: [PATCH v3 13/17] ACPI: identify device tree root by null parent pointer, not ACPI_BUS_TYPE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2009-09-24 at 10:10 +0800, ykzhao wrote:
> On Thu, 2009-09-24 at 00:14 +0800, Bjorn Helgaas wrote:
> > On Tuesday 22 September 2009 09:09:44 pm ykzhao wrote:
> > > On Tue, 2009-09-22 at 03:29 +0800, Bjorn Helgaas wrote:
> > > > We can identify the root of the ACPI device tree by the fact that it
> > > > has no parent.  This is simpler than passing around ACPI_BUS_TYPE_SYSTEM
> > > > and will help remove special treatment of the device tree root.
> > > > 
> > > > Currently, we add the root by hand with ACPI_BUS_TYPE_SYSTEM.  If we
> > > > traverse the tree treating the root as just another device and use
> > > > acpi_get_type(), the root shows up as ACPI_TYPE_DEVICE.
> > > > 
> > > > Signed-off-by: Bjorn Helgaas <bjorn.helgaas@xxxxxx>
> > > > ---
> > > >  drivers/acpi/scan.c     |   20 +++++++++++++-------
> > > >  include/acpi/acpi_bus.h |    1 -
> > > >  2 files changed, 13 insertions(+), 8 deletions(-)
> > > > 
> > > > diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> > > > index 27d2dec..0b5aaf0 100644
> > > > --- a/drivers/acpi/scan.c
> > > > +++ b/drivers/acpi/scan.c
> > > > @@ -22,6 +22,8 @@ extern struct acpi_device *acpi_root;
> > > >  #define ACPI_BUS_HID			"LNXSYBUS"
> > > >  #define ACPI_BUS_DEVICE_NAME		"System Bus"
> > > >  
> > > > +#define ACPI_IS_ROOT_DEVICE(device)    (!(device)->parent)
> > 
> > > the following definition will be better
> > >    #define ACPI_IS_ROOT_DEVICE(device)  \
> > > 				(device->handle == ACPI_ROOT_OBJECT)
> > 
> > I wish you'd given me a clue about *why* you think it's better to
> > check the handle.
> Every acpi device has its corresponding acpi_handle. We can use this
> info to check whether the device is the root device. 
> 
> Of course it is also ok to check whether the device is the root device
> by using device->parent.
> > 
> > I considered checking the handle, but I used the parent pointer
> > because:
> > 
> >   1) There are synonyms for the root handle: ACPI_ROOT_OBJECT is the
> >      special-case #define to allow ACPICA users to start traversing
> >      the namespace before they know any handles, but acpi_gbl_root_node
> >      is the real root handle.  In fact, if you call acpi_get_parent()
> >      on a child of the root, it returns acpi_gbl_root_node, not
> >      ACPI_ROOT_OBJECT.  This is a bit messy, and it seems safest to
> >      me to just avoid testing against ACPI_ROOT_OBJECT at all.
> > 
> >   2) It's a reminder that the acpi_device tree data structure should
> >      be a proper fully-connected tree with exactly one root.  If we
> >      assume a valid tree, there's exactly one node with no parent.
> >      That's more fundamental than the handle, where you have to
> >      analyze more code to make sure we don't assign ACPI_ROOT_OBJECT
> >      to several nodes.
> > 
> >      (There is existing code that allows disconnected trees to be built.
> >      For example, dock_create_acpi_device() can call acpi_bus_add()
> >      with a NULL parent pointer.  This "shouldn't happen," but I
> >      consider the fact that the interface allows this to be a bug.
> >      That's one reason I'm removing the "parent" argument from
> >      acpi_add_single_object() and related interfaces.)
> > 
> >   3) We build acpi_devices for things with no handle, e.g., functional
> >      fixed hardware.  Their handles happen to be NULL but I prefer to
> >      think of them as undefined and not rely on them at all.
>        Is it possible to build the acpi_device without acpi handle? It
> seems that now we won't create a new acpi device for the functional
> fixed hardware.For example: the acpi handle is NULL when we add the acpi
> device for fixed power/sleep button.  In such case it is still different
> with the ACPI

This paragraph looks truncated, so maybe you didn't quite finish it.  In
any case, we do build acpi_devices for functional fixed hardware in
acpi_bus_scan_fixed(), and those devices have a NULL handle.

> >   4) acpi_walk_namespace(..., ACPI_ROOT_OBJECT, ...) doesn't actually
> >      visit the root node; it starts with the children.  I consider
> >      this a bug.  If it were ever fixed, we would probably call the
> >      callback with acpi_gbl_root_node, not ACPI_ROOT_OBJECT, so the
> >      root acpi_device handle would no longer be ACPI_ROOT_OBJECT.
>        When the ACPI_ROOT_OBJECT is passed to acpi_walk_namespace, then
> it will start from acpi_gbl_root_node(this is changed in the function of
> acpi_ns_walk_namespace).

Yes.  But the callback is never called for the root node, only for the
*children* of that node.  That's why, in patch 14/17 of this series,
where I convert acpi_bus_scan() to use acpi_walk_namespace(), I have to
call acpi_bus_check_add() once by hand on the root of the tree, followed
by acpi_walk_namespace() to walk the rest of the tree.

Bjorn

> > > > +
> > > >  static LIST_HEAD(acpi_device_list);
> > > >  static LIST_HEAD(acpi_bus_id_list);
> > > >  DEFINE_MUTEX(acpi_device_lock);
> > > > @@ -955,10 +957,12 @@ static void acpi_device_get_busid(struct acpi_device *device)
> > > >  	 * The device's Bus ID is simply the object name.
> > > >  	 * TBD: Shouldn't this value be unique (within the ACPI namespace)?
> > > >  	 */
> > > > -	switch (device->device_type) {
> > > > -	case ACPI_BUS_TYPE_SYSTEM:
> > > > +	if (ACPI_IS_ROOT_DEVICE(device)) {
> > > >  		strcpy(device->pnp.bus_id, "ACPI");
> > > > -		break;
> > > > +		return;
> > > > +	}
> > > > +
> > > > +	switch (device->device_type) {
> > > >  	case ACPI_BUS_TYPE_POWER_BUTTON:
> > > >  		strcpy(device->pnp.bus_id, "PWRF");
> > > >  		break;
> > > > @@ -1093,6 +1097,11 @@ static void acpi_device_set_id(struct acpi_device *device)
> > > >  
> > > >  	switch (device->device_type) {
> > > >  	case ACPI_BUS_TYPE_DEVICE:
> > > > +		if (ACPI_IS_ROOT_DEVICE(device)) {
> > > > +			hid = ACPI_SYSTEM_HID;
> > > > +			break;
> > > > +		}
> > > > +
> > > >  		status = acpi_get_object_info(device->handle, &info);
> > > >  		if (ACPI_FAILURE(status)) {
> > > >  			printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
> > > > @@ -1129,9 +1138,6 @@ static void acpi_device_set_id(struct acpi_device *device)
> > > >  	case ACPI_BUS_TYPE_PROCESSOR:
> > > >  		hid = ACPI_PROCESSOR_OBJECT_HID;
> > > >  		break;
> > > > -	case ACPI_BUS_TYPE_SYSTEM:
> > > > -		hid = ACPI_SYSTEM_HID;
> > > > -		break;
> > > >  	case ACPI_BUS_TYPE_THERMAL:
> > > >  		hid = ACPI_THERMAL_HID;
> > > >  		break;
> > > > @@ -1643,7 +1649,7 @@ int __init acpi_scan_init(void)
> > > >  	 * Create the root device in the bus's device tree
> > > >  	 */
> > > >  	result = acpi_add_single_object(&acpi_root, ACPI_ROOT_OBJECT,
> > > > -					ACPI_BUS_TYPE_SYSTEM, &ops);
> > > > +					ACPI_BUS_TYPE_DEVICE, &ops);
> > > >  	if (result)
> > > >  		goto Done;
> > > >  
> > > > diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> > > > index 8e39b3e..ef1cb23 100644
> > > > --- a/include/acpi/acpi_bus.h
> > > > +++ b/include/acpi/acpi_bus.h
> > > > @@ -70,7 +70,6 @@ enum acpi_bus_device_type {
> > > >  	ACPI_BUS_TYPE_POWER,
> > > >  	ACPI_BUS_TYPE_PROCESSOR,
> > > >  	ACPI_BUS_TYPE_THERMAL,
> > > > -	ACPI_BUS_TYPE_SYSTEM,
> > > >  	ACPI_BUS_TYPE_POWER_BUTTON,
> > > >  	ACPI_BUS_TYPE_SLEEP_BUTTON,
> > > >  	ACPI_BUS_DEVICE_TYPE_COUNT
> > > > 
> > > > --
> > > > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> > > > the body of a message to majordomo@xxxxxxxxxxxxxxx
> > > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > > 
> > > 
> > 
> > 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux