aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/setup-bus.c
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2012-02-10 18:33:47 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2012-02-23 14:59:56 -0500
commit1184893439b1a7532b579a85a354db12bbf1b277 (patch)
treecfba5be149def3389707a0773909d44c50b58f30 /drivers/pci/setup-bus.c
parentdcef0d06b34a80071da4496556e85f9bf3b3c0bf (diff)
PCI: Fix "cardbus bridge resources as optional" size handling
We should not set the requested size to -2; that will confuse the resource list sorting with align when SIZEALIGN is used. Change to STARTALIGN and pass align from start; we are safe to do that just as we do that regular pci bridge. In the long run, we should just treat cardbus like a regular pci bridge. Also fix the case when realloc_head is not passed: we should keep the requested size. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Tested-by: Dominik Brodowski <linux@dominikbrodowski.net> Acked-by: Ram Pai <linuxram@us.ibm.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/setup-bus.c')
-rw-r--r--drivers/pci/setup-bus.c65
1 files changed, 37 insertions, 28 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index d5897c32f66..3b3932a6465 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -898,21 +898,30 @@ static void pci_bus_size_cardbus(struct pci_bus *bus,
898{ 898{
899 struct pci_dev *bridge = bus->self; 899 struct pci_dev *bridge = bus->self;
900 struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; 900 struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
901 resource_size_t b_res_3_size = pci_cardbus_mem_size * 2;
901 u16 ctrl; 902 u16 ctrl;
902 903
903 /* 904 /*
904 * Reserve some resources for CardBus. We reserve 905 * Reserve some resources for CardBus. We reserve
905 * a fixed amount of bus space for CardBus bridges. 906 * a fixed amount of bus space for CardBus bridges.
906 */ 907 */
907 b_res[0].start = 0; 908 b_res[0].start = pci_cardbus_io_size;
908 b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; 909 b_res[0].end = b_res[0].start + pci_cardbus_io_size - 1;
909 if (realloc_head) 910 b_res[0].flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN;
910 add_to_list(realloc_head, bridge, b_res, pci_cardbus_io_size, 0 /* dont care */); 911 if (realloc_head) {
912 b_res[0].end -= pci_cardbus_io_size;
913 add_to_list(realloc_head, bridge, b_res, pci_cardbus_io_size,
914 pci_cardbus_io_size);
915 }
911 916
912 b_res[1].start = 0; 917 b_res[1].start = pci_cardbus_io_size;
913 b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; 918 b_res[1].end = b_res[1].start + pci_cardbus_io_size - 1;
914 if (realloc_head) 919 b_res[1].flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN;
915 add_to_list(realloc_head, bridge, b_res+1, pci_cardbus_io_size, 0 /* dont care */); 920 if (realloc_head) {
921 b_res[1].end -= pci_cardbus_io_size;
922 add_to_list(realloc_head, bridge, b_res+1, pci_cardbus_io_size,
923 pci_cardbus_io_size);
924 }
916 925
917 /* MEM1 must not be pref mmio */ 926 /* MEM1 must not be pref mmio */
918 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); 927 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
@@ -939,28 +948,28 @@ static void pci_bus_size_cardbus(struct pci_bus *bus,
939 * twice the size. 948 * twice the size.
940 */ 949 */
941 if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { 950 if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
942 b_res[2].start = 0; 951 b_res[2].start = pci_cardbus_mem_size;
943 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN; 952 b_res[2].end = b_res[2].start + pci_cardbus_mem_size - 1;
944 if (realloc_head) 953 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH |
945 add_to_list(realloc_head, bridge, b_res+2, pci_cardbus_mem_size, 0 /* dont care */); 954 IORESOURCE_STARTALIGN;
946 955 if (realloc_head) {
947 b_res[3].start = 0; 956 b_res[2].end -= pci_cardbus_mem_size;
948 b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; 957 add_to_list(realloc_head, bridge, b_res+2,
949 if (realloc_head) 958 pci_cardbus_mem_size, pci_cardbus_mem_size);
950 add_to_list(realloc_head, bridge, b_res+3, pci_cardbus_mem_size, 0 /* dont care */); 959 }
951 } else { 960
952 b_res[3].start = 0; 961 /* reduce that to half */
953 b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; 962 b_res_3_size = pci_cardbus_mem_size;
954 if (realloc_head)
955 add_to_list(realloc_head, bridge, b_res+3, pci_cardbus_mem_size * 2, 0 /* dont care */);
956 } 963 }
957 964
958 /* set the size of the resource to zero, so that the resource does not 965 b_res[3].start = pci_cardbus_mem_size;
959 * get assigned during required-resource allocation cycle but gets assigned 966 b_res[3].end = b_res[3].start + b_res_3_size - 1;
960 * during the optional-resource allocation cycle. 967 b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_STARTALIGN;
961 */ 968 if (realloc_head) {
962 b_res[0].start = b_res[1].start = b_res[2].start = b_res[3].start = 1; 969 b_res[3].end -= b_res_3_size;
963 b_res[0].end = b_res[1].end = b_res[2].end = b_res[3].end = 0; 970 add_to_list(realloc_head, bridge, b_res+3, b_res_3_size,
971 pci_cardbus_mem_size);
972 }
964} 973}
965 974
966void __ref __pci_bus_size_bridges(struct pci_bus *bus, 975void __ref __pci_bus_size_bridges(struct pci_bus *bus,