diff options
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); | ||