diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-30 02:35:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-30 02:35:05 -0400 |
commit | f85f19de90a9997583bb26e6f1f9297a4e152c18 (patch) | |
tree | 2dfe61dab6c39ca202f114cb68c68978da1624e3 /drivers/pci | |
parent | b993fdbc7fe26f96b59003a3552c418a71aa0a9f (diff) | |
parent | 7b87c9df5602efd6c7edeb291bbd104d49a6babf (diff) |
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6:
PCI: remove printks about disabled bridge windows
PCI: fold pci_calc_resource_flags() into decode_bar()
PCI: treat mem BAR type "11" (reserved) as 32-bit, not 64-bit, BAR
PCI: correct pcie_set_readrq write size
PCI: pciehp: change wait time for valid configuration access
x86/PCI: Preserve existing pci=bfsort whitelist for Dell systems
PCI: ARI is a PCIe v2 feature
x86/PCI: quirks: Use pci_dev->revision
PCI: Make the struct pci_dev * argument of pci_fixup_irqs const.
PCI hotplug: cpqphp: use pci_dev->vendor
PCI hotplug: cpqphp: use pci_dev->subsystem_{vendor|device}
x86/PCI: config space accessor functions should not ignore the segment argument
PCI: Assign values to 'pci_obff_signal_type' enumeration constants
x86/PCI: reduce severity of host bridge window conflict warnings
PCI: enumerate the PCI device only removed out PCI hieratchy of OS when re-scanning PCI
PCI: PCIe AER: add aer_recover_queue
x86/PCI: select direct access mode for mmconfig option
PCI hotplug: Rename is_ejectable which also exists in dock.c
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/acpi_pcihp.c | 6 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_core.c | 17 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_ctrl.c | 3 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 11 | ||||
-rw-r--r-- | drivers/pci/pci.c | 11 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_core.c | 76 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_errprint.c | 3 | ||||
-rw-r--r-- | drivers/pci/probe.c | 87 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 3 | ||||
-rw-r--r-- | drivers/pci/setup-irq.c | 4 | ||||
-rw-r--r-- | drivers/pci/setup-res.c | 3 |
11 files changed, 136 insertions, 88 deletions
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 8f3faf343f75..095f29e13734 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -408,7 +408,7 @@ got_one: | |||
408 | } | 408 | } |
409 | EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware); | 409 | EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware); |
410 | 410 | ||
411 | static int is_ejectable(acpi_handle handle) | 411 | static int pcihp_is_ejectable(acpi_handle handle) |
412 | { | 412 | { |
413 | acpi_status status; | 413 | acpi_status status; |
414 | acpi_handle tmp; | 414 | acpi_handle tmp; |
@@ -442,7 +442,7 @@ int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle) | |||
442 | return 0; | 442 | return 0; |
443 | if (bridge_handle != parent_handle) | 443 | if (bridge_handle != parent_handle) |
444 | return 0; | 444 | return 0; |
445 | return is_ejectable(handle); | 445 | return pcihp_is_ejectable(handle); |
446 | } | 446 | } |
447 | EXPORT_SYMBOL_GPL(acpi_pci_check_ejectable); | 447 | EXPORT_SYMBOL_GPL(acpi_pci_check_ejectable); |
448 | 448 | ||
@@ -450,7 +450,7 @@ static acpi_status | |||
450 | check_hotplug(acpi_handle handle, u32 lvl, void *context, void **rv) | 450 | check_hotplug(acpi_handle handle, u32 lvl, void *context, void **rv) |
451 | { | 451 | { |
452 | int *found = (int *)context; | 452 | int *found = (int *)context; |
453 | if (is_ejectable(handle)) { | 453 | if (pcihp_is_ejectable(handle)) { |
454 | *found = 1; | 454 | *found = 1; |
455 | return AE_CTRL_TERMINATE; | 455 | return AE_CTRL_TERMINATE; |
456 | } | 456 | } |
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 4952c3b9379d..f1ce99cceac6 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -840,8 +840,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
840 | /* Need to read VID early b/c it's used to differentiate CPQ and INTC | 840 | /* Need to read VID early b/c it's used to differentiate CPQ and INTC |
841 | * discovery | 841 | * discovery |
842 | */ | 842 | */ |
843 | rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id); | 843 | vendor_id = pdev->vendor; |
844 | if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) { | 844 | if ((vendor_id != PCI_VENDOR_ID_COMPAQ) && |
845 | (vendor_id != PCI_VENDOR_ID_INTEL)) { | ||
845 | err(msg_HPC_non_compaq_or_intel); | 846 | err(msg_HPC_non_compaq_or_intel); |
846 | rc = -ENODEV; | 847 | rc = -ENODEV; |
847 | goto err_disable_device; | 848 | goto err_disable_device; |
@@ -868,11 +869,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
868 | /* TODO: This code can be made to support non-Compaq or Intel | 869 | /* TODO: This code can be made to support non-Compaq or Intel |
869 | * subsystem IDs | 870 | * subsystem IDs |
870 | */ | 871 | */ |
871 | rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid); | 872 | subsystem_vid = pdev->subsystem_vendor; |
872 | if (rc) { | ||
873 | err("%s : pci_read_config_word failed\n", __func__); | ||
874 | goto err_disable_device; | ||
875 | } | ||
876 | dbg("Subsystem Vendor ID: %x\n", subsystem_vid); | 873 | dbg("Subsystem Vendor ID: %x\n", subsystem_vid); |
877 | if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) { | 874 | if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) { |
878 | err(msg_HPC_non_compaq_or_intel); | 875 | err(msg_HPC_non_compaq_or_intel); |
@@ -887,11 +884,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
887 | goto err_disable_device; | 884 | goto err_disable_device; |
888 | } | 885 | } |
889 | 886 | ||
890 | rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid); | 887 | subsystem_deviceid = pdev->subsystem_device; |
891 | if (rc) { | ||
892 | err("%s : pci_read_config_word failed\n", __func__); | ||
893 | goto err_free_ctrl; | ||
894 | } | ||
895 | 888 | ||
896 | info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid); | 889 | info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid); |
897 | 890 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 085dbb5fc168..1e9c9aacc3a6 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -213,6 +213,9 @@ static int board_added(struct slot *p_slot) | |||
213 | goto err_exit; | 213 | goto err_exit; |
214 | } | 214 | } |
215 | 215 | ||
216 | /* Wait for 1 second after checking link training status */ | ||
217 | msleep(1000); | ||
218 | |||
216 | /* Check for a power fault */ | 219 | /* Check for a power fault */ |
217 | if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) { | 220 | if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) { |
218 | ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); | 221 | ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 50a23da5d24d..96dc4734e4af 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -275,16 +275,9 @@ int pciehp_check_link_status(struct controller *ctrl) | |||
275 | * hot-plug capable downstream port. But old controller might | 275 | * hot-plug capable downstream port. But old controller might |
276 | * not implement it. In this case, we wait for 1000 ms. | 276 | * not implement it. In this case, we wait for 1000 ms. |
277 | */ | 277 | */ |
278 | if (ctrl->link_active_reporting){ | 278 | if (ctrl->link_active_reporting) |
279 | /* Wait for Data Link Layer Link Active bit to be set */ | ||
280 | pcie_wait_link_active(ctrl); | 279 | pcie_wait_link_active(ctrl); |
281 | /* | 280 | else |
282 | * We must wait for 100 ms after the Data Link Layer | ||
283 | * Link Active bit reads 1b before initiating a | ||
284 | * configuration access to the hot added device. | ||
285 | */ | ||
286 | msleep(100); | ||
287 | } else | ||
288 | msleep(1000); | 281 | msleep(1000); |
289 | 282 | ||
290 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); | 283 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 692671b11667..08a95b369d85 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1905,7 +1905,7 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1905 | { | 1905 | { |
1906 | int pos; | 1906 | int pos; |
1907 | u32 cap; | 1907 | u32 cap; |
1908 | u16 ctrl; | 1908 | u16 flags, ctrl; |
1909 | struct pci_dev *bridge; | 1909 | struct pci_dev *bridge; |
1910 | 1910 | ||
1911 | if (!pci_is_pcie(dev) || dev->devfn) | 1911 | if (!pci_is_pcie(dev) || dev->devfn) |
@@ -1923,6 +1923,11 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1923 | if (!pos) | 1923 | if (!pos) |
1924 | return; | 1924 | return; |
1925 | 1925 | ||
1926 | /* ARI is a PCIe v2 feature */ | ||
1927 | pci_read_config_word(bridge, pos + PCI_EXP_FLAGS, &flags); | ||
1928 | if ((flags & PCI_EXP_FLAGS_VERS) < 2) | ||
1929 | return; | ||
1930 | |||
1926 | pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap); | 1931 | pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap); |
1927 | if (!(cap & PCI_EXP_DEVCAP2_ARI)) | 1932 | if (!(cap & PCI_EXP_DEVCAP2_ARI)) |
1928 | return; | 1933 | return; |
@@ -3186,7 +3191,7 @@ EXPORT_SYMBOL(pcie_get_readrq); | |||
3186 | * @rq: maximum memory read count in bytes | 3191 | * @rq: maximum memory read count in bytes |
3187 | * valid values are 128, 256, 512, 1024, 2048, 4096 | 3192 | * valid values are 128, 256, 512, 1024, 2048, 4096 |
3188 | * | 3193 | * |
3189 | * If possible sets maximum read byte count | 3194 | * If possible sets maximum memory read request in bytes |
3190 | */ | 3195 | */ |
3191 | int pcie_set_readrq(struct pci_dev *dev, int rq) | 3196 | int pcie_set_readrq(struct pci_dev *dev, int rq) |
3192 | { | 3197 | { |
@@ -3209,7 +3214,7 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) | |||
3209 | if ((ctl & PCI_EXP_DEVCTL_READRQ) != v) { | 3214 | if ((ctl & PCI_EXP_DEVCTL_READRQ) != v) { |
3210 | ctl &= ~PCI_EXP_DEVCTL_READRQ; | 3215 | ctl &= ~PCI_EXP_DEVCTL_READRQ; |
3211 | ctl |= v; | 3216 | ctl |= v; |
3212 | err = pci_write_config_dword(dev, cap + PCI_EXP_DEVCTL, ctl); | 3217 | err = pci_write_config_word(dev, cap + PCI_EXP_DEVCTL, ctl); |
3213 | } | 3218 | } |
3214 | 3219 | ||
3215 | out: | 3220 | out: |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 43421fbe080a..9674e9f30d49 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/suspend.h> | 24 | #include <linux/suspend.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/kfifo.h> | ||
27 | #include "aerdrv.h" | 28 | #include "aerdrv.h" |
28 | 29 | ||
29 | static int forceload; | 30 | static int forceload; |
@@ -445,8 +446,7 @@ static struct pcie_port_service_driver *find_aer_service(struct pci_dev *dev) | |||
445 | return drv; | 446 | return drv; |
446 | } | 447 | } |
447 | 448 | ||
448 | static pci_ers_result_t reset_link(struct pcie_device *aerdev, | 449 | static pci_ers_result_t reset_link(struct pci_dev *dev) |
449 | struct pci_dev *dev) | ||
450 | { | 450 | { |
451 | struct pci_dev *udev; | 451 | struct pci_dev *udev; |
452 | pci_ers_result_t status; | 452 | pci_ers_result_t status; |
@@ -486,7 +486,6 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev, | |||
486 | 486 | ||
487 | /** | 487 | /** |
488 | * do_recovery - handle nonfatal/fatal error recovery process | 488 | * do_recovery - handle nonfatal/fatal error recovery process |
489 | * @aerdev: pointer to a pcie_device data structure of root port | ||
490 | * @dev: pointer to a pci_dev data structure of agent detecting an error | 489 | * @dev: pointer to a pci_dev data structure of agent detecting an error |
491 | * @severity: error severity type | 490 | * @severity: error severity type |
492 | * | 491 | * |
@@ -494,8 +493,7 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev, | |||
494 | * error detected message to all downstream drivers within a hierarchy in | 493 | * error detected message to all downstream drivers within a hierarchy in |
495 | * question and return the returned code. | 494 | * question and return the returned code. |
496 | */ | 495 | */ |
497 | static void do_recovery(struct pcie_device *aerdev, struct pci_dev *dev, | 496 | static void do_recovery(struct pci_dev *dev, int severity) |
498 | int severity) | ||
499 | { | 497 | { |
500 | pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED; | 498 | pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED; |
501 | enum pci_channel_state state; | 499 | enum pci_channel_state state; |
@@ -511,7 +509,7 @@ static void do_recovery(struct pcie_device *aerdev, struct pci_dev *dev, | |||
511 | report_error_detected); | 509 | report_error_detected); |
512 | 510 | ||
513 | if (severity == AER_FATAL) { | 511 | if (severity == AER_FATAL) { |
514 | result = reset_link(aerdev, dev); | 512 | result = reset_link(dev); |
515 | if (result != PCI_ERS_RESULT_RECOVERED) | 513 | if (result != PCI_ERS_RESULT_RECOVERED) |
516 | goto failed; | 514 | goto failed; |
517 | } | 515 | } |
@@ -576,9 +574,73 @@ static void handle_error_source(struct pcie_device *aerdev, | |||
576 | pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, | 574 | pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, |
577 | info->status); | 575 | info->status); |
578 | } else | 576 | } else |
579 | do_recovery(aerdev, dev, info->severity); | 577 | do_recovery(dev, info->severity); |
580 | } | 578 | } |
581 | 579 | ||
580 | #ifdef CONFIG_ACPI_APEI_PCIEAER | ||
581 | static void aer_recover_work_func(struct work_struct *work); | ||
582 | |||
583 | #define AER_RECOVER_RING_ORDER 4 | ||
584 | #define AER_RECOVER_RING_SIZE (1 << AER_RECOVER_RING_ORDER) | ||
585 | |||
586 | struct aer_recover_entry | ||
587 | { | ||
588 | u8 bus; | ||
589 | u8 devfn; | ||
590 | u16 domain; | ||
591 | int severity; | ||
592 | }; | ||
593 | |||
594 | static DEFINE_KFIFO(aer_recover_ring, struct aer_recover_entry, | ||
595 | AER_RECOVER_RING_SIZE); | ||
596 | /* | ||
597 | * Mutual exclusion for writers of aer_recover_ring, reader side don't | ||
598 | * need lock, because there is only one reader and lock is not needed | ||
599 | * between reader and writer. | ||
600 | */ | ||
601 | static DEFINE_SPINLOCK(aer_recover_ring_lock); | ||
602 | static DECLARE_WORK(aer_recover_work, aer_recover_work_func); | ||
603 | |||
604 | void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, | ||
605 | int severity) | ||
606 | { | ||
607 | unsigned long flags; | ||
608 | struct aer_recover_entry entry = { | ||
609 | .bus = bus, | ||
610 | .devfn = devfn, | ||
611 | .domain = domain, | ||
612 | .severity = severity, | ||
613 | }; | ||
614 | |||
615 | spin_lock_irqsave(&aer_recover_ring_lock, flags); | ||
616 | if (kfifo_put(&aer_recover_ring, &entry)) | ||
617 | schedule_work(&aer_recover_work); | ||
618 | else | ||
619 | pr_err("AER recover: Buffer overflow when recovering AER for %04x:%02x:%02x:%x\n", | ||
620 | domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); | ||
621 | spin_unlock_irqrestore(&aer_recover_ring_lock, flags); | ||
622 | } | ||
623 | EXPORT_SYMBOL_GPL(aer_recover_queue); | ||
624 | |||
625 | static void aer_recover_work_func(struct work_struct *work) | ||
626 | { | ||
627 | struct aer_recover_entry entry; | ||
628 | struct pci_dev *pdev; | ||
629 | |||
630 | while (kfifo_get(&aer_recover_ring, &entry)) { | ||
631 | pdev = pci_get_domain_bus_and_slot(entry.domain, entry.bus, | ||
632 | entry.devfn); | ||
633 | if (!pdev) { | ||
634 | pr_err("AER recover: Can not find pci_dev for %04x:%02x:%02x:%x\n", | ||
635 | entry.domain, entry.bus, | ||
636 | PCI_SLOT(entry.devfn), PCI_FUNC(entry.devfn)); | ||
637 | continue; | ||
638 | } | ||
639 | do_recovery(pdev, entry.severity); | ||
640 | } | ||
641 | } | ||
642 | #endif | ||
643 | |||
582 | /** | 644 | /** |
583 | * get_device_error_info - read error status from dev and store it to info | 645 | * get_device_error_info - read error status from dev and store it to info |
584 | * @dev: pointer to the device expected to have a error record | 646 | * @dev: pointer to the device expected to have a error record |
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index b07a42e0b350..3ea51736f18d 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c | |||
@@ -204,7 +204,7 @@ void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info) | |||
204 | } | 204 | } |
205 | 205 | ||
206 | #ifdef CONFIG_ACPI_APEI_PCIEAER | 206 | #ifdef CONFIG_ACPI_APEI_PCIEAER |
207 | static int cper_severity_to_aer(int cper_severity) | 207 | int cper_severity_to_aer(int cper_severity) |
208 | { | 208 | { |
209 | switch (cper_severity) { | 209 | switch (cper_severity) { |
210 | case CPER_SEV_RECOVERABLE: | 210 | case CPER_SEV_RECOVERABLE: |
@@ -215,6 +215,7 @@ static int cper_severity_to_aer(int cper_severity) | |||
215 | return AER_CORRECTABLE; | 215 | return AER_CORRECTABLE; |
216 | } | 216 | } |
217 | } | 217 | } |
218 | EXPORT_SYMBOL_GPL(cper_severity_to_aer); | ||
218 | 219 | ||
219 | void cper_print_aer(const char *prefix, int cper_severity, | 220 | void cper_print_aer(const char *prefix, int cper_severity, |
220 | struct aer_capability_regs *aer) | 221 | struct aer_capability_regs *aer) |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 9ab492f21f86..795c9026d55f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -68,21 +68,6 @@ static int __init pcibus_class_init(void) | |||
68 | } | 68 | } |
69 | postcore_initcall(pcibus_class_init); | 69 | postcore_initcall(pcibus_class_init); |
70 | 70 | ||
71 | /* | ||
72 | * Translate the low bits of the PCI base | ||
73 | * to the resource type | ||
74 | */ | ||
75 | static inline unsigned int pci_calc_resource_flags(unsigned int flags) | ||
76 | { | ||
77 | if (flags & PCI_BASE_ADDRESS_SPACE_IO) | ||
78 | return IORESOURCE_IO; | ||
79 | |||
80 | if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH) | ||
81 | return IORESOURCE_MEM | IORESOURCE_PREFETCH; | ||
82 | |||
83 | return IORESOURCE_MEM; | ||
84 | } | ||
85 | |||
86 | static u64 pci_size(u64 base, u64 maxbase, u64 mask) | 71 | static u64 pci_size(u64 base, u64 maxbase, u64 mask) |
87 | { | 72 | { |
88 | u64 size = mask & maxbase; /* Find the significant bits */ | 73 | u64 size = mask & maxbase; /* Find the significant bits */ |
@@ -101,18 +86,39 @@ static u64 pci_size(u64 base, u64 maxbase, u64 mask) | |||
101 | return size; | 86 | return size; |
102 | } | 87 | } |
103 | 88 | ||
104 | static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar) | 89 | static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar) |
105 | { | 90 | { |
91 | u32 mem_type; | ||
92 | unsigned long flags; | ||
93 | |||
106 | if ((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { | 94 | if ((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { |
107 | res->flags = bar & ~PCI_BASE_ADDRESS_IO_MASK; | 95 | flags = bar & ~PCI_BASE_ADDRESS_IO_MASK; |
108 | return pci_bar_io; | 96 | flags |= IORESOURCE_IO; |
97 | return flags; | ||
109 | } | 98 | } |
110 | 99 | ||
111 | res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK; | 100 | flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK; |
101 | flags |= IORESOURCE_MEM; | ||
102 | if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH) | ||
103 | flags |= IORESOURCE_PREFETCH; | ||
112 | 104 | ||
113 | if (res->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) | 105 | mem_type = bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK; |
114 | return pci_bar_mem64; | 106 | switch (mem_type) { |
115 | return pci_bar_mem32; | 107 | case PCI_BASE_ADDRESS_MEM_TYPE_32: |
108 | break; | ||
109 | case PCI_BASE_ADDRESS_MEM_TYPE_1M: | ||
110 | dev_info(&dev->dev, "1M mem BAR treated as 32-bit BAR\n"); | ||
111 | break; | ||
112 | case PCI_BASE_ADDRESS_MEM_TYPE_64: | ||
113 | flags |= IORESOURCE_MEM_64; | ||
114 | break; | ||
115 | default: | ||
116 | dev_warn(&dev->dev, | ||
117 | "mem unknown type %x treated as 32-bit BAR\n", | ||
118 | mem_type); | ||
119 | break; | ||
120 | } | ||
121 | return flags; | ||
116 | } | 122 | } |
117 | 123 | ||
118 | /** | 124 | /** |
@@ -165,9 +171,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
165 | l = 0; | 171 | l = 0; |
166 | 172 | ||
167 | if (type == pci_bar_unknown) { | 173 | if (type == pci_bar_unknown) { |
168 | type = decode_bar(res, l); | 174 | res->flags = decode_bar(dev, l); |
169 | res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN; | 175 | res->flags |= IORESOURCE_SIZEALIGN; |
170 | if (type == pci_bar_io) { | 176 | if (res->flags & IORESOURCE_IO) { |
171 | l &= PCI_BASE_ADDRESS_IO_MASK; | 177 | l &= PCI_BASE_ADDRESS_IO_MASK; |
172 | mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT; | 178 | mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT; |
173 | } else { | 179 | } else { |
@@ -180,7 +186,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
180 | mask = (u32)PCI_ROM_ADDRESS_MASK; | 186 | mask = (u32)PCI_ROM_ADDRESS_MASK; |
181 | } | 187 | } |
182 | 188 | ||
183 | if (type == pci_bar_mem64) { | 189 | if (res->flags & IORESOURCE_MEM_64) { |
184 | u64 l64 = l; | 190 | u64 l64 = l; |
185 | u64 sz64 = sz; | 191 | u64 sz64 = sz; |
186 | u64 mask64 = mask | (u64)~0 << 32; | 192 | u64 mask64 = mask | (u64)~0 << 32; |
@@ -204,7 +210,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
204 | goto fail; | 210 | goto fail; |
205 | } | 211 | } |
206 | 212 | ||
207 | res->flags |= IORESOURCE_MEM_64; | ||
208 | if ((sizeof(resource_size_t) < 8) && l) { | 213 | if ((sizeof(resource_size_t) < 8) && l) { |
209 | /* Address above 32-bit boundary; disable the BAR */ | 214 | /* Address above 32-bit boundary; disable the BAR */ |
210 | pci_write_config_dword(dev, pos, 0); | 215 | pci_write_config_dword(dev, pos, 0); |
@@ -230,7 +235,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
230 | } | 235 | } |
231 | 236 | ||
232 | out: | 237 | out: |
233 | return (type == pci_bar_mem64) ? 1 : 0; | 238 | return (res->flags & IORESOURCE_MEM_64) ? 1 : 0; |
234 | fail: | 239 | fail: |
235 | res->flags = 0; | 240 | res->flags = 0; |
236 | goto out; | 241 | goto out; |
@@ -284,10 +289,6 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child) | |||
284 | if (!res->end) | 289 | if (!res->end) |
285 | res->end = limit + 0xfff; | 290 | res->end = limit + 0xfff; |
286 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 291 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
287 | } else { | ||
288 | dev_printk(KERN_DEBUG, &dev->dev, | ||
289 | " bridge window [io %#06lx-%#06lx] (disabled)\n", | ||
290 | base, limit); | ||
291 | } | 292 | } |
292 | } | 293 | } |
293 | 294 | ||
@@ -308,10 +309,6 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child) | |||
308 | res->start = base; | 309 | res->start = base; |
309 | res->end = limit + 0xfffff; | 310 | res->end = limit + 0xfffff; |
310 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 311 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
311 | } else { | ||
312 | dev_printk(KERN_DEBUG, &dev->dev, | ||
313 | " bridge window [mem %#010lx-%#010lx] (disabled)\n", | ||
314 | base, limit + 0xfffff); | ||
315 | } | 312 | } |
316 | } | 313 | } |
317 | 314 | ||
@@ -359,10 +356,6 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child) | |||
359 | res->start = base; | 356 | res->start = base; |
360 | res->end = limit + 0xfffff; | 357 | res->end = limit + 0xfffff; |
361 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 358 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
362 | } else { | ||
363 | dev_printk(KERN_DEBUG, &dev->dev, | ||
364 | " bridge window [mem %#010lx-%#010lx pref] (disabled)\n", | ||
365 | base, limit + 0xfffff); | ||
366 | } | 359 | } |
367 | } | 360 | } |
368 | 361 | ||
@@ -725,12 +718,14 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
725 | pci_write_config_word(dev, PCI_STATUS, 0xffff); | 718 | pci_write_config_word(dev, PCI_STATUS, 0xffff); |
726 | 719 | ||
727 | /* Prevent assigning a bus number that already exists. | 720 | /* Prevent assigning a bus number that already exists. |
728 | * This can happen when a bridge is hot-plugged */ | 721 | * This can happen when a bridge is hot-plugged, so in |
729 | if (pci_find_bus(pci_domain_nr(bus), max+1)) | 722 | * this case we only re-scan this bus. */ |
730 | goto out; | 723 | child = pci_find_bus(pci_domain_nr(bus), max+1); |
731 | child = pci_add_new_bus(bus, dev, ++max); | 724 | if (!child) { |
732 | if (!child) | 725 | child = pci_add_new_bus(bus, dev, ++max); |
733 | goto out; | 726 | if (!child) |
727 | goto out; | ||
728 | } | ||
734 | buses = (buses & 0xff000000) | 729 | buses = (buses & 0xff000000) |
735 | | ((unsigned int)(child->primary) << 0) | 730 | | ((unsigned int)(child->primary) << 0) |
736 | | ((unsigned int)(child->secondary) << 8) | 731 | | ((unsigned int)(child->secondary) << 8) |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 9995842e45b5..8a1d3c7863a8 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -336,7 +336,6 @@ static void pci_setup_bridge_io(struct pci_bus *bus) | |||
336 | /* Clear upper 16 bits of I/O base/limit. */ | 336 | /* Clear upper 16 bits of I/O base/limit. */ |
337 | io_upper16 = 0; | 337 | io_upper16 = 0; |
338 | l = 0x00f0; | 338 | l = 0x00f0; |
339 | dev_info(&bridge->dev, " bridge window [io disabled]\n"); | ||
340 | } | 339 | } |
341 | /* Temporarily disable the I/O range before updating PCI_IO_BASE. */ | 340 | /* Temporarily disable the I/O range before updating PCI_IO_BASE. */ |
342 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff); | 341 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff); |
@@ -362,7 +361,6 @@ static void pci_setup_bridge_mmio(struct pci_bus *bus) | |||
362 | dev_info(&bridge->dev, " bridge window %pR\n", res); | 361 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
363 | } else { | 362 | } else { |
364 | l = 0x0000fff0; | 363 | l = 0x0000fff0; |
365 | dev_info(&bridge->dev, " bridge window [mem disabled]\n"); | ||
366 | } | 364 | } |
367 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); | 365 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); |
368 | } | 366 | } |
@@ -393,7 +391,6 @@ static void pci_setup_bridge_mmio_pref(struct pci_bus *bus) | |||
393 | dev_info(&bridge->dev, " bridge window %pR\n", res); | 391 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
394 | } else { | 392 | } else { |
395 | l = 0x0000fff0; | 393 | l = 0x0000fff0; |
396 | dev_info(&bridge->dev, " bridge window [mem pref disabled]\n"); | ||
397 | } | 394 | } |
398 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); | 395 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); |
399 | 396 | ||
diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c index eec9738f3492..eb219a1d16f7 100644 --- a/drivers/pci/setup-irq.c +++ b/drivers/pci/setup-irq.c | |||
@@ -21,7 +21,7 @@ | |||
21 | static void __init | 21 | static void __init |
22 | pdev_fixup_irq(struct pci_dev *dev, | 22 | pdev_fixup_irq(struct pci_dev *dev, |
23 | u8 (*swizzle)(struct pci_dev *, u8 *), | 23 | u8 (*swizzle)(struct pci_dev *, u8 *), |
24 | int (*map_irq)(struct pci_dev *, u8, u8)) | 24 | int (*map_irq)(const struct pci_dev *, u8, u8)) |
25 | { | 25 | { |
26 | u8 pin, slot; | 26 | u8 pin, slot; |
27 | int irq = 0; | 27 | int irq = 0; |
@@ -56,7 +56,7 @@ pdev_fixup_irq(struct pci_dev *dev, | |||
56 | 56 | ||
57 | void __init | 57 | void __init |
58 | pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *), | 58 | pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *), |
59 | int (*map_irq)(struct pci_dev *, u8, u8)) | 59 | int (*map_irq)(const struct pci_dev *, u8, u8)) |
60 | { | 60 | { |
61 | struct pci_dev *dev = NULL; | 61 | struct pci_dev *dev = NULL; |
62 | for_each_pci_dev(dev) | 62 | for_each_pci_dev(dev) |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index bc0e6eea0fff..319f359906e8 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -74,8 +74,7 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
74 | resno, new, check); | 74 | resno, new, check); |
75 | } | 75 | } |
76 | 76 | ||
77 | if ((new & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == | 77 | if (res->flags & IORESOURCE_MEM_64) { |
78 | (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) { | ||
79 | new = region.start >> 16 >> 16; | 78 | new = region.start >> 16 >> 16; |
80 | pci_write_config_dword(dev, reg + 4, new); | 79 | pci_write_config_dword(dev, reg + 4, new); |
81 | pci_read_config_dword(dev, reg + 4, &check); | 80 | pci_read_config_dword(dev, reg + 4, &check); |