aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/rsrc_nonstatic.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2006-01-07 09:40:05 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-01-07 09:40:05 -0500
commit123656d4cc8c946f578ebd18c2050f5251720428 (patch)
tree3d5432eff034a3b9cfdc98b37e245abe5695342d /drivers/pcmcia/rsrc_nonstatic.c
parenta62c80e559809e6c7851ec04d30575e85ad6f6ed (diff)
parent0aec63e67c69545ca757a73a66f5dcf05fa484bf (diff)
Merge with Linus' kernel.
Diffstat (limited to 'drivers/pcmcia/rsrc_nonstatic.c')
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c140
1 files changed, 75 insertions, 65 deletions
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 00960a379b9c..5301ac60358f 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -75,10 +75,9 @@ static DECLARE_MUTEX(rsrc_sem);
75static struct resource * 75static struct resource *
76make_resource(unsigned long b, unsigned long n, int flags, char *name) 76make_resource(unsigned long b, unsigned long n, int flags, char *name)
77{ 77{
78 struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL); 78 struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
79 79
80 if (res) { 80 if (res) {
81 memset(res, 0, sizeof(*res));
82 res->name = name; 81 res->name = name;
83 res->start = b; 82 res->start = b;
84 res->end = b + n - 1; 83 res->end = b + n - 1;
@@ -200,12 +199,11 @@ static void do_io_probe(struct pcmcia_socket *s, kio_addr_t base, kio_addr_t num
200 base, base+num-1); 199 base, base+num-1);
201 200
202 /* First, what does a floating port look like? */ 201 /* First, what does a floating port look like? */
203 b = kmalloc(256, GFP_KERNEL); 202 b = kzalloc(256, GFP_KERNEL);
204 if (!b) { 203 if (!b) {
205 printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes"); 204 printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
206 return; 205 return;
207 } 206 }
208 memset(b, 0, 256);
209 for (i = base, most = 0; i < base+num; i += 8) { 207 for (i = base, most = 0; i < base+num; i += 8) {
210 res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe"); 208 res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
211 if (!res) 209 if (!res)
@@ -407,69 +405,79 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
407 405
408static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s) 406static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
409{ 407{
410 struct socket_data *s_data = s->resource_data; 408 struct socket_data *s_data = s->resource_data;
411 u_long ok; 409 u_long ok;
412 if (m == &s_data->mem_db) 410 if (m == &s_data->mem_db)
413 return 0; 411 return 0;
414 ok = inv_probe(m->next, s); 412 ok = inv_probe(m->next, s);
415 if (ok) { 413 if (ok) {
416 if (m->base >= 0x100000) 414 if (m->base >= 0x100000)
417 sub_interval(&s_data->mem_db, m->base, m->num); 415 sub_interval(&s_data->mem_db, m->base, m->num);
418 return ok; 416 return ok;
419 } 417 }
420 if (m->base < 0x100000) 418 if (m->base < 0x100000)
421 return 0; 419 return 0;
422 return do_mem_probe(m->base, m->num, s); 420 return do_mem_probe(m->base, m->num, s);
423} 421}
424 422
425static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) 423static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
426{ 424{
427 struct resource_map *m, mm; 425 struct resource_map *m, mm;
428 static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; 426 static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
429 u_long b, i, ok = 0; 427 unsigned long b, i, ok = 0;
430 struct socket_data *s_data = s->resource_data; 428 struct socket_data *s_data = s->resource_data;
431 429
432 /* We do up to four passes through the list */ 430 /* We do up to four passes through the list */
433 if (probe_mask & MEM_PROBE_HIGH) { 431 if (probe_mask & MEM_PROBE_HIGH) {
434 if (inv_probe(s_data->mem_db.next, s) > 0) 432 if (inv_probe(s_data->mem_db.next, s) > 0)
435 return; 433 return 0;
436 printk(KERN_NOTICE "cs: warning: no high memory space " 434 printk(KERN_NOTICE "cs: warning: no high memory space "
437 "available!\n"); 435 "available!\n");
438 } 436 return -ENODEV;
439 if ((probe_mask & MEM_PROBE_LOW) == 0)
440 return;
441 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
442 mm = *m;
443 /* Only probe < 1 MB */
444 if (mm.base >= 0x100000) continue;
445 if ((mm.base | mm.num) & 0xffff) {
446 ok += do_mem_probe(mm.base, mm.num, s);
447 continue;
448 } 437 }
449 /* Special probe for 64K-aligned block */ 438
450 for (i = 0; i < 4; i++) { 439 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
451 b = order[i] << 12; 440 mm = *m;
452 if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) { 441 /* Only probe < 1 MB */
453 if (ok >= mem_limit) 442 if (mm.base >= 0x100000)
454 sub_interval(&s_data->mem_db, b, 0x10000); 443 continue;
455 else 444 if ((mm.base | mm.num) & 0xffff) {
456 ok += do_mem_probe(b, 0x10000, s); 445 ok += do_mem_probe(mm.base, mm.num, s);
457 } 446 continue;
447 }
448 /* Special probe for 64K-aligned block */
449 for (i = 0; i < 4; i++) {
450 b = order[i] << 12;
451 if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
452 if (ok >= mem_limit)
453 sub_interval(&s_data->mem_db, b, 0x10000);
454 else
455 ok += do_mem_probe(b, 0x10000, s);
456 }
457 }
458 } 458 }
459 } 459
460 if (ok > 0)
461 return 0;
462
463 return -ENODEV;
460} 464}
461 465
462#else /* CONFIG_PCMCIA_PROBE */ 466#else /* CONFIG_PCMCIA_PROBE */
463 467
464static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) 468static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
465{ 469{
466 struct resource_map *m, mm; 470 struct resource_map *m, mm;
467 struct socket_data *s_data = s->resource_data; 471 struct socket_data *s_data = s->resource_data;
472 unsigned long ok = 0;
468 473
469 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { 474 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
470 mm = *m; 475 mm = *m;
471 do_mem_probe(mm.base, mm.num, s); 476 ok += do_mem_probe(mm.base, mm.num, s);
472 } 477 }
478 if (ok > 0)
479 return 0;
480 return -ENODEV;
473} 481}
474 482
475#endif /* CONFIG_PCMCIA_PROBE */ 483#endif /* CONFIG_PCMCIA_PROBE */
@@ -478,27 +486,30 @@ static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
478/* 486/*
479 * Locking note: Must be called with skt_sem held! 487 * Locking note: Must be called with skt_sem held!
480 */ 488 */
481static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) 489static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
482{ 490{
483 struct socket_data *s_data = s->resource_data; 491 struct socket_data *s_data = s->resource_data;
484 if (probe_mem) { 492 unsigned int probe_mask = MEM_PROBE_LOW;
485 unsigned int probe_mask; 493 int ret = 0;
486 494
487 down(&rsrc_sem); 495 if (!probe_mem)
496 return 0;
488 497
489 probe_mask = MEM_PROBE_LOW; 498 down(&rsrc_sem);
490 if (s->features & SS_CAP_PAGE_REGS)
491 probe_mask = MEM_PROBE_HIGH;
492 499
493 if (probe_mask & ~s_data->rsrc_mem_probe) { 500 if (s->features & SS_CAP_PAGE_REGS)
501 probe_mask = MEM_PROBE_HIGH;
502
503 if (probe_mask & ~s_data->rsrc_mem_probe) {
504 if (s->state & SOCKET_PRESENT)
505 ret = validate_mem(s, probe_mask);
506 if (!ret)
494 s_data->rsrc_mem_probe |= probe_mask; 507 s_data->rsrc_mem_probe |= probe_mask;
508 }
495 509
496 if (s->state & SOCKET_PRESENT) 510 up(&rsrc_sem);
497 validate_mem(s, probe_mask);
498 }
499 511
500 up(&rsrc_sem); 512 return ret;
501 }
502} 513}
503 514
504struct pcmcia_align_data { 515struct pcmcia_align_data {
@@ -837,10 +848,9 @@ static int nonstatic_init(struct pcmcia_socket *s)
837{ 848{
838 struct socket_data *data; 849 struct socket_data *data;
839 850
840 data = kmalloc(sizeof(struct socket_data), GFP_KERNEL); 851 data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
841 if (!data) 852 if (!data)
842 return -ENOMEM; 853 return -ENOMEM;
843 memset(data, 0, sizeof(struct socket_data));
844 854
845 data->mem_db.next = &data->mem_db; 855 data->mem_db.next = &data->mem_db;
846 data->io_db.next = &data->io_db; 856 data->io_db.next = &data->io_db;