aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/search.c
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew@wil.cx>2008-10-20 21:13:08 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-10-22 19:42:35 -0400
commitc4ed02fae78bf6cea0b22edd34a67df972f29832 (patch)
treeeaa2a319b16f601d43f1d39db768d3b6d7a5a4ff /drivers/pci/search.c
parentd389fec6a2aec1ea7d47833f36a0413a619c8c12 (diff)
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>
Diffstat (limited to 'drivers/pci/search.c')
-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 4edfc4731bd4..5af8bd538149 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,
166{ 166{
167 struct pci_dev *pdev; 167 struct pci_dev *pdev;
168 168
169 pci_dev_get(from);
169 pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); 170 pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
170 pci_dev_put(pdev); 171 pci_dev_put(pdev);
171 return pdev; 172 return pdev;
@@ -270,12 +271,8 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
270 struct pci_dev *pdev = NULL; 271 struct pci_dev *pdev = NULL;
271 272
272 WARN_ON(in_interrupt()); 273 WARN_ON(in_interrupt());
273 if (from) { 274 if (from)
274 /* FIXME 275 dev_start = &from->dev;
275 * take the cast off, when bus_find_device is made const.
276 */
277 dev_start = (struct device *)&from->dev;
278 }
279 dev = bus_find_device(&pci_bus_type, dev_start, (void *)id, 276 dev = bus_find_device(&pci_bus_type, dev_start, (void *)id,
280 match_pci_dev_by_id); 277 match_pci_dev_by_id);
281 if (dev) 278 if (dev)