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.c285
1 files changed, 179 insertions, 106 deletions
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index c67638fe6914..4663b3fa9f96 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -55,11 +55,10 @@ struct resource_map {
55 55
56struct socket_data { 56struct socket_data {
57 struct resource_map mem_db; 57 struct resource_map mem_db;
58 struct resource_map mem_db_valid;
58 struct resource_map io_db; 59 struct resource_map io_db;
59 unsigned int rsrc_mem_probe;
60}; 60};
61 61
62static DEFINE_MUTEX(rsrc_mutex);
63#define MEM_PROBE_LOW (1 << 0) 62#define MEM_PROBE_LOW (1 << 0)
64#define MEM_PROBE_HIGH (1 << 1) 63#define MEM_PROBE_HIGH (1 << 1)
65 64
@@ -125,8 +124,10 @@ static int add_interval(struct resource_map *map, u_long base, u_long num)
125 struct resource_map *p, *q; 124 struct resource_map *p, *q;
126 125
127 for (p = map; ; p = p->next) { 126 for (p = map; ; p = p->next) {
128 if ((p != map) && (p->base+p->num-1 >= base)) 127 if ((p != map) && (p->base+p->num >= base)) {
129 return -1; 128 p->num = max(num + base - p->base, p->num);
129 return 0;
130 }
130 if ((p->next == map) || (p->next->base > base+num-1)) 131 if ((p->next == map) || (p->next->base > base+num-1))
131 break; 132 break;
132 } 133 }
@@ -264,36 +265,44 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
264} 265}
265#endif 266#endif
266 267
267/*====================================================================== 268/*======================================================================*/
268
269 This is tricky... when we set up CIS memory, we try to validate
270 the memory window space allocations.
271
272======================================================================*/
273 269
274/* Validation function for cards with a valid CIS */ 270/**
271 * readable() - iomem validation function for cards with a valid CIS
272 */
275static int readable(struct pcmcia_socket *s, struct resource *res, 273static int readable(struct pcmcia_socket *s, struct resource *res,
276 unsigned int *count) 274 unsigned int *count)
277{ 275{
278 int ret = -1; 276 int ret = -EINVAL;
277
278 if (s->fake_cis) {
279 dev_dbg(&s->dev, "fake CIS is being used: can't validate mem\n");
280 return 0;
281 }
279 282
280 s->cis_mem.res = res; 283 s->cis_mem.res = res;
281 s->cis_virt = ioremap(res->start, s->map_size); 284 s->cis_virt = ioremap(res->start, s->map_size);
282 if (s->cis_virt) { 285 if (s->cis_virt) {
283 ret = pccard_validate_cis(s, count); 286 mutex_unlock(&s->ops_mutex);
284 /* invalidate mapping and CIS cache */ 287 /* as we're only called from pcmcia.c, we're safe */
288 if (s->callback->validate)
289 ret = s->callback->validate(s, count);
290 /* invalidate mapping */
291 mutex_lock(&s->ops_mutex);
285 iounmap(s->cis_virt); 292 iounmap(s->cis_virt);
286 s->cis_virt = NULL; 293 s->cis_virt = NULL;
287 destroy_cis_cache(s);
288 } 294 }
289 s->cis_mem.res = NULL; 295 s->cis_mem.res = NULL;
290 if ((ret != 0) || (*count == 0)) 296 if ((ret) || (*count == 0))
291 return 0; 297 return -EINVAL;
292 return 1; 298 return 0;
293} 299}
294 300
295/* Validation function for simple memory cards */ 301/**
296static int checksum(struct pcmcia_socket *s, struct resource *res) 302 * checksum() - iomem validation function for simple memory cards
303 */
304static int checksum(struct pcmcia_socket *s, struct resource *res,
305 unsigned int *value)
297{ 306{
298 pccard_mem_map map; 307 pccard_mem_map map;
299 int i, a = 0, b = -1, d; 308 int i, a = 0, b = -1, d;
@@ -321,61 +330,90 @@ static int checksum(struct pcmcia_socket *s, struct resource *res)
321 iounmap(virt); 330 iounmap(virt);
322 } 331 }
323 332
324 return (b == -1) ? -1 : (a>>1); 333 if (b == -1)
334 return -EINVAL;
335
336 *value = a;
337
338 return 0;
325} 339}
326 340
327static int 341/**
328cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size) 342 * do_validate_mem() - low level validate a memory region for PCMCIA use
343 * @s: PCMCIA socket to validate
344 * @base: start address of resource to check
345 * @size: size of resource to check
346 * @validate: validation function to use
347 *
348 * do_validate_mem() splits up the memory region which is to be checked
349 * into two parts. Both are passed to the @validate() function. If
350 * @validate() returns non-zero, or the value parameter to @validate()
351 * is zero, or the value parameter is different between both calls,
352 * the check fails, and -EINVAL is returned. Else, 0 is returned.
353 */
354static int do_validate_mem(struct pcmcia_socket *s,
355 unsigned long base, unsigned long size,
356 int validate (struct pcmcia_socket *s,
357 struct resource *res,
358 unsigned int *value))
329{ 359{
360 struct socket_data *s_data = s->resource_data;
330 struct resource *res1, *res2; 361 struct resource *res1, *res2;
331 unsigned int info1, info2; 362 unsigned int info1 = 1, info2 = 1;
332 int ret = 0; 363 int ret = -EINVAL;
333 364
334 res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe"); 365 res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
335 res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, 366 res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
336 "PCMCIA memprobe"); 367 "PCMCIA memprobe");
337 368
338 if (res1 && res2) { 369 if (res1 && res2) {
339 ret = readable(s, res1, &info1); 370 ret = 0;
340 ret += readable(s, res2, &info2); 371 if (validate) {
372 ret = validate(s, res1, &info1);
373 ret += validate(s, res2, &info2);
374 }
341 } 375 }
342 376
343 free_region(res2); 377 free_region(res2);
344 free_region(res1); 378 free_region(res1);
345 379
346 return (ret == 2) && (info1 == info2); 380 dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
347} 381 base, base+size-1, res1, res2, ret, info1, info2);
348 382
349static int 383 if ((ret) || (info1 != info2) || (info1 == 0))
350checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size) 384 return -EINVAL;
351{
352 struct resource *res1, *res2;
353 int a = -1, b = -1;
354
355 res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
356 res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
357 "PCMCIA memprobe");
358 385
359 if (res1 && res2) { 386 if (validate && !s->fake_cis) {
360 a = checksum(s, res1); 387 /* move it to the validated data set */
361 b = checksum(s, res2); 388 add_interval(&s_data->mem_db_valid, base, size);
389 sub_interval(&s_data->mem_db, base, size);
362 } 390 }
363 391
364 free_region(res2); 392 return 0;
365 free_region(res1);
366
367 return (a == b) && (a >= 0);
368} 393}
369 394
370/*======================================================================
371
372 The memory probe. If the memory list includes a 64K-aligned block
373 below 1MB, we probe in 64K chunks, and as soon as we accumulate at
374 least mem_limit free space, we quit.
375
376======================================================================*/
377 395
378static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s) 396/**
397 * do_mem_probe() - validate a memory region for PCMCIA use
398 * @s: PCMCIA socket to validate
399 * @base: start address of resource to check
400 * @num: size of resource to check
401 * @validate: validation function to use
402 * @fallback: validation function to use if validate fails
403 *
404 * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
405 * To do so, the area is split up into sensible parts, and then passed
406 * into the @validate() function. Only if @validate() and @fallback() fail,
407 * the area is marked as unavaibale for use by the PCMCIA subsystem. The
408 * function returns the size of the usable memory area.
409 */
410static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
411 int validate (struct pcmcia_socket *s,
412 struct resource *res,
413 unsigned int *value),
414 int fallback (struct pcmcia_socket *s,
415 struct resource *res,
416 unsigned int *value))
379{ 417{
380 struct socket_data *s_data = s->resource_data; 418 struct socket_data *s_data = s->resource_data;
381 u_long i, j, bad, fail, step; 419 u_long i, j, bad, fail, step;
@@ -393,15 +431,14 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
393 for (i = j = base; i < base+num; i = j + step) { 431 for (i = j = base; i < base+num; i = j + step) {
394 if (!fail) { 432 if (!fail) {
395 for (j = i; j < base+num; j += step) { 433 for (j = i; j < base+num; j += step) {
396 if (cis_readable(s, j, step)) 434 if (!do_validate_mem(s, j, step, validate))
397 break; 435 break;
398 } 436 }
399 fail = ((i == base) && (j == base+num)); 437 fail = ((i == base) && (j == base+num));
400 } 438 }
401 if (fail) { 439 if ((fail) && (fallback)) {
402 for (j = i; j < base+num; j += 2*step) 440 for (j = i; j < base+num; j += step)
403 if (checksum_match(s, j, step) && 441 if (!do_validate_mem(s, j, step, fallback))
404 checksum_match(s, j + step, step))
405 break; 442 break;
406 } 443 }
407 if (i != j) { 444 if (i != j) {
@@ -416,8 +453,14 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
416 return num - bad; 453 return num - bad;
417} 454}
418 455
456
419#ifdef CONFIG_PCMCIA_PROBE 457#ifdef CONFIG_PCMCIA_PROBE
420 458
459/**
460 * inv_probe() - top-to-bottom search for one usuable high memory area
461 * @s: PCMCIA socket to validate
462 * @m: resource_map to check
463 */
421static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s) 464static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
422{ 465{
423 struct socket_data *s_data = s->resource_data; 466 struct socket_data *s_data = s->resource_data;
@@ -432,9 +475,18 @@ static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
432 } 475 }
433 if (m->base < 0x100000) 476 if (m->base < 0x100000)
434 return 0; 477 return 0;
435 return do_mem_probe(m->base, m->num, s); 478 return do_mem_probe(s, m->base, m->num, readable, checksum);
436} 479}
437 480
481/**
482 * validate_mem() - memory probe function
483 * @s: PCMCIA socket to validate
484 * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
485 *
486 * The memory probe. If the memory list includes a 64K-aligned block
487 * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
488 * least mem_limit free space, we quit. Returns 0 on usuable ports.
489 */
438static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) 490static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
439{ 491{
440 struct resource_map *m, mm; 492 struct resource_map *m, mm;
@@ -446,6 +498,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
446 if (probe_mask & MEM_PROBE_HIGH) { 498 if (probe_mask & MEM_PROBE_HIGH) {
447 if (inv_probe(s_data->mem_db.next, s) > 0) 499 if (inv_probe(s_data->mem_db.next, s) > 0)
448 return 0; 500 return 0;
501 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
502 return 0;
449 dev_printk(KERN_NOTICE, &s->dev, 503 dev_printk(KERN_NOTICE, &s->dev,
450 "cs: warning: no high memory space available!\n"); 504 "cs: warning: no high memory space available!\n");
451 return -ENODEV; 505 return -ENODEV;
@@ -457,7 +511,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
457 if (mm.base >= 0x100000) 511 if (mm.base >= 0x100000)
458 continue; 512 continue;
459 if ((mm.base | mm.num) & 0xffff) { 513 if ((mm.base | mm.num) & 0xffff) {
460 ok += do_mem_probe(mm.base, mm.num, s); 514 ok += do_mem_probe(s, mm.base, mm.num, readable,
515 checksum);
461 continue; 516 continue;
462 } 517 }
463 /* Special probe for 64K-aligned block */ 518 /* Special probe for 64K-aligned block */
@@ -467,7 +522,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
467 if (ok >= mem_limit) 522 if (ok >= mem_limit)
468 sub_interval(&s_data->mem_db, b, 0x10000); 523 sub_interval(&s_data->mem_db, b, 0x10000);
469 else 524 else
470 ok += do_mem_probe(b, 0x10000, s); 525 ok += do_mem_probe(s, b, 0x10000,
526 readable, checksum);
471 } 527 }
472 } 528 }
473 } 529 }
@@ -480,6 +536,13 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
480 536
481#else /* CONFIG_PCMCIA_PROBE */ 537#else /* CONFIG_PCMCIA_PROBE */
482 538
539/**
540 * validate_mem() - memory probe function
541 * @s: PCMCIA socket to validate
542 * @probe_mask: ignored
543 *
544 * Returns 0 on usuable ports.
545 */
483static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) 546static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
484{ 547{
485 struct resource_map *m, mm; 548 struct resource_map *m, mm;
@@ -488,7 +551,7 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
488 551
489 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { 552 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
490 mm = *m; 553 mm = *m;
491 ok += do_mem_probe(mm.base, mm.num, s); 554 ok += do_mem_probe(s, mm.base, mm.num, readable, checksum);
492 } 555 }
493 if (ok > 0) 556 if (ok > 0)
494 return 0; 557 return 0;
@@ -498,31 +561,31 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
498#endif /* CONFIG_PCMCIA_PROBE */ 561#endif /* CONFIG_PCMCIA_PROBE */
499 562
500 563
501/* 564/**
565 * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
566 * @s: PCMCIA socket to validate
567 *
568 * This is tricky... when we set up CIS memory, we try to validate
569 * the memory window space allocations.
570 *
502 * Locking note: Must be called with skt_mutex held! 571 * Locking note: Must be called with skt_mutex held!
503 */ 572 */
504static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) 573static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
505{ 574{
506 struct socket_data *s_data = s->resource_data; 575 struct socket_data *s_data = s->resource_data;
507 unsigned int probe_mask = MEM_PROBE_LOW; 576 unsigned int probe_mask = MEM_PROBE_LOW;
508 int ret = 0; 577 int ret;
509 578
510 if (!probe_mem) 579 if (!probe_mem || !(s->state & SOCKET_PRESENT))
511 return 0; 580 return 0;
512 581
513 mutex_lock(&rsrc_mutex);
514
515 if (s->features & SS_CAP_PAGE_REGS) 582 if (s->features & SS_CAP_PAGE_REGS)
516 probe_mask = MEM_PROBE_HIGH; 583 probe_mask = MEM_PROBE_HIGH;
517 584
518 if (probe_mask & ~s_data->rsrc_mem_probe) { 585 ret = validate_mem(s, probe_mask);
519 if (s->state & SOCKET_PRESENT)
520 ret = validate_mem(s, probe_mask);
521 if (!ret)
522 s_data->rsrc_mem_probe |= probe_mask;
523 }
524 586
525 mutex_unlock(&rsrc_mutex); 587 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
588 return 0;
526 589
527 return ret; 590 return ret;
528} 591}
@@ -602,7 +665,6 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
602 struct socket_data *s_data = s->resource_data; 665 struct socket_data *s_data = s->resource_data;
603 int ret = -ENOMEM; 666 int ret = -ENOMEM;
604 667
605 mutex_lock(&rsrc_mutex);
606 for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) { 668 for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
607 unsigned long start = m->base; 669 unsigned long start = m->base;
608 unsigned long end = m->base + m->num - 1; 670 unsigned long end = m->base + m->num - 1;
@@ -613,7 +675,6 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
613 ret = adjust_resource(res, r_start, r_end - r_start + 1); 675 ret = adjust_resource(res, r_start, r_end - r_start + 1);
614 break; 676 break;
615 } 677 }
616 mutex_unlock(&rsrc_mutex);
617 678
618 return ret; 679 return ret;
619} 680}
@@ -647,7 +708,6 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
647 data.offset = base & data.mask; 708 data.offset = base & data.mask;
648 data.map = &s_data->io_db; 709 data.map = &s_data->io_db;
649 710
650 mutex_lock(&rsrc_mutex);
651#ifdef CONFIG_PCI 711#ifdef CONFIG_PCI
652 if (s->cb_dev) { 712 if (s->cb_dev) {
653 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, 713 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
@@ -656,7 +716,6 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
656#endif 716#endif
657 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, 717 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
658 1, pcmcia_align, &data); 718 1, pcmcia_align, &data);
659 mutex_unlock(&rsrc_mutex);
660 719
661 if (ret != 0) { 720 if (ret != 0) {
662 kfree(res); 721 kfree(res);
@@ -672,15 +731,15 @@ static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
672 struct socket_data *s_data = s->resource_data; 731 struct socket_data *s_data = s->resource_data;
673 struct pcmcia_align_data data; 732 struct pcmcia_align_data data;
674 unsigned long min, max; 733 unsigned long min, max;
675 int ret, i; 734 int ret, i, j;
676 735
677 low = low || !(s->features & SS_CAP_PAGE_REGS); 736 low = low || !(s->features & SS_CAP_PAGE_REGS);
678 737
679 data.mask = align - 1; 738 data.mask = align - 1;
680 data.offset = base & data.mask; 739 data.offset = base & data.mask;
681 data.map = &s_data->mem_db;
682 740
683 for (i = 0; i < 2; i++) { 741 for (i = 0; i < 2; i++) {
742 data.map = &s_data->mem_db_valid;
684 if (low) { 743 if (low) {
685 max = 0x100000UL; 744 max = 0x100000UL;
686 min = base < max ? base : 0; 745 min = base < max ? base : 0;
@@ -689,17 +748,23 @@ static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
689 min = 0x100000UL + base; 748 min = 0x100000UL + base;
690 } 749 }
691 750
692 mutex_lock(&rsrc_mutex); 751 for (j = 0; j < 2; j++) {
693#ifdef CONFIG_PCI 752#ifdef CONFIG_PCI
694 if (s->cb_dev) { 753 if (s->cb_dev) {
695 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 754 ret = pci_bus_alloc_resource(s->cb_dev->bus,
696 1, min, 0, 755 res, num, 1, min, 0,
697 pcmcia_align, &data); 756 pcmcia_align, &data);
698 } else 757 } else
699#endif 758#endif
700 ret = allocate_resource(&iomem_resource, res, num, min, 759 {
701 max, 1, pcmcia_align, &data); 760 ret = allocate_resource(&iomem_resource,
702 mutex_unlock(&rsrc_mutex); 761 res, num, min, max, 1,
762 pcmcia_align, &data);
763 }
764 if (ret == 0)
765 break;
766 data.map = &s_data->mem_db;
767 }
703 if (ret == 0 || low) 768 if (ret == 0 || low)
704 break; 769 break;
705 low = 1; 770 low = 1;
@@ -722,25 +787,18 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
722 if (end < start) 787 if (end < start)
723 return -EINVAL; 788 return -EINVAL;
724 789
725 mutex_lock(&rsrc_mutex);
726 switch (action) { 790 switch (action) {
727 case ADD_MANAGED_RESOURCE: 791 case ADD_MANAGED_RESOURCE:
728 ret = add_interval(&data->mem_db, start, size); 792 ret = add_interval(&data->mem_db, start, size);
793 if (!ret)
794 do_mem_probe(s, start, size, NULL, NULL);
729 break; 795 break;
730 case REMOVE_MANAGED_RESOURCE: 796 case REMOVE_MANAGED_RESOURCE:
731 ret = sub_interval(&data->mem_db, start, size); 797 ret = sub_interval(&data->mem_db, start, size);
732 if (!ret) {
733 struct pcmcia_socket *socket;
734 down_read(&pcmcia_socket_list_rwsem);
735 list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
736 release_cis_mem(socket);
737 up_read(&pcmcia_socket_list_rwsem);
738 }
739 break; 798 break;
740 default: 799 default:
741 ret = -EINVAL; 800 ret = -EINVAL;
742 } 801 }
743 mutex_unlock(&rsrc_mutex);
744 802
745 return ret; 803 return ret;
746} 804}
@@ -758,7 +816,6 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
758 if (end > IO_SPACE_LIMIT) 816 if (end > IO_SPACE_LIMIT)
759 return -EINVAL; 817 return -EINVAL;
760 818
761 mutex_lock(&rsrc_mutex);
762 switch (action) { 819 switch (action) {
763 case ADD_MANAGED_RESOURCE: 820 case ADD_MANAGED_RESOURCE:
764 if (add_interval(&data->io_db, start, size) != 0) { 821 if (add_interval(&data->io_db, start, size) != 0) {
@@ -777,7 +834,6 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
777 ret = -EINVAL; 834 ret = -EINVAL;
778 break; 835 break;
779 } 836 }
780 mutex_unlock(&rsrc_mutex);
781 837
782 return ret; 838 return ret;
783} 839}
@@ -860,6 +916,7 @@ static int nonstatic_init(struct pcmcia_socket *s)
860 return -ENOMEM; 916 return -ENOMEM;
861 917
862 data->mem_db.next = &data->mem_db; 918 data->mem_db.next = &data->mem_db;
919 data->mem_db_valid.next = &data->mem_db_valid;
863 data->io_db.next = &data->io_db; 920 data->io_db.next = &data->io_db;
864 921
865 s->resource_data = (void *) data; 922 s->resource_data = (void *) data;
@@ -874,7 +931,10 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
874 struct socket_data *data = s->resource_data; 931 struct socket_data *data = s->resource_data;
875 struct resource_map *p, *q; 932 struct resource_map *p, *q;
876 933
877 mutex_lock(&rsrc_mutex); 934 for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
935 q = p->next;
936 kfree(p);
937 }
878 for (p = data->mem_db.next; p != &data->mem_db; p = q) { 938 for (p = data->mem_db.next; p != &data->mem_db; p = q) {
879 q = p->next; 939 q = p->next;
880 kfree(p); 940 kfree(p);
@@ -883,7 +943,6 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
883 q = p->next; 943 q = p->next;
884 kfree(p); 944 kfree(p);
885 } 945 }
886 mutex_unlock(&rsrc_mutex);
887} 946}
888 947
889 948
@@ -910,7 +969,7 @@ static ssize_t show_io_db(struct device *dev,
910 struct resource_map *p; 969 struct resource_map *p;
911 ssize_t ret = 0; 970 ssize_t ret = 0;
912 971
913 mutex_lock(&rsrc_mutex); 972 mutex_lock(&s->ops_mutex);
914 data = s->resource_data; 973 data = s->resource_data;
915 974
916 for (p = data->io_db.next; p != &data->io_db; p = p->next) { 975 for (p = data->io_db.next; p != &data->io_db; p = p->next) {
@@ -922,7 +981,7 @@ static ssize_t show_io_db(struct device *dev,
922 ((unsigned long) p->base + p->num - 1)); 981 ((unsigned long) p->base + p->num - 1));
923 } 982 }
924 983
925 mutex_unlock(&rsrc_mutex); 984 mutex_unlock(&s->ops_mutex);
926 return ret; 985 return ret;
927} 986}
928 987
@@ -950,9 +1009,11 @@ static ssize_t store_io_db(struct device *dev,
950 if (end_addr < start_addr) 1009 if (end_addr < start_addr)
951 return -EINVAL; 1010 return -EINVAL;
952 1011
1012 mutex_lock(&s->ops_mutex);
953 ret = adjust_io(s, add, start_addr, end_addr); 1013 ret = adjust_io(s, add, start_addr, end_addr);
954 if (!ret) 1014 if (!ret)
955 s->resource_setup_new = 1; 1015 s->resource_setup_new = 1;
1016 mutex_unlock(&s->ops_mutex);
956 1017
957 return ret ? ret : count; 1018 return ret ? ret : count;
958} 1019}
@@ -966,9 +1027,19 @@ static ssize_t show_mem_db(struct device *dev,
966 struct resource_map *p; 1027 struct resource_map *p;
967 ssize_t ret = 0; 1028 ssize_t ret = 0;
968 1029
969 mutex_lock(&rsrc_mutex); 1030 mutex_lock(&s->ops_mutex);
970 data = s->resource_data; 1031 data = s->resource_data;
971 1032
1033 for (p = data->mem_db_valid.next; p != &data->mem_db_valid;
1034 p = p->next) {
1035 if (ret > (PAGE_SIZE - 10))
1036 continue;
1037 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1038 "0x%08lx - 0x%08lx\n",
1039 ((unsigned long) p->base),
1040 ((unsigned long) p->base + p->num - 1));
1041 }
1042
972 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) { 1043 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
973 if (ret > (PAGE_SIZE - 10)) 1044 if (ret > (PAGE_SIZE - 10))
974 continue; 1045 continue;
@@ -978,7 +1049,7 @@ static ssize_t show_mem_db(struct device *dev,
978 ((unsigned long) p->base + p->num - 1)); 1049 ((unsigned long) p->base + p->num - 1));
979 } 1050 }
980 1051
981 mutex_unlock(&rsrc_mutex); 1052 mutex_unlock(&s->ops_mutex);
982 return ret; 1053 return ret;
983} 1054}
984 1055
@@ -1006,9 +1077,11 @@ static ssize_t store_mem_db(struct device *dev,
1006 if (end_addr < start_addr) 1077 if (end_addr < start_addr)
1007 return -EINVAL; 1078 return -EINVAL;
1008 1079
1080 mutex_lock(&s->ops_mutex);
1009 ret = adjust_memory(s, add, start_addr, end_addr); 1081 ret = adjust_memory(s, add, start_addr, end_addr);
1010 if (!ret) 1082 if (!ret)
1011 s->resource_setup_new = 1; 1083 s->resource_setup_new = 1;
1084 mutex_unlock(&s->ops_mutex);
1012 1085
1013 return ret ? ret : count; 1086 return ret ? ret : count;
1014} 1087}