diff options
Diffstat (limited to 'drivers/pci/access.c')
-rw-r--r-- | drivers/pci/access.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 2f646fe1260f..531bc697d800 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c | |||
@@ -13,7 +13,7 @@ | |||
13 | * configuration space. | 13 | * configuration space. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | static DEFINE_SPINLOCK(pci_lock); | 16 | static DEFINE_RAW_SPINLOCK(pci_lock); |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * Wrappers for all PCI configuration access functions. They just check | 19 | * Wrappers for all PCI configuration access functions. They just check |
@@ -33,10 +33,10 @@ int pci_bus_read_config_##size \ | |||
33 | unsigned long flags; \ | 33 | unsigned long flags; \ |
34 | u32 data = 0; \ | 34 | u32 data = 0; \ |
35 | if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ | 35 | if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ |
36 | spin_lock_irqsave(&pci_lock, flags); \ | 36 | raw_spin_lock_irqsave(&pci_lock, flags); \ |
37 | res = bus->ops->read(bus, devfn, pos, len, &data); \ | 37 | res = bus->ops->read(bus, devfn, pos, len, &data); \ |
38 | *value = (type)data; \ | 38 | *value = (type)data; \ |
39 | spin_unlock_irqrestore(&pci_lock, flags); \ | 39 | raw_spin_unlock_irqrestore(&pci_lock, flags); \ |
40 | return res; \ | 40 | return res; \ |
41 | } | 41 | } |
42 | 42 | ||
@@ -47,9 +47,9 @@ int pci_bus_write_config_##size \ | |||
47 | int res; \ | 47 | int res; \ |
48 | unsigned long flags; \ | 48 | unsigned long flags; \ |
49 | if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ | 49 | if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ |
50 | spin_lock_irqsave(&pci_lock, flags); \ | 50 | raw_spin_lock_irqsave(&pci_lock, flags); \ |
51 | res = bus->ops->write(bus, devfn, pos, len, value); \ | 51 | res = bus->ops->write(bus, devfn, pos, len, value); \ |
52 | spin_unlock_irqrestore(&pci_lock, flags); \ | 52 | raw_spin_unlock_irqrestore(&pci_lock, flags); \ |
53 | return res; \ | 53 | return res; \ |
54 | } | 54 | } |
55 | 55 | ||
@@ -79,10 +79,10 @@ struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops) | |||
79 | struct pci_ops *old_ops; | 79 | struct pci_ops *old_ops; |
80 | unsigned long flags; | 80 | unsigned long flags; |
81 | 81 | ||
82 | spin_lock_irqsave(&pci_lock, flags); | 82 | raw_spin_lock_irqsave(&pci_lock, flags); |
83 | old_ops = bus->ops; | 83 | old_ops = bus->ops; |
84 | bus->ops = ops; | 84 | bus->ops = ops; |
85 | spin_unlock_irqrestore(&pci_lock, flags); | 85 | raw_spin_unlock_irqrestore(&pci_lock, flags); |
86 | return old_ops; | 86 | return old_ops; |
87 | } | 87 | } |
88 | EXPORT_SYMBOL(pci_bus_set_ops); | 88 | EXPORT_SYMBOL(pci_bus_set_ops); |
@@ -136,9 +136,9 @@ static noinline void pci_wait_ucfg(struct pci_dev *dev) | |||
136 | __add_wait_queue(&pci_ucfg_wait, &wait); | 136 | __add_wait_queue(&pci_ucfg_wait, &wait); |
137 | do { | 137 | do { |
138 | set_current_state(TASK_UNINTERRUPTIBLE); | 138 | set_current_state(TASK_UNINTERRUPTIBLE); |
139 | spin_unlock_irq(&pci_lock); | 139 | raw_spin_unlock_irq(&pci_lock); |
140 | schedule(); | 140 | schedule(); |
141 | spin_lock_irq(&pci_lock); | 141 | raw_spin_lock_irq(&pci_lock); |
142 | } while (dev->block_ucfg_access); | 142 | } while (dev->block_ucfg_access); |
143 | __remove_wait_queue(&pci_ucfg_wait, &wait); | 143 | __remove_wait_queue(&pci_ucfg_wait, &wait); |
144 | } | 144 | } |
@@ -150,11 +150,11 @@ int pci_user_read_config_##size \ | |||
150 | int ret = 0; \ | 150 | int ret = 0; \ |
151 | u32 data = -1; \ | 151 | u32 data = -1; \ |
152 | if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ | 152 | if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ |
153 | spin_lock_irq(&pci_lock); \ | 153 | raw_spin_lock_irq(&pci_lock); \ |
154 | if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ | 154 | if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ |
155 | ret = dev->bus->ops->read(dev->bus, dev->devfn, \ | 155 | ret = dev->bus->ops->read(dev->bus, dev->devfn, \ |
156 | pos, sizeof(type), &data); \ | 156 | pos, sizeof(type), &data); \ |
157 | spin_unlock_irq(&pci_lock); \ | 157 | raw_spin_unlock_irq(&pci_lock); \ |
158 | *val = (type)data; \ | 158 | *val = (type)data; \ |
159 | return ret; \ | 159 | return ret; \ |
160 | } | 160 | } |
@@ -165,11 +165,11 @@ int pci_user_write_config_##size \ | |||
165 | { \ | 165 | { \ |
166 | int ret = -EIO; \ | 166 | int ret = -EIO; \ |
167 | if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ | 167 | if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ |
168 | spin_lock_irq(&pci_lock); \ | 168 | raw_spin_lock_irq(&pci_lock); \ |
169 | if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ | 169 | if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ |
170 | ret = dev->bus->ops->write(dev->bus, dev->devfn, \ | 170 | ret = dev->bus->ops->write(dev->bus, dev->devfn, \ |
171 | pos, sizeof(type), val); \ | 171 | pos, sizeof(type), val); \ |
172 | spin_unlock_irq(&pci_lock); \ | 172 | raw_spin_unlock_irq(&pci_lock); \ |
173 | return ret; \ | 173 | return ret; \ |
174 | } | 174 | } |
175 | 175 | ||
@@ -220,8 +220,13 @@ static int pci_vpd_pci22_wait(struct pci_dev *dev) | |||
220 | return 0; | 220 | return 0; |
221 | } | 221 | } |
222 | 222 | ||
223 | if (time_after(jiffies, timeout)) | 223 | if (time_after(jiffies, timeout)) { |
224 | dev_printk(KERN_DEBUG, &dev->dev, | ||
225 | "vpd r/w failed. This is likely a firmware " | ||
226 | "bug on this device. Contact the card " | ||
227 | "vendor for a firmware update."); | ||
224 | return -ETIMEDOUT; | 228 | return -ETIMEDOUT; |
229 | } | ||
225 | if (fatal_signal_pending(current)) | 230 | if (fatal_signal_pending(current)) |
226 | return -EINTR; | 231 | return -EINTR; |
227 | if (!cond_resched()) | 232 | if (!cond_resched()) |
@@ -396,10 +401,10 @@ void pci_block_user_cfg_access(struct pci_dev *dev) | |||
396 | unsigned long flags; | 401 | unsigned long flags; |
397 | int was_blocked; | 402 | int was_blocked; |
398 | 403 | ||
399 | spin_lock_irqsave(&pci_lock, flags); | 404 | raw_spin_lock_irqsave(&pci_lock, flags); |
400 | was_blocked = dev->block_ucfg_access; | 405 | was_blocked = dev->block_ucfg_access; |
401 | dev->block_ucfg_access = 1; | 406 | dev->block_ucfg_access = 1; |
402 | spin_unlock_irqrestore(&pci_lock, flags); | 407 | raw_spin_unlock_irqrestore(&pci_lock, flags); |
403 | 408 | ||
404 | /* If we BUG() inside the pci_lock, we're guaranteed to hose | 409 | /* If we BUG() inside the pci_lock, we're guaranteed to hose |
405 | * the machine */ | 410 | * the machine */ |
@@ -417,7 +422,7 @@ void pci_unblock_user_cfg_access(struct pci_dev *dev) | |||
417 | { | 422 | { |
418 | unsigned long flags; | 423 | unsigned long flags; |
419 | 424 | ||
420 | spin_lock_irqsave(&pci_lock, flags); | 425 | raw_spin_lock_irqsave(&pci_lock, flags); |
421 | 426 | ||
422 | /* This indicates a problem in the caller, but we don't need | 427 | /* This indicates a problem in the caller, but we don't need |
423 | * to kill them, unlike a double-block above. */ | 428 | * to kill them, unlike a double-block above. */ |
@@ -425,6 +430,6 @@ void pci_unblock_user_cfg_access(struct pci_dev *dev) | |||
425 | 430 | ||
426 | dev->block_ucfg_access = 0; | 431 | dev->block_ucfg_access = 0; |
427 | wake_up_all(&pci_ucfg_wait); | 432 | wake_up_all(&pci_ucfg_wait); |
428 | spin_unlock_irqrestore(&pci_lock, flags); | 433 | raw_spin_unlock_irqrestore(&pci_lock, flags); |
429 | } | 434 | } |
430 | EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access); | 435 | EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access); |