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