1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/interrupt.h>
19#include <linux/kernel.h>
20#include <linux/errno.h>
21#include <linux/types.h>
22#include <linux/slab.h>
23#include <linux/ioport.h>
24#include <linux/timer.h>
25#include <linux/pci.h>
26#include <linux/device.h>
27#include <linux/io.h>
28
29#include <asm/irq.h>
30
31#include <pcmcia/ss.h>
32#include <pcmcia/cistpl.h>
33#include "cs_internal.h"
34
35
36
37
38
39
40
41
42#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
43
44INT_MODULE_PARM(probe_mem, 1);
45#ifdef CONFIG_PCMCIA_PROBE
46INT_MODULE_PARM(probe_io, 1);
47INT_MODULE_PARM(mem_limit, 0x10000);
48#endif
49
50
51struct resource_map {
52 u_long base, num;
53 struct resource_map *next;
54};
55
56struct socket_data {
57 struct resource_map mem_db;
58 struct resource_map mem_db_valid;
59 struct resource_map io_db;
60};
61
62#define MEM_PROBE_LOW (1 << 0)
63#define MEM_PROBE_HIGH (1 << 1)
64
65
66#define REMOVE_MANAGED_RESOURCE 1
67#define ADD_MANAGED_RESOURCE 2
68
69
70
71
72
73
74
75static struct resource *
76claim_region(struct pcmcia_socket *s, resource_size_t base,
77 resource_size_t size, int type, char *name)
78{
79 struct resource *res, *parent;
80
81 parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
82 res = pcmcia_make_resource(base, size, type | IORESOURCE_BUSY, name);
83
84 if (res) {
85#ifdef CONFIG_PCI
86 if (s && s->cb_dev)
87 parent = pci_find_parent_resource(s->cb_dev, res);
88#endif
89 if (!parent || request_resource(parent, res)) {
90 kfree(res);
91 res = NULL;
92 }
93 }
94 return res;
95}
96
97static void free_region(struct resource *res)
98{
99 if (res) {
100 release_resource(res);
101 kfree(res);
102 }
103}
104
105
106
107
108
109
110
111static int add_interval(struct resource_map *map, u_long base, u_long num)
112{
113 struct resource_map *p, *q;
114
115 for (p = map; ; p = p->next) {
116 if ((p != map) && (p->base+p->num >= base)) {
117 p->num = max(num + base - p->base, p->num);
118 return 0;
119 }
120 if ((p->next == map) || (p->next->base > base+num-1))
121 break;
122 }
123 q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
124 if (!q) {
125 printk(KERN_WARNING "out of memory to update resources\n");
126 return -ENOMEM;
127 }
128 q->base = base; q->num = num;
129 q->next = p->next; p->next = q;
130 return 0;
131}
132
133
134
135static int sub_interval(struct resource_map *map, u_long base, u_long num)
136{
137 struct resource_map *p, *q;
138
139 for (p = map; ; p = q) {
140 q = p->next;
141 if (q == map)
142 break;
143 if ((q->base+q->num > base) && (base+num > q->base)) {
144 if (q->base >= base) {
145 if (q->base+q->num <= base+num) {
146
147 p->next = q->next;
148 kfree(q);
149
150 q = p;
151 } else {
152
153 q->num = q->base + q->num - base - num;
154 q->base = base + num;
155 }
156 } else if (q->base+q->num <= base+num) {
157
158 q->num = base - q->base;
159 } else {
160
161 p = kmalloc(sizeof(struct resource_map),
162 GFP_KERNEL);
163 if (!p) {
164 printk(KERN_WARNING "out of memory to update resources\n");
165 return -ENOMEM;
166 }
167 p->base = base+num;
168 p->num = q->base+q->num - p->base;
169 q->num = base - q->base;
170 p->next = q->next ; q->next = p;
171 }
172 }
173 }
174 return 0;
175}
176
177
178
179
180
181
182
183
184#ifdef CONFIG_PCMCIA_PROBE
185static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
186 unsigned int num)
187{
188 struct resource *res;
189 struct socket_data *s_data = s->resource_data;
190 unsigned int i, j, bad;
191 int any;
192 u_char *b, hole, most;
193
194 dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
195 base, base+num-1);
196
197
198 b = kzalloc(256, GFP_KERNEL);
199 if (!b) {
200 printk("\n");
201 dev_printk(KERN_ERR, &s->dev,
202 "do_io_probe: unable to kmalloc 256 bytes");
203 return;
204 }
205 for (i = base, most = 0; i < base+num; i += 8) {
206 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
207 if (!res)
208 continue;
209 hole = inb(i);
210 for (j = 1; j < 8; j++)
211 if (inb(i+j) != hole)
212 break;
213 free_region(res);
214 if ((j == 8) && (++b[hole] > b[most]))
215 most = hole;
216 if (b[most] == 127)
217 break;
218 }
219 kfree(b);
220
221 bad = any = 0;
222 for (i = base; i < base+num; i += 8) {
223 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
224 if (!res) {
225 if (!any)
226 printk(" excluding");
227 if (!bad)
228 bad = any = i;
229 continue;
230 }
231 for (j = 0; j < 8; j++)
232 if (inb(i+j) != most)
233 break;
234 free_region(res);
235 if (j < 8) {
236 if (!any)
237 printk(" excluding");
238 if (!bad)
239 bad = any = i;
240 } else {
241 if (bad) {
242 sub_interval(&s_data->io_db, bad, i-bad);
243 printk(" %#x-%#x", bad, i-1);
244 bad = 0;
245 }
246 }
247 }
248 if (bad) {
249 if ((num > 16) && (bad == base) && (i == base+num)) {
250 sub_interval(&s_data->io_db, bad, i-bad);
251 printk(" nothing: probe failed.\n");
252 return;
253 } else {
254 sub_interval(&s_data->io_db, bad, i-bad);
255 printk(" %#x-%#x", bad, i-1);
256 }
257 }
258
259 printk(any ? "\n" : " clean.\n");
260}
261#endif
262
263
264
265
266
267
268static int readable(struct pcmcia_socket *s, struct resource *res,
269 unsigned int *count)
270{
271 int ret = -EINVAL;
272
273 if (s->fake_cis) {
274 dev_dbg(&s->dev, "fake CIS is being used: can't validate mem\n");
275 return 0;
276 }
277
278 s->cis_mem.res = res;
279 s->cis_virt = ioremap(res->start, s->map_size);
280 if (s->cis_virt) {
281 mutex_unlock(&s->ops_mutex);
282
283 if (s->callback->validate)
284 ret = s->callback->validate(s, count);
285
286 mutex_lock(&s->ops_mutex);
287 iounmap(s->cis_virt);
288 s->cis_virt = NULL;
289 }
290 s->cis_mem.res = NULL;
291 if ((ret) || (*count == 0))
292 return -EINVAL;
293 return 0;
294}
295
296
297
298
299static int checksum(struct pcmcia_socket *s, struct resource *res,
300 unsigned int *value)
301{
302 pccard_mem_map map;
303 int i, a = 0, b = -1, d;
304 void __iomem *virt;
305
306 virt = ioremap(res->start, s->map_size);
307 if (virt) {
308 map.map = 0;
309 map.flags = MAP_ACTIVE;
310 map.speed = 0;
311 map.res = res;
312 map.card_start = 0;
313 s->ops->set_mem_map(s, &map);
314
315
316 for (i = 0; i < s->map_size; i += 44) {
317 d = readl(virt+i);
318 a += d;
319 b &= d;
320 }
321
322 map.flags = 0;
323 s->ops->set_mem_map(s, &map);
324
325 iounmap(virt);
326 }
327
328 if (b == -1)
329 return -EINVAL;
330
331 *value = a;
332
333 return 0;
334}
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349static int do_validate_mem(struct pcmcia_socket *s,
350 unsigned long base, unsigned long size,
351 int validate (struct pcmcia_socket *s,
352 struct resource *res,
353 unsigned int *value))
354{
355 struct socket_data *s_data = s->resource_data;
356 struct resource *res1, *res2;
357 unsigned int info1 = 1, info2 = 1;
358 int ret = -EINVAL;
359
360 res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
361 res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
362 "PCMCIA memprobe");
363
364 if (res1 && res2) {
365 ret = 0;
366 if (validate) {
367 ret = validate(s, res1, &info1);
368 ret += validate(s, res2, &info2);
369 }
370 }
371
372 dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
373 base, base+size-1, res1, res2, ret, info1, info2);
374
375 free_region(res2);
376 free_region(res1);
377
378 if ((ret) || (info1 != info2) || (info1 == 0))
379 return -EINVAL;
380
381 if (validate && !s->fake_cis) {
382
383 add_interval(&s_data->mem_db_valid, base, size);
384 sub_interval(&s_data->mem_db, base, size);
385 }
386
387 return 0;
388}
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
406 int validate (struct pcmcia_socket *s,
407 struct resource *res,
408 unsigned int *value),
409 int fallback (struct pcmcia_socket *s,
410 struct resource *res,
411 unsigned int *value))
412{
413 struct socket_data *s_data = s->resource_data;
414 u_long i, j, bad, fail, step;
415
416 dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
417 base, base+num-1);
418 bad = fail = 0;
419 step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
420
421 if (step > 0x800000)
422 step = 0x800000;
423
424 if (step < 2 * s->map_size)
425 step = 2 * s->map_size;
426 for (i = j = base; i < base+num; i = j + step) {
427 if (!fail) {
428 for (j = i; j < base+num; j += step) {
429 if (!do_validate_mem(s, j, step, validate))
430 break;
431 }
432 fail = ((i == base) && (j == base+num));
433 }
434 if ((fail) && (fallback)) {
435 for (j = i; j < base+num; j += step)
436 if (!do_validate_mem(s, j, step, fallback))
437 break;
438 }
439 if (i != j) {
440 if (!bad)
441 printk(" excluding");
442 printk(" %#05lx-%#05lx", i, j-1);
443 sub_interval(&s_data->mem_db, i, j-i);
444 bad += j-i;
445 }
446 }
447 printk(bad ? "\n" : " clean.\n");
448 return num - bad;
449}
450
451
452#ifdef CONFIG_PCMCIA_PROBE
453
454
455
456
457
458
459static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
460{
461 struct socket_data *s_data = s->resource_data;
462 u_long ok;
463 if (m == &s_data->mem_db)
464 return 0;
465 ok = inv_probe(m->next, s);
466 if (ok) {
467 if (m->base >= 0x100000)
468 sub_interval(&s_data->mem_db, m->base, m->num);
469 return ok;
470 }
471 if (m->base < 0x100000)
472 return 0;
473 return do_mem_probe(s, m->base, m->num, readable, checksum);
474}
475
476
477
478
479
480
481
482
483
484
485static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
486{
487 struct resource_map *m, mm;
488 static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
489 unsigned long b, i, ok = 0;
490 struct socket_data *s_data = s->resource_data;
491
492
493 if (probe_mask & MEM_PROBE_HIGH) {
494 if (inv_probe(s_data->mem_db.next, s) > 0)
495 return 0;
496 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
497 return 0;
498 dev_printk(KERN_NOTICE, &s->dev,
499 "cs: warning: no high memory space available!\n");
500 return -ENODEV;
501 }
502
503 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
504 mm = *m;
505
506 if (mm.base >= 0x100000)
507 continue;
508 if ((mm.base | mm.num) & 0xffff) {
509 ok += do_mem_probe(s, mm.base, mm.num, readable,
510 checksum);
511 continue;
512 }
513
514 for (i = 0; i < 4; i++) {
515 b = order[i] << 12;
516 if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
517 if (ok >= mem_limit)
518 sub_interval(&s_data->mem_db, b, 0x10000);
519 else
520 ok += do_mem_probe(s, b, 0x10000,
521 readable, checksum);
522 }
523 }
524 }
525
526 if (ok > 0)
527 return 0;
528
529 return -ENODEV;
530}
531
532#else
533
534
535
536
537
538
539
540
541static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
542{
543 struct resource_map *m, mm;
544 struct socket_data *s_data = s->resource_data;
545 unsigned long ok = 0;
546
547 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
548 mm = *m;
549 ok += do_mem_probe(s, mm.base, mm.num, readable, checksum);
550 }
551 if (ok > 0)
552 return 0;
553 return -ENODEV;
554}
555
556#endif
557
558
559
560
561
562
563
564
565
566
567
568static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
569{
570 struct socket_data *s_data = s->resource_data;
571 unsigned int probe_mask = MEM_PROBE_LOW;
572 int ret;
573
574 if (!probe_mem || !(s->state & SOCKET_PRESENT))
575 return 0;
576
577 if (s->features & SS_CAP_PAGE_REGS)
578 probe_mask = MEM_PROBE_HIGH;
579
580 ret = validate_mem(s, probe_mask);
581
582 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
583 return 0;
584
585 return ret;
586}
587
588struct pcmcia_align_data {
589 unsigned long mask;
590 unsigned long offset;
591 struct resource_map *map;
592};
593
594static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data,
595 resource_size_t start)
596{
597 resource_size_t ret;
598
599
600
601 ret = (start & ~align_data->mask) + align_data->offset;
602 if (ret < start)
603 ret += align_data->mask + 1;
604 return ret;
605}
606
607static resource_size_t
608pcmcia_align(void *align_data, const struct resource *res,
609 resource_size_t size, resource_size_t align)
610{
611 struct pcmcia_align_data *data = align_data;
612 struct resource_map *m;
613 resource_size_t start;
614
615 start = pcmcia_common_align(data, res->start);
616
617 for (m = data->map->next; m != data->map; m = m->next) {
618 unsigned long map_start = m->base;
619 unsigned long map_end = m->base + m->num - 1;
620
621
622
623
624
625
626 if (start < map_start)
627 start = pcmcia_common_align(data, map_start);
628
629
630
631
632
633 if (start >= res->end)
634 break;
635
636 if ((start + size - 1) <= map_end)
637 break;
638 }
639
640
641
642
643 if (m == data->map)
644 start = res->end;
645
646 return start;
647}
648
649
650
651
652
653static int __nonstatic_adjust_io_region(struct pcmcia_socket *s,
654 unsigned long r_start,
655 unsigned long r_end)
656{
657 struct resource_map *m;
658 struct socket_data *s_data = s->resource_data;
659 int ret = -ENOMEM;
660
661 for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
662 unsigned long start = m->base;
663 unsigned long end = m->base + m->num - 1;
664
665 if (start > r_start || r_end > end)
666 continue;
667
668 ret = 0;
669 }
670
671 return ret;
672}
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s,
688 unsigned long base, int num,
689 unsigned long align)
690{
691 struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO,
692 dev_name(&s->dev));
693 struct socket_data *s_data = s->resource_data;
694 struct pcmcia_align_data data;
695 unsigned long min = base;
696 int ret;
697
698 data.mask = align - 1;
699 data.offset = base & data.mask;
700 data.map = &s_data->io_db;
701
702#ifdef CONFIG_PCI
703 if (s->cb_dev) {
704 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
705 min, 0, pcmcia_align, &data);
706 } else
707#endif
708 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
709 1, pcmcia_align, &data);
710
711 if (ret != 0) {
712 kfree(res);
713 res = NULL;
714 }
715 return res;
716}
717
718static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
719 unsigned int *base, unsigned int num,
720 unsigned int align, struct resource **parent)
721{
722 int i, ret = 0;
723
724
725
726
727
728 for (i = 0; i < MAX_IO_WIN; i++) {
729 if (!s->io[i].res)
730 continue;
731
732 if (!*base)
733 continue;
734
735 if ((s->io[i].res->start & (align-1)) == *base)
736 return -EBUSY;
737 }
738
739 for (i = 0; i < MAX_IO_WIN; i++) {
740 struct resource *res = s->io[i].res;
741 unsigned int try;
742
743 if (res && (res->flags & IORESOURCE_BITS) !=
744 (attr & IORESOURCE_BITS))
745 continue;
746
747 if (!res) {
748 if (align == 0)
749 align = 0x10000;
750
751 res = s->io[i].res = __nonstatic_find_io_region(s,
752 *base, num,
753 align);
754 if (!res)
755 return -EINVAL;
756
757 *base = res->start;
758 s->io[i].res->flags =
759 ((res->flags & ~IORESOURCE_BITS) |
760 (attr & IORESOURCE_BITS));
761 s->io[i].InUse = num;
762 *parent = res;
763 return 0;
764 }
765
766
767 try = res->end + 1;
768 if ((*base == 0) || (*base == try)) {
769 ret = __nonstatic_adjust_io_region(s, res->start,
770 res->end + num);
771 if (!ret) {
772 ret = adjust_resource(s->io[i].res, res->start,
773 resource_size(res) + num);
774 if (ret)
775 continue;
776 *base = try;
777 s->io[i].InUse += num;
778 *parent = res;
779 return 0;
780 }
781 }
782
783
784 try = res->start - num;
785 if ((*base == 0) || (*base == try)) {
786 ret = __nonstatic_adjust_io_region(s,
787 res->start - num,
788 res->end);
789 if (!ret) {
790 ret = adjust_resource(s->io[i].res,
791 res->start - num,
792 resource_size(res) + num);
793 if (ret)
794 continue;
795 *base = try;
796 s->io[i].InUse += num;
797 *parent = res;
798 return 0;
799 }
800 }
801 }
802
803 return -EINVAL;
804}
805
806
807static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
808 u_long align, int low, struct pcmcia_socket *s)
809{
810 struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM,
811 dev_name(&s->dev));
812 struct socket_data *s_data = s->resource_data;
813 struct pcmcia_align_data data;
814 unsigned long min, max;
815 int ret, i, j;
816
817 low = low || !(s->features & SS_CAP_PAGE_REGS);
818
819 data.mask = align - 1;
820 data.offset = base & data.mask;
821
822 for (i = 0; i < 2; i++) {
823 data.map = &s_data->mem_db_valid;
824 if (low) {
825 max = 0x100000UL;
826 min = base < max ? base : 0;
827 } else {
828 max = ~0UL;
829 min = 0x100000UL + base;
830 }
831
832 for (j = 0; j < 2; j++) {
833#ifdef CONFIG_PCI
834 if (s->cb_dev) {
835 ret = pci_bus_alloc_resource(s->cb_dev->bus,
836 res, num, 1, min, 0,
837 pcmcia_align, &data);
838 } else
839#endif
840 {
841 ret = allocate_resource(&iomem_resource,
842 res, num, min, max, 1,
843 pcmcia_align, &data);
844 }
845 if (ret == 0)
846 break;
847 data.map = &s_data->mem_db;
848 }
849 if (ret == 0 || low)
850 break;
851 low = 1;
852 }
853
854 if (ret != 0) {
855 kfree(res);
856 res = NULL;
857 }
858 return res;
859}
860
861
862static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
863{
864 struct socket_data *data = s->resource_data;
865 unsigned long size = end - start + 1;
866 int ret = 0;
867
868 if (end < start)
869 return -EINVAL;
870
871 switch (action) {
872 case ADD_MANAGED_RESOURCE:
873 ret = add_interval(&data->mem_db, start, size);
874 if (!ret)
875 do_mem_probe(s, start, size, NULL, NULL);
876 break;
877 case REMOVE_MANAGED_RESOURCE:
878 ret = sub_interval(&data->mem_db, start, size);
879 break;
880 default:
881 ret = -EINVAL;
882 }
883
884 return ret;
885}
886
887
888static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
889{
890 struct socket_data *data = s->resource_data;
891 unsigned long size;
892 int ret = 0;
893
894#if defined(CONFIG_X86)
895
896
897 if (start < 0x100)
898 start = 0x100;
899#endif
900
901 size = end - start + 1;
902
903 if (end < start)
904 return -EINVAL;
905
906 if (end > IO_SPACE_LIMIT)
907 return -EINVAL;
908
909 switch (action) {
910 case ADD_MANAGED_RESOURCE:
911 if (add_interval(&data->io_db, start, size) != 0) {
912 ret = -EBUSY;
913 break;
914 }
915#ifdef CONFIG_PCMCIA_PROBE
916 if (probe_io)
917 do_io_probe(s, start, size);
918#endif
919 break;
920 case REMOVE_MANAGED_RESOURCE:
921 sub_interval(&data->io_db, start, size);
922 break;
923 default:
924 ret = -EINVAL;
925 break;
926 }
927
928 return ret;
929}
930
931
932#ifdef CONFIG_PCI
933static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
934{
935 struct resource *res;
936 int i, done = 0;
937
938 if (!s->cb_dev || !s->cb_dev->bus)
939 return -ENODEV;
940
941#if defined(CONFIG_X86)
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960 if (s->cb_dev->bus->number == 0)
961 return -EINVAL;
962
963 for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
964 res = s->cb_dev->bus->resource[i];
965#else
966 pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
967#endif
968 if (!res)
969 continue;
970
971 if (res->flags & IORESOURCE_IO) {
972
973
974
975 if (res == &ioport_resource)
976 continue;
977
978 dev_printk(KERN_INFO, &s->cb_dev->dev,
979 "pcmcia: parent PCI bridge window: %pR\n",
980 res);
981 if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
982 done |= IORESOURCE_IO;
983
984 }
985
986 if (res->flags & IORESOURCE_MEM) {
987
988
989
990 if (res == &iomem_resource)
991 continue;
992
993 dev_printk(KERN_INFO, &s->cb_dev->dev,
994 "pcmcia: parent PCI bridge window: %pR\n",
995 res);
996 if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
997 done |= IORESOURCE_MEM;
998 }
999 }
1000
1001
1002
1003 if (done == (IORESOURCE_MEM | IORESOURCE_IO))
1004 s->resource_setup_done = 1;
1005
1006 return 0;
1007}
1008
1009#else
1010
1011static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
1012{
1013 return -ENODEV;
1014}
1015
1016#endif
1017
1018
1019static int nonstatic_init(struct pcmcia_socket *s)
1020{
1021 struct socket_data *data;
1022
1023 data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
1024 if (!data)
1025 return -ENOMEM;
1026
1027 data->mem_db.next = &data->mem_db;
1028 data->mem_db_valid.next = &data->mem_db_valid;
1029 data->io_db.next = &data->io_db;
1030
1031 s->resource_data = (void *) data;
1032
1033 nonstatic_autoadd_resources(s);
1034
1035 return 0;
1036}
1037
1038static void nonstatic_release_resource_db(struct pcmcia_socket *s)
1039{
1040 struct socket_data *data = s->resource_data;
1041 struct resource_map *p, *q;
1042
1043 for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
1044 q = p->next;
1045 kfree(p);
1046 }
1047 for (p = data->mem_db.next; p != &data->mem_db; p = q) {
1048 q = p->next;
1049 kfree(p);
1050 }
1051 for (p = data->io_db.next; p != &data->io_db; p = q) {
1052 q = p->next;
1053 kfree(p);
1054 }
1055}
1056
1057
1058struct pccard_resource_ops pccard_nonstatic_ops = {
1059 .validate_mem = pcmcia_nonstatic_validate_mem,
1060 .find_io = nonstatic_find_io,
1061 .find_mem = nonstatic_find_mem_region,
1062 .init = nonstatic_init,
1063 .exit = nonstatic_release_resource_db,
1064};
1065EXPORT_SYMBOL(pccard_nonstatic_ops);
1066
1067
1068
1069
1070static ssize_t show_io_db(struct device *dev,
1071 struct device_attribute *attr, char *buf)
1072{
1073 struct pcmcia_socket *s = dev_get_drvdata(dev);
1074 struct socket_data *data;
1075 struct resource_map *p;
1076 ssize_t ret = 0;
1077
1078 mutex_lock(&s->ops_mutex);
1079 data = s->resource_data;
1080
1081 for (p = data->io_db.next; p != &data->io_db; p = p->next) {
1082 if (ret > (PAGE_SIZE - 10))
1083 continue;
1084 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1085 "0x%08lx - 0x%08lx\n",
1086 ((unsigned long) p->base),
1087 ((unsigned long) p->base + p->num - 1));
1088 }
1089
1090 mutex_unlock(&s->ops_mutex);
1091 return ret;
1092}
1093
1094static ssize_t store_io_db(struct device *dev,
1095 struct device_attribute *attr,
1096 const char *buf, size_t count)
1097{
1098 struct pcmcia_socket *s = dev_get_drvdata(dev);
1099 unsigned long start_addr, end_addr;
1100 unsigned int add = ADD_MANAGED_RESOURCE;
1101 ssize_t ret = 0;
1102
1103 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1104 if (ret != 2) {
1105 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1106 add = REMOVE_MANAGED_RESOURCE;
1107 if (ret != 2) {
1108 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1109 &end_addr);
1110 add = ADD_MANAGED_RESOURCE;
1111 if (ret != 2)
1112 return -EINVAL;
1113 }
1114 }
1115 if (end_addr < start_addr)
1116 return -EINVAL;
1117
1118 mutex_lock(&s->ops_mutex);
1119 ret = adjust_io(s, add, start_addr, end_addr);
1120 mutex_unlock(&s->ops_mutex);
1121
1122 return ret ? ret : count;
1123}
1124static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
1125
1126static ssize_t show_mem_db(struct device *dev,
1127 struct device_attribute *attr, char *buf)
1128{
1129 struct pcmcia_socket *s = dev_get_drvdata(dev);
1130 struct socket_data *data;
1131 struct resource_map *p;
1132 ssize_t ret = 0;
1133
1134 mutex_lock(&s->ops_mutex);
1135 data = s->resource_data;
1136
1137 for (p = data->mem_db_valid.next; p != &data->mem_db_valid;
1138 p = p->next) {
1139 if (ret > (PAGE_SIZE - 10))
1140 continue;
1141 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1142 "0x%08lx - 0x%08lx\n",
1143 ((unsigned long) p->base),
1144 ((unsigned long) p->base + p->num - 1));
1145 }
1146
1147 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
1148 if (ret > (PAGE_SIZE - 10))
1149 continue;
1150 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1151 "0x%08lx - 0x%08lx\n",
1152 ((unsigned long) p->base),
1153 ((unsigned long) p->base + p->num - 1));
1154 }
1155
1156 mutex_unlock(&s->ops_mutex);
1157 return ret;
1158}
1159
1160static ssize_t store_mem_db(struct device *dev,
1161 struct device_attribute *attr,
1162 const char *buf, size_t count)
1163{
1164 struct pcmcia_socket *s = dev_get_drvdata(dev);
1165 unsigned long start_addr, end_addr;
1166 unsigned int add = ADD_MANAGED_RESOURCE;
1167 ssize_t ret = 0;
1168
1169 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1170 if (ret != 2) {
1171 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1172 add = REMOVE_MANAGED_RESOURCE;
1173 if (ret != 2) {
1174 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1175 &end_addr);
1176 add = ADD_MANAGED_RESOURCE;
1177 if (ret != 2)
1178 return -EINVAL;
1179 }
1180 }
1181 if (end_addr < start_addr)
1182 return -EINVAL;
1183
1184 mutex_lock(&s->ops_mutex);
1185 ret = adjust_memory(s, add, start_addr, end_addr);
1186 mutex_unlock(&s->ops_mutex);
1187
1188 return ret ? ret : count;
1189}
1190static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1191
1192static struct attribute *pccard_rsrc_attributes[] = {
1193 &dev_attr_available_resources_io.attr,
1194 &dev_attr_available_resources_mem.attr,
1195 NULL,
1196};
1197
1198static const struct attribute_group rsrc_attributes = {
1199 .attrs = pccard_rsrc_attributes,
1200};
1201
1202static int pccard_sysfs_add_rsrc(struct device *dev,
1203 struct class_interface *class_intf)
1204{
1205 struct pcmcia_socket *s = dev_get_drvdata(dev);
1206
1207 if (s->resource_ops != &pccard_nonstatic_ops)
1208 return 0;
1209 return sysfs_create_group(&dev->kobj, &rsrc_attributes);
1210}
1211
1212static void pccard_sysfs_remove_rsrc(struct device *dev,
1213 struct class_interface *class_intf)
1214{
1215 struct pcmcia_socket *s = dev_get_drvdata(dev);
1216
1217 if (s->resource_ops != &pccard_nonstatic_ops)
1218 return;
1219 sysfs_remove_group(&dev->kobj, &rsrc_attributes);
1220}
1221
1222static struct class_interface pccard_rsrc_interface __refdata = {
1223 .class = &pcmcia_socket_class,
1224 .add_dev = &pccard_sysfs_add_rsrc,
1225 .remove_dev = &pccard_sysfs_remove_rsrc,
1226};
1227
1228static int __init nonstatic_sysfs_init(void)
1229{
1230 return class_interface_register(&pccard_rsrc_interface);
1231}
1232
1233static void __exit nonstatic_sysfs_exit(void)
1234{
1235 class_interface_unregister(&pccard_rsrc_interface);
1236}
1237
1238module_init(nonstatic_sysfs_init);
1239module_exit(nonstatic_sysfs_exit);
1240