diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pcmcia/rsrc_nonstatic.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index ba5256debde2..dcd1a4ad3d63 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -935,23 +935,42 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) | |||
935 | return -ENODEV; | 935 | return -ENODEV; |
936 | 936 | ||
937 | #if defined(CONFIG_X86) | 937 | #if defined(CONFIG_X86) |
938 | /* If this is the root bus, the risk of hitting | 938 | /* If this is the root bus, the risk of hitting some strange |
939 | * some strange system devices which aren't protected | 939 | * system devices is too high: If a driver isn't loaded, the |
940 | * by either ACPI resource tables or properly requested | 940 | * resources are not claimed; even if a driver is loaded, it |
941 | * resources is too big. Therefore, don't do auto-adding | 941 | * may not request all resources or even the wrong one. We |
942 | * of resources at the moment. | 942 | * can neither trust the rest of the kernel nor ACPI/PNP and |
943 | * CRS parsing to get it right. Therefore, use several | ||
944 | * safeguards: | ||
945 | * | ||
946 | * - Do not auto-add resources if the CardBus bridge is on | ||
947 | * the PCI root bus | ||
948 | * | ||
949 | * - Avoid any I/O ports < 0x100. | ||
950 | * | ||
951 | * - On PCI-PCI bridges, only use resources which are set up | ||
952 | * exclusively for the secondary PCI bus: the risk of hitting | ||
953 | * system devices is quite low, as they usually aren't | ||
954 | * connected to the secondary PCI bus. | ||
943 | */ | 955 | */ |
944 | if (s->cb_dev->bus->number == 0) | 956 | if (s->cb_dev->bus->number == 0) |
945 | return -EINVAL; | 957 | return -EINVAL; |
946 | #endif | ||
947 | 958 | ||
959 | for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) { | ||
960 | res = s->cb_dev->bus->resource[i]; | ||
961 | #else | ||
948 | pci_bus_for_each_resource(s->cb_dev->bus, res, i) { | 962 | pci_bus_for_each_resource(s->cb_dev->bus, res, i) { |
963 | #endif | ||
949 | if (!res) | 964 | if (!res) |
950 | continue; | 965 | continue; |
951 | 966 | ||
952 | if (res->flags & IORESOURCE_IO) { | 967 | if (res->flags & IORESOURCE_IO) { |
968 | /* safeguard against the root resource, where the | ||
969 | * risk of hitting any other device would be too | ||
970 | * high */ | ||
953 | if (res == &ioport_resource) | 971 | if (res == &ioport_resource) |
954 | continue; | 972 | continue; |
973 | |||
955 | dev_printk(KERN_INFO, &s->cb_dev->dev, | 974 | dev_printk(KERN_INFO, &s->cb_dev->dev, |
956 | "pcmcia: parent PCI bridge window: %pR\n", | 975 | "pcmcia: parent PCI bridge window: %pR\n", |
957 | res); | 976 | res); |
@@ -961,8 +980,12 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) | |||
961 | } | 980 | } |
962 | 981 | ||
963 | if (res->flags & IORESOURCE_MEM) { | 982 | if (res->flags & IORESOURCE_MEM) { |
983 | /* safeguard against the root resource, where the | ||
984 | * risk of hitting any other device would be too | ||
985 | * high */ | ||
964 | if (res == &iomem_resource) | 986 | if (res == &iomem_resource) |
965 | continue; | 987 | continue; |
988 | |||
966 | dev_printk(KERN_INFO, &s->cb_dev->dev, | 989 | dev_printk(KERN_INFO, &s->cb_dev->dev, |
967 | "pcmcia: parent PCI bridge window: %pR\n", | 990 | "pcmcia: parent PCI bridge window: %pR\n", |
968 | res); | 991 | res); |