aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2013-06-14 19:47:46 -0400
committerBjorn Helgaas <bhelgaas@google.com>2013-06-14 19:47:46 -0400
commitdf58f46c0f2a1d69268b734ac25c87ffb7aeb32a (patch)
tree46540d251f4f1c1e44af8d5ce339b37e0045ffe0 /drivers
parent726246d2e6d0ed53ac22b6fec50d1345f25e6730 (diff)
parent050134864c1c76f49eb86c134a0e02fb3c196382 (diff)
Merge branch 'pci/jiang-bus-lock-v3' into next
* pci/jiang-bus-lock-v3: PCI: Return early on allocation failures to unindent mainline code PCI: Simplify IOV implementation and fix reference count races PCI: Drop redundant setting of bus->is_added in virtfn_add_bus() unicore32/PCI: Remove redundant call of pci_bus_add_devices() m68k/PCI: Remove redundant call of pci_bus_add_devices() PCI: Rename pci_release_bus_bridge_dev() to pci_release_host_bridge_dev() PCI: Fix refcount issue in pci_create_root_bus() error recovery path ia64/PCI: Clean up pci_scan_root_bus() usage PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) PCI: Introduce pci_alloc_dev(struct pci_bus*) to replace alloc_pci_dev() PCI: Introduce pci_bus_{get|put}() to manage PCI bus reference count Conflicts: drivers/pci/probe.c
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/agp/alpha-agp.c2
-rw-r--r--drivers/char/agp/parisc-agp.c2
-rw-r--r--drivers/pci/bus.c15
-rw-r--r--drivers/pci/iov.c60
-rw-r--r--drivers/pci/probe.c83
-rw-r--r--drivers/scsi/megaraid.c2
6 files changed, 90 insertions, 74 deletions
diff --git a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c
index dd84af4d4f7e..199b8e99f7d7 100644
--- a/drivers/char/agp/alpha-agp.c
+++ b/drivers/char/agp/alpha-agp.c
@@ -174,7 +174,7 @@ alpha_core_agp_setup(void)
174 /* 174 /*
175 * Build a fake pci_dev struct 175 * Build a fake pci_dev struct
176 */ 176 */
177 pdev = alloc_pci_dev(); 177 pdev = pci_alloc_dev(NULL);
178 if (!pdev) 178 if (!pdev)
179 return -ENOMEM; 179 return -ENOMEM;
180 pdev->vendor = 0xffff; 180 pdev->vendor = 0xffff;
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index 94821ab01c6d..bf5d2477cb77 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -333,7 +333,7 @@ parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa)
333 struct agp_bridge_data *bridge; 333 struct agp_bridge_data *bridge;
334 int error = 0; 334 int error = 0;
335 335
336 fake_bridge_dev = alloc_pci_dev(); 336 fake_bridge_dev = pci_alloc_dev(NULL);
337 if (!fake_bridge_dev) { 337 if (!fake_bridge_dev) {
338 error = -ENOMEM; 338 error = -ENOMEM;
339 goto fail; 339 goto fail;
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 32e66a6f12d9..b1ff02ab4f13 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -283,6 +283,21 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
283} 283}
284EXPORT_SYMBOL_GPL(pci_walk_bus); 284EXPORT_SYMBOL_GPL(pci_walk_bus);
285 285
286struct pci_bus *pci_bus_get(struct pci_bus *bus)
287{
288 if (bus)
289 get_device(&bus->dev);
290 return bus;
291}
292EXPORT_SYMBOL(pci_bus_get);
293
294void pci_bus_put(struct pci_bus *bus)
295{
296 if (bus)
297 put_device(&bus->dev);
298}
299EXPORT_SYMBOL(pci_bus_put);
300
286EXPORT_SYMBOL(pci_bus_alloc_resource); 301EXPORT_SYMBOL(pci_bus_alloc_resource);
287EXPORT_SYMBOL_GPL(pci_bus_add_device); 302EXPORT_SYMBOL_GPL(pci_bus_add_device);
288EXPORT_SYMBOL(pci_bus_add_devices); 303EXPORT_SYMBOL(pci_bus_add_devices);
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index a971a6f6268d..de8ffacf9c9b 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -47,46 +47,36 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
47 return NULL; 47 return NULL;
48 48
49 pci_bus_insert_busn_res(child, busnr, busnr); 49 pci_bus_insert_busn_res(child, busnr, busnr);
50 bus->is_added = 1;
51 50
52 return child; 51 return child;
53} 52}
54 53
55static void virtfn_remove_bus(struct pci_bus *bus, int busnr) 54static void virtfn_remove_bus(struct pci_bus *physbus, struct pci_bus *virtbus)
56{ 55{
57 struct pci_bus *child; 56 if (physbus != virtbus && list_empty(&virtbus->devices))
58 57 pci_remove_bus(virtbus);
59 if (bus->number == busnr)
60 return;
61
62 child = pci_find_bus(pci_domain_nr(bus), busnr);
63 BUG_ON(!child);
64
65 if (list_empty(&child->devices))
66 pci_remove_bus(child);
67} 58}
68 59
69static int virtfn_add(struct pci_dev *dev, int id, int reset) 60static int virtfn_add(struct pci_dev *dev, int id, int reset)
70{ 61{
71 int i; 62 int i;
72 int rc; 63 int rc = -ENOMEM;
73 u64 size; 64 u64 size;
74 char buf[VIRTFN_ID_LEN]; 65 char buf[VIRTFN_ID_LEN];
75 struct pci_dev *virtfn; 66 struct pci_dev *virtfn;
76 struct resource *res; 67 struct resource *res;
77 struct pci_sriov *iov = dev->sriov; 68 struct pci_sriov *iov = dev->sriov;
69 struct pci_bus *bus;
78 70
79 virtfn = alloc_pci_dev(); 71 mutex_lock(&iov->dev->sriov->lock);
72 bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
73 if (!bus)
74 goto failed;
75
76 virtfn = pci_alloc_dev(bus);
80 if (!virtfn) 77 if (!virtfn)
81 return -ENOMEM; 78 goto failed0;
82 79
83 mutex_lock(&iov->dev->sriov->lock);
84 virtfn->bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
85 if (!virtfn->bus) {
86 kfree(virtfn);
87 mutex_unlock(&iov->dev->sriov->lock);
88 return -ENOMEM;
89 }
90 virtfn->devfn = virtfn_devfn(dev, id); 80 virtfn->devfn = virtfn_devfn(dev, id);
91 virtfn->vendor = dev->vendor; 81 virtfn->vendor = dev->vendor;
92 pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device); 82 pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device);
@@ -134,7 +124,9 @@ failed1:
134 pci_dev_put(dev); 124 pci_dev_put(dev);
135 mutex_lock(&iov->dev->sriov->lock); 125 mutex_lock(&iov->dev->sriov->lock);
136 pci_stop_and_remove_bus_device(virtfn); 126 pci_stop_and_remove_bus_device(virtfn);
137 virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); 127failed0:
128 virtfn_remove_bus(dev->bus, bus);
129failed:
138 mutex_unlock(&iov->dev->sriov->lock); 130 mutex_unlock(&iov->dev->sriov->lock);
139 131
140 return rc; 132 return rc;
@@ -143,20 +135,15 @@ failed1:
143static void virtfn_remove(struct pci_dev *dev, int id, int reset) 135static void virtfn_remove(struct pci_dev *dev, int id, int reset)
144{ 136{
145 char buf[VIRTFN_ID_LEN]; 137 char buf[VIRTFN_ID_LEN];
146 struct pci_bus *bus;
147 struct pci_dev *virtfn; 138 struct pci_dev *virtfn;
148 struct pci_sriov *iov = dev->sriov; 139 struct pci_sriov *iov = dev->sriov;
149 140
150 bus = pci_find_bus(pci_domain_nr(dev->bus), virtfn_bus(dev, id)); 141 virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus),
151 if (!bus) 142 virtfn_bus(dev, id),
152 return; 143 virtfn_devfn(dev, id));
153
154 virtfn = pci_get_slot(bus, virtfn_devfn(dev, id));
155 if (!virtfn) 144 if (!virtfn)
156 return; 145 return;
157 146
158 pci_dev_put(virtfn);
159
160 if (reset) { 147 if (reset) {
161 device_release_driver(&virtfn->dev); 148 device_release_driver(&virtfn->dev);
162 __pci_reset_function(virtfn); 149 __pci_reset_function(virtfn);
@@ -174,9 +161,11 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset)
174 161
175 mutex_lock(&iov->dev->sriov->lock); 162 mutex_lock(&iov->dev->sriov->lock);
176 pci_stop_and_remove_bus_device(virtfn); 163 pci_stop_and_remove_bus_device(virtfn);
177 virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); 164 virtfn_remove_bus(dev->bus, virtfn->bus);
178 mutex_unlock(&iov->dev->sriov->lock); 165 mutex_unlock(&iov->dev->sriov->lock);
179 166
167 /* balance pci_get_domain_bus_and_slot() */
168 pci_dev_put(virtfn);
180 pci_dev_put(dev); 169 pci_dev_put(dev);
181} 170}
182 171
@@ -333,13 +322,14 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
333 if (!pdev) 322 if (!pdev)
334 return -ENODEV; 323 return -ENODEV;
335 324
336 pci_dev_put(pdev); 325 if (!pdev->is_physfn) {
337 326 pci_dev_put(pdev);
338 if (!pdev->is_physfn)
339 return -ENODEV; 327 return -ENODEV;
328 }
340 329
341 rc = sysfs_create_link(&dev->dev.kobj, 330 rc = sysfs_create_link(&dev->dev.kobj,
342 &pdev->dev.kobj, "dep_link"); 331 &pdev->dev.kobj, "dep_link");
332 pci_dev_put(pdev);
343 if (rc) 333 if (rc)
344 return rc; 334 return rc;
345 } 335 }
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index d0c33aac768e..46ada5c098eb 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -470,33 +470,46 @@ void pci_read_bridge_bases(struct pci_bus *child)
470 } 470 }
471} 471}
472 472
473static struct pci_bus * pci_alloc_bus(void) 473static struct pci_bus *pci_alloc_bus(void)
474{ 474{
475 struct pci_bus *b; 475 struct pci_bus *b;
476 476
477 b = kzalloc(sizeof(*b), GFP_KERNEL); 477 b = kzalloc(sizeof(*b), GFP_KERNEL);
478 if (b) { 478 if (!b)
479 INIT_LIST_HEAD(&b->node); 479 return NULL;
480 INIT_LIST_HEAD(&b->children); 480
481 INIT_LIST_HEAD(&b->devices); 481 INIT_LIST_HEAD(&b->node);
482 INIT_LIST_HEAD(&b->slots); 482 INIT_LIST_HEAD(&b->children);
483 INIT_LIST_HEAD(&b->resources); 483 INIT_LIST_HEAD(&b->devices);
484 b->max_bus_speed = PCI_SPEED_UNKNOWN; 484 INIT_LIST_HEAD(&b->slots);
485 b->cur_bus_speed = PCI_SPEED_UNKNOWN; 485 INIT_LIST_HEAD(&b->resources);
486 } 486 b->max_bus_speed = PCI_SPEED_UNKNOWN;
487 b->cur_bus_speed = PCI_SPEED_UNKNOWN;
487 return b; 488 return b;
488} 489}
489 490
491static void pci_release_host_bridge_dev(struct device *dev)
492{
493 struct pci_host_bridge *bridge = to_pci_host_bridge(dev);
494
495 if (bridge->release_fn)
496 bridge->release_fn(bridge);
497
498 pci_free_resource_list(&bridge->windows);
499
500 kfree(bridge);
501}
502
490static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b) 503static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
491{ 504{
492 struct pci_host_bridge *bridge; 505 struct pci_host_bridge *bridge;
493 506
494 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); 507 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
495 if (bridge) { 508 if (!bridge)
496 INIT_LIST_HEAD(&bridge->windows); 509 return NULL;
497 bridge->bus = b;
498 }
499 510
511 INIT_LIST_HEAD(&bridge->windows);
512 bridge->bus = b;
500 return bridge; 513 return bridge;
501} 514}
502 515
@@ -1152,6 +1165,7 @@ static void pci_release_dev(struct device *dev)
1152 pci_release_capabilities(pci_dev); 1165 pci_release_capabilities(pci_dev);
1153 pci_release_of_node(pci_dev); 1166 pci_release_of_node(pci_dev);
1154 pcibios_release_device(pci_dev); 1167 pcibios_release_device(pci_dev);
1168 pci_bus_put(pci_dev->bus);
1155 kfree(pci_dev); 1169 kfree(pci_dev);
1156} 1170}
1157 1171
@@ -1208,19 +1222,7 @@ int pci_cfg_space_size(struct pci_dev *dev)
1208 return PCI_CFG_SPACE_SIZE; 1222 return PCI_CFG_SPACE_SIZE;
1209} 1223}
1210 1224
1211static void pci_release_bus_bridge_dev(struct device *dev) 1225struct pci_dev *pci_alloc_dev(struct pci_bus *bus)
1212{
1213 struct pci_host_bridge *bridge = to_pci_host_bridge(dev);
1214
1215 if (bridge->release_fn)
1216 bridge->release_fn(bridge);
1217
1218 pci_free_resource_list(&bridge->windows);
1219
1220 kfree(bridge);
1221}
1222
1223struct pci_dev *alloc_pci_dev(void)
1224{ 1226{
1225 struct pci_dev *dev; 1227 struct pci_dev *dev;
1226 1228
@@ -1230,9 +1232,16 @@ struct pci_dev *alloc_pci_dev(void)
1230 1232
1231 INIT_LIST_HEAD(&dev->bus_list); 1233 INIT_LIST_HEAD(&dev->bus_list);
1232 dev->dev.type = &pci_dev_type; 1234 dev->dev.type = &pci_dev_type;
1235 dev->bus = pci_bus_get(bus);
1233 1236
1234 return dev; 1237 return dev;
1235} 1238}
1239EXPORT_SYMBOL(pci_alloc_dev);
1240
1241struct pci_dev *alloc_pci_dev(void)
1242{
1243 return pci_alloc_dev(NULL);
1244}
1236EXPORT_SYMBOL(alloc_pci_dev); 1245EXPORT_SYMBOL(alloc_pci_dev);
1237 1246
1238bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l, 1247bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
@@ -1283,11 +1292,10 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
1283 if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000)) 1292 if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000))
1284 return NULL; 1293 return NULL;
1285 1294
1286 dev = alloc_pci_dev(); 1295 dev = pci_alloc_dev(bus);
1287 if (!dev) 1296 if (!dev)
1288 return NULL; 1297 return NULL;
1289 1298
1290 dev->bus = bus;
1291 dev->devfn = devfn; 1299 dev->devfn = devfn;
1292 dev->vendor = l & 0xffff; 1300 dev->vendor = l & 0xffff;
1293 dev->device = (l >> 16) & 0xffff; 1301 dev->device = (l >> 16) & 0xffff;
@@ -1295,6 +1303,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
1295 pci_set_of_node(dev); 1303 pci_set_of_node(dev);
1296 1304
1297 if (pci_setup_device(dev)) { 1305 if (pci_setup_device(dev)) {
1306 pci_bus_put(dev->bus);
1298 kfree(dev); 1307 kfree(dev);
1299 return NULL; 1308 return NULL;
1300 } 1309 }
@@ -1720,15 +1729,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1720 goto err_out; 1729 goto err_out;
1721 1730
1722 bridge->dev.parent = parent; 1731 bridge->dev.parent = parent;
1723 bridge->dev.release = pci_release_bus_bridge_dev; 1732 bridge->dev.release = pci_release_host_bridge_dev;
1724 dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); 1733 dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
1725 error = pcibios_root_bridge_prepare(bridge); 1734 error = pcibios_root_bridge_prepare(bridge);
1726 if (error) 1735 if (error) {
1727 goto bridge_dev_reg_err; 1736 kfree(bridge);
1737 goto err_out;
1738 }
1728 1739
1729 error = device_register(&bridge->dev); 1740 error = device_register(&bridge->dev);
1730 if (error) 1741 if (error) {
1731 goto bridge_dev_reg_err; 1742 put_device(&bridge->dev);
1743 goto err_out;
1744 }
1732 b->bridge = get_device(&bridge->dev); 1745 b->bridge = get_device(&bridge->dev);
1733 device_enable_async_suspend(b->bridge); 1746 device_enable_async_suspend(b->bridge);
1734 pci_set_bus_of_node(b); 1747 pci_set_bus_of_node(b);
@@ -1784,8 +1797,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1784class_dev_reg_err: 1797class_dev_reg_err:
1785 put_device(&bridge->dev); 1798 put_device(&bridge->dev);
1786 device_unregister(&bridge->dev); 1799 device_unregister(&bridge->dev);
1787bridge_dev_reg_err:
1788 kfree(bridge);
1789err_out: 1800err_out:
1790 kfree(b); 1801 kfree(b);
1791 return NULL; 1802 return NULL;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 846f475f62c1..90c95a3385d1 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -2026,7 +2026,7 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor)
2026static inline int 2026static inline int
2027make_local_pdev(adapter_t *adapter, struct pci_dev **pdev) 2027make_local_pdev(adapter_t *adapter, struct pci_dev **pdev)
2028{ 2028{
2029 *pdev = alloc_pci_dev(); 2029 *pdev = pci_alloc_dev(NULL);
2030 2030
2031 if( *pdev == NULL ) return -1; 2031 if( *pdev == NULL ) return -1;
2032 2032