diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 17:02:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 17:02:12 -0400 |
commit | 475c77edf826333aa61625f49d6a2bec26ecb5a6 (patch) | |
tree | 8e1c6c319e347cd3c649fdb0b3ab45971c6b19e7 /drivers | |
parent | 934e18b5cb4531cc6e81865bf54115cfd21d1ac6 (diff) | |
parent | 1488d5158dcd612fcdaf6b642451b026ee8bbcbb (diff) |
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci
Pull PCI changes (including maintainer change) from Jesse Barnes:
"This pull has some good cleanups from Bjorn and Yinghai, as well as
some more code from Yinghai to better handle resource re-allocation
when enabled.
There's also a new initcall_debug feature from Arjan which will print
out quirk timing information to help identify slow quirks for fixing
or refinement (Yinghai sent in a few patches to do just that once the
new debug code landed).
Beyond that, I'm handing off PCI maintainership to Bjorn Helgaas.
He's been a core PCI and Linux contributor for some time now, and has
kindly volunteered to take over. I just don't feel I have the time
for PCI review and work that it deserves lately (I've taken on some
other projects), and haven't been as responsive lately as I'd like, so
I approached Bjorn asking if he'd like to manage things. He's going
to give it a try, and I'm confident he'll do at least as well as I
have in keeping the tree managed, patches flowing, and keeping things
stable."
Fix up some fairly trivial conflicts due to other cleanups (mips device
resource fixup cleanups clashing with list handling cleanup, ppc iseries
removal clashing with pci_probe_only cleanup etc)
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci: (112 commits)
PCI: Bjorn gets PCI hotplug too
PCI: hand PCI maintenance over to Bjorn Helgaas
unicore32/PCI: move <asm-generic/pci-bridge.h> include to asm/pci.h
sparc/PCI: convert devtree and arch-probed bus addresses to resource
powerpc/PCI: allow reallocation on PA Semi
powerpc/PCI: convert devtree bus addresses to resource
powerpc/PCI: compute I/O space bus-to-resource offset consistently
arm/PCI: don't export pci_flags
PCI: fix bridge I/O window bus-to-resource conversion
x86/PCI: add spinlock held check to 'pcibios_fwaddrmap_lookup()'
PCI / PCIe: Introduce command line option to disable ARI
PCI: make acpihp use __pci_remove_bus_device instead
PCI: export __pci_remove_bus_device
PCI: Rename pci_remove_behind_bridge to pci_stop_and_remove_behind_bridge
PCI: Rename pci_remove_bus_device to pci_stop_and_remove_bus_device
PCI: print out PCI device info along with duration
PCI: Move "pci reassigndev resource alignment" out of quirks.c
PCI: Use class for quirk for usb host controller fixup
PCI: Use class for quirk for ti816x class fixup
PCI: Use class for quirk for intel e100 interrupt fixup
...
Diffstat (limited to 'drivers')
37 files changed, 1200 insertions, 577 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index a7dc4672d996..a5c591ffe395 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -346,7 +346,7 @@ static int mpt_remove_dead_ioc_func(void *arg) | |||
346 | if ((pdev == NULL)) | 346 | if ((pdev == NULL)) |
347 | return -1; | 347 | return -1; |
348 | 348 | ||
349 | pci_remove_bus_device(pdev); | 349 | pci_stop_and_remove_bus_device(pdev); |
350 | return 0; | 350 | return 0; |
351 | } | 351 | } |
352 | 352 | ||
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 7ff10c1e8664..0610e91bceb2 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -553,7 +553,6 @@ dino_fixup_bus(struct pci_bus *bus) | |||
553 | struct list_head *ln; | 553 | struct list_head *ln; |
554 | struct pci_dev *dev; | 554 | struct pci_dev *dev; |
555 | struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); | 555 | struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); |
556 | int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num); | ||
557 | 556 | ||
558 | DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n", | 557 | DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n", |
559 | __func__, bus, bus->secondary, | 558 | __func__, bus, bus->secondary, |
@@ -599,8 +598,6 @@ dino_fixup_bus(struct pci_bus *bus) | |||
599 | 598 | ||
600 | 599 | ||
601 | list_for_each(ln, &bus->devices) { | 600 | list_for_each(ln, &bus->devices) { |
602 | int i; | ||
603 | |||
604 | dev = pci_dev_b(ln); | 601 | dev = pci_dev_b(ln); |
605 | if (is_card_dino(&dino_dev->hba.dev->id)) | 602 | if (is_card_dino(&dino_dev->hba.dev->id)) |
606 | dino_card_fixup(dev); | 603 | dino_card_fixup(dev); |
@@ -612,21 +609,6 @@ dino_fixup_bus(struct pci_bus *bus) | |||
612 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) | 609 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) |
613 | continue; | 610 | continue; |
614 | 611 | ||
615 | /* Adjust the I/O Port space addresses */ | ||
616 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
617 | struct resource *res = &dev->resource[i]; | ||
618 | if (res->flags & IORESOURCE_IO) { | ||
619 | res->start |= port_base; | ||
620 | res->end |= port_base; | ||
621 | } | ||
622 | #ifdef __LP64__ | ||
623 | /* Sign Extend MMIO addresses */ | ||
624 | else if (res->flags & IORESOURCE_MEM) { | ||
625 | res->start |= F_EXTEND(0UL); | ||
626 | res->end |= F_EXTEND(0UL); | ||
627 | } | ||
628 | #endif | ||
629 | } | ||
630 | /* null out the ROM resource if there is one (we don't | 612 | /* null out the ROM resource if there is one (we don't |
631 | * care about an expansion rom on parisc, since it | 613 | * care about an expansion rom on parisc, since it |
632 | * usually contains (x86) bios code) */ | 614 | * usually contains (x86) bios code) */ |
@@ -991,11 +973,14 @@ static int __init dino_probe(struct parisc_device *dev) | |||
991 | 973 | ||
992 | dev->dev.platform_data = dino_dev; | 974 | dev->dev.platform_data = dino_dev; |
993 | 975 | ||
994 | pci_add_resource(&resources, &dino_dev->hba.io_space); | 976 | pci_add_resource_offset(&resources, &dino_dev->hba.io_space, |
977 | HBA_PORT_BASE(dino_dev->hba.hba_num)); | ||
995 | if (dino_dev->hba.lmmio_space.flags) | 978 | if (dino_dev->hba.lmmio_space.flags) |
996 | pci_add_resource(&resources, &dino_dev->hba.lmmio_space); | 979 | pci_add_resource_offset(&resources, &dino_dev->hba.lmmio_space, |
980 | dino_dev->hba.lmmio_space_offset); | ||
997 | if (dino_dev->hba.elmmio_space.flags) | 981 | if (dino_dev->hba.elmmio_space.flags) |
998 | pci_add_resource(&resources, &dino_dev->hba.elmmio_space); | 982 | pci_add_resource_offset(&resources, &dino_dev->hba.elmmio_space, |
983 | dino_dev->hba.lmmio_space_offset); | ||
999 | if (dino_dev->hba.gmmio_space.flags) | 984 | if (dino_dev->hba.gmmio_space.flags) |
1000 | pci_add_resource(&resources, &dino_dev->hba.gmmio_space); | 985 | pci_add_resource(&resources, &dino_dev->hba.gmmio_space); |
1001 | 986 | ||
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index d5f3d753a108..e8857647e210 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -635,7 +635,6 @@ lba_fixup_bus(struct pci_bus *bus) | |||
635 | u16 status; | 635 | u16 status; |
636 | #endif | 636 | #endif |
637 | struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge)); | 637 | struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge)); |
638 | int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num); | ||
639 | 638 | ||
640 | DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n", | 639 | DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n", |
641 | bus, bus->secondary, bus->bridge->platform_data); | 640 | bus, bus->secondary, bus->bridge->platform_data); |
@@ -726,27 +725,6 @@ lba_fixup_bus(struct pci_bus *bus) | |||
726 | if (!res->start) | 725 | if (!res->start) |
727 | continue; | 726 | continue; |
728 | 727 | ||
729 | if (res->flags & IORESOURCE_IO) { | ||
730 | DBG("lba_fixup_bus() I/O Ports [%lx/%lx] -> ", | ||
731 | res->start, res->end); | ||
732 | res->start |= lba_portbase; | ||
733 | res->end |= lba_portbase; | ||
734 | DBG("[%lx/%lx]\n", res->start, res->end); | ||
735 | } else if (res->flags & IORESOURCE_MEM) { | ||
736 | /* | ||
737 | ** Convert PCI (IO_VIEW) addresses to | ||
738 | ** processor (PA_VIEW) addresses | ||
739 | */ | ||
740 | DBG("lba_fixup_bus() MMIO [%lx/%lx] -> ", | ||
741 | res->start, res->end); | ||
742 | res->start = PCI_HOST_ADDR(HBA_DATA(ldev), res->start); | ||
743 | res->end = PCI_HOST_ADDR(HBA_DATA(ldev), res->end); | ||
744 | DBG("[%lx/%lx]\n", res->start, res->end); | ||
745 | } else { | ||
746 | DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX", | ||
747 | res->flags, res->start, res->end); | ||
748 | } | ||
749 | |||
750 | /* | 728 | /* |
751 | ** FIXME: this will result in whinging for devices | 729 | ** FIXME: this will result in whinging for devices |
752 | ** that share expansion ROMs (think quad tulip), but | 730 | ** that share expansion ROMs (think quad tulip), but |
@@ -1514,11 +1492,14 @@ lba_driver_probe(struct parisc_device *dev) | |||
1514 | lba_dev->hba.lmmio_space.flags = 0; | 1492 | lba_dev->hba.lmmio_space.flags = 0; |
1515 | } | 1493 | } |
1516 | 1494 | ||
1517 | pci_add_resource(&resources, &lba_dev->hba.io_space); | 1495 | pci_add_resource_offset(&resources, &lba_dev->hba.io_space, |
1496 | HBA_PORT_BASE(lba_dev->hba.hba_num)); | ||
1518 | if (lba_dev->hba.elmmio_space.start) | 1497 | if (lba_dev->hba.elmmio_space.start) |
1519 | pci_add_resource(&resources, &lba_dev->hba.elmmio_space); | 1498 | pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space, |
1499 | lba_dev->hba.lmmio_space_offset); | ||
1520 | if (lba_dev->hba.lmmio_space.flags) | 1500 | if (lba_dev->hba.lmmio_space.flags) |
1521 | pci_add_resource(&resources, &lba_dev->hba.lmmio_space); | 1501 | pci_add_resource_offset(&resources, &lba_dev->hba.lmmio_space, |
1502 | lba_dev->hba.lmmio_space_offset); | ||
1522 | if (lba_dev->hba.gmmio_space.flags) | 1503 | if (lba_dev->hba.gmmio_space.flags) |
1523 | pci_add_resource(&resources, &lba_dev->hba.gmmio_space); | 1504 | pci_add_resource(&resources, &lba_dev->hba.gmmio_space); |
1524 | 1505 | ||
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 37856f7c7781..848bfb84c04c 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -31,6 +31,19 @@ config PCI_DEBUG | |||
31 | 31 | ||
32 | When in doubt, say N. | 32 | When in doubt, say N. |
33 | 33 | ||
34 | config PCI_REALLOC_ENABLE_AUTO | ||
35 | bool "Enable PCI resource re-allocation detection" | ||
36 | depends on PCI | ||
37 | help | ||
38 | Say Y here if you want the PCI core to detect if PCI resource | ||
39 | re-allocation needs to be enabled. You can always use pci=realloc=on | ||
40 | or pci=realloc=off to override it. Note this feature is a no-op | ||
41 | unless PCI_IOV support is also enabled; in that case it will | ||
42 | automatically re-allocate PCI resources if SR-IOV BARs have not | ||
43 | been allocated by the BIOS. | ||
44 | |||
45 | When in doubt, say N. | ||
46 | |||
34 | config PCI_STUB | 47 | config PCI_STUB |
35 | tristate "PCI Stub driver" | 48 | tristate "PCI Stub driver" |
36 | depends on PCI | 49 | depends on PCI |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 398f5d859791..4ce5ef2f2826 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -18,28 +18,36 @@ | |||
18 | 18 | ||
19 | #include "pci.h" | 19 | #include "pci.h" |
20 | 20 | ||
21 | void pci_add_resource(struct list_head *resources, struct resource *res) | 21 | void pci_add_resource_offset(struct list_head *resources, struct resource *res, |
22 | resource_size_t offset) | ||
22 | { | 23 | { |
23 | struct pci_bus_resource *bus_res; | 24 | struct pci_host_bridge_window *window; |
24 | 25 | ||
25 | bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL); | 26 | window = kzalloc(sizeof(struct pci_host_bridge_window), GFP_KERNEL); |
26 | if (!bus_res) { | 27 | if (!window) { |
27 | printk(KERN_ERR "PCI: can't add bus resource %pR\n", res); | 28 | printk(KERN_ERR "PCI: can't add host bridge window %pR\n", res); |
28 | return; | 29 | return; |
29 | } | 30 | } |
30 | 31 | ||
31 | bus_res->res = res; | 32 | window->res = res; |
32 | list_add_tail(&bus_res->list, resources); | 33 | window->offset = offset; |
34 | list_add_tail(&window->list, resources); | ||
35 | } | ||
36 | EXPORT_SYMBOL(pci_add_resource_offset); | ||
37 | |||
38 | void pci_add_resource(struct list_head *resources, struct resource *res) | ||
39 | { | ||
40 | pci_add_resource_offset(resources, res, 0); | ||
33 | } | 41 | } |
34 | EXPORT_SYMBOL(pci_add_resource); | 42 | EXPORT_SYMBOL(pci_add_resource); |
35 | 43 | ||
36 | void pci_free_resource_list(struct list_head *resources) | 44 | void pci_free_resource_list(struct list_head *resources) |
37 | { | 45 | { |
38 | struct pci_bus_resource *bus_res, *tmp; | 46 | struct pci_host_bridge_window *window, *tmp; |
39 | 47 | ||
40 | list_for_each_entry_safe(bus_res, tmp, resources, list) { | 48 | list_for_each_entry_safe(window, tmp, resources, list) { |
41 | list_del(&bus_res->list); | 49 | list_del(&window->list); |
42 | kfree(bus_res); | 50 | kfree(window); |
43 | } | 51 | } |
44 | } | 52 | } |
45 | EXPORT_SYMBOL(pci_free_resource_list); | 53 | EXPORT_SYMBOL(pci_free_resource_list); |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 9ddf69e3bbef..806c44fa645a 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -800,20 +800,10 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
800 | if (slot->flags & SLOT_ENABLED) | 800 | if (slot->flags & SLOT_ENABLED) |
801 | goto err_exit; | 801 | goto err_exit; |
802 | 802 | ||
803 | /* sanity check: dev should be NULL when hot-plugged in */ | ||
804 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); | ||
805 | if (dev) { | ||
806 | /* This case shouldn't happen */ | ||
807 | err("pci_dev structure already exists.\n"); | ||
808 | pci_dev_put(dev); | ||
809 | retval = -1; | ||
810 | goto err_exit; | ||
811 | } | ||
812 | |||
813 | num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); | 803 | num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); |
814 | if (num == 0) { | 804 | if (num == 0) { |
815 | err("No new device found\n"); | 805 | /* Maybe only part of funcs are added. */ |
816 | retval = -1; | 806 | dbg("No new device found\n"); |
817 | goto err_exit; | 807 | goto err_exit; |
818 | } | 808 | } |
819 | 809 | ||
@@ -848,11 +838,16 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
848 | 838 | ||
849 | pci_bus_add_devices(bus); | 839 | pci_bus_add_devices(bus); |
850 | 840 | ||
841 | slot->flags |= SLOT_ENABLED; | ||
851 | list_for_each_entry(func, &slot->funcs, sibling) { | 842 | list_for_each_entry(func, &slot->funcs, sibling) { |
852 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, | 843 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, |
853 | func->function)); | 844 | func->function)); |
854 | if (!dev) | 845 | if (!dev) { |
846 | /* Do not set SLOT_ENABLED flag if some funcs | ||
847 | are not added. */ | ||
848 | slot->flags &= (~SLOT_ENABLED); | ||
855 | continue; | 849 | continue; |
850 | } | ||
856 | 851 | ||
857 | if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && | 852 | if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && |
858 | dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) { | 853 | dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) { |
@@ -867,7 +862,6 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
867 | pci_dev_put(dev); | 862 | pci_dev_put(dev); |
868 | } | 863 | } |
869 | 864 | ||
870 | slot->flags |= SLOT_ENABLED; | ||
871 | 865 | ||
872 | err_exit: | 866 | err_exit: |
873 | return retval; | 867 | return retval; |
@@ -892,9 +886,12 @@ static int disable_device(struct acpiphp_slot *slot) | |||
892 | { | 886 | { |
893 | struct acpiphp_func *func; | 887 | struct acpiphp_func *func; |
894 | struct pci_dev *pdev; | 888 | struct pci_dev *pdev; |
889 | struct pci_bus *bus = slot->bridge->pci_bus; | ||
895 | 890 | ||
896 | /* is this slot already disabled? */ | 891 | /* The slot will be enabled when func 0 is added, so check |
897 | if (!(slot->flags & SLOT_ENABLED)) | 892 | func 0 before disable the slot. */ |
893 | pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); | ||
894 | if (!pdev) | ||
898 | goto err_exit; | 895 | goto err_exit; |
899 | 896 | ||
900 | list_for_each_entry(func, &slot->funcs, sibling) { | 897 | list_for_each_entry(func, &slot->funcs, sibling) { |
@@ -913,7 +910,7 @@ static int disable_device(struct acpiphp_slot *slot) | |||
913 | disable_bridges(pdev->subordinate); | 910 | disable_bridges(pdev->subordinate); |
914 | pci_disable_device(pdev); | 911 | pci_disable_device(pdev); |
915 | } | 912 | } |
916 | pci_remove_bus_device(pdev); | 913 | __pci_remove_bus_device(pdev); |
917 | pci_dev_put(pdev); | 914 | pci_dev_put(pdev); |
918 | } | 915 | } |
919 | } | 916 | } |
@@ -1070,7 +1067,7 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) | |||
1070 | res->end) { | 1067 | res->end) { |
1071 | /* Could not assign a required resources | 1068 | /* Could not assign a required resources |
1072 | * for this device, remove it */ | 1069 | * for this device, remove it */ |
1073 | pci_remove_bus_device(dev); | 1070 | pci_stop_and_remove_bus_device(dev); |
1074 | break; | 1071 | break; |
1075 | } | 1072 | } |
1076 | } | 1073 | } |
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 829c327cfb5e..ae853ccd0cd5 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -341,7 +341,7 @@ int cpci_unconfigure_slot(struct slot* slot) | |||
341 | dev = pci_get_slot(slot->bus, | 341 | dev = pci_get_slot(slot->bus, |
342 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); | 342 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); |
343 | if (dev) { | 343 | if (dev) { |
344 | pci_remove_bus_device(dev); | 344 | pci_stop_and_remove_bus_device(dev); |
345 | pci_dev_put(dev); | 345 | pci_dev_put(dev); |
346 | } | 346 | } |
347 | } | 347 | } |
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c index fb3f84661bdc..81af764c629b 100644 --- a/drivers/pci/hotplug/cpcihp_generic.c +++ b/drivers/pci/hotplug/cpcihp_generic.c | |||
@@ -62,7 +62,7 @@ | |||
62 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 62 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
63 | 63 | ||
64 | /* local variables */ | 64 | /* local variables */ |
65 | static int debug; | 65 | static bool debug; |
66 | static char *bridge; | 66 | static char *bridge; |
67 | static u8 bridge_busnr; | 67 | static u8 bridge_busnr; |
68 | static u8 bridge_slot; | 68 | static u8 bridge_slot; |
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 6173b9a4544e..1c8494021a42 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c | |||
@@ -127,7 +127,7 @@ int cpqhp_unconfigure_device(struct pci_func* func) | |||
127 | struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j)); | 127 | struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j)); |
128 | if (temp) { | 128 | if (temp) { |
129 | pci_dev_put(temp); | 129 | pci_dev_put(temp); |
130 | pci_remove_bus_device(temp); | 130 | pci_stop_and_remove_bus_device(temp); |
131 | } | 131 | } |
132 | } | 132 | } |
133 | return 0; | 133 | return 0; |
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 17d10e2e8fb6..a019c9a712be 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -40,7 +40,7 @@ static ssize_t legacy_show(struct kobject *kobj, struct attribute *attr, | |||
40 | 40 | ||
41 | static void remove_callback(void *data) | 41 | static void remove_callback(void *data) |
42 | { | 42 | { |
43 | pci_remove_bus_device((struct pci_dev *)data); | 43 | pci_stop_and_remove_bus_device((struct pci_dev *)data); |
44 | } | 44 | } |
45 | 45 | ||
46 | static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr, | 46 | static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr, |
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 5506e0e8fbc0..4fda7e6a86a7 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
@@ -721,7 +721,7 @@ static void ibm_unconfigure_device(struct pci_func *func) | |||
721 | for (j = 0; j < 0x08; j++) { | 721 | for (j = 0; j < 0x08; j++) { |
722 | temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j); | 722 | temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j); |
723 | if (temp) { | 723 | if (temp) { |
724 | pci_remove_bus_device(temp); | 724 | pci_stop_and_remove_bus_device(temp); |
725 | pci_dev_put(temp); | 725 | pci_dev_put(temp); |
726 | } | 726 | } |
727 | } | 727 | } |
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 2850e64dedae..714ca5c4ed50 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c | |||
@@ -368,8 +368,10 @@ int __init ibmphp_access_ebda (void) | |||
368 | debug ("rio blk id: %x\n", blk_id); | 368 | debug ("rio blk id: %x\n", blk_id); |
369 | 369 | ||
370 | rio_table_ptr = kzalloc(sizeof(struct rio_table_hdr), GFP_KERNEL); | 370 | rio_table_ptr = kzalloc(sizeof(struct rio_table_hdr), GFP_KERNEL); |
371 | if (!rio_table_ptr) | 371 | if (!rio_table_ptr) { |
372 | return -ENOMEM; | 372 | rc = -ENOMEM; |
373 | goto out; | ||
374 | } | ||
373 | rio_table_ptr->ver_num = readb (io_mem + offset); | 375 | rio_table_ptr->ver_num = readb (io_mem + offset); |
374 | rio_table_ptr->scal_count = readb (io_mem + offset + 1); | 376 | rio_table_ptr->scal_count = readb (io_mem + offset + 1); |
375 | rio_table_ptr->riodev_count = readb (io_mem + offset + 2); | 377 | rio_table_ptr->riodev_count = readb (io_mem + offset + 2); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index bcdbb1643621..a960faec1021 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -241,34 +241,79 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
241 | return retval; | 241 | return retval; |
242 | } | 242 | } |
243 | 243 | ||
244 | static inline int check_link_active(struct controller *ctrl) | 244 | static bool check_link_active(struct controller *ctrl) |
245 | { | 245 | { |
246 | u16 link_status; | 246 | bool ret = false; |
247 | u16 lnk_status; | ||
247 | 248 | ||
248 | if (pciehp_readw(ctrl, PCI_EXP_LNKSTA, &link_status)) | 249 | if (pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status)) |
249 | return 0; | 250 | return ret; |
250 | return !!(link_status & PCI_EXP_LNKSTA_DLLLA); | 251 | |
252 | ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA); | ||
253 | |||
254 | if (ret) | ||
255 | ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); | ||
256 | |||
257 | return ret; | ||
251 | } | 258 | } |
252 | 259 | ||
253 | static void pcie_wait_link_active(struct controller *ctrl) | 260 | static void __pcie_wait_link_active(struct controller *ctrl, bool active) |
254 | { | 261 | { |
255 | int timeout = 1000; | 262 | int timeout = 1000; |
256 | 263 | ||
257 | if (check_link_active(ctrl)) | 264 | if (check_link_active(ctrl) == active) |
258 | return; | 265 | return; |
259 | while (timeout > 0) { | 266 | while (timeout > 0) { |
260 | msleep(10); | 267 | msleep(10); |
261 | timeout -= 10; | 268 | timeout -= 10; |
262 | if (check_link_active(ctrl)) | 269 | if (check_link_active(ctrl) == active) |
263 | return; | 270 | return; |
264 | } | 271 | } |
265 | ctrl_dbg(ctrl, "Data Link Layer Link Active not set in 1000 msec\n"); | 272 | ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n", |
273 | active ? "set" : "cleared"); | ||
274 | } | ||
275 | |||
276 | static void pcie_wait_link_active(struct controller *ctrl) | ||
277 | { | ||
278 | __pcie_wait_link_active(ctrl, true); | ||
279 | } | ||
280 | |||
281 | static void pcie_wait_link_not_active(struct controller *ctrl) | ||
282 | { | ||
283 | __pcie_wait_link_active(ctrl, false); | ||
284 | } | ||
285 | |||
286 | static bool pci_bus_check_dev(struct pci_bus *bus, int devfn) | ||
287 | { | ||
288 | u32 l; | ||
289 | int count = 0; | ||
290 | int delay = 1000, step = 20; | ||
291 | bool found = false; | ||
292 | |||
293 | do { | ||
294 | found = pci_bus_read_dev_vendor_id(bus, devfn, &l, 0); | ||
295 | count++; | ||
296 | |||
297 | if (found) | ||
298 | break; | ||
299 | |||
300 | msleep(step); | ||
301 | delay -= step; | ||
302 | } while (delay > 0); | ||
303 | |||
304 | if (count > 1 && pciehp_debug) | ||
305 | printk(KERN_DEBUG "pci %04x:%02x:%02x.%d id reading try %d times with interval %d ms to get %08x\n", | ||
306 | pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), | ||
307 | PCI_FUNC(devfn), count, step, l); | ||
308 | |||
309 | return found; | ||
266 | } | 310 | } |
267 | 311 | ||
268 | int pciehp_check_link_status(struct controller *ctrl) | 312 | int pciehp_check_link_status(struct controller *ctrl) |
269 | { | 313 | { |
270 | u16 lnk_status; | 314 | u16 lnk_status; |
271 | int retval = 0; | 315 | int retval = 0; |
316 | bool found = false; | ||
272 | 317 | ||
273 | /* | 318 | /* |
274 | * Data Link Layer Link Active Reporting must be capable for | 319 | * Data Link Layer Link Active Reporting must be capable for |
@@ -280,13 +325,10 @@ int pciehp_check_link_status(struct controller *ctrl) | |||
280 | else | 325 | else |
281 | msleep(1000); | 326 | msleep(1000); |
282 | 327 | ||
283 | /* | 328 | /* wait 100ms before read pci conf, and try in 1s */ |
284 | * Need to wait for 1000 ms after Data Link Layer Link Active | 329 | msleep(100); |
285 | * (DLLLA) bit reads 1b before sending configuration request. | 330 | found = pci_bus_check_dev(ctrl->pcie->port->subordinate, |
286 | * We need it before checking Link Training (LT) bit becuase | 331 | PCI_DEVFN(0, 0)); |
287 | * LT is still set even after DLLLA bit is set on some platform. | ||
288 | */ | ||
289 | msleep(1000); | ||
290 | 332 | ||
291 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); | 333 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); |
292 | if (retval) { | 334 | if (retval) { |
@@ -302,19 +344,50 @@ int pciehp_check_link_status(struct controller *ctrl) | |||
302 | return retval; | 344 | return retval; |
303 | } | 345 | } |
304 | 346 | ||
305 | /* | ||
306 | * If the port supports Link speeds greater than 5.0 GT/s, we | ||
307 | * must wait for 100 ms after Link training completes before | ||
308 | * sending configuration request. | ||
309 | */ | ||
310 | if (ctrl->pcie->port->subordinate->max_bus_speed > PCIE_SPEED_5_0GT) | ||
311 | msleep(100); | ||
312 | |||
313 | pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); | 347 | pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); |
314 | 348 | ||
349 | if (!found && !retval) | ||
350 | retval = -1; | ||
351 | |||
315 | return retval; | 352 | return retval; |
316 | } | 353 | } |
317 | 354 | ||
355 | static int __pciehp_link_set(struct controller *ctrl, bool enable) | ||
356 | { | ||
357 | u16 lnk_ctrl; | ||
358 | int retval = 0; | ||
359 | |||
360 | retval = pciehp_readw(ctrl, PCI_EXP_LNKCTL, &lnk_ctrl); | ||
361 | if (retval) { | ||
362 | ctrl_err(ctrl, "Cannot read LNKCTRL register\n"); | ||
363 | return retval; | ||
364 | } | ||
365 | |||
366 | if (enable) | ||
367 | lnk_ctrl &= ~PCI_EXP_LNKCTL_LD; | ||
368 | else | ||
369 | lnk_ctrl |= PCI_EXP_LNKCTL_LD; | ||
370 | |||
371 | retval = pciehp_writew(ctrl, PCI_EXP_LNKCTL, lnk_ctrl); | ||
372 | if (retval) { | ||
373 | ctrl_err(ctrl, "Cannot write LNKCTRL register\n"); | ||
374 | return retval; | ||
375 | } | ||
376 | ctrl_dbg(ctrl, "%s: lnk_ctrl = %x\n", __func__, lnk_ctrl); | ||
377 | |||
378 | return retval; | ||
379 | } | ||
380 | |||
381 | static int pciehp_link_enable(struct controller *ctrl) | ||
382 | { | ||
383 | return __pciehp_link_set(ctrl, true); | ||
384 | } | ||
385 | |||
386 | static int pciehp_link_disable(struct controller *ctrl) | ||
387 | { | ||
388 | return __pciehp_link_set(ctrl, false); | ||
389 | } | ||
390 | |||
318 | int pciehp_get_attention_status(struct slot *slot, u8 *status) | 391 | int pciehp_get_attention_status(struct slot *slot, u8 *status) |
319 | { | 392 | { |
320 | struct controller *ctrl = slot->ctrl; | 393 | struct controller *ctrl = slot->ctrl; |
@@ -533,6 +606,10 @@ int pciehp_power_on_slot(struct slot * slot) | |||
533 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 606 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
534 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); | 607 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
535 | 608 | ||
609 | retval = pciehp_link_enable(ctrl); | ||
610 | if (retval) | ||
611 | ctrl_err(ctrl, "%s: Can not enable the link!\n", __func__); | ||
612 | |||
536 | return retval; | 613 | return retval; |
537 | } | 614 | } |
538 | 615 | ||
@@ -543,6 +620,14 @@ int pciehp_power_off_slot(struct slot * slot) | |||
543 | u16 cmd_mask; | 620 | u16 cmd_mask; |
544 | int retval; | 621 | int retval; |
545 | 622 | ||
623 | /* Disable the link at first */ | ||
624 | pciehp_link_disable(ctrl); | ||
625 | /* wait the link is down */ | ||
626 | if (ctrl->link_active_reporting) | ||
627 | pcie_wait_link_not_active(ctrl); | ||
628 | else | ||
629 | msleep(1000); | ||
630 | |||
546 | slot_cmd = POWER_OFF; | 631 | slot_cmd = POWER_OFF; |
547 | cmd_mask = PCI_EXP_SLTCTL_PCC; | 632 | cmd_mask = PCI_EXP_SLTCTL_PCC; |
548 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 633 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index a4031dfe938e..47d9dc06b109 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
@@ -141,7 +141,7 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
141 | break; | 141 | break; |
142 | } | 142 | } |
143 | } | 143 | } |
144 | pci_remove_bus_device(temp); | 144 | pci_stop_and_remove_bus_device(temp); |
145 | /* | 145 | /* |
146 | * Ensure that no new Requests will be generated from | 146 | * Ensure that no new Requests will be generated from |
147 | * the device. | 147 | * the device. |
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index c56a9413e1af..1e117c2a3cad 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
@@ -389,7 +389,7 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) | |||
389 | BUG_ON(!bus->self); | 389 | BUG_ON(!bus->self); |
390 | pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self)); | 390 | pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self)); |
391 | eeh_remove_bus_device(bus->self); | 391 | eeh_remove_bus_device(bus->self); |
392 | pci_remove_bus_device(bus->self); | 392 | pci_stop_and_remove_bus_device(bus->self); |
393 | 393 | ||
394 | return 0; | 394 | return 0; |
395 | } | 395 | } |
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index 72d507b6a2aa..de573113c102 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c | |||
@@ -554,7 +554,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
554 | PCI_FUNC(func))); | 554 | PCI_FUNC(func))); |
555 | if (dev) { | 555 | if (dev) { |
556 | sn_bus_free_data(dev); | 556 | sn_bus_free_data(dev); |
557 | pci_remove_bus_device(dev); | 557 | pci_stop_and_remove_bus_device(dev); |
558 | pci_dev_put(dev); | 558 | pci_dev_put(dev); |
559 | } | 559 | } |
560 | } | 560 | } |
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index a2ccfcd3c298..df7e4bfadae3 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c | |||
@@ -124,7 +124,7 @@ int shpchp_unconfigure_device(struct slot *p_slot) | |||
124 | break; | 124 | break; |
125 | } | 125 | } |
126 | } | 126 | } |
127 | pci_remove_bus_device(temp); | 127 | pci_stop_and_remove_bus_device(temp); |
128 | pci_dev_put(temp); | 128 | pci_dev_put(temp); |
129 | } | 129 | } |
130 | return rc; | 130 | return rc; |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 0dab5ecf61bb..6554e1a0f634 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -142,7 +142,7 @@ failed2: | |||
142 | failed1: | 142 | failed1: |
143 | pci_dev_put(dev); | 143 | pci_dev_put(dev); |
144 | mutex_lock(&iov->dev->sriov->lock); | 144 | mutex_lock(&iov->dev->sriov->lock); |
145 | pci_remove_bus_device(virtfn); | 145 | pci_stop_and_remove_bus_device(virtfn); |
146 | virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); | 146 | virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); |
147 | mutex_unlock(&iov->dev->sriov->lock); | 147 | mutex_unlock(&iov->dev->sriov->lock); |
148 | 148 | ||
@@ -173,10 +173,16 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset) | |||
173 | 173 | ||
174 | sprintf(buf, "virtfn%u", id); | 174 | sprintf(buf, "virtfn%u", id); |
175 | sysfs_remove_link(&dev->dev.kobj, buf); | 175 | sysfs_remove_link(&dev->dev.kobj, buf); |
176 | sysfs_remove_link(&virtfn->dev.kobj, "physfn"); | 176 | /* |
177 | * pci_stop_dev() could have been called for this virtfn already, | ||
178 | * so the directory for the virtfn may have been removed before. | ||
179 | * Double check to avoid spurious sysfs warnings. | ||
180 | */ | ||
181 | if (virtfn->dev.kobj.sd) | ||
182 | sysfs_remove_link(&virtfn->dev.kobj, "physfn"); | ||
177 | 183 | ||
178 | mutex_lock(&iov->dev->sriov->lock); | 184 | mutex_lock(&iov->dev->sriov->lock); |
179 | pci_remove_bus_device(virtfn); | 185 | pci_stop_and_remove_bus_device(virtfn); |
180 | virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); | 186 | virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); |
181 | mutex_unlock(&iov->dev->sriov->lock); | 187 | mutex_unlock(&iov->dev->sriov->lock); |
182 | 188 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 8d9616b821ca..6b54b23b990b 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -419,6 +419,16 @@ static void pci_device_shutdown(struct device *dev) | |||
419 | drv->shutdown(pci_dev); | 419 | drv->shutdown(pci_dev); |
420 | pci_msi_shutdown(pci_dev); | 420 | pci_msi_shutdown(pci_dev); |
421 | pci_msix_shutdown(pci_dev); | 421 | pci_msix_shutdown(pci_dev); |
422 | |||
423 | /* | ||
424 | * Devices may be enabled to wake up by runtime PM, but they need not | ||
425 | * be supposed to wake up the system from its "power off" state (e.g. | ||
426 | * ACPI S5). Therefore disable wakeup for all devices that aren't | ||
427 | * supposed to wake up the system at this point. The state argument | ||
428 | * will be ignored by pci_enable_wake(). | ||
429 | */ | ||
430 | if (!device_may_wakeup(dev)) | ||
431 | pci_enable_wake(pci_dev, PCI_UNKNOWN, false); | ||
422 | } | 432 | } |
423 | 433 | ||
424 | #ifdef CONFIG_PM | 434 | #ifdef CONFIG_PM |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index a3cd8cad532a..a55e248618cd 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -330,7 +330,7 @@ static void remove_callback(struct device *dev) | |||
330 | struct pci_dev *pdev = to_pci_dev(dev); | 330 | struct pci_dev *pdev = to_pci_dev(dev); |
331 | 331 | ||
332 | mutex_lock(&pci_remove_rescan_mutex); | 332 | mutex_lock(&pci_remove_rescan_mutex); |
333 | pci_remove_bus_device(pdev); | 333 | pci_stop_and_remove_bus_device(pdev); |
334 | mutex_unlock(&pci_remove_rescan_mutex); | 334 | mutex_unlock(&pci_remove_rescan_mutex); |
335 | } | 335 | } |
336 | 336 | ||
@@ -366,7 +366,10 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr, | |||
366 | 366 | ||
367 | if (val) { | 367 | if (val) { |
368 | mutex_lock(&pci_remove_rescan_mutex); | 368 | mutex_lock(&pci_remove_rescan_mutex); |
369 | pci_rescan_bus(bus); | 369 | if (!pci_is_root_bus(bus) && list_empty(&bus->devices)) |
370 | pci_rescan_bus_bridge_resize(bus->self); | ||
371 | else | ||
372 | pci_rescan_bus(bus); | ||
370 | mutex_unlock(&pci_remove_rescan_mutex); | 373 | mutex_unlock(&pci_remove_rescan_mutex); |
371 | } | 374 | } |
372 | return count; | 375 | return count; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 053670e09e2b..815674415267 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -94,6 +94,9 @@ u8 pci_cache_line_size; | |||
94 | */ | 94 | */ |
95 | unsigned int pcibios_max_latency = 255; | 95 | unsigned int pcibios_max_latency = 255; |
96 | 96 | ||
97 | /* If set, the PCIe ARI capability will not be used. */ | ||
98 | static bool pcie_ari_disabled; | ||
99 | |||
97 | /** | 100 | /** |
98 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children | 101 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children |
99 | * @bus: pointer to PCI bus structure to search | 102 | * @bus: pointer to PCI bus structure to search |
@@ -825,6 +828,19 @@ EXPORT_SYMBOL(pci_choose_state); | |||
825 | #define pcie_cap_has_sltctl2(type, flags) \ | 828 | #define pcie_cap_has_sltctl2(type, flags) \ |
826 | ((flags & PCI_EXP_FLAGS_VERS) > 1) | 829 | ((flags & PCI_EXP_FLAGS_VERS) > 1) |
827 | 830 | ||
831 | static struct pci_cap_saved_state *pci_find_saved_cap( | ||
832 | struct pci_dev *pci_dev, char cap) | ||
833 | { | ||
834 | struct pci_cap_saved_state *tmp; | ||
835 | struct hlist_node *pos; | ||
836 | |||
837 | hlist_for_each_entry(tmp, pos, &pci_dev->saved_cap_space, next) { | ||
838 | if (tmp->cap.cap_nr == cap) | ||
839 | return tmp; | ||
840 | } | ||
841 | return NULL; | ||
842 | } | ||
843 | |||
828 | static int pci_save_pcie_state(struct pci_dev *dev) | 844 | static int pci_save_pcie_state(struct pci_dev *dev) |
829 | { | 845 | { |
830 | int pos, i = 0; | 846 | int pos, i = 0; |
@@ -959,6 +975,7 @@ void pci_restore_state(struct pci_dev *dev) | |||
959 | { | 975 | { |
960 | int i; | 976 | int i; |
961 | u32 val; | 977 | u32 val; |
978 | int tries; | ||
962 | 979 | ||
963 | if (!dev->state_saved) | 980 | if (!dev->state_saved) |
964 | return; | 981 | return; |
@@ -973,12 +990,16 @@ void pci_restore_state(struct pci_dev *dev) | |||
973 | */ | 990 | */ |
974 | for (i = 15; i >= 0; i--) { | 991 | for (i = 15; i >= 0; i--) { |
975 | pci_read_config_dword(dev, i * 4, &val); | 992 | pci_read_config_dword(dev, i * 4, &val); |
976 | if (val != dev->saved_config_space[i]) { | 993 | tries = 10; |
994 | while (tries && val != dev->saved_config_space[i]) { | ||
977 | dev_dbg(&dev->dev, "restoring config " | 995 | dev_dbg(&dev->dev, "restoring config " |
978 | "space at offset %#x (was %#x, writing %#x)\n", | 996 | "space at offset %#x (was %#x, writing %#x)\n", |
979 | i, val, (int)dev->saved_config_space[i]); | 997 | i, val, (int)dev->saved_config_space[i]); |
980 | pci_write_config_dword(dev,i * 4, | 998 | pci_write_config_dword(dev,i * 4, |
981 | dev->saved_config_space[i]); | 999 | dev->saved_config_space[i]); |
1000 | pci_read_config_dword(dev, i * 4, &val); | ||
1001 | mdelay(10); | ||
1002 | tries--; | ||
982 | } | 1003 | } |
983 | } | 1004 | } |
984 | pci_restore_pcix_state(dev); | 1005 | pci_restore_pcix_state(dev); |
@@ -1864,6 +1885,12 @@ void platform_pci_wakeup_init(struct pci_dev *dev) | |||
1864 | platform_pci_sleep_wake(dev, false); | 1885 | platform_pci_sleep_wake(dev, false); |
1865 | } | 1886 | } |
1866 | 1887 | ||
1888 | static void pci_add_saved_cap(struct pci_dev *pci_dev, | ||
1889 | struct pci_cap_saved_state *new_cap) | ||
1890 | { | ||
1891 | hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); | ||
1892 | } | ||
1893 | |||
1867 | /** | 1894 | /** |
1868 | * pci_add_save_buffer - allocate buffer for saving given capability registers | 1895 | * pci_add_save_buffer - allocate buffer for saving given capability registers |
1869 | * @dev: the PCI device | 1896 | * @dev: the PCI device |
@@ -1911,6 +1938,15 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev) | |||
1911 | "unable to preallocate PCI-X save buffer\n"); | 1938 | "unable to preallocate PCI-X save buffer\n"); |
1912 | } | 1939 | } |
1913 | 1940 | ||
1941 | void pci_free_cap_save_buffers(struct pci_dev *dev) | ||
1942 | { | ||
1943 | struct pci_cap_saved_state *tmp; | ||
1944 | struct hlist_node *pos, *n; | ||
1945 | |||
1946 | hlist_for_each_entry_safe(tmp, pos, n, &dev->saved_cap_space, next) | ||
1947 | kfree(tmp); | ||
1948 | } | ||
1949 | |||
1914 | /** | 1950 | /** |
1915 | * pci_enable_ari - enable ARI forwarding if hardware support it | 1951 | * pci_enable_ari - enable ARI forwarding if hardware support it |
1916 | * @dev: the PCI device | 1952 | * @dev: the PCI device |
@@ -1922,7 +1958,7 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1922 | u16 flags, ctrl; | 1958 | u16 flags, ctrl; |
1923 | struct pci_dev *bridge; | 1959 | struct pci_dev *bridge; |
1924 | 1960 | ||
1925 | if (!pci_is_pcie(dev) || dev->devfn) | 1961 | if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) |
1926 | return; | 1962 | return; |
1927 | 1963 | ||
1928 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | 1964 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); |
@@ -3661,6 +3697,68 @@ int pci_is_reassigndev(struct pci_dev *dev) | |||
3661 | return (pci_specified_resource_alignment(dev) != 0); | 3697 | return (pci_specified_resource_alignment(dev) != 0); |
3662 | } | 3698 | } |
3663 | 3699 | ||
3700 | /* | ||
3701 | * This function disables memory decoding and releases memory resources | ||
3702 | * of the device specified by kernel's boot parameter 'pci=resource_alignment='. | ||
3703 | * It also rounds up size to specified alignment. | ||
3704 | * Later on, the kernel will assign page-aligned memory resource back | ||
3705 | * to the device. | ||
3706 | */ | ||
3707 | void pci_reassigndev_resource_alignment(struct pci_dev *dev) | ||
3708 | { | ||
3709 | int i; | ||
3710 | struct resource *r; | ||
3711 | resource_size_t align, size; | ||
3712 | u16 command; | ||
3713 | |||
3714 | if (!pci_is_reassigndev(dev)) | ||
3715 | return; | ||
3716 | |||
3717 | if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL && | ||
3718 | (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) { | ||
3719 | dev_warn(&dev->dev, | ||
3720 | "Can't reassign resources to host bridge.\n"); | ||
3721 | return; | ||
3722 | } | ||
3723 | |||
3724 | dev_info(&dev->dev, | ||
3725 | "Disabling memory decoding and releasing memory resources.\n"); | ||
3726 | pci_read_config_word(dev, PCI_COMMAND, &command); | ||
3727 | command &= ~PCI_COMMAND_MEMORY; | ||
3728 | pci_write_config_word(dev, PCI_COMMAND, command); | ||
3729 | |||
3730 | align = pci_specified_resource_alignment(dev); | ||
3731 | for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) { | ||
3732 | r = &dev->resource[i]; | ||
3733 | if (!(r->flags & IORESOURCE_MEM)) | ||
3734 | continue; | ||
3735 | size = resource_size(r); | ||
3736 | if (size < align) { | ||
3737 | size = align; | ||
3738 | dev_info(&dev->dev, | ||
3739 | "Rounding up size of resource #%d to %#llx.\n", | ||
3740 | i, (unsigned long long)size); | ||
3741 | } | ||
3742 | r->end = size - 1; | ||
3743 | r->start = 0; | ||
3744 | } | ||
3745 | /* Need to disable bridge's resource window, | ||
3746 | * to enable the kernel to reassign new resource | ||
3747 | * window later on. | ||
3748 | */ | ||
3749 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && | ||
3750 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
3751 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { | ||
3752 | r = &dev->resource[i]; | ||
3753 | if (!(r->flags & IORESOURCE_MEM)) | ||
3754 | continue; | ||
3755 | r->end = resource_size(r) - 1; | ||
3756 | r->start = 0; | ||
3757 | } | ||
3758 | pci_disable_bridge_window(dev); | ||
3759 | } | ||
3760 | } | ||
3761 | |||
3664 | ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) | 3762 | ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) |
3665 | { | 3763 | { |
3666 | if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) | 3764 | if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) |
@@ -3739,10 +3837,14 @@ static int __init pci_setup(char *str) | |||
3739 | pci_no_msi(); | 3837 | pci_no_msi(); |
3740 | } else if (!strcmp(str, "noaer")) { | 3838 | } else if (!strcmp(str, "noaer")) { |
3741 | pci_no_aer(); | 3839 | pci_no_aer(); |
3840 | } else if (!strncmp(str, "realloc=", 8)) { | ||
3841 | pci_realloc_get_opt(str + 8); | ||
3742 | } else if (!strncmp(str, "realloc", 7)) { | 3842 | } else if (!strncmp(str, "realloc", 7)) { |
3743 | pci_realloc(); | 3843 | pci_realloc_get_opt("on"); |
3744 | } else if (!strcmp(str, "nodomains")) { | 3844 | } else if (!strcmp(str, "nodomains")) { |
3745 | pci_no_domains(); | 3845 | pci_no_domains(); |
3846 | } else if (!strncmp(str, "noari", 5)) { | ||
3847 | pcie_ari_disabled = true; | ||
3746 | } else if (!strncmp(str, "cbiosize=", 9)) { | 3848 | } else if (!strncmp(str, "cbiosize=", 9)) { |
3747 | pci_cardbus_io_size = memparse(str + 9, &str); | 3849 | pci_cardbus_io_size = memparse(str + 9, &str); |
3748 | } else if (!strncmp(str, "cbmemsize=", 10)) { | 3850 | } else if (!strncmp(str, "cbmemsize=", 10)) { |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 1009a5e88e53..e4943479b234 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -73,6 +73,7 @@ extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); | |||
73 | extern void pci_pm_init(struct pci_dev *dev); | 73 | extern void pci_pm_init(struct pci_dev *dev); |
74 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | 74 | extern void platform_pci_wakeup_init(struct pci_dev *dev); |
75 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 75 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
76 | void pci_free_cap_save_buffers(struct pci_dev *dev); | ||
76 | 77 | ||
77 | static inline void pci_wakeup_event(struct pci_dev *dev) | 78 | static inline void pci_wakeup_event(struct pci_dev *dev) |
78 | { | 79 | { |
@@ -148,7 +149,7 @@ static inline void pci_no_msi(void) { } | |||
148 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } | 149 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } |
149 | #endif | 150 | #endif |
150 | 151 | ||
151 | extern void pci_realloc(void); | 152 | void pci_realloc_get_opt(char *); |
152 | 153 | ||
153 | static inline int pci_no_d1d2(struct pci_dev *dev) | 154 | static inline int pci_no_d1d2(struct pci_dev *dev) |
154 | { | 155 | { |
@@ -207,6 +208,8 @@ enum pci_bar_type { | |||
207 | pci_bar_mem64, /* A 64-bit memory BAR */ | 208 | pci_bar_mem64, /* A 64-bit memory BAR */ |
208 | }; | 209 | }; |
209 | 210 | ||
211 | bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, | ||
212 | int crs_timeout); | ||
210 | extern int pci_setup_device(struct pci_dev *dev); | 213 | extern int pci_setup_device(struct pci_dev *dev); |
211 | extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | 214 | extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, |
212 | struct resource *res, unsigned int reg); | 215 | struct resource *res, unsigned int reg); |
@@ -225,11 +228,8 @@ static inline int pci_ari_enabled(struct pci_bus *bus) | |||
225 | return bus->self && bus->self->ari_enabled; | 228 | return bus->self && bus->self->ari_enabled; |
226 | } | 229 | } |
227 | 230 | ||
228 | #ifdef CONFIG_PCI_QUIRKS | 231 | void pci_reassigndev_resource_alignment(struct pci_dev *dev); |
229 | extern int pci_is_reassigndev(struct pci_dev *dev); | ||
230 | resource_size_t pci_specified_resource_alignment(struct pci_dev *dev); | ||
231 | extern void pci_disable_bridge_window(struct pci_dev *dev); | 232 | extern void pci_disable_bridge_window(struct pci_dev *dev); |
232 | #endif | ||
233 | 233 | ||
234 | /* Single Root I/O Virtualization */ | 234 | /* Single Root I/O Virtualization */ |
235 | struct pci_sriov { | 235 | struct pci_sriov { |
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 72962cc92e0a..6c8bc5809787 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig | |||
@@ -55,6 +55,31 @@ config PCIEASPM_DEBUG | |||
55 | This enables PCI Express ASPM debug support. It will add per-device | 55 | This enables PCI Express ASPM debug support. It will add per-device |
56 | interface to control ASPM. | 56 | interface to control ASPM. |
57 | 57 | ||
58 | choice | ||
59 | prompt "Default ASPM policy" | ||
60 | default PCIEASPM_DEFAULT | ||
61 | depends on PCIEASPM | ||
62 | |||
63 | config PCIEASPM_DEFAULT | ||
64 | bool "BIOS default" | ||
65 | depends on PCIEASPM | ||
66 | help | ||
67 | Use the BIOS defaults for PCI Express ASPM. | ||
68 | |||
69 | config PCIEASPM_POWERSAVE | ||
70 | bool "Powersave" | ||
71 | depends on PCIEASPM | ||
72 | help | ||
73 | Enable PCI Express ASPM L0s and L1 where possible, even if the | ||
74 | BIOS did not. | ||
75 | |||
76 | config PCIEASPM_PERFORMANCE | ||
77 | bool "Performance" | ||
78 | depends on PCIEASPM | ||
79 | help | ||
80 | Disable PCI Express ASPM L0s and L1, even if the BIOS enabled them. | ||
81 | endchoice | ||
82 | |||
58 | config PCIE_PME | 83 | config PCIE_PME |
59 | def_bool y | 84 | def_bool y |
60 | depends on PCIEPORTBUS && PM_RUNTIME && EXPERIMENTAL && ACPI | 85 | depends on PCIEPORTBUS && PM_RUNTIME && EXPERIMENTAL && ACPI |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 24f049e73952..4bdef24cd412 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -76,7 +76,15 @@ static LIST_HEAD(link_list); | |||
76 | #define POLICY_DEFAULT 0 /* BIOS default setting */ | 76 | #define POLICY_DEFAULT 0 /* BIOS default setting */ |
77 | #define POLICY_PERFORMANCE 1 /* high performance */ | 77 | #define POLICY_PERFORMANCE 1 /* high performance */ |
78 | #define POLICY_POWERSAVE 2 /* high power saving */ | 78 | #define POLICY_POWERSAVE 2 /* high power saving */ |
79 | |||
80 | #ifdef CONFIG_PCIEASPM_PERFORMANCE | ||
81 | static int aspm_policy = POLICY_PERFORMANCE; | ||
82 | #elif defined CONFIG_PCIEASPM_POWERSAVE | ||
83 | static int aspm_policy = POLICY_POWERSAVE; | ||
84 | #else | ||
79 | static int aspm_policy; | 85 | static int aspm_policy; |
86 | #endif | ||
87 | |||
80 | static const char *policy_str[] = { | 88 | static const char *policy_str[] = { |
81 | [POLICY_DEFAULT] = "default", | 89 | [POLICY_DEFAULT] = "default", |
82 | [POLICY_PERFORMANCE] = "performance", | 90 | [POLICY_PERFORMANCE] = "performance", |
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index bd00a01aef14..eea2ca2375e6 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -34,6 +34,18 @@ struct pci_dev; | |||
34 | 34 | ||
35 | extern void pcie_clear_root_pme_status(struct pci_dev *dev); | 35 | extern void pcie_clear_root_pme_status(struct pci_dev *dev); |
36 | 36 | ||
37 | #ifdef CONFIG_HOTPLUG_PCI_PCIE | ||
38 | extern bool pciehp_msi_disabled; | ||
39 | |||
40 | static inline bool pciehp_no_msi(void) | ||
41 | { | ||
42 | return pciehp_msi_disabled; | ||
43 | } | ||
44 | |||
45 | #else /* !CONFIG_HOTPLUG_PCI_PCIE */ | ||
46 | static inline bool pciehp_no_msi(void) { return false; } | ||
47 | #endif /* !CONFIG_HOTPLUG_PCI_PCIE */ | ||
48 | |||
37 | #ifdef CONFIG_PCIE_PME | 49 | #ifdef CONFIG_PCIE_PME |
38 | extern bool pcie_pme_msi_disabled; | 50 | extern bool pcie_pme_msi_disabled; |
39 | 51 | ||
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 595654a1a6a6..2f589a54f9bd 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -19,6 +19,17 @@ | |||
19 | #include "../pci.h" | 19 | #include "../pci.h" |
20 | #include "portdrv.h" | 20 | #include "portdrv.h" |
21 | 21 | ||
22 | bool pciehp_msi_disabled; | ||
23 | |||
24 | static int __init pciehp_setup(char *str) | ||
25 | { | ||
26 | if (!strncmp(str, "nomsi", 5)) | ||
27 | pciehp_msi_disabled = true; | ||
28 | |||
29 | return 1; | ||
30 | } | ||
31 | __setup("pcie_hp=", pciehp_setup); | ||
32 | |||
22 | /** | 33 | /** |
23 | * release_pcie_device - free PCI Express port service device structure | 34 | * release_pcie_device - free PCI Express port service device structure |
24 | * @dev: Port service device to release | 35 | * @dev: Port service device to release |
@@ -189,8 +200,9 @@ static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask) | |||
189 | { | 200 | { |
190 | int i, irq = -1; | 201 | int i, irq = -1; |
191 | 202 | ||
192 | /* We have to use INTx if MSI cannot be used for PCIe PME. */ | 203 | /* We have to use INTx if MSI cannot be used for PCIe PME or pciehp. */ |
193 | if ((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) { | 204 | if (((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) || |
205 | ((mask & PCIE_PORT_SERVICE_HP) && pciehp_no_msi())) { | ||
194 | if (dev->pin) | 206 | if (dev->pin) |
195 | irq = dev->irq; | 207 | irq = dev->irq; |
196 | goto no_msi; | 208 | goto no_msi; |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 71eac9cd724d..5e1ca3c58a7d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | 15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ |
16 | #define CARDBUS_RESERVE_BUSNR 3 | 16 | #define CARDBUS_RESERVE_BUSNR 3 |
17 | 17 | ||
18 | static LIST_HEAD(pci_host_bridges); | ||
19 | |||
18 | /* Ugh. Need to stop exporting this to modules. */ | 20 | /* Ugh. Need to stop exporting this to modules. */ |
19 | LIST_HEAD(pci_root_buses); | 21 | LIST_HEAD(pci_root_buses); |
20 | EXPORT_SYMBOL(pci_root_buses); | 22 | EXPORT_SYMBOL(pci_root_buses); |
@@ -42,6 +44,82 @@ int no_pci_devices(void) | |||
42 | } | 44 | } |
43 | EXPORT_SYMBOL(no_pci_devices); | 45 | EXPORT_SYMBOL(no_pci_devices); |
44 | 46 | ||
47 | static struct pci_host_bridge *pci_host_bridge(struct pci_dev *dev) | ||
48 | { | ||
49 | struct pci_bus *bus; | ||
50 | struct pci_host_bridge *bridge; | ||
51 | |||
52 | bus = dev->bus; | ||
53 | while (bus->parent) | ||
54 | bus = bus->parent; | ||
55 | |||
56 | list_for_each_entry(bridge, &pci_host_bridges, list) { | ||
57 | if (bridge->bus == bus) | ||
58 | return bridge; | ||
59 | } | ||
60 | |||
61 | return NULL; | ||
62 | } | ||
63 | |||
64 | static bool resource_contains(struct resource *res1, struct resource *res2) | ||
65 | { | ||
66 | return res1->start <= res2->start && res1->end >= res2->end; | ||
67 | } | ||
68 | |||
69 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
70 | struct resource *res) | ||
71 | { | ||
72 | struct pci_host_bridge *bridge = pci_host_bridge(dev); | ||
73 | struct pci_host_bridge_window *window; | ||
74 | resource_size_t offset = 0; | ||
75 | |||
76 | list_for_each_entry(window, &bridge->windows, list) { | ||
77 | if (resource_type(res) != resource_type(window->res)) | ||
78 | continue; | ||
79 | |||
80 | if (resource_contains(window->res, res)) { | ||
81 | offset = window->offset; | ||
82 | break; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | region->start = res->start - offset; | ||
87 | region->end = res->end - offset; | ||
88 | } | ||
89 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
90 | |||
91 | static bool region_contains(struct pci_bus_region *region1, | ||
92 | struct pci_bus_region *region2) | ||
93 | { | ||
94 | return region1->start <= region2->start && region1->end >= region2->end; | ||
95 | } | ||
96 | |||
97 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
98 | struct pci_bus_region *region) | ||
99 | { | ||
100 | struct pci_host_bridge *bridge = pci_host_bridge(dev); | ||
101 | struct pci_host_bridge_window *window; | ||
102 | struct pci_bus_region bus_region; | ||
103 | resource_size_t offset = 0; | ||
104 | |||
105 | list_for_each_entry(window, &bridge->windows, list) { | ||
106 | if (resource_type(res) != resource_type(window->res)) | ||
107 | continue; | ||
108 | |||
109 | bus_region.start = window->res->start - window->offset; | ||
110 | bus_region.end = window->res->end - window->offset; | ||
111 | |||
112 | if (region_contains(&bus_region, region)) { | ||
113 | offset = window->offset; | ||
114 | break; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | res->start = region->start + offset; | ||
119 | res->end = region->end + offset; | ||
120 | } | ||
121 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
122 | |||
45 | /* | 123 | /* |
46 | * PCI Bus Class | 124 | * PCI Bus Class |
47 | */ | 125 | */ |
@@ -135,6 +213,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
135 | { | 213 | { |
136 | u32 l, sz, mask; | 214 | u32 l, sz, mask; |
137 | u16 orig_cmd; | 215 | u16 orig_cmd; |
216 | struct pci_bus_region region; | ||
138 | 217 | ||
139 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; | 218 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; |
140 | 219 | ||
@@ -214,11 +293,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
214 | /* Address above 32-bit boundary; disable the BAR */ | 293 | /* Address above 32-bit boundary; disable the BAR */ |
215 | pci_write_config_dword(dev, pos, 0); | 294 | pci_write_config_dword(dev, pos, 0); |
216 | pci_write_config_dword(dev, pos + 4, 0); | 295 | pci_write_config_dword(dev, pos + 4, 0); |
217 | res->start = 0; | 296 | region.start = 0; |
218 | res->end = sz64; | 297 | region.end = sz64; |
298 | pcibios_bus_to_resource(dev, res, ®ion); | ||
219 | } else { | 299 | } else { |
220 | res->start = l64; | 300 | region.start = l64; |
221 | res->end = l64 + sz64; | 301 | region.end = l64 + sz64; |
302 | pcibios_bus_to_resource(dev, res, ®ion); | ||
222 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", | 303 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", |
223 | pos, res); | 304 | pos, res); |
224 | } | 305 | } |
@@ -228,8 +309,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
228 | if (!sz) | 309 | if (!sz) |
229 | goto fail; | 310 | goto fail; |
230 | 311 | ||
231 | res->start = l; | 312 | region.start = l; |
232 | res->end = l + sz; | 313 | region.end = l + sz; |
314 | pcibios_bus_to_resource(dev, res, ®ion); | ||
233 | 315 | ||
234 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); | 316 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); |
235 | } | 317 | } |
@@ -266,7 +348,8 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child) | |||
266 | struct pci_dev *dev = child->self; | 348 | struct pci_dev *dev = child->self; |
267 | u8 io_base_lo, io_limit_lo; | 349 | u8 io_base_lo, io_limit_lo; |
268 | unsigned long base, limit; | 350 | unsigned long base, limit; |
269 | struct resource *res; | 351 | struct pci_bus_region region; |
352 | struct resource *res, res2; | ||
270 | 353 | ||
271 | res = child->resource[0]; | 354 | res = child->resource[0]; |
272 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); | 355 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); |
@@ -284,10 +367,14 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child) | |||
284 | 367 | ||
285 | if (base && base <= limit) { | 368 | if (base && base <= limit) { |
286 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; | 369 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; |
370 | res2.flags = res->flags; | ||
371 | region.start = base; | ||
372 | region.end = limit + 0xfff; | ||
373 | pcibios_bus_to_resource(dev, &res2, ®ion); | ||
287 | if (!res->start) | 374 | if (!res->start) |
288 | res->start = base; | 375 | res->start = res2.start; |
289 | if (!res->end) | 376 | if (!res->end) |
290 | res->end = limit + 0xfff; | 377 | res->end = res2.end; |
291 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 378 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
292 | } | 379 | } |
293 | } | 380 | } |
@@ -297,6 +384,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child) | |||
297 | struct pci_dev *dev = child->self; | 384 | struct pci_dev *dev = child->self; |
298 | u16 mem_base_lo, mem_limit_lo; | 385 | u16 mem_base_lo, mem_limit_lo; |
299 | unsigned long base, limit; | 386 | unsigned long base, limit; |
387 | struct pci_bus_region region; | ||
300 | struct resource *res; | 388 | struct resource *res; |
301 | 389 | ||
302 | res = child->resource[1]; | 390 | res = child->resource[1]; |
@@ -306,8 +394,9 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child) | |||
306 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; | 394 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; |
307 | if (base && base <= limit) { | 395 | if (base && base <= limit) { |
308 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; | 396 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; |
309 | res->start = base; | 397 | region.start = base; |
310 | res->end = limit + 0xfffff; | 398 | region.end = limit + 0xfffff; |
399 | pcibios_bus_to_resource(dev, res, ®ion); | ||
311 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 400 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
312 | } | 401 | } |
313 | } | 402 | } |
@@ -317,6 +406,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child) | |||
317 | struct pci_dev *dev = child->self; | 406 | struct pci_dev *dev = child->self; |
318 | u16 mem_base_lo, mem_limit_lo; | 407 | u16 mem_base_lo, mem_limit_lo; |
319 | unsigned long base, limit; | 408 | unsigned long base, limit; |
409 | struct pci_bus_region region; | ||
320 | struct resource *res; | 410 | struct resource *res; |
321 | 411 | ||
322 | res = child->resource[2]; | 412 | res = child->resource[2]; |
@@ -353,8 +443,9 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child) | |||
353 | IORESOURCE_MEM | IORESOURCE_PREFETCH; | 443 | IORESOURCE_MEM | IORESOURCE_PREFETCH; |
354 | if (res->flags & PCI_PREF_RANGE_TYPE_64) | 444 | if (res->flags & PCI_PREF_RANGE_TYPE_64) |
355 | res->flags |= IORESOURCE_MEM_64; | 445 | res->flags |= IORESOURCE_MEM_64; |
356 | res->start = base; | 446 | region.start = base; |
357 | res->end = limit + 0xfffff; | 447 | region.end = limit + 0xfffff; |
448 | pcibios_bus_to_resource(dev, res, ®ion); | ||
358 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 449 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
359 | } | 450 | } |
360 | } | 451 | } |
@@ -900,6 +991,8 @@ int pci_setup_device(struct pci_dev *dev) | |||
900 | u8 hdr_type; | 991 | u8 hdr_type; |
901 | struct pci_slot *slot; | 992 | struct pci_slot *slot; |
902 | int pos = 0; | 993 | int pos = 0; |
994 | struct pci_bus_region region; | ||
995 | struct resource *res; | ||
903 | 996 | ||
904 | if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) | 997 | if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) |
905 | return -EIO; | 998 | return -EIO; |
@@ -926,12 +1019,10 @@ int pci_setup_device(struct pci_dev *dev) | |||
926 | 1019 | ||
927 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); | 1020 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); |
928 | dev->revision = class & 0xff; | 1021 | dev->revision = class & 0xff; |
929 | class >>= 8; /* upper 3 bytes */ | 1022 | dev->class = class >> 8; /* upper 3 bytes */ |
930 | dev->class = class; | ||
931 | class >>= 8; | ||
932 | 1023 | ||
933 | dev_printk(KERN_DEBUG, &dev->dev, "[%04x:%04x] type %d class %#08x\n", | 1024 | dev_printk(KERN_DEBUG, &dev->dev, "[%04x:%04x] type %02x class %#08x\n", |
934 | dev->vendor, dev->device, dev->hdr_type, class); | 1025 | dev->vendor, dev->device, dev->hdr_type, dev->class); |
935 | 1026 | ||
936 | /* need to have dev->class ready */ | 1027 | /* need to have dev->class ready */ |
937 | dev->cfg_size = pci_cfg_space_size(dev); | 1028 | dev->cfg_size = pci_cfg_space_size(dev); |
@@ -963,20 +1054,28 @@ int pci_setup_device(struct pci_dev *dev) | |||
963 | u8 progif; | 1054 | u8 progif; |
964 | pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); | 1055 | pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); |
965 | if ((progif & 1) == 0) { | 1056 | if ((progif & 1) == 0) { |
966 | dev->resource[0].start = 0x1F0; | 1057 | region.start = 0x1F0; |
967 | dev->resource[0].end = 0x1F7; | 1058 | region.end = 0x1F7; |
968 | dev->resource[0].flags = LEGACY_IO_RESOURCE; | 1059 | res = &dev->resource[0]; |
969 | dev->resource[1].start = 0x3F6; | 1060 | res->flags = LEGACY_IO_RESOURCE; |
970 | dev->resource[1].end = 0x3F6; | 1061 | pcibios_bus_to_resource(dev, res, ®ion); |
971 | dev->resource[1].flags = LEGACY_IO_RESOURCE; | 1062 | region.start = 0x3F6; |
1063 | region.end = 0x3F6; | ||
1064 | res = &dev->resource[1]; | ||
1065 | res->flags = LEGACY_IO_RESOURCE; | ||
1066 | pcibios_bus_to_resource(dev, res, ®ion); | ||
972 | } | 1067 | } |
973 | if ((progif & 4) == 0) { | 1068 | if ((progif & 4) == 0) { |
974 | dev->resource[2].start = 0x170; | 1069 | region.start = 0x170; |
975 | dev->resource[2].end = 0x177; | 1070 | region.end = 0x177; |
976 | dev->resource[2].flags = LEGACY_IO_RESOURCE; | 1071 | res = &dev->resource[2]; |
977 | dev->resource[3].start = 0x376; | 1072 | res->flags = LEGACY_IO_RESOURCE; |
978 | dev->resource[3].end = 0x376; | 1073 | pcibios_bus_to_resource(dev, res, ®ion); |
979 | dev->resource[3].flags = LEGACY_IO_RESOURCE; | 1074 | region.start = 0x376; |
1075 | region.end = 0x376; | ||
1076 | res = &dev->resource[3]; | ||
1077 | res->flags = LEGACY_IO_RESOURCE; | ||
1078 | pcibios_bus_to_resource(dev, res, ®ion); | ||
980 | } | 1079 | } |
981 | } | 1080 | } |
982 | break; | 1081 | break; |
@@ -1013,8 +1112,8 @@ int pci_setup_device(struct pci_dev *dev) | |||
1013 | return -EIO; | 1112 | return -EIO; |
1014 | 1113 | ||
1015 | bad: | 1114 | bad: |
1016 | dev_err(&dev->dev, "ignoring class %02x (doesn't match header " | 1115 | dev_err(&dev->dev, "ignoring class %#08x (doesn't match header " |
1017 | "type %02x)\n", class, dev->hdr_type); | 1116 | "type %02x)\n", dev->class, dev->hdr_type); |
1018 | dev->class = PCI_CLASS_NOT_DEFINED; | 1117 | dev->class = PCI_CLASS_NOT_DEFINED; |
1019 | } | 1118 | } |
1020 | 1119 | ||
@@ -1026,6 +1125,7 @@ static void pci_release_capabilities(struct pci_dev *dev) | |||
1026 | { | 1125 | { |
1027 | pci_vpd_release(dev); | 1126 | pci_vpd_release(dev); |
1028 | pci_iov_release(dev); | 1127 | pci_iov_release(dev); |
1128 | pci_free_cap_save_buffers(dev); | ||
1029 | } | 1129 | } |
1030 | 1130 | ||
1031 | /** | 1131 | /** |
@@ -1118,40 +1218,54 @@ struct pci_dev *alloc_pci_dev(void) | |||
1118 | } | 1218 | } |
1119 | EXPORT_SYMBOL(alloc_pci_dev); | 1219 | EXPORT_SYMBOL(alloc_pci_dev); |
1120 | 1220 | ||
1121 | /* | 1221 | bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l, |
1122 | * Read the config data for a PCI device, sanity-check it | 1222 | int crs_timeout) |
1123 | * and fill in the dev structure... | ||
1124 | */ | ||
1125 | static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) | ||
1126 | { | 1223 | { |
1127 | struct pci_dev *dev; | ||
1128 | u32 l; | ||
1129 | int delay = 1; | 1224 | int delay = 1; |
1130 | 1225 | ||
1131 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l)) | 1226 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) |
1132 | return NULL; | 1227 | return false; |
1133 | 1228 | ||
1134 | /* some broken boards return 0 or ~0 if a slot is empty: */ | 1229 | /* some broken boards return 0 or ~0 if a slot is empty: */ |
1135 | if (l == 0xffffffff || l == 0x00000000 || | 1230 | if (*l == 0xffffffff || *l == 0x00000000 || |
1136 | l == 0x0000ffff || l == 0xffff0000) | 1231 | *l == 0x0000ffff || *l == 0xffff0000) |
1137 | return NULL; | 1232 | return false; |
1138 | 1233 | ||
1139 | /* Configuration request Retry Status */ | 1234 | /* Configuration request Retry Status */ |
1140 | while (l == 0xffff0001) { | 1235 | while (*l == 0xffff0001) { |
1236 | if (!crs_timeout) | ||
1237 | return false; | ||
1238 | |||
1141 | msleep(delay); | 1239 | msleep(delay); |
1142 | delay *= 2; | 1240 | delay *= 2; |
1143 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l)) | 1241 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) |
1144 | return NULL; | 1242 | return false; |
1145 | /* Card hasn't responded in 60 seconds? Must be stuck. */ | 1243 | /* Card hasn't responded in 60 seconds? Must be stuck. */ |
1146 | if (delay > 60 * 1000) { | 1244 | if (delay > crs_timeout) { |
1147 | printk(KERN_WARNING "pci %04x:%02x:%02x.%d: not " | 1245 | printk(KERN_WARNING "pci %04x:%02x:%02x.%d: not " |
1148 | "responding\n", pci_domain_nr(bus), | 1246 | "responding\n", pci_domain_nr(bus), |
1149 | bus->number, PCI_SLOT(devfn), | 1247 | bus->number, PCI_SLOT(devfn), |
1150 | PCI_FUNC(devfn)); | 1248 | PCI_FUNC(devfn)); |
1151 | return NULL; | 1249 | return false; |
1152 | } | 1250 | } |
1153 | } | 1251 | } |
1154 | 1252 | ||
1253 | return true; | ||
1254 | } | ||
1255 | EXPORT_SYMBOL(pci_bus_read_dev_vendor_id); | ||
1256 | |||
1257 | /* | ||
1258 | * Read the config data for a PCI device, sanity-check it | ||
1259 | * and fill in the dev structure... | ||
1260 | */ | ||
1261 | static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) | ||
1262 | { | ||
1263 | struct pci_dev *dev; | ||
1264 | u32 l; | ||
1265 | |||
1266 | if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000)) | ||
1267 | return NULL; | ||
1268 | |||
1155 | dev = alloc_pci_dev(); | 1269 | dev = alloc_pci_dev(); |
1156 | if (!dev) | 1270 | if (!dev) |
1157 | return NULL; | 1271 | return NULL; |
@@ -1212,6 +1326,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | |||
1212 | /* Fix up broken headers */ | 1326 | /* Fix up broken headers */ |
1213 | pci_fixup_device(pci_fixup_header, dev); | 1327 | pci_fixup_device(pci_fixup_header, dev); |
1214 | 1328 | ||
1329 | /* moved out from quirk header fixup code */ | ||
1330 | pci_reassigndev_resource_alignment(dev); | ||
1331 | |||
1215 | /* Clear the state_saved flag. */ | 1332 | /* Clear the state_saved flag. */ |
1216 | dev->state_saved = false; | 1333 | dev->state_saved = false; |
1217 | 1334 | ||
@@ -1530,21 +1647,27 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1530 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | 1647 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, |
1531 | struct pci_ops *ops, void *sysdata, struct list_head *resources) | 1648 | struct pci_ops *ops, void *sysdata, struct list_head *resources) |
1532 | { | 1649 | { |
1533 | int error, i; | 1650 | int error; |
1651 | struct pci_host_bridge *bridge; | ||
1534 | struct pci_bus *b, *b2; | 1652 | struct pci_bus *b, *b2; |
1535 | struct device *dev; | 1653 | struct device *dev; |
1536 | struct pci_bus_resource *bus_res, *n; | 1654 | struct pci_host_bridge_window *window, *n; |
1537 | struct resource *res; | 1655 | struct resource *res; |
1656 | resource_size_t offset; | ||
1657 | char bus_addr[64]; | ||
1658 | char *fmt; | ||
1659 | |||
1660 | bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); | ||
1661 | if (!bridge) | ||
1662 | return NULL; | ||
1538 | 1663 | ||
1539 | b = pci_alloc_bus(); | 1664 | b = pci_alloc_bus(); |
1540 | if (!b) | 1665 | if (!b) |
1541 | return NULL; | 1666 | goto err_bus; |
1542 | 1667 | ||
1543 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 1668 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
1544 | if (!dev) { | 1669 | if (!dev) |
1545 | kfree(b); | 1670 | goto err_dev; |
1546 | return NULL; | ||
1547 | } | ||
1548 | 1671 | ||
1549 | b->sysdata = sysdata; | 1672 | b->sysdata = sysdata; |
1550 | b->ops = ops; | 1673 | b->ops = ops; |
@@ -1556,10 +1679,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1556 | goto err_out; | 1679 | goto err_out; |
1557 | } | 1680 | } |
1558 | 1681 | ||
1559 | down_write(&pci_bus_sem); | ||
1560 | list_add_tail(&b->node, &pci_root_buses); | ||
1561 | up_write(&pci_bus_sem); | ||
1562 | |||
1563 | dev->parent = parent; | 1682 | dev->parent = parent; |
1564 | dev->release = pci_release_bus_bridge_dev; | 1683 | dev->release = pci_release_bus_bridge_dev; |
1565 | dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus); | 1684 | dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus); |
@@ -1585,31 +1704,53 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1585 | 1704 | ||
1586 | b->number = b->secondary = bus; | 1705 | b->number = b->secondary = bus; |
1587 | 1706 | ||
1588 | /* Add initial resources to the bus */ | 1707 | bridge->bus = b; |
1589 | list_for_each_entry_safe(bus_res, n, resources, list) | 1708 | INIT_LIST_HEAD(&bridge->windows); |
1590 | list_move_tail(&bus_res->list, &b->resources); | ||
1591 | 1709 | ||
1592 | if (parent) | 1710 | if (parent) |
1593 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); | 1711 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); |
1594 | else | 1712 | else |
1595 | printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev)); | 1713 | printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev)); |
1596 | 1714 | ||
1597 | pci_bus_for_each_resource(b, res, i) { | 1715 | /* Add initial resources to the bus */ |
1598 | if (res) | 1716 | list_for_each_entry_safe(window, n, resources, list) { |
1599 | dev_info(&b->dev, "root bus resource %pR\n", res); | 1717 | list_move_tail(&window->list, &bridge->windows); |
1718 | res = window->res; | ||
1719 | offset = window->offset; | ||
1720 | pci_bus_add_resource(b, res, 0); | ||
1721 | if (offset) { | ||
1722 | if (resource_type(res) == IORESOURCE_IO) | ||
1723 | fmt = " (bus address [%#06llx-%#06llx])"; | ||
1724 | else | ||
1725 | fmt = " (bus address [%#010llx-%#010llx])"; | ||
1726 | snprintf(bus_addr, sizeof(bus_addr), fmt, | ||
1727 | (unsigned long long) (res->start - offset), | ||
1728 | (unsigned long long) (res->end - offset)); | ||
1729 | } else | ||
1730 | bus_addr[0] = '\0'; | ||
1731 | dev_info(&b->dev, "root bus resource %pR%s\n", res, bus_addr); | ||
1600 | } | 1732 | } |
1601 | 1733 | ||
1734 | down_write(&pci_bus_sem); | ||
1735 | list_add_tail(&bridge->list, &pci_host_bridges); | ||
1736 | list_add_tail(&b->node, &pci_root_buses); | ||
1737 | up_write(&pci_bus_sem); | ||
1738 | |||
1602 | return b; | 1739 | return b; |
1603 | 1740 | ||
1604 | class_dev_reg_err: | 1741 | class_dev_reg_err: |
1605 | device_unregister(dev); | 1742 | device_unregister(dev); |
1606 | dev_reg_err: | 1743 | dev_reg_err: |
1607 | down_write(&pci_bus_sem); | 1744 | down_write(&pci_bus_sem); |
1745 | list_del(&bridge->list); | ||
1608 | list_del(&b->node); | 1746 | list_del(&b->node); |
1609 | up_write(&pci_bus_sem); | 1747 | up_write(&pci_bus_sem); |
1610 | err_out: | 1748 | err_out: |
1611 | kfree(dev); | 1749 | kfree(dev); |
1750 | err_dev: | ||
1612 | kfree(b); | 1751 | kfree(b); |
1752 | err_bus: | ||
1753 | kfree(bridge); | ||
1613 | return NULL; | 1754 | return NULL; |
1614 | } | 1755 | } |
1615 | 1756 | ||
@@ -1667,36 +1808,29 @@ EXPORT_SYMBOL(pci_scan_bus); | |||
1667 | 1808 | ||
1668 | #ifdef CONFIG_HOTPLUG | 1809 | #ifdef CONFIG_HOTPLUG |
1669 | /** | 1810 | /** |
1670 | * pci_rescan_bus - scan a PCI bus for devices. | 1811 | * pci_rescan_bus_bridge_resize - scan a PCI bus for devices. |
1671 | * @bus: PCI bus to scan | 1812 | * @bridge: PCI bridge for the bus to scan |
1672 | * | 1813 | * |
1673 | * Scan a PCI bus and child buses for new devices, adds them, | 1814 | * Scan a PCI bus and child buses for new devices, add them, |
1674 | * and enables them. | 1815 | * and enable them, resizing bridge mmio/io resource if necessary |
1816 | * and possible. The caller must ensure the child devices are already | ||
1817 | * removed for resizing to occur. | ||
1675 | * | 1818 | * |
1676 | * Returns the max number of subordinate bus discovered. | 1819 | * Returns the max number of subordinate bus discovered. |
1677 | */ | 1820 | */ |
1678 | unsigned int __ref pci_rescan_bus(struct pci_bus *bus) | 1821 | unsigned int __ref pci_rescan_bus_bridge_resize(struct pci_dev *bridge) |
1679 | { | 1822 | { |
1680 | unsigned int max; | 1823 | unsigned int max; |
1681 | struct pci_dev *dev; | 1824 | struct pci_bus *bus = bridge->subordinate; |
1682 | 1825 | ||
1683 | max = pci_scan_child_bus(bus); | 1826 | max = pci_scan_child_bus(bus); |
1684 | 1827 | ||
1685 | down_read(&pci_bus_sem); | 1828 | pci_assign_unassigned_bridge_resources(bridge); |
1686 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
1687 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | ||
1688 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) | ||
1689 | if (dev->subordinate) | ||
1690 | pci_bus_size_bridges(dev->subordinate); | ||
1691 | up_read(&pci_bus_sem); | ||
1692 | 1829 | ||
1693 | pci_bus_assign_resources(bus); | ||
1694 | pci_enable_bridges(bus); | ||
1695 | pci_bus_add_devices(bus); | 1830 | pci_bus_add_devices(bus); |
1696 | 1831 | ||
1697 | return max; | 1832 | return max; |
1698 | } | 1833 | } |
1699 | EXPORT_SYMBOL_GPL(pci_rescan_bus); | ||
1700 | 1834 | ||
1701 | EXPORT_SYMBOL(pci_add_new_bus); | 1835 | EXPORT_SYMBOL(pci_add_new_bus); |
1702 | EXPORT_SYMBOL(pci_scan_slot); | 1836 | EXPORT_SYMBOL(pci_scan_slot); |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f722c5f6951a..4bf71028556b 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -26,73 +26,12 @@ | |||
26 | #include <linux/dmi.h> | 26 | #include <linux/dmi.h> |
27 | #include <linux/pci-aspm.h> | 27 | #include <linux/pci-aspm.h> |
28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/sched.h> | ||
30 | #include <linux/ktime.h> | ||
29 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ | 31 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ |
30 | #include "pci.h" | 32 | #include "pci.h" |
31 | 33 | ||
32 | /* | 34 | /* |
33 | * This quirk function disables memory decoding and releases memory resources | ||
34 | * of the device specified by kernel's boot parameter 'pci=resource_alignment='. | ||
35 | * It also rounds up size to specified alignment. | ||
36 | * Later on, the kernel will assign page-aligned memory resource back | ||
37 | * to the device. | ||
38 | */ | ||
39 | static void __devinit quirk_resource_alignment(struct pci_dev *dev) | ||
40 | { | ||
41 | int i; | ||
42 | struct resource *r; | ||
43 | resource_size_t align, size; | ||
44 | u16 command; | ||
45 | |||
46 | if (!pci_is_reassigndev(dev)) | ||
47 | return; | ||
48 | |||
49 | if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL && | ||
50 | (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) { | ||
51 | dev_warn(&dev->dev, | ||
52 | "Can't reassign resources to host bridge.\n"); | ||
53 | return; | ||
54 | } | ||
55 | |||
56 | dev_info(&dev->dev, | ||
57 | "Disabling memory decoding and releasing memory resources.\n"); | ||
58 | pci_read_config_word(dev, PCI_COMMAND, &command); | ||
59 | command &= ~PCI_COMMAND_MEMORY; | ||
60 | pci_write_config_word(dev, PCI_COMMAND, command); | ||
61 | |||
62 | align = pci_specified_resource_alignment(dev); | ||
63 | for (i=0; i < PCI_BRIDGE_RESOURCES; i++) { | ||
64 | r = &dev->resource[i]; | ||
65 | if (!(r->flags & IORESOURCE_MEM)) | ||
66 | continue; | ||
67 | size = resource_size(r); | ||
68 | if (size < align) { | ||
69 | size = align; | ||
70 | dev_info(&dev->dev, | ||
71 | "Rounding up size of resource #%d to %#llx.\n", | ||
72 | i, (unsigned long long)size); | ||
73 | } | ||
74 | r->end = size - 1; | ||
75 | r->start = 0; | ||
76 | } | ||
77 | /* Need to disable bridge's resource window, | ||
78 | * to enable the kernel to reassign new resource | ||
79 | * window later on. | ||
80 | */ | ||
81 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && | ||
82 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
83 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { | ||
84 | r = &dev->resource[i]; | ||
85 | if (!(r->flags & IORESOURCE_MEM)) | ||
86 | continue; | ||
87 | r->end = resource_size(r) - 1; | ||
88 | r->start = 0; | ||
89 | } | ||
90 | pci_disable_bridge_window(dev); | ||
91 | } | ||
92 | } | ||
93 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment); | ||
94 | |||
95 | /* | ||
96 | * Decoding should be disabled for a PCI device during BAR sizing to avoid | 35 | * Decoding should be disabled for a PCI device during BAR sizing to avoid |
97 | * conflict. But doing so may cause problems on host bridge and perhaps other | 36 | * conflict. But doing so may cause problems on host bridge and perhaps other |
98 | * key system devices. For devices that need to have mmio decoding always-on, | 37 | * key system devices. For devices that need to have mmio decoding always-on, |
@@ -100,10 +39,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment); | |||
100 | */ | 39 | */ |
101 | static void __devinit quirk_mmio_always_on(struct pci_dev *dev) | 40 | static void __devinit quirk_mmio_always_on(struct pci_dev *dev) |
102 | { | 41 | { |
103 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) | 42 | dev->mmio_always_on = 1; |
104 | dev->mmio_always_on = 1; | ||
105 | } | 43 | } |
106 | DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_mmio_always_on); | 44 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID, |
45 | PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on); | ||
107 | 46 | ||
108 | /* The Mellanox Tavor device gives false positive parity errors | 47 | /* The Mellanox Tavor device gives false positive parity errors |
109 | * Mark this device with a broken_parity_status, to allow | 48 | * Mark this device with a broken_parity_status, to allow |
@@ -1002,12 +941,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt | |||
1002 | */ | 941 | */ |
1003 | static void quirk_cardbus_legacy(struct pci_dev *dev) | 942 | static void quirk_cardbus_legacy(struct pci_dev *dev) |
1004 | { | 943 | { |
1005 | if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class) | ||
1006 | return; | ||
1007 | pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0); | 944 | pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0); |
1008 | } | 945 | } |
1009 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); | 946 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, |
1010 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); | 947 | PCI_CLASS_BRIDGE_CARDBUS, 8, quirk_cardbus_legacy); |
948 | DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(PCI_ANY_ID, PCI_ANY_ID, | ||
949 | PCI_CLASS_BRIDGE_CARDBUS, 8, quirk_cardbus_legacy); | ||
1011 | 950 | ||
1012 | /* | 951 | /* |
1013 | * Following the PCI ordering rules is optional on the AMD762. I'm not | 952 | * Following the PCI ordering rules is optional on the AMD762. I'm not |
@@ -1164,17 +1103,20 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, qui | |||
1164 | 1103 | ||
1165 | static void __devinit quirk_no_ata_d3(struct pci_dev *pdev) | 1104 | static void __devinit quirk_no_ata_d3(struct pci_dev *pdev) |
1166 | { | 1105 | { |
1167 | /* Quirk the legacy ATA devices only. The AHCI ones are ok */ | 1106 | pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3; |
1168 | if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) | ||
1169 | pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3; | ||
1170 | } | 1107 | } |
1171 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_ANY_ID, quirk_no_ata_d3); | 1108 | /* Quirk the legacy ATA devices only. The AHCI ones are ok */ |
1172 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, PCI_ANY_ID, quirk_no_ata_d3); | 1109 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_ANY_ID, |
1110 | PCI_CLASS_STORAGE_IDE, 8, quirk_no_ata_d3); | ||
1111 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_ATI, PCI_ANY_ID, | ||
1112 | PCI_CLASS_STORAGE_IDE, 8, quirk_no_ata_d3); | ||
1173 | /* ALi loses some register settings that we cannot then restore */ | 1113 | /* ALi loses some register settings that we cannot then restore */ |
1174 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, PCI_ANY_ID, quirk_no_ata_d3); | 1114 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AL, PCI_ANY_ID, |
1115 | PCI_CLASS_STORAGE_IDE, 8, quirk_no_ata_d3); | ||
1175 | /* VIA comes back fine but we need to keep it alive or ACPI GTM failures | 1116 | /* VIA comes back fine but we need to keep it alive or ACPI GTM failures |
1176 | occur when mode detecting */ | 1117 | occur when mode detecting */ |
1177 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_no_ata_d3); | 1118 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_VIA, PCI_ANY_ID, |
1119 | PCI_CLASS_STORAGE_IDE, 8, quirk_no_ata_d3); | ||
1178 | 1120 | ||
1179 | /* This was originally an Alpha specific thing, but it really fits here. | 1121 | /* This was originally an Alpha specific thing, but it really fits here. |
1180 | * The i82375 PCI/EISA bridge appears as non-classified. Fix that. | 1122 | * The i82375 PCI/EISA bridge appears as non-classified. Fix that. |
@@ -1873,8 +1815,7 @@ static void __devinit quirk_netmos(struct pci_dev *dev) | |||
1873 | case PCI_DEVICE_ID_NETMOS_9745: | 1815 | case PCI_DEVICE_ID_NETMOS_9745: |
1874 | case PCI_DEVICE_ID_NETMOS_9845: | 1816 | case PCI_DEVICE_ID_NETMOS_9845: |
1875 | case PCI_DEVICE_ID_NETMOS_9855: | 1817 | case PCI_DEVICE_ID_NETMOS_9855: |
1876 | if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_SERIAL && | 1818 | if (num_parallel) { |
1877 | num_parallel) { | ||
1878 | dev_info(&dev->dev, "Netmos %04x (%u parallel, " | 1819 | dev_info(&dev->dev, "Netmos %04x (%u parallel, " |
1879 | "%u serial); changing class SERIAL to OTHER " | 1820 | "%u serial); changing class SERIAL to OTHER " |
1880 | "(use parport_serial)\n", | 1821 | "(use parport_serial)\n", |
@@ -1884,7 +1825,8 @@ static void __devinit quirk_netmos(struct pci_dev *dev) | |||
1884 | } | 1825 | } |
1885 | } | 1826 | } |
1886 | } | 1827 | } |
1887 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos); | 1828 | DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, |
1829 | PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); | ||
1888 | 1830 | ||
1889 | static void __devinit quirk_e100_interrupt(struct pci_dev *dev) | 1831 | static void __devinit quirk_e100_interrupt(struct pci_dev *dev) |
1890 | { | 1832 | { |
@@ -1952,7 +1894,8 @@ static void __devinit quirk_e100_interrupt(struct pci_dev *dev) | |||
1952 | 1894 | ||
1953 | iounmap(csr); | 1895 | iounmap(csr); |
1954 | } | 1896 | } |
1955 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); | 1897 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, |
1898 | PCI_CLASS_NETWORK_ETHERNET, 8, quirk_e100_interrupt); | ||
1956 | 1899 | ||
1957 | /* | 1900 | /* |
1958 | * The 82575 and 82598 may experience data corruption issues when transitioning | 1901 | * The 82575 and 82598 may experience data corruption issues when transitioning |
@@ -2834,12 +2777,11 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors); | |||
2834 | static void __devinit fixup_ti816x_class(struct pci_dev* dev) | 2777 | static void __devinit fixup_ti816x_class(struct pci_dev* dev) |
2835 | { | 2778 | { |
2836 | /* TI 816x devices do not have class code set when in PCIe boot mode */ | 2779 | /* TI 816x devices do not have class code set when in PCIe boot mode */ |
2837 | if (dev->class == PCI_CLASS_NOT_DEFINED) { | 2780 | dev_info(&dev->dev, "Setting PCI class for 816x PCIe device\n"); |
2838 | dev_info(&dev->dev, "Setting PCI class for 816x PCIe device\n"); | 2781 | dev->class = PCI_CLASS_MULTIMEDIA_VIDEO; |
2839 | dev->class = PCI_CLASS_MULTIMEDIA_VIDEO; | ||
2840 | } | ||
2841 | } | 2782 | } |
2842 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_TI, 0xb800, fixup_ti816x_class); | 2783 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_TI, 0xb800, |
2784 | PCI_CLASS_NOT_DEFINED, 0, fixup_ti816x_class); | ||
2843 | 2785 | ||
2844 | /* Some PCIe devices do not work reliably with the claimed maximum | 2786 | /* Some PCIe devices do not work reliably with the claimed maximum |
2845 | * payload size supported. | 2787 | * payload size supported. |
@@ -2924,17 +2866,73 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f8, quirk_intel_mc_errata); | |||
2924 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); | 2866 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); |
2925 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); | 2867 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); |
2926 | 2868 | ||
2869 | |||
2870 | static void do_one_fixup_debug(void (*fn)(struct pci_dev *dev), struct pci_dev *dev) | ||
2871 | { | ||
2872 | ktime_t calltime, delta, rettime; | ||
2873 | unsigned long long duration; | ||
2874 | |||
2875 | printk(KERN_DEBUG "calling %pF @ %i for %s\n", | ||
2876 | fn, task_pid_nr(current), dev_name(&dev->dev)); | ||
2877 | calltime = ktime_get(); | ||
2878 | fn(dev); | ||
2879 | rettime = ktime_get(); | ||
2880 | delta = ktime_sub(rettime, calltime); | ||
2881 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; | ||
2882 | printk(KERN_DEBUG "pci fixup %pF returned after %lld usecs for %s\n", | ||
2883 | fn, duration, dev_name(&dev->dev)); | ||
2884 | } | ||
2885 | |||
2886 | /* | ||
2887 | * Some BIOS implementations leave the Intel GPU interrupts enabled, | ||
2888 | * even though no one is handling them (f.e. i915 driver is never loaded). | ||
2889 | * Additionally the interrupt destination is not set up properly | ||
2890 | * and the interrupt ends up -somewhere-. | ||
2891 | * | ||
2892 | * These spurious interrupts are "sticky" and the kernel disables | ||
2893 | * the (shared) interrupt line after 100.000+ generated interrupts. | ||
2894 | * | ||
2895 | * Fix it by disabling the still enabled interrupts. | ||
2896 | * This resolves crashes often seen on monitor unplug. | ||
2897 | */ | ||
2898 | #define I915_DEIER_REG 0x4400c | ||
2899 | static void __devinit disable_igfx_irq(struct pci_dev *dev) | ||
2900 | { | ||
2901 | void __iomem *regs = pci_iomap(dev, 0, 0); | ||
2902 | if (regs == NULL) { | ||
2903 | dev_warn(&dev->dev, "igfx quirk: Can't iomap PCI device\n"); | ||
2904 | return; | ||
2905 | } | ||
2906 | |||
2907 | /* Check if any interrupt line is still enabled */ | ||
2908 | if (readl(regs + I915_DEIER_REG) != 0) { | ||
2909 | dev_warn(&dev->dev, "BIOS left Intel GPU interrupts enabled; " | ||
2910 | "disabling\n"); | ||
2911 | |||
2912 | writel(0, regs + I915_DEIER_REG); | ||
2913 | } | ||
2914 | |||
2915 | pci_iounmap(dev, regs); | ||
2916 | } | ||
2917 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); | ||
2918 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); | ||
2919 | |||
2927 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2920 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
2928 | struct pci_fixup *end) | 2921 | struct pci_fixup *end) |
2929 | { | 2922 | { |
2930 | while (f < end) { | 2923 | for (; f < end; f++) |
2931 | if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) && | 2924 | if ((f->class == (u32) (dev->class >> f->class_shift) || |
2932 | (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { | 2925 | f->class == (u32) PCI_ANY_ID) && |
2926 | (f->vendor == dev->vendor || | ||
2927 | f->vendor == (u16) PCI_ANY_ID) && | ||
2928 | (f->device == dev->device || | ||
2929 | f->device == (u16) PCI_ANY_ID)) { | ||
2933 | dev_dbg(&dev->dev, "calling %pF\n", f->hook); | 2930 | dev_dbg(&dev->dev, "calling %pF\n", f->hook); |
2934 | f->hook(dev); | 2931 | if (initcall_debug) |
2932 | do_one_fixup_debug(f->hook, dev); | ||
2933 | else | ||
2934 | f->hook(dev); | ||
2935 | } | 2935 | } |
2936 | f++; | ||
2937 | } | ||
2938 | } | 2936 | } |
2939 | 2937 | ||
2940 | extern struct pci_fixup __start_pci_fixups_early[]; | 2938 | extern struct pci_fixup __start_pci_fixups_early[]; |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index ef8b18c48f26..fd77e2bde2e8 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -79,7 +79,7 @@ EXPORT_SYMBOL(pci_remove_bus); | |||
79 | 79 | ||
80 | static void __pci_remove_behind_bridge(struct pci_dev *dev); | 80 | static void __pci_remove_behind_bridge(struct pci_dev *dev); |
81 | /** | 81 | /** |
82 | * pci_remove_bus_device - remove a PCI device and any children | 82 | * pci_stop_and_remove_bus_device - remove a PCI device and any children |
83 | * @dev: the device to remove | 83 | * @dev: the device to remove |
84 | * | 84 | * |
85 | * Remove a PCI device from the device lists, informing the drivers | 85 | * Remove a PCI device from the device lists, informing the drivers |
@@ -90,7 +90,7 @@ static void __pci_remove_behind_bridge(struct pci_dev *dev); | |||
90 | * device lists, remove the /proc entry, and notify userspace | 90 | * device lists, remove the /proc entry, and notify userspace |
91 | * (/sbin/hotplug). | 91 | * (/sbin/hotplug). |
92 | */ | 92 | */ |
93 | static void __pci_remove_bus_device(struct pci_dev *dev) | 93 | void __pci_remove_bus_device(struct pci_dev *dev) |
94 | { | 94 | { |
95 | if (dev->subordinate) { | 95 | if (dev->subordinate) { |
96 | struct pci_bus *b = dev->subordinate; | 96 | struct pci_bus *b = dev->subordinate; |
@@ -102,7 +102,9 @@ static void __pci_remove_bus_device(struct pci_dev *dev) | |||
102 | 102 | ||
103 | pci_destroy_dev(dev); | 103 | pci_destroy_dev(dev); |
104 | } | 104 | } |
105 | void pci_remove_bus_device(struct pci_dev *dev) | 105 | EXPORT_SYMBOL(__pci_remove_bus_device); |
106 | |||
107 | void pci_stop_and_remove_bus_device(struct pci_dev *dev) | ||
106 | { | 108 | { |
107 | pci_stop_bus_device(dev); | 109 | pci_stop_bus_device(dev); |
108 | __pci_remove_bus_device(dev); | 110 | __pci_remove_bus_device(dev); |
@@ -127,14 +129,15 @@ static void pci_stop_behind_bridge(struct pci_dev *dev) | |||
127 | } | 129 | } |
128 | 130 | ||
129 | /** | 131 | /** |
130 | * pci_remove_behind_bridge - remove all devices behind a PCI bridge | 132 | * pci_stop_and_remove_behind_bridge - stop and remove all devices behind |
133 | * a PCI bridge | ||
131 | * @dev: PCI bridge device | 134 | * @dev: PCI bridge device |
132 | * | 135 | * |
133 | * Remove all devices on the bus, except for the parent bridge. | 136 | * Remove all devices on the bus, except for the parent bridge. |
134 | * This also removes any child buses, and any devices they may | 137 | * This also removes any child buses, and any devices they may |
135 | * contain in a depth-first manner. | 138 | * contain in a depth-first manner. |
136 | */ | 139 | */ |
137 | void pci_remove_behind_bridge(struct pci_dev *dev) | 140 | void pci_stop_and_remove_behind_bridge(struct pci_dev *dev) |
138 | { | 141 | { |
139 | pci_stop_behind_bridge(dev); | 142 | pci_stop_behind_bridge(dev); |
140 | __pci_remove_behind_bridge(dev); | 143 | __pci_remove_behind_bridge(dev); |
@@ -144,7 +147,15 @@ static void pci_stop_bus_devices(struct pci_bus *bus) | |||
144 | { | 147 | { |
145 | struct list_head *l, *n; | 148 | struct list_head *l, *n; |
146 | 149 | ||
147 | list_for_each_safe(l, n, &bus->devices) { | 150 | /* |
151 | * VFs could be removed by pci_stop_and_remove_bus_device() in the | ||
152 | * pci_stop_bus_devices() code path for PF. | ||
153 | * aka, bus->devices get updated in the process. | ||
154 | * but VFs are inserted after PFs when SRIOV is enabled for PF, | ||
155 | * We can iterate the list backwards to get prev valid PF instead | ||
156 | * of removed VF. | ||
157 | */ | ||
158 | list_for_each_prev_safe(l, n, &bus->devices) { | ||
148 | struct pci_dev *dev = pci_dev_b(l); | 159 | struct pci_dev *dev = pci_dev_b(l); |
149 | pci_stop_bus_device(dev); | 160 | pci_stop_bus_device(dev); |
150 | } | 161 | } |
@@ -166,6 +177,6 @@ void pci_stop_bus_device(struct pci_dev *dev) | |||
166 | pci_stop_dev(dev); | 177 | pci_stop_dev(dev); |
167 | } | 178 | } |
168 | 179 | ||
169 | EXPORT_SYMBOL(pci_remove_bus_device); | 180 | EXPORT_SYMBOL(pci_stop_and_remove_bus_device); |
170 | EXPORT_SYMBOL(pci_remove_behind_bridge); | 181 | EXPORT_SYMBOL(pci_stop_and_remove_behind_bridge); |
171 | EXPORT_SYMBOL_GPL(pci_stop_bus_device); | 182 | EXPORT_SYMBOL_GPL(pci_stop_bus_device); |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 86b69f85f900..8fa2d4be88de 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -25,10 +25,13 @@ | |||
25 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> |
26 | #include <linux/cache.h> | 26 | #include <linux/cache.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <asm-generic/pci-bridge.h> | ||
28 | #include "pci.h" | 29 | #include "pci.h" |
29 | 30 | ||
30 | struct resource_list_x { | 31 | unsigned int pci_flags; |
31 | struct resource_list_x *next; | 32 | |
33 | struct pci_dev_resource { | ||
34 | struct list_head list; | ||
32 | struct resource *res; | 35 | struct resource *res; |
33 | struct pci_dev *dev; | 36 | struct pci_dev *dev; |
34 | resource_size_t start; | 37 | resource_size_t start; |
@@ -38,21 +41,14 @@ struct resource_list_x { | |||
38 | unsigned long flags; | 41 | unsigned long flags; |
39 | }; | 42 | }; |
40 | 43 | ||
41 | #define free_list(type, head) do { \ | 44 | static void free_list(struct list_head *head) |
42 | struct type *list, *tmp; \ | ||
43 | for (list = (head)->next; list;) { \ | ||
44 | tmp = list; \ | ||
45 | list = list->next; \ | ||
46 | kfree(tmp); \ | ||
47 | } \ | ||
48 | (head)->next = NULL; \ | ||
49 | } while (0) | ||
50 | |||
51 | int pci_realloc_enable = 0; | ||
52 | #define pci_realloc_enabled() pci_realloc_enable | ||
53 | void pci_realloc(void) | ||
54 | { | 45 | { |
55 | pci_realloc_enable = 1; | 46 | struct pci_dev_resource *dev_res, *tmp; |
47 | |||
48 | list_for_each_entry_safe(dev_res, tmp, head, list) { | ||
49 | list_del(&dev_res->list); | ||
50 | kfree(dev_res); | ||
51 | } | ||
56 | } | 52 | } |
57 | 53 | ||
58 | /** | 54 | /** |
@@ -64,21 +60,18 @@ void pci_realloc(void) | |||
64 | * @add_size: additional size to be optionally added | 60 | * @add_size: additional size to be optionally added |
65 | * to the resource | 61 | * to the resource |
66 | */ | 62 | */ |
67 | static void add_to_list(struct resource_list_x *head, | 63 | static int add_to_list(struct list_head *head, |
68 | struct pci_dev *dev, struct resource *res, | 64 | struct pci_dev *dev, struct resource *res, |
69 | resource_size_t add_size, resource_size_t min_align) | 65 | resource_size_t add_size, resource_size_t min_align) |
70 | { | 66 | { |
71 | struct resource_list_x *list = head; | 67 | struct pci_dev_resource *tmp; |
72 | struct resource_list_x *ln = list->next; | ||
73 | struct resource_list_x *tmp; | ||
74 | 68 | ||
75 | tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); | 69 | tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); |
76 | if (!tmp) { | 70 | if (!tmp) { |
77 | pr_warning("add_to_list: kmalloc() failed!\n"); | 71 | pr_warning("add_to_list: kmalloc() failed!\n"); |
78 | return; | 72 | return -ENOMEM; |
79 | } | 73 | } |
80 | 74 | ||
81 | tmp->next = ln; | ||
82 | tmp->res = res; | 75 | tmp->res = res; |
83 | tmp->dev = dev; | 76 | tmp->dev = dev; |
84 | tmp->start = res->start; | 77 | tmp->start = res->start; |
@@ -86,19 +79,100 @@ static void add_to_list(struct resource_list_x *head, | |||
86 | tmp->flags = res->flags; | 79 | tmp->flags = res->flags; |
87 | tmp->add_size = add_size; | 80 | tmp->add_size = add_size; |
88 | tmp->min_align = min_align; | 81 | tmp->min_align = min_align; |
89 | list->next = tmp; | 82 | |
83 | list_add(&tmp->list, head); | ||
84 | |||
85 | return 0; | ||
90 | } | 86 | } |
91 | 87 | ||
92 | static void add_to_failed_list(struct resource_list_x *head, | 88 | static void remove_from_list(struct list_head *head, |
93 | struct pci_dev *dev, struct resource *res) | 89 | struct resource *res) |
94 | { | 90 | { |
95 | add_to_list(head, dev, res, | 91 | struct pci_dev_resource *dev_res, *tmp; |
96 | 0 /* dont care */, | 92 | |
97 | 0 /* dont care */); | 93 | list_for_each_entry_safe(dev_res, tmp, head, list) { |
94 | if (dev_res->res == res) { | ||
95 | list_del(&dev_res->list); | ||
96 | kfree(dev_res); | ||
97 | break; | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | |||
102 | static resource_size_t get_res_add_size(struct list_head *head, | ||
103 | struct resource *res) | ||
104 | { | ||
105 | struct pci_dev_resource *dev_res; | ||
106 | |||
107 | list_for_each_entry(dev_res, head, list) { | ||
108 | if (dev_res->res == res) { | ||
109 | int idx = res - &dev_res->dev->resource[0]; | ||
110 | |||
111 | dev_printk(KERN_DEBUG, &dev_res->dev->dev, | ||
112 | "res[%d]=%pR get_res_add_size add_size %llx\n", | ||
113 | idx, dev_res->res, | ||
114 | (unsigned long long)dev_res->add_size); | ||
115 | |||
116 | return dev_res->add_size; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | /* Sort resources by alignment */ | ||
124 | static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head) | ||
125 | { | ||
126 | int i; | ||
127 | |||
128 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
129 | struct resource *r; | ||
130 | struct pci_dev_resource *dev_res, *tmp; | ||
131 | resource_size_t r_align; | ||
132 | struct list_head *n; | ||
133 | |||
134 | r = &dev->resource[i]; | ||
135 | |||
136 | if (r->flags & IORESOURCE_PCI_FIXED) | ||
137 | continue; | ||
138 | |||
139 | if (!(r->flags) || r->parent) | ||
140 | continue; | ||
141 | |||
142 | r_align = pci_resource_alignment(dev, r); | ||
143 | if (!r_align) { | ||
144 | dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n", | ||
145 | i, r); | ||
146 | continue; | ||
147 | } | ||
148 | |||
149 | tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); | ||
150 | if (!tmp) | ||
151 | panic("pdev_sort_resources(): " | ||
152 | "kmalloc() failed!\n"); | ||
153 | tmp->res = r; | ||
154 | tmp->dev = dev; | ||
155 | |||
156 | /* fallback is smallest one or list is empty*/ | ||
157 | n = head; | ||
158 | list_for_each_entry(dev_res, head, list) { | ||
159 | resource_size_t align; | ||
160 | |||
161 | align = pci_resource_alignment(dev_res->dev, | ||
162 | dev_res->res); | ||
163 | |||
164 | if (r_align > align) { | ||
165 | n = &dev_res->list; | ||
166 | break; | ||
167 | } | ||
168 | } | ||
169 | /* Insert it just before n*/ | ||
170 | list_add_tail(&tmp->list, n); | ||
171 | } | ||
98 | } | 172 | } |
99 | 173 | ||
100 | static void __dev_sort_resources(struct pci_dev *dev, | 174 | static void __dev_sort_resources(struct pci_dev *dev, |
101 | struct resource_list *head) | 175 | struct list_head *head) |
102 | { | 176 | { |
103 | u16 class = dev->class >> 8; | 177 | u16 class = dev->class >> 8; |
104 | 178 | ||
@@ -136,49 +210,54 @@ static inline void reset_resource(struct resource *res) | |||
136 | * additional resources for the element, provided the element | 210 | * additional resources for the element, provided the element |
137 | * is in the head list. | 211 | * is in the head list. |
138 | */ | 212 | */ |
139 | static void reassign_resources_sorted(struct resource_list_x *realloc_head, | 213 | static void reassign_resources_sorted(struct list_head *realloc_head, |
140 | struct resource_list *head) | 214 | struct list_head *head) |
141 | { | 215 | { |
142 | struct resource *res; | 216 | struct resource *res; |
143 | struct resource_list_x *list, *tmp, *prev; | 217 | struct pci_dev_resource *add_res, *tmp; |
144 | struct resource_list *hlist; | 218 | struct pci_dev_resource *dev_res; |
145 | resource_size_t add_size; | 219 | resource_size_t add_size; |
146 | int idx; | 220 | int idx; |
147 | 221 | ||
148 | prev = realloc_head; | 222 | list_for_each_entry_safe(add_res, tmp, realloc_head, list) { |
149 | for (list = realloc_head->next; list;) { | 223 | bool found_match = false; |
150 | res = list->res; | 224 | |
225 | res = add_res->res; | ||
151 | /* skip resource that has been reset */ | 226 | /* skip resource that has been reset */ |
152 | if (!res->flags) | 227 | if (!res->flags) |
153 | goto out; | 228 | goto out; |
154 | 229 | ||
155 | /* skip this resource if not found in head list */ | 230 | /* skip this resource if not found in head list */ |
156 | for (hlist = head->next; hlist && hlist->res != res; | 231 | list_for_each_entry(dev_res, head, list) { |
157 | hlist = hlist->next); | 232 | if (dev_res->res == res) { |
158 | if (!hlist) { /* just skip */ | 233 | found_match = true; |
159 | prev = list; | 234 | break; |
160 | list = list->next; | 235 | } |
161 | continue; | ||
162 | } | 236 | } |
237 | if (!found_match)/* just skip */ | ||
238 | continue; | ||
163 | 239 | ||
164 | idx = res - &list->dev->resource[0]; | 240 | idx = res - &add_res->dev->resource[0]; |
165 | add_size=list->add_size; | 241 | add_size = add_res->add_size; |
166 | if (!resource_size(res)) { | 242 | if (!resource_size(res)) { |
167 | res->start = list->start; | 243 | res->start = add_res->start; |
168 | res->end = res->start + add_size - 1; | 244 | res->end = res->start + add_size - 1; |
169 | if(pci_assign_resource(list->dev, idx)) | 245 | if (pci_assign_resource(add_res->dev, idx)) |
170 | reset_resource(res); | 246 | reset_resource(res); |
171 | } else { | 247 | } else { |
172 | resource_size_t align = list->min_align; | 248 | resource_size_t align = add_res->min_align; |
173 | res->flags |= list->flags & (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN); | 249 | res->flags |= add_res->flags & |
174 | if (pci_reassign_resource(list->dev, idx, add_size, align)) | 250 | (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN); |
175 | dev_printk(KERN_DEBUG, &list->dev->dev, "failed to add optional resources res=%pR\n", | 251 | if (pci_reassign_resource(add_res->dev, idx, |
176 | res); | 252 | add_size, align)) |
253 | dev_printk(KERN_DEBUG, &add_res->dev->dev, | ||
254 | "failed to add %llx res[%d]=%pR\n", | ||
255 | (unsigned long long)add_size, | ||
256 | idx, res); | ||
177 | } | 257 | } |
178 | out: | 258 | out: |
179 | tmp = list; | 259 | list_del(&add_res->list); |
180 | prev->next = list = list->next; | 260 | kfree(add_res); |
181 | kfree(tmp); | ||
182 | } | 261 | } |
183 | } | 262 | } |
184 | 263 | ||
@@ -192,35 +271,99 @@ out: | |||
192 | * Satisfy resource requests of each element in the list. Add | 271 | * Satisfy resource requests of each element in the list. Add |
193 | * requests that could not satisfied to the failed_list. | 272 | * requests that could not satisfied to the failed_list. |
194 | */ | 273 | */ |
195 | static void assign_requested_resources_sorted(struct resource_list *head, | 274 | static void assign_requested_resources_sorted(struct list_head *head, |
196 | struct resource_list_x *fail_head) | 275 | struct list_head *fail_head) |
197 | { | 276 | { |
198 | struct resource *res; | 277 | struct resource *res; |
199 | struct resource_list *list; | 278 | struct pci_dev_resource *dev_res; |
200 | int idx; | 279 | int idx; |
201 | 280 | ||
202 | for (list = head->next; list; list = list->next) { | 281 | list_for_each_entry(dev_res, head, list) { |
203 | res = list->res; | 282 | res = dev_res->res; |
204 | idx = res - &list->dev->resource[0]; | 283 | idx = res - &dev_res->dev->resource[0]; |
205 | if (resource_size(res) && pci_assign_resource(list->dev, idx)) { | 284 | if (resource_size(res) && |
206 | if (fail_head && !pci_is_root_bus(list->dev->bus)) { | 285 | pci_assign_resource(dev_res->dev, idx)) { |
286 | if (fail_head && !pci_is_root_bus(dev_res->dev->bus)) { | ||
207 | /* | 287 | /* |
208 | * if the failed res is for ROM BAR, and it will | 288 | * if the failed res is for ROM BAR, and it will |
209 | * be enabled later, don't add it to the list | 289 | * be enabled later, don't add it to the list |
210 | */ | 290 | */ |
211 | if (!((idx == PCI_ROM_RESOURCE) && | 291 | if (!((idx == PCI_ROM_RESOURCE) && |
212 | (!(res->flags & IORESOURCE_ROM_ENABLE)))) | 292 | (!(res->flags & IORESOURCE_ROM_ENABLE)))) |
213 | add_to_failed_list(fail_head, list->dev, res); | 293 | add_to_list(fail_head, |
294 | dev_res->dev, res, | ||
295 | 0 /* dont care */, | ||
296 | 0 /* dont care */); | ||
214 | } | 297 | } |
215 | reset_resource(res); | 298 | reset_resource(res); |
216 | } | 299 | } |
217 | } | 300 | } |
218 | } | 301 | } |
219 | 302 | ||
220 | static void __assign_resources_sorted(struct resource_list *head, | 303 | static void __assign_resources_sorted(struct list_head *head, |
221 | struct resource_list_x *realloc_head, | 304 | struct list_head *realloc_head, |
222 | struct resource_list_x *fail_head) | 305 | struct list_head *fail_head) |
223 | { | 306 | { |
307 | /* | ||
308 | * Should not assign requested resources at first. | ||
309 | * they could be adjacent, so later reassign can not reallocate | ||
310 | * them one by one in parent resource window. | ||
311 | * Try to assign requested + add_size at begining | ||
312 | * if could do that, could get out early. | ||
313 | * if could not do that, we still try to assign requested at first, | ||
314 | * then try to reassign add_size for some resources. | ||
315 | */ | ||
316 | LIST_HEAD(save_head); | ||
317 | LIST_HEAD(local_fail_head); | ||
318 | struct pci_dev_resource *save_res; | ||
319 | struct pci_dev_resource *dev_res; | ||
320 | |||
321 | /* Check if optional add_size is there */ | ||
322 | if (!realloc_head || list_empty(realloc_head)) | ||
323 | goto requested_and_reassign; | ||
324 | |||
325 | /* Save original start, end, flags etc at first */ | ||
326 | list_for_each_entry(dev_res, head, list) { | ||
327 | if (add_to_list(&save_head, dev_res->dev, dev_res->res, 0, 0)) { | ||
328 | free_list(&save_head); | ||
329 | goto requested_and_reassign; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | /* Update res in head list with add_size in realloc_head list */ | ||
334 | list_for_each_entry(dev_res, head, list) | ||
335 | dev_res->res->end += get_res_add_size(realloc_head, | ||
336 | dev_res->res); | ||
337 | |||
338 | /* Try updated head list with add_size added */ | ||
339 | assign_requested_resources_sorted(head, &local_fail_head); | ||
340 | |||
341 | /* all assigned with add_size ? */ | ||
342 | if (list_empty(&local_fail_head)) { | ||
343 | /* Remove head list from realloc_head list */ | ||
344 | list_for_each_entry(dev_res, head, list) | ||
345 | remove_from_list(realloc_head, dev_res->res); | ||
346 | free_list(&save_head); | ||
347 | free_list(head); | ||
348 | return; | ||
349 | } | ||
350 | |||
351 | free_list(&local_fail_head); | ||
352 | /* Release assigned resource */ | ||
353 | list_for_each_entry(dev_res, head, list) | ||
354 | if (dev_res->res->parent) | ||
355 | release_resource(dev_res->res); | ||
356 | /* Restore start/end/flags from saved list */ | ||
357 | list_for_each_entry(save_res, &save_head, list) { | ||
358 | struct resource *res = save_res->res; | ||
359 | |||
360 | res->start = save_res->start; | ||
361 | res->end = save_res->end; | ||
362 | res->flags = save_res->flags; | ||
363 | } | ||
364 | free_list(&save_head); | ||
365 | |||
366 | requested_and_reassign: | ||
224 | /* Satisfy the must-have resource requests */ | 367 | /* Satisfy the must-have resource requests */ |
225 | assign_requested_resources_sorted(head, fail_head); | 368 | assign_requested_resources_sorted(head, fail_head); |
226 | 369 | ||
@@ -228,28 +371,27 @@ static void __assign_resources_sorted(struct resource_list *head, | |||
228 | requests */ | 371 | requests */ |
229 | if (realloc_head) | 372 | if (realloc_head) |
230 | reassign_resources_sorted(realloc_head, head); | 373 | reassign_resources_sorted(realloc_head, head); |
231 | free_list(resource_list, head); | 374 | free_list(head); |
232 | } | 375 | } |
233 | 376 | ||
234 | static void pdev_assign_resources_sorted(struct pci_dev *dev, | 377 | static void pdev_assign_resources_sorted(struct pci_dev *dev, |
235 | struct resource_list_x *fail_head) | 378 | struct list_head *add_head, |
379 | struct list_head *fail_head) | ||
236 | { | 380 | { |
237 | struct resource_list head; | 381 | LIST_HEAD(head); |
238 | 382 | ||
239 | head.next = NULL; | ||
240 | __dev_sort_resources(dev, &head); | 383 | __dev_sort_resources(dev, &head); |
241 | __assign_resources_sorted(&head, NULL, fail_head); | 384 | __assign_resources_sorted(&head, add_head, fail_head); |
242 | 385 | ||
243 | } | 386 | } |
244 | 387 | ||
245 | static void pbus_assign_resources_sorted(const struct pci_bus *bus, | 388 | static void pbus_assign_resources_sorted(const struct pci_bus *bus, |
246 | struct resource_list_x *realloc_head, | 389 | struct list_head *realloc_head, |
247 | struct resource_list_x *fail_head) | 390 | struct list_head *fail_head) |
248 | { | 391 | { |
249 | struct pci_dev *dev; | 392 | struct pci_dev *dev; |
250 | struct resource_list head; | 393 | LIST_HEAD(head); |
251 | 394 | ||
252 | head.next = NULL; | ||
253 | list_for_each_entry(dev, &bus->devices, bus_list) | 395 | list_for_each_entry(dev, &bus->devices, bus_list) |
254 | __dev_sort_resources(dev, &head); | 396 | __dev_sort_resources(dev, &head); |
255 | 397 | ||
@@ -548,20 +690,6 @@ static resource_size_t calculate_memsize(resource_size_t size, | |||
548 | return size; | 690 | return size; |
549 | } | 691 | } |
550 | 692 | ||
551 | static resource_size_t get_res_add_size(struct resource_list_x *realloc_head, | ||
552 | struct resource *res) | ||
553 | { | ||
554 | struct resource_list_x *list; | ||
555 | |||
556 | /* check if it is in realloc_head list */ | ||
557 | for (list = realloc_head->next; list && list->res != res; | ||
558 | list = list->next); | ||
559 | if (list) | ||
560 | return list->add_size; | ||
561 | |||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | /** | 693 | /** |
566 | * pbus_size_io() - size the io window of a given bus | 694 | * pbus_size_io() - size the io window of a given bus |
567 | * | 695 | * |
@@ -576,7 +704,7 @@ static resource_size_t get_res_add_size(struct resource_list_x *realloc_head, | |||
576 | * We must be careful with the ISA aliasing though. | 704 | * We must be careful with the ISA aliasing though. |
577 | */ | 705 | */ |
578 | static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | 706 | static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, |
579 | resource_size_t add_size, struct resource_list_x *realloc_head) | 707 | resource_size_t add_size, struct list_head *realloc_head) |
580 | { | 708 | { |
581 | struct pci_dev *dev; | 709 | struct pci_dev *dev; |
582 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); | 710 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); |
@@ -612,7 +740,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | |||
612 | if (children_add_size > add_size) | 740 | if (children_add_size > add_size) |
613 | add_size = children_add_size; | 741 | add_size = children_add_size; |
614 | size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : | 742 | size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : |
615 | calculate_iosize(size, min_size+add_size, size1, | 743 | calculate_iosize(size, min_size, add_size + size1, |
616 | resource_size(b_res), 4096); | 744 | resource_size(b_res), 4096); |
617 | if (!size0 && !size1) { | 745 | if (!size0 && !size1) { |
618 | if (b_res->start || b_res->end) | 746 | if (b_res->start || b_res->end) |
@@ -626,8 +754,12 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | |||
626 | b_res->start = 4096; | 754 | b_res->start = 4096; |
627 | b_res->end = b_res->start + size0 - 1; | 755 | b_res->end = b_res->start + size0 - 1; |
628 | b_res->flags |= IORESOURCE_STARTALIGN; | 756 | b_res->flags |= IORESOURCE_STARTALIGN; |
629 | if (size1 > size0 && realloc_head) | 757 | if (size1 > size0 && realloc_head) { |
630 | add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096); | 758 | add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096); |
759 | dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window " | ||
760 | "%pR to [bus %02x-%02x] add_size %lx\n", b_res, | ||
761 | bus->secondary, bus->subordinate, size1-size0); | ||
762 | } | ||
631 | } | 763 | } |
632 | 764 | ||
633 | /** | 765 | /** |
@@ -644,7 +776,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | |||
644 | static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | 776 | static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, |
645 | unsigned long type, resource_size_t min_size, | 777 | unsigned long type, resource_size_t min_size, |
646 | resource_size_t add_size, | 778 | resource_size_t add_size, |
647 | struct resource_list_x *realloc_head) | 779 | struct list_head *realloc_head) |
648 | { | 780 | { |
649 | struct pci_dev *dev; | 781 | struct pci_dev *dev; |
650 | resource_size_t min_align, align, size, size0, size1; | 782 | resource_size_t min_align, align, size, size0, size1; |
@@ -726,7 +858,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
726 | if (children_add_size > add_size) | 858 | if (children_add_size > add_size) |
727 | add_size = children_add_size; | 859 | add_size = children_add_size; |
728 | size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : | 860 | size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : |
729 | calculate_memsize(size, min_size+add_size, 0, | 861 | calculate_memsize(size, min_size, add_size, |
730 | resource_size(b_res), min_align); | 862 | resource_size(b_res), min_align); |
731 | if (!size0 && !size1) { | 863 | if (!size0 && !size1) { |
732 | if (b_res->start || b_res->end) | 864 | if (b_res->start || b_res->end) |
@@ -739,8 +871,12 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
739 | b_res->start = min_align; | 871 | b_res->start = min_align; |
740 | b_res->end = size0 + min_align - 1; | 872 | b_res->end = size0 + min_align - 1; |
741 | b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask; | 873 | b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask; |
742 | if (size1 > size0 && realloc_head) | 874 | if (size1 > size0 && realloc_head) { |
743 | add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align); | 875 | add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align); |
876 | dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window " | ||
877 | "%pR to [bus %02x-%02x] add_size %llx\n", b_res, | ||
878 | bus->secondary, bus->subordinate, (unsigned long long)size1-size0); | ||
879 | } | ||
744 | return 1; | 880 | return 1; |
745 | } | 881 | } |
746 | 882 | ||
@@ -754,25 +890,48 @@ unsigned long pci_cardbus_resource_alignment(struct resource *res) | |||
754 | } | 890 | } |
755 | 891 | ||
756 | static void pci_bus_size_cardbus(struct pci_bus *bus, | 892 | static void pci_bus_size_cardbus(struct pci_bus *bus, |
757 | struct resource_list_x *realloc_head) | 893 | struct list_head *realloc_head) |
758 | { | 894 | { |
759 | struct pci_dev *bridge = bus->self; | 895 | struct pci_dev *bridge = bus->self; |
760 | struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; | 896 | struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; |
897 | resource_size_t b_res_3_size = pci_cardbus_mem_size * 2; | ||
761 | u16 ctrl; | 898 | u16 ctrl; |
762 | 899 | ||
900 | if (b_res[0].parent) | ||
901 | goto handle_b_res_1; | ||
763 | /* | 902 | /* |
764 | * Reserve some resources for CardBus. We reserve | 903 | * Reserve some resources for CardBus. We reserve |
765 | * a fixed amount of bus space for CardBus bridges. | 904 | * a fixed amount of bus space for CardBus bridges. |
766 | */ | 905 | */ |
767 | b_res[0].start = 0; | 906 | b_res[0].start = pci_cardbus_io_size; |
768 | b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; | 907 | b_res[0].end = b_res[0].start + pci_cardbus_io_size - 1; |
769 | if (realloc_head) | 908 | b_res[0].flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN; |
770 | add_to_list(realloc_head, bridge, b_res, pci_cardbus_io_size, 0 /* dont care */); | 909 | if (realloc_head) { |
910 | b_res[0].end -= pci_cardbus_io_size; | ||
911 | add_to_list(realloc_head, bridge, b_res, pci_cardbus_io_size, | ||
912 | pci_cardbus_io_size); | ||
913 | } | ||
771 | 914 | ||
772 | b_res[1].start = 0; | 915 | handle_b_res_1: |
773 | b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; | 916 | if (b_res[1].parent) |
774 | if (realloc_head) | 917 | goto handle_b_res_2; |
775 | add_to_list(realloc_head, bridge, b_res+1, pci_cardbus_io_size, 0 /* dont care */); | 918 | b_res[1].start = pci_cardbus_io_size; |
919 | b_res[1].end = b_res[1].start + pci_cardbus_io_size - 1; | ||
920 | b_res[1].flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN; | ||
921 | if (realloc_head) { | ||
922 | b_res[1].end -= pci_cardbus_io_size; | ||
923 | add_to_list(realloc_head, bridge, b_res+1, pci_cardbus_io_size, | ||
924 | pci_cardbus_io_size); | ||
925 | } | ||
926 | |||
927 | handle_b_res_2: | ||
928 | /* MEM1 must not be pref mmio */ | ||
929 | pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); | ||
930 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM1) { | ||
931 | ctrl &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1; | ||
932 | pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl); | ||
933 | pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); | ||
934 | } | ||
776 | 935 | ||
777 | /* | 936 | /* |
778 | * Check whether prefetchable memory is supported | 937 | * Check whether prefetchable memory is supported |
@@ -785,38 +944,46 @@ static void pci_bus_size_cardbus(struct pci_bus *bus, | |||
785 | pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); | 944 | pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); |
786 | } | 945 | } |
787 | 946 | ||
947 | if (b_res[2].parent) | ||
948 | goto handle_b_res_3; | ||
788 | /* | 949 | /* |
789 | * If we have prefetchable memory support, allocate | 950 | * If we have prefetchable memory support, allocate |
790 | * two regions. Otherwise, allocate one region of | 951 | * two regions. Otherwise, allocate one region of |
791 | * twice the size. | 952 | * twice the size. |
792 | */ | 953 | */ |
793 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { | 954 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { |
794 | b_res[2].start = 0; | 955 | b_res[2].start = pci_cardbus_mem_size; |
795 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN; | 956 | b_res[2].end = b_res[2].start + pci_cardbus_mem_size - 1; |
796 | if (realloc_head) | 957 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | |
797 | add_to_list(realloc_head, bridge, b_res+2, pci_cardbus_mem_size, 0 /* dont care */); | 958 | IORESOURCE_STARTALIGN; |
798 | 959 | if (realloc_head) { | |
799 | b_res[3].start = 0; | 960 | b_res[2].end -= pci_cardbus_mem_size; |
800 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; | 961 | add_to_list(realloc_head, bridge, b_res+2, |
801 | if (realloc_head) | 962 | pci_cardbus_mem_size, pci_cardbus_mem_size); |
802 | add_to_list(realloc_head, bridge, b_res+3, pci_cardbus_mem_size, 0 /* dont care */); | 963 | } |
803 | } else { | 964 | |
804 | b_res[3].start = 0; | 965 | /* reduce that to half */ |
805 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; | 966 | b_res_3_size = pci_cardbus_mem_size; |
806 | if (realloc_head) | 967 | } |
807 | add_to_list(realloc_head, bridge, b_res+3, pci_cardbus_mem_size * 2, 0 /* dont care */); | 968 | |
969 | handle_b_res_3: | ||
970 | if (b_res[3].parent) | ||
971 | goto handle_done; | ||
972 | b_res[3].start = pci_cardbus_mem_size; | ||
973 | b_res[3].end = b_res[3].start + b_res_3_size - 1; | ||
974 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_STARTALIGN; | ||
975 | if (realloc_head) { | ||
976 | b_res[3].end -= b_res_3_size; | ||
977 | add_to_list(realloc_head, bridge, b_res+3, b_res_3_size, | ||
978 | pci_cardbus_mem_size); | ||
808 | } | 979 | } |
809 | 980 | ||
810 | /* set the size of the resource to zero, so that the resource does not | 981 | handle_done: |
811 | * get assigned during required-resource allocation cycle but gets assigned | 982 | ; |
812 | * during the optional-resource allocation cycle. | ||
813 | */ | ||
814 | b_res[0].start = b_res[1].start = b_res[2].start = b_res[3].start = 1; | ||
815 | b_res[0].end = b_res[1].end = b_res[2].end = b_res[3].end = 0; | ||
816 | } | 983 | } |
817 | 984 | ||
818 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, | 985 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, |
819 | struct resource_list_x *realloc_head) | 986 | struct list_head *realloc_head) |
820 | { | 987 | { |
821 | struct pci_dev *dev; | 988 | struct pci_dev *dev; |
822 | unsigned long mask, prefmask; | 989 | unsigned long mask, prefmask; |
@@ -858,7 +1025,8 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, | |||
858 | * Follow thru | 1025 | * Follow thru |
859 | */ | 1026 | */ |
860 | default: | 1027 | default: |
861 | pbus_size_io(bus, 0, additional_io_size, realloc_head); | 1028 | pbus_size_io(bus, realloc_head ? 0 : additional_io_size, |
1029 | additional_io_size, realloc_head); | ||
862 | /* If the bridge supports prefetchable range, size it | 1030 | /* If the bridge supports prefetchable range, size it |
863 | separately. If it doesn't, or its prefetchable window | 1031 | separately. If it doesn't, or its prefetchable window |
864 | has already been allocated by arch code, try | 1032 | has already been allocated by arch code, try |
@@ -866,11 +1034,15 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, | |||
866 | resources. */ | 1034 | resources. */ |
867 | mask = IORESOURCE_MEM; | 1035 | mask = IORESOURCE_MEM; |
868 | prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; | 1036 | prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; |
869 | if (pbus_size_mem(bus, prefmask, prefmask, 0, additional_mem_size, realloc_head)) | 1037 | if (pbus_size_mem(bus, prefmask, prefmask, |
1038 | realloc_head ? 0 : additional_mem_size, | ||
1039 | additional_mem_size, realloc_head)) | ||
870 | mask = prefmask; /* Success, size non-prefetch only. */ | 1040 | mask = prefmask; /* Success, size non-prefetch only. */ |
871 | else | 1041 | else |
872 | additional_mem_size += additional_mem_size; | 1042 | additional_mem_size += additional_mem_size; |
873 | pbus_size_mem(bus, mask, IORESOURCE_MEM, 0, additional_mem_size, realloc_head); | 1043 | pbus_size_mem(bus, mask, IORESOURCE_MEM, |
1044 | realloc_head ? 0 : additional_mem_size, | ||
1045 | additional_mem_size, realloc_head); | ||
874 | break; | 1046 | break; |
875 | } | 1047 | } |
876 | } | 1048 | } |
@@ -882,8 +1054,8 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus) | |||
882 | EXPORT_SYMBOL(pci_bus_size_bridges); | 1054 | EXPORT_SYMBOL(pci_bus_size_bridges); |
883 | 1055 | ||
884 | static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, | 1056 | static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, |
885 | struct resource_list_x *realloc_head, | 1057 | struct list_head *realloc_head, |
886 | struct resource_list_x *fail_head) | 1058 | struct list_head *fail_head) |
887 | { | 1059 | { |
888 | struct pci_bus *b; | 1060 | struct pci_bus *b; |
889 | struct pci_dev *dev; | 1061 | struct pci_dev *dev; |
@@ -922,17 +1094,19 @@ void __ref pci_bus_assign_resources(const struct pci_bus *bus) | |||
922 | EXPORT_SYMBOL(pci_bus_assign_resources); | 1094 | EXPORT_SYMBOL(pci_bus_assign_resources); |
923 | 1095 | ||
924 | static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge, | 1096 | static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge, |
925 | struct resource_list_x *fail_head) | 1097 | struct list_head *add_head, |
1098 | struct list_head *fail_head) | ||
926 | { | 1099 | { |
927 | struct pci_bus *b; | 1100 | struct pci_bus *b; |
928 | 1101 | ||
929 | pdev_assign_resources_sorted((struct pci_dev *)bridge, fail_head); | 1102 | pdev_assign_resources_sorted((struct pci_dev *)bridge, |
1103 | add_head, fail_head); | ||
930 | 1104 | ||
931 | b = bridge->subordinate; | 1105 | b = bridge->subordinate; |
932 | if (!b) | 1106 | if (!b) |
933 | return; | 1107 | return; |
934 | 1108 | ||
935 | __pci_bus_assign_resources(b, NULL, fail_head); | 1109 | __pci_bus_assign_resources(b, add_head, fail_head); |
936 | 1110 | ||
937 | switch (bridge->class >> 8) { | 1111 | switch (bridge->class >> 8) { |
938 | case PCI_CLASS_BRIDGE_PCI: | 1112 | case PCI_CLASS_BRIDGE_PCI: |
@@ -1095,6 +1269,58 @@ static int __init pci_get_max_depth(void) | |||
1095 | return depth; | 1269 | return depth; |
1096 | } | 1270 | } |
1097 | 1271 | ||
1272 | /* | ||
1273 | * -1: undefined, will auto detect later | ||
1274 | * 0: disabled by user | ||
1275 | * 1: disabled by auto detect | ||
1276 | * 2: enabled by user | ||
1277 | * 3: enabled by auto detect | ||
1278 | */ | ||
1279 | enum enable_type { | ||
1280 | undefined = -1, | ||
1281 | user_disabled, | ||
1282 | auto_disabled, | ||
1283 | user_enabled, | ||
1284 | auto_enabled, | ||
1285 | }; | ||
1286 | |||
1287 | static enum enable_type pci_realloc_enable __initdata = undefined; | ||
1288 | void __init pci_realloc_get_opt(char *str) | ||
1289 | { | ||
1290 | if (!strncmp(str, "off", 3)) | ||
1291 | pci_realloc_enable = user_disabled; | ||
1292 | else if (!strncmp(str, "on", 2)) | ||
1293 | pci_realloc_enable = user_enabled; | ||
1294 | } | ||
1295 | static bool __init pci_realloc_enabled(void) | ||
1296 | { | ||
1297 | return pci_realloc_enable >= user_enabled; | ||
1298 | } | ||
1299 | |||
1300 | static void __init pci_realloc_detect(void) | ||
1301 | { | ||
1302 | #if defined(CONFIG_PCI_IOV) && defined(CONFIG_PCI_REALLOC_ENABLE_AUTO) | ||
1303 | struct pci_dev *dev = NULL; | ||
1304 | |||
1305 | if (pci_realloc_enable != undefined) | ||
1306 | return; | ||
1307 | |||
1308 | for_each_pci_dev(dev) { | ||
1309 | int i; | ||
1310 | |||
1311 | for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) { | ||
1312 | struct resource *r = &dev->resource[i]; | ||
1313 | |||
1314 | /* Not assigned, or rejected by kernel ? */ | ||
1315 | if (r->flags && !r->start) { | ||
1316 | pci_realloc_enable = auto_enabled; | ||
1317 | |||
1318 | return; | ||
1319 | } | ||
1320 | } | ||
1321 | } | ||
1322 | #endif | ||
1323 | } | ||
1098 | 1324 | ||
1099 | /* | 1325 | /* |
1100 | * first try will not touch pci bridge res | 1326 | * first try will not touch pci bridge res |
@@ -1105,59 +1331,57 @@ void __init | |||
1105 | pci_assign_unassigned_resources(void) | 1331 | pci_assign_unassigned_resources(void) |
1106 | { | 1332 | { |
1107 | struct pci_bus *bus; | 1333 | struct pci_bus *bus; |
1108 | struct resource_list_x realloc_list; /* list of resources that | 1334 | LIST_HEAD(realloc_head); /* list of resources that |
1109 | want additional resources */ | 1335 | want additional resources */ |
1336 | struct list_head *add_list = NULL; | ||
1110 | int tried_times = 0; | 1337 | int tried_times = 0; |
1111 | enum release_type rel_type = leaf_only; | 1338 | enum release_type rel_type = leaf_only; |
1112 | struct resource_list_x head, *list; | 1339 | LIST_HEAD(fail_head); |
1340 | struct pci_dev_resource *fail_res; | ||
1113 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | 1341 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | |
1114 | IORESOURCE_PREFETCH; | 1342 | IORESOURCE_PREFETCH; |
1115 | unsigned long failed_type; | 1343 | int pci_try_num = 1; |
1116 | int max_depth = pci_get_max_depth(); | ||
1117 | int pci_try_num; | ||
1118 | |||
1119 | 1344 | ||
1120 | head.next = NULL; | 1345 | /* don't realloc if asked to do so */ |
1121 | realloc_list.next = NULL; | 1346 | pci_realloc_detect(); |
1347 | if (pci_realloc_enabled()) { | ||
1348 | int max_depth = pci_get_max_depth(); | ||
1122 | 1349 | ||
1123 | pci_try_num = max_depth + 1; | 1350 | pci_try_num = max_depth + 1; |
1124 | printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", | 1351 | printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", |
1125 | max_depth, pci_try_num); | 1352 | max_depth, pci_try_num); |
1353 | } | ||
1126 | 1354 | ||
1127 | again: | 1355 | again: |
1356 | /* | ||
1357 | * last try will use add_list, otherwise will try good to have as | ||
1358 | * must have, so can realloc parent bridge resource | ||
1359 | */ | ||
1360 | if (tried_times + 1 == pci_try_num) | ||
1361 | add_list = &realloc_head; | ||
1128 | /* Depth first, calculate sizes and alignments of all | 1362 | /* Depth first, calculate sizes and alignments of all |
1129 | subordinate buses. */ | 1363 | subordinate buses. */ |
1130 | list_for_each_entry(bus, &pci_root_buses, node) | 1364 | list_for_each_entry(bus, &pci_root_buses, node) |
1131 | __pci_bus_size_bridges(bus, &realloc_list); | 1365 | __pci_bus_size_bridges(bus, add_list); |
1132 | 1366 | ||
1133 | /* Depth last, allocate resources and update the hardware. */ | 1367 | /* Depth last, allocate resources and update the hardware. */ |
1134 | list_for_each_entry(bus, &pci_root_buses, node) | 1368 | list_for_each_entry(bus, &pci_root_buses, node) |
1135 | __pci_bus_assign_resources(bus, &realloc_list, &head); | 1369 | __pci_bus_assign_resources(bus, add_list, &fail_head); |
1136 | BUG_ON(realloc_list.next); | 1370 | if (add_list) |
1371 | BUG_ON(!list_empty(add_list)); | ||
1137 | tried_times++; | 1372 | tried_times++; |
1138 | 1373 | ||
1139 | /* any device complain? */ | 1374 | /* any device complain? */ |
1140 | if (!head.next) | 1375 | if (list_empty(&fail_head)) |
1141 | goto enable_and_dump; | 1376 | goto enable_and_dump; |
1142 | 1377 | ||
1143 | /* don't realloc if asked to do so */ | 1378 | if (tried_times >= pci_try_num) { |
1144 | if (!pci_realloc_enabled()) { | 1379 | if (pci_realloc_enable == undefined) |
1145 | free_list(resource_list_x, &head); | 1380 | printk(KERN_INFO "Some PCI device resources are unassigned, try booting with pci=realloc\n"); |
1146 | goto enable_and_dump; | 1381 | else if (pci_realloc_enable == auto_enabled) |
1147 | } | 1382 | printk(KERN_INFO "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); |
1148 | 1383 | ||
1149 | failed_type = 0; | 1384 | free_list(&fail_head); |
1150 | for (list = head.next; list;) { | ||
1151 | failed_type |= list->flags; | ||
1152 | list = list->next; | ||
1153 | } | ||
1154 | /* | ||
1155 | * io port are tight, don't try extra | ||
1156 | * or if reach the limit, don't want to try more | ||
1157 | */ | ||
1158 | failed_type &= type_mask; | ||
1159 | if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) { | ||
1160 | free_list(resource_list_x, &head); | ||
1161 | goto enable_and_dump; | 1385 | goto enable_and_dump; |
1162 | } | 1386 | } |
1163 | 1387 | ||
@@ -1172,25 +1396,23 @@ again: | |||
1172 | * Try to release leaf bridge's resources that doesn't fit resource of | 1396 | * Try to release leaf bridge's resources that doesn't fit resource of |
1173 | * child device under that bridge | 1397 | * child device under that bridge |
1174 | */ | 1398 | */ |
1175 | for (list = head.next; list;) { | 1399 | list_for_each_entry(fail_res, &fail_head, list) { |
1176 | bus = list->dev->bus; | 1400 | bus = fail_res->dev->bus; |
1177 | pci_bus_release_bridge_resources(bus, list->flags & type_mask, | 1401 | pci_bus_release_bridge_resources(bus, |
1178 | rel_type); | 1402 | fail_res->flags & type_mask, |
1179 | list = list->next; | 1403 | rel_type); |
1180 | } | 1404 | } |
1181 | /* restore size and flags */ | 1405 | /* restore size and flags */ |
1182 | for (list = head.next; list;) { | 1406 | list_for_each_entry(fail_res, &fail_head, list) { |
1183 | struct resource *res = list->res; | 1407 | struct resource *res = fail_res->res; |
1184 | 1408 | ||
1185 | res->start = list->start; | 1409 | res->start = fail_res->start; |
1186 | res->end = list->end; | 1410 | res->end = fail_res->end; |
1187 | res->flags = list->flags; | 1411 | res->flags = fail_res->flags; |
1188 | if (list->dev->subordinate) | 1412 | if (fail_res->dev->subordinate) |
1189 | res->flags = 0; | 1413 | res->flags = 0; |
1190 | |||
1191 | list = list->next; | ||
1192 | } | 1414 | } |
1193 | free_list(resource_list_x, &head); | 1415 | free_list(&fail_head); |
1194 | 1416 | ||
1195 | goto again; | 1417 | goto again; |
1196 | 1418 | ||
@@ -1207,26 +1429,27 @@ enable_and_dump: | |||
1207 | void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) | 1429 | void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) |
1208 | { | 1430 | { |
1209 | struct pci_bus *parent = bridge->subordinate; | 1431 | struct pci_bus *parent = bridge->subordinate; |
1432 | LIST_HEAD(add_list); /* list of resources that | ||
1433 | want additional resources */ | ||
1210 | int tried_times = 0; | 1434 | int tried_times = 0; |
1211 | struct resource_list_x head, *list; | 1435 | LIST_HEAD(fail_head); |
1436 | struct pci_dev_resource *fail_res; | ||
1212 | int retval; | 1437 | int retval; |
1213 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | 1438 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | |
1214 | IORESOURCE_PREFETCH; | 1439 | IORESOURCE_PREFETCH; |
1215 | 1440 | ||
1216 | head.next = NULL; | ||
1217 | |||
1218 | again: | 1441 | again: |
1219 | pci_bus_size_bridges(parent); | 1442 | __pci_bus_size_bridges(parent, &add_list); |
1220 | __pci_bridge_assign_resources(bridge, &head); | 1443 | __pci_bridge_assign_resources(bridge, &add_list, &fail_head); |
1221 | 1444 | BUG_ON(!list_empty(&add_list)); | |
1222 | tried_times++; | 1445 | tried_times++; |
1223 | 1446 | ||
1224 | if (!head.next) | 1447 | if (list_empty(&fail_head)) |
1225 | goto enable_all; | 1448 | goto enable_all; |
1226 | 1449 | ||
1227 | if (tried_times >= 2) { | 1450 | if (tried_times >= 2) { |
1228 | /* still fail, don't need to try more */ | 1451 | /* still fail, don't need to try more */ |
1229 | free_list(resource_list_x, &head); | 1452 | free_list(&fail_head); |
1230 | goto enable_all; | 1453 | goto enable_all; |
1231 | } | 1454 | } |
1232 | 1455 | ||
@@ -1237,27 +1460,24 @@ again: | |||
1237 | * Try to release leaf bridge's resources that doesn't fit resource of | 1460 | * Try to release leaf bridge's resources that doesn't fit resource of |
1238 | * child device under that bridge | 1461 | * child device under that bridge |
1239 | */ | 1462 | */ |
1240 | for (list = head.next; list;) { | 1463 | list_for_each_entry(fail_res, &fail_head, list) { |
1241 | struct pci_bus *bus = list->dev->bus; | 1464 | struct pci_bus *bus = fail_res->dev->bus; |
1242 | unsigned long flags = list->flags; | 1465 | unsigned long flags = fail_res->flags; |
1243 | 1466 | ||
1244 | pci_bus_release_bridge_resources(bus, flags & type_mask, | 1467 | pci_bus_release_bridge_resources(bus, flags & type_mask, |
1245 | whole_subtree); | 1468 | whole_subtree); |
1246 | list = list->next; | ||
1247 | } | 1469 | } |
1248 | /* restore size and flags */ | 1470 | /* restore size and flags */ |
1249 | for (list = head.next; list;) { | 1471 | list_for_each_entry(fail_res, &fail_head, list) { |
1250 | struct resource *res = list->res; | 1472 | struct resource *res = fail_res->res; |
1251 | 1473 | ||
1252 | res->start = list->start; | 1474 | res->start = fail_res->start; |
1253 | res->end = list->end; | 1475 | res->end = fail_res->end; |
1254 | res->flags = list->flags; | 1476 | res->flags = fail_res->flags; |
1255 | if (list->dev->subordinate) | 1477 | if (fail_res->dev->subordinate) |
1256 | res->flags = 0; | 1478 | res->flags = 0; |
1257 | |||
1258 | list = list->next; | ||
1259 | } | 1479 | } |
1260 | free_list(resource_list_x, &head); | 1480 | free_list(&fail_head); |
1261 | 1481 | ||
1262 | goto again; | 1482 | goto again; |
1263 | 1483 | ||
@@ -1267,3 +1487,41 @@ enable_all: | |||
1267 | pci_enable_bridges(parent); | 1487 | pci_enable_bridges(parent); |
1268 | } | 1488 | } |
1269 | EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources); | 1489 | EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources); |
1490 | |||
1491 | #ifdef CONFIG_HOTPLUG | ||
1492 | /** | ||
1493 | * pci_rescan_bus - scan a PCI bus for devices. | ||
1494 | * @bus: PCI bus to scan | ||
1495 | * | ||
1496 | * Scan a PCI bus and child buses for new devices, adds them, | ||
1497 | * and enables them. | ||
1498 | * | ||
1499 | * Returns the max number of subordinate bus discovered. | ||
1500 | */ | ||
1501 | unsigned int __ref pci_rescan_bus(struct pci_bus *bus) | ||
1502 | { | ||
1503 | unsigned int max; | ||
1504 | struct pci_dev *dev; | ||
1505 | LIST_HEAD(add_list); /* list of resources that | ||
1506 | want additional resources */ | ||
1507 | |||
1508 | max = pci_scan_child_bus(bus); | ||
1509 | |||
1510 | down_read(&pci_bus_sem); | ||
1511 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
1512 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | ||
1513 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) | ||
1514 | if (dev->subordinate) | ||
1515 | __pci_bus_size_bridges(dev->subordinate, | ||
1516 | &add_list); | ||
1517 | up_read(&pci_bus_sem); | ||
1518 | __pci_bus_assign_resources(bus, &add_list, NULL); | ||
1519 | BUG_ON(!list_empty(&add_list)); | ||
1520 | |||
1521 | pci_enable_bridges(bus); | ||
1522 | pci_bus_add_devices(bus); | ||
1523 | |||
1524 | return max; | ||
1525 | } | ||
1526 | EXPORT_SYMBOL_GPL(pci_rescan_bus); | ||
1527 | #endif | ||
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index b66bfdbd21f7..eea85dafc763 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -114,7 +114,6 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
114 | } | 114 | } |
115 | EXPORT_SYMBOL(pci_claim_resource); | 115 | EXPORT_SYMBOL(pci_claim_resource); |
116 | 116 | ||
117 | #ifdef CONFIG_PCI_QUIRKS | ||
118 | void pci_disable_bridge_window(struct pci_dev *dev) | 117 | void pci_disable_bridge_window(struct pci_dev *dev) |
119 | { | 118 | { |
120 | dev_info(&dev->dev, "disabling bridge mem windows\n"); | 119 | dev_info(&dev->dev, "disabling bridge mem windows\n"); |
@@ -127,9 +126,6 @@ void pci_disable_bridge_window(struct pci_dev *dev) | |||
127 | pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0); | 126 | pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0); |
128 | pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff); | 127 | pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff); |
129 | } | 128 | } |
130 | #endif /* CONFIG_PCI_QUIRKS */ | ||
131 | |||
132 | |||
133 | 129 | ||
134 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | 130 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, |
135 | int resno, resource_size_t size, resource_size_t align) | 131 | int resno, resource_size_t size, resource_size_t align) |
@@ -158,22 +154,44 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | |||
158 | return ret; | 154 | return ret; |
159 | } | 155 | } |
160 | 156 | ||
157 | /* | ||
158 | * Generic function that returns a value indicating that the device's | ||
159 | * original BIOS BAR address was not saved and so is not available for | ||
160 | * reinstatement. | ||
161 | * | ||
162 | * Can be over-ridden by architecture specific code that implements | ||
163 | * reinstatement functionality rather than leaving it disabled when | ||
164 | * normal allocation attempts fail. | ||
165 | */ | ||
166 | resource_size_t __weak pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx) | ||
167 | { | ||
168 | return 0; | ||
169 | } | ||
170 | |||
161 | static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, | 171 | static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, |
162 | int resno, resource_size_t size) | 172 | int resno, resource_size_t size) |
163 | { | 173 | { |
164 | struct resource *root, *conflict; | 174 | struct resource *root, *conflict; |
165 | resource_size_t start, end; | 175 | resource_size_t fw_addr, start, end; |
166 | int ret = 0; | 176 | int ret = 0; |
167 | 177 | ||
168 | if (res->flags & IORESOURCE_IO) | 178 | fw_addr = pcibios_retrieve_fw_addr(dev, resno); |
169 | root = &ioport_resource; | 179 | if (!fw_addr) |
170 | else | 180 | return 1; |
171 | root = &iomem_resource; | ||
172 | 181 | ||
173 | start = res->start; | 182 | start = res->start; |
174 | end = res->end; | 183 | end = res->end; |
175 | res->start = dev->fw_addr[resno]; | 184 | res->start = fw_addr; |
176 | res->end = res->start + size - 1; | 185 | res->end = res->start + size - 1; |
186 | |||
187 | root = pci_find_parent_resource(dev, res); | ||
188 | if (!root) { | ||
189 | if (res->flags & IORESOURCE_IO) | ||
190 | root = &ioport_resource; | ||
191 | else | ||
192 | root = &iomem_resource; | ||
193 | } | ||
194 | |||
177 | dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n", | 195 | dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n", |
178 | resno, res); | 196 | resno, res); |
179 | conflict = request_resource_conflict(root, res); | 197 | conflict = request_resource_conflict(root, res); |
@@ -228,16 +246,17 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
228 | int ret; | 246 | int ret; |
229 | 247 | ||
230 | if (!res->parent) { | 248 | if (!res->parent) { |
231 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resouce %pR " | 249 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " |
232 | "\n", resno, res); | 250 | "\n", resno, res); |
233 | return -EINVAL; | 251 | return -EINVAL; |
234 | } | 252 | } |
235 | 253 | ||
236 | new_size = resource_size(res) + addsize + min_align; | 254 | /* already aligned with min_align */ |
255 | new_size = resource_size(res) + addsize; | ||
237 | ret = _pci_assign_resource(dev, resno, new_size, min_align); | 256 | ret = _pci_assign_resource(dev, resno, new_size, min_align); |
238 | if (!ret) { | 257 | if (!ret) { |
239 | res->flags &= ~IORESOURCE_STARTALIGN; | 258 | res->flags &= ~IORESOURCE_STARTALIGN; |
240 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | 259 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); |
241 | if (resno < PCI_BRIDGE_RESOURCES) | 260 | if (resno < PCI_BRIDGE_RESOURCES) |
242 | pci_update_resource(dev, resno); | 261 | pci_update_resource(dev, resno); |
243 | } | 262 | } |
@@ -267,7 +286,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
267 | * where firmware left it. That at least has a chance of | 286 | * where firmware left it. That at least has a chance of |
268 | * working, which is better than just leaving it disabled. | 287 | * working, which is better than just leaving it disabled. |
269 | */ | 288 | */ |
270 | if (ret < 0 && dev->fw_addr[resno]) | 289 | if (ret < 0) |
271 | ret = pci_revert_fw_address(res, dev, resno, size); | 290 | ret = pci_revert_fw_address(res, dev, resno, size); |
272 | 291 | ||
273 | if (!ret) { | 292 | if (!ret) { |
@@ -279,53 +298,6 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
279 | return ret; | 298 | return ret; |
280 | } | 299 | } |
281 | 300 | ||
282 | |||
283 | /* Sort resources by alignment */ | ||
284 | void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | ||
285 | { | ||
286 | int i; | ||
287 | |||
288 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
289 | struct resource *r; | ||
290 | struct resource_list *list, *tmp; | ||
291 | resource_size_t r_align; | ||
292 | |||
293 | r = &dev->resource[i]; | ||
294 | |||
295 | if (r->flags & IORESOURCE_PCI_FIXED) | ||
296 | continue; | ||
297 | |||
298 | if (!(r->flags) || r->parent) | ||
299 | continue; | ||
300 | |||
301 | r_align = pci_resource_alignment(dev, r); | ||
302 | if (!r_align) { | ||
303 | dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n", | ||
304 | i, r); | ||
305 | continue; | ||
306 | } | ||
307 | for (list = head; ; list = list->next) { | ||
308 | resource_size_t align = 0; | ||
309 | struct resource_list *ln = list->next; | ||
310 | |||
311 | if (ln) | ||
312 | align = pci_resource_alignment(ln->dev, ln->res); | ||
313 | |||
314 | if (r_align > align) { | ||
315 | tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); | ||
316 | if (!tmp) | ||
317 | panic("pdev_sort_resources(): " | ||
318 | "kmalloc() failed!\n"); | ||
319 | tmp->next = ln; | ||
320 | tmp->res = r; | ||
321 | tmp->dev = dev; | ||
322 | list->next = tmp; | ||
323 | break; | ||
324 | } | ||
325 | } | ||
326 | } | ||
327 | } | ||
328 | |||
329 | int pci_enable_resources(struct pci_dev *dev, int mask) | 301 | int pci_enable_resources(struct pci_dev *dev, int mask) |
330 | { | 302 | { |
331 | u16 cmd, old_cmd; | 303 | u16 cmd, old_cmd; |
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 401090110922..fd00ff02ab4d 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c | |||
@@ -544,7 +544,7 @@ static void free_root_bus_devs(struct pci_bus *bus) | |||
544 | dev = container_of(bus->devices.next, struct pci_dev, | 544 | dev = container_of(bus->devices.next, struct pci_dev, |
545 | bus_list); | 545 | bus_list); |
546 | dev_dbg(&dev->dev, "removing device\n"); | 546 | dev_dbg(&dev->dev, "removing device\n"); |
547 | pci_remove_bus_device(dev); | 547 | pci_stop_and_remove_bus_device(dev); |
548 | } | 548 | } |
549 | } | 549 | } |
550 | 550 | ||
@@ -1044,7 +1044,7 @@ static int pcifront_detach_devices(struct pcifront_device *pdev) | |||
1044 | domain, bus, slot, func); | 1044 | domain, bus, slot, func); |
1045 | continue; | 1045 | continue; |
1046 | } | 1046 | } |
1047 | pci_remove_bus_device(pci_dev); | 1047 | pci_stop_and_remove_bus_device(pci_dev); |
1048 | pci_dev_put(pci_dev); | 1048 | pci_dev_put(pci_dev); |
1049 | 1049 | ||
1050 | dev_dbg(&pdev->xdev->dev, | 1050 | dev_dbg(&pdev->xdev->dev, |
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index 9a58862f1401..6e75153c5b4f 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c | |||
@@ -108,5 +108,5 @@ void cb_free(struct pcmcia_socket *s) | |||
108 | struct pci_dev *bridge = s->cb_dev; | 108 | struct pci_dev *bridge = s->cb_dev; |
109 | 109 | ||
110 | if (bridge) | 110 | if (bridge) |
111 | pci_remove_behind_bridge(bridge); | 111 | pci_stop_and_remove_behind_bridge(bridge); |
112 | } | 112 | } |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 72d731c21d45..9929246895de 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -571,7 +571,7 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus) | |||
571 | } else { | 571 | } else { |
572 | dev = pci_get_slot(bus, 0); | 572 | dev = pci_get_slot(bus, 0); |
573 | if (dev) { | 573 | if (dev) { |
574 | pci_remove_bus_device(dev); | 574 | pci_stop_and_remove_bus_device(dev); |
575 | pci_dev_put(dev); | 575 | pci_dev_put(dev); |
576 | } | 576 | } |
577 | } | 577 | } |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index ea44abd8df48..d9a9e2bedb30 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -646,7 +646,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
646 | } else { | 646 | } else { |
647 | dev = pci_get_slot(bus, 0); | 647 | dev = pci_get_slot(bus, 0); |
648 | if (dev) { | 648 | if (dev) { |
649 | pci_remove_bus_device(dev); | 649 | pci_stop_and_remove_bus_device(dev); |
650 | pci_dev_put(dev); | 650 | pci_dev_put(dev); |
651 | } | 651 | } |
652 | } | 652 | } |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 82fa6ce481f0..5e69f468535f 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -132,7 +132,7 @@ static int mpt2sas_remove_dead_ioc_func(void *arg) | |||
132 | pdev = ioc->pdev; | 132 | pdev = ioc->pdev; |
133 | if ((pdev == NULL)) | 133 | if ((pdev == NULL)) |
134 | return -1; | 134 | return -1; |
135 | pci_remove_bus_device(pdev); | 135 | pci_stop_and_remove_bus_device(pdev); |
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | 138 | ||
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 7732d69e49e0..11de5f1be981 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -893,4 +893,5 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) | |||
893 | quirk_usb_handoff_xhci(pdev); | 893 | quirk_usb_handoff_xhci(pdev); |
894 | pci_disable_device(pdev); | 894 | pci_disable_device(pdev); |
895 | } | 895 | } |
896 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); | 896 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, |
897 | PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff); | ||