[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20081220105658.GA1760@localhost.localdomain>
Date: Sat, 20 Dec 2008 11:56:58 +0100
From: Vegard Nossum <vegard.nossum@...il.com>
To: Greg KH <gregkh@...e.de>, Jesse Barnes <jbarnes@...tuousgeek.org>
Cc: Pekka Enberg <penberg@...helsinki.fi>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: [PATCH] pci: fix no_pci_devices()
On Sat, Dec 20, 2008 at 9:58 AM, Greg KH <gregkh@...e.de> wrote:
> Care to make a patch for no_pci_devices() to work properly in this kind
> of situation?
How does this look?
I have introduced a variable pci_is_initiated, which is set after the bus
has been registered.
Should the variable be atomic? My assumption is that initcalls are
synchronous and that the variable therefore cannot be accessed concurrently
by two or more CPUs.
Vegard
>From 409132338c9a6122dc7da08d2764492dbf351f32 Mon Sep 17 00:00:00 2001
From: Vegard Nossum <vegard.nossum@...il.com>
Date: Sat, 20 Dec 2008 11:37:16 +0100
Subject: [PATCH] pci: fix no_pci_devices()
In short, no_pci_devices() should not use bus_find_device() before
initcalls have run, because the pci bus structure has not been
initialized yet.
Reference: http://lkml.org/lkml/2008/12/20/21
Cc: Greg KH <gregkh@...e.de>
Cc: Pekka Enberg <penberg@...helsinki.fi>
Signed-off-by: Vegard Nossum <vegard.nossum@...il.com>
---
drivers/pci/pci-driver.c | 10 +++++++++-
drivers/pci/probe.c | 3 +++
include/linux/pci.h | 1 +
3 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index b4cdd69..9e0215e 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -825,6 +825,8 @@ int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
}
#endif
+int pci_is_initiated __read_mostly;
+
struct bus_type pci_bus_type = {
.name = "pci",
.match = pci_bus_match,
@@ -838,7 +840,13 @@ struct bus_type pci_bus_type = {
static int __init pci_driver_init(void)
{
- return bus_register(&pci_bus_type);
+ int ret;
+
+ ret = bus_register(&pci_bus_type);
+ if (ret == 0)
+ pci_is_initiated = 1;
+
+ return ret;
}
postcore_initcall(pci_driver_init);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 003a9b3..1320a81 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -35,6 +35,9 @@ int no_pci_devices(void)
struct device *dev;
int no_devices;
+ if (!pci_is_initiated)
+ return 1;
+
dev = bus_find_device(&pci_bus_type, NULL, NULL, find_anything);
no_devices = (dev == NULL);
put_device(dev);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index feb4657..9e1b30f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -484,6 +484,7 @@ extern struct bus_type pci_bus_type;
* code, or pci core code. */
extern struct list_head pci_root_buses; /* list of all known PCI buses */
/* Some device drivers need know if pci is initiated */
+extern int pci_is_initiated;
extern int no_pci_devices(void);
void pcibios_fixup_bus(struct pci_bus *);
--
1.5.6.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists