summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew@wil.cx>2008-10-20 19:13:08 -0600
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-10-22 16:42:35 -0700
commitc4ed02fae78bf6cea0b22edd34a67df972f29832 (patch)
treeeaa2a319b16f601d43f1d39db768d3b6d7a5a4ff
parentd389fec6a2aec1ea7d47833f36a0413a619c8c12 (diff)
downloadlinux-3.10-c4ed02fae78bf6cea0b22edd34a67df972f29832.tar.gz
linux-3.10-c4ed02fae78bf6cea0b22edd34a67df972f29832.tar.bz2
linux-3.10-c4ed02fae78bf6cea0b22edd34a67df972f29832.zip
PCI: Fix reference counting bug
pci_get_subsys() will decrement the reference count of the device that it starts searching from. Unfortunately, the pci_find_device() interface will already have decremented the reference count of the device earlier, so the device will end up losing all reference counts and be freed. We can fix this by incrementing the reference count of the device to start searching from before calling pci_get_subsys(). Signed-off-by: Matthew Wilcox <willy@linux.intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r--drivers/pci/search.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 4edfc4731bd..5af8bd53814 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -166,6 +166,7 @@ struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device,
{
struct pci_dev *pdev;
+ pci_dev_get(from);
pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
pci_dev_put(pdev);
return pdev;
@@ -270,12 +271,8 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
struct pci_dev *pdev = NULL;
WARN_ON(in_interrupt());
- if (from) {
- /* FIXME
- * take the cast off, when bus_find_device is made const.
- */
- dev_start = (struct device *)&from->dev;
- }
+ if (from)
+ dev_start = &from->dev;
dev = bus_find_device(&pci_bus_type, dev_start, (void *)id,
match_pci_dev_by_id);
if (dev)