* [PATCH 0/3] Find pci root bridges by comparing HID from acpi_device_info, not acpi_device.
@ 2012-10-12 10:31 Tang Chen
2012-10-12 10:31 ` [PATCH 1/3] Introduce a new acpi to determine HID match Tang Chen
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Tang Chen @ 2012-10-12 10:31 UTC (permalink / raw)
To: yinghai, lenb, bhelgaas, izumi.taku, jiang.liu, linux-acpi,
linux-pci, linux-kernel
Hi Yinghai,
I found a little problem in your following patches. :)
[PATCH 00/40] PCI, ACPI, x86: pci root bus hotplug support.
In acpi_is_root_bridge(), it gets device's HID from acpi_device struct.
If the device is not added when the system boots, there will be no
acpi_device for it. And as a result, acpi_is_root_bridge() will fail.
But it doesn't mean that the device is not a root bridge.
In this case, the not-added root bridges have no handle_hotplug_event_root()
callback registerred. And when we hot add it later, it will do nothing.
This patch set changes the acpi_is_root_bridge()'s behavior. When we fail
to get HID from acpi_device, we will get HID from acpi_device_info by
acpi_get_object_info(), which gets the HID from ACPI namespace directly.
So no matter the device is present or not, we will always find out if it
is a pci root bridge, and register a handle_hotplug_event_root() callback
for it.
These patches are based on Lu Yinghai's for-pci-root-bus-hotplug branch.
Tang Chen (3):
Introduce a new acpi to determine HID match.
Do not use acpi_device to find pci root bridge in _init code.
Check exit status of acpi_install_notify_handler() in
find_root_bridges().
drivers/acpi/pci_root.c | 27 ++++++++++++++++++++++-----
drivers/acpi/pci_root_hp.c | 12 +++++++++---
drivers/acpi/scan.c | 24 ++++++++++++++++++++++++
include/acpi/acpi_bus.h | 2 ++
4 files changed, 57 insertions(+), 8 deletions(-)
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 1/3] Introduce a new acpi to determine HID match. 2012-10-12 10:31 [PATCH 0/3] Find pci root bridges by comparing HID from acpi_device_info, not acpi_device Tang Chen @ 2012-10-12 10:31 ` Tang Chen 2012-10-12 10:31 ` [PATCH 2/3] Do not use acpi_device to find pci root bridge in _init code Tang Chen 2012-10-12 10:31 ` [PATCH 3/3] Check exit status of acpi_install_notify_handler() in find_root_bridges() Tang Chen 2 siblings, 0 replies; 10+ messages in thread From: Tang Chen @ 2012-10-12 10:31 UTC (permalink / raw) To: yinghai, lenb, bhelgaas, izumi.taku, jiang.liu, linux-acpi, linux-pci, linux-kernel Cc: Tang Chen This introduce a new api to determine if a HID matches a list of IDs. Different from acpi_match_device_ids(), the new api gets HID from acpi_device_info struct. Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com> --- drivers/acpi/scan.c | 24 ++++++++++++++++++++++++ include/acpi/acpi_bus.h | 2 ++ 2 files changed, 26 insertions(+), 0 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 03c12e6..41fd4c9 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -312,6 +312,30 @@ int acpi_match_device_ids(struct acpi_device *device, } EXPORT_SYMBOL(acpi_match_device_ids); +int acpi_match_object_info_ids(struct acpi_device_info *info, + const struct acpi_device_id *ids) +{ + char *hardware_id; + int i, j; + + for (i = 0; ids[i].id[0]; i++) { + hardware_id = info->hardware_id.string; + if (hardware_id && + !strcmp((char *)ids[i].id, hardware_id)) + return 0; + + for (j = 0; j < info->compatible_id_list.count; j++) { + hardware_id = info->compatible_id_list.ids[j].string; + if (hardware_id && + !strcmp((char *)ids[i].id, hardware_id)) + return 0; + } + } + + return 1; +} +EXPORT_SYMBOL(acpi_match_object_info_ids); + static void acpi_free_ids(struct acpi_device *device) { struct acpi_hardware_id *id, *tmp; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index f0b9681..f83d581 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -379,6 +379,8 @@ int acpi_bus_start(struct acpi_device *device); acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd); int acpi_match_device_ids(struct acpi_device *device, const struct acpi_device_id *ids); +int acpi_match_object_info_ids(struct acpi_device_info *info, + const struct acpi_device_id *ids); int acpi_create_dir(struct acpi_device *); void acpi_remove_dir(struct acpi_device *); -- 1.7.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3] Do not use acpi_device to find pci root bridge in _init code. 2012-10-12 10:31 [PATCH 0/3] Find pci root bridges by comparing HID from acpi_device_info, not acpi_device Tang Chen 2012-10-12 10:31 ` [PATCH 1/3] Introduce a new acpi to determine HID match Tang Chen @ 2012-10-12 10:31 ` Tang Chen 2012-10-12 10:36 ` Jiang Liu 2012-10-12 10:31 ` [PATCH 3/3] Check exit status of acpi_install_notify_handler() in find_root_bridges() Tang Chen 2 siblings, 1 reply; 10+ messages in thread From: Tang Chen @ 2012-10-12 10:31 UTC (permalink / raw) To: yinghai, lenb, bhelgaas, izumi.taku, jiang.liu, linux-acpi, linux-pci, linux-kernel Cc: Tang Chen When the kernel is being initialized, and some hardwares are not added to system, there won't be acpi_device structs for these devices. But acpi_is_root_bridge() depends on acpi_device struct. As a result, all the not-added root bridge will not be judged as a root bridge in find_root_bridges(). And further more, no handle_hotplug_event_root() notifier will be installed for them. This patch introduces a new api to find all root bridges in system by getting HID directly from ACPI namespace, not depending on acpi_device struct. Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com> --- drivers/acpi/pci_root.c | 27 ++++++++++++++++++++++----- 1 files changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 7d0fb03..3819bee 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -128,9 +128,6 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); /** * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge * @handle - the ACPI CA node in question. - * - * Note: we could make this API take a struct acpi_device * instead, but - * for now, it's more convenient to operate on an acpi_handle. */ int acpi_is_root_bridge(acpi_handle handle) { @@ -138,8 +135,28 @@ int acpi_is_root_bridge(acpi_handle handle) struct acpi_device *device; ret = acpi_bus_get_device(handle, &device); - if (ret) - return 0; + if (ret) { + /** + * If a device is not added to the system yet, there won't be + * an acpi_device struct for it. But it doesn't mean it is not + * a PCI root bridge. In this case we need to get HID and CID + * from ACPI namespace directly. + */ + struct acpi_device_info *info; + acpi_status status; + status = acpi_get_object_info(handle, &info); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "%s: Error reading" + "device info\n", __func__); + return 0; + } + + ret = acpi_match_object_info_ids(info, root_device_ids); + if (ret) + return 0; + else + return 1; + } ret = acpi_match_device_ids(device, root_device_ids); if (ret) -- 1.7.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] Do not use acpi_device to find pci root bridge in _init code. 2012-10-12 10:31 ` [PATCH 2/3] Do not use acpi_device to find pci root bridge in _init code Tang Chen @ 2012-10-12 10:36 ` Jiang Liu 2012-10-12 10:42 ` Tang Chen 0 siblings, 1 reply; 10+ messages in thread From: Jiang Liu @ 2012-10-12 10:36 UTC (permalink / raw) To: Tang Chen Cc: yinghai, lenb, bhelgaas, izumi.taku, linux-acpi, linux-pci, linux-kernel On 2012-10-12 18:31, Tang Chen wrote: > When the kernel is being initialized, and some hardwares are not added > to system, there won't be acpi_device structs for these devices. But > acpi_is_root_bridge() depends on acpi_device struct. As a result, all > the not-added root bridge will not be judged as a root bridge in > find_root_bridges(). And further more, no handle_hotplug_event_root() > notifier will be installed for them. > > This patch introduces a new api to find all root bridges in system by > getting HID directly from ACPI namespace, not depending on acpi_device > struct. > > Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com> > --- > drivers/acpi/pci_root.c | 27 ++++++++++++++++++++++----- > 1 files changed, 22 insertions(+), 5 deletions(-) > > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c > index 7d0fb03..3819bee 100644 > --- a/drivers/acpi/pci_root.c > +++ b/drivers/acpi/pci_root.c > @@ -128,9 +128,6 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); > /** > * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge > * @handle - the ACPI CA node in question. > - * > - * Note: we could make this API take a struct acpi_device * instead, but > - * for now, it's more convenient to operate on an acpi_handle. > */ > int acpi_is_root_bridge(acpi_handle handle) > { > @@ -138,8 +135,28 @@ int acpi_is_root_bridge(acpi_handle handle) > struct acpi_device *device; > > ret = acpi_bus_get_device(handle, &device); > - if (ret) > - return 0; > + if (ret) { > + /** > + * If a device is not added to the system yet, there won't be > + * an acpi_device struct for it. But it doesn't mean it is not > + * a PCI root bridge. In this case we need to get HID and CID > + * from ACPI namespace directly. > + */ > + struct acpi_device_info *info; > + acpi_status status; > + status = acpi_get_object_info(handle, &info); > + if (ACPI_FAILURE(status)) { > + printk(KERN_ERR PREFIX "%s: Error reading" > + "device info\n", __func__); > + return 0; > + } > + > + ret = acpi_match_object_info_ids(info, root_device_ids); > + if (ret) > + return 0; > + else > + return 1; > + } I have sent a similar patch to Yinghai before. For simplicity, we could use acpi_match_object_info_ids() instead of acpi_match_device_ids() directly. Thanks! Gerry > > ret = acpi_match_device_ids(device, root_device_ids); > if (ret) ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] Do not use acpi_device to find pci root bridge in _init code. 2012-10-12 10:36 ` Jiang Liu @ 2012-10-12 10:42 ` Tang Chen 2012-10-12 10:54 ` Jiang Liu 0 siblings, 1 reply; 10+ messages in thread From: Tang Chen @ 2012-10-12 10:42 UTC (permalink / raw) To: Jiang Liu Cc: yinghai, lenb, bhelgaas, izumi.taku, linux-acpi, linux-pci, linux-kernel On 10/12/2012 06:36 PM, Jiang Liu wrote: > On 2012-10-12 18:31, Tang Chen wrote: >> When the kernel is being initialized, and some hardwares are not added >> to system, there won't be acpi_device structs for these devices. But >> acpi_is_root_bridge() depends on acpi_device struct. As a result, all >> the not-added root bridge will not be judged as a root bridge in >> find_root_bridges(). And further more, no handle_hotplug_event_root() >> notifier will be installed for them. >> >> This patch introduces a new api to find all root bridges in system by >> getting HID directly from ACPI namespace, not depending on acpi_device >> struct. >> >> Signed-off-by: Tang Chen<tangchen@cn.fujitsu.com> >> --- >> drivers/acpi/pci_root.c | 27 ++++++++++++++++++++++----- >> 1 files changed, 22 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c >> index 7d0fb03..3819bee 100644 >> --- a/drivers/acpi/pci_root.c >> +++ b/drivers/acpi/pci_root.c >> @@ -128,9 +128,6 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); >> /** >> * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge >> * @handle - the ACPI CA node in question. >> - * >> - * Note: we could make this API take a struct acpi_device * instead, but >> - * for now, it's more convenient to operate on an acpi_handle. >> */ >> int acpi_is_root_bridge(acpi_handle handle) >> { >> @@ -138,8 +135,28 @@ int acpi_is_root_bridge(acpi_handle handle) >> struct acpi_device *device; >> >> ret = acpi_bus_get_device(handle,&device); >> - if (ret) >> - return 0; >> + if (ret) { >> + /** >> + * If a device is not added to the system yet, there won't be >> + * an acpi_device struct for it. But it doesn't mean it is not >> + * a PCI root bridge. In this case we need to get HID and CID >> + * from ACPI namespace directly. >> + */ >> + struct acpi_device_info *info; >> + acpi_status status; >> + status = acpi_get_object_info(handle,&info); >> + if (ACPI_FAILURE(status)) { >> + printk(KERN_ERR PREFIX "%s: Error reading" >> + "device info\n", __func__); >> + return 0; >> + } >> + >> + ret = acpi_match_object_info_ids(info, root_device_ids); >> + if (ret) >> + return 0; >> + else >> + return 1; >> + } > I have sent a similar patch to Yinghai before. For simplicity, we could > use acpi_match_object_info_ids() instead of acpi_match_device_ids() > directly. Hum, I must have missed it. :) Using acpi_match_object_info_ids() directly seems good. I'm just worry about if it could cause any other problem. :) So now, is this bug fixed ? And we don't need these patches, right ? Thanks. :) > Thanks! > Gerry > >> >> ret = acpi_match_device_ids(device, root_device_ids); >> if (ret) > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-pci" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] Do not use acpi_device to find pci root bridge in _init code. 2012-10-12 10:42 ` Tang Chen @ 2012-10-12 10:54 ` Jiang Liu 2012-10-12 10:58 ` Tang Chen 2012-10-12 18:34 ` Yinghai Lu 0 siblings, 2 replies; 10+ messages in thread From: Jiang Liu @ 2012-10-12 10:54 UTC (permalink / raw) To: Tang Chen Cc: yinghai, lenb, bhelgaas, izumi.taku, linux-acpi, linux-pci, linux-kernel On 2012-10-12 18:42, Tang Chen wrote: > On 10/12/2012 06:36 PM, Jiang Liu wrote: >> On 2012-10-12 18:31, Tang Chen wrote: >>> When the kernel is being initialized, and some hardwares are not added >>> to system, there won't be acpi_device structs for these devices. But >>> acpi_is_root_bridge() depends on acpi_device struct. As a result, all >>> the not-added root bridge will not be judged as a root bridge in >>> find_root_bridges(). And further more, no handle_hotplug_event_root() >>> notifier will be installed for them. >>> >>> This patch introduces a new api to find all root bridges in system by >>> getting HID directly from ACPI namespace, not depending on acpi_device >>> struct. >>> >>> Signed-off-by: Tang Chen<tangchen@cn.fujitsu.com> >>> --- >>> drivers/acpi/pci_root.c | 27 ++++++++++++++++++++++----- >>> 1 files changed, 22 insertions(+), 5 deletions(-) >>> >>> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c >>> index 7d0fb03..3819bee 100644 >>> --- a/drivers/acpi/pci_root.c >>> +++ b/drivers/acpi/pci_root.c >>> @@ -128,9 +128,6 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); >>> /** >>> * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge >>> * @handle - the ACPI CA node in question. >>> - * >>> - * Note: we could make this API take a struct acpi_device * instead, but >>> - * for now, it's more convenient to operate on an acpi_handle. >>> */ >>> int acpi_is_root_bridge(acpi_handle handle) >>> { >>> @@ -138,8 +135,28 @@ int acpi_is_root_bridge(acpi_handle handle) >>> struct acpi_device *device; >>> >>> ret = acpi_bus_get_device(handle,&device); >>> - if (ret) >>> - return 0; >>> + if (ret) { >>> + /** >>> + * If a device is not added to the system yet, there won't be >>> + * an acpi_device struct for it. But it doesn't mean it is not >>> + * a PCI root bridge. In this case we need to get HID and CID >>> + * from ACPI namespace directly. >>> + */ >>> + struct acpi_device_info *info; >>> + acpi_status status; >>> + status = acpi_get_object_info(handle,&info); >>> + if (ACPI_FAILURE(status)) { >>> + printk(KERN_ERR PREFIX "%s: Error reading" >>> + "device info\n", __func__); >>> + return 0; >>> + } >>> + >>> + ret = acpi_match_object_info_ids(info, root_device_ids); >>> + if (ret) >>> + return 0; >>> + else >>> + return 1; >>> + } >> I have sent a similar patch to Yinghai before. For simplicity, we could >> use acpi_match_object_info_ids() instead of acpi_match_device_ids() >> directly. > > Hum, I must have missed it. :) > Using acpi_match_object_info_ids() directly seems good. I'm just worry > about if it could cause any other problem. :) > > So now, is this bug fixed ? And we don't need these patches, right ? > > Thanks. :) I think Yinghai has missed my patch too, so just suggest to use acpi_match_object_info_ids() directly. --Gerry > >> Thanks! >> Gerry >> >>> >>> ret = acpi_match_device_ids(device, root_device_ids); >>> if (ret) >> >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-pci" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html >> > > > . > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] Do not use acpi_device to find pci root bridge in _init code. 2012-10-12 10:54 ` Jiang Liu @ 2012-10-12 10:58 ` Tang Chen 2012-10-12 18:34 ` Yinghai Lu 1 sibling, 0 replies; 10+ messages in thread From: Tang Chen @ 2012-10-12 10:58 UTC (permalink / raw) To: Jiang Liu Cc: yinghai, lenb, bhelgaas, izumi.taku, linux-acpi, linux-pci, linux-kernel On 10/12/2012 06:54 PM, Jiang Liu wrote: >>> I have sent a similar patch to Yinghai before. For simplicity, we could >>> use acpi_match_object_info_ids() instead of acpi_match_device_ids() >>> directly. >> >> Hum, I must have missed it. :) >> Using acpi_match_object_info_ids() directly seems good. I'm just worry >> about if it could cause any other problem. :) >> >> So now, is this bug fixed ? And we don't need these patches, right ? >> >> Thanks. :) > I think Yinghai has missed my patch too, so just suggest to use > acpi_match_object_info_ids() directly. OK. :) I will resend a new patch set soon. Thanks for your advice. :) > > --Gerry > >> >>> Thanks! >>> Gerry >>> >>>> >>>> ret = acpi_match_device_ids(device, root_device_ids); >>>> if (ret) >>> >>> >>> -- >>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in >>> the body of a message to majordomo@vger.kernel.org >>> More majordomo info at http://vger.kernel.org/majordomo-info.html >>> >> >> >> . >> > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] Do not use acpi_device to find pci root bridge in _init code. 2012-10-12 10:54 ` Jiang Liu 2012-10-12 10:58 ` Tang Chen @ 2012-10-12 18:34 ` Yinghai Lu 2012-10-12 22:00 ` Yinghai Lu 1 sibling, 1 reply; 10+ messages in thread From: Yinghai Lu @ 2012-10-12 18:34 UTC (permalink / raw) To: Jiang Liu Cc: Tang Chen, lenb, bhelgaas, izumi.taku, linux-acpi, linux-pci, linux-kernel On Fri, Oct 12, 2012 at 3:54 AM, Jiang Liu <jiang.liu@huawei.com> wrote: > On 2012-10-12 18:42, Tang Chen wrote: >> On 10/12/2012 06:36 PM, Jiang Liu wrote: >>> I have sent a similar patch to Yinghai before. For simplicity, we could >>> use acpi_match_object_info_ids() instead of acpi_match_device_ids() >>> directly. >> >> Hum, I must have missed it. :) >> Using acpi_match_object_info_ids() directly seems good. I'm just worry >> about if it could cause any other problem. :) >> >> So now, is this bug fixed ? And we don't need these patches, right ? >> >> Thanks. :) > I think Yinghai has missed my patch too, so just suggest to use > acpi_match_object_info_ids() directly. i put that patch from Jiang in my branch for while, and later found it cause pci_root_bus notifying do not work anymore, so i dropped that. Yinghai ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] Do not use acpi_device to find pci root bridge in _init code. 2012-10-12 18:34 ` Yinghai Lu @ 2012-10-12 22:00 ` Yinghai Lu 0 siblings, 0 replies; 10+ messages in thread From: Yinghai Lu @ 2012-10-12 22:00 UTC (permalink / raw) To: Jiang Liu Cc: Tang Chen, lenb, bhelgaas, izumi.taku, linux-acpi, linux-pci, linux-kernel [-- Attachment #1: Type: text/plain, Size: 1238 bytes --] On Fri, Oct 12, 2012 at 11:34 AM, Yinghai Lu <yinghai@kernel.org> wrote: > On Fri, Oct 12, 2012 at 3:54 AM, Jiang Liu <jiang.liu@huawei.com> wrote: >> On 2012-10-12 18:42, Tang Chen wrote: >>> On 10/12/2012 06:36 PM, Jiang Liu wrote: >>>> I have sent a similar patch to Yinghai before. For simplicity, we could >>>> use acpi_match_object_info_ids() instead of acpi_match_device_ids() >>>> directly. >>> >>> Hum, I must have missed it. :) >>> Using acpi_match_object_info_ids() directly seems good. I'm just worry >>> about if it could cause any other problem. :) >>> >>> So now, is this bug fixed ? And we don't need these patches, right ? >>> >>> Thanks. :) >> I think Yinghai has missed my patch too, so just suggest to use >> acpi_match_object_info_ids() directly. > > i put that patch from Jiang in my branch for while, and later found it > cause pci_root_bus notifying > do not work anymore, so i dropped that. I updated three patches and put them into my for-pci-split-pci-root-hp-2 branch. http://git.kernel.org/?p=linux/kernel/git/yinghai/linux-yinghai.git;a=shortlog;h=refs/heads/for-pci-split-pci-root-hp-2 git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-pci-split-pci-root-hp-2 Thanks Yinghai [-- Attachment #2: 0001-ACPI-Introduce-a-new-acpi-handle-to-determine-HID-ma.patch --] [-- Type: application/octet-stream, Size: 2754 bytes --] From 073058d25883cd069abdbd7631dafddb2962742f Mon Sep 17 00:00:00 2001 From: Tang Chen <tangchen@cn.fujitsu.com> Date: Fri, 12 Oct 2012 20:34:19 +0800 Subject: [PATCH 1/3] ACPI: Introduce a new acpi handle to determine HID match. We need to find out if one handle is for root bridge, and install notify handler for it to handle pci root bus hot add. At that time, root bridge acpi device is not created yet. So acpi_match_device_ids() will not work. This patch add a function to check if new acpi handle's HID matches a list of IDs. The new api use acpi_device_info instead acpi_device. -v2: updated changelog, also check length for string info... change checking sequence by moving string comaring close to for loop. - Yinghai Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com> Signed-off-by: Yinghai Lu <yinghai@kernel.org> Cc: Len Brown <lenb@kernel.org> Cc: linux-acpi@vger.kernel.org --- drivers/acpi/scan.c | 33 +++++++++++++++++++++++++++++++++ include/acpi/acpi_bus.h | 2 ++ 2 files changed, 35 insertions(+), 0 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 5dfec09..33ca993 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -312,6 +312,39 @@ int acpi_match_device_ids(struct acpi_device *device, } EXPORT_SYMBOL(acpi_match_device_ids); +int acpi_match_object_info_ids(struct acpi_device_info *info, + const struct acpi_device_id *ids) +{ + const struct acpi_device_id *id; + char *str; + u32 len; + int i; + + len = info->hardware_id.length; + if (len) { + str = info->hardware_id.string; + if (str) + for (id = ids; id->id[0]; id++) + if (!strcmp((char *)id->id, str)) + return 0; + } + + for (i = 0; i < info->compatible_id_list.count; i++) { + len = info->compatible_id_list.ids[i].length; + if (!len) + continue; + str = info->compatible_id_list.ids[i].string; + if (!str) + continue; + for (id = ids; id->id[0]; id++) + if (!strcmp((char *)id->id, str)) + return 0; + } + + return -ENOENT; +} +EXPORT_SYMBOL(acpi_match_object_info_ids); + static void acpi_free_ids(struct acpi_device *device) { struct acpi_hardware_id *id, *tmp; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 608f92f..6ac415c 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -374,6 +374,8 @@ int acpi_bus_start(struct acpi_device *device); acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd); int acpi_match_device_ids(struct acpi_device *device, const struct acpi_device_id *ids); +int acpi_match_object_info_ids(struct acpi_device_info *info, + const struct acpi_device_id *ids); int acpi_create_dir(struct acpi_device *); void acpi_remove_dir(struct acpi_device *); -- 1.7.7 [-- Attachment #3: 0002-PCI-correctly-detect-ACPI-PCI-host-bridge-objects.patch --] [-- Type: application/octet-stream, Size: 2527 bytes --] From 265e6cab59db6261e1c2e4e144680252e5aceca8 Mon Sep 17 00:00:00 2001 From: Jiang Liu <jiang.liu@huawei.com> Date: Thu, 12 Apr 2012 00:27:03 +0800 Subject: [PATCH 2/3] PCI: correctly detect ACPI PCI host bridge objects The code in pci_root_hp.c depends on function acpi_is_root_bridge() to check whether an ACPI object is a PCI host bridge or not. If an ACPI device hasn't been created for the ACPI object yet, function acpi_is_root_bridge() will return false even if the object is a PCI host bridge object. That behavior will cause two issues: 1) No ACPI notification handler installed for PCI host bridges absent at startup, so hotplug events for those bridges won't be handled. 2) rescan_root_bridge() can't reenumerate offlined PCI host bridges because the ACPI devices have been already destroyed. So use acpi_match_object_info_ids() to correctly detect PCI host bridges. -v2: update to use acpi_match_object_info_ids() from Tang Chen - Yinghai Signed-off-by: Jiang Liu <jiang.liu@huawei.com> Signed-off-by: Yinghai Lu <yinghai@kernel.org> Cc: Len Brown <lenb@kernel.org> Cc: linux-acpi@vger.kernel.org --- drivers/acpi/pci_root_hp.c | 25 ++++++++++++++++++++++++- 1 files changed, 24 insertions(+), 1 deletions(-) diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c index 2aebf78..3edec7f 100644 --- a/drivers/acpi/pci_root_hp.c +++ b/drivers/acpi/pci_root_hp.c @@ -19,6 +19,12 @@ struct acpi_root_bridge { u32 flags; }; +static const struct acpi_device_id root_device_ids[] = { + {"PNP0A03", 0}, + {"PNP0A08", 0}, + {"", 0}, +}; + /* bridge flags */ #define ROOT_BRIDGE_HAS_EJ0 (0x00000002) #define ROOT_BRIDGE_HAS_PS3 (0x00000080) @@ -256,6 +262,23 @@ static void handle_hotplug_event_root(acpi_handle handle, u32 type, _handle_hotplug_event_root); } +static bool acpi_is_root_bridge_object(acpi_handle handle) +{ + struct acpi_device_info *info = NULL; + acpi_status status; + bool ret; + + status = acpi_get_object_info(handle, &info); + if (ACPI_FAILURE(status)) + return false; + + ret = !acpi_match_object_info_ids(info, root_device_ids); + + kfree(info); + + return ret; +} + static acpi_status __init find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) { @@ -264,7 +287,7 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) .pointer = objname }; int *count = (int *)context; - if (!acpi_is_root_bridge(handle)) + if (!acpi_is_root_bridge_object(handle)) return AE_OK; (*count)++; -- 1.7.7 [-- Attachment #4: 0003-PCI-ACPI-debug-print-for-installation-of-acpi-root-b.patch --] [-- Type: application/octet-stream, Size: 1750 bytes --] From d0793097ec0ecebef45eb98e9632b978d0f77370 Mon Sep 17 00:00:00 2001 From: Tang Chen <tangchen@cn.fujitsu.com> Date: Fri, 12 Oct 2012 20:34:21 +0800 Subject: [PATCH 3/3] PCI, ACPI: debug print for installation of acpi root bridge's notifier acpi_install_notify_handler() could fail. So check the exit status and give a better debug info. Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com> Singed-off-by: Yinghai Lu <yinghai@kernel.org> --- drivers/acpi/pci_root_hp.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c index 3edec7f..01e71f6 100644 --- a/drivers/acpi/pci_root_hp.c +++ b/drivers/acpi/pci_root_hp.c @@ -282,6 +282,7 @@ static bool acpi_is_root_bridge_object(acpi_handle handle) static acpi_status __init find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) { + acpi_status status; char objname[64]; struct acpi_buffer buffer = { .length = sizeof(objname), .pointer = objname }; @@ -294,9 +295,14 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); - acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_root, NULL); - printk(KERN_DEBUG "acpi root: %s notify handler installed\n", objname); + status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + handle_hotplug_event_root, NULL); + if (ACPI_FAILURE(status)) + printk(KERN_DEBUG "acpi root: %s notify handler is not installed, exit status: %u\n", + objname, (unsigned int)status); + else + printk(KERN_DEBUG "acpi root: %s notify handler is installed\n", + objname); add_acpi_root_bridge(handle); -- 1.7.7 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] Check exit status of acpi_install_notify_handler() in find_root_bridges(). 2012-10-12 10:31 [PATCH 0/3] Find pci root bridges by comparing HID from acpi_device_info, not acpi_device Tang Chen 2012-10-12 10:31 ` [PATCH 1/3] Introduce a new acpi to determine HID match Tang Chen 2012-10-12 10:31 ` [PATCH 2/3] Do not use acpi_device to find pci root bridge in _init code Tang Chen @ 2012-10-12 10:31 ` Tang Chen 2 siblings, 0 replies; 10+ messages in thread From: Tang Chen @ 2012-10-12 10:31 UTC (permalink / raw) To: yinghai, lenb, bhelgaas, izumi.taku, jiang.liu, linux-acpi, linux-pci, linux-kernel Cc: Tang Chen acpi_install_notify_handler() could fail. So check the exit status and give a better debug info. Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com> --- drivers/acpi/pci_root_hp.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c index 05a88ae..1985749 100644 --- a/drivers/acpi/pci_root_hp.c +++ b/drivers/acpi/pci_root_hp.c @@ -246,6 +246,7 @@ static void handle_hotplug_event_root(acpi_handle handle, u32 type, static acpi_status __init find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) { + acpi_status status; char objname[64]; struct acpi_buffer buffer = { .length = sizeof(objname), .pointer = objname }; @@ -258,9 +259,14 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); - acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_root, NULL); - printk(KERN_DEBUG "acpi root: %s notify handler installed\n", objname); + status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + handle_hotplug_event_root, NULL); + if (ACPI_FAILURE(status)) + printk(KERN_DEBUG "acpi root: %s notify handler not installed\n" + "acpi root: exit status: %u\n", + objname, (unsigned int)status); + else + printk(KERN_DEBUG "acpi root: %s notify handler installed\n", objname); add_acpi_root_bridge(handle); -- 1.7.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2012-10-12 22:00 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-10-12 10:31 [PATCH 0/3] Find pci root bridges by comparing HID from acpi_device_info, not acpi_device Tang Chen 2012-10-12 10:31 ` [PATCH 1/3] Introduce a new acpi to determine HID match Tang Chen 2012-10-12 10:31 ` [PATCH 2/3] Do not use acpi_device to find pci root bridge in _init code Tang Chen 2012-10-12 10:36 ` Jiang Liu 2012-10-12 10:42 ` Tang Chen 2012-10-12 10:54 ` Jiang Liu 2012-10-12 10:58 ` Tang Chen 2012-10-12 18:34 ` Yinghai Lu 2012-10-12 22:00 ` Yinghai Lu 2012-10-12 10:31 ` [PATCH 3/3] Check exit status of acpi_install_notify_handler() in find_root_bridges() Tang Chen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox