[PATCH] pcmcia: resource handling fixes

- properly bail out in set_cis_map if call to socket driver's set_mem_map
failed
- don't abort do_mem_probe cycle if one entry failed (!CONFIG_PCMCIA_PROBE)
- don't do iomem probing in chunks larger than 0x800000 (1 << 23) as
yenta_socket and vrc4173_cardu.c fail to set_mem_map for windows equal to
or larger than (1 << 24).

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Dominik Brodowski and committed by Linus Torvalds 2ad0a0a7 f861bd23

+12 -3
+8 -1
drivers/pcmcia/cistpl.c
··· 89 set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) 90 { 91 pccard_mem_map *mem = &s->cis_mem; 92 if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) { 93 mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); 94 if (mem->res == NULL) { ··· 101 } 102 mem->card_start = card_offset; 103 mem->flags = flags; 104 - s->ops->set_mem_map(s, mem); 105 if (s->features & SS_CAP_STATIC_MAP) { 106 if (s->cis_virt) 107 iounmap(s->cis_virt);
··· 89 set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) 90 { 91 pccard_mem_map *mem = &s->cis_mem; 92 + int ret; 93 + 94 if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) { 95 mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); 96 if (mem->res == NULL) { ··· 99 } 100 mem->card_start = card_offset; 101 mem->flags = flags; 102 + ret = s->ops->set_mem_map(s, mem); 103 + if (ret) { 104 + iounmap(s->cis_virt); 105 + return NULL; 106 + } 107 + 108 if (s->features & SS_CAP_STATIC_MAP) { 109 if (s->cis_virt) 110 iounmap(s->cis_virt);
+4 -2
drivers/pcmcia/rsrc_nonstatic.c
··· 372 base, base+num-1); 373 bad = fail = 0; 374 step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff); 375 /* cis_readable wants to map 2x map_size */ 376 if (step < 2 * s->map_size) 377 step = 2 * s->map_size; ··· 468 469 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { 470 mm = *m; 471 - if (do_mem_probe(mm.base, mm.num, s)) 472 - break; 473 } 474 } 475
··· 372 base, base+num-1); 373 bad = fail = 0; 374 step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff); 375 + /* don't allow too large steps */ 376 + if (step > 0x800000) 377 + step = 0x800000; 378 /* cis_readable wants to map 2x map_size */ 379 if (step < 2 * s->map_size) 380 step = 2 * s->map_size; ··· 465 466 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { 467 mm = *m; 468 + do_mem_probe(mm.base, mm.num, s); 469 } 470 } 471