aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/rsrc_nonstatic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/rsrc_nonstatic.c')
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c47
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
599static resource_size_t 605static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data,
600pcmcia_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
614static resource_size_t 618static 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
807static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end) 810static 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