diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/host/pci-host-generic.c | 2 | ||||
-rw-r--r-- | drivers/pci/host/pci-mvebu.c | 2 | ||||
-rw-r--r-- | drivers/pci/host/pci-tegra.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_sysfs.c | 3 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 3 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 7 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 101 | ||||
-rw-r--r-- | drivers/pci/msi.c | 141 | ||||
-rw-r--r-- | drivers/pci/pci-label.c | 18 | ||||
-rw-r--r-- | drivers/pci/pci.c | 19 | ||||
-rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 4 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 2 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 2 | ||||
-rw-r--r-- | drivers/pci/setup-res.c | 75 |
14 files changed, 180 insertions, 201 deletions
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c index 44fe6aa6a43f..3d2076f59911 100644 --- a/drivers/pci/host/pci-host-generic.c +++ b/drivers/pci/host/pci-host-generic.c | |||
@@ -385,4 +385,4 @@ module_platform_driver(gen_pci_driver); | |||
385 | 385 | ||
386 | MODULE_DESCRIPTION("Generic PCI host driver"); | 386 | MODULE_DESCRIPTION("Generic PCI host driver"); |
387 | MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>"); | 387 | MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>"); |
388 | MODULE_LICENSE("GPLv2"); | 388 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index ce23e0f076b6..a8c6f1a92e0f 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -1094,4 +1094,4 @@ module_platform_driver(mvebu_pcie_driver); | |||
1094 | 1094 | ||
1095 | MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); | 1095 | MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); |
1096 | MODULE_DESCRIPTION("Marvell EBU PCIe driver"); | 1096 | MODULE_DESCRIPTION("Marvell EBU PCIe driver"); |
1097 | MODULE_LICENSE("GPLv2"); | 1097 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 083cf37ca047..c284e841e3ea 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -1716,4 +1716,4 @@ module_platform_driver(tegra_pcie_driver); | |||
1716 | 1716 | ||
1717 | MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); | 1717 | MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); |
1718 | MODULE_DESCRIPTION("NVIDIA Tegra PCIe driver"); | 1718 | MODULE_DESCRIPTION("NVIDIA Tegra PCIe driver"); |
1719 | MODULE_LICENSE("GPLv2"); | 1719 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index 4a392c44e3d3..d81648f71425 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c | |||
@@ -216,8 +216,7 @@ void cpqhp_create_debugfs_files(struct controller *ctrl) | |||
216 | 216 | ||
217 | void cpqhp_remove_debugfs_files(struct controller *ctrl) | 217 | void cpqhp_remove_debugfs_files(struct controller *ctrl) |
218 | { | 218 | { |
219 | if (ctrl->dentry) | 219 | debugfs_remove(ctrl->dentry); |
220 | debugfs_remove(ctrl->dentry); | ||
221 | ctrl->dentry = NULL; | 220 | ctrl->dentry = NULL; |
222 | } | 221 | } |
223 | 222 | ||
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 8e9012dca450..9e5a9fbb93d7 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -92,9 +92,10 @@ struct controller { | |||
92 | struct slot *slot; | 92 | struct slot *slot; |
93 | wait_queue_head_t queue; /* sleep & wake process */ | 93 | wait_queue_head_t queue; /* sleep & wake process */ |
94 | u32 slot_cap; | 94 | u32 slot_cap; |
95 | u32 slot_ctrl; | ||
95 | struct timer_list poll_timer; | 96 | struct timer_list poll_timer; |
97 | unsigned long cmd_started; /* jiffies */ | ||
96 | unsigned int cmd_busy:1; | 98 | unsigned int cmd_busy:1; |
97 | unsigned int no_cmd_complete:1; | ||
98 | unsigned int link_active_reporting:1; | 99 | unsigned int link_active_reporting:1; |
99 | unsigned int notification_enabled:1; | 100 | unsigned int notification_enabled:1; |
100 | unsigned int power_fault_detected; | 101 | unsigned int power_fault_detected; |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index a2297db80813..07aa722bb12c 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -255,6 +255,13 @@ static int pciehp_probe(struct pcie_device *dev) | |||
255 | else if (pciehp_acpi_slot_detection_check(dev->port)) | 255 | else if (pciehp_acpi_slot_detection_check(dev->port)) |
256 | goto err_out_none; | 256 | goto err_out_none; |
257 | 257 | ||
258 | if (!dev->port->subordinate) { | ||
259 | /* Can happen if we run out of bus numbers during probe */ | ||
260 | dev_err(&dev->device, | ||
261 | "Hotplug bridge without secondary bus, ignoring\n"); | ||
262 | goto err_out_none; | ||
263 | } | ||
264 | |||
258 | ctrl = pcie_init(dev); | 265 | ctrl = pcie_init(dev); |
259 | if (!ctrl) { | 266 | if (!ctrl) { |
260 | dev_err(&dev->device, "Controller initialization failed\n"); | 267 | dev_err(&dev->device, "Controller initialization failed\n"); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 42914e04d110..9da84b8b27d8 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -104,11 +104,10 @@ static inline void pciehp_free_irq(struct controller *ctrl) | |||
104 | free_irq(ctrl->pcie->irq, ctrl); | 104 | free_irq(ctrl->pcie->irq, ctrl); |
105 | } | 105 | } |
106 | 106 | ||
107 | static int pcie_poll_cmd(struct controller *ctrl) | 107 | static int pcie_poll_cmd(struct controller *ctrl, int timeout) |
108 | { | 108 | { |
109 | struct pci_dev *pdev = ctrl_dev(ctrl); | 109 | struct pci_dev *pdev = ctrl_dev(ctrl); |
110 | u16 slot_status; | 110 | u16 slot_status; |
111 | int timeout = 1000; | ||
112 | 111 | ||
113 | pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); | 112 | pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); |
114 | if (slot_status & PCI_EXP_SLTSTA_CC) { | 113 | if (slot_status & PCI_EXP_SLTSTA_CC) { |
@@ -129,18 +128,52 @@ static int pcie_poll_cmd(struct controller *ctrl) | |||
129 | return 0; /* timeout */ | 128 | return 0; /* timeout */ |
130 | } | 129 | } |
131 | 130 | ||
132 | static void pcie_wait_cmd(struct controller *ctrl, int poll) | 131 | static void pcie_wait_cmd(struct controller *ctrl) |
133 | { | 132 | { |
134 | unsigned int msecs = pciehp_poll_mode ? 2500 : 1000; | 133 | unsigned int msecs = pciehp_poll_mode ? 2500 : 1000; |
135 | unsigned long timeout = msecs_to_jiffies(msecs); | 134 | unsigned long duration = msecs_to_jiffies(msecs); |
135 | unsigned long cmd_timeout = ctrl->cmd_started + duration; | ||
136 | unsigned long now, timeout; | ||
136 | int rc; | 137 | int rc; |
137 | 138 | ||
138 | if (poll) | 139 | /* |
139 | rc = pcie_poll_cmd(ctrl); | 140 | * If the controller does not generate notifications for command |
141 | * completions, we never need to wait between writes. | ||
142 | */ | ||
143 | if (NO_CMD_CMPL(ctrl)) | ||
144 | return; | ||
145 | |||
146 | if (!ctrl->cmd_busy) | ||
147 | return; | ||
148 | |||
149 | /* | ||
150 | * Even if the command has already timed out, we want to call | ||
151 | * pcie_poll_cmd() so it can clear PCI_EXP_SLTSTA_CC. | ||
152 | */ | ||
153 | now = jiffies; | ||
154 | if (time_before_eq(cmd_timeout, now)) | ||
155 | timeout = 1; | ||
140 | else | 156 | else |
157 | timeout = cmd_timeout - now; | ||
158 | |||
159 | if (ctrl->slot_ctrl & PCI_EXP_SLTCTL_HPIE && | ||
160 | ctrl->slot_ctrl & PCI_EXP_SLTCTL_CCIE) | ||
141 | rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout); | 161 | rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout); |
162 | else | ||
163 | rc = pcie_poll_cmd(ctrl, timeout); | ||
164 | |||
165 | /* | ||
166 | * Controllers with errata like Intel CF118 don't generate | ||
167 | * completion notifications unless the power/indicator/interlock | ||
168 | * control bits are changed. On such controllers, we'll emit this | ||
169 | * timeout message when we wait for completion of commands that | ||
170 | * don't change those bits, e.g., commands that merely enable | ||
171 | * interrupts. | ||
172 | */ | ||
142 | if (!rc) | 173 | if (!rc) |
143 | ctrl_dbg(ctrl, "Command not completed in 1000 msec\n"); | 174 | ctrl_info(ctrl, "Timeout on hotplug command %#010x (issued %u msec ago)\n", |
175 | ctrl->slot_ctrl, | ||
176 | jiffies_to_msecs(now - ctrl->cmd_started)); | ||
144 | } | 177 | } |
145 | 178 | ||
146 | /** | 179 | /** |
@@ -152,34 +185,12 @@ static void pcie_wait_cmd(struct controller *ctrl, int poll) | |||
152 | static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | 185 | static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) |
153 | { | 186 | { |
154 | struct pci_dev *pdev = ctrl_dev(ctrl); | 187 | struct pci_dev *pdev = ctrl_dev(ctrl); |
155 | u16 slot_status; | ||
156 | u16 slot_ctrl; | 188 | u16 slot_ctrl; |
157 | 189 | ||
158 | mutex_lock(&ctrl->ctrl_lock); | 190 | mutex_lock(&ctrl->ctrl_lock); |
159 | 191 | ||
160 | pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); | 192 | /* Wait for any previous command that might still be in progress */ |
161 | if (slot_status & PCI_EXP_SLTSTA_CC) { | 193 | pcie_wait_cmd(ctrl); |
162 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, | ||
163 | PCI_EXP_SLTSTA_CC); | ||
164 | if (!ctrl->no_cmd_complete) { | ||
165 | /* | ||
166 | * After 1 sec and CMD_COMPLETED still not set, just | ||
167 | * proceed forward to issue the next command according | ||
168 | * to spec. Just print out the error message. | ||
169 | */ | ||
170 | ctrl_dbg(ctrl, "CMD_COMPLETED not clear after 1 sec\n"); | ||
171 | } else if (!NO_CMD_CMPL(ctrl)) { | ||
172 | /* | ||
173 | * This controller seems to notify of command completed | ||
174 | * event even though it supports none of power | ||
175 | * controller, attention led, power led and EMI. | ||
176 | */ | ||
177 | ctrl_dbg(ctrl, "Unexpected CMD_COMPLETED. Need to wait for command completed event\n"); | ||
178 | ctrl->no_cmd_complete = 0; | ||
179 | } else { | ||
180 | ctrl_dbg(ctrl, "Unexpected CMD_COMPLETED. Maybe the controller is broken\n"); | ||
181 | } | ||
182 | } | ||
183 | 194 | ||
184 | pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); | 195 | pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); |
185 | slot_ctrl &= ~mask; | 196 | slot_ctrl &= ~mask; |
@@ -187,22 +198,9 @@ static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
187 | ctrl->cmd_busy = 1; | 198 | ctrl->cmd_busy = 1; |
188 | smp_mb(); | 199 | smp_mb(); |
189 | pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, slot_ctrl); | 200 | pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, slot_ctrl); |
201 | ctrl->cmd_started = jiffies; | ||
202 | ctrl->slot_ctrl = slot_ctrl; | ||
190 | 203 | ||
191 | /* | ||
192 | * Wait for command completion. | ||
193 | */ | ||
194 | if (!ctrl->no_cmd_complete) { | ||
195 | int poll = 0; | ||
196 | /* | ||
197 | * if hotplug interrupt is not enabled or command | ||
198 | * completed interrupt is not enabled, we need to poll | ||
199 | * command completed event. | ||
200 | */ | ||
201 | if (!(slot_ctrl & PCI_EXP_SLTCTL_HPIE) || | ||
202 | !(slot_ctrl & PCI_EXP_SLTCTL_CCIE)) | ||
203 | poll = 1; | ||
204 | pcie_wait_cmd(ctrl, poll); | ||
205 | } | ||
206 | mutex_unlock(&ctrl->ctrl_lock); | 204 | mutex_unlock(&ctrl->ctrl_lock); |
207 | } | 205 | } |
208 | 206 | ||
@@ -773,15 +771,6 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
773 | mutex_init(&ctrl->ctrl_lock); | 771 | mutex_init(&ctrl->ctrl_lock); |
774 | init_waitqueue_head(&ctrl->queue); | 772 | init_waitqueue_head(&ctrl->queue); |
775 | dbg_ctrl(ctrl); | 773 | dbg_ctrl(ctrl); |
776 | /* | ||
777 | * Controller doesn't notify of command completion if the "No | ||
778 | * Command Completed Support" bit is set in Slot Capability | ||
779 | * register or the controller supports none of power | ||
780 | * controller, attention led, power led and EMI. | ||
781 | */ | ||
782 | if (NO_CMD_CMPL(ctrl) || | ||
783 | !(POWER_CTRL(ctrl) | ATTN_LED(ctrl) | PWR_LED(ctrl) | EMI(ctrl))) | ||
784 | ctrl->no_cmd_complete = 1; | ||
785 | 774 | ||
786 | /* Check if Data Link Layer Link Active Reporting is implemented */ | 775 | /* Check if Data Link Layer Link Active Reporting is implemented */ |
787 | pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &link_cap); | 776 | pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &link_cap); |
@@ -794,7 +783,7 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
794 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, | 783 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, |
795 | PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | | 784 | PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | |
796 | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | | 785 | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | |
797 | PCI_EXP_SLTSTA_CC); | 786 | PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC); |
798 | 787 | ||
799 | /* Disable software notification */ | 788 | /* Disable software notification */ |
800 | pcie_disable_notification(ctrl); | 789 | pcie_disable_notification(ctrl); |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 13f3d3037272..5a40516444f3 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -149,15 +149,14 @@ static void msi_set_enable(struct pci_dev *dev, int enable) | |||
149 | pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); | 149 | pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); |
150 | } | 150 | } |
151 | 151 | ||
152 | static void msix_set_enable(struct pci_dev *dev, int enable) | 152 | static void msix_clear_and_set_ctrl(struct pci_dev *dev, u16 clear, u16 set) |
153 | { | 153 | { |
154 | u16 control; | 154 | u16 ctrl; |
155 | 155 | ||
156 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); | 156 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &ctrl); |
157 | control &= ~PCI_MSIX_FLAGS_ENABLE; | 157 | ctrl &= ~clear; |
158 | if (enable) | 158 | ctrl |= set; |
159 | control |= PCI_MSIX_FLAGS_ENABLE; | 159 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, ctrl); |
160 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); | ||
161 | } | 160 | } |
162 | 161 | ||
163 | static inline __attribute_const__ u32 msi_mask(unsigned x) | 162 | static inline __attribute_const__ u32 msi_mask(unsigned x) |
@@ -168,16 +167,6 @@ static inline __attribute_const__ u32 msi_mask(unsigned x) | |||
168 | return (1 << (1 << x)) - 1; | 167 | return (1 << (1 << x)) - 1; |
169 | } | 168 | } |
170 | 169 | ||
171 | static inline __attribute_const__ u32 msi_capable_mask(u16 control) | ||
172 | { | ||
173 | return msi_mask((control >> 1) & 7); | ||
174 | } | ||
175 | |||
176 | static inline __attribute_const__ u32 msi_enabled_mask(u16 control) | ||
177 | { | ||
178 | return msi_mask((control >> 4) & 7); | ||
179 | } | ||
180 | |||
181 | /* | 170 | /* |
182 | * PCI 2.3 does not specify mask bits for each MSI interrupt. Attempting to | 171 | * PCI 2.3 does not specify mask bits for each MSI interrupt. Attempting to |
183 | * mask all MSI interrupts by clearing the MSI enable bit does not work | 172 | * mask all MSI interrupts by clearing the MSI enable bit does not work |
@@ -246,7 +235,7 @@ static void msi_set_mask_bit(struct irq_data *data, u32 flag) | |||
246 | msix_mask_irq(desc, flag); | 235 | msix_mask_irq(desc, flag); |
247 | readl(desc->mask_base); /* Flush write to device */ | 236 | readl(desc->mask_base); /* Flush write to device */ |
248 | } else { | 237 | } else { |
249 | unsigned offset = data->irq - desc->dev->irq; | 238 | unsigned offset = data->irq - desc->irq; |
250 | msi_mask_irq(desc, 1 << offset, flag << offset); | 239 | msi_mask_irq(desc, 1 << offset, flag << offset); |
251 | } | 240 | } |
252 | } | 241 | } |
@@ -460,7 +449,8 @@ static void __pci_restore_msi_state(struct pci_dev *dev) | |||
460 | arch_restore_msi_irqs(dev); | 449 | arch_restore_msi_irqs(dev); |
461 | 450 | ||
462 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); | 451 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); |
463 | msi_mask_irq(entry, msi_capable_mask(control), entry->masked); | 452 | msi_mask_irq(entry, msi_mask(entry->msi_attrib.multi_cap), |
453 | entry->masked); | ||
464 | control &= ~PCI_MSI_FLAGS_QSIZE; | 454 | control &= ~PCI_MSI_FLAGS_QSIZE; |
465 | control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE; | 455 | control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE; |
466 | pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); | 456 | pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); |
@@ -469,26 +459,22 @@ static void __pci_restore_msi_state(struct pci_dev *dev) | |||
469 | static void __pci_restore_msix_state(struct pci_dev *dev) | 459 | static void __pci_restore_msix_state(struct pci_dev *dev) |
470 | { | 460 | { |
471 | struct msi_desc *entry; | 461 | struct msi_desc *entry; |
472 | u16 control; | ||
473 | 462 | ||
474 | if (!dev->msix_enabled) | 463 | if (!dev->msix_enabled) |
475 | return; | 464 | return; |
476 | BUG_ON(list_empty(&dev->msi_list)); | 465 | BUG_ON(list_empty(&dev->msi_list)); |
477 | entry = list_first_entry(&dev->msi_list, struct msi_desc, list); | ||
478 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); | ||
479 | 466 | ||
480 | /* route the table */ | 467 | /* route the table */ |
481 | pci_intx_for_msi(dev, 0); | 468 | pci_intx_for_msi(dev, 0); |
482 | control |= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL; | 469 | msix_clear_and_set_ctrl(dev, 0, |
483 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); | 470 | PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL); |
484 | 471 | ||
485 | arch_restore_msi_irqs(dev); | 472 | arch_restore_msi_irqs(dev); |
486 | list_for_each_entry(entry, &dev->msi_list, list) { | 473 | list_for_each_entry(entry, &dev->msi_list, list) { |
487 | msix_mask_irq(entry, entry->masked); | 474 | msix_mask_irq(entry, entry->masked); |
488 | } | 475 | } |
489 | 476 | ||
490 | control &= ~PCI_MSIX_FLAGS_MASKALL; | 477 | msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0); |
491 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); | ||
492 | } | 478 | } |
493 | 479 | ||
494 | void pci_restore_msi_state(struct pci_dev *dev) | 480 | void pci_restore_msi_state(struct pci_dev *dev) |
@@ -501,7 +487,6 @@ EXPORT_SYMBOL_GPL(pci_restore_msi_state); | |||
501 | static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr, | 487 | static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr, |
502 | char *buf) | 488 | char *buf) |
503 | { | 489 | { |
504 | struct pci_dev *pdev = to_pci_dev(dev); | ||
505 | struct msi_desc *entry; | 490 | struct msi_desc *entry; |
506 | unsigned long irq; | 491 | unsigned long irq; |
507 | int retval; | 492 | int retval; |
@@ -510,12 +495,11 @@ static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr, | |||
510 | if (retval) | 495 | if (retval) |
511 | return retval; | 496 | return retval; |
512 | 497 | ||
513 | list_for_each_entry(entry, &pdev->msi_list, list) { | 498 | entry = irq_get_msi_desc(irq); |
514 | if (entry->irq == irq) { | 499 | if (entry) |
515 | return sprintf(buf, "%s\n", | 500 | return sprintf(buf, "%s\n", |
516 | entry->msi_attrib.is_msix ? "msix" : "msi"); | 501 | entry->msi_attrib.is_msix ? "msix" : "msi"); |
517 | } | 502 | |
518 | } | ||
519 | return -ENODEV; | 503 | return -ENODEV; |
520 | } | 504 | } |
521 | 505 | ||
@@ -594,6 +578,38 @@ error_attrs: | |||
594 | return ret; | 578 | return ret; |
595 | } | 579 | } |
596 | 580 | ||
581 | static struct msi_desc *msi_setup_entry(struct pci_dev *dev) | ||
582 | { | ||
583 | u16 control; | ||
584 | struct msi_desc *entry; | ||
585 | |||
586 | /* MSI Entry Initialization */ | ||
587 | entry = alloc_msi_entry(dev); | ||
588 | if (!entry) | ||
589 | return NULL; | ||
590 | |||
591 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); | ||
592 | |||
593 | entry->msi_attrib.is_msix = 0; | ||
594 | entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT); | ||
595 | entry->msi_attrib.entry_nr = 0; | ||
596 | entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT); | ||
597 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ | ||
598 | entry->msi_attrib.pos = dev->msi_cap; | ||
599 | entry->msi_attrib.multi_cap = (control & PCI_MSI_FLAGS_QMASK) >> 1; | ||
600 | |||
601 | if (control & PCI_MSI_FLAGS_64BIT) | ||
602 | entry->mask_pos = dev->msi_cap + PCI_MSI_MASK_64; | ||
603 | else | ||
604 | entry->mask_pos = dev->msi_cap + PCI_MSI_MASK_32; | ||
605 | |||
606 | /* Save the initial mask status */ | ||
607 | if (entry->msi_attrib.maskbit) | ||
608 | pci_read_config_dword(dev, entry->mask_pos, &entry->masked); | ||
609 | |||
610 | return entry; | ||
611 | } | ||
612 | |||
597 | /** | 613 | /** |
598 | * msi_capability_init - configure device's MSI capability structure | 614 | * msi_capability_init - configure device's MSI capability structure |
599 | * @dev: pointer to the pci_dev data structure of MSI device function | 615 | * @dev: pointer to the pci_dev data structure of MSI device function |
@@ -609,32 +625,16 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) | |||
609 | { | 625 | { |
610 | struct msi_desc *entry; | 626 | struct msi_desc *entry; |
611 | int ret; | 627 | int ret; |
612 | u16 control; | ||
613 | unsigned mask; | 628 | unsigned mask; |
614 | 629 | ||
615 | msi_set_enable(dev, 0); /* Disable MSI during set up */ | 630 | msi_set_enable(dev, 0); /* Disable MSI during set up */ |
616 | 631 | ||
617 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); | 632 | entry = msi_setup_entry(dev); |
618 | /* MSI Entry Initialization */ | ||
619 | entry = alloc_msi_entry(dev); | ||
620 | if (!entry) | 633 | if (!entry) |
621 | return -ENOMEM; | 634 | return -ENOMEM; |
622 | 635 | ||
623 | entry->msi_attrib.is_msix = 0; | ||
624 | entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT); | ||
625 | entry->msi_attrib.entry_nr = 0; | ||
626 | entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT); | ||
627 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ | ||
628 | entry->msi_attrib.pos = dev->msi_cap; | ||
629 | |||
630 | if (control & PCI_MSI_FLAGS_64BIT) | ||
631 | entry->mask_pos = dev->msi_cap + PCI_MSI_MASK_64; | ||
632 | else | ||
633 | entry->mask_pos = dev->msi_cap + PCI_MSI_MASK_32; | ||
634 | /* All MSIs are unmasked by default, Mask them all */ | 636 | /* All MSIs are unmasked by default, Mask them all */ |
635 | if (entry->msi_attrib.maskbit) | 637 | mask = msi_mask(entry->msi_attrib.multi_cap); |
636 | pci_read_config_dword(dev, entry->mask_pos, &entry->masked); | ||
637 | mask = msi_capable_mask(control); | ||
638 | msi_mask_irq(entry, mask, mask); | 638 | msi_mask_irq(entry, mask, mask); |
639 | 639 | ||
640 | list_add_tail(&entry->list, &dev->msi_list); | 640 | list_add_tail(&entry->list, &dev->msi_list); |
@@ -743,12 +743,10 @@ static int msix_capability_init(struct pci_dev *dev, | |||
743 | u16 control; | 743 | u16 control; |
744 | void __iomem *base; | 744 | void __iomem *base; |
745 | 745 | ||
746 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); | ||
747 | |||
748 | /* Ensure MSI-X is disabled while it is set up */ | 746 | /* Ensure MSI-X is disabled while it is set up */ |
749 | control &= ~PCI_MSIX_FLAGS_ENABLE; | 747 | msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); |
750 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); | ||
751 | 748 | ||
749 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); | ||
752 | /* Request & Map MSI-X table region */ | 750 | /* Request & Map MSI-X table region */ |
753 | base = msix_map_region(dev, msix_table_size(control)); | 751 | base = msix_map_region(dev, msix_table_size(control)); |
754 | if (!base) | 752 | if (!base) |
@@ -767,8 +765,8 @@ static int msix_capability_init(struct pci_dev *dev, | |||
767 | * MSI-X registers. We need to mask all the vectors to prevent | 765 | * MSI-X registers. We need to mask all the vectors to prevent |
768 | * interrupts coming in before they're fully set up. | 766 | * interrupts coming in before they're fully set up. |
769 | */ | 767 | */ |
770 | control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE; | 768 | msix_clear_and_set_ctrl(dev, 0, |
771 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); | 769 | PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE); |
772 | 770 | ||
773 | msix_program_entries(dev, entries); | 771 | msix_program_entries(dev, entries); |
774 | 772 | ||
@@ -780,8 +778,7 @@ static int msix_capability_init(struct pci_dev *dev, | |||
780 | pci_intx_for_msi(dev, 0); | 778 | pci_intx_for_msi(dev, 0); |
781 | dev->msix_enabled = 1; | 779 | dev->msix_enabled = 1; |
782 | 780 | ||
783 | control &= ~PCI_MSIX_FLAGS_MASKALL; | 781 | msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0); |
784 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); | ||
785 | 782 | ||
786 | return 0; | 783 | return 0; |
787 | 784 | ||
@@ -882,7 +879,6 @@ void pci_msi_shutdown(struct pci_dev *dev) | |||
882 | { | 879 | { |
883 | struct msi_desc *desc; | 880 | struct msi_desc *desc; |
884 | u32 mask; | 881 | u32 mask; |
885 | u16 ctrl; | ||
886 | 882 | ||
887 | if (!pci_msi_enable || !dev || !dev->msi_enabled) | 883 | if (!pci_msi_enable || !dev || !dev->msi_enabled) |
888 | return; | 884 | return; |
@@ -895,8 +891,7 @@ void pci_msi_shutdown(struct pci_dev *dev) | |||
895 | dev->msi_enabled = 0; | 891 | dev->msi_enabled = 0; |
896 | 892 | ||
897 | /* Return the device with MSI unmasked as initial states */ | 893 | /* Return the device with MSI unmasked as initial states */ |
898 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &ctrl); | 894 | mask = msi_mask(desc->msi_attrib.multi_cap); |
899 | mask = msi_capable_mask(ctrl); | ||
900 | /* Keep cached state to be restored */ | 895 | /* Keep cached state to be restored */ |
901 | arch_msi_mask_irq(desc, mask, ~mask); | 896 | arch_msi_mask_irq(desc, mask, ~mask); |
902 | 897 | ||
@@ -1001,7 +996,7 @@ void pci_msix_shutdown(struct pci_dev *dev) | |||
1001 | arch_msix_mask_irq(entry, 1); | 996 | arch_msix_mask_irq(entry, 1); |
1002 | } | 997 | } |
1003 | 998 | ||
1004 | msix_set_enable(dev, 0); | 999 | msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); |
1005 | pci_intx_for_msi(dev, 1); | 1000 | pci_intx_for_msi(dev, 1); |
1006 | dev->msix_enabled = 0; | 1001 | dev->msix_enabled = 0; |
1007 | } | 1002 | } |
@@ -1016,24 +1011,6 @@ void pci_disable_msix(struct pci_dev *dev) | |||
1016 | } | 1011 | } |
1017 | EXPORT_SYMBOL(pci_disable_msix); | 1012 | EXPORT_SYMBOL(pci_disable_msix); |
1018 | 1013 | ||
1019 | /** | ||
1020 | * msi_remove_pci_irq_vectors - reclaim MSI(X) irqs to unused state | ||
1021 | * @dev: pointer to the pci_dev data structure of MSI(X) device function | ||
1022 | * | ||
1023 | * Being called during hotplug remove, from which the device function | ||
1024 | * is hot-removed. All previous assigned MSI/MSI-X irqs, if | ||
1025 | * allocated for this device function, are reclaimed to unused state, | ||
1026 | * which may be used later on. | ||
1027 | **/ | ||
1028 | void msi_remove_pci_irq_vectors(struct pci_dev *dev) | ||
1029 | { | ||
1030 | if (!pci_msi_enable || !dev) | ||
1031 | return; | ||
1032 | |||
1033 | if (dev->msi_enabled || dev->msix_enabled) | ||
1034 | free_msi_irqs(dev); | ||
1035 | } | ||
1036 | |||
1037 | void pci_no_msi(void) | 1014 | void pci_no_msi(void) |
1038 | { | 1015 | { |
1039 | pci_msi_enable = 0; | 1016 | pci_msi_enable = 0; |
@@ -1065,7 +1042,7 @@ void pci_msi_init_pci_dev(struct pci_dev *dev) | |||
1065 | 1042 | ||
1066 | dev->msix_cap = pci_find_capability(dev, PCI_CAP_ID_MSIX); | 1043 | dev->msix_cap = pci_find_capability(dev, PCI_CAP_ID_MSIX); |
1067 | if (dev->msix_cap) | 1044 | if (dev->msix_cap) |
1068 | msix_set_enable(dev, 0); | 1045 | msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); |
1069 | } | 1046 | } |
1070 | 1047 | ||
1071 | /** | 1048 | /** |
diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c index a3fbe2012ea3..2ab1b47c7651 100644 --- a/drivers/pci/pci-label.c +++ b/drivers/pci/pci-label.c | |||
@@ -161,8 +161,8 @@ enum acpi_attr_enum { | |||
161 | static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf) | 161 | static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf) |
162 | { | 162 | { |
163 | int len; | 163 | int len; |
164 | len = utf16s_to_utf8s((const wchar_t *)obj->string.pointer, | 164 | len = utf16s_to_utf8s((const wchar_t *)obj->buffer.pointer, |
165 | obj->string.length, | 165 | obj->buffer.length, |
166 | UTF16_LITTLE_ENDIAN, | 166 | UTF16_LITTLE_ENDIAN, |
167 | buf, PAGE_SIZE); | 167 | buf, PAGE_SIZE); |
168 | buf[len] = '\n'; | 168 | buf[len] = '\n'; |
@@ -187,16 +187,22 @@ static int dsm_get_label(struct device *dev, char *buf, | |||
187 | tmp = obj->package.elements; | 187 | tmp = obj->package.elements; |
188 | if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2 && | 188 | if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2 && |
189 | tmp[0].type == ACPI_TYPE_INTEGER && | 189 | tmp[0].type == ACPI_TYPE_INTEGER && |
190 | tmp[1].type == ACPI_TYPE_STRING) { | 190 | (tmp[1].type == ACPI_TYPE_STRING || |
191 | tmp[1].type == ACPI_TYPE_BUFFER)) { | ||
191 | /* | 192 | /* |
192 | * The second string element is optional even when | 193 | * The second string element is optional even when |
193 | * this _DSM is implemented; when not implemented, | 194 | * this _DSM is implemented; when not implemented, |
194 | * this entry must return a null string. | 195 | * this entry must return a null string. |
195 | */ | 196 | */ |
196 | if (attr == ACPI_ATTR_INDEX_SHOW) | 197 | if (attr == ACPI_ATTR_INDEX_SHOW) { |
197 | scnprintf(buf, PAGE_SIZE, "%llu\n", tmp->integer.value); | 198 | scnprintf(buf, PAGE_SIZE, "%llu\n", tmp->integer.value); |
198 | else if (attr == ACPI_ATTR_LABEL_SHOW) | 199 | } else if (attr == ACPI_ATTR_LABEL_SHOW) { |
199 | dsm_label_utf16s_to_utf8s(tmp + 1, buf); | 200 | if (tmp[1].type == ACPI_TYPE_STRING) |
201 | scnprintf(buf, PAGE_SIZE, "%s\n", | ||
202 | tmp[1].string.pointer); | ||
203 | else if (tmp[1].type == ACPI_TYPE_BUFFER) | ||
204 | dsm_label_utf16s_to_utf8s(tmp + 1, buf); | ||
205 | } | ||
200 | len = strlen(buf) > 0 ? strlen(buf) : -1; | 206 | len = strlen(buf) > 0 ? strlen(buf) : -1; |
201 | } | 207 | } |
202 | 208 | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 63a54a340863..74043a2a2da8 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -839,12 +839,6 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
839 | 839 | ||
840 | if (!__pci_complete_power_transition(dev, state)) | 840 | if (!__pci_complete_power_transition(dev, state)) |
841 | error = 0; | 841 | error = 0; |
842 | /* | ||
843 | * When aspm_policy is "powersave" this call ensures | ||
844 | * that ASPM is configured. | ||
845 | */ | ||
846 | if (!error && dev->bus->self) | ||
847 | pcie_aspm_powersave_config_link(dev->bus->self); | ||
848 | 842 | ||
849 | return error; | 843 | return error; |
850 | } | 844 | } |
@@ -1195,12 +1189,18 @@ int __weak pcibios_enable_device(struct pci_dev *dev, int bars) | |||
1195 | static int do_pci_enable_device(struct pci_dev *dev, int bars) | 1189 | static int do_pci_enable_device(struct pci_dev *dev, int bars) |
1196 | { | 1190 | { |
1197 | int err; | 1191 | int err; |
1192 | struct pci_dev *bridge; | ||
1198 | u16 cmd; | 1193 | u16 cmd; |
1199 | u8 pin; | 1194 | u8 pin; |
1200 | 1195 | ||
1201 | err = pci_set_power_state(dev, PCI_D0); | 1196 | err = pci_set_power_state(dev, PCI_D0); |
1202 | if (err < 0 && err != -EIO) | 1197 | if (err < 0 && err != -EIO) |
1203 | return err; | 1198 | return err; |
1199 | |||
1200 | bridge = pci_upstream_bridge(dev); | ||
1201 | if (bridge) | ||
1202 | pcie_aspm_powersave_config_link(bridge); | ||
1203 | |||
1204 | err = pcibios_enable_device(dev, bars); | 1204 | err = pcibios_enable_device(dev, bars); |
1205 | if (err < 0) | 1205 | if (err < 0) |
1206 | return err; | 1206 | return err; |
@@ -3193,7 +3193,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) | |||
3193 | return 0; | 3193 | return 0; |
3194 | } | 3194 | } |
3195 | 3195 | ||
3196 | void __weak pcibios_reset_secondary_bus(struct pci_dev *dev) | 3196 | void pci_reset_secondary_bus(struct pci_dev *dev) |
3197 | { | 3197 | { |
3198 | u16 ctrl; | 3198 | u16 ctrl; |
3199 | 3199 | ||
@@ -3219,6 +3219,11 @@ void __weak pcibios_reset_secondary_bus(struct pci_dev *dev) | |||
3219 | ssleep(1); | 3219 | ssleep(1); |
3220 | } | 3220 | } |
3221 | 3221 | ||
3222 | void __weak pcibios_reset_secondary_bus(struct pci_dev *dev) | ||
3223 | { | ||
3224 | pci_reset_secondary_bus(dev); | ||
3225 | } | ||
3226 | |||
3222 | /** | 3227 | /** |
3223 | * pci_reset_bridge_secondary_bus - Reset the secondary bus on a PCI bridge. | 3228 | * pci_reset_bridge_secondary_bus - Reset the secondary bus on a PCI bridge. |
3224 | * @dev: Bridge device | 3229 | * @dev: Bridge device |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 80887eaa0668..2ccc9b926ea7 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -203,10 +203,6 @@ static int pcie_portdrv_probe(struct pci_dev *dev, | |||
203 | (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM))) | 203 | (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM))) |
204 | return -ENODEV; | 204 | return -ENODEV; |
205 | 205 | ||
206 | if (!dev->irq && dev->pin) { | ||
207 | dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; check vendor BIOS\n", | ||
208 | dev->vendor, dev->device); | ||
209 | } | ||
210 | status = pcie_port_device_register(dev); | 206 | status = pcie_port_device_register(dev); |
211 | if (status) | 207 | if (status) |
212 | return status; | 208 | return status; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index d0f69269eb6c..ad566827b547 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -3405,6 +3405,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ASMEDIA, 0x1080, | |||
3405 | DECLARE_PCI_FIXUP_HEADER(0x10e3, 0x8113, quirk_use_pcie_bridge_dma_alias); | 3405 | DECLARE_PCI_FIXUP_HEADER(0x10e3, 0x8113, quirk_use_pcie_bridge_dma_alias); |
3406 | /* ITE 8892, https://bugzilla.kernel.org/show_bug.cgi?id=73551 */ | 3406 | /* ITE 8892, https://bugzilla.kernel.org/show_bug.cgi?id=73551 */ |
3407 | DECLARE_PCI_FIXUP_HEADER(0x1283, 0x8892, quirk_use_pcie_bridge_dma_alias); | 3407 | DECLARE_PCI_FIXUP_HEADER(0x1283, 0x8892, quirk_use_pcie_bridge_dma_alias); |
3408 | /* Intel 82801, https://bugzilla.kernel.org/show_bug.cgi?id=44881#c49 */ | ||
3409 | DECLARE_PCI_FIXUP_HEADER(0x8086, 0x244e, quirk_use_pcie_bridge_dma_alias); | ||
3408 | 3410 | ||
3409 | static struct pci_dev *pci_func_0_dma_source(struct pci_dev *dev) | 3411 | static struct pci_dev *pci_func_0_dma_source(struct pci_dev *dev) |
3410 | { | 3412 | { |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index a5a63ecfb628..6373985ad3f7 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -925,7 +925,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
925 | { | 925 | { |
926 | struct pci_dev *dev; | 926 | struct pci_dev *dev; |
927 | resource_size_t min_align, align, size, size0, size1; | 927 | resource_size_t min_align, align, size, size0, size1; |
928 | resource_size_t aligns[14]; /* Alignments from 1Mb to 8Gb */ | 928 | resource_size_t aligns[18]; /* Alignments from 1Mb to 128Gb */ |
929 | int order, max_order; | 929 | int order, max_order; |
930 | struct resource *b_res = find_free_bus_resource(bus, | 930 | struct resource *b_res = find_free_bus_resource(bus, |
931 | mask | IORESOURCE_PREFETCH, type); | 931 | mask | IORESOURCE_PREFETCH, type); |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index caed1ce6facd..b7c3a5ea1fca 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -166,11 +166,10 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, | |||
166 | { | 166 | { |
167 | struct resource *root, *conflict; | 167 | struct resource *root, *conflict; |
168 | resource_size_t fw_addr, start, end; | 168 | resource_size_t fw_addr, start, end; |
169 | int ret = 0; | ||
170 | 169 | ||
171 | fw_addr = pcibios_retrieve_fw_addr(dev, resno); | 170 | fw_addr = pcibios_retrieve_fw_addr(dev, resno); |
172 | if (!fw_addr) | 171 | if (!fw_addr) |
173 | return 1; | 172 | return -ENOMEM; |
174 | 173 | ||
175 | start = res->start; | 174 | start = res->start; |
176 | end = res->end; | 175 | end = res->end; |
@@ -189,14 +188,13 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, | |||
189 | resno, res); | 188 | resno, res); |
190 | conflict = request_resource_conflict(root, res); | 189 | conflict = request_resource_conflict(root, res); |
191 | if (conflict) { | 190 | if (conflict) { |
192 | dev_info(&dev->dev, | 191 | dev_info(&dev->dev, "BAR %d: %pR conflicts with %s %pR\n", |
193 | "BAR %d: %pR conflicts with %s %pR\n", resno, | 192 | resno, res, conflict->name, conflict); |
194 | res, conflict->name, conflict); | ||
195 | res->start = start; | 193 | res->start = start; |
196 | res->end = end; | 194 | res->end = end; |
197 | ret = 1; | 195 | return -EBUSY; |
198 | } | 196 | } |
199 | return ret; | 197 | return 0; |
200 | } | 198 | } |
201 | 199 | ||
202 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | 200 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, |
@@ -250,10 +248,8 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | |||
250 | static int _pci_assign_resource(struct pci_dev *dev, int resno, | 248 | static int _pci_assign_resource(struct pci_dev *dev, int resno, |
251 | resource_size_t size, resource_size_t min_align) | 249 | resource_size_t size, resource_size_t min_align) |
252 | { | 250 | { |
253 | struct resource *res = dev->resource + resno; | ||
254 | struct pci_bus *bus; | 251 | struct pci_bus *bus; |
255 | int ret; | 252 | int ret; |
256 | char *type; | ||
257 | 253 | ||
258 | bus = dev->bus; | 254 | bus = dev->bus; |
259 | while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) { | 255 | while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) { |
@@ -262,21 +258,6 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno, | |||
262 | bus = bus->parent; | 258 | bus = bus->parent; |
263 | } | 259 | } |
264 | 260 | ||
265 | if (ret) { | ||
266 | if (res->flags & IORESOURCE_MEM) | ||
267 | if (res->flags & IORESOURCE_PREFETCH) | ||
268 | type = "mem pref"; | ||
269 | else | ||
270 | type = "mem"; | ||
271 | else if (res->flags & IORESOURCE_IO) | ||
272 | type = "io"; | ||
273 | else | ||
274 | type = "unknown"; | ||
275 | dev_info(&dev->dev, | ||
276 | "BAR %d: can't assign %s (size %#llx)\n", | ||
277 | resno, type, (unsigned long long) resource_size(res)); | ||
278 | } | ||
279 | |||
280 | return ret; | 261 | return ret; |
281 | } | 262 | } |
282 | 263 | ||
@@ -302,17 +283,24 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
302 | * where firmware left it. That at least has a chance of | 283 | * where firmware left it. That at least has a chance of |
303 | * working, which is better than just leaving it disabled. | 284 | * working, which is better than just leaving it disabled. |
304 | */ | 285 | */ |
305 | if (ret < 0) | 286 | if (ret < 0) { |
287 | dev_info(&dev->dev, "BAR %d: no space for %pR\n", resno, res); | ||
306 | ret = pci_revert_fw_address(res, dev, resno, size); | 288 | ret = pci_revert_fw_address(res, dev, resno, size); |
289 | } | ||
307 | 290 | ||
308 | if (!ret) { | 291 | if (ret < 0) { |
309 | res->flags &= ~IORESOURCE_UNSET; | 292 | dev_info(&dev->dev, "BAR %d: failed to assign %pR\n", resno, |
310 | res->flags &= ~IORESOURCE_STARTALIGN; | 293 | res); |
311 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | 294 | return ret; |
312 | if (resno < PCI_BRIDGE_RESOURCES) | ||
313 | pci_update_resource(dev, resno); | ||
314 | } | 295 | } |
315 | return ret; | 296 | |
297 | res->flags &= ~IORESOURCE_UNSET; | ||
298 | res->flags &= ~IORESOURCE_STARTALIGN; | ||
299 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | ||
300 | if (resno < PCI_BRIDGE_RESOURCES) | ||
301 | pci_update_resource(dev, resno); | ||
302 | |||
303 | return 0; | ||
316 | } | 304 | } |
317 | EXPORT_SYMBOL(pci_assign_resource); | 305 | EXPORT_SYMBOL(pci_assign_resource); |
318 | 306 | ||
@@ -320,9 +308,11 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
320 | resource_size_t min_align) | 308 | resource_size_t min_align) |
321 | { | 309 | { |
322 | struct resource *res = dev->resource + resno; | 310 | struct resource *res = dev->resource + resno; |
311 | unsigned long flags; | ||
323 | resource_size_t new_size; | 312 | resource_size_t new_size; |
324 | int ret; | 313 | int ret; |
325 | 314 | ||
315 | flags = res->flags; | ||
326 | res->flags |= IORESOURCE_UNSET; | 316 | res->flags |= IORESOURCE_UNSET; |
327 | if (!res->parent) { | 317 | if (!res->parent) { |
328 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR\n", | 318 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR\n", |
@@ -333,14 +323,21 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
333 | /* already aligned with min_align */ | 323 | /* already aligned with min_align */ |
334 | new_size = resource_size(res) + addsize; | 324 | new_size = resource_size(res) + addsize; |
335 | ret = _pci_assign_resource(dev, resno, new_size, min_align); | 325 | ret = _pci_assign_resource(dev, resno, new_size, min_align); |
336 | if (!ret) { | 326 | if (ret) { |
337 | res->flags &= ~IORESOURCE_UNSET; | 327 | res->flags = flags; |
338 | res->flags &= ~IORESOURCE_STARTALIGN; | 328 | dev_info(&dev->dev, "BAR %d: %pR (failed to expand by %#llx)\n", |
339 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); | 329 | resno, res, (unsigned long long) addsize); |
340 | if (resno < PCI_BRIDGE_RESOURCES) | 330 | return ret; |
341 | pci_update_resource(dev, resno); | ||
342 | } | 331 | } |
343 | return ret; | 332 | |
333 | res->flags &= ~IORESOURCE_UNSET; | ||
334 | res->flags &= ~IORESOURCE_STARTALIGN; | ||
335 | dev_info(&dev->dev, "BAR %d: reassigned %pR (expanded by %#llx)\n", | ||
336 | resno, res, (unsigned long long) addsize); | ||
337 | if (resno < PCI_BRIDGE_RESOURCES) | ||
338 | pci_update_resource(dev, resno); | ||
339 | |||
340 | return 0; | ||
344 | } | 341 | } |
345 | 342 | ||
346 | int pci_enable_resources(struct pci_dev *dev, int mask) | 343 | int pci_enable_resources(struct pci_dev *dev, int mask) |