diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-03-05 06:47:28 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-05 06:47:28 -0500 |
commit | 7df4edb07cf54a4868b9a750424c0d2aa68f8d66 (patch) | |
tree | 0ad0ad3f3dcb6f9edf26dde42ba625053dddf54f /drivers/pci | |
parent | 0d688da5505d77bcef2441e0a22d8cc26459702d (diff) | |
parent | 559595a985e106d2fa9f0c79b7f5805453fed593 (diff) |
Merge branch 'linus' into core/iommu
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/dmar.c | 73 | ||||
-rw-r--r-- | drivers/pci/hotplug/Makefile | 6 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/fakephp.c | 42 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 11 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 15 | ||||
-rw-r--r-- | drivers/pci/intel-iommu.c | 30 | ||||
-rw-r--r-- | drivers/pci/intr_remapping.c | 21 | ||||
-rw-r--r-- | drivers/pci/msi.c | 27 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 266 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 4 | ||||
-rw-r--r-- | drivers/pci/pci.c | 84 | ||||
-rw-r--r-- | drivers/pci/pci.h | 26 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_core.c | 48 | ||||
-rw-r--r-- | drivers/pci/pcie/aspm.c | 4 | ||||
-rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 18 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 122 | ||||
-rw-r--r-- | drivers/pci/rom.c | 9 |
19 files changed, 549 insertions, 261 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index f5a662a50acb..26c536b51c5a 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -330,6 +330,14 @@ parse_dmar_table(void) | |||
330 | entry_header = (struct acpi_dmar_header *)(dmar + 1); | 330 | entry_header = (struct acpi_dmar_header *)(dmar + 1); |
331 | while (((unsigned long)entry_header) < | 331 | while (((unsigned long)entry_header) < |
332 | (((unsigned long)dmar) + dmar_tbl->length)) { | 332 | (((unsigned long)dmar) + dmar_tbl->length)) { |
333 | /* Avoid looping forever on bad ACPI tables */ | ||
334 | if (entry_header->length == 0) { | ||
335 | printk(KERN_WARNING PREFIX | ||
336 | "Invalid 0-length structure\n"); | ||
337 | ret = -EINVAL; | ||
338 | break; | ||
339 | } | ||
340 | |||
333 | dmar_table_print_dmar_entry(entry_header); | 341 | dmar_table_print_dmar_entry(entry_header); |
334 | 342 | ||
335 | switch (entry_header->type) { | 343 | switch (entry_header->type) { |
@@ -491,7 +499,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
491 | int map_size; | 499 | int map_size; |
492 | u32 ver; | 500 | u32 ver; |
493 | static int iommu_allocated = 0; | 501 | static int iommu_allocated = 0; |
494 | int agaw; | 502 | int agaw = 0; |
495 | 503 | ||
496 | iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); | 504 | iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); |
497 | if (!iommu) | 505 | if (!iommu) |
@@ -507,6 +515,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
507 | iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); | 515 | iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); |
508 | iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); | 516 | iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); |
509 | 517 | ||
518 | #ifdef CONFIG_DMAR | ||
510 | agaw = iommu_calculate_agaw(iommu); | 519 | agaw = iommu_calculate_agaw(iommu); |
511 | if (agaw < 0) { | 520 | if (agaw < 0) { |
512 | printk(KERN_ERR | 521 | printk(KERN_ERR |
@@ -514,6 +523,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
514 | iommu->seq_id); | 523 | iommu->seq_id); |
515 | goto error; | 524 | goto error; |
516 | } | 525 | } |
526 | #endif | ||
517 | iommu->agaw = agaw; | 527 | iommu->agaw = agaw; |
518 | 528 | ||
519 | /* the registers might be more than one page */ | 529 | /* the registers might be more than one page */ |
@@ -571,19 +581,49 @@ static inline void reclaim_free_desc(struct q_inval *qi) | |||
571 | } | 581 | } |
572 | } | 582 | } |
573 | 583 | ||
584 | static int qi_check_fault(struct intel_iommu *iommu, int index) | ||
585 | { | ||
586 | u32 fault; | ||
587 | int head; | ||
588 | struct q_inval *qi = iommu->qi; | ||
589 | int wait_index = (index + 1) % QI_LENGTH; | ||
590 | |||
591 | fault = readl(iommu->reg + DMAR_FSTS_REG); | ||
592 | |||
593 | /* | ||
594 | * If IQE happens, the head points to the descriptor associated | ||
595 | * with the error. No new descriptors are fetched until the IQE | ||
596 | * is cleared. | ||
597 | */ | ||
598 | if (fault & DMA_FSTS_IQE) { | ||
599 | head = readl(iommu->reg + DMAR_IQH_REG); | ||
600 | if ((head >> 4) == index) { | ||
601 | memcpy(&qi->desc[index], &qi->desc[wait_index], | ||
602 | sizeof(struct qi_desc)); | ||
603 | __iommu_flush_cache(iommu, &qi->desc[index], | ||
604 | sizeof(struct qi_desc)); | ||
605 | writel(DMA_FSTS_IQE, iommu->reg + DMAR_FSTS_REG); | ||
606 | return -EINVAL; | ||
607 | } | ||
608 | } | ||
609 | |||
610 | return 0; | ||
611 | } | ||
612 | |||
574 | /* | 613 | /* |
575 | * Submit the queued invalidation descriptor to the remapping | 614 | * Submit the queued invalidation descriptor to the remapping |
576 | * hardware unit and wait for its completion. | 615 | * hardware unit and wait for its completion. |
577 | */ | 616 | */ |
578 | void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) | 617 | int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) |
579 | { | 618 | { |
619 | int rc = 0; | ||
580 | struct q_inval *qi = iommu->qi; | 620 | struct q_inval *qi = iommu->qi; |
581 | struct qi_desc *hw, wait_desc; | 621 | struct qi_desc *hw, wait_desc; |
582 | int wait_index, index; | 622 | int wait_index, index; |
583 | unsigned long flags; | 623 | unsigned long flags; |
584 | 624 | ||
585 | if (!qi) | 625 | if (!qi) |
586 | return; | 626 | return 0; |
587 | 627 | ||
588 | hw = qi->desc; | 628 | hw = qi->desc; |
589 | 629 | ||
@@ -601,7 +641,8 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) | |||
601 | 641 | ||
602 | hw[index] = *desc; | 642 | hw[index] = *desc; |
603 | 643 | ||
604 | wait_desc.low = QI_IWD_STATUS_DATA(2) | QI_IWD_STATUS_WRITE | QI_IWD_TYPE; | 644 | wait_desc.low = QI_IWD_STATUS_DATA(QI_DONE) | |
645 | QI_IWD_STATUS_WRITE | QI_IWD_TYPE; | ||
605 | wait_desc.high = virt_to_phys(&qi->desc_status[wait_index]); | 646 | wait_desc.high = virt_to_phys(&qi->desc_status[wait_index]); |
606 | 647 | ||
607 | hw[wait_index] = wait_desc; | 648 | hw[wait_index] = wait_desc; |
@@ -612,13 +653,11 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) | |||
612 | qi->free_head = (qi->free_head + 2) % QI_LENGTH; | 653 | qi->free_head = (qi->free_head + 2) % QI_LENGTH; |
613 | qi->free_cnt -= 2; | 654 | qi->free_cnt -= 2; |
614 | 655 | ||
615 | spin_lock(&iommu->register_lock); | ||
616 | /* | 656 | /* |
617 | * update the HW tail register indicating the presence of | 657 | * update the HW tail register indicating the presence of |
618 | * new descriptors. | 658 | * new descriptors. |
619 | */ | 659 | */ |
620 | writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG); | 660 | writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG); |
621 | spin_unlock(&iommu->register_lock); | ||
622 | 661 | ||
623 | while (qi->desc_status[wait_index] != QI_DONE) { | 662 | while (qi->desc_status[wait_index] != QI_DONE) { |
624 | /* | 663 | /* |
@@ -628,15 +667,21 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) | |||
628 | * a deadlock where the interrupt context can wait indefinitely | 667 | * a deadlock where the interrupt context can wait indefinitely |
629 | * for free slots in the queue. | 668 | * for free slots in the queue. |
630 | */ | 669 | */ |
670 | rc = qi_check_fault(iommu, index); | ||
671 | if (rc) | ||
672 | goto out; | ||
673 | |||
631 | spin_unlock(&qi->q_lock); | 674 | spin_unlock(&qi->q_lock); |
632 | cpu_relax(); | 675 | cpu_relax(); |
633 | spin_lock(&qi->q_lock); | 676 | spin_lock(&qi->q_lock); |
634 | } | 677 | } |
635 | 678 | out: | |
636 | qi->desc_status[index] = QI_DONE; | 679 | qi->desc_status[index] = qi->desc_status[wait_index] = QI_DONE; |
637 | 680 | ||
638 | reclaim_free_desc(qi); | 681 | reclaim_free_desc(qi); |
639 | spin_unlock_irqrestore(&qi->q_lock, flags); | 682 | spin_unlock_irqrestore(&qi->q_lock, flags); |
683 | |||
684 | return rc; | ||
640 | } | 685 | } |
641 | 686 | ||
642 | /* | 687 | /* |
@@ -649,13 +694,13 @@ void qi_global_iec(struct intel_iommu *iommu) | |||
649 | desc.low = QI_IEC_TYPE; | 694 | desc.low = QI_IEC_TYPE; |
650 | desc.high = 0; | 695 | desc.high = 0; |
651 | 696 | ||
697 | /* should never fail */ | ||
652 | qi_submit_sync(&desc, iommu); | 698 | qi_submit_sync(&desc, iommu); |
653 | } | 699 | } |
654 | 700 | ||
655 | int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm, | 701 | int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm, |
656 | u64 type, int non_present_entry_flush) | 702 | u64 type, int non_present_entry_flush) |
657 | { | 703 | { |
658 | |||
659 | struct qi_desc desc; | 704 | struct qi_desc desc; |
660 | 705 | ||
661 | if (non_present_entry_flush) { | 706 | if (non_present_entry_flush) { |
@@ -669,10 +714,7 @@ int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm, | |||
669 | | QI_CC_GRAN(type) | QI_CC_TYPE; | 714 | | QI_CC_GRAN(type) | QI_CC_TYPE; |
670 | desc.high = 0; | 715 | desc.high = 0; |
671 | 716 | ||
672 | qi_submit_sync(&desc, iommu); | 717 | return qi_submit_sync(&desc, iommu); |
673 | |||
674 | return 0; | ||
675 | |||
676 | } | 718 | } |
677 | 719 | ||
678 | int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, | 720 | int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, |
@@ -702,10 +744,7 @@ int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, | |||
702 | desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih) | 744 | desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih) |
703 | | QI_IOTLB_AM(size_order); | 745 | | QI_IOTLB_AM(size_order); |
704 | 746 | ||
705 | qi_submit_sync(&desc, iommu); | 747 | return qi_submit_sync(&desc, iommu); |
706 | |||
707 | return 0; | ||
708 | |||
709 | } | 748 | } |
710 | 749 | ||
711 | /* | 750 | /* |
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index e31fb91652ce..2aa117c8cd87 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile | |||
@@ -5,11 +5,15 @@ | |||
5 | obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o | 5 | obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o |
6 | obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o | 6 | obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o |
7 | obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o | 7 | obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o |
8 | |||
9 | # pciehp should be linked before acpiphp in order to allow the native driver | ||
10 | # to attempt to bind first. We can then fall back to generic support. | ||
11 | |||
12 | obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o | ||
8 | obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o | 13 | obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o |
9 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o | 14 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o |
10 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o | 15 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o |
11 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o | 16 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o |
12 | obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o | ||
13 | obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o | 17 | obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o |
14 | obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o | 18 | obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o |
15 | obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o | 19 | obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index f09b1010d477..803d9ddd6e75 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -266,6 +266,8 @@ static int detect_ejectable_slots(struct pci_bus *pbus) | |||
266 | int found = acpi_pci_detect_ejectable(pbus); | 266 | int found = acpi_pci_detect_ejectable(pbus); |
267 | if (!found) { | 267 | if (!found) { |
268 | acpi_handle bridge_handle = acpi_pci_get_bridge_handle(pbus); | 268 | acpi_handle bridge_handle = acpi_pci_get_bridge_handle(pbus); |
269 | if (!bridge_handle) | ||
270 | return 0; | ||
269 | acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1, | 271 | acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1, |
270 | is_pci_dock_device, (void *)&found, NULL); | 272 | is_pci_dock_device, (void *)&found, NULL); |
271 | } | 273 | } |
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index b0e7de9e536d..d8649e127298 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -195,13 +195,13 @@ static void remove_slot_worker(struct work_struct *work) | |||
195 | * Tries hard not to re-enable already existing devices; | 195 | * Tries hard not to re-enable already existing devices; |
196 | * also handles scanning of subfunctions. | 196 | * also handles scanning of subfunctions. |
197 | */ | 197 | */ |
198 | static void pci_rescan_slot(struct pci_dev *temp) | 198 | static int pci_rescan_slot(struct pci_dev *temp) |
199 | { | 199 | { |
200 | struct pci_bus *bus = temp->bus; | 200 | struct pci_bus *bus = temp->bus; |
201 | struct pci_dev *dev; | 201 | struct pci_dev *dev; |
202 | int func; | 202 | int func; |
203 | int retval; | ||
204 | u8 hdr_type; | 203 | u8 hdr_type; |
204 | int count = 0; | ||
205 | 205 | ||
206 | if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { | 206 | if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { |
207 | temp->hdr_type = hdr_type & 0x7f; | 207 | temp->hdr_type = hdr_type & 0x7f; |
@@ -213,17 +213,12 @@ static void pci_rescan_slot(struct pci_dev *temp) | |||
213 | dbg("New device on %s function %x:%x\n", | 213 | dbg("New device on %s function %x:%x\n", |
214 | bus->name, temp->devfn >> 3, | 214 | bus->name, temp->devfn >> 3, |
215 | temp->devfn & 7); | 215 | temp->devfn & 7); |
216 | retval = pci_bus_add_device(dev); | 216 | count++; |
217 | if (retval) | ||
218 | dev_err(&dev->dev, "error adding " | ||
219 | "device, continuing.\n"); | ||
220 | else | ||
221 | add_slot(dev); | ||
222 | } | 217 | } |
223 | } | 218 | } |
224 | /* multifunction device? */ | 219 | /* multifunction device? */ |
225 | if (!(hdr_type & 0x80)) | 220 | if (!(hdr_type & 0x80)) |
226 | return; | 221 | return count; |
227 | 222 | ||
228 | /* continue scanning for other functions */ | 223 | /* continue scanning for other functions */ |
229 | for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) { | 224 | for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) { |
@@ -239,16 +234,13 @@ static void pci_rescan_slot(struct pci_dev *temp) | |||
239 | dbg("New device on %s function %x:%x\n", | 234 | dbg("New device on %s function %x:%x\n", |
240 | bus->name, temp->devfn >> 3, | 235 | bus->name, temp->devfn >> 3, |
241 | temp->devfn & 7); | 236 | temp->devfn & 7); |
242 | retval = pci_bus_add_device(dev); | 237 | count++; |
243 | if (retval) | ||
244 | dev_err(&dev->dev, "error adding " | ||
245 | "device, continuing.\n"); | ||
246 | else | ||
247 | add_slot(dev); | ||
248 | } | 238 | } |
249 | } | 239 | } |
250 | } | 240 | } |
251 | } | 241 | } |
242 | |||
243 | return count; | ||
252 | } | 244 | } |
253 | 245 | ||
254 | 246 | ||
@@ -262,6 +254,8 @@ static void pci_rescan_bus(const struct pci_bus *bus) | |||
262 | { | 254 | { |
263 | unsigned int devfn; | 255 | unsigned int devfn; |
264 | struct pci_dev *dev; | 256 | struct pci_dev *dev; |
257 | int retval; | ||
258 | int found = 0; | ||
265 | dev = alloc_pci_dev(); | 259 | dev = alloc_pci_dev(); |
266 | if (!dev) | 260 | if (!dev) |
267 | return; | 261 | return; |
@@ -270,7 +264,23 @@ static void pci_rescan_bus(const struct pci_bus *bus) | |||
270 | dev->sysdata = bus->sysdata; | 264 | dev->sysdata = bus->sysdata; |
271 | for (devfn = 0; devfn < 0x100; devfn += 8) { | 265 | for (devfn = 0; devfn < 0x100; devfn += 8) { |
272 | dev->devfn = devfn; | 266 | dev->devfn = devfn; |
273 | pci_rescan_slot(dev); | 267 | found += pci_rescan_slot(dev); |
268 | } | ||
269 | |||
270 | if (found) { | ||
271 | pci_bus_assign_resources(bus); | ||
272 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
273 | /* Skip already-added devices */ | ||
274 | if (dev->is_added) | ||
275 | continue; | ||
276 | retval = pci_bus_add_device(dev); | ||
277 | if (retval) | ||
278 | dev_err(&dev->dev, | ||
279 | "Error adding device, continuing\n"); | ||
280 | else | ||
281 | add_slot(dev); | ||
282 | } | ||
283 | pci_bus_add_devices(bus); | ||
274 | } | 284 | } |
275 | kfree(dev); | 285 | kfree(dev); |
276 | } | 286 | } |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index db85284ffb62..39ae37589fda 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -111,6 +111,7 @@ struct controller { | |||
111 | int cmd_busy; | 111 | int cmd_busy; |
112 | unsigned int no_cmd_complete:1; | 112 | unsigned int no_cmd_complete:1; |
113 | unsigned int link_active_reporting:1; | 113 | unsigned int link_active_reporting:1; |
114 | unsigned int notification_enabled:1; | ||
114 | }; | 115 | }; |
115 | 116 | ||
116 | #define INT_BUTTON_IGNORE 0 | 117 | #define INT_BUTTON_IGNORE 0 |
@@ -170,6 +171,7 @@ extern int pciehp_configure_device(struct slot *p_slot); | |||
170 | extern int pciehp_unconfigure_device(struct slot *p_slot); | 171 | extern int pciehp_unconfigure_device(struct slot *p_slot); |
171 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); | 172 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); |
172 | struct controller *pcie_init(struct pcie_device *dev); | 173 | struct controller *pcie_init(struct pcie_device *dev); |
174 | int pcie_init_notification(struct controller *ctrl); | ||
173 | int pciehp_enable_slot(struct slot *p_slot); | 175 | int pciehp_enable_slot(struct slot *p_slot); |
174 | int pciehp_disable_slot(struct slot *p_slot); | 176 | int pciehp_disable_slot(struct slot *p_slot); |
175 | int pcie_enable_notification(struct controller *ctrl); | 177 | int pcie_enable_notification(struct controller *ctrl); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 5482d4ed8256..681e3912b821 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -126,8 +126,10 @@ static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status) | |||
126 | mutex_lock(&slot->ctrl->crit_sect); | 126 | mutex_lock(&slot->ctrl->crit_sect); |
127 | 127 | ||
128 | /* has it been >1 sec since our last toggle? */ | 128 | /* has it been >1 sec since our last toggle? */ |
129 | if ((get_seconds() - slot->last_emi_toggle) < 1) | 129 | if ((get_seconds() - slot->last_emi_toggle) < 1) { |
130 | mutex_unlock(&slot->ctrl->crit_sect); | ||
130 | return -EINVAL; | 131 | return -EINVAL; |
132 | } | ||
131 | 133 | ||
132 | /* see what our current state is */ | 134 | /* see what our current state is */ |
133 | retval = get_lock_status(hotplug_slot, &value); | 135 | retval = get_lock_status(hotplug_slot, &value); |
@@ -432,6 +434,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
432 | goto err_out_release_ctlr; | 434 | goto err_out_release_ctlr; |
433 | } | 435 | } |
434 | 436 | ||
437 | /* Enable events after we have setup the data structures */ | ||
438 | rc = pcie_init_notification(ctrl); | ||
439 | if (rc) { | ||
440 | ctrl_err(ctrl, "Notification initialization failed\n"); | ||
441 | goto err_out_release_ctlr; | ||
442 | } | ||
443 | |||
435 | /* Check if slot is occupied */ | 444 | /* Check if slot is occupied */ |
436 | t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); | 445 | t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); |
437 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); | 446 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 71a8012886b0..7a16c6897bb9 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -934,7 +934,7 @@ static void pcie_disable_notification(struct controller *ctrl) | |||
934 | ctrl_warn(ctrl, "Cannot disable software notification\n"); | 934 | ctrl_warn(ctrl, "Cannot disable software notification\n"); |
935 | } | 935 | } |
936 | 936 | ||
937 | static int pcie_init_notification(struct controller *ctrl) | 937 | int pcie_init_notification(struct controller *ctrl) |
938 | { | 938 | { |
939 | if (pciehp_request_irq(ctrl)) | 939 | if (pciehp_request_irq(ctrl)) |
940 | return -1; | 940 | return -1; |
@@ -942,13 +942,17 @@ static int pcie_init_notification(struct controller *ctrl) | |||
942 | pciehp_free_irq(ctrl); | 942 | pciehp_free_irq(ctrl); |
943 | return -1; | 943 | return -1; |
944 | } | 944 | } |
945 | ctrl->notification_enabled = 1; | ||
945 | return 0; | 946 | return 0; |
946 | } | 947 | } |
947 | 948 | ||
948 | static void pcie_shutdown_notification(struct controller *ctrl) | 949 | static void pcie_shutdown_notification(struct controller *ctrl) |
949 | { | 950 | { |
950 | pcie_disable_notification(ctrl); | 951 | if (ctrl->notification_enabled) { |
951 | pciehp_free_irq(ctrl); | 952 | pcie_disable_notification(ctrl); |
953 | pciehp_free_irq(ctrl); | ||
954 | ctrl->notification_enabled = 0; | ||
955 | } | ||
952 | } | 956 | } |
953 | 957 | ||
954 | static int pcie_init_slot(struct controller *ctrl) | 958 | static int pcie_init_slot(struct controller *ctrl) |
@@ -1110,13 +1114,8 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
1110 | if (pcie_init_slot(ctrl)) | 1114 | if (pcie_init_slot(ctrl)) |
1111 | goto abort_ctrl; | 1115 | goto abort_ctrl; |
1112 | 1116 | ||
1113 | if (pcie_init_notification(ctrl)) | ||
1114 | goto abort_slot; | ||
1115 | |||
1116 | return ctrl; | 1117 | return ctrl; |
1117 | 1118 | ||
1118 | abort_slot: | ||
1119 | pcie_cleanup_slot(ctrl); | ||
1120 | abort_ctrl: | 1119 | abort_ctrl: |
1121 | kfree(ctrl); | 1120 | kfree(ctrl); |
1122 | abort: | 1121 | abort: |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 628f8b72e530..e7d058aa7b0d 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -61,6 +61,8 @@ | |||
61 | /* global iommu list, set NULL for ignored DMAR units */ | 61 | /* global iommu list, set NULL for ignored DMAR units */ |
62 | static struct intel_iommu **g_iommus; | 62 | static struct intel_iommu **g_iommus; |
63 | 63 | ||
64 | static int rwbf_quirk; | ||
65 | |||
64 | /* | 66 | /* |
65 | * 0: Present | 67 | * 0: Present |
66 | * 1-11: Reserved | 68 | * 1-11: Reserved |
@@ -268,7 +270,12 @@ static long list_size; | |||
268 | 270 | ||
269 | static void domain_remove_dev_info(struct dmar_domain *domain); | 271 | static void domain_remove_dev_info(struct dmar_domain *domain); |
270 | 272 | ||
271 | int dmar_disabled; | 273 | #ifdef CONFIG_DMAR_DEFAULT_ON |
274 | int dmar_disabled = 0; | ||
275 | #else | ||
276 | int dmar_disabled = 1; | ||
277 | #endif /*CONFIG_DMAR_DEFAULT_ON*/ | ||
278 | |||
272 | static int __initdata dmar_map_gfx = 1; | 279 | static int __initdata dmar_map_gfx = 1; |
273 | static int dmar_forcedac; | 280 | static int dmar_forcedac; |
274 | static int intel_iommu_strict; | 281 | static int intel_iommu_strict; |
@@ -284,9 +291,12 @@ static int __init intel_iommu_setup(char *str) | |||
284 | if (!str) | 291 | if (!str) |
285 | return -EINVAL; | 292 | return -EINVAL; |
286 | while (*str) { | 293 | while (*str) { |
287 | if (!strncmp(str, "off", 3)) { | 294 | if (!strncmp(str, "on", 2)) { |
295 | dmar_disabled = 0; | ||
296 | printk(KERN_INFO "Intel-IOMMU: enabled\n"); | ||
297 | } else if (!strncmp(str, "off", 3)) { | ||
288 | dmar_disabled = 1; | 298 | dmar_disabled = 1; |
289 | printk(KERN_INFO"Intel-IOMMU: disabled\n"); | 299 | printk(KERN_INFO "Intel-IOMMU: disabled\n"); |
290 | } else if (!strncmp(str, "igfx_off", 8)) { | 300 | } else if (!strncmp(str, "igfx_off", 8)) { |
291 | dmar_map_gfx = 0; | 301 | dmar_map_gfx = 0; |
292 | printk(KERN_INFO | 302 | printk(KERN_INFO |
@@ -777,7 +787,7 @@ static void iommu_flush_write_buffer(struct intel_iommu *iommu) | |||
777 | u32 val; | 787 | u32 val; |
778 | unsigned long flag; | 788 | unsigned long flag; |
779 | 789 | ||
780 | if (!cap_rwbf(iommu->cap)) | 790 | if (!rwbf_quirk && !cap_rwbf(iommu->cap)) |
781 | return; | 791 | return; |
782 | val = iommu->gcmd | DMA_GCMD_WBF; | 792 | val = iommu->gcmd | DMA_GCMD_WBF; |
783 | 793 | ||
@@ -3145,3 +3155,15 @@ static struct iommu_ops intel_iommu_ops = { | |||
3145 | .unmap = intel_iommu_unmap_range, | 3155 | .unmap = intel_iommu_unmap_range, |
3146 | .iova_to_phys = intel_iommu_iova_to_phys, | 3156 | .iova_to_phys = intel_iommu_iova_to_phys, |
3147 | }; | 3157 | }; |
3158 | |||
3159 | static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) | ||
3160 | { | ||
3161 | /* | ||
3162 | * Mobile 4 Series Chipset neglects to set RWBF capability, | ||
3163 | * but needs it: | ||
3164 | */ | ||
3165 | printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n"); | ||
3166 | rwbf_quirk = 1; | ||
3167 | } | ||
3168 | |||
3169 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); | ||
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index f78371b22529..45effc5726c0 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c | |||
@@ -207,7 +207,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) | |||
207 | return index; | 207 | return index; |
208 | } | 208 | } |
209 | 209 | ||
210 | static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask) | 210 | static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask) |
211 | { | 211 | { |
212 | struct qi_desc desc; | 212 | struct qi_desc desc; |
213 | 213 | ||
@@ -215,7 +215,7 @@ static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask) | |||
215 | | QI_IEC_SELECTIVE; | 215 | | QI_IEC_SELECTIVE; |
216 | desc.high = 0; | 216 | desc.high = 0; |
217 | 217 | ||
218 | qi_submit_sync(&desc, iommu); | 218 | return qi_submit_sync(&desc, iommu); |
219 | } | 219 | } |
220 | 220 | ||
221 | int map_irq_to_irte_handle(int irq, u16 *sub_handle) | 221 | int map_irq_to_irte_handle(int irq, u16 *sub_handle) |
@@ -283,6 +283,7 @@ int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index) | |||
283 | 283 | ||
284 | int modify_irte(int irq, struct irte *irte_modified) | 284 | int modify_irte(int irq, struct irte *irte_modified) |
285 | { | 285 | { |
286 | int rc; | ||
286 | int index; | 287 | int index; |
287 | struct irte *irte; | 288 | struct irte *irte; |
288 | struct intel_iommu *iommu; | 289 | struct intel_iommu *iommu; |
@@ -303,14 +304,15 @@ int modify_irte(int irq, struct irte *irte_modified) | |||
303 | set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); | 304 | set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); |
304 | __iommu_flush_cache(iommu, irte, sizeof(*irte)); | 305 | __iommu_flush_cache(iommu, irte, sizeof(*irte)); |
305 | 306 | ||
306 | qi_flush_iec(iommu, index, 0); | 307 | rc = qi_flush_iec(iommu, index, 0); |
307 | |||
308 | spin_unlock(&irq_2_ir_lock); | 308 | spin_unlock(&irq_2_ir_lock); |
309 | return 0; | 309 | |
310 | return rc; | ||
310 | } | 311 | } |
311 | 312 | ||
312 | int flush_irte(int irq) | 313 | int flush_irte(int irq) |
313 | { | 314 | { |
315 | int rc; | ||
314 | int index; | 316 | int index; |
315 | struct intel_iommu *iommu; | 317 | struct intel_iommu *iommu; |
316 | struct irq_2_iommu *irq_iommu; | 318 | struct irq_2_iommu *irq_iommu; |
@@ -326,10 +328,10 @@ int flush_irte(int irq) | |||
326 | 328 | ||
327 | index = irq_iommu->irte_index + irq_iommu->sub_handle; | 329 | index = irq_iommu->irte_index + irq_iommu->sub_handle; |
328 | 330 | ||
329 | qi_flush_iec(iommu, index, irq_iommu->irte_mask); | 331 | rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask); |
330 | spin_unlock(&irq_2_ir_lock); | 332 | spin_unlock(&irq_2_ir_lock); |
331 | 333 | ||
332 | return 0; | 334 | return rc; |
333 | } | 335 | } |
334 | 336 | ||
335 | struct intel_iommu *map_ioapic_to_ir(int apic) | 337 | struct intel_iommu *map_ioapic_to_ir(int apic) |
@@ -355,6 +357,7 @@ struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) | |||
355 | 357 | ||
356 | int free_irte(int irq) | 358 | int free_irte(int irq) |
357 | { | 359 | { |
360 | int rc = 0; | ||
358 | int index, i; | 361 | int index, i; |
359 | struct irte *irte; | 362 | struct irte *irte; |
360 | struct intel_iommu *iommu; | 363 | struct intel_iommu *iommu; |
@@ -375,7 +378,7 @@ int free_irte(int irq) | |||
375 | if (!irq_iommu->sub_handle) { | 378 | if (!irq_iommu->sub_handle) { |
376 | for (i = 0; i < (1 << irq_iommu->irte_mask); i++) | 379 | for (i = 0; i < (1 << irq_iommu->irte_mask); i++) |
377 | set_64bit((unsigned long *)irte, 0); | 380 | set_64bit((unsigned long *)irte, 0); |
378 | qi_flush_iec(iommu, index, irq_iommu->irte_mask); | 381 | rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask); |
379 | } | 382 | } |
380 | 383 | ||
381 | irq_iommu->iommu = NULL; | 384 | irq_iommu->iommu = NULL; |
@@ -385,7 +388,7 @@ int free_irte(int irq) | |||
385 | 388 | ||
386 | spin_unlock(&irq_2_ir_lock); | 389 | spin_unlock(&irq_2_ir_lock); |
387 | 390 | ||
388 | return 0; | 391 | return rc; |
389 | } | 392 | } |
390 | 393 | ||
391 | static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode) | 394 | static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode) |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index b4a90badd0a6..baba2eb5367d 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -103,6 +103,14 @@ static void msix_set_enable(struct pci_dev *dev, int enable) | |||
103 | } | 103 | } |
104 | } | 104 | } |
105 | 105 | ||
106 | static inline __attribute_const__ u32 msi_mask(unsigned x) | ||
107 | { | ||
108 | /* Don't shift by >= width of type */ | ||
109 | if (x >= 5) | ||
110 | return 0xffffffff; | ||
111 | return (1 << (1 << x)) - 1; | ||
112 | } | ||
113 | |||
106 | static void msix_flush_writes(struct irq_desc *desc) | 114 | static void msix_flush_writes(struct irq_desc *desc) |
107 | { | 115 | { |
108 | struct msi_desc *entry; | 116 | struct msi_desc *entry; |
@@ -398,21 +406,18 @@ static int msi_capability_init(struct pci_dev *dev) | |||
398 | entry->msi_attrib.masked = 1; | 406 | entry->msi_attrib.masked = 1; |
399 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ | 407 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ |
400 | entry->msi_attrib.pos = pos; | 408 | entry->msi_attrib.pos = pos; |
401 | if (entry->msi_attrib.maskbit) { | ||
402 | entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, | ||
403 | entry->msi_attrib.is_64); | ||
404 | } | ||
405 | entry->dev = dev; | 409 | entry->dev = dev; |
406 | if (entry->msi_attrib.maskbit) { | 410 | if (entry->msi_attrib.maskbit) { |
407 | unsigned int maskbits, temp; | 411 | unsigned int base, maskbits, temp; |
412 | |||
413 | base = msi_mask_bits_reg(pos, entry->msi_attrib.is_64); | ||
414 | entry->mask_base = (void __iomem *)(long)base; | ||
415 | |||
408 | /* All MSIs are unmasked by default, Mask them all */ | 416 | /* All MSIs are unmasked by default, Mask them all */ |
409 | pci_read_config_dword(dev, | 417 | pci_read_config_dword(dev, base, &maskbits); |
410 | msi_mask_bits_reg(pos, entry->msi_attrib.is_64), | 418 | temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1); |
411 | &maskbits); | ||
412 | temp = (1 << multi_msi_capable(control)); | ||
413 | temp = ((temp - 1) & ~temp); | ||
414 | maskbits |= temp; | 419 | maskbits |= temp; |
415 | pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits); | 420 | pci_write_config_dword(dev, base, maskbits); |
416 | entry->msi_attrib.maskbits_mask = temp; | 421 | entry->msi_attrib.maskbits_mask = temp; |
417 | } | 422 | } |
418 | list_add_tail(&entry->list, &dev->msi_list); | 423 | list_add_tail(&entry->list, &dev->msi_list); |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index c697f2680856..93eac1423585 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -355,17 +355,34 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state) | |||
355 | int i = 0; | 355 | int i = 0; |
356 | 356 | ||
357 | if (drv && drv->suspend) { | 357 | if (drv && drv->suspend) { |
358 | pci_power_t prev = pci_dev->current_state; | ||
359 | |||
360 | pci_dev->state_saved = false; | ||
361 | |||
358 | i = drv->suspend(pci_dev, state); | 362 | i = drv->suspend(pci_dev, state); |
359 | suspend_report_result(drv->suspend, i); | 363 | suspend_report_result(drv->suspend, i); |
360 | } else { | 364 | if (i) |
361 | pci_save_state(pci_dev); | 365 | return i; |
362 | /* | 366 | |
363 | * This is for compatibility with existing code with legacy PM | 367 | if (pci_dev->state_saved) |
364 | * support. | 368 | goto Fixup; |
365 | */ | 369 | |
366 | pci_pm_set_unknown_state(pci_dev); | 370 | if (pci_dev->current_state != PCI_D0 |
371 | && pci_dev->current_state != PCI_UNKNOWN) { | ||
372 | WARN_ONCE(pci_dev->current_state != prev, | ||
373 | "PCI PM: Device state not saved by %pF\n", | ||
374 | drv->suspend); | ||
375 | goto Fixup; | ||
376 | } | ||
367 | } | 377 | } |
368 | 378 | ||
379 | pci_save_state(pci_dev); | ||
380 | /* | ||
381 | * This is for compatibility with existing code with legacy PM support. | ||
382 | */ | ||
383 | pci_pm_set_unknown_state(pci_dev); | ||
384 | |||
385 | Fixup: | ||
369 | pci_fixup_device(pci_fixup_suspend, pci_dev); | 386 | pci_fixup_device(pci_fixup_suspend, pci_dev); |
370 | 387 | ||
371 | return i; | 388 | return i; |
@@ -386,108 +403,47 @@ static int pci_legacy_suspend_late(struct device *dev, pm_message_t state) | |||
386 | 403 | ||
387 | static int pci_legacy_resume_early(struct device *dev) | 404 | static int pci_legacy_resume_early(struct device *dev) |
388 | { | 405 | { |
389 | int error = 0; | ||
390 | struct pci_dev * pci_dev = to_pci_dev(dev); | 406 | struct pci_dev * pci_dev = to_pci_dev(dev); |
391 | struct pci_driver * drv = pci_dev->driver; | 407 | struct pci_driver * drv = pci_dev->driver; |
392 | 408 | ||
393 | pci_fixup_device(pci_fixup_resume_early, pci_dev); | 409 | return drv && drv->resume_early ? |
394 | 410 | drv->resume_early(pci_dev) : 0; | |
395 | if (drv && drv->resume_early) | ||
396 | error = drv->resume_early(pci_dev); | ||
397 | return error; | ||
398 | } | 411 | } |
399 | 412 | ||
400 | static int pci_legacy_resume(struct device *dev) | 413 | static int pci_legacy_resume(struct device *dev) |
401 | { | 414 | { |
402 | int error; | ||
403 | struct pci_dev * pci_dev = to_pci_dev(dev); | 415 | struct pci_dev * pci_dev = to_pci_dev(dev); |
404 | struct pci_driver * drv = pci_dev->driver; | 416 | struct pci_driver * drv = pci_dev->driver; |
405 | 417 | ||
406 | pci_fixup_device(pci_fixup_resume, pci_dev); | 418 | pci_fixup_device(pci_fixup_resume, pci_dev); |
407 | 419 | ||
408 | if (drv && drv->resume) { | 420 | return drv && drv->resume ? |
409 | error = drv->resume(pci_dev); | 421 | drv->resume(pci_dev) : pci_pm_reenable_device(pci_dev); |
410 | } else { | ||
411 | /* restore the PCI config space */ | ||
412 | pci_restore_state(pci_dev); | ||
413 | error = pci_pm_reenable_device(pci_dev); | ||
414 | } | ||
415 | return error; | ||
416 | } | 422 | } |
417 | 423 | ||
418 | /* Auxiliary functions used by the new power management framework */ | 424 | /* Auxiliary functions used by the new power management framework */ |
419 | 425 | ||
420 | static int pci_restore_standard_config(struct pci_dev *pci_dev) | ||
421 | { | ||
422 | struct pci_dev *parent = pci_dev->bus->self; | ||
423 | int error = 0; | ||
424 | |||
425 | /* Check if the device's bus is operational */ | ||
426 | if (!parent || parent->current_state == PCI_D0) { | ||
427 | pci_restore_state(pci_dev); | ||
428 | pci_update_current_state(pci_dev, PCI_D0); | ||
429 | } else { | ||
430 | dev_warn(&pci_dev->dev, "unable to restore config, " | ||
431 | "bridge %s in low power state D%d\n", pci_name(parent), | ||
432 | parent->current_state); | ||
433 | pci_dev->current_state = PCI_UNKNOWN; | ||
434 | error = -EAGAIN; | ||
435 | } | ||
436 | |||
437 | return error; | ||
438 | } | ||
439 | |||
440 | static bool pci_is_bridge(struct pci_dev *pci_dev) | ||
441 | { | ||
442 | return !!(pci_dev->subordinate); | ||
443 | } | ||
444 | |||
445 | static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) | 426 | static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) |
446 | { | 427 | { |
447 | if (pci_restore_standard_config(pci_dev)) | 428 | pci_restore_standard_config(pci_dev); |
448 | pci_fixup_device(pci_fixup_resume_early, pci_dev); | 429 | pci_dev->state_saved = false; |
430 | pci_fixup_device(pci_fixup_resume_early, pci_dev); | ||
449 | } | 431 | } |
450 | 432 | ||
451 | static int pci_pm_default_resume(struct pci_dev *pci_dev) | 433 | static void pci_pm_default_resume(struct pci_dev *pci_dev) |
452 | { | 434 | { |
453 | /* | ||
454 | * pci_restore_standard_config() should have been called once already, | ||
455 | * but it would have failed if the device's parent bridge had not been | ||
456 | * in power state D0 at that time. Check it and try again if necessary. | ||
457 | */ | ||
458 | if (pci_dev->current_state == PCI_UNKNOWN) { | ||
459 | int error = pci_restore_standard_config(pci_dev); | ||
460 | if (error) | ||
461 | return error; | ||
462 | } | ||
463 | |||
464 | pci_fixup_device(pci_fixup_resume, pci_dev); | 435 | pci_fixup_device(pci_fixup_resume, pci_dev); |
465 | 436 | ||
466 | if (!pci_is_bridge(pci_dev)) | 437 | if (!pci_is_bridge(pci_dev)) |
467 | pci_enable_wake(pci_dev, PCI_D0, false); | 438 | pci_enable_wake(pci_dev, PCI_D0, false); |
468 | |||
469 | return pci_pm_reenable_device(pci_dev); | ||
470 | } | ||
471 | |||
472 | static void pci_pm_default_suspend_generic(struct pci_dev *pci_dev) | ||
473 | { | ||
474 | /* If device is enabled at this point, disable it */ | ||
475 | pci_disable_enabled_device(pci_dev); | ||
476 | /* | ||
477 | * Save state with interrupts enabled, because in principle the bus the | ||
478 | * device is on may be put into a low power state after this code runs. | ||
479 | */ | ||
480 | pci_save_state(pci_dev); | ||
481 | } | 439 | } |
482 | 440 | ||
483 | static void pci_pm_default_suspend(struct pci_dev *pci_dev) | 441 | static void pci_pm_default_suspend(struct pci_dev *pci_dev) |
484 | { | 442 | { |
485 | pci_pm_default_suspend_generic(pci_dev); | 443 | /* Disable non-bridge devices without PM support */ |
486 | |||
487 | if (!pci_is_bridge(pci_dev)) | 444 | if (!pci_is_bridge(pci_dev)) |
488 | pci_prepare_to_sleep(pci_dev); | 445 | pci_disable_enabled_device(pci_dev); |
489 | 446 | pci_save_state(pci_dev); | |
490 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
491 | } | 447 | } |
492 | 448 | ||
493 | static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) | 449 | static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) |
@@ -532,21 +488,49 @@ static void pci_pm_complete(struct device *dev) | |||
532 | static int pci_pm_suspend(struct device *dev) | 488 | static int pci_pm_suspend(struct device *dev) |
533 | { | 489 | { |
534 | struct pci_dev *pci_dev = to_pci_dev(dev); | 490 | struct pci_dev *pci_dev = to_pci_dev(dev); |
535 | struct device_driver *drv = dev->driver; | 491 | struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
536 | int error = 0; | ||
537 | 492 | ||
538 | if (pci_has_legacy_pm_support(pci_dev)) | 493 | if (pci_has_legacy_pm_support(pci_dev)) |
539 | return pci_legacy_suspend(dev, PMSG_SUSPEND); | 494 | return pci_legacy_suspend(dev, PMSG_SUSPEND); |
540 | 495 | ||
541 | if (drv && drv->pm && drv->pm->suspend) { | 496 | if (!pm) { |
542 | error = drv->pm->suspend(dev); | 497 | pci_pm_default_suspend(pci_dev); |
543 | suspend_report_result(drv->pm->suspend, error); | 498 | goto Fixup; |
544 | } | 499 | } |
545 | 500 | ||
546 | if (!error) | 501 | pci_dev->state_saved = false; |
547 | pci_pm_default_suspend(pci_dev); | ||
548 | 502 | ||
549 | return error; | 503 | if (pm->suspend) { |
504 | pci_power_t prev = pci_dev->current_state; | ||
505 | int error; | ||
506 | |||
507 | error = pm->suspend(dev); | ||
508 | suspend_report_result(pm->suspend, error); | ||
509 | if (error) | ||
510 | return error; | ||
511 | |||
512 | if (pci_dev->state_saved) | ||
513 | goto Fixup; | ||
514 | |||
515 | if (pci_dev->current_state != PCI_D0 | ||
516 | && pci_dev->current_state != PCI_UNKNOWN) { | ||
517 | WARN_ONCE(pci_dev->current_state != prev, | ||
518 | "PCI PM: State of device not saved by %pF\n", | ||
519 | pm->suspend); | ||
520 | goto Fixup; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | if (!pci_dev->state_saved) { | ||
525 | pci_save_state(pci_dev); | ||
526 | if (!pci_is_bridge(pci_dev)) | ||
527 | pci_prepare_to_sleep(pci_dev); | ||
528 | } | ||
529 | |||
530 | Fixup: | ||
531 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
532 | |||
533 | return 0; | ||
550 | } | 534 | } |
551 | 535 | ||
552 | static int pci_pm_suspend_noirq(struct device *dev) | 536 | static int pci_pm_suspend_noirq(struct device *dev) |
@@ -575,11 +559,11 @@ static int pci_pm_resume_noirq(struct device *dev) | |||
575 | struct device_driver *drv = dev->driver; | 559 | struct device_driver *drv = dev->driver; |
576 | int error = 0; | 560 | int error = 0; |
577 | 561 | ||
562 | pci_pm_default_resume_noirq(pci_dev); | ||
563 | |||
578 | if (pci_has_legacy_pm_support(pci_dev)) | 564 | if (pci_has_legacy_pm_support(pci_dev)) |
579 | return pci_legacy_resume_early(dev); | 565 | return pci_legacy_resume_early(dev); |
580 | 566 | ||
581 | pci_pm_default_resume_noirq(pci_dev); | ||
582 | |||
583 | if (drv && drv->pm && drv->pm->resume_noirq) | 567 | if (drv && drv->pm && drv->pm->resume_noirq) |
584 | error = drv->pm->resume_noirq(dev); | 568 | error = drv->pm->resume_noirq(dev); |
585 | 569 | ||
@@ -589,18 +573,29 @@ static int pci_pm_resume_noirq(struct device *dev) | |||
589 | static int pci_pm_resume(struct device *dev) | 573 | static int pci_pm_resume(struct device *dev) |
590 | { | 574 | { |
591 | struct pci_dev *pci_dev = to_pci_dev(dev); | 575 | struct pci_dev *pci_dev = to_pci_dev(dev); |
592 | struct device_driver *drv = dev->driver; | 576 | struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
593 | int error = 0; | 577 | int error = 0; |
594 | 578 | ||
579 | /* | ||
580 | * This is necessary for the suspend error path in which resume is | ||
581 | * called without restoring the standard config registers of the device. | ||
582 | */ | ||
583 | if (pci_dev->state_saved) | ||
584 | pci_restore_standard_config(pci_dev); | ||
585 | |||
595 | if (pci_has_legacy_pm_support(pci_dev)) | 586 | if (pci_has_legacy_pm_support(pci_dev)) |
596 | return pci_legacy_resume(dev); | 587 | return pci_legacy_resume(dev); |
597 | 588 | ||
598 | error = pci_pm_default_resume(pci_dev); | 589 | pci_pm_default_resume(pci_dev); |
599 | 590 | ||
600 | if (!error && drv && drv->pm && drv->pm->resume) | 591 | if (pm) { |
601 | error = drv->pm->resume(dev); | 592 | if (pm->resume) |
593 | error = pm->resume(dev); | ||
594 | } else { | ||
595 | pci_pm_reenable_device(pci_dev); | ||
596 | } | ||
602 | 597 | ||
603 | return error; | 598 | return 0; |
604 | } | 599 | } |
605 | 600 | ||
606 | #else /* !CONFIG_SUSPEND */ | 601 | #else /* !CONFIG_SUSPEND */ |
@@ -617,21 +612,31 @@ static int pci_pm_resume(struct device *dev) | |||
617 | static int pci_pm_freeze(struct device *dev) | 612 | static int pci_pm_freeze(struct device *dev) |
618 | { | 613 | { |
619 | struct pci_dev *pci_dev = to_pci_dev(dev); | 614 | struct pci_dev *pci_dev = to_pci_dev(dev); |
620 | struct device_driver *drv = dev->driver; | 615 | struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
621 | int error = 0; | ||
622 | 616 | ||
623 | if (pci_has_legacy_pm_support(pci_dev)) | 617 | if (pci_has_legacy_pm_support(pci_dev)) |
624 | return pci_legacy_suspend(dev, PMSG_FREEZE); | 618 | return pci_legacy_suspend(dev, PMSG_FREEZE); |
625 | 619 | ||
626 | if (drv && drv->pm && drv->pm->freeze) { | 620 | if (!pm) { |
627 | error = drv->pm->freeze(dev); | 621 | pci_pm_default_suspend(pci_dev); |
628 | suspend_report_result(drv->pm->freeze, error); | 622 | return 0; |
629 | } | 623 | } |
630 | 624 | ||
631 | if (!error) | 625 | pci_dev->state_saved = false; |
632 | pci_pm_default_suspend_generic(pci_dev); | ||
633 | 626 | ||
634 | return error; | 627 | if (pm->freeze) { |
628 | int error; | ||
629 | |||
630 | error = pm->freeze(dev); | ||
631 | suspend_report_result(pm->freeze, error); | ||
632 | if (error) | ||
633 | return error; | ||
634 | } | ||
635 | |||
636 | if (!pci_dev->state_saved) | ||
637 | pci_save_state(pci_dev); | ||
638 | |||
639 | return 0; | ||
635 | } | 640 | } |
636 | 641 | ||
637 | static int pci_pm_freeze_noirq(struct device *dev) | 642 | static int pci_pm_freeze_noirq(struct device *dev) |
@@ -674,16 +679,18 @@ static int pci_pm_thaw_noirq(struct device *dev) | |||
674 | static int pci_pm_thaw(struct device *dev) | 679 | static int pci_pm_thaw(struct device *dev) |
675 | { | 680 | { |
676 | struct pci_dev *pci_dev = to_pci_dev(dev); | 681 | struct pci_dev *pci_dev = to_pci_dev(dev); |
677 | struct device_driver *drv = dev->driver; | 682 | struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
678 | int error = 0; | 683 | int error = 0; |
679 | 684 | ||
680 | if (pci_has_legacy_pm_support(pci_dev)) | 685 | if (pci_has_legacy_pm_support(pci_dev)) |
681 | return pci_legacy_resume(dev); | 686 | return pci_legacy_resume(dev); |
682 | 687 | ||
683 | pci_pm_reenable_device(pci_dev); | 688 | if (pm) { |
684 | 689 | if (pm->thaw) | |
685 | if (drv && drv->pm && drv->pm->thaw) | 690 | error = pm->thaw(dev); |
686 | error = drv->pm->thaw(dev); | 691 | } else { |
692 | pci_pm_reenable_device(pci_dev); | ||
693 | } | ||
687 | 694 | ||
688 | return error; | 695 | return error; |
689 | } | 696 | } |
@@ -691,19 +698,29 @@ static int pci_pm_thaw(struct device *dev) | |||
691 | static int pci_pm_poweroff(struct device *dev) | 698 | static int pci_pm_poweroff(struct device *dev) |
692 | { | 699 | { |
693 | struct pci_dev *pci_dev = to_pci_dev(dev); | 700 | struct pci_dev *pci_dev = to_pci_dev(dev); |
694 | struct device_driver *drv = dev->driver; | 701 | struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
695 | int error = 0; | 702 | int error = 0; |
696 | 703 | ||
697 | if (pci_has_legacy_pm_support(pci_dev)) | 704 | if (pci_has_legacy_pm_support(pci_dev)) |
698 | return pci_legacy_suspend(dev, PMSG_HIBERNATE); | 705 | return pci_legacy_suspend(dev, PMSG_HIBERNATE); |
699 | 706 | ||
700 | if (drv && drv->pm && drv->pm->poweroff) { | 707 | if (!pm) { |
701 | error = drv->pm->poweroff(dev); | 708 | pci_pm_default_suspend(pci_dev); |
702 | suspend_report_result(drv->pm->poweroff, error); | 709 | goto Fixup; |
703 | } | 710 | } |
704 | 711 | ||
705 | if (!error) | 712 | pci_dev->state_saved = false; |
706 | pci_pm_default_suspend(pci_dev); | 713 | |
714 | if (pm->poweroff) { | ||
715 | error = pm->poweroff(dev); | ||
716 | suspend_report_result(pm->poweroff, error); | ||
717 | } | ||
718 | |||
719 | if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) | ||
720 | pci_prepare_to_sleep(pci_dev); | ||
721 | |||
722 | Fixup: | ||
723 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
707 | 724 | ||
708 | return error; | 725 | return error; |
709 | } | 726 | } |
@@ -730,11 +747,11 @@ static int pci_pm_restore_noirq(struct device *dev) | |||
730 | struct device_driver *drv = dev->driver; | 747 | struct device_driver *drv = dev->driver; |
731 | int error = 0; | 748 | int error = 0; |
732 | 749 | ||
750 | pci_pm_default_resume_noirq(pci_dev); | ||
751 | |||
733 | if (pci_has_legacy_pm_support(pci_dev)) | 752 | if (pci_has_legacy_pm_support(pci_dev)) |
734 | return pci_legacy_resume_early(dev); | 753 | return pci_legacy_resume_early(dev); |
735 | 754 | ||
736 | pci_pm_default_resume_noirq(pci_dev); | ||
737 | |||
738 | if (drv && drv->pm && drv->pm->restore_noirq) | 755 | if (drv && drv->pm && drv->pm->restore_noirq) |
739 | error = drv->pm->restore_noirq(dev); | 756 | error = drv->pm->restore_noirq(dev); |
740 | 757 | ||
@@ -744,16 +761,27 @@ static int pci_pm_restore_noirq(struct device *dev) | |||
744 | static int pci_pm_restore(struct device *dev) | 761 | static int pci_pm_restore(struct device *dev) |
745 | { | 762 | { |
746 | struct pci_dev *pci_dev = to_pci_dev(dev); | 763 | struct pci_dev *pci_dev = to_pci_dev(dev); |
747 | struct device_driver *drv = dev->driver; | 764 | struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
748 | int error = 0; | 765 | int error = 0; |
749 | 766 | ||
767 | /* | ||
768 | * This is necessary for the hibernation error path in which restore is | ||
769 | * called without restoring the standard config registers of the device. | ||
770 | */ | ||
771 | if (pci_dev->state_saved) | ||
772 | pci_restore_standard_config(pci_dev); | ||
773 | |||
750 | if (pci_has_legacy_pm_support(pci_dev)) | 774 | if (pci_has_legacy_pm_support(pci_dev)) |
751 | return pci_legacy_resume(dev); | 775 | return pci_legacy_resume(dev); |
752 | 776 | ||
753 | error = pci_pm_default_resume(pci_dev); | 777 | pci_pm_default_resume(pci_dev); |
754 | 778 | ||
755 | if (!error && drv && drv->pm && drv->pm->restore) | 779 | if (pm) { |
756 | error = drv->pm->restore(dev); | 780 | if (pm->restore) |
781 | error = pm->restore(dev); | ||
782 | } else { | ||
783 | pci_pm_reenable_device(pci_dev); | ||
784 | } | ||
757 | 785 | ||
758 | return error; | 786 | return error; |
759 | } | 787 | } |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index db7ec14fa719..dfc4e0ddf241 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -768,8 +768,8 @@ pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
768 | return -EINVAL; | 768 | return -EINVAL; |
769 | 769 | ||
770 | rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */ | 770 | rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */ |
771 | if (!rom) | 771 | if (!rom || !size) |
772 | return 0; | 772 | return -EIO; |
773 | 773 | ||
774 | if (off >= size) | 774 | if (off >= size) |
775 | count = 0; | 775 | count = 0; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c12f6c790698..6d6120007af4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ | 22 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ |
23 | #include "pci.h" | 23 | #include "pci.h" |
24 | 24 | ||
25 | unsigned int pci_pm_d3_delay = 10; | 25 | unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT; |
26 | 26 | ||
27 | #ifdef CONFIG_PCI_DOMAINS | 27 | #ifdef CONFIG_PCI_DOMAINS |
28 | int pci_domains_supported = 1; | 28 | int pci_domains_supported = 1; |
@@ -426,6 +426,7 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
426 | * given PCI device | 426 | * given PCI device |
427 | * @dev: PCI device to handle. | 427 | * @dev: PCI device to handle. |
428 | * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. | 428 | * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. |
429 | * @wait: If 'true', wait for the device to change its power state | ||
429 | * | 430 | * |
430 | * RETURN VALUE: | 431 | * RETURN VALUE: |
431 | * -EINVAL if the requested state is invalid. | 432 | * -EINVAL if the requested state is invalid. |
@@ -435,7 +436,7 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
435 | * 0 if device's power state has been successfully changed. | 436 | * 0 if device's power state has been successfully changed. |
436 | */ | 437 | */ |
437 | static int | 438 | static int |
438 | pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) | 439 | pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait) |
439 | { | 440 | { |
440 | u16 pmcsr; | 441 | u16 pmcsr; |
441 | bool need_restore = false; | 442 | bool need_restore = false; |
@@ -480,8 +481,10 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
480 | break; | 481 | break; |
481 | case PCI_UNKNOWN: /* Boot-up */ | 482 | case PCI_UNKNOWN: /* Boot-up */ |
482 | if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot | 483 | if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot |
483 | && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) | 484 | && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) { |
484 | need_restore = true; | 485 | need_restore = true; |
486 | wait = true; | ||
487 | } | ||
485 | /* Fall-through: force to D0 */ | 488 | /* Fall-through: force to D0 */ |
486 | default: | 489 | default: |
487 | pmcsr = 0; | 490 | pmcsr = 0; |
@@ -491,12 +494,15 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
491 | /* enter specified state */ | 494 | /* enter specified state */ |
492 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); | 495 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); |
493 | 496 | ||
497 | if (!wait) | ||
498 | return 0; | ||
499 | |||
494 | /* Mandatory power management transition delays */ | 500 | /* Mandatory power management transition delays */ |
495 | /* see PCI PM 1.1 5.6.1 table 18 */ | 501 | /* see PCI PM 1.1 5.6.1 table 18 */ |
496 | if (state == PCI_D3hot || dev->current_state == PCI_D3hot) | 502 | if (state == PCI_D3hot || dev->current_state == PCI_D3hot) |
497 | msleep(pci_pm_d3_delay); | 503 | msleep(pci_pm_d3_delay); |
498 | else if (state == PCI_D2 || dev->current_state == PCI_D2) | 504 | else if (state == PCI_D2 || dev->current_state == PCI_D2) |
499 | udelay(200); | 505 | udelay(PCI_PM_D2_DELAY); |
500 | 506 | ||
501 | dev->current_state = state; | 507 | dev->current_state = state; |
502 | 508 | ||
@@ -515,7 +521,7 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
515 | if (need_restore) | 521 | if (need_restore) |
516 | pci_restore_bars(dev); | 522 | pci_restore_bars(dev); |
517 | 523 | ||
518 | if (dev->bus->self) | 524 | if (wait && dev->bus->self) |
519 | pcie_aspm_pm_state_change(dev->bus->self); | 525 | pcie_aspm_pm_state_change(dev->bus->self); |
520 | 526 | ||
521 | return 0; | 527 | return 0; |
@@ -585,7 +591,7 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
585 | if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) | 591 | if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) |
586 | return 0; | 592 | return 0; |
587 | 593 | ||
588 | error = pci_raw_set_power_state(dev, state); | 594 | error = pci_raw_set_power_state(dev, state, true); |
589 | 595 | ||
590 | if (state > PCI_D0 && platform_pci_power_manageable(dev)) { | 596 | if (state > PCI_D0 && platform_pci_power_manageable(dev)) { |
591 | /* Allow the platform to finalize the transition */ | 597 | /* Allow the platform to finalize the transition */ |
@@ -730,6 +736,7 @@ pci_save_state(struct pci_dev *dev) | |||
730 | /* XXX: 100% dword access ok here? */ | 736 | /* XXX: 100% dword access ok here? */ |
731 | for (i = 0; i < 16; i++) | 737 | for (i = 0; i < 16; i++) |
732 | pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); | 738 | pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); |
739 | dev->state_saved = true; | ||
733 | if ((i = pci_save_pcie_state(dev)) != 0) | 740 | if ((i = pci_save_pcie_state(dev)) != 0) |
734 | return i; | 741 | return i; |
735 | if ((i = pci_save_pcix_state(dev)) != 0) | 742 | if ((i = pci_save_pcix_state(dev)) != 0) |
@@ -1260,15 +1267,14 @@ void pci_pm_init(struct pci_dev *dev) | |||
1260 | /* find PCI PM capability in list */ | 1267 | /* find PCI PM capability in list */ |
1261 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); | 1268 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); |
1262 | if (!pm) | 1269 | if (!pm) |
1263 | goto Exit; | 1270 | return; |
1264 | |||
1265 | /* Check device's ability to generate PME# */ | 1271 | /* Check device's ability to generate PME# */ |
1266 | pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc); | 1272 | pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc); |
1267 | 1273 | ||
1268 | if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { | 1274 | if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { |
1269 | dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n", | 1275 | dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n", |
1270 | pmc & PCI_PM_CAP_VER_MASK); | 1276 | pmc & PCI_PM_CAP_VER_MASK); |
1271 | goto Exit; | 1277 | return; |
1272 | } | 1278 | } |
1273 | 1279 | ||
1274 | dev->pm_cap = pm; | 1280 | dev->pm_cap = pm; |
@@ -1307,9 +1313,6 @@ void pci_pm_init(struct pci_dev *dev) | |||
1307 | } else { | 1313 | } else { |
1308 | dev->pme_support = 0; | 1314 | dev->pme_support = 0; |
1309 | } | 1315 | } |
1310 | |||
1311 | Exit: | ||
1312 | pci_update_current_state(dev, PCI_D0); | ||
1313 | } | 1316 | } |
1314 | 1317 | ||
1315 | /** | 1318 | /** |
@@ -1378,6 +1381,50 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev) | |||
1378 | } | 1381 | } |
1379 | 1382 | ||
1380 | /** | 1383 | /** |
1384 | * pci_restore_standard_config - restore standard config registers of PCI device | ||
1385 | * @dev: PCI device to handle | ||
1386 | * | ||
1387 | * This function assumes that the device's configuration space is accessible. | ||
1388 | * If the device needs to be powered up, the function will wait for it to | ||
1389 | * change the state. | ||
1390 | */ | ||
1391 | int pci_restore_standard_config(struct pci_dev *dev) | ||
1392 | { | ||
1393 | pci_power_t prev_state; | ||
1394 | int error; | ||
1395 | |||
1396 | pci_update_current_state(dev, PCI_D0); | ||
1397 | |||
1398 | prev_state = dev->current_state; | ||
1399 | if (prev_state == PCI_D0) | ||
1400 | goto Restore; | ||
1401 | |||
1402 | error = pci_raw_set_power_state(dev, PCI_D0, false); | ||
1403 | if (error) | ||
1404 | return error; | ||
1405 | |||
1406 | /* | ||
1407 | * This assumes that we won't get a bus in B2 or B3 from the BIOS, but | ||
1408 | * we've made this assumption forever and it appears to be universally | ||
1409 | * satisfied. | ||
1410 | */ | ||
1411 | switch(prev_state) { | ||
1412 | case PCI_D3cold: | ||
1413 | case PCI_D3hot: | ||
1414 | mdelay(pci_pm_d3_delay); | ||
1415 | break; | ||
1416 | case PCI_D2: | ||
1417 | udelay(PCI_PM_D2_DELAY); | ||
1418 | break; | ||
1419 | } | ||
1420 | |||
1421 | pci_update_current_state(dev, PCI_D0); | ||
1422 | |||
1423 | Restore: | ||
1424 | return dev->state_saved ? pci_restore_state(dev) : 0; | ||
1425 | } | ||
1426 | |||
1427 | /** | ||
1381 | * pci_enable_ari - enable ARI forwarding if hardware support it | 1428 | * pci_enable_ari - enable ARI forwarding if hardware support it |
1382 | * @dev: the PCI device | 1429 | * @dev: the PCI device |
1383 | */ | 1430 | */ |
@@ -1493,16 +1540,21 @@ void pci_release_region(struct pci_dev *pdev, int bar) | |||
1493 | } | 1540 | } |
1494 | 1541 | ||
1495 | /** | 1542 | /** |
1496 | * pci_request_region - Reserved PCI I/O and memory resource | 1543 | * __pci_request_region - Reserved PCI I/O and memory resource |
1497 | * @pdev: PCI device whose resources are to be reserved | 1544 | * @pdev: PCI device whose resources are to be reserved |
1498 | * @bar: BAR to be reserved | 1545 | * @bar: BAR to be reserved |
1499 | * @res_name: Name to be associated with resource. | 1546 | * @res_name: Name to be associated with resource. |
1547 | * @exclusive: whether the region access is exclusive or not | ||
1500 | * | 1548 | * |
1501 | * Mark the PCI region associated with PCI device @pdev BR @bar as | 1549 | * Mark the PCI region associated with PCI device @pdev BR @bar as |
1502 | * being reserved by owner @res_name. Do not access any | 1550 | * being reserved by owner @res_name. Do not access any |
1503 | * address inside the PCI regions unless this call returns | 1551 | * address inside the PCI regions unless this call returns |
1504 | * successfully. | 1552 | * successfully. |
1505 | * | 1553 | * |
1554 | * If @exclusive is set, then the region is marked so that userspace | ||
1555 | * is explicitly not allowed to map the resource via /dev/mem or | ||
1556 | * sysfs MMIO access. | ||
1557 | * | ||
1506 | * Returns 0 on success, or %EBUSY on error. A warning | 1558 | * Returns 0 on success, or %EBUSY on error. A warning |
1507 | * message is also printed on failure. | 1559 | * message is also printed on failure. |
1508 | */ | 1560 | */ |
@@ -1541,12 +1593,12 @@ err_out: | |||
1541 | } | 1593 | } |
1542 | 1594 | ||
1543 | /** | 1595 | /** |
1544 | * pci_request_region - Reserved PCI I/O and memory resource | 1596 | * pci_request_region - Reserve PCI I/O and memory resource |
1545 | * @pdev: PCI device whose resources are to be reserved | 1597 | * @pdev: PCI device whose resources are to be reserved |
1546 | * @bar: BAR to be reserved | 1598 | * @bar: BAR to be reserved |
1547 | * @res_name: Name to be associated with resource. | 1599 | * @res_name: Name to be associated with resource |
1548 | * | 1600 | * |
1549 | * Mark the PCI region associated with PCI device @pdev BR @bar as | 1601 | * Mark the PCI region associated with PCI device @pdev BAR @bar as |
1550 | * being reserved by owner @res_name. Do not access any | 1602 | * being reserved by owner @res_name. Do not access any |
1551 | * address inside the PCI regions unless this call returns | 1603 | * address inside the PCI regions unless this call returns |
1552 | * successfully. | 1604 | * successfully. |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 1351bb4addde..07c0aa5275e6 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -16,21 +16,21 @@ extern int pci_mmap_fits(struct pci_dev *pdev, int resno, | |||
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | /** | 18 | /** |
19 | * Firmware PM callbacks | 19 | * struct pci_platform_pm_ops - Firmware PM callbacks |
20 | * | 20 | * |
21 | * @is_manageable - returns 'true' if given device is power manageable by the | 21 | * @is_manageable: returns 'true' if given device is power manageable by the |
22 | * platform firmware | 22 | * platform firmware |
23 | * | 23 | * |
24 | * @set_state - invokes the platform firmware to set the device's power state | 24 | * @set_state: invokes the platform firmware to set the device's power state |
25 | * | 25 | * |
26 | * @choose_state - returns PCI power state of given device preferred by the | 26 | * @choose_state: returns PCI power state of given device preferred by the |
27 | * platform; to be used during system-wide transitions from a | 27 | * platform; to be used during system-wide transitions from a |
28 | * sleeping state to the working state and vice versa | 28 | * sleeping state to the working state and vice versa |
29 | * | 29 | * |
30 | * @can_wakeup - returns 'true' if given device is capable of waking up the | 30 | * @can_wakeup: returns 'true' if given device is capable of waking up the |
31 | * system from a sleeping state | 31 | * system from a sleeping state |
32 | * | 32 | * |
33 | * @sleep_wake - enables/disables the system wake up capability of given device | 33 | * @sleep_wake: enables/disables the system wake up capability of given device |
34 | * | 34 | * |
35 | * If given platform is generally capable of power managing PCI devices, all of | 35 | * If given platform is generally capable of power managing PCI devices, all of |
36 | * these callbacks are mandatory. | 36 | * these callbacks are mandatory. |
@@ -49,6 +49,12 @@ extern void pci_disable_enabled_device(struct pci_dev *dev); | |||
49 | extern void pci_pm_init(struct pci_dev *dev); | 49 | extern void pci_pm_init(struct pci_dev *dev); |
50 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | 50 | extern void platform_pci_wakeup_init(struct pci_dev *dev); |
51 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 51 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
52 | extern int pci_restore_standard_config(struct pci_dev *dev); | ||
53 | |||
54 | static inline bool pci_is_bridge(struct pci_dev *pci_dev) | ||
55 | { | ||
56 | return !!(pci_dev->subordinate); | ||
57 | } | ||
52 | 58 | ||
53 | extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); | 59 | extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); |
54 | extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); | 60 | extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index aac7006949f1..d0c973685868 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -108,6 +108,34 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev) | |||
108 | } | 108 | } |
109 | #endif /* 0 */ | 109 | #endif /* 0 */ |
110 | 110 | ||
111 | |||
112 | static void set_device_error_reporting(struct pci_dev *dev, void *data) | ||
113 | { | ||
114 | bool enable = *((bool *)data); | ||
115 | |||
116 | if (dev->pcie_type != PCIE_RC_PORT && | ||
117 | dev->pcie_type != PCIE_SW_UPSTREAM_PORT && | ||
118 | dev->pcie_type != PCIE_SW_DOWNSTREAM_PORT) | ||
119 | return; | ||
120 | |||
121 | if (enable) | ||
122 | pci_enable_pcie_error_reporting(dev); | ||
123 | else | ||
124 | pci_disable_pcie_error_reporting(dev); | ||
125 | } | ||
126 | |||
127 | /** | ||
128 | * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports. | ||
129 | * @dev: pointer to root port's pci_dev data structure | ||
130 | * @enable: true = enable error reporting, false = disable error reporting. | ||
131 | */ | ||
132 | static void set_downstream_devices_error_reporting(struct pci_dev *dev, | ||
133 | bool enable) | ||
134 | { | ||
135 | set_device_error_reporting(dev, &enable); | ||
136 | pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable); | ||
137 | } | ||
138 | |||
111 | static int find_device_iter(struct device *device, void *data) | 139 | static int find_device_iter(struct device *device, void *data) |
112 | { | 140 | { |
113 | struct pci_dev *dev; | 141 | struct pci_dev *dev; |
@@ -525,15 +553,11 @@ void aer_enable_rootport(struct aer_rpc *rpc) | |||
525 | pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); | 553 | pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); |
526 | pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); | 554 | pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); |
527 | 555 | ||
528 | /* Enable Root Port device reporting error itself */ | 556 | /* |
529 | pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, ®16); | 557 | * Enable error reporting for the root port device and downstream port |
530 | reg16 = reg16 | | 558 | * devices. |
531 | PCI_EXP_DEVCTL_CERE | | 559 | */ |
532 | PCI_EXP_DEVCTL_NFERE | | 560 | set_downstream_devices_error_reporting(pdev, true); |
533 | PCI_EXP_DEVCTL_FERE | | ||
534 | PCI_EXP_DEVCTL_URRE; | ||
535 | pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL, | ||
536 | reg16); | ||
537 | 561 | ||
538 | /* Enable Root Port's interrupt in response to error messages */ | 562 | /* Enable Root Port's interrupt in response to error messages */ |
539 | pci_write_config_dword(pdev, | 563 | pci_write_config_dword(pdev, |
@@ -553,6 +577,12 @@ static void disable_root_aer(struct aer_rpc *rpc) | |||
553 | u32 reg32; | 577 | u32 reg32; |
554 | int pos; | 578 | int pos; |
555 | 579 | ||
580 | /* | ||
581 | * Disable error reporting for the root port device and downstream port | ||
582 | * devices. | ||
583 | */ | ||
584 | set_downstream_devices_error_reporting(pdev, false); | ||
585 | |||
556 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); | 586 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); |
557 | /* Disable Root's interrupt in response to error messages */ | 587 | /* Disable Root's interrupt in response to error messages */ |
558 | pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); | 588 | pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 586b6f75910d..b0367f168af4 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -718,9 +718,9 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) | |||
718 | 718 | ||
719 | /* | 719 | /* |
720 | * All PCIe functions are in one slot, remove one function will remove | 720 | * All PCIe functions are in one slot, remove one function will remove |
721 | * the the whole slot, so just wait | 721 | * the whole slot, so just wait until we are the last function left. |
722 | */ | 722 | */ |
723 | if (!list_empty(&parent->subordinate->devices)) | 723 | if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices)) |
724 | goto out; | 724 | goto out; |
725 | 725 | ||
726 | /* All functions are removed, so just disable ASPM for the link */ | 726 | /* All functions are removed, so just disable ASPM for the link */ |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 99a914a027f8..248b4db91552 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -55,25 +55,13 @@ static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) | |||
55 | 55 | ||
56 | } | 56 | } |
57 | 57 | ||
58 | static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state) | ||
59 | { | ||
60 | return pci_save_state(dev); | ||
61 | } | ||
62 | |||
63 | static int pcie_portdrv_resume_early(struct pci_dev *dev) | ||
64 | { | ||
65 | return pci_restore_state(dev); | ||
66 | } | ||
67 | |||
68 | static int pcie_portdrv_resume(struct pci_dev *dev) | 58 | static int pcie_portdrv_resume(struct pci_dev *dev) |
69 | { | 59 | { |
70 | pcie_portdrv_restore_config(dev); | 60 | pci_set_master(dev); |
71 | return pcie_port_device_resume(dev); | 61 | return pcie_port_device_resume(dev); |
72 | } | 62 | } |
73 | #else | 63 | #else |
74 | #define pcie_portdrv_suspend NULL | 64 | #define pcie_portdrv_suspend NULL |
75 | #define pcie_portdrv_suspend_late NULL | ||
76 | #define pcie_portdrv_resume_early NULL | ||
77 | #define pcie_portdrv_resume NULL | 65 | #define pcie_portdrv_resume NULL |
78 | #endif | 66 | #endif |
79 | 67 | ||
@@ -109,8 +97,6 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, | |||
109 | 97 | ||
110 | pcie_portdrv_save_config(dev); | 98 | pcie_portdrv_save_config(dev); |
111 | 99 | ||
112 | pci_enable_pcie_error_reporting(dev); | ||
113 | |||
114 | return 0; | 100 | return 0; |
115 | } | 101 | } |
116 | 102 | ||
@@ -292,8 +278,6 @@ static struct pci_driver pcie_portdriver = { | |||
292 | .remove = pcie_portdrv_remove, | 278 | .remove = pcie_portdrv_remove, |
293 | 279 | ||
294 | .suspend = pcie_portdrv_suspend, | 280 | .suspend = pcie_portdrv_suspend, |
295 | .suspend_late = pcie_portdrv_suspend_late, | ||
296 | .resume_early = pcie_portdrv_resume_early, | ||
297 | .resume = pcie_portdrv_resume, | 281 | .resume = pcie_portdrv_resume, |
298 | 282 | ||
299 | .err_handler = &pcie_portdrv_err_handler, | 283 | .err_handler = &pcie_portdrv_err_handler, |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index baad093aafe3..f20d55368edb 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -1584,6 +1584,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_ | |||
1584 | */ | 1584 | */ |
1585 | #define AMD_813X_MISC 0x40 | 1585 | #define AMD_813X_MISC 0x40 |
1586 | #define AMD_813X_NOIOAMODE (1<<0) | 1586 | #define AMD_813X_NOIOAMODE (1<<0) |
1587 | #define AMD_813X_REV_B2 0x13 | ||
1587 | 1588 | ||
1588 | static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | 1589 | static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) |
1589 | { | 1590 | { |
@@ -1591,6 +1592,8 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | |||
1591 | 1592 | ||
1592 | if (noioapicquirk) | 1593 | if (noioapicquirk) |
1593 | return; | 1594 | return; |
1595 | if (dev->revision == AMD_813X_REV_B2) | ||
1596 | return; | ||
1594 | 1597 | ||
1595 | pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); | 1598 | pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); |
1596 | pci_config_dword &= ~AMD_813X_NOIOAMODE; | 1599 | pci_config_dword &= ~AMD_813X_NOIOAMODE; |
@@ -1981,7 +1984,6 @@ static void __devinit quirk_msi_ht_cap(struct pci_dev *dev) | |||
1981 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, | 1984 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, |
1982 | quirk_msi_ht_cap); | 1985 | quirk_msi_ht_cap); |
1983 | 1986 | ||
1984 | |||
1985 | /* The nVidia CK804 chipset may have 2 HT MSI mappings. | 1987 | /* The nVidia CK804 chipset may have 2 HT MSI mappings. |
1986 | * MSI are supported if the MSI capability set in any of these mappings. | 1988 | * MSI are supported if the MSI capability set in any of these mappings. |
1987 | */ | 1989 | */ |
@@ -2032,6 +2034,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, | |||
2032 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, | 2034 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, |
2033 | ht_enable_msi_mapping); | 2035 | ht_enable_msi_mapping); |
2034 | 2036 | ||
2037 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, | ||
2038 | ht_enable_msi_mapping); | ||
2039 | |||
2035 | /* The P5N32-SLI Premium motherboard from Asus has a problem with msi | 2040 | /* The P5N32-SLI Premium motherboard from Asus has a problem with msi |
2036 | * for the MCP55 NIC. It is not yet determined whether the msi problem | 2041 | * for the MCP55 NIC. It is not yet determined whether the msi problem |
2037 | * also affects other devices. As for now, turn off msi for this device. | 2042 | * also affects other devices. As for now, turn off msi for this device. |
@@ -2048,10 +2053,100 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, | |||
2048 | PCI_DEVICE_ID_NVIDIA_NVENET_15, | 2053 | PCI_DEVICE_ID_NVIDIA_NVENET_15, |
2049 | nvenet_msi_disable); | 2054 | nvenet_msi_disable); |
2050 | 2055 | ||
2051 | static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) | 2056 | static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev) |
2052 | { | 2057 | { |
2053 | struct pci_dev *host_bridge; | 2058 | struct pci_dev *host_bridge; |
2059 | int pos; | ||
2060 | int i, dev_no; | ||
2061 | int found = 0; | ||
2062 | |||
2063 | dev_no = dev->devfn >> 3; | ||
2064 | for (i = dev_no; i >= 0; i--) { | ||
2065 | host_bridge = pci_get_slot(dev->bus, PCI_DEVFN(i, 0)); | ||
2066 | if (!host_bridge) | ||
2067 | continue; | ||
2068 | |||
2069 | pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); | ||
2070 | if (pos != 0) { | ||
2071 | found = 1; | ||
2072 | break; | ||
2073 | } | ||
2074 | pci_dev_put(host_bridge); | ||
2075 | } | ||
2076 | |||
2077 | if (!found) | ||
2078 | return; | ||
2079 | |||
2080 | /* root did that ! */ | ||
2081 | if (msi_ht_cap_enabled(host_bridge)) | ||
2082 | goto out; | ||
2083 | |||
2084 | ht_enable_msi_mapping(dev); | ||
2085 | |||
2086 | out: | ||
2087 | pci_dev_put(host_bridge); | ||
2088 | } | ||
2089 | |||
2090 | static void __devinit ht_disable_msi_mapping(struct pci_dev *dev) | ||
2091 | { | ||
2092 | int pos, ttl = 48; | ||
2093 | |||
2094 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); | ||
2095 | while (pos && ttl--) { | ||
2096 | u8 flags; | ||
2097 | |||
2098 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, | ||
2099 | &flags) == 0) { | ||
2100 | dev_info(&dev->dev, "Enabling HT MSI Mapping\n"); | ||
2101 | |||
2102 | pci_write_config_byte(dev, pos + HT_MSI_FLAGS, | ||
2103 | flags & ~HT_MSI_FLAGS_ENABLE); | ||
2104 | } | ||
2105 | pos = pci_find_next_ht_capability(dev, pos, | ||
2106 | HT_CAPTYPE_MSI_MAPPING); | ||
2107 | } | ||
2108 | } | ||
2109 | |||
2110 | static int __devinit ht_check_msi_mapping(struct pci_dev *dev) | ||
2111 | { | ||
2054 | int pos, ttl = 48; | 2112 | int pos, ttl = 48; |
2113 | int found = 0; | ||
2114 | |||
2115 | /* check if there is HT MSI cap or enabled on this device */ | ||
2116 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); | ||
2117 | while (pos && ttl--) { | ||
2118 | u8 flags; | ||
2119 | |||
2120 | if (found < 1) | ||
2121 | found = 1; | ||
2122 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, | ||
2123 | &flags) == 0) { | ||
2124 | if (flags & HT_MSI_FLAGS_ENABLE) { | ||
2125 | if (found < 2) { | ||
2126 | found = 2; | ||
2127 | break; | ||
2128 | } | ||
2129 | } | ||
2130 | } | ||
2131 | pos = pci_find_next_ht_capability(dev, pos, | ||
2132 | HT_CAPTYPE_MSI_MAPPING); | ||
2133 | } | ||
2134 | |||
2135 | return found; | ||
2136 | } | ||
2137 | |||
2138 | static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) | ||
2139 | { | ||
2140 | struct pci_dev *host_bridge; | ||
2141 | int pos; | ||
2142 | int found; | ||
2143 | |||
2144 | /* check if there is HT MSI cap or enabled on this device */ | ||
2145 | found = ht_check_msi_mapping(dev); | ||
2146 | |||
2147 | /* no HT MSI CAP */ | ||
2148 | if (found == 0) | ||
2149 | return; | ||
2055 | 2150 | ||
2056 | /* | 2151 | /* |
2057 | * HT MSI mapping should be disabled on devices that are below | 2152 | * HT MSI mapping should be disabled on devices that are below |
@@ -2067,24 +2162,19 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) | |||
2067 | pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); | 2162 | pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); |
2068 | if (pos != 0) { | 2163 | if (pos != 0) { |
2069 | /* Host bridge is to HT */ | 2164 | /* Host bridge is to HT */ |
2070 | ht_enable_msi_mapping(dev); | 2165 | if (found == 1) { |
2166 | /* it is not enabled, try to enable it */ | ||
2167 | nv_ht_enable_msi_mapping(dev); | ||
2168 | } | ||
2071 | return; | 2169 | return; |
2072 | } | 2170 | } |
2073 | 2171 | ||
2074 | /* Host bridge is not to HT, disable HT MSI mapping on this device */ | 2172 | /* HT MSI is not enabled */ |
2075 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); | 2173 | if (found == 1) |
2076 | while (pos && ttl--) { | 2174 | return; |
2077 | u8 flags; | ||
2078 | 2175 | ||
2079 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, | 2176 | /* Host bridge is not to HT, disable HT MSI mapping on this device */ |
2080 | &flags) == 0) { | 2177 | ht_disable_msi_mapping(dev); |
2081 | dev_info(&dev->dev, "Disabling HT MSI mapping"); | ||
2082 | pci_write_config_byte(dev, pos + HT_MSI_FLAGS, | ||
2083 | flags & ~HT_MSI_FLAGS_ENABLE); | ||
2084 | } | ||
2085 | pos = pci_find_next_ht_capability(dev, pos, | ||
2086 | HT_CAPTYPE_MSI_MAPPING); | ||
2087 | } | ||
2088 | } | 2178 | } |
2089 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); | 2179 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); |
2090 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk); | 2180 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk); |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 132a78159b60..36864a935d68 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -55,6 +55,7 @@ void pci_disable_rom(struct pci_dev *pdev) | |||
55 | 55 | ||
56 | /** | 56 | /** |
57 | * pci_get_rom_size - obtain the actual size of the ROM image | 57 | * pci_get_rom_size - obtain the actual size of the ROM image |
58 | * @pdev: target PCI device | ||
58 | * @rom: kernel virtual pointer to image of ROM | 59 | * @rom: kernel virtual pointer to image of ROM |
59 | * @size: size of PCI window | 60 | * @size: size of PCI window |
60 | * return: size of actual ROM image | 61 | * return: size of actual ROM image |
@@ -63,7 +64,7 @@ void pci_disable_rom(struct pci_dev *pdev) | |||
63 | * The PCI window size could be much larger than the | 64 | * The PCI window size could be much larger than the |
64 | * actual image size. | 65 | * actual image size. |
65 | */ | 66 | */ |
66 | size_t pci_get_rom_size(void __iomem *rom, size_t size) | 67 | size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) |
67 | { | 68 | { |
68 | void __iomem *image; | 69 | void __iomem *image; |
69 | int last_image; | 70 | int last_image; |
@@ -72,8 +73,10 @@ size_t pci_get_rom_size(void __iomem *rom, size_t size) | |||
72 | do { | 73 | do { |
73 | void __iomem *pds; | 74 | void __iomem *pds; |
74 | /* Standard PCI ROMs start out with these bytes 55 AA */ | 75 | /* Standard PCI ROMs start out with these bytes 55 AA */ |
75 | if (readb(image) != 0x55) | 76 | if (readb(image) != 0x55) { |
77 | dev_err(&pdev->dev, "Invalid ROM contents\n"); | ||
76 | break; | 78 | break; |
79 | } | ||
77 | if (readb(image + 1) != 0xAA) | 80 | if (readb(image + 1) != 0xAA) |
78 | break; | 81 | break; |
79 | /* get the PCI data structure and check its signature */ | 82 | /* get the PCI data structure and check its signature */ |
@@ -159,7 +162,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
159 | * size is much larger than the actual size of the ROM. | 162 | * size is much larger than the actual size of the ROM. |
160 | * True size is important if the ROM is going to be copied. | 163 | * True size is important if the ROM is going to be copied. |
161 | */ | 164 | */ |
162 | *size = pci_get_rom_size(rom, *size); | 165 | *size = pci_get_rom_size(pdev, rom, *size); |
163 | return rom; | 166 | return rom; |
164 | } | 167 | } |
165 | 168 | ||