diff options
Diffstat (limited to 'drivers/pcmcia/rsrc_nonstatic.c')
-rw-r--r-- | drivers/pcmcia/rsrc_nonstatic.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 2e47991eccf6..a6eb7b59ba9f 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -214,7 +214,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, | |||
214 | return; | 214 | return; |
215 | } | 215 | } |
216 | for (i = base, most = 0; i < base+num; i += 8) { | 216 | for (i = base, most = 0; i < base+num; i += 8) { |
217 | res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); | 217 | res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); |
218 | if (!res) | 218 | if (!res) |
219 | continue; | 219 | continue; |
220 | hole = inb(i); | 220 | hole = inb(i); |
@@ -231,9 +231,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, | |||
231 | 231 | ||
232 | bad = any = 0; | 232 | bad = any = 0; |
233 | for (i = base; i < base+num; i += 8) { | 233 | for (i = base; i < base+num; i += 8) { |
234 | res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); | 234 | res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); |
235 | if (!res) | 235 | if (!res) { |
236 | if (!any) | ||
237 | printk(" excluding"); | ||
238 | if (!bad) | ||
239 | bad = any = i; | ||
236 | continue; | 240 | continue; |
241 | } | ||
237 | for (j = 0; j < 8; j++) | 242 | for (j = 0; j < 8; j++) |
238 | if (inb(i+j) != most) | 243 | if (inb(i+j) != most) |
239 | break; | 244 | break; |
@@ -253,6 +258,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, | |||
253 | } | 258 | } |
254 | if (bad) { | 259 | if (bad) { |
255 | if ((num > 16) && (bad == base) && (i == base+num)) { | 260 | if ((num > 16) && (bad == base) && (i == base+num)) { |
261 | sub_interval(&s_data->io_db, bad, i-bad); | ||
256 | printk(" nothing: probe failed.\n"); | 262 | printk(" nothing: probe failed.\n"); |
257 | return; | 263 | return; |
258 | } else { | 264 | } else { |
@@ -596,19 +602,17 @@ struct pcmcia_align_data { | |||
596 | struct resource_map *map; | 602 | struct resource_map *map; |
597 | }; | 603 | }; |
598 | 604 | ||
599 | static resource_size_t | 605 | static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data, |
600 | pcmcia_common_align(void *align_data, const struct resource *res, | 606 | resource_size_t start) |
601 | resource_size_t size, resource_size_t align) | ||
602 | { | 607 | { |
603 | struct pcmcia_align_data *data = align_data; | 608 | resource_size_t ret; |
604 | resource_size_t start; | ||
605 | /* | 609 | /* |
606 | * Ensure that we have the correct start address | 610 | * Ensure that we have the correct start address |
607 | */ | 611 | */ |
608 | start = (res->start & ~data->mask) + data->offset; | 612 | ret = (start & ~align_data->mask) + align_data->offset; |
609 | if (start < res->start) | 613 | if (ret < start) |
610 | start += data->mask + 1; | 614 | ret += align_data->mask + 1; |
611 | return start; | 615 | return ret; |
612 | } | 616 | } |
613 | 617 | ||
614 | static resource_size_t | 618 | static resource_size_t |
@@ -619,29 +623,28 @@ pcmcia_align(void *align_data, const struct resource *res, | |||
619 | struct resource_map *m; | 623 | struct resource_map *m; |
620 | resource_size_t start; | 624 | resource_size_t start; |
621 | 625 | ||
622 | start = pcmcia_common_align(data, res, size, align); | 626 | start = pcmcia_common_align(data, res->start); |
623 | 627 | ||
624 | for (m = data->map->next; m != data->map; m = m->next) { | 628 | for (m = data->map->next; m != data->map; m = m->next) { |
625 | unsigned long start = m->base; | 629 | unsigned long map_start = m->base; |
626 | unsigned long end = m->base + m->num - 1; | 630 | unsigned long map_end = m->base + m->num - 1; |
627 | 631 | ||
628 | /* | 632 | /* |
629 | * If the lower resources are not available, try aligning | 633 | * If the lower resources are not available, try aligning |
630 | * to this entry of the resource database to see if it'll | 634 | * to this entry of the resource database to see if it'll |
631 | * fit here. | 635 | * fit here. |
632 | */ | 636 | */ |
633 | if (res->start < start) { | 637 | if (start < map_start) |
634 | start = pcmcia_common_align(data, res, size, align); | 638 | start = pcmcia_common_align(data, map_start); |
635 | } | ||
636 | 639 | ||
637 | /* | 640 | /* |
638 | * If we're above the area which was passed in, there's | 641 | * If we're above the area which was passed in, there's |
639 | * no point proceeding. | 642 | * no point proceeding. |
640 | */ | 643 | */ |
641 | if (res->start >= res->end) | 644 | if (start >= res->end) |
642 | break; | 645 | break; |
643 | 646 | ||
644 | if ((res->start + size - 1) <= end) | 647 | if ((start + size - 1) <= map_end) |
645 | break; | 648 | break; |
646 | } | 649 | } |
647 | 650 | ||
@@ -807,7 +810,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned | |||
807 | static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end) | 810 | static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end) |
808 | { | 811 | { |
809 | struct socket_data *data = s->resource_data; | 812 | struct socket_data *data = s->resource_data; |
810 | unsigned long size = end - start + 1; | 813 | unsigned long size; |
811 | int ret = 0; | 814 | int ret = 0; |
812 | 815 | ||
813 | #if defined(CONFIG_X86) | 816 | #if defined(CONFIG_X86) |
@@ -817,6 +820,8 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long | |||
817 | start = 0x100; | 820 | start = 0x100; |
818 | #endif | 821 | #endif |
819 | 822 | ||
823 | size = end - start + 1; | ||
824 | |||
820 | if (end < start) | 825 | if (end < start) |
821 | return -EINVAL; | 826 | return -EINVAL; |
822 | 827 | ||