diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-11 15:18:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-11 15:18:16 -0500 |
commit | 11bd04f6f35621193311c32e0721142b073a7794 (patch) | |
tree | 00979740582bb26e8d3756bf3526c85f19f66a46 /drivers/pci | |
parent | 4e2ccdb0409146f8cf64a11b6ef82a9c928ced2a (diff) | |
parent | 9e0b5b2c447ad0caa075a5cfef86def62e1782ff (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: (109 commits)
PCI: fix coding style issue in pci_save_state()
PCI: add pci_request_acs
PCI: fix BUG_ON triggered by logical PCIe root port removal
PCI: remove ifdefed pci_cleanup_aer_correct_error_status
PCI: unconditionally clear AER uncorr status register during cleanup
x86/PCI: claim SR-IOV BARs in pcibios_allocate_resource
PCI: portdrv: remove redundant definitions
PCI: portdrv: remove unnecessary struct pcie_port_data
PCI: portdrv: minor cleanup for pcie_port_device_register
PCI: portdrv: add missing irq cleanup
PCI: portdrv: enable device before irq initialization
PCI: portdrv: cleanup service irqs initialization
PCI: portdrv: check capabilities first
PCI: portdrv: move PME capability check
PCI: portdrv: remove redundant pcie type calculation
PCI: portdrv: cleanup pcie_device registration
PCI: portdrv: remove redundant pcie_port_device_probe
PCI: Always set prefetchable base/limit upper32 registers
PCI: read-modify-write the pcie device control register when initiating pcie flr
PCI: show dma_mask bits in /sys
...
Fixed up conflicts in:
arch/x86/kernel/amd_iommu_init.c
drivers/pci/dmar.c
drivers/pci/hotplug/acpiphp_glue.c
Diffstat (limited to 'drivers/pci')
37 files changed, 818 insertions, 968 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index fdc864f9cf23..b1ecefa2a23d 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -27,10 +27,10 @@ config PCI_LEGACY | |||
27 | default y | 27 | default y |
28 | help | 28 | help |
29 | Say Y here if you want to include support for the deprecated | 29 | Say Y here if you want to include support for the deprecated |
30 | pci_find_slot() and pci_find_device() APIs. Most drivers have | 30 | pci_find_device() API. Most drivers have been converted over |
31 | been converted over to using the proper hotplug APIs, so this | 31 | to using the proper hotplug APIs, so this option serves to |
32 | option serves to include/exclude only a few drivers that are | 32 | include/exclude only a few drivers that are still using this |
33 | still using this API. | 33 | API. |
34 | 34 | ||
35 | config PCI_DEBUG | 35 | config PCI_DEBUG |
36 | bool "PCI Debugging" | 36 | bool "PCI Debugging" |
@@ -69,3 +69,10 @@ config PCI_IOV | |||
69 | physical resources. | 69 | physical resources. |
70 | 70 | ||
71 | If unsure, say N. | 71 | If unsure, say N. |
72 | |||
73 | config PCI_IOAPIC | ||
74 | bool | ||
75 | depends on PCI | ||
76 | depends on ACPI | ||
77 | depends on HOTPLUG | ||
78 | default y | ||
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 4a7f11d8f432..4df48d58eaa6 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -14,6 +14,8 @@ CFLAGS_legacy.o += -Wno-deprecated-declarations | |||
14 | # Build PCI Express stuff if needed | 14 | # Build PCI Express stuff if needed |
15 | obj-$(CONFIG_PCIEPORTBUS) += pcie/ | 15 | obj-$(CONFIG_PCIEPORTBUS) += pcie/ |
16 | 16 | ||
17 | obj-$(CONFIG_PCI_IOAPIC) += ioapic.o | ||
18 | |||
17 | obj-$(CONFIG_HOTPLUG) += hotplug.o | 19 | obj-$(CONFIG_HOTPLUG) += hotplug.o |
18 | 20 | ||
19 | # Build the PCI Hotplug drivers if we were asked to | 21 | # Build the PCI Hotplug drivers if we were asked to |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 416f6ac65b76..6cdc931f7c17 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -320,7 +320,7 @@ found: | |||
320 | for (bus = dev->bus; bus; bus = bus->parent) { | 320 | for (bus = dev->bus; bus; bus = bus->parent) { |
321 | struct pci_dev *bridge = bus->self; | 321 | struct pci_dev *bridge = bus->self; |
322 | 322 | ||
323 | if (!bridge || !bridge->is_pcie || | 323 | if (!bridge || !pci_is_pcie(bridge) || |
324 | bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) | 324 | bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) |
325 | return 0; | 325 | return 0; |
326 | 326 | ||
@@ -645,8 +645,11 @@ void __init detect_intel_iommu(void) | |||
645 | "x2apic and Intr-remapping.\n"); | 645 | "x2apic and Intr-remapping.\n"); |
646 | #endif | 646 | #endif |
647 | #ifdef CONFIG_DMAR | 647 | #ifdef CONFIG_DMAR |
648 | if (ret && !no_iommu && !iommu_detected && !dmar_disabled) | 648 | if (ret && !no_iommu && !iommu_detected && !dmar_disabled) { |
649 | iommu_detected = 1; | 649 | iommu_detected = 1; |
650 | /* Make sure ACS will be enabled */ | ||
651 | pci_request_acs(); | ||
652 | } | ||
650 | #endif | 653 | #endif |
651 | #ifdef CONFIG_X86 | 654 | #ifdef CONFIG_X86 |
652 | if (ret) | 655 | if (ret) |
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 3625b094bf7e..6cd9f3c9887d 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile | |||
@@ -6,18 +6,22 @@ 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 | 8 | ||
9 | # pciehp should be linked before acpiphp in order to allow the native driver | 9 | # native drivers should be linked before acpiphp in order to allow the |
10 | # to attempt to bind first. We can then fall back to generic support. | 10 | # native driver to attempt to bind first. We can then fall back to |
11 | # generic support. | ||
11 | 12 | ||
12 | obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o | 13 | obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o |
13 | obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o | ||
14 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o | ||
15 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o | 14 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o |
16 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o | 15 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o |
17 | obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o | 16 | obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o |
18 | obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o | 17 | obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o |
19 | obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o | 18 | obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o |
20 | obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o | 19 | obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o |
20 | obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o | ||
21 | |||
22 | # acpiphp_ibm extends acpiphp, so should be linked afterwards. | ||
23 | |||
24 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o | ||
21 | 25 | ||
22 | # Link this last so it doesn't claim devices that have a real hotplug driver | 26 | # Link this last so it doesn't claim devices that have a real hotplug driver |
23 | obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o | 27 | obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o |
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 0f32571b94df..3c76fc67cf0e 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -362,6 +362,8 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
362 | status = acpi_pci_osc_control_set(handle, flags); | 362 | status = acpi_pci_osc_control_set(handle, flags); |
363 | if (ACPI_SUCCESS(status)) | 363 | if (ACPI_SUCCESS(status)) |
364 | goto got_one; | 364 | goto got_one; |
365 | if (status == AE_SUPPORT) | ||
366 | goto no_control; | ||
365 | kfree(string.pointer); | 367 | kfree(string.pointer); |
366 | string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL }; | 368 | string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL }; |
367 | } | 369 | } |
@@ -394,10 +396,9 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
394 | if (ACPI_FAILURE(status)) | 396 | if (ACPI_FAILURE(status)) |
395 | break; | 397 | break; |
396 | } | 398 | } |
397 | 399 | no_control: | |
398 | dbg("Cannot get control of hotplug hardware for pci %s\n", | 400 | dbg("Cannot get control of hotplug hardware for pci %s\n", |
399 | pci_name(pdev)); | 401 | pci_name(pdev)); |
400 | |||
401 | kfree(string.pointer); | 402 | kfree(string.pointer); |
402 | return -ENODEV; | 403 | return -ENODEV; |
403 | got_one: | 404 | got_one: |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 7d938df79206..bab52047baa8 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -146,12 +146,6 @@ struct acpiphp_attention_info | |||
146 | struct module *owner; | 146 | struct module *owner; |
147 | }; | 147 | }; |
148 | 148 | ||
149 | struct acpiphp_ioapic { | ||
150 | struct pci_dev *dev; | ||
151 | u32 gsi_base; | ||
152 | struct list_head list; | ||
153 | }; | ||
154 | |||
155 | /* PCI bus bridge HID */ | 149 | /* PCI bus bridge HID */ |
156 | #define ACPI_PCI_HOST_HID "PNP0A03" | 150 | #define ACPI_PCI_HOST_HID "PNP0A03" |
157 | 151 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index df1b0ea089d1..8e952fdab764 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -52,8 +52,6 @@ | |||
52 | #include "acpiphp.h" | 52 | #include "acpiphp.h" |
53 | 53 | ||
54 | static LIST_HEAD(bridge_list); | 54 | static LIST_HEAD(bridge_list); |
55 | static LIST_HEAD(ioapic_list); | ||
56 | static DEFINE_SPINLOCK(ioapic_list_lock); | ||
57 | 55 | ||
58 | #define MY_NAME "acpiphp_glue" | 56 | #define MY_NAME "acpiphp_glue" |
59 | 57 | ||
@@ -311,17 +309,13 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) | |||
311 | /* find acpiphp_func from acpiphp_bridge */ | 309 | /* find acpiphp_func from acpiphp_bridge */ |
312 | static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle) | 310 | static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle) |
313 | { | 311 | { |
314 | struct list_head *node, *l; | ||
315 | struct acpiphp_bridge *bridge; | 312 | struct acpiphp_bridge *bridge; |
316 | struct acpiphp_slot *slot; | 313 | struct acpiphp_slot *slot; |
317 | struct acpiphp_func *func; | 314 | struct acpiphp_func *func; |
318 | 315 | ||
319 | list_for_each(node, &bridge_list) { | 316 | list_for_each_entry(bridge, &bridge_list, list) { |
320 | bridge = list_entry(node, struct acpiphp_bridge, list); | ||
321 | for (slot = bridge->slots; slot; slot = slot->next) { | 317 | for (slot = bridge->slots; slot; slot = slot->next) { |
322 | list_for_each(l, &slot->funcs) { | 318 | list_for_each_entry(func, &slot->funcs, sibling) { |
323 | func = list_entry(l, struct acpiphp_func, | ||
324 | sibling); | ||
325 | if (func->handle == handle) | 319 | if (func->handle == handle) |
326 | return func; | 320 | return func; |
327 | } | 321 | } |
@@ -495,21 +489,19 @@ static int add_bridge(acpi_handle handle) | |||
495 | 489 | ||
496 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) | 490 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) |
497 | { | 491 | { |
498 | struct list_head *head; | 492 | struct acpiphp_bridge *bridge; |
499 | list_for_each(head, &bridge_list) { | 493 | |
500 | struct acpiphp_bridge *bridge = list_entry(head, | 494 | list_for_each_entry(bridge, &bridge_list, list) |
501 | struct acpiphp_bridge, list); | ||
502 | if (bridge->handle == handle) | 495 | if (bridge->handle == handle) |
503 | return bridge; | 496 | return bridge; |
504 | } | ||
505 | 497 | ||
506 | return NULL; | 498 | return NULL; |
507 | } | 499 | } |
508 | 500 | ||
509 | static void cleanup_bridge(struct acpiphp_bridge *bridge) | 501 | static void cleanup_bridge(struct acpiphp_bridge *bridge) |
510 | { | 502 | { |
511 | struct list_head *list, *tmp; | 503 | struct acpiphp_slot *slot, *next; |
512 | struct acpiphp_slot *slot; | 504 | struct acpiphp_func *func, *tmp; |
513 | acpi_status status; | 505 | acpi_status status; |
514 | acpi_handle handle = bridge->handle; | 506 | acpi_handle handle = bridge->handle; |
515 | 507 | ||
@@ -530,10 +522,8 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
530 | 522 | ||
531 | slot = bridge->slots; | 523 | slot = bridge->slots; |
532 | while (slot) { | 524 | while (slot) { |
533 | struct acpiphp_slot *next = slot->next; | 525 | next = slot->next; |
534 | list_for_each_safe (list, tmp, &slot->funcs) { | 526 | list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { |
535 | struct acpiphp_func *func; | ||
536 | func = list_entry(list, struct acpiphp_func, sibling); | ||
537 | if (is_dock_device(func->handle)) { | 527 | if (is_dock_device(func->handle)) { |
538 | unregister_hotplug_dock_device(func->handle); | 528 | unregister_hotplug_dock_device(func->handle); |
539 | unregister_dock_notifier(&func->nb); | 529 | unregister_dock_notifier(&func->nb); |
@@ -545,7 +535,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
545 | if (ACPI_FAILURE(status)) | 535 | if (ACPI_FAILURE(status)) |
546 | err("failed to remove notify handler\n"); | 536 | err("failed to remove notify handler\n"); |
547 | } | 537 | } |
548 | list_del(list); | 538 | list_del(&func->sibling); |
549 | kfree(func); | 539 | kfree(func); |
550 | } | 540 | } |
551 | acpiphp_unregister_hotplug_slot(slot); | 541 | acpiphp_unregister_hotplug_slot(slot); |
@@ -606,204 +596,17 @@ static void remove_bridge(acpi_handle handle) | |||
606 | handle_hotplug_event_bridge); | 596 | handle_hotplug_event_bridge); |
607 | } | 597 | } |
608 | 598 | ||
609 | static struct pci_dev * get_apic_pci_info(acpi_handle handle) | ||
610 | { | ||
611 | struct pci_dev *dev; | ||
612 | |||
613 | dev = acpi_get_pci_dev(handle); | ||
614 | if (!dev) | ||
615 | return NULL; | ||
616 | |||
617 | if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) && | ||
618 | (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC)) | ||
619 | { | ||
620 | pci_dev_put(dev); | ||
621 | return NULL; | ||
622 | } | ||
623 | |||
624 | return dev; | ||
625 | } | ||
626 | |||
627 | static int get_gsi_base(acpi_handle handle, u32 *gsi_base) | ||
628 | { | ||
629 | acpi_status status; | ||
630 | int result = -1; | ||
631 | unsigned long long gsb; | ||
632 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
633 | union acpi_object *obj; | ||
634 | void *table; | ||
635 | |||
636 | status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb); | ||
637 | if (ACPI_SUCCESS(status)) { | ||
638 | *gsi_base = (u32)gsb; | ||
639 | return 0; | ||
640 | } | ||
641 | |||
642 | status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer); | ||
643 | if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer) | ||
644 | return -1; | ||
645 | |||
646 | obj = buffer.pointer; | ||
647 | if (obj->type != ACPI_TYPE_BUFFER) | ||
648 | goto out; | ||
649 | |||
650 | table = obj->buffer.pointer; | ||
651 | switch (((struct acpi_subtable_header *)table)->type) { | ||
652 | case ACPI_MADT_TYPE_IO_SAPIC: | ||
653 | *gsi_base = ((struct acpi_madt_io_sapic *)table)->global_irq_base; | ||
654 | result = 0; | ||
655 | break; | ||
656 | case ACPI_MADT_TYPE_IO_APIC: | ||
657 | *gsi_base = ((struct acpi_madt_io_apic *)table)->global_irq_base; | ||
658 | result = 0; | ||
659 | break; | ||
660 | default: | ||
661 | break; | ||
662 | } | ||
663 | out: | ||
664 | kfree(buffer.pointer); | ||
665 | return result; | ||
666 | } | ||
667 | |||
668 | static acpi_status | ||
669 | ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
670 | { | ||
671 | acpi_status status; | ||
672 | unsigned long long sta; | ||
673 | acpi_handle tmp; | ||
674 | struct pci_dev *pdev; | ||
675 | u32 gsi_base; | ||
676 | u64 phys_addr; | ||
677 | struct acpiphp_ioapic *ioapic; | ||
678 | |||
679 | /* Evaluate _STA if present */ | ||
680 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
681 | if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL) | ||
682 | return AE_CTRL_DEPTH; | ||
683 | |||
684 | /* Scan only PCI bus scope */ | ||
685 | status = acpi_get_handle(handle, "_HID", &tmp); | ||
686 | if (ACPI_SUCCESS(status)) | ||
687 | return AE_CTRL_DEPTH; | ||
688 | |||
689 | if (get_gsi_base(handle, &gsi_base)) | ||
690 | return AE_OK; | ||
691 | |||
692 | ioapic = kmalloc(sizeof(*ioapic), GFP_KERNEL); | ||
693 | if (!ioapic) | ||
694 | return AE_NO_MEMORY; | ||
695 | |||
696 | pdev = get_apic_pci_info(handle); | ||
697 | if (!pdev) | ||
698 | goto exit_kfree; | ||
699 | |||
700 | if (pci_enable_device(pdev)) | ||
701 | goto exit_pci_dev_put; | ||
702 | |||
703 | pci_set_master(pdev); | ||
704 | |||
705 | if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) | ||
706 | goto exit_pci_disable_device; | ||
707 | |||
708 | phys_addr = pci_resource_start(pdev, 0); | ||
709 | if (acpi_register_ioapic(handle, phys_addr, gsi_base)) | ||
710 | goto exit_pci_release_region; | ||
711 | |||
712 | ioapic->gsi_base = gsi_base; | ||
713 | ioapic->dev = pdev; | ||
714 | spin_lock(&ioapic_list_lock); | ||
715 | list_add_tail(&ioapic->list, &ioapic_list); | ||
716 | spin_unlock(&ioapic_list_lock); | ||
717 | |||
718 | return AE_OK; | ||
719 | |||
720 | exit_pci_release_region: | ||
721 | pci_release_region(pdev, 0); | ||
722 | exit_pci_disable_device: | ||
723 | pci_disable_device(pdev); | ||
724 | exit_pci_dev_put: | ||
725 | pci_dev_put(pdev); | ||
726 | exit_kfree: | ||
727 | kfree(ioapic); | ||
728 | |||
729 | return AE_OK; | ||
730 | } | ||
731 | |||
732 | static acpi_status | ||
733 | ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
734 | { | ||
735 | acpi_status status; | ||
736 | unsigned long long sta; | ||
737 | acpi_handle tmp; | ||
738 | u32 gsi_base; | ||
739 | struct acpiphp_ioapic *pos, *n, *ioapic = NULL; | ||
740 | |||
741 | /* Evaluate _STA if present */ | ||
742 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
743 | if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL) | ||
744 | return AE_CTRL_DEPTH; | ||
745 | |||
746 | /* Scan only PCI bus scope */ | ||
747 | status = acpi_get_handle(handle, "_HID", &tmp); | ||
748 | if (ACPI_SUCCESS(status)) | ||
749 | return AE_CTRL_DEPTH; | ||
750 | |||
751 | if (get_gsi_base(handle, &gsi_base)) | ||
752 | return AE_OK; | ||
753 | |||
754 | acpi_unregister_ioapic(handle, gsi_base); | ||
755 | |||
756 | spin_lock(&ioapic_list_lock); | ||
757 | list_for_each_entry_safe(pos, n, &ioapic_list, list) { | ||
758 | if (pos->gsi_base != gsi_base) | ||
759 | continue; | ||
760 | ioapic = pos; | ||
761 | list_del(&ioapic->list); | ||
762 | break; | ||
763 | } | ||
764 | spin_unlock(&ioapic_list_lock); | ||
765 | |||
766 | if (!ioapic) | ||
767 | return AE_OK; | ||
768 | |||
769 | pci_release_region(ioapic->dev, 0); | ||
770 | pci_disable_device(ioapic->dev); | ||
771 | pci_dev_put(ioapic->dev); | ||
772 | kfree(ioapic); | ||
773 | |||
774 | return AE_OK; | ||
775 | } | ||
776 | |||
777 | static int acpiphp_configure_ioapics(acpi_handle handle) | ||
778 | { | ||
779 | ioapic_add(handle, 0, NULL, NULL); | ||
780 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
781 | ACPI_UINT32_MAX, ioapic_add, NULL, NULL, NULL); | ||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | static int acpiphp_unconfigure_ioapics(acpi_handle handle) | ||
786 | { | ||
787 | ioapic_remove(handle, 0, NULL, NULL); | ||
788 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
789 | ACPI_UINT32_MAX, ioapic_remove, NULL, NULL, NULL); | ||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | static int power_on_slot(struct acpiphp_slot *slot) | 599 | static int power_on_slot(struct acpiphp_slot *slot) |
794 | { | 600 | { |
795 | acpi_status status; | 601 | acpi_status status; |
796 | struct acpiphp_func *func; | 602 | struct acpiphp_func *func; |
797 | struct list_head *l; | ||
798 | int retval = 0; | 603 | int retval = 0; |
799 | 604 | ||
800 | /* if already enabled, just skip */ | 605 | /* if already enabled, just skip */ |
801 | if (slot->flags & SLOT_POWEREDON) | 606 | if (slot->flags & SLOT_POWEREDON) |
802 | goto err_exit; | 607 | goto err_exit; |
803 | 608 | ||
804 | list_for_each (l, &slot->funcs) { | 609 | list_for_each_entry(func, &slot->funcs, sibling) { |
805 | func = list_entry(l, struct acpiphp_func, sibling); | ||
806 | |||
807 | if (func->flags & FUNC_HAS_PS0) { | 610 | if (func->flags & FUNC_HAS_PS0) { |
808 | dbg("%s: executing _PS0\n", __func__); | 611 | dbg("%s: executing _PS0\n", __func__); |
809 | status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL); | 612 | status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL); |
@@ -829,7 +632,6 @@ static int power_off_slot(struct acpiphp_slot *slot) | |||
829 | { | 632 | { |
830 | acpi_status status; | 633 | acpi_status status; |
831 | struct acpiphp_func *func; | 634 | struct acpiphp_func *func; |
832 | struct list_head *l; | ||
833 | 635 | ||
834 | int retval = 0; | 636 | int retval = 0; |
835 | 637 | ||
@@ -837,9 +639,7 @@ static int power_off_slot(struct acpiphp_slot *slot) | |||
837 | if ((slot->flags & SLOT_POWEREDON) == 0) | 639 | if ((slot->flags & SLOT_POWEREDON) == 0) |
838 | goto err_exit; | 640 | goto err_exit; |
839 | 641 | ||
840 | list_for_each (l, &slot->funcs) { | 642 | list_for_each_entry(func, &slot->funcs, sibling) { |
841 | func = list_entry(l, struct acpiphp_func, sibling); | ||
842 | |||
843 | if (func->flags & FUNC_HAS_PS3) { | 643 | if (func->flags & FUNC_HAS_PS3) { |
844 | status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); | 644 | status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); |
845 | if (ACPI_FAILURE(status)) { | 645 | if (ACPI_FAILURE(status)) { |
@@ -966,7 +766,6 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
966 | { | 766 | { |
967 | struct pci_dev *dev; | 767 | struct pci_dev *dev; |
968 | struct pci_bus *bus = slot->bridge->pci_bus; | 768 | struct pci_bus *bus = slot->bridge->pci_bus; |
969 | struct list_head *l; | ||
970 | struct acpiphp_func *func; | 769 | struct acpiphp_func *func; |
971 | int retval = 0; | 770 | int retval = 0; |
972 | int num, max, pass; | 771 | int num, max, pass; |
@@ -1006,21 +805,16 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
1006 | } | 805 | } |
1007 | } | 806 | } |
1008 | 807 | ||
1009 | list_for_each (l, &slot->funcs) { | 808 | list_for_each_entry(func, &slot->funcs, sibling) |
1010 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1011 | acpiphp_bus_add(func); | 809 | acpiphp_bus_add(func); |
1012 | } | ||
1013 | 810 | ||
1014 | pci_bus_assign_resources(bus); | 811 | pci_bus_assign_resources(bus); |
1015 | acpiphp_sanitize_bus(bus); | 812 | acpiphp_sanitize_bus(bus); |
1016 | acpiphp_set_hpp_values(bus); | 813 | acpiphp_set_hpp_values(bus); |
1017 | list_for_each_entry(func, &slot->funcs, sibling) | ||
1018 | acpiphp_configure_ioapics(func->handle); | ||
1019 | pci_enable_bridges(bus); | 814 | pci_enable_bridges(bus); |
1020 | pci_bus_add_devices(bus); | 815 | pci_bus_add_devices(bus); |
1021 | 816 | ||
1022 | list_for_each (l, &slot->funcs) { | 817 | list_for_each_entry(func, &slot->funcs, sibling) { |
1023 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1024 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, | 818 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, |
1025 | func->function)); | 819 | func->function)); |
1026 | if (!dev) | 820 | if (!dev) |
@@ -1091,7 +885,6 @@ static int disable_device(struct acpiphp_slot *slot) | |||
1091 | } | 885 | } |
1092 | 886 | ||
1093 | list_for_each_entry(func, &slot->funcs, sibling) { | 887 | list_for_each_entry(func, &slot->funcs, sibling) { |
1094 | acpiphp_unconfigure_ioapics(func->handle); | ||
1095 | acpiphp_bus_trim(func->handle); | 888 | acpiphp_bus_trim(func->handle); |
1096 | } | 889 | } |
1097 | 890 | ||
@@ -1119,12 +912,9 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) | |||
1119 | acpi_status status; | 912 | acpi_status status; |
1120 | unsigned long long sta = 0; | 913 | unsigned long long sta = 0; |
1121 | u32 dvid; | 914 | u32 dvid; |
1122 | struct list_head *l; | ||
1123 | struct acpiphp_func *func; | 915 | struct acpiphp_func *func; |
1124 | 916 | ||
1125 | list_for_each (l, &slot->funcs) { | 917 | list_for_each_entry(func, &slot->funcs, sibling) { |
1126 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1127 | |||
1128 | if (func->flags & FUNC_HAS_STA) { | 918 | if (func->flags & FUNC_HAS_STA) { |
1129 | status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta); | 919 | status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta); |
1130 | if (ACPI_SUCCESS(status) && sta) | 920 | if (ACPI_SUCCESS(status) && sta) |
@@ -1152,13 +942,10 @@ int acpiphp_eject_slot(struct acpiphp_slot *slot) | |||
1152 | { | 942 | { |
1153 | acpi_status status; | 943 | acpi_status status; |
1154 | struct acpiphp_func *func; | 944 | struct acpiphp_func *func; |
1155 | struct list_head *l; | ||
1156 | struct acpi_object_list arg_list; | 945 | struct acpi_object_list arg_list; |
1157 | union acpi_object arg; | 946 | union acpi_object arg; |
1158 | 947 | ||
1159 | list_for_each (l, &slot->funcs) { | 948 | list_for_each_entry(func, &slot->funcs, sibling) { |
1160 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1161 | |||
1162 | /* We don't want to call _EJ0 on non-existing functions. */ | 949 | /* We don't want to call _EJ0 on non-existing functions. */ |
1163 | if ((func->flags & FUNC_HAS_EJ0)) { | 950 | if ((func->flags & FUNC_HAS_EJ0)) { |
1164 | /* _EJ0 method take one argument */ | 951 | /* _EJ0 method take one argument */ |
@@ -1275,7 +1062,6 @@ static int acpiphp_configure_bridge (acpi_handle handle) | |||
1275 | acpiphp_sanitize_bus(bus); | 1062 | acpiphp_sanitize_bus(bus); |
1276 | acpiphp_set_hpp_values(bus); | 1063 | acpiphp_set_hpp_values(bus); |
1277 | pci_enable_bridges(bus); | 1064 | pci_enable_bridges(bus); |
1278 | acpiphp_configure_ioapics(handle); | ||
1279 | return 0; | 1065 | return 0; |
1280 | } | 1066 | } |
1281 | 1067 | ||
@@ -1542,7 +1328,7 @@ int __init acpiphp_get_num_slots(void) | |||
1542 | struct acpiphp_bridge *bridge; | 1328 | struct acpiphp_bridge *bridge; |
1543 | int num_slots = 0; | 1329 | int num_slots = 0; |
1544 | 1330 | ||
1545 | list_for_each_entry (bridge, &bridge_list, list) { | 1331 | list_for_each_entry(bridge, &bridge_list, list) { |
1546 | dbg("Bus %04x:%02x has %d slot%s\n", | 1332 | dbg("Bus %04x:%02x has %d slot%s\n", |
1547 | pci_domain_nr(bridge->pci_bus), | 1333 | pci_domain_nr(bridge->pci_bus), |
1548 | bridge->pci_bus->number, bridge->nr_slots, | 1334 | bridge->pci_bus->number, bridge->nr_slots, |
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index 83f337c891a9..c7084f0eca5a 100644 --- a/drivers/pci/hotplug/ibmphp_hpc.c +++ b/drivers/pci/hotplug/ibmphp_hpc.c | |||
@@ -890,7 +890,7 @@ static int poll_hpc(void *data) | |||
890 | msleep(POLL_INTERVAL_SEC * 1000); | 890 | msleep(POLL_INTERVAL_SEC * 1000); |
891 | 891 | ||
892 | if (kthread_should_stop()) | 892 | if (kthread_should_stop()) |
893 | break; | 893 | goto out_sleep; |
894 | 894 | ||
895 | down (&semOperations); | 895 | down (&semOperations); |
896 | 896 | ||
@@ -904,6 +904,7 @@ static int poll_hpc(void *data) | |||
904 | /* give up the hardware semaphore */ | 904 | /* give up the hardware semaphore */ |
905 | up (&semOperations); | 905 | up (&semOperations); |
906 | /* sleep for a short time just for good measure */ | 906 | /* sleep for a short time just for good measure */ |
907 | out_sleep: | ||
907 | msleep(100); | 908 | msleep(100); |
908 | } | 909 | } |
909 | up (&sem_exit); | 910 | up (&sem_exit); |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 0325d989bb46..38183a534b65 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -68,26 +68,26 @@ static DEFINE_MUTEX(pci_hp_mutex); | |||
68 | static char *pci_bus_speed_strings[] = { | 68 | static char *pci_bus_speed_strings[] = { |
69 | "33 MHz PCI", /* 0x00 */ | 69 | "33 MHz PCI", /* 0x00 */ |
70 | "66 MHz PCI", /* 0x01 */ | 70 | "66 MHz PCI", /* 0x01 */ |
71 | "66 MHz PCIX", /* 0x02 */ | 71 | "66 MHz PCI-X", /* 0x02 */ |
72 | "100 MHz PCIX", /* 0x03 */ | 72 | "100 MHz PCI-X", /* 0x03 */ |
73 | "133 MHz PCIX", /* 0x04 */ | 73 | "133 MHz PCI-X", /* 0x04 */ |
74 | NULL, /* 0x05 */ | 74 | NULL, /* 0x05 */ |
75 | NULL, /* 0x06 */ | 75 | NULL, /* 0x06 */ |
76 | NULL, /* 0x07 */ | 76 | NULL, /* 0x07 */ |
77 | NULL, /* 0x08 */ | 77 | NULL, /* 0x08 */ |
78 | "66 MHz PCIX 266", /* 0x09 */ | 78 | "66 MHz PCI-X 266", /* 0x09 */ |
79 | "100 MHz PCIX 266", /* 0x0a */ | 79 | "100 MHz PCI-X 266", /* 0x0a */ |
80 | "133 MHz PCIX 266", /* 0x0b */ | 80 | "133 MHz PCI-X 266", /* 0x0b */ |
81 | NULL, /* 0x0c */ | 81 | NULL, /* 0x0c */ |
82 | NULL, /* 0x0d */ | 82 | NULL, /* 0x0d */ |
83 | NULL, /* 0x0e */ | 83 | NULL, /* 0x0e */ |
84 | NULL, /* 0x0f */ | 84 | NULL, /* 0x0f */ |
85 | NULL, /* 0x10 */ | 85 | NULL, /* 0x10 */ |
86 | "66 MHz PCIX 533", /* 0x11 */ | 86 | "66 MHz PCI-X 533", /* 0x11 */ |
87 | "100 MHz PCIX 533", /* 0x12 */ | 87 | "100 MHz PCI-X 533", /* 0x12 */ |
88 | "133 MHz PCIX 533", /* 0x13 */ | 88 | "133 MHz PCI-X 533", /* 0x13 */ |
89 | "2.5 GT/s PCI-E", /* 0x14 */ | 89 | "2.5 GT/s PCIe", /* 0x14 */ |
90 | "5.0 GT/s PCI-E", /* 0x15 */ | 90 | "5.0 GT/s PCIe", /* 0x15 */ |
91 | }; | 91 | }; |
92 | 92 | ||
93 | #ifdef CONFIG_HOTPLUG_PCI_CPCI | 93 | #ifdef CONFIG_HOTPLUG_PCI_CPCI |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 3070f77eb56a..4ed76b47b6dc 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -91,7 +91,6 @@ struct controller { | |||
91 | struct slot *slot; | 91 | struct slot *slot; |
92 | wait_queue_head_t queue; /* sleep & wake process */ | 92 | wait_queue_head_t queue; /* sleep & wake process */ |
93 | u32 slot_cap; | 93 | u32 slot_cap; |
94 | u8 cap_base; | ||
95 | struct timer_list poll_timer; | 94 | struct timer_list poll_timer; |
96 | unsigned int cmd_busy:1; | 95 | unsigned int cmd_busy:1; |
97 | unsigned int no_cmd_complete:1; | 96 | unsigned int no_cmd_complete:1; |
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 37c8d3d0323e..b09b083011d6 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -87,7 +87,8 @@ static int __init dummy_probe(struct pcie_device *dev) | |||
87 | /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ | 87 | /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ |
88 | if (pciehp_get_hp_hw_control_from_firmware(pdev)) | 88 | if (pciehp_get_hp_hw_control_from_firmware(pdev)) |
89 | return -ENODEV; | 89 | return -ENODEV; |
90 | if (!(pos = pci_find_capability(pdev, PCI_CAP_ID_EXP))) | 90 | pos = pci_pcie_cap(pdev); |
91 | if (!pos) | ||
91 | return -ENODEV; | 92 | return -ENODEV; |
92 | pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap); | 93 | pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap); |
93 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); | 94 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index bc234719b1df..5674b2075bdc 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -72,18 +72,6 @@ static int get_adapter_status (struct hotplug_slot *slot, u8 *value); | |||
72 | static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | 72 | static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); |
73 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | 73 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); |
74 | 74 | ||
75 | static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { | ||
76 | .set_attention_status = set_attention_status, | ||
77 | .enable_slot = enable_slot, | ||
78 | .disable_slot = disable_slot, | ||
79 | .get_power_status = get_power_status, | ||
80 | .get_attention_status = get_attention_status, | ||
81 | .get_latch_status = get_latch_status, | ||
82 | .get_adapter_status = get_adapter_status, | ||
83 | .get_max_bus_speed = get_max_bus_speed, | ||
84 | .get_cur_bus_speed = get_cur_bus_speed, | ||
85 | }; | ||
86 | |||
87 | /** | 75 | /** |
88 | * release_slot - free up the memory used by a slot | 76 | * release_slot - free up the memory used by a slot |
89 | * @hotplug_slot: slot to free | 77 | * @hotplug_slot: slot to free |
@@ -95,6 +83,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot) | |||
95 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 83 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
96 | __func__, hotplug_slot_name(hotplug_slot)); | 84 | __func__, hotplug_slot_name(hotplug_slot)); |
97 | 85 | ||
86 | kfree(hotplug_slot->ops); | ||
98 | kfree(hotplug_slot->info); | 87 | kfree(hotplug_slot->info); |
99 | kfree(hotplug_slot); | 88 | kfree(hotplug_slot); |
100 | } | 89 | } |
@@ -104,6 +93,7 @@ static int init_slot(struct controller *ctrl) | |||
104 | struct slot *slot = ctrl->slot; | 93 | struct slot *slot = ctrl->slot; |
105 | struct hotplug_slot *hotplug = NULL; | 94 | struct hotplug_slot *hotplug = NULL; |
106 | struct hotplug_slot_info *info = NULL; | 95 | struct hotplug_slot_info *info = NULL; |
96 | struct hotplug_slot_ops *ops = NULL; | ||
107 | char name[SLOT_NAME_SIZE]; | 97 | char name[SLOT_NAME_SIZE]; |
108 | int retval = -ENOMEM; | 98 | int retval = -ENOMEM; |
109 | 99 | ||
@@ -115,11 +105,28 @@ static int init_slot(struct controller *ctrl) | |||
115 | if (!info) | 105 | if (!info) |
116 | goto out; | 106 | goto out; |
117 | 107 | ||
108 | /* Setup hotplug slot ops */ | ||
109 | ops = kzalloc(sizeof(*ops), GFP_KERNEL); | ||
110 | if (!ops) | ||
111 | goto out; | ||
112 | ops->enable_slot = enable_slot; | ||
113 | ops->disable_slot = disable_slot; | ||
114 | ops->get_power_status = get_power_status; | ||
115 | ops->get_adapter_status = get_adapter_status; | ||
116 | ops->get_max_bus_speed = get_max_bus_speed; | ||
117 | ops->get_cur_bus_speed = get_cur_bus_speed; | ||
118 | if (MRL_SENS(ctrl)) | ||
119 | ops->get_latch_status = get_latch_status; | ||
120 | if (ATTN_LED(ctrl)) { | ||
121 | ops->get_attention_status = get_attention_status; | ||
122 | ops->set_attention_status = set_attention_status; | ||
123 | } | ||
124 | |||
118 | /* register this slot with the hotplug pci core */ | 125 | /* register this slot with the hotplug pci core */ |
119 | hotplug->info = info; | 126 | hotplug->info = info; |
120 | hotplug->private = slot; | 127 | hotplug->private = slot; |
121 | hotplug->release = &release_slot; | 128 | hotplug->release = &release_slot; |
122 | hotplug->ops = &pciehp_hotplug_slot_ops; | 129 | hotplug->ops = ops; |
123 | slot->hotplug_slot = hotplug; | 130 | slot->hotplug_slot = hotplug; |
124 | snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); | 131 | snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); |
125 | 132 | ||
@@ -128,17 +135,12 @@ static int init_slot(struct controller *ctrl) | |||
128 | ctrl->pcie->port->subordinate->number, PSN(ctrl)); | 135 | ctrl->pcie->port->subordinate->number, PSN(ctrl)); |
129 | retval = pci_hp_register(hotplug, | 136 | retval = pci_hp_register(hotplug, |
130 | ctrl->pcie->port->subordinate, 0, name); | 137 | ctrl->pcie->port->subordinate, 0, name); |
131 | if (retval) { | 138 | if (retval) |
132 | ctrl_err(ctrl, | 139 | ctrl_err(ctrl, |
133 | "pci_hp_register failed with error %d\n", retval); | 140 | "pci_hp_register failed with error %d\n", retval); |
134 | goto out; | ||
135 | } | ||
136 | get_power_status(hotplug, &info->power_status); | ||
137 | get_attention_status(hotplug, &info->attention_status); | ||
138 | get_latch_status(hotplug, &info->latch_status); | ||
139 | get_adapter_status(hotplug, &info->adapter_status); | ||
140 | out: | 141 | out: |
141 | if (retval) { | 142 | if (retval) { |
143 | kfree(ops); | ||
142 | kfree(info); | 144 | kfree(info); |
143 | kfree(hotplug); | 145 | kfree(hotplug); |
144 | } | 146 | } |
@@ -160,12 +162,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) | |||
160 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 162 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
161 | __func__, slot_name(slot)); | 163 | __func__, slot_name(slot)); |
162 | 164 | ||
163 | hotplug_slot->info->attention_status = status; | 165 | return pciehp_set_attention_status(slot, status); |
164 | |||
165 | if (ATTN_LED(slot->ctrl)) | ||
166 | pciehp_set_attention_status(slot, status); | ||
167 | |||
168 | return 0; | ||
169 | } | 166 | } |
170 | 167 | ||
171 | 168 | ||
@@ -193,92 +190,62 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) | |||
193 | static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) | 190 | static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) |
194 | { | 191 | { |
195 | struct slot *slot = hotplug_slot->private; | 192 | struct slot *slot = hotplug_slot->private; |
196 | int retval; | ||
197 | 193 | ||
198 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 194 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
199 | __func__, slot_name(slot)); | 195 | __func__, slot_name(slot)); |
200 | 196 | ||
201 | retval = pciehp_get_power_status(slot, value); | 197 | return pciehp_get_power_status(slot, value); |
202 | if (retval < 0) | ||
203 | *value = hotplug_slot->info->power_status; | ||
204 | |||
205 | return 0; | ||
206 | } | 198 | } |
207 | 199 | ||
208 | static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) | 200 | static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) |
209 | { | 201 | { |
210 | struct slot *slot = hotplug_slot->private; | 202 | struct slot *slot = hotplug_slot->private; |
211 | int retval; | ||
212 | 203 | ||
213 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 204 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
214 | __func__, slot_name(slot)); | 205 | __func__, slot_name(slot)); |
215 | 206 | ||
216 | retval = pciehp_get_attention_status(slot, value); | 207 | return pciehp_get_attention_status(slot, value); |
217 | if (retval < 0) | ||
218 | *value = hotplug_slot->info->attention_status; | ||
219 | |||
220 | return 0; | ||
221 | } | 208 | } |
222 | 209 | ||
223 | static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) | 210 | static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) |
224 | { | 211 | { |
225 | struct slot *slot = hotplug_slot->private; | 212 | struct slot *slot = hotplug_slot->private; |
226 | int retval; | ||
227 | 213 | ||
228 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 214 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
229 | __func__, slot_name(slot)); | 215 | __func__, slot_name(slot)); |
230 | 216 | ||
231 | retval = pciehp_get_latch_status(slot, value); | 217 | return pciehp_get_latch_status(slot, value); |
232 | if (retval < 0) | ||
233 | *value = hotplug_slot->info->latch_status; | ||
234 | |||
235 | return 0; | ||
236 | } | 218 | } |
237 | 219 | ||
238 | static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) | 220 | static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) |
239 | { | 221 | { |
240 | struct slot *slot = hotplug_slot->private; | 222 | struct slot *slot = hotplug_slot->private; |
241 | int retval; | ||
242 | 223 | ||
243 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 224 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
244 | __func__, slot_name(slot)); | 225 | __func__, slot_name(slot)); |
245 | 226 | ||
246 | retval = pciehp_get_adapter_status(slot, value); | 227 | return pciehp_get_adapter_status(slot, value); |
247 | if (retval < 0) | ||
248 | *value = hotplug_slot->info->adapter_status; | ||
249 | |||
250 | return 0; | ||
251 | } | 228 | } |
252 | 229 | ||
253 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, | 230 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, |
254 | enum pci_bus_speed *value) | 231 | enum pci_bus_speed *value) |
255 | { | 232 | { |
256 | struct slot *slot = hotplug_slot->private; | 233 | struct slot *slot = hotplug_slot->private; |
257 | int retval; | ||
258 | 234 | ||
259 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 235 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
260 | __func__, slot_name(slot)); | 236 | __func__, slot_name(slot)); |
261 | 237 | ||
262 | retval = pciehp_get_max_link_speed(slot, value); | 238 | return pciehp_get_max_link_speed(slot, value); |
263 | if (retval < 0) | ||
264 | *value = PCI_SPEED_UNKNOWN; | ||
265 | |||
266 | return 0; | ||
267 | } | 239 | } |
268 | 240 | ||
269 | static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | 241 | static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) |
270 | { | 242 | { |
271 | struct slot *slot = hotplug_slot->private; | 243 | struct slot *slot = hotplug_slot->private; |
272 | int retval; | ||
273 | 244 | ||
274 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 245 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
275 | __func__, slot_name(slot)); | 246 | __func__, slot_name(slot)); |
276 | 247 | ||
277 | retval = pciehp_get_cur_link_speed(slot, value); | 248 | return pciehp_get_cur_link_speed(slot, value); |
278 | if (retval < 0) | ||
279 | *value = PCI_SPEED_UNKNOWN; | ||
280 | |||
281 | return 0; | ||
282 | } | 249 | } |
283 | 250 | ||
284 | static int pciehp_probe(struct pcie_device *dev) | 251 | static int pciehp_probe(struct pcie_device *dev) |
@@ -286,14 +253,13 @@ static int pciehp_probe(struct pcie_device *dev) | |||
286 | int rc; | 253 | int rc; |
287 | struct controller *ctrl; | 254 | struct controller *ctrl; |
288 | struct slot *slot; | 255 | struct slot *slot; |
289 | u8 value; | 256 | u8 occupied, poweron; |
290 | struct pci_dev *pdev = dev->port; | ||
291 | 257 | ||
292 | if (pciehp_force) | 258 | if (pciehp_force) |
293 | dev_info(&dev->device, | 259 | dev_info(&dev->device, |
294 | "Bypassing BIOS check for pciehp use on %s\n", | 260 | "Bypassing BIOS check for pciehp use on %s\n", |
295 | pci_name(pdev)); | 261 | pci_name(dev->port)); |
296 | else if (pciehp_get_hp_hw_control_from_firmware(pdev)) | 262 | else if (pciehp_get_hp_hw_control_from_firmware(dev->port)) |
297 | goto err_out_none; | 263 | goto err_out_none; |
298 | 264 | ||
299 | ctrl = pcie_init(dev); | 265 | ctrl = pcie_init(dev); |
@@ -318,23 +284,18 @@ static int pciehp_probe(struct pcie_device *dev) | |||
318 | rc = pcie_init_notification(ctrl); | 284 | rc = pcie_init_notification(ctrl); |
319 | if (rc) { | 285 | if (rc) { |
320 | ctrl_err(ctrl, "Notification initialization failed\n"); | 286 | ctrl_err(ctrl, "Notification initialization failed\n"); |
321 | goto err_out_release_ctlr; | 287 | goto err_out_free_ctrl_slot; |
322 | } | 288 | } |
323 | 289 | ||
324 | /* Check if slot is occupied */ | 290 | /* Check if slot is occupied */ |
325 | slot = ctrl->slot; | 291 | slot = ctrl->slot; |
326 | pciehp_get_adapter_status(slot, &value); | 292 | pciehp_get_adapter_status(slot, &occupied); |
327 | if (value) { | 293 | pciehp_get_power_status(slot, &poweron); |
328 | if (pciehp_force) | 294 | if (occupied && pciehp_force) |
329 | pciehp_enable_slot(slot); | 295 | pciehp_enable_slot(slot); |
330 | } else { | 296 | /* If empty slot's power status is on, turn power off */ |
331 | /* Power off slot if not occupied */ | 297 | if (!occupied && poweron && POWER_CTRL(ctrl)) |
332 | if (POWER_CTRL(ctrl)) { | 298 | pciehp_power_off_slot(slot); |
333 | rc = pciehp_power_off_slot(slot); | ||
334 | if (rc) | ||
335 | goto err_out_free_ctrl_slot; | ||
336 | } | ||
337 | } | ||
338 | 299 | ||
339 | return 0; | 300 | return 0; |
340 | 301 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 84487d126e4d..d6ac1b261dd9 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -142,23 +142,9 @@ u8 pciehp_handle_power_fault(struct slot *p_slot) | |||
142 | 142 | ||
143 | /* power fault */ | 143 | /* power fault */ |
144 | ctrl_dbg(ctrl, "Power fault interrupt received\n"); | 144 | ctrl_dbg(ctrl, "Power fault interrupt received\n"); |
145 | 145 | ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); | |
146 | if (!pciehp_query_power_fault(p_slot)) { | 146 | event_type = INT_POWER_FAULT; |
147 | /* | 147 | ctrl_info(ctrl, "Power fault bit %x set\n", 0); |
148 | * power fault Cleared | ||
149 | */ | ||
150 | ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n", | ||
151 | slot_name(p_slot)); | ||
152 | event_type = INT_POWER_FAULT_CLEAR; | ||
153 | } else { | ||
154 | /* | ||
155 | * power fault | ||
156 | */ | ||
157 | ctrl_info(ctrl, "Power fault on Slot(%s)\n", slot_name(p_slot)); | ||
158 | event_type = INT_POWER_FAULT; | ||
159 | ctrl_info(ctrl, "Power fault bit %x set\n", 0); | ||
160 | } | ||
161 | |||
162 | queue_interrupt_event(p_slot, event_type); | 148 | queue_interrupt_event(p_slot, event_type); |
163 | 149 | ||
164 | return 1; | 150 | return 1; |
@@ -224,13 +210,12 @@ static int board_added(struct slot *p_slot) | |||
224 | retval = pciehp_check_link_status(ctrl); | 210 | retval = pciehp_check_link_status(ctrl); |
225 | if (retval) { | 211 | if (retval) { |
226 | ctrl_err(ctrl, "Failed to check link status\n"); | 212 | ctrl_err(ctrl, "Failed to check link status\n"); |
227 | set_slot_off(ctrl, p_slot); | 213 | goto err_exit; |
228 | return retval; | ||
229 | } | 214 | } |
230 | 215 | ||
231 | /* Check for a power fault */ | 216 | /* Check for a power fault */ |
232 | if (pciehp_query_power_fault(p_slot)) { | 217 | if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) { |
233 | ctrl_dbg(ctrl, "Power fault detected\n"); | 218 | ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); |
234 | retval = -EIO; | 219 | retval = -EIO; |
235 | goto err_exit; | 220 | goto err_exit; |
236 | } | 221 | } |
@@ -363,25 +348,6 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) | |||
363 | mutex_unlock(&p_slot->lock); | 348 | mutex_unlock(&p_slot->lock); |
364 | } | 349 | } |
365 | 350 | ||
366 | static int update_slot_info(struct slot *slot) | ||
367 | { | ||
368 | struct hotplug_slot_info *info; | ||
369 | int result; | ||
370 | |||
371 | info = kmalloc(sizeof(*info), GFP_KERNEL); | ||
372 | if (!info) | ||
373 | return -ENOMEM; | ||
374 | |||
375 | pciehp_get_power_status(slot, &info->power_status); | ||
376 | pciehp_get_attention_status(slot, &info->attention_status); | ||
377 | pciehp_get_latch_status(slot, &info->latch_status); | ||
378 | pciehp_get_adapter_status(slot, &info->adapter_status); | ||
379 | |||
380 | result = pci_hp_change_slot_info(slot->hotplug_slot, info); | ||
381 | kfree (info); | ||
382 | return result; | ||
383 | } | ||
384 | |||
385 | /* | 351 | /* |
386 | * Note: This function must be called with slot->lock held | 352 | * Note: This function must be called with slot->lock held |
387 | */ | 353 | */ |
@@ -442,7 +408,6 @@ static void handle_button_press_event(struct slot *p_slot) | |||
442 | * to hot-add or hot-remove is undergoing | 408 | * to hot-add or hot-remove is undergoing |
443 | */ | 409 | */ |
444 | ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot)); | 410 | ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot)); |
445 | update_slot_info(p_slot); | ||
446 | break; | 411 | break; |
447 | default: | 412 | default: |
448 | ctrl_warn(ctrl, "Not a valid state\n"); | 413 | ctrl_warn(ctrl, "Not a valid state\n"); |
@@ -500,11 +465,9 @@ static void interrupt_event_handler(struct work_struct *work) | |||
500 | if (!HP_SUPR_RM(ctrl)) | 465 | if (!HP_SUPR_RM(ctrl)) |
501 | break; | 466 | break; |
502 | ctrl_dbg(ctrl, "Surprise Removal\n"); | 467 | ctrl_dbg(ctrl, "Surprise Removal\n"); |
503 | update_slot_info(p_slot); | ||
504 | handle_surprise_event(p_slot); | 468 | handle_surprise_event(p_slot); |
505 | break; | 469 | break; |
506 | default: | 470 | default: |
507 | update_slot_info(p_slot); | ||
508 | break; | 471 | break; |
509 | } | 472 | } |
510 | mutex_unlock(&p_slot->lock); | 473 | mutex_unlock(&p_slot->lock); |
@@ -547,9 +510,6 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
547 | if (rc) { | 510 | if (rc) { |
548 | pciehp_get_latch_status(p_slot, &getstatus); | 511 | pciehp_get_latch_status(p_slot, &getstatus); |
549 | } | 512 | } |
550 | |||
551 | update_slot_info(p_slot); | ||
552 | |||
553 | return rc; | 513 | return rc; |
554 | } | 514 | } |
555 | 515 | ||
@@ -590,10 +550,7 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
590 | } | 550 | } |
591 | } | 551 | } |
592 | 552 | ||
593 | ret = remove_board(p_slot); | 553 | return remove_board(p_slot); |
594 | update_slot_info(p_slot); | ||
595 | |||
596 | return ret; | ||
597 | } | 554 | } |
598 | 555 | ||
599 | int pciehp_sysfs_enable_slot(struct slot *p_slot) | 556 | int pciehp_sysfs_enable_slot(struct slot *p_slot) |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9ef4605c1ef6..10040d58c8ef 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -45,25 +45,25 @@ static atomic_t pciehp_num_controllers = ATOMIC_INIT(0); | |||
45 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) | 45 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) |
46 | { | 46 | { |
47 | struct pci_dev *dev = ctrl->pcie->port; | 47 | struct pci_dev *dev = ctrl->pcie->port; |
48 | return pci_read_config_word(dev, ctrl->cap_base + reg, value); | 48 | return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value); |
49 | } | 49 | } |
50 | 50 | ||
51 | static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) | 51 | static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) |
52 | { | 52 | { |
53 | struct pci_dev *dev = ctrl->pcie->port; | 53 | struct pci_dev *dev = ctrl->pcie->port; |
54 | return pci_read_config_dword(dev, ctrl->cap_base + reg, value); | 54 | return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg, value); |
55 | } | 55 | } |
56 | 56 | ||
57 | static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) | 57 | static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) |
58 | { | 58 | { |
59 | struct pci_dev *dev = ctrl->pcie->port; | 59 | struct pci_dev *dev = ctrl->pcie->port; |
60 | return pci_write_config_word(dev, ctrl->cap_base + reg, value); | 60 | return pci_write_config_word(dev, pci_pcie_cap(dev) + reg, value); |
61 | } | 61 | } |
62 | 62 | ||
63 | static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) | 63 | static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) |
64 | { | 64 | { |
65 | struct pci_dev *dev = ctrl->pcie->port; | 65 | struct pci_dev *dev = ctrl->pcie->port; |
66 | return pci_write_config_dword(dev, ctrl->cap_base + reg, value); | 66 | return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg, value); |
67 | } | 67 | } |
68 | 68 | ||
69 | /* Power Control Command */ | 69 | /* Power Control Command */ |
@@ -318,8 +318,8 @@ int pciehp_get_attention_status(struct slot *slot, u8 *status) | |||
318 | return retval; | 318 | return retval; |
319 | } | 319 | } |
320 | 320 | ||
321 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", | 321 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__, |
322 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl); | 322 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); |
323 | 323 | ||
324 | atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6; | 324 | atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6; |
325 | 325 | ||
@@ -356,8 +356,8 @@ int pciehp_get_power_status(struct slot *slot, u8 *status) | |||
356 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); | 356 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); |
357 | return retval; | 357 | return retval; |
358 | } | 358 | } |
359 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", | 359 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", __func__, |
360 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl); | 360 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); |
361 | 361 | ||
362 | pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10; | 362 | pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10; |
363 | 363 | ||
@@ -427,27 +427,24 @@ int pciehp_set_attention_status(struct slot *slot, u8 value) | |||
427 | struct controller *ctrl = slot->ctrl; | 427 | struct controller *ctrl = slot->ctrl; |
428 | u16 slot_cmd; | 428 | u16 slot_cmd; |
429 | u16 cmd_mask; | 429 | u16 cmd_mask; |
430 | int rc; | ||
431 | 430 | ||
432 | cmd_mask = PCI_EXP_SLTCTL_AIC; | 431 | cmd_mask = PCI_EXP_SLTCTL_AIC; |
433 | switch (value) { | 432 | switch (value) { |
434 | case 0 : /* turn off */ | 433 | case 0 : /* turn off */ |
435 | slot_cmd = 0x00C0; | 434 | slot_cmd = 0x00C0; |
436 | break; | 435 | break; |
437 | case 1: /* turn on */ | 436 | case 1: /* turn on */ |
438 | slot_cmd = 0x0040; | 437 | slot_cmd = 0x0040; |
439 | break; | 438 | break; |
440 | case 2: /* turn blink */ | 439 | case 2: /* turn blink */ |
441 | slot_cmd = 0x0080; | 440 | slot_cmd = 0x0080; |
442 | break; | 441 | break; |
443 | default: | 442 | default: |
444 | return -1; | 443 | return -EINVAL; |
445 | } | 444 | } |
446 | rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 445 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
447 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 446 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
448 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 447 | return pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
449 | |||
450 | return rc; | ||
451 | } | 448 | } |
452 | 449 | ||
453 | void pciehp_green_led_on(struct slot *slot) | 450 | void pciehp_green_led_on(struct slot *slot) |
@@ -459,8 +456,8 @@ void pciehp_green_led_on(struct slot *slot) | |||
459 | slot_cmd = 0x0100; | 456 | slot_cmd = 0x0100; |
460 | cmd_mask = PCI_EXP_SLTCTL_PIC; | 457 | cmd_mask = PCI_EXP_SLTCTL_PIC; |
461 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 458 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
462 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 459 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
463 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 460 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
464 | } | 461 | } |
465 | 462 | ||
466 | void pciehp_green_led_off(struct slot *slot) | 463 | void pciehp_green_led_off(struct slot *slot) |
@@ -472,8 +469,8 @@ void pciehp_green_led_off(struct slot *slot) | |||
472 | slot_cmd = 0x0300; | 469 | slot_cmd = 0x0300; |
473 | cmd_mask = PCI_EXP_SLTCTL_PIC; | 470 | cmd_mask = PCI_EXP_SLTCTL_PIC; |
474 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 471 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
475 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 472 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
476 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 473 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
477 | } | 474 | } |
478 | 475 | ||
479 | void pciehp_green_led_blink(struct slot *slot) | 476 | void pciehp_green_led_blink(struct slot *slot) |
@@ -485,8 +482,8 @@ void pciehp_green_led_blink(struct slot *slot) | |||
485 | slot_cmd = 0x0200; | 482 | slot_cmd = 0x0200; |
486 | cmd_mask = PCI_EXP_SLTCTL_PIC; | 483 | cmd_mask = PCI_EXP_SLTCTL_PIC; |
487 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 484 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
488 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 485 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
489 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 486 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
490 | } | 487 | } |
491 | 488 | ||
492 | int pciehp_power_on_slot(struct slot * slot) | 489 | int pciehp_power_on_slot(struct slot * slot) |
@@ -514,97 +511,38 @@ int pciehp_power_on_slot(struct slot * slot) | |||
514 | return retval; | 511 | return retval; |
515 | } | 512 | } |
516 | } | 513 | } |
514 | ctrl->power_fault_detected = 0; | ||
517 | 515 | ||
518 | slot_cmd = POWER_ON; | 516 | slot_cmd = POWER_ON; |
519 | cmd_mask = PCI_EXP_SLTCTL_PCC; | 517 | cmd_mask = PCI_EXP_SLTCTL_PCC; |
520 | if (!pciehp_poll_mode) { | ||
521 | /* Enable power fault detection turned off at power off time */ | ||
522 | slot_cmd |= PCI_EXP_SLTCTL_PFDE; | ||
523 | cmd_mask |= PCI_EXP_SLTCTL_PFDE; | ||
524 | } | ||
525 | |||
526 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 518 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
527 | if (retval) { | 519 | if (retval) { |
528 | ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd); | 520 | ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd); |
529 | return retval; | 521 | return retval; |
530 | } | 522 | } |
531 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 523 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
532 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 524 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
533 | 525 | ||
534 | ctrl->power_fault_detected = 0; | ||
535 | return retval; | 526 | return retval; |
536 | } | 527 | } |
537 | 528 | ||
538 | static inline int pcie_mask_bad_dllp(struct controller *ctrl) | ||
539 | { | ||
540 | struct pci_dev *dev = ctrl->pcie->port; | ||
541 | int pos; | ||
542 | u32 reg; | ||
543 | |||
544 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
545 | if (!pos) | ||
546 | return 0; | ||
547 | pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®); | ||
548 | if (reg & PCI_ERR_COR_BAD_DLLP) | ||
549 | return 0; | ||
550 | reg |= PCI_ERR_COR_BAD_DLLP; | ||
551 | pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg); | ||
552 | return 1; | ||
553 | } | ||
554 | |||
555 | static inline void pcie_unmask_bad_dllp(struct controller *ctrl) | ||
556 | { | ||
557 | struct pci_dev *dev = ctrl->pcie->port; | ||
558 | u32 reg; | ||
559 | int pos; | ||
560 | |||
561 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
562 | if (!pos) | ||
563 | return; | ||
564 | pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®); | ||
565 | if (!(reg & PCI_ERR_COR_BAD_DLLP)) | ||
566 | return; | ||
567 | reg &= ~PCI_ERR_COR_BAD_DLLP; | ||
568 | pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg); | ||
569 | } | ||
570 | |||
571 | int pciehp_power_off_slot(struct slot * slot) | 529 | int pciehp_power_off_slot(struct slot * slot) |
572 | { | 530 | { |
573 | struct controller *ctrl = slot->ctrl; | 531 | struct controller *ctrl = slot->ctrl; |
574 | u16 slot_cmd; | 532 | u16 slot_cmd; |
575 | u16 cmd_mask; | 533 | u16 cmd_mask; |
576 | int retval = 0; | 534 | int retval; |
577 | int changed; | ||
578 | |||
579 | /* | ||
580 | * Set Bad DLLP Mask bit in Correctable Error Mask | ||
581 | * Register. This is the workaround against Bad DLLP error | ||
582 | * that sometimes happens during turning power off the slot | ||
583 | * which conforms to PCI Express 1.0a spec. | ||
584 | */ | ||
585 | changed = pcie_mask_bad_dllp(ctrl); | ||
586 | 535 | ||
587 | slot_cmd = POWER_OFF; | 536 | slot_cmd = POWER_OFF; |
588 | cmd_mask = PCI_EXP_SLTCTL_PCC; | 537 | cmd_mask = PCI_EXP_SLTCTL_PCC; |
589 | if (!pciehp_poll_mode) { | ||
590 | /* Disable power fault detection */ | ||
591 | slot_cmd &= ~PCI_EXP_SLTCTL_PFDE; | ||
592 | cmd_mask |= PCI_EXP_SLTCTL_PFDE; | ||
593 | } | ||
594 | |||
595 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 538 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
596 | if (retval) { | 539 | if (retval) { |
597 | ctrl_err(ctrl, "Write command failed!\n"); | 540 | ctrl_err(ctrl, "Write command failed!\n"); |
598 | retval = -1; | 541 | return retval; |
599 | goto out; | ||
600 | } | 542 | } |
601 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 543 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
602 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 544 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
603 | out: | 545 | return 0; |
604 | if (changed) | ||
605 | pcie_unmask_bad_dllp(ctrl); | ||
606 | |||
607 | return retval; | ||
608 | } | 546 | } |
609 | 547 | ||
610 | static irqreturn_t pcie_isr(int irq, void *dev_id) | 548 | static irqreturn_t pcie_isr(int irq, void *dev_id) |
@@ -840,11 +778,19 @@ int pcie_enable_notification(struct controller *ctrl) | |||
840 | { | 778 | { |
841 | u16 cmd, mask; | 779 | u16 cmd, mask; |
842 | 780 | ||
781 | /* | ||
782 | * TBD: Power fault detected software notification support. | ||
783 | * | ||
784 | * Power fault detected software notification is not enabled | ||
785 | * now, because it caused power fault detected interrupt storm | ||
786 | * on some machines. On those machines, power fault detected | ||
787 | * bit in the slot status register was set again immediately | ||
788 | * when it is cleared in the interrupt service routine, and | ||
789 | * next power fault detected interrupt was notified again. | ||
790 | */ | ||
843 | cmd = PCI_EXP_SLTCTL_PDCE; | 791 | cmd = PCI_EXP_SLTCTL_PDCE; |
844 | if (ATTN_BUTTN(ctrl)) | 792 | if (ATTN_BUTTN(ctrl)) |
845 | cmd |= PCI_EXP_SLTCTL_ABPE; | 793 | cmd |= PCI_EXP_SLTCTL_ABPE; |
846 | if (POWER_CTRL(ctrl)) | ||
847 | cmd |= PCI_EXP_SLTCTL_PFDE; | ||
848 | if (MRL_SENS(ctrl)) | 794 | if (MRL_SENS(ctrl)) |
849 | cmd |= PCI_EXP_SLTCTL_MRLSCE; | 795 | cmd |= PCI_EXP_SLTCTL_MRLSCE; |
850 | if (!pciehp_poll_mode) | 796 | if (!pciehp_poll_mode) |
@@ -866,7 +812,8 @@ static void pcie_disable_notification(struct controller *ctrl) | |||
866 | u16 mask; | 812 | u16 mask; |
867 | mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | | 813 | mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | |
868 | PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | | 814 | PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | |
869 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE); | 815 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE | |
816 | PCI_EXP_SLTCTL_DLLSCE); | ||
870 | if (pcie_write_cmd(ctrl, 0, mask)) | 817 | if (pcie_write_cmd(ctrl, 0, mask)) |
871 | ctrl_warn(ctrl, "Cannot disable software notification\n"); | 818 | ctrl_warn(ctrl, "Cannot disable software notification\n"); |
872 | } | 819 | } |
@@ -934,7 +881,8 @@ static inline void dbg_ctrl(struct controller *ctrl) | |||
934 | pdev->subsystem_device); | 881 | pdev->subsystem_device); |
935 | ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n", | 882 | ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n", |
936 | pdev->subsystem_vendor); | 883 | pdev->subsystem_vendor); |
937 | ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n", ctrl->cap_base); | 884 | ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n", |
885 | pci_pcie_cap(pdev)); | ||
938 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 886 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
939 | if (!pci_resource_len(pdev, i)) | 887 | if (!pci_resource_len(pdev, i)) |
940 | continue; | 888 | continue; |
@@ -978,8 +926,7 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
978 | goto abort; | 926 | goto abort; |
979 | } | 927 | } |
980 | ctrl->pcie = dev; | 928 | ctrl->pcie = dev; |
981 | ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 929 | if (!pci_pcie_cap(pdev)) { |
982 | if (!ctrl->cap_base) { | ||
983 | ctrl_err(ctrl, "Cannot find PCI Express capability\n"); | 930 | ctrl_err(ctrl, "Cannot find PCI Express capability\n"); |
984 | goto abort_ctrl; | 931 | goto abort_ctrl; |
985 | } | 932 | } |
diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c index cc8ec3aa41a7..80b461c98557 100644 --- a/drivers/pci/hotplug/pcihp_slot.c +++ b/drivers/pci/hotplug/pcihp_slot.c | |||
@@ -43,7 +43,7 @@ static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp) | |||
43 | * Perhaps we *should* use default settings for PCIe, but | 43 | * Perhaps we *should* use default settings for PCIe, but |
44 | * pciehp didn't, so we won't either. | 44 | * pciehp didn't, so we won't either. |
45 | */ | 45 | */ |
46 | if (dev->is_pcie) | 46 | if (pci_is_pcie(dev)) |
47 | return; | 47 | return; |
48 | dev_info(&dev->dev, "using default PCI settings\n"); | 48 | dev_info(&dev->dev, "using default PCI settings\n"); |
49 | hpp = &pci_default_type0; | 49 | hpp = &pci_default_type0; |
@@ -102,7 +102,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | |||
102 | return; | 102 | return; |
103 | 103 | ||
104 | /* Find PCI Express capability */ | 104 | /* Find PCI Express capability */ |
105 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 105 | pos = pci_pcie_cap(dev); |
106 | if (!pos) | 106 | if (!pos) |
107 | return; | 107 | return; |
108 | 108 | ||
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 9261327b49f3..8d6159426311 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -1611,7 +1611,7 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev, | |||
1611 | return ret; | 1611 | return ret; |
1612 | parent = parent->bus->self; | 1612 | parent = parent->bus->self; |
1613 | } | 1613 | } |
1614 | if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */ | 1614 | if (pci_is_pcie(tmp)) /* this is a PCIE-to-PCI bridge */ |
1615 | return domain_context_mapping_one(domain, | 1615 | return domain_context_mapping_one(domain, |
1616 | pci_domain_nr(tmp->subordinate), | 1616 | pci_domain_nr(tmp->subordinate), |
1617 | tmp->subordinate->number, 0, | 1617 | tmp->subordinate->number, 0, |
@@ -1651,7 +1651,7 @@ static int domain_context_mapped(struct pci_dev *pdev) | |||
1651 | return ret; | 1651 | return ret; |
1652 | parent = parent->bus->self; | 1652 | parent = parent->bus->self; |
1653 | } | 1653 | } |
1654 | if (tmp->is_pcie) | 1654 | if (pci_is_pcie(tmp)) |
1655 | return device_context_mapped(iommu, tmp->subordinate->number, | 1655 | return device_context_mapped(iommu, tmp->subordinate->number, |
1656 | 0); | 1656 | 0); |
1657 | else | 1657 | else |
@@ -1821,7 +1821,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) | |||
1821 | 1821 | ||
1822 | dev_tmp = pci_find_upstream_pcie_bridge(pdev); | 1822 | dev_tmp = pci_find_upstream_pcie_bridge(pdev); |
1823 | if (dev_tmp) { | 1823 | if (dev_tmp) { |
1824 | if (dev_tmp->is_pcie) { | 1824 | if (pci_is_pcie(dev_tmp)) { |
1825 | bus = dev_tmp->subordinate->number; | 1825 | bus = dev_tmp->subordinate->number; |
1826 | devfn = 0; | 1826 | devfn = 0; |
1827 | } else { | 1827 | } else { |
@@ -2182,7 +2182,7 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup) | |||
2182 | * the 1:1 domain, just in _case_ one of their siblings turns out | 2182 | * the 1:1 domain, just in _case_ one of their siblings turns out |
2183 | * not to be able to map all of memory. | 2183 | * not to be able to map all of memory. |
2184 | */ | 2184 | */ |
2185 | if (!pdev->is_pcie) { | 2185 | if (!pci_is_pcie(pdev)) { |
2186 | if (!pci_is_root_bus(pdev->bus)) | 2186 | if (!pci_is_root_bus(pdev->bus)) |
2187 | return 0; | 2187 | return 0; |
2188 | if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI) | 2188 | if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI) |
@@ -3319,7 +3319,7 @@ static void iommu_detach_dependent_devices(struct intel_iommu *iommu, | |||
3319 | parent->devfn); | 3319 | parent->devfn); |
3320 | parent = parent->bus->self; | 3320 | parent = parent->bus->self; |
3321 | } | 3321 | } |
3322 | if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */ | 3322 | if (pci_is_pcie(tmp)) /* this is a PCIE-to-PCI bridge */ |
3323 | iommu_detach_dev(iommu, | 3323 | iommu_detach_dev(iommu, |
3324 | tmp->subordinate->number, 0); | 3324 | tmp->subordinate->number, 0); |
3325 | else /* this is a legacy PCI bridge */ | 3325 | else /* this is a legacy PCI bridge */ |
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 3b3658669bee..1487bf2be863 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c | |||
@@ -520,7 +520,7 @@ int set_msi_sid(struct irte *irte, struct pci_dev *dev) | |||
520 | return -1; | 520 | return -1; |
521 | 521 | ||
522 | /* PCIe device or Root Complex integrated PCI device */ | 522 | /* PCIe device or Root Complex integrated PCI device */ |
523 | if (dev->is_pcie || !dev->bus->parent) { | 523 | if (pci_is_pcie(dev) || !dev->bus->parent) { |
524 | set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, | 524 | set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, |
525 | (dev->bus->number << 8) | dev->devfn); | 525 | (dev->bus->number << 8) | dev->devfn); |
526 | return 0; | 526 | return 0; |
@@ -528,7 +528,7 @@ int set_msi_sid(struct irte *irte, struct pci_dev *dev) | |||
528 | 528 | ||
529 | bridge = pci_find_upstream_pcie_bridge(dev); | 529 | bridge = pci_find_upstream_pcie_bridge(dev); |
530 | if (bridge) { | 530 | if (bridge) { |
531 | if (bridge->is_pcie) /* this is a PCIE-to-PCI/PCIX bridge */ | 531 | if (pci_is_pcie(bridge))/* this is a PCIE-to-PCI/PCIX bridge */ |
532 | set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16, | 532 | set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16, |
533 | (bridge->bus->number << 8) | dev->bus->number); | 533 | (bridge->bus->number << 8) | dev->bus->number); |
534 | else /* this is a legacy PCI bridge */ | 534 | else /* this is a legacy PCI bridge */ |
diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c new file mode 100644 index 000000000000..3e0d7b5dd1b9 --- /dev/null +++ b/drivers/pci/ioapic.c | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * IOAPIC/IOxAPIC/IOSAPIC driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Fujitsu Limited. | ||
5 | * (c) Copyright 2009 Hewlett-Packard Development Company, L.P. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * This driver manages PCI I/O APICs added by hotplug after boot. We try to | ||
14 | * claim all I/O APIC PCI devices, but those present at boot were registered | ||
15 | * when we parsed the ACPI MADT, so we'll fail when we try to re-register | ||
16 | * them. | ||
17 | */ | ||
18 | |||
19 | #include <linux/pci.h> | ||
20 | #include <linux/acpi.h> | ||
21 | #include <acpi/acpi_bus.h> | ||
22 | |||
23 | struct ioapic { | ||
24 | acpi_handle handle; | ||
25 | u32 gsi_base; | ||
26 | }; | ||
27 | |||
28 | static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) | ||
29 | { | ||
30 | acpi_handle handle; | ||
31 | acpi_status status; | ||
32 | unsigned long long gsb; | ||
33 | struct ioapic *ioapic; | ||
34 | u64 addr; | ||
35 | int ret; | ||
36 | char *type; | ||
37 | |||
38 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | ||
39 | if (!handle) | ||
40 | return -EINVAL; | ||
41 | |||
42 | status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb); | ||
43 | if (ACPI_FAILURE(status)) | ||
44 | return -EINVAL; | ||
45 | |||
46 | /* | ||
47 | * The previous code in acpiphp evaluated _MAT if _GSB failed, but | ||
48 | * ACPI spec 4.0 sec 6.2.2 requires _GSB for hot-pluggable I/O APICs. | ||
49 | */ | ||
50 | |||
51 | ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL); | ||
52 | if (!ioapic) | ||
53 | return -ENOMEM; | ||
54 | |||
55 | ioapic->handle = handle; | ||
56 | ioapic->gsi_base = (u32) gsb; | ||
57 | |||
58 | if (dev->class == PCI_CLASS_SYSTEM_PIC_IOAPIC) | ||
59 | type = "IOAPIC"; | ||
60 | else | ||
61 | type = "IOxAPIC"; | ||
62 | |||
63 | ret = pci_enable_device(dev); | ||
64 | if (ret < 0) | ||
65 | goto exit_free; | ||
66 | |||
67 | pci_set_master(dev); | ||
68 | |||
69 | if (pci_request_region(dev, 0, type)) | ||
70 | goto exit_disable; | ||
71 | |||
72 | addr = pci_resource_start(dev, 0); | ||
73 | if (acpi_register_ioapic(ioapic->handle, addr, ioapic->gsi_base)) | ||
74 | goto exit_release; | ||
75 | |||
76 | pci_set_drvdata(dev, ioapic); | ||
77 | dev_info(&dev->dev, "%s at %#llx, GSI %u\n", type, addr, | ||
78 | ioapic->gsi_base); | ||
79 | return 0; | ||
80 | |||
81 | exit_release: | ||
82 | pci_release_region(dev, 0); | ||
83 | exit_disable: | ||
84 | pci_disable_device(dev); | ||
85 | exit_free: | ||
86 | kfree(ioapic); | ||
87 | return -ENODEV; | ||
88 | } | ||
89 | |||
90 | static void ioapic_remove(struct pci_dev *dev) | ||
91 | { | ||
92 | struct ioapic *ioapic = pci_get_drvdata(dev); | ||
93 | |||
94 | acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base); | ||
95 | pci_release_region(dev, 0); | ||
96 | pci_disable_device(dev); | ||
97 | kfree(ioapic); | ||
98 | } | ||
99 | |||
100 | |||
101 | static struct pci_device_id ioapic_devices[] = { | ||
102 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
103 | PCI_CLASS_SYSTEM_PIC_IOAPIC << 8, 0xffff00, }, | ||
104 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
105 | PCI_CLASS_SYSTEM_PIC_IOXAPIC << 8, 0xffff00, }, | ||
106 | { } | ||
107 | }; | ||
108 | |||
109 | static struct pci_driver ioapic_driver = { | ||
110 | .name = "ioapic", | ||
111 | .id_table = ioapic_devices, | ||
112 | .probe = ioapic_probe, | ||
113 | .remove = __devexit_p(ioapic_remove), | ||
114 | }; | ||
115 | |||
116 | static int __init ioapic_init(void) | ||
117 | { | ||
118 | return pci_register_driver(&ioapic_driver); | ||
119 | } | ||
120 | |||
121 | static void __exit ioapic_exit(void) | ||
122 | { | ||
123 | pci_unregister_driver(&ioapic_driver); | ||
124 | } | ||
125 | |||
126 | module_init(ioapic_init); | ||
127 | module_exit(ioapic_exit); | ||
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index e03fe98f0619..b2a448e19fe6 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -555,7 +555,7 @@ int pci_iov_init(struct pci_dev *dev) | |||
555 | { | 555 | { |
556 | int pos; | 556 | int pos; |
557 | 557 | ||
558 | if (!dev->is_pcie) | 558 | if (!pci_is_pcie(dev)) |
559 | return -ENODEV; | 559 | return -ENODEV; |
560 | 560 | ||
561 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV); | 561 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV); |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 33317df47699..cc617ddd33d0 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -116,7 +116,7 @@ static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) | |||
116 | int ret; | 116 | int ret; |
117 | 117 | ||
118 | ret = acpi_pm_device_sleep_wake(&bridge->dev, enable); | 118 | ret = acpi_pm_device_sleep_wake(&bridge->dev, enable); |
119 | if (!ret || bridge->is_pcie) | 119 | if (!ret || pci_is_pcie(bridge)) |
120 | return; | 120 | return; |
121 | bus = bus->parent; | 121 | bus = bus->parent; |
122 | } | 122 | } |
@@ -131,7 +131,7 @@ static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
131 | if (acpi_pci_can_wakeup(dev)) | 131 | if (acpi_pci_can_wakeup(dev)) |
132 | return acpi_pm_device_sleep_wake(&dev->dev, enable); | 132 | return acpi_pm_device_sleep_wake(&dev->dev, enable); |
133 | 133 | ||
134 | if (!dev->is_pcie) | 134 | if (!pci_is_pcie(dev)) |
135 | acpi_pci_propagate_wakeup_enable(dev->bus, enable); | 135 | acpi_pci_propagate_wakeup_enable(dev->bus, enable); |
136 | 136 | ||
137 | return 0; | 137 | return 0; |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 0f6382f090ee..c5df94e86678 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -74,7 +74,11 @@ static ssize_t local_cpus_show(struct device *dev, | |||
74 | const struct cpumask *mask; | 74 | const struct cpumask *mask; |
75 | int len; | 75 | int len; |
76 | 76 | ||
77 | #ifdef CONFIG_NUMA | ||
78 | mask = cpumask_of_node(dev_to_node(dev)); | ||
79 | #else | ||
77 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); | 80 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); |
81 | #endif | ||
78 | len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask); | 82 | len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask); |
79 | buf[len++] = '\n'; | 83 | buf[len++] = '\n'; |
80 | buf[len] = '\0'; | 84 | buf[len] = '\0'; |
@@ -88,7 +92,11 @@ static ssize_t local_cpulist_show(struct device *dev, | |||
88 | const struct cpumask *mask; | 92 | const struct cpumask *mask; |
89 | int len; | 93 | int len; |
90 | 94 | ||
95 | #ifdef CONFIG_NUMA | ||
96 | mask = cpumask_of_node(dev_to_node(dev)); | ||
97 | #else | ||
91 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); | 98 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); |
99 | #endif | ||
92 | len = cpulist_scnprintf(buf, PAGE_SIZE-2, mask); | 100 | len = cpulist_scnprintf(buf, PAGE_SIZE-2, mask); |
93 | buf[len++] = '\n'; | 101 | buf[len++] = '\n'; |
94 | buf[len] = '\0'; | 102 | buf[len] = '\0'; |
@@ -176,6 +184,21 @@ numa_node_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
176 | #endif | 184 | #endif |
177 | 185 | ||
178 | static ssize_t | 186 | static ssize_t |
187 | dma_mask_bits_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
188 | { | ||
189 | struct pci_dev *pdev = to_pci_dev(dev); | ||
190 | |||
191 | return sprintf (buf, "%d\n", fls64(pdev->dma_mask)); | ||
192 | } | ||
193 | |||
194 | static ssize_t | ||
195 | consistent_dma_mask_bits_show(struct device *dev, struct device_attribute *attr, | ||
196 | char *buf) | ||
197 | { | ||
198 | return sprintf (buf, "%d\n", fls64(dev->coherent_dma_mask)); | ||
199 | } | ||
200 | |||
201 | static ssize_t | ||
179 | msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf) | 202 | msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf) |
180 | { | 203 | { |
181 | struct pci_dev *pdev = to_pci_dev(dev); | 204 | struct pci_dev *pdev = to_pci_dev(dev); |
@@ -306,6 +329,8 @@ struct device_attribute pci_dev_attrs[] = { | |||
306 | #ifdef CONFIG_NUMA | 329 | #ifdef CONFIG_NUMA |
307 | __ATTR_RO(numa_node), | 330 | __ATTR_RO(numa_node), |
308 | #endif | 331 | #endif |
332 | __ATTR_RO(dma_mask_bits), | ||
333 | __ATTR_RO(consistent_dma_mask_bits), | ||
309 | __ATTR(enable, 0600, is_enabled_show, is_enabled_store), | 334 | __ATTR(enable, 0600, is_enabled_show, is_enabled_store), |
310 | __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), | 335 | __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), |
311 | broken_parity_status_show,broken_parity_status_store), | 336 | broken_parity_status_show,broken_parity_status_store), |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 4e4c295a049f..0bc27e059019 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -47,6 +47,15 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE; | |||
47 | unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; | 47 | unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; |
48 | unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; | 48 | unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; |
49 | 49 | ||
50 | /* | ||
51 | * The default CLS is used if arch didn't set CLS explicitly and not | ||
52 | * all pci devices agree on the same value. Arch can override either | ||
53 | * the dfl or actual value as it sees fit. Don't forget this is | ||
54 | * measured in 32-bit words, not bytes. | ||
55 | */ | ||
56 | u8 pci_dfl_cache_line_size __devinitdata = L1_CACHE_BYTES >> 2; | ||
57 | u8 pci_cache_line_size; | ||
58 | |||
50 | /** | 59 | /** |
51 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children | 60 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children |
52 | * @bus: pointer to PCI bus structure to search | 61 | * @bus: pointer to PCI bus structure to search |
@@ -373,8 +382,12 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) | |||
373 | continue; /* Wrong type */ | 382 | continue; /* Wrong type */ |
374 | if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) | 383 | if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) |
375 | return r; /* Exact match */ | 384 | return r; /* Exact match */ |
376 | if ((res->flags & IORESOURCE_PREFETCH) && !(r->flags & IORESOURCE_PREFETCH)) | 385 | /* We can't insert a non-prefetch resource inside a prefetchable parent .. */ |
377 | best = r; /* Approximating prefetchable by non-prefetchable */ | 386 | if (r->flags & IORESOURCE_PREFETCH) |
387 | continue; | ||
388 | /* .. but we can put a prefetchable resource inside a non-prefetchable one */ | ||
389 | if (!best) | ||
390 | best = r; | ||
378 | } | 391 | } |
379 | return best; | 392 | return best; |
380 | } | 393 | } |
@@ -728,8 +741,8 @@ static int pci_save_pcie_state(struct pci_dev *dev) | |||
728 | u16 *cap; | 741 | u16 *cap; |
729 | u16 flags; | 742 | u16 flags; |
730 | 743 | ||
731 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 744 | pos = pci_pcie_cap(dev); |
732 | if (pos <= 0) | 745 | if (!pos) |
733 | return 0; | 746 | return 0; |
734 | 747 | ||
735 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); | 748 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); |
@@ -837,7 +850,7 @@ pci_save_state(struct pci_dev *dev) | |||
837 | int i; | 850 | int i; |
838 | /* XXX: 100% dword access ok here? */ | 851 | /* XXX: 100% dword access ok here? */ |
839 | for (i = 0; i < 16; i++) | 852 | for (i = 0; i < 16; i++) |
840 | pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); | 853 | pci_read_config_dword(dev, i * 4, &dev->saved_config_space[i]); |
841 | dev->state_saved = true; | 854 | dev->state_saved = true; |
842 | if ((i = pci_save_pcie_state(dev)) != 0) | 855 | if ((i = pci_save_pcie_state(dev)) != 0) |
843 | return i; | 856 | return i; |
@@ -1202,7 +1215,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
1202 | 1215 | ||
1203 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); | 1216 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); |
1204 | 1217 | ||
1205 | dev_printk(KERN_INFO, &dev->dev, "PME# %s\n", | 1218 | dev_printk(KERN_DEBUG, &dev->dev, "PME# %s\n", |
1206 | enable ? "enabled" : "disabled"); | 1219 | enable ? "enabled" : "disabled"); |
1207 | } | 1220 | } |
1208 | 1221 | ||
@@ -1413,7 +1426,8 @@ void pci_pm_init(struct pci_dev *dev) | |||
1413 | 1426 | ||
1414 | pmc &= PCI_PM_CAP_PME_MASK; | 1427 | pmc &= PCI_PM_CAP_PME_MASK; |
1415 | if (pmc) { | 1428 | if (pmc) { |
1416 | dev_info(&dev->dev, "PME# supported from%s%s%s%s%s\n", | 1429 | dev_printk(KERN_DEBUG, &dev->dev, |
1430 | "PME# supported from%s%s%s%s%s\n", | ||
1417 | (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", | 1431 | (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", |
1418 | (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", | 1432 | (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", |
1419 | (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", | 1433 | (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", |
@@ -1510,7 +1524,7 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1510 | u16 ctrl; | 1524 | u16 ctrl; |
1511 | struct pci_dev *bridge; | 1525 | struct pci_dev *bridge; |
1512 | 1526 | ||
1513 | if (!dev->is_pcie || dev->devfn) | 1527 | if (!pci_is_pcie(dev) || dev->devfn) |
1514 | return; | 1528 | return; |
1515 | 1529 | ||
1516 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | 1530 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); |
@@ -1518,10 +1532,10 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1518 | return; | 1532 | return; |
1519 | 1533 | ||
1520 | bridge = dev->bus->self; | 1534 | bridge = dev->bus->self; |
1521 | if (!bridge || !bridge->is_pcie) | 1535 | if (!bridge || !pci_is_pcie(bridge)) |
1522 | return; | 1536 | return; |
1523 | 1537 | ||
1524 | pos = pci_find_capability(bridge, PCI_CAP_ID_EXP); | 1538 | pos = pci_pcie_cap(bridge); |
1525 | if (!pos) | 1539 | if (!pos) |
1526 | return; | 1540 | return; |
1527 | 1541 | ||
@@ -1536,6 +1550,54 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1536 | bridge->ari_enabled = 1; | 1550 | bridge->ari_enabled = 1; |
1537 | } | 1551 | } |
1538 | 1552 | ||
1553 | static int pci_acs_enable; | ||
1554 | |||
1555 | /** | ||
1556 | * pci_request_acs - ask for ACS to be enabled if supported | ||
1557 | */ | ||
1558 | void pci_request_acs(void) | ||
1559 | { | ||
1560 | pci_acs_enable = 1; | ||
1561 | } | ||
1562 | |||
1563 | /** | ||
1564 | * pci_enable_acs - enable ACS if hardware support it | ||
1565 | * @dev: the PCI device | ||
1566 | */ | ||
1567 | void pci_enable_acs(struct pci_dev *dev) | ||
1568 | { | ||
1569 | int pos; | ||
1570 | u16 cap; | ||
1571 | u16 ctrl; | ||
1572 | |||
1573 | if (!pci_acs_enable) | ||
1574 | return; | ||
1575 | |||
1576 | if (!pci_is_pcie(dev)) | ||
1577 | return; | ||
1578 | |||
1579 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS); | ||
1580 | if (!pos) | ||
1581 | return; | ||
1582 | |||
1583 | pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap); | ||
1584 | pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl); | ||
1585 | |||
1586 | /* Source Validation */ | ||
1587 | ctrl |= (cap & PCI_ACS_SV); | ||
1588 | |||
1589 | /* P2P Request Redirect */ | ||
1590 | ctrl |= (cap & PCI_ACS_RR); | ||
1591 | |||
1592 | /* P2P Completion Redirect */ | ||
1593 | ctrl |= (cap & PCI_ACS_CR); | ||
1594 | |||
1595 | /* Upstream Forwarding */ | ||
1596 | ctrl |= (cap & PCI_ACS_UF); | ||
1597 | |||
1598 | pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl); | ||
1599 | } | ||
1600 | |||
1539 | /** | 1601 | /** |
1540 | * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge | 1602 | * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge |
1541 | * @dev: the PCI device | 1603 | * @dev: the PCI device |
@@ -1669,9 +1731,7 @@ static int __pci_request_region(struct pci_dev *pdev, int bar, const char *res_n | |||
1669 | return 0; | 1731 | return 0; |
1670 | 1732 | ||
1671 | err_out: | 1733 | err_out: |
1672 | dev_warn(&pdev->dev, "BAR %d: can't reserve %s region %pR\n", | 1734 | dev_warn(&pdev->dev, "BAR %d: can't reserve %pR\n", bar, |
1673 | bar, | ||
1674 | pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem", | ||
1675 | &pdev->resource[bar]); | 1735 | &pdev->resource[bar]); |
1676 | return -EBUSY; | 1736 | return -EBUSY; |
1677 | } | 1737 | } |
@@ -1866,31 +1926,6 @@ void pci_clear_master(struct pci_dev *dev) | |||
1866 | __pci_set_master(dev, false); | 1926 | __pci_set_master(dev, false); |
1867 | } | 1927 | } |
1868 | 1928 | ||
1869 | #ifdef PCI_DISABLE_MWI | ||
1870 | int pci_set_mwi(struct pci_dev *dev) | ||
1871 | { | ||
1872 | return 0; | ||
1873 | } | ||
1874 | |||
1875 | int pci_try_set_mwi(struct pci_dev *dev) | ||
1876 | { | ||
1877 | return 0; | ||
1878 | } | ||
1879 | |||
1880 | void pci_clear_mwi(struct pci_dev *dev) | ||
1881 | { | ||
1882 | } | ||
1883 | |||
1884 | #else | ||
1885 | |||
1886 | #ifndef PCI_CACHE_LINE_BYTES | ||
1887 | #define PCI_CACHE_LINE_BYTES L1_CACHE_BYTES | ||
1888 | #endif | ||
1889 | |||
1890 | /* This can be overridden by arch code. */ | ||
1891 | /* Don't forget this is measured in 32-bit words, not bytes */ | ||
1892 | u8 pci_cache_line_size = PCI_CACHE_LINE_BYTES / 4; | ||
1893 | |||
1894 | /** | 1929 | /** |
1895 | * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed | 1930 | * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed |
1896 | * @dev: the PCI device for which MWI is to be enabled | 1931 | * @dev: the PCI device for which MWI is to be enabled |
@@ -1901,13 +1936,12 @@ u8 pci_cache_line_size = PCI_CACHE_LINE_BYTES / 4; | |||
1901 | * | 1936 | * |
1902 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. | 1937 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. |
1903 | */ | 1938 | */ |
1904 | static int | 1939 | int pci_set_cacheline_size(struct pci_dev *dev) |
1905 | pci_set_cacheline_size(struct pci_dev *dev) | ||
1906 | { | 1940 | { |
1907 | u8 cacheline_size; | 1941 | u8 cacheline_size; |
1908 | 1942 | ||
1909 | if (!pci_cache_line_size) | 1943 | if (!pci_cache_line_size) |
1910 | return -EINVAL; /* The system doesn't support MWI. */ | 1944 | return -EINVAL; |
1911 | 1945 | ||
1912 | /* Validate current setting: the PCI_CACHE_LINE_SIZE must be | 1946 | /* Validate current setting: the PCI_CACHE_LINE_SIZE must be |
1913 | equal to or multiple of the right value. */ | 1947 | equal to or multiple of the right value. */ |
@@ -1928,6 +1962,24 @@ pci_set_cacheline_size(struct pci_dev *dev) | |||
1928 | 1962 | ||
1929 | return -EINVAL; | 1963 | return -EINVAL; |
1930 | } | 1964 | } |
1965 | EXPORT_SYMBOL_GPL(pci_set_cacheline_size); | ||
1966 | |||
1967 | #ifdef PCI_DISABLE_MWI | ||
1968 | int pci_set_mwi(struct pci_dev *dev) | ||
1969 | { | ||
1970 | return 0; | ||
1971 | } | ||
1972 | |||
1973 | int pci_try_set_mwi(struct pci_dev *dev) | ||
1974 | { | ||
1975 | return 0; | ||
1976 | } | ||
1977 | |||
1978 | void pci_clear_mwi(struct pci_dev *dev) | ||
1979 | { | ||
1980 | } | ||
1981 | |||
1982 | #else | ||
1931 | 1983 | ||
1932 | /** | 1984 | /** |
1933 | * pci_set_mwi - enables memory-write-invalidate PCI transaction | 1985 | * pci_set_mwi - enables memory-write-invalidate PCI transaction |
@@ -2062,6 +2114,7 @@ pci_set_dma_mask(struct pci_dev *dev, u64 mask) | |||
2062 | return -EIO; | 2114 | return -EIO; |
2063 | 2115 | ||
2064 | dev->dma_mask = mask; | 2116 | dev->dma_mask = mask; |
2117 | dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask)); | ||
2065 | 2118 | ||
2066 | return 0; | 2119 | return 0; |
2067 | } | 2120 | } |
@@ -2073,6 +2126,7 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) | |||
2073 | return -EIO; | 2126 | return -EIO; |
2074 | 2127 | ||
2075 | dev->dev.coherent_dma_mask = mask; | 2128 | dev->dev.coherent_dma_mask = mask; |
2129 | dev_dbg(&dev->dev, "using %dbit consistent DMA mask\n", fls64(mask)); | ||
2076 | 2130 | ||
2077 | return 0; | 2131 | return 0; |
2078 | } | 2132 | } |
@@ -2099,9 +2153,9 @@ static int pcie_flr(struct pci_dev *dev, int probe) | |||
2099 | int i; | 2153 | int i; |
2100 | int pos; | 2154 | int pos; |
2101 | u32 cap; | 2155 | u32 cap; |
2102 | u16 status; | 2156 | u16 status, control; |
2103 | 2157 | ||
2104 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 2158 | pos = pci_pcie_cap(dev); |
2105 | if (!pos) | 2159 | if (!pos) |
2106 | return -ENOTTY; | 2160 | return -ENOTTY; |
2107 | 2161 | ||
@@ -2126,8 +2180,10 @@ static int pcie_flr(struct pci_dev *dev, int probe) | |||
2126 | "proceeding with reset anyway\n"); | 2180 | "proceeding with reset anyway\n"); |
2127 | 2181 | ||
2128 | clear: | 2182 | clear: |
2129 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, | 2183 | pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &control); |
2130 | PCI_EXP_DEVCTL_BCR_FLR); | 2184 | control |= PCI_EXP_DEVCTL_BCR_FLR; |
2185 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, control); | ||
2186 | |||
2131 | msleep(100); | 2187 | msleep(100); |
2132 | 2188 | ||
2133 | return 0; | 2189 | return 0; |
@@ -2450,7 +2506,7 @@ int pcie_get_readrq(struct pci_dev *dev) | |||
2450 | int ret, cap; | 2506 | int ret, cap; |
2451 | u16 ctl; | 2507 | u16 ctl; |
2452 | 2508 | ||
2453 | cap = pci_find_capability(dev, PCI_CAP_ID_EXP); | 2509 | cap = pci_pcie_cap(dev); |
2454 | if (!cap) | 2510 | if (!cap) |
2455 | return -EINVAL; | 2511 | return -EINVAL; |
2456 | 2512 | ||
@@ -2480,7 +2536,7 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) | |||
2480 | 2536 | ||
2481 | v = (ffs(rq) - 8) << 12; | 2537 | v = (ffs(rq) - 8) << 12; |
2482 | 2538 | ||
2483 | cap = pci_find_capability(dev, PCI_CAP_ID_EXP); | 2539 | cap = pci_pcie_cap(dev); |
2484 | if (!cap) | 2540 | if (!cap) |
2485 | goto out; | 2541 | goto out; |
2486 | 2542 | ||
@@ -2540,7 +2596,7 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) | |||
2540 | return reg; | 2596 | return reg; |
2541 | } | 2597 | } |
2542 | 2598 | ||
2543 | dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno); | 2599 | dev_err(&dev->dev, "BAR %d: invalid resource\n", resno); |
2544 | return 0; | 2600 | return 0; |
2545 | } | 2601 | } |
2546 | 2602 | ||
@@ -2590,7 +2646,7 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode, | |||
2590 | 2646 | ||
2591 | #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE | 2647 | #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE |
2592 | static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; | 2648 | static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; |
2593 | spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED; | 2649 | static DEFINE_SPINLOCK(resource_alignment_lock); |
2594 | 2650 | ||
2595 | /** | 2651 | /** |
2596 | * pci_specified_resource_alignment - get resource alignment specified by user. | 2652 | * pci_specified_resource_alignment - get resource alignment specified by user. |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d92d1954a2fb..33ed8e0aba1e 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -311,4 +311,6 @@ static inline int pci_resource_alignment(struct pci_dev *dev, | |||
311 | return resource_alignment(res); | 311 | return resource_alignment(res); |
312 | } | 312 | } |
313 | 313 | ||
314 | extern void pci_enable_acs(struct pci_dev *dev); | ||
315 | |||
314 | #endif /* DRIVERS_PCI_H */ | 316 | #endif /* DRIVERS_PCI_H */ |
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 62d15f652bb6..7fcd5331b14c 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
25 | #include <linux/uaccess.h> | 25 | #include <linux/uaccess.h> |
26 | #include <linux/stddef.h> | ||
26 | #include "aerdrv.h" | 27 | #include "aerdrv.h" |
27 | 28 | ||
28 | struct aer_error_inj { | 29 | struct aer_error_inj { |
@@ -35,10 +36,12 @@ struct aer_error_inj { | |||
35 | u32 header_log1; | 36 | u32 header_log1; |
36 | u32 header_log2; | 37 | u32 header_log2; |
37 | u32 header_log3; | 38 | u32 header_log3; |
39 | u16 domain; | ||
38 | }; | 40 | }; |
39 | 41 | ||
40 | struct aer_error { | 42 | struct aer_error { |
41 | struct list_head list; | 43 | struct list_head list; |
44 | u16 domain; | ||
42 | unsigned int bus; | 45 | unsigned int bus; |
43 | unsigned int devfn; | 46 | unsigned int devfn; |
44 | int pos_cap_err; | 47 | int pos_cap_err; |
@@ -66,22 +69,27 @@ static LIST_HEAD(pci_bus_ops_list); | |||
66 | /* Protect einjected and pci_bus_ops_list */ | 69 | /* Protect einjected and pci_bus_ops_list */ |
67 | static DEFINE_SPINLOCK(inject_lock); | 70 | static DEFINE_SPINLOCK(inject_lock); |
68 | 71 | ||
69 | static void aer_error_init(struct aer_error *err, unsigned int bus, | 72 | static void aer_error_init(struct aer_error *err, u16 domain, |
70 | unsigned int devfn, int pos_cap_err) | 73 | unsigned int bus, unsigned int devfn, |
74 | int pos_cap_err) | ||
71 | { | 75 | { |
72 | INIT_LIST_HEAD(&err->list); | 76 | INIT_LIST_HEAD(&err->list); |
77 | err->domain = domain; | ||
73 | err->bus = bus; | 78 | err->bus = bus; |
74 | err->devfn = devfn; | 79 | err->devfn = devfn; |
75 | err->pos_cap_err = pos_cap_err; | 80 | err->pos_cap_err = pos_cap_err; |
76 | } | 81 | } |
77 | 82 | ||
78 | /* inject_lock must be held before calling */ | 83 | /* inject_lock must be held before calling */ |
79 | static struct aer_error *__find_aer_error(unsigned int bus, unsigned int devfn) | 84 | static struct aer_error *__find_aer_error(u16 domain, unsigned int bus, |
85 | unsigned int devfn) | ||
80 | { | 86 | { |
81 | struct aer_error *err; | 87 | struct aer_error *err; |
82 | 88 | ||
83 | list_for_each_entry(err, &einjected, list) { | 89 | list_for_each_entry(err, &einjected, list) { |
84 | if (bus == err->bus && devfn == err->devfn) | 90 | if (domain == err->domain && |
91 | bus == err->bus && | ||
92 | devfn == err->devfn) | ||
85 | return err; | 93 | return err; |
86 | } | 94 | } |
87 | return NULL; | 95 | return NULL; |
@@ -90,7 +98,10 @@ static struct aer_error *__find_aer_error(unsigned int bus, unsigned int devfn) | |||
90 | /* inject_lock must be held before calling */ | 98 | /* inject_lock must be held before calling */ |
91 | static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev) | 99 | static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev) |
92 | { | 100 | { |
93 | return __find_aer_error(dev->bus->number, dev->devfn); | 101 | int domain = pci_domain_nr(dev->bus); |
102 | if (domain < 0) | ||
103 | return NULL; | ||
104 | return __find_aer_error((u16)domain, dev->bus->number, dev->devfn); | ||
94 | } | 105 | } |
95 | 106 | ||
96 | /* inject_lock must be held before calling */ | 107 | /* inject_lock must be held before calling */ |
@@ -172,11 +183,15 @@ static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where, | |||
172 | struct aer_error *err; | 183 | struct aer_error *err; |
173 | unsigned long flags; | 184 | unsigned long flags; |
174 | struct pci_ops *ops; | 185 | struct pci_ops *ops; |
186 | int domain; | ||
175 | 187 | ||
176 | spin_lock_irqsave(&inject_lock, flags); | 188 | spin_lock_irqsave(&inject_lock, flags); |
177 | if (size != sizeof(u32)) | 189 | if (size != sizeof(u32)) |
178 | goto out; | 190 | goto out; |
179 | err = __find_aer_error(bus->number, devfn); | 191 | domain = pci_domain_nr(bus); |
192 | if (domain < 0) | ||
193 | goto out; | ||
194 | err = __find_aer_error((u16)domain, bus->number, devfn); | ||
180 | if (!err) | 195 | if (!err) |
181 | goto out; | 196 | goto out; |
182 | 197 | ||
@@ -200,11 +215,15 @@ int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, int size, | |||
200 | unsigned long flags; | 215 | unsigned long flags; |
201 | int rw1cs; | 216 | int rw1cs; |
202 | struct pci_ops *ops; | 217 | struct pci_ops *ops; |
218 | int domain; | ||
203 | 219 | ||
204 | spin_lock_irqsave(&inject_lock, flags); | 220 | spin_lock_irqsave(&inject_lock, flags); |
205 | if (size != sizeof(u32)) | 221 | if (size != sizeof(u32)) |
206 | goto out; | 222 | goto out; |
207 | err = __find_aer_error(bus->number, devfn); | 223 | domain = pci_domain_nr(bus); |
224 | if (domain < 0) | ||
225 | goto out; | ||
226 | err = __find_aer_error((u16)domain, bus->number, devfn); | ||
208 | if (!err) | 227 | if (!err) |
209 | goto out; | 228 | goto out; |
210 | 229 | ||
@@ -262,7 +281,7 @@ out: | |||
262 | static struct pci_dev *pcie_find_root_port(struct pci_dev *dev) | 281 | static struct pci_dev *pcie_find_root_port(struct pci_dev *dev) |
263 | { | 282 | { |
264 | while (1) { | 283 | while (1) { |
265 | if (!dev->is_pcie) | 284 | if (!pci_is_pcie(dev)) |
266 | break; | 285 | break; |
267 | if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) | 286 | if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) |
268 | return dev; | 287 | return dev; |
@@ -305,25 +324,25 @@ static int aer_inject(struct aer_error_inj *einj) | |||
305 | u32 sever; | 324 | u32 sever; |
306 | int ret = 0; | 325 | int ret = 0; |
307 | 326 | ||
308 | dev = pci_get_bus_and_slot(einj->bus, devfn); | 327 | dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); |
309 | if (!dev) | 328 | if (!dev) |
310 | return -EINVAL; | 329 | return -ENODEV; |
311 | rpdev = pcie_find_root_port(dev); | 330 | rpdev = pcie_find_root_port(dev); |
312 | if (!rpdev) { | 331 | if (!rpdev) { |
313 | ret = -EINVAL; | 332 | ret = -ENOTTY; |
314 | goto out_put; | 333 | goto out_put; |
315 | } | 334 | } |
316 | 335 | ||
317 | pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 336 | pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
318 | if (!pos_cap_err) { | 337 | if (!pos_cap_err) { |
319 | ret = -EIO; | 338 | ret = -ENOTTY; |
320 | goto out_put; | 339 | goto out_put; |
321 | } | 340 | } |
322 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); | 341 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); |
323 | 342 | ||
324 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); | 343 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); |
325 | if (!rp_pos_cap_err) { | 344 | if (!rp_pos_cap_err) { |
326 | ret = -EIO; | 345 | ret = -ENOTTY; |
327 | goto out_put; | 346 | goto out_put; |
328 | } | 347 | } |
329 | 348 | ||
@@ -344,7 +363,8 @@ static int aer_inject(struct aer_error_inj *einj) | |||
344 | if (!err) { | 363 | if (!err) { |
345 | err = err_alloc; | 364 | err = err_alloc; |
346 | err_alloc = NULL; | 365 | err_alloc = NULL; |
347 | aer_error_init(err, einj->bus, devfn, pos_cap_err); | 366 | aer_error_init(err, einj->domain, einj->bus, devfn, |
367 | pos_cap_err); | ||
348 | list_add(&err->list, &einjected); | 368 | list_add(&err->list, &einjected); |
349 | } | 369 | } |
350 | err->uncor_status |= einj->uncor_status; | 370 | err->uncor_status |= einj->uncor_status; |
@@ -358,7 +378,8 @@ static int aer_inject(struct aer_error_inj *einj) | |||
358 | if (!rperr) { | 378 | if (!rperr) { |
359 | rperr = rperr_alloc; | 379 | rperr = rperr_alloc; |
360 | rperr_alloc = NULL; | 380 | rperr_alloc = NULL; |
361 | aer_error_init(rperr, rpdev->bus->number, rpdev->devfn, | 381 | aer_error_init(rperr, pci_domain_nr(rpdev->bus), |
382 | rpdev->bus->number, rpdev->devfn, | ||
362 | rp_pos_cap_err); | 383 | rp_pos_cap_err); |
363 | list_add(&rperr->list, &einjected); | 384 | list_add(&rperr->list, &einjected); |
364 | } | 385 | } |
@@ -411,10 +432,11 @@ static ssize_t aer_inject_write(struct file *filp, const char __user *ubuf, | |||
411 | 432 | ||
412 | if (!capable(CAP_SYS_ADMIN)) | 433 | if (!capable(CAP_SYS_ADMIN)) |
413 | return -EPERM; | 434 | return -EPERM; |
414 | 435 | if (usize < offsetof(struct aer_error_inj, domain) || | |
415 | if (usize != sizeof(struct aer_error_inj)) | 436 | usize > sizeof(einj)) |
416 | return -EINVAL; | 437 | return -EINVAL; |
417 | 438 | ||
439 | memset(&einj, 0, sizeof(einj)); | ||
418 | if (copy_from_user(&einj, ubuf, usize)) | 440 | if (copy_from_user(&einj, ubuf, usize)) |
419 | return -EFAULT; | 441 | return -EFAULT; |
420 | 442 | ||
@@ -452,7 +474,7 @@ static void __exit aer_inject_exit(void) | |||
452 | } | 474 | } |
453 | 475 | ||
454 | spin_lock_irqsave(&inject_lock, flags); | 476 | spin_lock_irqsave(&inject_lock, flags); |
455 | list_for_each_entry_safe(err, err_next, &pci_bus_ops_list, list) { | 477 | list_for_each_entry_safe(err, err_next, &einjected, list) { |
456 | list_del(&err->list); | 478 | list_del(&err->list); |
457 | kfree(err); | 479 | kfree(err); |
458 | } | 480 | } |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 40c3cc5d1caf..97a345927b55 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -53,7 +53,7 @@ static struct pci_error_handlers aer_error_handlers = { | |||
53 | 53 | ||
54 | static struct pcie_port_service_driver aerdriver = { | 54 | static struct pcie_port_service_driver aerdriver = { |
55 | .name = "aer", | 55 | .name = "aer", |
56 | .port_type = PCIE_RC_PORT, | 56 | .port_type = PCI_EXP_TYPE_ROOT_PORT, |
57 | .service = PCIE_PORT_SERVICE_AER, | 57 | .service = PCIE_PORT_SERVICE_AER, |
58 | 58 | ||
59 | .probe = aer_probe, | 59 | .probe = aer_probe, |
@@ -295,7 +295,7 @@ static void aer_error_resume(struct pci_dev *dev) | |||
295 | u16 reg16; | 295 | u16 reg16; |
296 | 296 | ||
297 | /* Clean up Root device status */ | 297 | /* Clean up Root device status */ |
298 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 298 | pos = pci_pcie_cap(dev); |
299 | pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, ®16); | 299 | pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, ®16); |
300 | pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); | 300 | pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); |
301 | 301 | ||
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 9f5ccbeb4fa5..ae672ca80333 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -35,11 +35,14 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev) | |||
35 | u16 reg16 = 0; | 35 | u16 reg16 = 0; |
36 | int pos; | 36 | int pos; |
37 | 37 | ||
38 | if (dev->aer_firmware_first) | ||
39 | return -EIO; | ||
40 | |||
38 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 41 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
39 | if (!pos) | 42 | if (!pos) |
40 | return -EIO; | 43 | return -EIO; |
41 | 44 | ||
42 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 45 | pos = pci_pcie_cap(dev); |
43 | if (!pos) | 46 | if (!pos) |
44 | return -EIO; | 47 | return -EIO; |
45 | 48 | ||
@@ -60,7 +63,10 @@ int pci_disable_pcie_error_reporting(struct pci_dev *dev) | |||
60 | u16 reg16 = 0; | 63 | u16 reg16 = 0; |
61 | int pos; | 64 | int pos; |
62 | 65 | ||
63 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 66 | if (dev->aer_firmware_first) |
67 | return -EIO; | ||
68 | |||
69 | pos = pci_pcie_cap(dev); | ||
64 | if (!pos) | 70 | if (!pos) |
65 | return -EIO; | 71 | return -EIO; |
66 | 72 | ||
@@ -78,48 +84,27 @@ EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); | |||
78 | int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) | 84 | int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) |
79 | { | 85 | { |
80 | int pos; | 86 | int pos; |
81 | u32 status, mask; | 87 | u32 status; |
82 | 88 | ||
83 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 89 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
84 | if (!pos) | 90 | if (!pos) |
85 | return -EIO; | 91 | return -EIO; |
86 | 92 | ||
87 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); | 93 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); |
88 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); | 94 | if (status) |
89 | if (dev->error_state == pci_channel_io_normal) | 95 | pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); |
90 | status &= ~mask; /* Clear corresponding nonfatal bits */ | ||
91 | else | ||
92 | status &= mask; /* Clear corresponding fatal bits */ | ||
93 | pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); | ||
94 | 96 | ||
95 | return 0; | 97 | return 0; |
96 | } | 98 | } |
97 | EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); | 99 | EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); |
98 | 100 | ||
99 | #if 0 | ||
100 | int pci_cleanup_aer_correct_error_status(struct pci_dev *dev) | ||
101 | { | ||
102 | int pos; | ||
103 | u32 status; | ||
104 | |||
105 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
106 | if (!pos) | ||
107 | return -EIO; | ||
108 | |||
109 | pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status); | ||
110 | pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, status); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | #endif /* 0 */ | ||
115 | |||
116 | static int set_device_error_reporting(struct pci_dev *dev, void *data) | 101 | static int set_device_error_reporting(struct pci_dev *dev, void *data) |
117 | { | 102 | { |
118 | bool enable = *((bool *)data); | 103 | bool enable = *((bool *)data); |
119 | 104 | ||
120 | if (dev->pcie_type == PCIE_RC_PORT || | 105 | if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) || |
121 | dev->pcie_type == PCIE_SW_UPSTREAM_PORT || | 106 | (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) || |
122 | dev->pcie_type == PCIE_SW_DOWNSTREAM_PORT) { | 107 | (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) { |
123 | if (enable) | 108 | if (enable) |
124 | pci_enable_pcie_error_reporting(dev); | 109 | pci_enable_pcie_error_reporting(dev); |
125 | else | 110 | else |
@@ -218,7 +203,7 @@ static int find_device_iter(struct pci_dev *dev, void *data) | |||
218 | */ | 203 | */ |
219 | if (atomic_read(&dev->enable_cnt) == 0) | 204 | if (atomic_read(&dev->enable_cnt) == 0) |
220 | return 0; | 205 | return 0; |
221 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 206 | pos = pci_pcie_cap(dev); |
222 | if (!pos) | 207 | if (!pos) |
223 | return 0; | 208 | return 0; |
224 | /* Check if AER is enabled */ | 209 | /* Check if AER is enabled */ |
@@ -431,10 +416,9 @@ static int find_aer_service_iter(struct device *device, void *data) | |||
431 | result = (struct find_aer_service_data *) data; | 416 | result = (struct find_aer_service_data *) data; |
432 | 417 | ||
433 | if (device->bus == &pcie_port_bus_type) { | 418 | if (device->bus == &pcie_port_bus_type) { |
434 | struct pcie_port_data *port_data; | 419 | struct pcie_device *pcie = to_pcie_device(device); |
435 | 420 | ||
436 | port_data = pci_get_drvdata(to_pcie_device(device)->port); | 421 | if (pcie->port->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) |
437 | if (port_data->port_type == PCIE_SW_DOWNSTREAM_PORT) | ||
438 | result->is_downstream = 1; | 422 | result->is_downstream = 1; |
439 | 423 | ||
440 | driver = device->driver; | 424 | driver = device->driver; |
@@ -612,7 +596,7 @@ void aer_enable_rootport(struct aer_rpc *rpc) | |||
612 | u16 reg16; | 596 | u16 reg16; |
613 | u32 reg32; | 597 | u32 reg32; |
614 | 598 | ||
615 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 599 | pos = pci_pcie_cap(pdev); |
616 | /* Clear PCIE Capability's Device Status */ | 600 | /* Clear PCIE Capability's Device Status */ |
617 | pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); | 601 | pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); |
618 | pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); | 602 | pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); |
@@ -874,8 +858,22 @@ void aer_delete_rootport(struct aer_rpc *rpc) | |||
874 | */ | 858 | */ |
875 | int aer_init(struct pcie_device *dev) | 859 | int aer_init(struct pcie_device *dev) |
876 | { | 860 | { |
877 | if (aer_osc_setup(dev) && !forceload) | 861 | if (dev->port->aer_firmware_first) { |
878 | return -ENXIO; | 862 | dev_printk(KERN_DEBUG, &dev->device, |
863 | "PCIe errors handled by platform firmware.\n"); | ||
864 | goto out; | ||
865 | } | ||
866 | |||
867 | if (aer_osc_setup(dev)) | ||
868 | goto out; | ||
879 | 869 | ||
880 | return 0; | 870 | return 0; |
871 | out: | ||
872 | if (forceload) { | ||
873 | dev_printk(KERN_DEBUG, &dev->device, | ||
874 | "aerdrv forceload requested.\n"); | ||
875 | dev->port->aer_firmware_first = 0; | ||
876 | return 0; | ||
877 | } | ||
878 | return -ENXIO; | ||
881 | } | 879 | } |
diff --git a/drivers/pci/pcie/aer/ecrc.c b/drivers/pci/pcie/aer/ecrc.c index a928d8ab6bda..a2747a663bc9 100644 --- a/drivers/pci/pcie/aer/ecrc.c +++ b/drivers/pci/pcie/aer/ecrc.c | |||
@@ -51,7 +51,7 @@ static int enable_ecrc_checking(struct pci_dev *dev) | |||
51 | int pos; | 51 | int pos; |
52 | u32 reg32; | 52 | u32 reg32; |
53 | 53 | ||
54 | if (!dev->is_pcie) | 54 | if (!pci_is_pcie(dev)) |
55 | return -ENODEV; | 55 | return -ENODEV; |
56 | 56 | ||
57 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 57 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
@@ -79,7 +79,7 @@ static int disable_ecrc_checking(struct pci_dev *dev) | |||
79 | int pos; | 79 | int pos; |
80 | u32 reg32; | 80 | u32 reg32; |
81 | 81 | ||
82 | if (!dev->is_pcie) | 82 | if (!pci_is_pcie(dev)) |
83 | return -ENODEV; | 83 | return -ENODEV; |
84 | 84 | ||
85 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 85 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 5b7056cec00c..5a01fc7fbf05 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -122,7 +122,7 @@ static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable) | |||
122 | struct pci_bus *linkbus = link->pdev->subordinate; | 122 | struct pci_bus *linkbus = link->pdev->subordinate; |
123 | 123 | ||
124 | list_for_each_entry(child, &linkbus->devices, bus_list) { | 124 | list_for_each_entry(child, &linkbus->devices, bus_list) { |
125 | pos = pci_find_capability(child, PCI_CAP_ID_EXP); | 125 | pos = pci_pcie_cap(child); |
126 | if (!pos) | 126 | if (!pos) |
127 | return; | 127 | return; |
128 | pci_read_config_word(child, pos + PCI_EXP_LNKCTL, ®16); | 128 | pci_read_config_word(child, pos + PCI_EXP_LNKCTL, ®16); |
@@ -156,7 +156,7 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) | |||
156 | 156 | ||
157 | /* All functions should have the same cap and state, take the worst */ | 157 | /* All functions should have the same cap and state, take the worst */ |
158 | list_for_each_entry(child, &linkbus->devices, bus_list) { | 158 | list_for_each_entry(child, &linkbus->devices, bus_list) { |
159 | pos = pci_find_capability(child, PCI_CAP_ID_EXP); | 159 | pos = pci_pcie_cap(child); |
160 | if (!pos) | 160 | if (!pos) |
161 | return; | 161 | return; |
162 | pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, ®32); | 162 | pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, ®32); |
@@ -191,23 +191,23 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) | |||
191 | * Configuration, so just check one function | 191 | * Configuration, so just check one function |
192 | */ | 192 | */ |
193 | child = list_entry(linkbus->devices.next, struct pci_dev, bus_list); | 193 | child = list_entry(linkbus->devices.next, struct pci_dev, bus_list); |
194 | BUG_ON(!child->is_pcie); | 194 | BUG_ON(!pci_is_pcie(child)); |
195 | 195 | ||
196 | /* Check downstream component if bit Slot Clock Configuration is 1 */ | 196 | /* Check downstream component if bit Slot Clock Configuration is 1 */ |
197 | cpos = pci_find_capability(child, PCI_CAP_ID_EXP); | 197 | cpos = pci_pcie_cap(child); |
198 | pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, ®16); | 198 | pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, ®16); |
199 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) | 199 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) |
200 | same_clock = 0; | 200 | same_clock = 0; |
201 | 201 | ||
202 | /* Check upstream component if bit Slot Clock Configuration is 1 */ | 202 | /* Check upstream component if bit Slot Clock Configuration is 1 */ |
203 | ppos = pci_find_capability(parent, PCI_CAP_ID_EXP); | 203 | ppos = pci_pcie_cap(parent); |
204 | pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, ®16); | 204 | pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, ®16); |
205 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) | 205 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) |
206 | same_clock = 0; | 206 | same_clock = 0; |
207 | 207 | ||
208 | /* Configure downstream component, all functions */ | 208 | /* Configure downstream component, all functions */ |
209 | list_for_each_entry(child, &linkbus->devices, bus_list) { | 209 | list_for_each_entry(child, &linkbus->devices, bus_list) { |
210 | cpos = pci_find_capability(child, PCI_CAP_ID_EXP); | 210 | cpos = pci_pcie_cap(child); |
211 | pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, ®16); | 211 | pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, ®16); |
212 | child_reg[PCI_FUNC(child->devfn)] = reg16; | 212 | child_reg[PCI_FUNC(child->devfn)] = reg16; |
213 | if (same_clock) | 213 | if (same_clock) |
@@ -247,7 +247,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) | |||
247 | dev_printk(KERN_ERR, &parent->dev, | 247 | dev_printk(KERN_ERR, &parent->dev, |
248 | "ASPM: Could not configure common clock\n"); | 248 | "ASPM: Could not configure common clock\n"); |
249 | list_for_each_entry(child, &linkbus->devices, bus_list) { | 249 | list_for_each_entry(child, &linkbus->devices, bus_list) { |
250 | cpos = pci_find_capability(child, PCI_CAP_ID_EXP); | 250 | cpos = pci_pcie_cap(child); |
251 | pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, | 251 | pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, |
252 | child_reg[PCI_FUNC(child->devfn)]); | 252 | child_reg[PCI_FUNC(child->devfn)]); |
253 | } | 253 | } |
@@ -300,7 +300,7 @@ static void pcie_get_aspm_reg(struct pci_dev *pdev, | |||
300 | u16 reg16; | 300 | u16 reg16; |
301 | u32 reg32; | 301 | u32 reg32; |
302 | 302 | ||
303 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 303 | pos = pci_pcie_cap(pdev); |
304 | pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, ®32); | 304 | pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, ®32); |
305 | info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10; | 305 | info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10; |
306 | info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12; | 306 | info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12; |
@@ -420,7 +420,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) | |||
420 | child->pcie_type != PCI_EXP_TYPE_LEG_END) | 420 | child->pcie_type != PCI_EXP_TYPE_LEG_END) |
421 | continue; | 421 | continue; |
422 | 422 | ||
423 | pos = pci_find_capability(child, PCI_CAP_ID_EXP); | 423 | pos = pci_pcie_cap(child); |
424 | pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, ®32); | 424 | pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, ®32); |
425 | /* Calculate endpoint L0s acceptable latency */ | 425 | /* Calculate endpoint L0s acceptable latency */ |
426 | encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; | 426 | encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; |
@@ -436,7 +436,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) | |||
436 | static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val) | 436 | static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val) |
437 | { | 437 | { |
438 | u16 reg16; | 438 | u16 reg16; |
439 | int pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 439 | int pos = pci_pcie_cap(pdev); |
440 | 440 | ||
441 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); | 441 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); |
442 | reg16 &= ~0x3; | 442 | reg16 &= ~0x3; |
@@ -503,7 +503,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) | |||
503 | * very strange. Disable ASPM for the whole slot | 503 | * very strange. Disable ASPM for the whole slot |
504 | */ | 504 | */ |
505 | list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { | 505 | list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { |
506 | pos = pci_find_capability(child, PCI_CAP_ID_EXP); | 506 | pos = pci_pcie_cap(child); |
507 | if (!pos) | 507 | if (!pos) |
508 | return -EINVAL; | 508 | return -EINVAL; |
509 | /* | 509 | /* |
@@ -563,7 +563,7 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) | |||
563 | struct pcie_link_state *link; | 563 | struct pcie_link_state *link; |
564 | int blacklist = !!pcie_aspm_sanity_check(pdev); | 564 | int blacklist = !!pcie_aspm_sanity_check(pdev); |
565 | 565 | ||
566 | if (aspm_disabled || !pdev->is_pcie || pdev->link_state) | 566 | if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state) |
567 | return; | 567 | return; |
568 | if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | 568 | if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && |
569 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | 569 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) |
@@ -629,7 +629,8 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) | |||
629 | struct pci_dev *parent = pdev->bus->self; | 629 | struct pci_dev *parent = pdev->bus->self; |
630 | struct pcie_link_state *link, *root, *parent_link; | 630 | struct pcie_link_state *link, *root, *parent_link; |
631 | 631 | ||
632 | if (aspm_disabled || !pdev->is_pcie || !parent || !parent->link_state) | 632 | if (aspm_disabled || !pci_is_pcie(pdev) || |
633 | !parent || !parent->link_state) | ||
633 | return; | 634 | return; |
634 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && | 635 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
635 | (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) | 636 | (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) |
@@ -670,7 +671,7 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev) | |||
670 | { | 671 | { |
671 | struct pcie_link_state *link = pdev->link_state; | 672 | struct pcie_link_state *link = pdev->link_state; |
672 | 673 | ||
673 | if (aspm_disabled || !pdev->is_pcie || !link) | 674 | if (aspm_disabled || !pci_is_pcie(pdev) || !link) |
674 | return; | 675 | return; |
675 | if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && | 676 | if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
676 | (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) | 677 | (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) |
@@ -696,7 +697,7 @@ void pci_disable_link_state(struct pci_dev *pdev, int state) | |||
696 | struct pci_dev *parent = pdev->bus->self; | 697 | struct pci_dev *parent = pdev->bus->self; |
697 | struct pcie_link_state *link; | 698 | struct pcie_link_state *link; |
698 | 699 | ||
699 | if (aspm_disabled || !pdev->is_pcie) | 700 | if (aspm_disabled || !pci_is_pcie(pdev)) |
700 | return; | 701 | return; |
701 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || | 702 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || |
702 | pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) | 703 | pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) |
@@ -841,8 +842,9 @@ void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) | |||
841 | { | 842 | { |
842 | struct pcie_link_state *link_state = pdev->link_state; | 843 | struct pcie_link_state *link_state = pdev->link_state; |
843 | 844 | ||
844 | if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | 845 | if (!pci_is_pcie(pdev) || |
845 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) | 846 | (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && |
847 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) | ||
846 | return; | 848 | return; |
847 | 849 | ||
848 | if (link_state->aspm_support) | 850 | if (link_state->aspm_support) |
@@ -857,8 +859,9 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) | |||
857 | { | 859 | { |
858 | struct pcie_link_state *link_state = pdev->link_state; | 860 | struct pcie_link_state *link_state = pdev->link_state; |
859 | 861 | ||
860 | if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | 862 | if (!pci_is_pcie(pdev) || |
861 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) | 863 | (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && |
864 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) | ||
862 | return; | 865 | return; |
863 | 866 | ||
864 | if (link_state->aspm_support) | 867 | if (link_state->aspm_support) |
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 17ad53868f9f..aaeb9d21cba5 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -11,31 +11,16 @@ | |||
11 | 11 | ||
12 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
13 | 13 | ||
14 | #if !defined(PCI_CAP_ID_PME) | 14 | #define PCIE_PORT_DEVICE_MAXSERVICES 4 |
15 | #define PCI_CAP_ID_PME 1 | ||
16 | #endif | ||
17 | |||
18 | #if !defined(PCI_CAP_ID_EXP) | ||
19 | #define PCI_CAP_ID_EXP 0x10 | ||
20 | #endif | ||
21 | |||
22 | #define PORT_TYPE_MASK 0xf | ||
23 | #define PORT_TO_SLOT_MASK 0x100 | ||
24 | #define SLOT_HP_CAPABLE_MASK 0x40 | ||
25 | #define PCIE_CAPABILITIES_REG 0x2 | ||
26 | #define PCIE_SLOT_CAPABILITIES_REG 0x14 | ||
27 | #define PCIE_PORT_DEVICE_MAXSERVICES 4 | ||
28 | #define PCIE_PORT_MSI_VECTOR_MASK 0x1f | ||
29 | /* | 15 | /* |
30 | * According to the PCI Express Base Specification 2.0, the indices of the MSI-X | 16 | * According to the PCI Express Base Specification 2.0, the indices of |
31 | * table entires used by port services must not exceed 31 | 17 | * the MSI-X table entires used by port services must not exceed 31 |
32 | */ | 18 | */ |
33 | #define PCIE_PORT_MAX_MSIX_ENTRIES 32 | 19 | #define PCIE_PORT_MAX_MSIX_ENTRIES 32 |
34 | 20 | ||
35 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) | 21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) |
36 | 22 | ||
37 | extern struct bus_type pcie_port_bus_type; | 23 | extern struct bus_type pcie_port_bus_type; |
38 | extern int pcie_port_device_probe(struct pci_dev *dev); | ||
39 | extern int pcie_port_device_register(struct pci_dev *dev); | 24 | extern int pcie_port_device_register(struct pci_dev *dev); |
40 | #ifdef CONFIG_PM | 25 | #ifdef CONFIG_PM |
41 | extern int pcie_port_device_suspend(struct device *dev); | 26 | extern int pcie_port_device_suspend(struct device *dev); |
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c index ef3a4eeaebb4..18bf90f748f6 100644 --- a/drivers/pci/pcie/portdrv_bus.c +++ b/drivers/pci/pcie/portdrv_bus.c | |||
@@ -26,7 +26,6 @@ EXPORT_SYMBOL_GPL(pcie_port_bus_type); | |||
26 | static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) | 26 | static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) |
27 | { | 27 | { |
28 | struct pcie_device *pciedev; | 28 | struct pcie_device *pciedev; |
29 | struct pcie_port_data *port_data; | ||
30 | struct pcie_port_service_driver *driver; | 29 | struct pcie_port_service_driver *driver; |
31 | 30 | ||
32 | if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type) | 31 | if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type) |
@@ -38,10 +37,8 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) | |||
38 | if (driver->service != pciedev->service) | 37 | if (driver->service != pciedev->service) |
39 | return 0; | 38 | return 0; |
40 | 39 | ||
41 | port_data = pci_get_drvdata(pciedev->port); | 40 | if ((driver->port_type != PCIE_ANY_PORT) && |
42 | 41 | (driver->port_type != pciedev->port->pcie_type)) | |
43 | if (driver->port_type != PCIE_ANY_PORT | ||
44 | && driver->port_type != port_data->port_type) | ||
45 | return 0; | 42 | return 0; |
46 | 43 | ||
47 | return 1; | 44 | return 1; |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 52f84fca9f7d..413262eb95b7 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -108,9 +108,9 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) | |||
108 | * the value in this field indicates which MSI-X Table entry is | 108 | * the value in this field indicates which MSI-X Table entry is |
109 | * used to generate the interrupt message." | 109 | * used to generate the interrupt message." |
110 | */ | 110 | */ |
111 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 111 | pos = pci_pcie_cap(dev); |
112 | pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, ®16); | 112 | pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); |
113 | entry = (reg16 >> 9) & PCIE_PORT_MSI_VECTOR_MASK; | 113 | entry = (reg16 & PCI_EXP_FLAGS_IRQ) >> 9; |
114 | if (entry >= nr_entries) | 114 | if (entry >= nr_entries) |
115 | goto Error; | 115 | goto Error; |
116 | 116 | ||
@@ -177,37 +177,40 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | /** | 179 | /** |
180 | * assign_interrupt_mode - choose interrupt mode for PCI Express port services | 180 | * init_service_irqs - initialize irqs for PCI Express port services |
181 | * (INTx, MSI-X, MSI) and set up vectors | ||
182 | * @dev: PCI Express port to handle | 181 | * @dev: PCI Express port to handle |
183 | * @vectors: Array of interrupt vectors to populate | 182 | * @irqs: Array of irqs to populate |
184 | * @mask: Bitmask of port capabilities returned by get_port_device_capability() | 183 | * @mask: Bitmask of port capabilities returned by get_port_device_capability() |
185 | * | 184 | * |
186 | * Return value: Interrupt mode associated with the port | 185 | * Return value: Interrupt mode associated with the port |
187 | */ | 186 | */ |
188 | static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask) | 187 | static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask) |
189 | { | 188 | { |
190 | int irq, interrupt_mode = PCIE_PORT_NO_IRQ; | 189 | int i, irq; |
191 | int i; | ||
192 | 190 | ||
193 | /* Try to use MSI-X if supported */ | 191 | /* Try to use MSI-X if supported */ |
194 | if (!pcie_port_enable_msix(dev, vectors, mask)) | 192 | if (!pcie_port_enable_msix(dev, irqs, mask)) |
195 | return PCIE_PORT_MSIX_MODE; | 193 | return 0; |
196 | |||
197 | /* We're not going to use MSI-X, so try MSI and fall back to INTx */ | 194 | /* We're not going to use MSI-X, so try MSI and fall back to INTx */ |
198 | if (!pci_enable_msi(dev)) | 195 | irq = -1; |
199 | interrupt_mode = PCIE_PORT_MSI_MODE; | 196 | if (!pci_enable_msi(dev) || dev->pin) |
200 | 197 | irq = dev->irq; | |
201 | if (interrupt_mode == PCIE_PORT_NO_IRQ && dev->pin) | ||
202 | interrupt_mode = PCIE_PORT_INTx_MODE; | ||
203 | 198 | ||
204 | irq = interrupt_mode != PCIE_PORT_NO_IRQ ? dev->irq : -1; | ||
205 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) | 199 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) |
206 | vectors[i] = irq; | 200 | irqs[i] = irq; |
201 | irqs[PCIE_PORT_SERVICE_VC_SHIFT] = -1; | ||
207 | 202 | ||
208 | vectors[PCIE_PORT_SERVICE_VC_SHIFT] = -1; | 203 | if (irq < 0) |
204 | return -ENODEV; | ||
205 | return 0; | ||
206 | } | ||
209 | 207 | ||
210 | return interrupt_mode; | 208 | static void cleanup_service_irqs(struct pci_dev *dev) |
209 | { | ||
210 | if (dev->msix_enabled) | ||
211 | pci_disable_msix(dev); | ||
212 | else if (dev->msi_enabled) | ||
213 | pci_disable_msi(dev); | ||
211 | } | 214 | } |
212 | 215 | ||
213 | /** | 216 | /** |
@@ -226,13 +229,12 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
226 | u16 reg16; | 229 | u16 reg16; |
227 | u32 reg32; | 230 | u32 reg32; |
228 | 231 | ||
229 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 232 | pos = pci_pcie_cap(dev); |
230 | pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, ®16); | 233 | pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); |
231 | /* Hot-Plug Capable */ | 234 | /* Hot-Plug Capable */ |
232 | if (reg16 & PORT_TO_SLOT_MASK) { | 235 | if (reg16 & PCI_EXP_FLAGS_SLOT) { |
233 | pci_read_config_dword(dev, | 236 | pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, ®32); |
234 | pos + PCIE_SLOT_CAPABILITIES_REG, ®32); | 237 | if (reg32 & PCI_EXP_SLTCAP_HPC) |
235 | if (reg32 & SLOT_HP_CAPABLE_MASK) | ||
236 | services |= PCIE_PORT_SERVICE_HP; | 238 | services |= PCIE_PORT_SERVICE_HP; |
237 | } | 239 | } |
238 | /* AER capable */ | 240 | /* AER capable */ |
@@ -241,80 +243,47 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
241 | /* VC support */ | 243 | /* VC support */ |
242 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) | 244 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) |
243 | services |= PCIE_PORT_SERVICE_VC; | 245 | services |= PCIE_PORT_SERVICE_VC; |
246 | /* Root ports are capable of generating PME too */ | ||
247 | if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) | ||
248 | services |= PCIE_PORT_SERVICE_PME; | ||
244 | 249 | ||
245 | return services; | 250 | return services; |
246 | } | 251 | } |
247 | 252 | ||
248 | /** | 253 | /** |
249 | * pcie_device_init - initialize PCI Express port service device | 254 | * pcie_device_init - allocate and initialize PCI Express port service device |
250 | * @dev: Port service device to initialize | 255 | * @pdev: PCI Express port to associate the service device with |
251 | * @parent: PCI Express port to associate the service device with | 256 | * @service: Type of service to associate with the service device |
252 | * @port_type: Type of the port | ||
253 | * @service_type: Type of service to associate with the service device | ||
254 | * @irq: Interrupt vector to associate with the service device | 257 | * @irq: Interrupt vector to associate with the service device |
255 | */ | 258 | */ |
256 | static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, | 259 | static int pcie_device_init(struct pci_dev *pdev, int service, int irq) |
257 | int service_type, int irq) | ||
258 | { | 260 | { |
259 | struct pcie_port_data *port_data = pci_get_drvdata(parent); | 261 | int retval; |
262 | struct pcie_device *pcie; | ||
260 | struct device *device; | 263 | struct device *device; |
261 | int port_type = port_data->port_type; | ||
262 | 264 | ||
263 | dev->port = parent; | 265 | pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); |
264 | dev->irq = irq; | 266 | if (!pcie) |
265 | dev->service = service_type; | 267 | return -ENOMEM; |
268 | pcie->port = pdev; | ||
269 | pcie->irq = irq; | ||
270 | pcie->service = service; | ||
266 | 271 | ||
267 | /* Initialize generic device interface */ | 272 | /* Initialize generic device interface */ |
268 | device = &dev->device; | 273 | device = &pcie->device; |
269 | memset(device, 0, sizeof(struct device)); | ||
270 | device->bus = &pcie_port_bus_type; | 274 | device->bus = &pcie_port_bus_type; |
271 | device->driver = NULL; | ||
272 | dev_set_drvdata(device, NULL); | ||
273 | device->release = release_pcie_device; /* callback to free pcie dev */ | 275 | device->release = release_pcie_device; /* callback to free pcie dev */ |
274 | dev_set_name(device, "%s:pcie%02x", | 276 | dev_set_name(device, "%s:pcie%02x", |
275 | pci_name(parent), get_descriptor_id(port_type, service_type)); | 277 | pci_name(pdev), |
276 | device->parent = &parent->dev; | 278 | get_descriptor_id(pdev->pcie_type, service)); |
277 | } | 279 | device->parent = &pdev->dev; |
278 | 280 | ||
279 | /** | 281 | retval = device_register(device); |
280 | * alloc_pcie_device - allocate PCI Express port service device structure | 282 | if (retval) |
281 | * @parent: PCI Express port to associate the service device with | 283 | kfree(pcie); |
282 | * @port_type: Type of the port | 284 | else |
283 | * @service_type: Type of service to associate with the service device | 285 | get_device(device); |
284 | * @irq: Interrupt vector to associate with the service device | 286 | return retval; |
285 | */ | ||
286 | static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, | ||
287 | int service_type, int irq) | ||
288 | { | ||
289 | struct pcie_device *device; | ||
290 | |||
291 | device = kzalloc(sizeof(struct pcie_device), GFP_KERNEL); | ||
292 | if (!device) | ||
293 | return NULL; | ||
294 | |||
295 | pcie_device_init(parent, device, service_type, irq); | ||
296 | return device; | ||
297 | } | ||
298 | |||
299 | /** | ||
300 | * pcie_port_device_probe - check if device is a PCI Express port | ||
301 | * @dev: Device to check | ||
302 | */ | ||
303 | int pcie_port_device_probe(struct pci_dev *dev) | ||
304 | { | ||
305 | int pos, type; | ||
306 | u16 reg; | ||
307 | |||
308 | if (!(pos = pci_find_capability(dev, PCI_CAP_ID_EXP))) | ||
309 | return -ENODEV; | ||
310 | |||
311 | pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, ®); | ||
312 | type = (reg >> 4) & PORT_TYPE_MASK; | ||
313 | if ( type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT || | ||
314 | type == PCIE_SW_DOWNSTREAM_PORT ) | ||
315 | return 0; | ||
316 | |||
317 | return -ENODEV; | ||
318 | } | 287 | } |
319 | 288 | ||
320 | /** | 289 | /** |
@@ -326,77 +295,49 @@ int pcie_port_device_probe(struct pci_dev *dev) | |||
326 | */ | 295 | */ |
327 | int pcie_port_device_register(struct pci_dev *dev) | 296 | int pcie_port_device_register(struct pci_dev *dev) |
328 | { | 297 | { |
329 | struct pcie_port_data *port_data; | 298 | int status, capabilities, i, nr_service; |
330 | int status, capabilities, irq_mode, i, nr_serv; | 299 | int irqs[PCIE_PORT_DEVICE_MAXSERVICES]; |
331 | int vectors[PCIE_PORT_DEVICE_MAXSERVICES]; | ||
332 | u16 reg16; | ||
333 | |||
334 | port_data = kzalloc(sizeof(*port_data), GFP_KERNEL); | ||
335 | if (!port_data) | ||
336 | return -ENOMEM; | ||
337 | pci_set_drvdata(dev, port_data); | ||
338 | |||
339 | /* Get port type */ | ||
340 | pci_read_config_word(dev, | ||
341 | pci_find_capability(dev, PCI_CAP_ID_EXP) + | ||
342 | PCIE_CAPABILITIES_REG, ®16); | ||
343 | port_data->port_type = (reg16 >> 4) & PORT_TYPE_MASK; | ||
344 | 300 | ||
301 | /* Get and check PCI Express port services */ | ||
345 | capabilities = get_port_device_capability(dev); | 302 | capabilities = get_port_device_capability(dev); |
346 | /* Root ports are capable of generating PME too */ | 303 | if (!capabilities) |
347 | if (port_data->port_type == PCIE_RC_PORT) | 304 | return -ENODEV; |
348 | capabilities |= PCIE_PORT_SERVICE_PME; | ||
349 | |||
350 | irq_mode = assign_interrupt_mode(dev, vectors, capabilities); | ||
351 | if (irq_mode == PCIE_PORT_NO_IRQ) { | ||
352 | /* | ||
353 | * Don't use service devices that require interrupts if there is | ||
354 | * no way to generate them. | ||
355 | */ | ||
356 | if (!(capabilities & PCIE_PORT_SERVICE_VC)) { | ||
357 | status = -ENODEV; | ||
358 | goto Error; | ||
359 | } | ||
360 | capabilities = PCIE_PORT_SERVICE_VC; | ||
361 | } | ||
362 | port_data->port_irq_mode = irq_mode; | ||
363 | 305 | ||
306 | /* Enable PCI Express port device */ | ||
364 | status = pci_enable_device(dev); | 307 | status = pci_enable_device(dev); |
365 | if (status) | 308 | if (status) |
366 | goto Error; | 309 | return status; |
367 | pci_set_master(dev); | 310 | pci_set_master(dev); |
311 | /* | ||
312 | * Initialize service irqs. Don't use service devices that | ||
313 | * require interrupts if there is no way to generate them. | ||
314 | */ | ||
315 | status = init_service_irqs(dev, irqs, capabilities); | ||
316 | if (status) { | ||
317 | capabilities &= PCIE_PORT_SERVICE_VC; | ||
318 | if (!capabilities) | ||
319 | goto error_disable; | ||
320 | } | ||
368 | 321 | ||
369 | /* Allocate child services if any */ | 322 | /* Allocate child services if any */ |
370 | for (i = 0, nr_serv = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { | 323 | status = -ENODEV; |
371 | struct pcie_device *child; | 324 | nr_service = 0; |
325 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { | ||
372 | int service = 1 << i; | 326 | int service = 1 << i; |
373 | |||
374 | if (!(capabilities & service)) | 327 | if (!(capabilities & service)) |
375 | continue; | 328 | continue; |
376 | 329 | if (!pcie_device_init(dev, service, irqs[i])) | |
377 | child = alloc_pcie_device(dev, service, vectors[i]); | 330 | nr_service++; |
378 | if (!child) | ||
379 | continue; | ||
380 | |||
381 | status = device_register(&child->device); | ||
382 | if (status) { | ||
383 | kfree(child); | ||
384 | continue; | ||
385 | } | ||
386 | |||
387 | get_device(&child->device); | ||
388 | nr_serv++; | ||
389 | } | ||
390 | if (!nr_serv) { | ||
391 | pci_disable_device(dev); | ||
392 | status = -ENODEV; | ||
393 | goto Error; | ||
394 | } | 331 | } |
332 | if (!nr_service) | ||
333 | goto error_cleanup_irqs; | ||
395 | 334 | ||
396 | return 0; | 335 | return 0; |
397 | 336 | ||
398 | Error: | 337 | error_cleanup_irqs: |
399 | kfree(port_data); | 338 | cleanup_service_irqs(dev); |
339 | error_disable: | ||
340 | pci_disable_device(dev); | ||
400 | return status; | 341 | return status; |
401 | } | 342 | } |
402 | 343 | ||
@@ -464,21 +405,9 @@ static int remove_iter(struct device *dev, void *data) | |||
464 | */ | 405 | */ |
465 | void pcie_port_device_remove(struct pci_dev *dev) | 406 | void pcie_port_device_remove(struct pci_dev *dev) |
466 | { | 407 | { |
467 | struct pcie_port_data *port_data = pci_get_drvdata(dev); | ||
468 | |||
469 | device_for_each_child(&dev->dev, NULL, remove_iter); | 408 | device_for_each_child(&dev->dev, NULL, remove_iter); |
409 | cleanup_service_irqs(dev); | ||
470 | pci_disable_device(dev); | 410 | pci_disable_device(dev); |
471 | |||
472 | switch (port_data->port_irq_mode) { | ||
473 | case PCIE_PORT_MSIX_MODE: | ||
474 | pci_disable_msix(dev); | ||
475 | break; | ||
476 | case PCIE_PORT_MSI_MODE: | ||
477 | pci_disable_msi(dev); | ||
478 | break; | ||
479 | } | ||
480 | |||
481 | kfree(port_data); | ||
482 | } | 411 | } |
483 | 412 | ||
484 | /** | 413 | /** |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index f635e476d632..ce52ea34fee5 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -67,14 +67,16 @@ static struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
67 | * this port device. | 67 | * this port device. |
68 | * | 68 | * |
69 | */ | 69 | */ |
70 | static int __devinit pcie_portdrv_probe (struct pci_dev *dev, | 70 | static int __devinit pcie_portdrv_probe(struct pci_dev *dev, |
71 | const struct pci_device_id *id ) | 71 | const struct pci_device_id *id) |
72 | { | 72 | { |
73 | int status; | 73 | int status; |
74 | 74 | ||
75 | status = pcie_port_device_probe(dev); | 75 | if (!pci_is_pcie(dev) || |
76 | if (status) | 76 | ((dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
77 | return status; | 77 | (dev->pcie_type != PCI_EXP_TYPE_UPSTREAM) && |
78 | (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))) | ||
79 | return -ENODEV; | ||
78 | 80 | ||
79 | if (!dev->irq && dev->pin) { | 81 | if (!dev->irq && dev->pin) { |
80 | dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " | 82 | dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 8105e32117f6..98ffb2de22e9 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/cpumask.h> | 11 | #include <linux/cpumask.h> |
12 | #include <linux/pci-aspm.h> | 12 | #include <linux/pci-aspm.h> |
13 | #include <acpi/acpi_hest.h> | ||
13 | #include "pci.h" | 14 | #include "pci.h" |
14 | 15 | ||
15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | 16 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ |
@@ -163,12 +164,12 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
163 | { | 164 | { |
164 | u32 l, sz, mask; | 165 | u32 l, sz, mask; |
165 | 166 | ||
166 | mask = type ? ~PCI_ROM_ADDRESS_ENABLE : ~0; | 167 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; |
167 | 168 | ||
168 | res->name = pci_name(dev); | 169 | res->name = pci_name(dev); |
169 | 170 | ||
170 | pci_read_config_dword(dev, pos, &l); | 171 | pci_read_config_dword(dev, pos, &l); |
171 | pci_write_config_dword(dev, pos, mask); | 172 | pci_write_config_dword(dev, pos, l | mask); |
172 | pci_read_config_dword(dev, pos, &sz); | 173 | pci_read_config_dword(dev, pos, &sz); |
173 | pci_write_config_dword(dev, pos, l); | 174 | pci_write_config_dword(dev, pos, l); |
174 | 175 | ||
@@ -223,9 +224,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
223 | goto fail; | 224 | goto fail; |
224 | 225 | ||
225 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { | 226 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { |
226 | dev_err(&dev->dev, "can't handle 64-bit BAR\n"); | 227 | dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", |
228 | pos); | ||
227 | goto fail; | 229 | goto fail; |
228 | } else if ((sizeof(resource_size_t) < 8) && l) { | 230 | } |
231 | |||
232 | res->flags |= IORESOURCE_MEM_64; | ||
233 | if ((sizeof(resource_size_t) < 8) && l) { | ||
229 | /* Address above 32-bit boundary; disable the BAR */ | 234 | /* Address above 32-bit boundary; disable the BAR */ |
230 | pci_write_config_dword(dev, pos, 0); | 235 | pci_write_config_dword(dev, pos, 0); |
231 | pci_write_config_dword(dev, pos + 4, 0); | 236 | pci_write_config_dword(dev, pos + 4, 0); |
@@ -234,14 +239,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
234 | } else { | 239 | } else { |
235 | res->start = l64; | 240 | res->start = l64; |
236 | res->end = l64 + sz64; | 241 | res->end = l64 + sz64; |
237 | dev_printk(KERN_DEBUG, &dev->dev, | 242 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", |
238 | "reg %x %s: %pR\n", pos, | 243 | pos, res); |
239 | (res->flags & IORESOURCE_PREFETCH) ? | ||
240 | "64bit mmio pref" : "64bit mmio", | ||
241 | res); | ||
242 | } | 244 | } |
243 | |||
244 | res->flags |= IORESOURCE_MEM_64; | ||
245 | } else { | 245 | } else { |
246 | sz = pci_size(l, sz, mask); | 246 | sz = pci_size(l, sz, mask); |
247 | 247 | ||
@@ -251,11 +251,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
251 | res->start = l; | 251 | res->start = l; |
252 | res->end = l + sz; | 252 | res->end = l + sz; |
253 | 253 | ||
254 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x %s: %pR\n", pos, | 254 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); |
255 | (res->flags & IORESOURCE_IO) ? "io port" : | ||
256 | ((res->flags & IORESOURCE_PREFETCH) ? | ||
257 | "32bit mmio pref" : "32bit mmio"), | ||
258 | res); | ||
259 | } | 255 | } |
260 | 256 | ||
261 | out: | 257 | out: |
@@ -297,8 +293,11 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
297 | if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ | 293 | if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ |
298 | return; | 294 | return; |
299 | 295 | ||
296 | dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n", | ||
297 | child->secondary, child->subordinate, | ||
298 | dev->transparent ? " (subtractive decode)": ""); | ||
299 | |||
300 | if (dev->transparent) { | 300 | if (dev->transparent) { |
301 | dev_info(&dev->dev, "transparent bridge\n"); | ||
302 | for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) | 301 | for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) |
303 | child->resource[i] = child->parent->resource[i - 3]; | 302 | child->resource[i] = child->parent->resource[i - 3]; |
304 | } | 303 | } |
@@ -323,7 +322,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
323 | res->start = base; | 322 | res->start = base; |
324 | if (!res->end) | 323 | if (!res->end) |
325 | res->end = limit + 0xfff; | 324 | res->end = limit + 0xfff; |
326 | dev_printk(KERN_DEBUG, &dev->dev, "bridge io port: %pR\n", res); | 325 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
327 | } | 326 | } |
328 | 327 | ||
329 | res = child->resource[1]; | 328 | res = child->resource[1]; |
@@ -335,8 +334,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
335 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; | 334 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; |
336 | res->start = base; | 335 | res->start = base; |
337 | res->end = limit + 0xfffff; | 336 | res->end = limit + 0xfffff; |
338 | dev_printk(KERN_DEBUG, &dev->dev, "bridge 32bit mmio: %pR\n", | 337 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
339 | res); | ||
340 | } | 338 | } |
341 | 339 | ||
342 | res = child->resource[2]; | 340 | res = child->resource[2]; |
@@ -375,9 +373,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
375 | res->flags |= IORESOURCE_MEM_64; | 373 | res->flags |= IORESOURCE_MEM_64; |
376 | res->start = base; | 374 | res->start = base; |
377 | res->end = limit + 0xfffff; | 375 | res->end = limit + 0xfffff; |
378 | dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n", | 376 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
379 | (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32", | ||
380 | res); | ||
381 | } | 377 | } |
382 | } | 378 | } |
383 | 379 | ||
@@ -651,13 +647,14 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
651 | (child->number > bus->subordinate) || | 647 | (child->number > bus->subordinate) || |
652 | (child->number < bus->number) || | 648 | (child->number < bus->number) || |
653 | (child->subordinate < bus->number)) { | 649 | (child->subordinate < bus->number)) { |
654 | pr_debug("PCI: Bus #%02x (-#%02x) is %s " | 650 | dev_info(&child->dev, "[bus %02x-%02x] %s " |
655 | "hidden behind%s bridge #%02x (-#%02x)\n", | 651 | "hidden behind%s bridge %s [bus %02x-%02x]\n", |
656 | child->number, child->subordinate, | 652 | child->number, child->subordinate, |
657 | (bus->number > child->subordinate && | 653 | (bus->number > child->subordinate && |
658 | bus->subordinate < child->number) ? | 654 | bus->subordinate < child->number) ? |
659 | "wholly" : "partially", | 655 | "wholly" : "partially", |
660 | bus->self->transparent ? " transparent" : "", | 656 | bus->self->transparent ? " transparent" : "", |
657 | dev_name(&bus->dev), | ||
661 | bus->number, bus->subordinate); | 658 | bus->number, bus->subordinate); |
662 | } | 659 | } |
663 | bus = bus->parent; | 660 | bus = bus->parent; |
@@ -693,6 +690,7 @@ static void set_pcie_port_type(struct pci_dev *pdev) | |||
693 | if (!pos) | 690 | if (!pos) |
694 | return; | 691 | return; |
695 | pdev->is_pcie = 1; | 692 | pdev->is_pcie = 1; |
693 | pdev->pcie_cap = pos; | ||
696 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); | 694 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); |
697 | pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; | 695 | pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; |
698 | } | 696 | } |
@@ -703,7 +701,7 @@ static void set_pcie_hotplug_bridge(struct pci_dev *pdev) | |||
703 | u16 reg16; | 701 | u16 reg16; |
704 | u32 reg32; | 702 | u32 reg32; |
705 | 703 | ||
706 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 704 | pos = pci_pcie_cap(pdev); |
707 | if (!pos) | 705 | if (!pos) |
708 | return; | 706 | return; |
709 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); | 707 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); |
@@ -714,6 +712,12 @@ static void set_pcie_hotplug_bridge(struct pci_dev *pdev) | |||
714 | pdev->is_hotplug_bridge = 1; | 712 | pdev->is_hotplug_bridge = 1; |
715 | } | 713 | } |
716 | 714 | ||
715 | static void set_pci_aer_firmware_first(struct pci_dev *pdev) | ||
716 | { | ||
717 | if (acpi_hest_firmware_first_pci(pdev)) | ||
718 | pdev->aer_firmware_first = 1; | ||
719 | } | ||
720 | |||
717 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) | 721 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) |
718 | 722 | ||
719 | /** | 723 | /** |
@@ -731,6 +735,7 @@ int pci_setup_device(struct pci_dev *dev) | |||
731 | u32 class; | 735 | u32 class; |
732 | u8 hdr_type; | 736 | u8 hdr_type; |
733 | struct pci_slot *slot; | 737 | struct pci_slot *slot; |
738 | int pos = 0; | ||
734 | 739 | ||
735 | if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) | 740 | if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) |
736 | return -EIO; | 741 | return -EIO; |
@@ -742,6 +747,7 @@ int pci_setup_device(struct pci_dev *dev) | |||
742 | dev->multifunction = !!(hdr_type & 0x80); | 747 | dev->multifunction = !!(hdr_type & 0x80); |
743 | dev->error_state = pci_channel_io_normal; | 748 | dev->error_state = pci_channel_io_normal; |
744 | set_pcie_port_type(dev); | 749 | set_pcie_port_type(dev); |
750 | set_pci_aer_firmware_first(dev); | ||
745 | 751 | ||
746 | list_for_each_entry(slot, &dev->bus->slots, list) | 752 | list_for_each_entry(slot, &dev->bus->slots, list) |
747 | if (PCI_SLOT(dev->devfn) == slot->number) | 753 | if (PCI_SLOT(dev->devfn) == slot->number) |
@@ -822,6 +828,11 @@ int pci_setup_device(struct pci_dev *dev) | |||
822 | dev->transparent = ((dev->class & 0xff) == 1); | 828 | dev->transparent = ((dev->class & 0xff) == 1); |
823 | pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); | 829 | pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); |
824 | set_pcie_hotplug_bridge(dev); | 830 | set_pcie_hotplug_bridge(dev); |
831 | pos = pci_find_capability(dev, PCI_CAP_ID_SSVID); | ||
832 | if (pos) { | ||
833 | pci_read_config_word(dev, pos + PCI_SSVID_VENDOR_ID, &dev->subsystem_vendor); | ||
834 | pci_read_config_word(dev, pos + PCI_SSVID_DEVICE_ID, &dev->subsystem_device); | ||
835 | } | ||
825 | break; | 836 | break; |
826 | 837 | ||
827 | case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */ | 838 | case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */ |
@@ -907,7 +918,7 @@ int pci_cfg_space_size(struct pci_dev *dev) | |||
907 | if (class == PCI_CLASS_BRIDGE_HOST) | 918 | if (class == PCI_CLASS_BRIDGE_HOST) |
908 | return pci_cfg_space_size_ext(dev); | 919 | return pci_cfg_space_size_ext(dev); |
909 | 920 | ||
910 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 921 | pos = pci_pcie_cap(dev); |
911 | if (!pos) { | 922 | if (!pos) { |
912 | pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 923 | pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
913 | if (!pos) | 924 | if (!pos) |
@@ -1014,6 +1025,9 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
1014 | 1025 | ||
1015 | /* Single Root I/O Virtualization */ | 1026 | /* Single Root I/O Virtualization */ |
1016 | pci_iov_init(dev); | 1027 | pci_iov_init(dev); |
1028 | |||
1029 | /* Enable ACS P2P upstream forwarding */ | ||
1030 | pci_enable_acs(dev); | ||
1017 | } | 1031 | } |
1018 | 1032 | ||
1019 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | 1033 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) |
@@ -1110,7 +1124,7 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1110 | unsigned int devfn, pass, max = bus->secondary; | 1124 | unsigned int devfn, pass, max = bus->secondary; |
1111 | struct pci_dev *dev; | 1125 | struct pci_dev *dev; |
1112 | 1126 | ||
1113 | pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(bus), bus->number); | 1127 | dev_dbg(&bus->dev, "scanning bus\n"); |
1114 | 1128 | ||
1115 | /* Go find them, Rover! */ | 1129 | /* Go find them, Rover! */ |
1116 | for (devfn = 0; devfn < 0x100; devfn += 8) | 1130 | for (devfn = 0; devfn < 0x100; devfn += 8) |
@@ -1124,8 +1138,7 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1124 | * all PCI-to-PCI bridges on this bus. | 1138 | * all PCI-to-PCI bridges on this bus. |
1125 | */ | 1139 | */ |
1126 | if (!bus->is_added) { | 1140 | if (!bus->is_added) { |
1127 | pr_debug("PCI: Fixups for bus %04x:%02x\n", | 1141 | dev_dbg(&bus->dev, "fixups for bus\n"); |
1128 | pci_domain_nr(bus), bus->number); | ||
1129 | pcibios_fixup_bus(bus); | 1142 | pcibios_fixup_bus(bus); |
1130 | if (pci_is_root_bus(bus)) | 1143 | if (pci_is_root_bus(bus)) |
1131 | bus->is_added = 1; | 1144 | bus->is_added = 1; |
@@ -1145,8 +1158,7 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1145 | * | 1158 | * |
1146 | * Return how far we've got finding sub-buses. | 1159 | * Return how far we've got finding sub-buses. |
1147 | */ | 1160 | */ |
1148 | pr_debug("PCI: Bus scan for %04x:%02x returning with max=%02x\n", | 1161 | dev_dbg(&bus->dev, "bus scan returning with max=%02x\n", max); |
1149 | pci_domain_nr(bus), bus->number, max); | ||
1150 | return max; | 1162 | return max; |
1151 | } | 1163 | } |
1152 | 1164 | ||
@@ -1154,7 +1166,7 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1154 | int bus, struct pci_ops *ops, void *sysdata) | 1166 | int bus, struct pci_ops *ops, void *sysdata) |
1155 | { | 1167 | { |
1156 | int error; | 1168 | int error; |
1157 | struct pci_bus *b; | 1169 | struct pci_bus *b, *b2; |
1158 | struct device *dev; | 1170 | struct device *dev; |
1159 | 1171 | ||
1160 | b = pci_alloc_bus(); | 1172 | b = pci_alloc_bus(); |
@@ -1170,9 +1182,10 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1170 | b->sysdata = sysdata; | 1182 | b->sysdata = sysdata; |
1171 | b->ops = ops; | 1183 | b->ops = ops; |
1172 | 1184 | ||
1173 | if (pci_find_bus(pci_domain_nr(b), bus)) { | 1185 | b2 = pci_find_bus(pci_domain_nr(b), bus); |
1186 | if (b2) { | ||
1174 | /* If we already got to this bus through a different bridge, ignore it */ | 1187 | /* If we already got to this bus through a different bridge, ignore it */ |
1175 | pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); | 1188 | dev_dbg(&b2->dev, "bus already known\n"); |
1176 | goto err_out; | 1189 | goto err_out; |
1177 | } | 1190 | } |
1178 | 1191 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 245d2cdb4765..7cfa7c38d318 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -357,7 +357,7 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, | |||
357 | pcibios_bus_to_resource(dev, res, &bus_region); | 357 | pcibios_bus_to_resource(dev, res, &bus_region); |
358 | 358 | ||
359 | pci_claim_resource(dev, nr); | 359 | pci_claim_resource(dev, nr); |
360 | dev_info(&dev->dev, "quirk: region %04x-%04x claimed by %s\n", region, region + size - 1, name); | 360 | dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name); |
361 | } | 361 | } |
362 | } | 362 | } |
363 | 363 | ||
@@ -1680,6 +1680,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_ | |||
1680 | */ | 1680 | */ |
1681 | #define AMD_813X_MISC 0x40 | 1681 | #define AMD_813X_MISC 0x40 |
1682 | #define AMD_813X_NOIOAMODE (1<<0) | 1682 | #define AMD_813X_NOIOAMODE (1<<0) |
1683 | #define AMD_813X_REV_B1 0x12 | ||
1683 | #define AMD_813X_REV_B2 0x13 | 1684 | #define AMD_813X_REV_B2 0x13 |
1684 | 1685 | ||
1685 | static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | 1686 | static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) |
@@ -1688,7 +1689,8 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | |||
1688 | 1689 | ||
1689 | if (noioapicquirk) | 1690 | if (noioapicquirk) |
1690 | return; | 1691 | return; |
1691 | if (dev->revision == AMD_813X_REV_B2) | 1692 | if ((dev->revision == AMD_813X_REV_B1) || |
1693 | (dev->revision == AMD_813X_REV_B2)) | ||
1692 | return; | 1694 | return; |
1693 | 1695 | ||
1694 | pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); | 1696 | pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); |
@@ -1698,8 +1700,10 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | |||
1698 | dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n", | 1700 | dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n", |
1699 | dev->vendor, dev->device); | 1701 | dev->vendor, dev->device); |
1700 | } | 1702 | } |
1701 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | 1703 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_amd_813x_boot_interrupt); |
1702 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | 1704 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_amd_813x_boot_interrupt); |
1705 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | ||
1706 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | ||
1703 | 1707 | ||
1704 | #define AMD_8111_PCI_IRQ_ROUTING 0x56 | 1708 | #define AMD_8111_PCI_IRQ_ROUTING 0x56 |
1705 | 1709 | ||
@@ -2595,9 +2599,37 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | |||
2595 | static int __init pci_apply_final_quirks(void) | 2599 | static int __init pci_apply_final_quirks(void) |
2596 | { | 2600 | { |
2597 | struct pci_dev *dev = NULL; | 2601 | struct pci_dev *dev = NULL; |
2602 | u8 cls = 0; | ||
2603 | u8 tmp; | ||
2604 | |||
2605 | if (pci_cache_line_size) | ||
2606 | printk(KERN_DEBUG "PCI: CLS %u bytes\n", | ||
2607 | pci_cache_line_size << 2); | ||
2598 | 2608 | ||
2599 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 2609 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
2600 | pci_fixup_device(pci_fixup_final, dev); | 2610 | pci_fixup_device(pci_fixup_final, dev); |
2611 | /* | ||
2612 | * If arch hasn't set it explicitly yet, use the CLS | ||
2613 | * value shared by all PCI devices. If there's a | ||
2614 | * mismatch, fall back to the default value. | ||
2615 | */ | ||
2616 | if (!pci_cache_line_size) { | ||
2617 | pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp); | ||
2618 | if (!cls) | ||
2619 | cls = tmp; | ||
2620 | if (!tmp || cls == tmp) | ||
2621 | continue; | ||
2622 | |||
2623 | printk(KERN_DEBUG "PCI: CLS mismatch (%u != %u), " | ||
2624 | "using %u bytes\n", cls << 2, tmp << 2, | ||
2625 | pci_dfl_cache_line_size << 2); | ||
2626 | pci_cache_line_size = pci_dfl_cache_line_size; | ||
2627 | } | ||
2628 | } | ||
2629 | if (!pci_cache_line_size) { | ||
2630 | printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n", | ||
2631 | cls << 2, pci_dfl_cache_line_size << 2); | ||
2632 | pci_cache_line_size = cls; | ||
2601 | } | 2633 | } |
2602 | 2634 | ||
2603 | return 0; | 2635 | return 0; |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index ec415352d9ba..6dae87143258 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -26,14 +26,14 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev) | |||
26 | { | 26 | { |
27 | struct pci_dev *tmp = NULL; | 27 | struct pci_dev *tmp = NULL; |
28 | 28 | ||
29 | if (pdev->is_pcie) | 29 | if (pci_is_pcie(pdev)) |
30 | return NULL; | 30 | return NULL; |
31 | while (1) { | 31 | while (1) { |
32 | if (pci_is_root_bus(pdev->bus)) | 32 | if (pci_is_root_bus(pdev->bus)) |
33 | break; | 33 | break; |
34 | pdev = pdev->bus->self; | 34 | pdev = pdev->bus->self; |
35 | /* a p2p bridge */ | 35 | /* a p2p bridge */ |
36 | if (!pdev->is_pcie) { | 36 | if (!pci_is_pcie(pdev)) { |
37 | tmp = pdev; | 37 | tmp = pdev; |
38 | continue; | 38 | continue; |
39 | } | 39 | } |
@@ -149,32 +149,33 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) | |||
149 | } | 149 | } |
150 | 150 | ||
151 | /** | 151 | /** |
152 | * pci_get_bus_and_slot - locate PCI device from a given PCI bus & slot | 152 | * pci_get_domain_bus_and_slot - locate PCI device for a given PCI domain (segment), bus, and slot |
153 | * @bus: number of PCI bus on which desired PCI device resides | 153 | * @domain: PCI domain/segment on which the PCI device resides. |
154 | * @devfn: encodes number of PCI slot in which the desired PCI | 154 | * @bus: PCI bus on which desired PCI device resides |
155 | * device resides and the logical device number within that slot | 155 | * @devfn: encodes number of PCI slot in which the desired PCI device |
156 | * in case of multi-function devices. | 156 | * resides and the logical device number within that slot in case of |
157 | * | 157 | * multi-function devices. |
158 | * Note: the bus/slot search is limited to PCI domain (segment) 0. | ||
159 | * | 158 | * |
160 | * Given a PCI bus and slot/function number, the desired PCI device | 159 | * Given a PCI domain, bus, and slot/function number, the desired PCI |
161 | * is located in system global list of PCI devices. If the device | 160 | * device is located in the list of PCI devices. If the device is |
162 | * is found, a pointer to its data structure is returned. If no | 161 | * found, its reference count is increased and this function returns a |
163 | * device is found, %NULL is returned. The returned device has its | 162 | * pointer to its data structure. The caller must decrement the |
164 | * reference count bumped by one. | 163 | * reference count by calling pci_dev_put(). If no device is found, |
164 | * %NULL is returned. | ||
165 | */ | 165 | */ |
166 | 166 | struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus, | |
167 | struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) | 167 | unsigned int devfn) |
168 | { | 168 | { |
169 | struct pci_dev *dev = NULL; | 169 | struct pci_dev *dev = NULL; |
170 | 170 | ||
171 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 171 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
172 | if (pci_domain_nr(dev->bus) == 0 && | 172 | if (pci_domain_nr(dev->bus) == domain && |
173 | (dev->bus->number == bus && dev->devfn == devfn)) | 173 | (dev->bus->number == bus && dev->devfn == devfn)) |
174 | return dev; | 174 | return dev; |
175 | } | 175 | } |
176 | return NULL; | 176 | return NULL; |
177 | } | 177 | } |
178 | EXPORT_SYMBOL(pci_get_domain_bus_and_slot); | ||
178 | 179 | ||
179 | static int match_pci_dev_by_id(struct device *dev, void *data) | 180 | static int match_pci_dev_by_id(struct device *dev, void *data) |
180 | { | 181 | { |
@@ -354,5 +355,4 @@ EXPORT_SYMBOL(pci_find_next_bus); | |||
354 | EXPORT_SYMBOL(pci_get_device); | 355 | EXPORT_SYMBOL(pci_get_device); |
355 | EXPORT_SYMBOL(pci_get_subsys); | 356 | EXPORT_SYMBOL(pci_get_subsys); |
356 | EXPORT_SYMBOL(pci_get_slot); | 357 | EXPORT_SYMBOL(pci_get_slot); |
357 | EXPORT_SYMBOL(pci_get_bus_and_slot); | ||
358 | EXPORT_SYMBOL(pci_get_class); | 358 | EXPORT_SYMBOL(pci_get_class); |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index cb1a027eb552..c48cd377b3f5 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -71,53 +71,50 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus) | |||
71 | void pci_setup_cardbus(struct pci_bus *bus) | 71 | void pci_setup_cardbus(struct pci_bus *bus) |
72 | { | 72 | { |
73 | struct pci_dev *bridge = bus->self; | 73 | struct pci_dev *bridge = bus->self; |
74 | struct resource *res; | ||
74 | struct pci_bus_region region; | 75 | struct pci_bus_region region; |
75 | 76 | ||
76 | dev_info(&bridge->dev, "CardBus bridge, secondary bus %04x:%02x\n", | 77 | dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n", |
77 | pci_domain_nr(bus), bus->number); | 78 | bus->secondary, bus->subordinate); |
78 | 79 | ||
79 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]); | 80 | res = bus->resource[0]; |
80 | if (bus->resource[0]->flags & IORESOURCE_IO) { | 81 | pcibios_resource_to_bus(bridge, ®ion, res); |
82 | if (res->flags & IORESOURCE_IO) { | ||
81 | /* | 83 | /* |
82 | * The IO resource is allocated a range twice as large as it | 84 | * The IO resource is allocated a range twice as large as it |
83 | * would normally need. This allows us to set both IO regs. | 85 | * would normally need. This allows us to set both IO regs. |
84 | */ | 86 | */ |
85 | dev_info(&bridge->dev, " IO window: %#08lx-%#08lx\n", | 87 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
86 | (unsigned long)region.start, | ||
87 | (unsigned long)region.end); | ||
88 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, | 88 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, |
89 | region.start); | 89 | region.start); |
90 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, | 90 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, |
91 | region.end); | 91 | region.end); |
92 | } | 92 | } |
93 | 93 | ||
94 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); | 94 | res = bus->resource[1]; |
95 | if (bus->resource[1]->flags & IORESOURCE_IO) { | 95 | pcibios_resource_to_bus(bridge, ®ion, res); |
96 | dev_info(&bridge->dev, " IO window: %#08lx-%#08lx\n", | 96 | if (res->flags & IORESOURCE_IO) { |
97 | (unsigned long)region.start, | 97 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
98 | (unsigned long)region.end); | ||
99 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, | 98 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, |
100 | region.start); | 99 | region.start); |
101 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, | 100 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, |
102 | region.end); | 101 | region.end); |
103 | } | 102 | } |
104 | 103 | ||
105 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); | 104 | res = bus->resource[2]; |
106 | if (bus->resource[2]->flags & IORESOURCE_MEM) { | 105 | pcibios_resource_to_bus(bridge, ®ion, res); |
107 | dev_info(&bridge->dev, " PREFETCH window: %#08lx-%#08lx\n", | 106 | if (res->flags & IORESOURCE_MEM) { |
108 | (unsigned long)region.start, | 107 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
109 | (unsigned long)region.end); | ||
110 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, | 108 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, |
111 | region.start); | 109 | region.start); |
112 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, | 110 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, |
113 | region.end); | 111 | region.end); |
114 | } | 112 | } |
115 | 113 | ||
116 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[3]); | 114 | res = bus->resource[3]; |
117 | if (bus->resource[3]->flags & IORESOURCE_MEM) { | 115 | pcibios_resource_to_bus(bridge, ®ion, res); |
118 | dev_info(&bridge->dev, " MEM window: %#08lx-%#08lx\n", | 116 | if (res->flags & IORESOURCE_MEM) { |
119 | (unsigned long)region.start, | 117 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
120 | (unsigned long)region.end); | ||
121 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, | 118 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, |
122 | region.start); | 119 | region.start); |
123 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, | 120 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, |
@@ -140,34 +137,33 @@ EXPORT_SYMBOL(pci_setup_cardbus); | |||
140 | static void pci_setup_bridge(struct pci_bus *bus) | 137 | static void pci_setup_bridge(struct pci_bus *bus) |
141 | { | 138 | { |
142 | struct pci_dev *bridge = bus->self; | 139 | struct pci_dev *bridge = bus->self; |
140 | struct resource *res; | ||
143 | struct pci_bus_region region; | 141 | struct pci_bus_region region; |
144 | u32 l, bu, lu, io_upper16; | 142 | u32 l, bu, lu, io_upper16; |
145 | int pref_mem64; | ||
146 | 143 | ||
147 | if (pci_is_enabled(bridge)) | 144 | if (pci_is_enabled(bridge)) |
148 | return; | 145 | return; |
149 | 146 | ||
150 | dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n", | 147 | dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n", |
151 | pci_domain_nr(bus), bus->number); | 148 | bus->secondary, bus->subordinate); |
152 | 149 | ||
153 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ | 150 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ |
154 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]); | 151 | res = bus->resource[0]; |
155 | if (bus->resource[0]->flags & IORESOURCE_IO) { | 152 | pcibios_resource_to_bus(bridge, ®ion, res); |
153 | if (res->flags & IORESOURCE_IO) { | ||
156 | pci_read_config_dword(bridge, PCI_IO_BASE, &l); | 154 | pci_read_config_dword(bridge, PCI_IO_BASE, &l); |
157 | l &= 0xffff0000; | 155 | l &= 0xffff0000; |
158 | l |= (region.start >> 8) & 0x00f0; | 156 | l |= (region.start >> 8) & 0x00f0; |
159 | l |= region.end & 0xf000; | 157 | l |= region.end & 0xf000; |
160 | /* Set up upper 16 bits of I/O base/limit. */ | 158 | /* Set up upper 16 bits of I/O base/limit. */ |
161 | io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); | 159 | io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); |
162 | dev_info(&bridge->dev, " IO window: %#04lx-%#04lx\n", | 160 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
163 | (unsigned long)region.start, | ||
164 | (unsigned long)region.end); | ||
165 | } | 161 | } |
166 | else { | 162 | else { |
167 | /* Clear upper 16 bits of I/O base/limit. */ | 163 | /* Clear upper 16 bits of I/O base/limit. */ |
168 | io_upper16 = 0; | 164 | io_upper16 = 0; |
169 | l = 0x00f0; | 165 | l = 0x00f0; |
170 | dev_info(&bridge->dev, " IO window: disabled\n"); | 166 | dev_info(&bridge->dev, " bridge window [io disabled]\n"); |
171 | } | 167 | } |
172 | /* Temporarily disable the I/O range before updating PCI_IO_BASE. */ | 168 | /* Temporarily disable the I/O range before updating PCI_IO_BASE. */ |
173 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff); | 169 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff); |
@@ -178,17 +174,16 @@ static void pci_setup_bridge(struct pci_bus *bus) | |||
178 | 174 | ||
179 | /* Set up the top and bottom of the PCI Memory segment | 175 | /* Set up the top and bottom of the PCI Memory segment |
180 | for this bus. */ | 176 | for this bus. */ |
181 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); | 177 | res = bus->resource[1]; |
182 | if (bus->resource[1]->flags & IORESOURCE_MEM) { | 178 | pcibios_resource_to_bus(bridge, ®ion, res); |
179 | if (res->flags & IORESOURCE_MEM) { | ||
183 | l = (region.start >> 16) & 0xfff0; | 180 | l = (region.start >> 16) & 0xfff0; |
184 | l |= region.end & 0xfff00000; | 181 | l |= region.end & 0xfff00000; |
185 | dev_info(&bridge->dev, " MEM window: %#08lx-%#08lx\n", | 182 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
186 | (unsigned long)region.start, | ||
187 | (unsigned long)region.end); | ||
188 | } | 183 | } |
189 | else { | 184 | else { |
190 | l = 0x0000fff0; | 185 | l = 0x0000fff0; |
191 | dev_info(&bridge->dev, " MEM window: disabled\n"); | 186 | dev_info(&bridge->dev, " bridge window [mem disabled]\n"); |
192 | } | 187 | } |
193 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); | 188 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); |
194 | 189 | ||
@@ -198,34 +193,27 @@ static void pci_setup_bridge(struct pci_bus *bus) | |||
198 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); | 193 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); |
199 | 194 | ||
200 | /* Set up PREF base/limit. */ | 195 | /* Set up PREF base/limit. */ |
201 | pref_mem64 = 0; | ||
202 | bu = lu = 0; | 196 | bu = lu = 0; |
203 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); | 197 | res = bus->resource[2]; |
204 | if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { | 198 | pcibios_resource_to_bus(bridge, ®ion, res); |
205 | int width = 8; | 199 | if (res->flags & IORESOURCE_PREFETCH) { |
206 | l = (region.start >> 16) & 0xfff0; | 200 | l = (region.start >> 16) & 0xfff0; |
207 | l |= region.end & 0xfff00000; | 201 | l |= region.end & 0xfff00000; |
208 | if (bus->resource[2]->flags & IORESOURCE_MEM_64) { | 202 | if (res->flags & IORESOURCE_MEM_64) { |
209 | pref_mem64 = 1; | ||
210 | bu = upper_32_bits(region.start); | 203 | bu = upper_32_bits(region.start); |
211 | lu = upper_32_bits(region.end); | 204 | lu = upper_32_bits(region.end); |
212 | width = 16; | ||
213 | } | 205 | } |
214 | dev_info(&bridge->dev, " PREFETCH window: %#0*llx-%#0*llx\n", | 206 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
215 | width, (unsigned long long)region.start, | ||
216 | width, (unsigned long long)region.end); | ||
217 | } | 207 | } |
218 | else { | 208 | else { |
219 | l = 0x0000fff0; | 209 | l = 0x0000fff0; |
220 | dev_info(&bridge->dev, " PREFETCH window: disabled\n"); | 210 | dev_info(&bridge->dev, " bridge window [mem pref disabled]\n"); |
221 | } | 211 | } |
222 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); | 212 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); |
223 | 213 | ||
224 | if (pref_mem64) { | 214 | /* Set the upper 32 bits of PREF base & limit. */ |
225 | /* Set the upper 32 bits of PREF base & limit. */ | 215 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); |
226 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); | 216 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); |
227 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); | ||
228 | } | ||
229 | 217 | ||
230 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); | 218 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); |
231 | } | 219 | } |
@@ -345,6 +333,10 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size) | |||
345 | #endif | 333 | #endif |
346 | size = ALIGN(size + size1, 4096); | 334 | size = ALIGN(size + size1, 4096); |
347 | if (!size) { | 335 | if (!size) { |
336 | if (b_res->start || b_res->end) | ||
337 | dev_info(&bus->self->dev, "disabling bridge window " | ||
338 | "%pR to [bus %02x-%02x] (unused)\n", b_res, | ||
339 | bus->secondary, bus->subordinate); | ||
348 | b_res->flags = 0; | 340 | b_res->flags = 0; |
349 | return; | 341 | return; |
350 | } | 342 | } |
@@ -390,8 +382,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
390 | align = pci_resource_alignment(dev, r); | 382 | align = pci_resource_alignment(dev, r); |
391 | order = __ffs(align) - 20; | 383 | order = __ffs(align) - 20; |
392 | if (order > 11) { | 384 | if (order > 11) { |
393 | dev_warn(&dev->dev, "BAR %d bad alignment %llx: " | 385 | dev_warn(&dev->dev, "disabling BAR %d: %pR " |
394 | "%pR\n", i, (unsigned long long)align, r); | 386 | "(bad alignment %#llx)\n", i, r, |
387 | (unsigned long long) align); | ||
395 | r->flags = 0; | 388 | r->flags = 0; |
396 | continue; | 389 | continue; |
397 | } | 390 | } |
@@ -425,6 +418,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
425 | } | 418 | } |
426 | size = ALIGN(size, min_align); | 419 | size = ALIGN(size, min_align); |
427 | if (!size) { | 420 | if (!size) { |
421 | if (b_res->start || b_res->end) | ||
422 | dev_info(&bus->self->dev, "disabling bridge window " | ||
423 | "%pR to [bus %02x-%02x] (unused)\n", b_res, | ||
424 | bus->secondary, bus->subordinate); | ||
428 | b_res->flags = 0; | 425 | b_res->flags = 0; |
429 | return 1; | 426 | return 1; |
430 | } | 427 | } |
@@ -582,10 +579,7 @@ static void pci_bus_dump_res(struct pci_bus *bus) | |||
582 | if (!res || !res->end) | 579 | if (!res || !res->end) |
583 | continue; | 580 | continue; |
584 | 581 | ||
585 | dev_printk(KERN_DEBUG, &bus->dev, "resource %d %s %pR\n", i, | 582 | dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res); |
586 | (res->flags & IORESOURCE_IO) ? "io: " : | ||
587 | ((res->flags & IORESOURCE_PREFETCH)? "pref mem":"mem:"), | ||
588 | res); | ||
589 | } | 583 | } |
590 | } | 584 | } |
591 | 585 | ||
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index c54526b206b5..7d678bb15ffb 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -51,12 +51,6 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
51 | 51 | ||
52 | pcibios_resource_to_bus(dev, ®ion, res); | 52 | pcibios_resource_to_bus(dev, ®ion, res); |
53 | 53 | ||
54 | dev_dbg(&dev->dev, "BAR %d: got res %pR bus [%#llx-%#llx] " | ||
55 | "flags %#lx\n", resno, res, | ||
56 | (unsigned long long)region.start, | ||
57 | (unsigned long long)region.end, | ||
58 | (unsigned long)res->flags); | ||
59 | |||
60 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); | 54 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); |
61 | if (res->flags & IORESOURCE_IO) | 55 | if (res->flags & IORESOURCE_IO) |
62 | mask = (u32)PCI_BASE_ADDRESS_IO_MASK; | 56 | mask = (u32)PCI_BASE_ADDRESS_IO_MASK; |
@@ -91,9 +85,9 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
91 | } | 85 | } |
92 | } | 86 | } |
93 | res->flags &= ~IORESOURCE_UNSET; | 87 | res->flags &= ~IORESOURCE_UNSET; |
94 | dev_dbg(&dev->dev, "BAR %d: moved to bus [%#llx-%#llx] flags %#lx\n", | 88 | dev_info(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx]\n", |
95 | resno, (unsigned long long)region.start, | 89 | resno, res, (unsigned long long)region.start, |
96 | (unsigned long long)region.end, res->flags); | 90 | (unsigned long long)region.end); |
97 | } | 91 | } |
98 | 92 | ||
99 | int pci_claim_resource(struct pci_dev *dev, int resource) | 93 | int pci_claim_resource(struct pci_dev *dev, int resource) |
@@ -103,20 +97,17 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
103 | int err; | 97 | int err; |
104 | 98 | ||
105 | root = pci_find_parent_resource(dev, res); | 99 | root = pci_find_parent_resource(dev, res); |
106 | 100 | if (!root) { | |
107 | err = -EINVAL; | 101 | dev_err(&dev->dev, "no compatible bridge window for %pR\n", |
108 | if (root != NULL) | 102 | res); |
109 | err = request_resource(root, res); | 103 | return -EINVAL; |
110 | |||
111 | if (err) { | ||
112 | const char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge"; | ||
113 | dev_err(&dev->dev, "BAR %d: %s of %s %pR\n", | ||
114 | resource, | ||
115 | root ? "address space collision on" : | ||
116 | "no parent found for", | ||
117 | dtype, res); | ||
118 | } | 104 | } |
119 | 105 | ||
106 | err = request_resource(root, res); | ||
107 | if (err) | ||
108 | dev_err(&dev->dev, | ||
109 | "address space collision: %pR already in use\n", res); | ||
110 | |||
120 | return err; | 111 | return err; |
121 | } | 112 | } |
122 | EXPORT_SYMBOL(pci_claim_resource); | 113 | EXPORT_SYMBOL(pci_claim_resource); |
@@ -124,7 +115,7 @@ EXPORT_SYMBOL(pci_claim_resource); | |||
124 | #ifdef CONFIG_PCI_QUIRKS | 115 | #ifdef CONFIG_PCI_QUIRKS |
125 | void pci_disable_bridge_window(struct pci_dev *dev) | 116 | void pci_disable_bridge_window(struct pci_dev *dev) |
126 | { | 117 | { |
127 | dev_dbg(&dev->dev, "Disabling bridge window.\n"); | 118 | dev_info(&dev->dev, "disabling bridge mem windows\n"); |
128 | 119 | ||
129 | /* MMIO Base/Limit */ | 120 | /* MMIO Base/Limit */ |
130 | pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0); | 121 | pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0); |
@@ -165,6 +156,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | |||
165 | 156 | ||
166 | if (!ret) { | 157 | if (!ret) { |
167 | res->flags &= ~IORESOURCE_STARTALIGN; | 158 | res->flags &= ~IORESOURCE_STARTALIGN; |
159 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | ||
168 | if (resno < PCI_BRIDGE_RESOURCES) | 160 | if (resno < PCI_BRIDGE_RESOURCES) |
169 | pci_update_resource(dev, resno); | 161 | pci_update_resource(dev, resno); |
170 | } | 162 | } |
@@ -178,12 +170,12 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
178 | resource_size_t align; | 170 | resource_size_t align; |
179 | struct pci_bus *bus; | 171 | struct pci_bus *bus; |
180 | int ret; | 172 | int ret; |
173 | char *type; | ||
181 | 174 | ||
182 | align = pci_resource_alignment(dev, res); | 175 | align = pci_resource_alignment(dev, res); |
183 | if (!align) { | 176 | if (!align) { |
184 | dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " | 177 | dev_info(&dev->dev, "BAR %d: can't assign %pR " |
185 | "alignment) %pR flags %#lx\n", | 178 | "(bogus alignment)\n", resno, res); |
186 | resno, res, res->flags); | ||
187 | return -EINVAL; | 179 | return -EINVAL; |
188 | } | 180 | } |
189 | 181 | ||
@@ -198,9 +190,20 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
198 | break; | 190 | break; |
199 | } | 191 | } |
200 | 192 | ||
201 | if (ret) | 193 | if (ret) { |
202 | dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", | 194 | if (res->flags & IORESOURCE_MEM) |
203 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); | 195 | if (res->flags & IORESOURCE_PREFETCH) |
196 | type = "mem pref"; | ||
197 | else | ||
198 | type = "mem"; | ||
199 | else if (res->flags & IORESOURCE_IO) | ||
200 | type = "io"; | ||
201 | else | ||
202 | type = "unknown"; | ||
203 | dev_info(&dev->dev, | ||
204 | "BAR %d: can't assign %s (size %#llx)\n", | ||
205 | resno, type, (unsigned long long) resource_size(res)); | ||
206 | } | ||
204 | 207 | ||
205 | return ret; | 208 | return ret; |
206 | } | 209 | } |
@@ -225,9 +228,8 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | |||
225 | 228 | ||
226 | r_align = pci_resource_alignment(dev, r); | 229 | r_align = pci_resource_alignment(dev, r); |
227 | if (!r_align) { | 230 | if (!r_align) { |
228 | dev_warn(&dev->dev, "BAR %d: bogus alignment " | 231 | dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n", |
229 | "%pR flags %#lx\n", | 232 | i, r); |
230 | i, r, r->flags); | ||
231 | continue; | 233 | continue; |
232 | } | 234 | } |
233 | for (list = head; ; list = list->next) { | 235 | for (list = head; ; list = list->next) { |
@@ -274,8 +276,8 @@ int pci_enable_resources(struct pci_dev *dev, int mask) | |||
274 | continue; | 276 | continue; |
275 | 277 | ||
276 | if (!r->parent) { | 278 | if (!r->parent) { |
277 | dev_err(&dev->dev, "device not available because of " | 279 | dev_err(&dev->dev, "device not available " |
278 | "BAR %d %pR collisions\n", i, r); | 280 | "(can't reserve %pR)\n", r); |
279 | return -EINVAL; | 281 | return -EINVAL; |
280 | } | 282 | } |
281 | 283 | ||