aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r--drivers/pci/probe.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index a10ed9dab2c..f89dbc3738b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -180,25 +180,31 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
180 res->flags |= pci_calc_resource_flags(l); 180 res->flags |= pci_calc_resource_flags(l);
181 if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) 181 if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
182 == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) { 182 == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
183 pci_read_config_dword(dev, reg+4, &l); 183 u32 szhi, lhi;
184 pci_read_config_dword(dev, reg+4, &lhi);
185 pci_write_config_dword(dev, reg+4, ~0);
186 pci_read_config_dword(dev, reg+4, &szhi);
187 pci_write_config_dword(dev, reg+4, lhi);
188 szhi = pci_size(lhi, szhi, 0xffffffff);
184 next++; 189 next++;
185#if BITS_PER_LONG == 64 190#if BITS_PER_LONG == 64
186 res->start |= ((unsigned long) l) << 32; 191 res->start |= ((unsigned long) lhi) << 32;
187 res->end = res->start + sz; 192 res->end = res->start + sz;
188 pci_write_config_dword(dev, reg+4, ~0); 193 if (szhi) {
189 pci_read_config_dword(dev, reg+4, &sz);
190 pci_write_config_dword(dev, reg+4, l);
191 sz = pci_size(l, sz, 0xffffffff);
192 if (sz) {
193 /* This BAR needs > 4GB? Wow. */ 194 /* This BAR needs > 4GB? Wow. */
194 res->end |= (unsigned long)sz<<32; 195 res->end |= (unsigned long)szhi<<32;
195 } 196 }
196#else 197#else
197 if (l) { 198 if (szhi) {
198 printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", pci_name(dev)); 199 printk(KERN_ERR "PCI: Unable to handle 64-bit BAR for device %s\n", pci_name(dev));
199 res->start = 0; 200 res->start = 0;
200 res->flags = 0; 201 res->flags = 0;
201 continue; 202 } else if (lhi) {
203 /* 64-bit wide address, treat as disabled */
204 pci_write_config_dword(dev, reg, l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK);
205 pci_write_config_dword(dev, reg+4, 0);
206 res->start = 0;
207 res->end = sz;
202 } 208 }
203#endif 209#endif
204 } 210 }
@@ -377,9 +383,9 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de
377 383
378 child = pci_alloc_child_bus(parent, dev, busnr); 384 child = pci_alloc_child_bus(parent, dev, busnr);
379 if (child) { 385 if (child) {
380 spin_lock(&pci_bus_lock); 386 down_write(&pci_bus_sem);
381 list_add_tail(&child->node, &parent->children); 387 list_add_tail(&child->node, &parent->children);
382 spin_unlock(&pci_bus_lock); 388 up_write(&pci_bus_sem);
383 } 389 }
384 return child; 390 return child;
385} 391}
@@ -838,9 +844,9 @@ void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
838 * and the bus list for fixup functions, etc. 844 * and the bus list for fixup functions, etc.
839 */ 845 */
840 INIT_LIST_HEAD(&dev->global_list); 846 INIT_LIST_HEAD(&dev->global_list);
841 spin_lock(&pci_bus_lock); 847 down_write(&pci_bus_sem);
842 list_add_tail(&dev->bus_list, &bus->devices); 848 list_add_tail(&dev->bus_list, &bus->devices);
843 spin_unlock(&pci_bus_lock); 849 up_write(&pci_bus_sem);
844} 850}
845 851
846struct pci_dev * __devinit 852struct pci_dev * __devinit
@@ -975,9 +981,10 @@ struct pci_bus * __devinit pci_create_bus(struct device *parent,
975 pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); 981 pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
976 goto err_out; 982 goto err_out;
977 } 983 }
978 spin_lock(&pci_bus_lock); 984
985 down_write(&pci_bus_sem);
979 list_add_tail(&b->node, &pci_root_buses); 986 list_add_tail(&b->node, &pci_root_buses);
980 spin_unlock(&pci_bus_lock); 987 up_write(&pci_bus_sem);
981 988
982 memset(dev, 0, sizeof(*dev)); 989 memset(dev, 0, sizeof(*dev));
983 dev->parent = parent; 990 dev->parent = parent;
@@ -1017,9 +1024,9 @@ class_dev_create_file_err:
1017class_dev_reg_err: 1024class_dev_reg_err:
1018 device_unregister(dev); 1025 device_unregister(dev);
1019dev_reg_err: 1026dev_reg_err:
1020 spin_lock(&pci_bus_lock); 1027 down_write(&pci_bus_sem);
1021 list_del(&b->node); 1028 list_del(&b->node);
1022 spin_unlock(&pci_bus_lock); 1029 up_write(&pci_bus_sem);
1023err_out: 1030err_out:
1024 kfree(dev); 1031 kfree(dev);
1025 kfree(b); 1032 kfree(b);