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
28#include <asm/irq.h>
29#include <asm/io.h>
30
31#include <pcmcia/cs_types.h>
32#include <pcmcia/ss.h>
33#include <pcmcia/cs.h>
34#include <pcmcia/cistpl.h>
35#include "cs_internal.h"
36
37MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
38MODULE_LICENSE("GPL");
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 io_db;
59 unsigned int rsrc_mem_probe;
60};
61
62static DEFINE_MUTEX(rsrc_mutex);
63#define MEM_PROBE_LOW (1 << 0)
64#define MEM_PROBE_HIGH (1 << 1)
65
66
67
68
69
70
71
72
73static struct resource *
74make_resource(resource_size_t b, resource_size_t n, int flags, const char *name)
75{
76 struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
77
78 if (res) {
79 res->name = name;
80 res->start = b;
81 res->end = b + n - 1;
82 res->flags = flags;
83 }
84 return res;
85}
86
87static struct resource *
88claim_region(struct pcmcia_socket *s, resource_size_t base,
89 resource_size_t size, int type, char *name)
90{
91 struct resource *res, *parent;
92
93 parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
94 res = make_resource(base, size, type | IORESOURCE_BUSY, name);
95
96 if (res) {
97#ifdef CONFIG_PCI
98 if (s && s->cb_dev)
99 parent = pci_find_parent_resource(s->cb_dev, res);
100#endif
101 if (!parent || request_resource(parent, res)) {
102 kfree(res);
103 res = NULL;
104 }
105 }
106 return res;
107}
108
109static void free_region(struct resource *res)
110{
111 if (res) {
112 release_resource(res);
113 kfree(res);
114 }
115}
116
117
118
119
120
121
122
123static int add_interval(struct resource_map *map, u_long base, u_long num)
124{
125 struct resource_map *p, *q;
126
127 for (p = map; ; p = p->next) {
128 if ((p != map) && (p->base+p->num-1 >= base))
129 return -1;
130 if ((p->next == map) || (p->next->base > base+num-1))
131 break;
132 }
133 q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
134 if (!q) {
135 printk(KERN_WARNING "out of memory to update resources\n");
136 return -ENOMEM;
137 }
138 q->base = base; q->num = num;
139 q->next = p->next; p->next = q;
140 return 0;
141}
142
143
144
145static int sub_interval(struct resource_map *map, u_long base, u_long num)
146{
147 struct resource_map *p, *q;
148
149 for (p = map; ; p = q) {
150 q = p->next;
151 if (q == map)
152 break;
153 if ((q->base+q->num > base) && (base+num > q->base)) {
154 if (q->base >= base) {
155 if (q->base+q->num <= base+num) {
156
157 p->next = q->next;
158 kfree(q);
159
160 q = p;
161 } else {
162
163 q->num = q->base + q->num - base - num;
164 q->base = base + num;
165 }
166 } else if (q->base+q->num <= base+num) {
167
168 q->num = base - q->base;
169 } else {
170
171 p = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
172 if (!p) {
173 printk(KERN_WARNING "out of memory to update resources\n");
174 return -ENOMEM;
175 }
176 p->base = base+num;
177 p->num = q->base+q->num - p->base;
178 q->num = base - q->base;
179 p->next = q->next ; q->next = p;
180 }
181 }
182 }
183 return 0;
184}
185
186
187
188
189
190
191
192
193#ifdef CONFIG_PCMCIA_PROBE
194static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
195 unsigned int num)
196{
197 struct resource *res;
198 struct socket_data *s_data = s->resource_data;
199 unsigned int i, j, bad;
200 int any;
201 u_char *b, hole, most;
202
203 dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
204 base, base+num-1);
205
206
207 b = kzalloc(256, GFP_KERNEL);
208 if (!b) {
209 printk("\n");
210 dev_printk(KERN_ERR, &s->dev,
211 "do_io_probe: unable to kmalloc 256 bytes");
212 return;
213 }
214 for (i = base, most = 0; i < base+num; i += 8) {
215 res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
216 if (!res)
217 continue;
218 hole = inb(i);
219 for (j = 1; j < 8; j++)
220 if (inb(i+j) != hole) break;
221 free_region(res);
222 if ((j == 8) && (++b[hole] > b[most]))
223 most = hole;
224 if (b[most] == 127) break;
225 }
226 kfree(b);
227
228 bad = any = 0;
229 for (i = base; i < base+num; i += 8) {
230 res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
231 if (!res)
232 continue;
233 for (j = 0; j < 8; j++)
234 if (inb(i+j) != most) break;
235 free_region(res);
236 if (j < 8) {
237 if (!any)
238 printk(" excluding");
239 if (!bad)
240 bad = any = i;
241 } else {
242 if (bad) {
243 sub_interval(&s_data->io_db, bad, i-bad);
244 printk(" %#x-%#x", bad, i-1);
245 bad = 0;
246 }
247 }
248 }
249 if (bad) {
250 if ((num > 16) && (bad == base) && (i == base+num)) {
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
268
269
270
271static int readable(struct pcmcia_socket *s, struct resource *res,
272 unsigned int *count)
273{
274 int ret = -1;
275
276 s->cis_mem.res = res;
277 s->cis_virt = ioremap(res->start, s->map_size);
278 if (s->cis_virt) {
279 ret = pccard_validate_cis(s, count);
280
281 iounmap(s->cis_virt);
282 s->cis_virt = NULL;
283 destroy_cis_cache(s);
284 }
285 s->cis_mem.res = NULL;
286 if ((ret != 0) || (*count == 0))
287 return 0;
288 return 1;
289}
290
291
292static int checksum(struct pcmcia_socket *s, struct resource *res)
293{
294 pccard_mem_map map;
295 int i, a = 0, b = -1, d;
296 void __iomem *virt;
297
298 virt = ioremap(res->start, s->map_size);
299 if (virt) {
300 map.map = 0;
301 map.flags = MAP_ACTIVE;
302 map.speed = 0;
303 map.res = res;
304 map.card_start = 0;
305 s->ops->set_mem_map(s, &map);
306
307
308 for (i = 0; i < s->map_size; i += 44) {
309 d = readl(virt+i);
310 a += d;
311 b &= d;
312 }
313
314 map.flags = 0;
315 s->ops->set_mem_map(s, &map);
316
317 iounmap(virt);
318 }
319
320 return (b == -1) ? -1 : (a>>1);
321}
322
323static int
324cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
325{
326 struct resource *res1, *res2;
327 unsigned int info1, info2;
328 int ret = 0;
329
330 res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
331 res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
332
333 if (res1 && res2) {
334 ret = readable(s, res1, &info1);
335 ret += readable(s, res2, &info2);
336 }
337
338 free_region(res2);
339 free_region(res1);
340
341 return (ret == 2) && (info1 == info2);
342}
343
344static int
345checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size)
346{
347 struct resource *res1, *res2;
348 int a = -1, b = -1;
349
350 res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
351 res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
352
353 if (res1 && res2) {
354 a = checksum(s, res1);
355 b = checksum(s, res2);
356 }
357
358 free_region(res2);
359 free_region(res1);
360
361 return (a == b) && (a >= 0);
362}
363
364
365
366
367
368
369
370
371
372static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
373{
374 struct socket_data *s_data = s->resource_data;
375 u_long i, j, bad, fail, step;
376
377 dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
378 base, base+num-1);
379 bad = fail = 0;
380 step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
381
382 if (step > 0x800000)
383 step = 0x800000;
384
385 if (step < 2 * s->map_size)
386 step = 2 * s->map_size;
387 for (i = j = base; i < base+num; i = j + step) {
388 if (!fail) {
389 for (j = i; j < base+num; j += step) {
390 if (cis_readable(s, j, step))
391 break;
392 }
393 fail = ((i == base) && (j == base+num));
394 }
395 if (fail) {
396 for (j = i; j < base+num; j += 2*step)
397 if (checksum_match(s, j, step) &&
398 checksum_match(s, j + step, step))
399 break;
400 }
401 if (i != j) {
402 if (!bad) printk(" excluding");
403 printk(" %#05lx-%#05lx", i, j-1);
404 sub_interval(&s_data->mem_db, i, j-i);
405 bad += j-i;
406 }
407 }
408 printk(bad ? "\n" : " clean.\n");
409 return (num - bad);
410}
411
412#ifdef CONFIG_PCMCIA_PROBE
413
414static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
415{
416 struct socket_data *s_data = s->resource_data;
417 u_long ok;
418 if (m == &s_data->mem_db)
419 return 0;
420 ok = inv_probe(m->next, s);
421 if (ok) {
422 if (m->base >= 0x100000)
423 sub_interval(&s_data->mem_db, m->base, m->num);
424 return ok;
425 }
426 if (m->base < 0x100000)
427 return 0;
428 return do_mem_probe(m->base, m->num, s);
429}
430
431static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
432{
433 struct resource_map *m, mm;
434 static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
435 unsigned long b, i, ok = 0;
436 struct socket_data *s_data = s->resource_data;
437
438
439 if (probe_mask & MEM_PROBE_HIGH) {
440 if (inv_probe(s_data->mem_db.next, s) > 0)
441 return 0;
442 dev_printk(KERN_NOTICE, &s->dev,
443 "cs: warning: no high memory space available!\n");
444 return -ENODEV;
445 }
446
447 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
448 mm = *m;
449
450 if (mm.base >= 0x100000)
451 continue;
452 if ((mm.base | mm.num) & 0xffff) {
453 ok += do_mem_probe(mm.base, mm.num, s);
454 continue;
455 }
456
457 for (i = 0; i < 4; i++) {
458 b = order[i] << 12;
459 if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
460 if (ok >= mem_limit)
461 sub_interval(&s_data->mem_db, b, 0x10000);
462 else
463 ok += do_mem_probe(b, 0x10000, s);
464 }
465 }
466 }
467
468 if (ok > 0)
469 return 0;
470
471 return -ENODEV;
472}
473
474#else
475
476static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
477{
478 struct resource_map *m, mm;
479 struct socket_data *s_data = s->resource_data;
480 unsigned long ok = 0;
481
482 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
483 mm = *m;
484 ok += do_mem_probe(mm.base, mm.num, s);
485 }
486 if (ok > 0)
487 return 0;
488 return -ENODEV;
489}
490
491#endif
492
493
494
495
496
497static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
498{
499 struct socket_data *s_data = s->resource_data;
500 unsigned int probe_mask = MEM_PROBE_LOW;
501 int ret = 0;
502
503 if (!probe_mem)
504 return 0;
505
506 mutex_lock(&rsrc_mutex);
507
508 if (s->features & SS_CAP_PAGE_REGS)
509 probe_mask = MEM_PROBE_HIGH;
510
511 if (probe_mask & ~s_data->rsrc_mem_probe) {
512 if (s->state & SOCKET_PRESENT)
513 ret = validate_mem(s, probe_mask);
514 if (!ret)
515 s_data->rsrc_mem_probe |= probe_mask;
516 }
517
518 mutex_unlock(&rsrc_mutex);
519
520 return ret;
521}
522
523struct pcmcia_align_data {
524 unsigned long mask;
525 unsigned long offset;
526 struct resource_map *map;
527};
528
529static void
530pcmcia_common_align(void *align_data, struct resource *res,
531 resource_size_t size, resource_size_t align)
532{
533 struct pcmcia_align_data *data = align_data;
534 resource_size_t start;
535
536
537
538 start = (res->start & ~data->mask) + data->offset;
539 if (start < res->start)
540 start += data->mask + 1;
541 res->start = start;
542}
543
544static void
545pcmcia_align(void *align_data, struct resource *res, resource_size_t size,
546 resource_size_t align)
547{
548 struct pcmcia_align_data *data = align_data;
549 struct resource_map *m;
550
551 pcmcia_common_align(data, res, size, align);
552
553 for (m = data->map->next; m != data->map; m = m->next) {
554 unsigned long start = m->base;
555 unsigned long end = m->base + m->num - 1;
556
557
558
559
560
561
562 if (res->start < start) {
563 res->start = start;
564 pcmcia_common_align(data, res, size, align);
565 }
566
567
568
569
570
571 if (res->start >= res->end)
572 break;
573
574 if ((res->start + size - 1) <= end)
575 break;
576 }
577
578
579
580
581 if (m == data->map)
582 res->start = res->end;
583}
584
585
586
587
588
589static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
590 unsigned long r_end, struct pcmcia_socket *s)
591{
592 struct resource_map *m;
593 struct socket_data *s_data = s->resource_data;
594 int ret = -ENOMEM;
595
596 mutex_lock(&rsrc_mutex);
597 for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
598 unsigned long start = m->base;
599 unsigned long end = m->base + m->num - 1;
600
601 if (start > r_start || r_end > end)
602 continue;
603
604 ret = adjust_resource(res, r_start, r_end - r_start + 1);
605 break;
606 }
607 mutex_unlock(&rsrc_mutex);
608
609 return ret;
610}
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625static struct resource *nonstatic_find_io_region(unsigned long base, int num,
626 unsigned long align, struct pcmcia_socket *s)
627{
628 struct resource *res = make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev));
629 struct socket_data *s_data = s->resource_data;
630 struct pcmcia_align_data data;
631 unsigned long min = base;
632 int ret;
633
634 if (align == 0)
635 align = 0x10000;
636
637 data.mask = align - 1;
638 data.offset = base & data.mask;
639 data.map = &s_data->io_db;
640
641 mutex_lock(&rsrc_mutex);
642#ifdef CONFIG_PCI
643 if (s->cb_dev) {
644 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
645 min, 0, pcmcia_align, &data);
646 } else
647#endif
648 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
649 1, pcmcia_align, &data);
650 mutex_unlock(&rsrc_mutex);
651
652 if (ret != 0) {
653 kfree(res);
654 res = NULL;
655 }
656 return res;
657}
658
659static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
660 u_long align, int low, struct pcmcia_socket *s)
661{
662 struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev));
663 struct socket_data *s_data = s->resource_data;
664 struct pcmcia_align_data data;
665 unsigned long min, max;
666 int ret, i;
667
668 low = low || !(s->features & SS_CAP_PAGE_REGS);
669
670 data.mask = align - 1;
671 data.offset = base & data.mask;
672 data.map = &s_data->mem_db;
673
674 for (i = 0; i < 2; i++) {
675 if (low) {
676 max = 0x100000UL;
677 min = base < max ? base : 0;
678 } else {
679 max = ~0UL;
680 min = 0x100000UL + base;
681 }
682
683 mutex_lock(&rsrc_mutex);
684#ifdef CONFIG_PCI
685 if (s->cb_dev) {
686 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
687 1, min, 0,
688 pcmcia_align, &data);
689 } else
690#endif
691 ret = allocate_resource(&iomem_resource, res, num, min,
692 max, 1, pcmcia_align, &data);
693 mutex_unlock(&rsrc_mutex);
694 if (ret == 0 || low)
695 break;
696 low = 1;
697 }
698
699 if (ret != 0) {
700 kfree(res);
701 res = NULL;
702 }
703 return res;
704}
705
706
707static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
708{
709 struct socket_data *data = s->resource_data;
710 unsigned long size = end - start + 1;
711 int ret = 0;
712
713 if (end < start)
714 return -EINVAL;
715
716 mutex_lock(&rsrc_mutex);
717 switch (action) {
718 case ADD_MANAGED_RESOURCE:
719 ret = add_interval(&data->mem_db, start, size);
720 break;
721 case REMOVE_MANAGED_RESOURCE:
722 ret = sub_interval(&data->mem_db, start, size);
723 if (!ret) {
724 struct pcmcia_socket *socket;
725 down_read(&pcmcia_socket_list_rwsem);
726 list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
727 release_cis_mem(socket);
728 up_read(&pcmcia_socket_list_rwsem);
729 }
730 break;
731 default:
732 ret = -EINVAL;
733 }
734 mutex_unlock(&rsrc_mutex);
735
736 return ret;
737}
738
739
740static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
741{
742 struct socket_data *data = s->resource_data;
743 unsigned long size = end - start + 1;
744 int ret = 0;
745
746 if (end < start)
747 return -EINVAL;
748
749 if (end > IO_SPACE_LIMIT)
750 return -EINVAL;
751
752 mutex_lock(&rsrc_mutex);
753 switch (action) {
754 case ADD_MANAGED_RESOURCE:
755 if (add_interval(&data->io_db, start, size) != 0) {
756 ret = -EBUSY;
757 break;
758 }
759#ifdef CONFIG_PCMCIA_PROBE
760 if (probe_io)
761 do_io_probe(s, start, size);
762#endif
763 break;
764 case REMOVE_MANAGED_RESOURCE:
765 sub_interval(&data->io_db, start, size);
766 break;
767 default:
768 ret = -EINVAL;
769 break;
770 }
771 mutex_unlock(&rsrc_mutex);
772
773 return ret;
774}
775
776
777#ifdef CONFIG_PCI
778static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
779{
780 struct resource *res;
781 int i, done = 0;
782
783 if (!s->cb_dev || !s->cb_dev->bus)
784 return -ENODEV;
785
786#if defined(CONFIG_X86)
787
788
789
790
791
792
793 if (s->cb_dev->bus->number == 0)
794 return -EINVAL;
795#endif
796
797 for (i=0; i < PCI_BUS_NUM_RESOURCES; i++) {
798 res = s->cb_dev->bus->resource[i];
799 if (!res)
800 continue;
801
802 if (res->flags & IORESOURCE_IO) {
803 if (res == &ioport_resource)
804 continue;
805 dev_printk(KERN_INFO, &s->cb_dev->dev,
806 "pcmcia: parent PCI bridge I/O "
807 "window: 0x%llx - 0x%llx\n",
808 (unsigned long long)res->start,
809 (unsigned long long)res->end);
810 if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
811 done |= IORESOURCE_IO;
812
813 }
814
815 if (res->flags & IORESOURCE_MEM) {
816 if (res == &iomem_resource)
817 continue;
818 dev_printk(KERN_INFO, &s->cb_dev->dev,
819 "pcmcia: parent PCI bridge Memory "
820 "window: 0x%llx - 0x%llx\n",
821 (unsigned long long)res->start,
822 (unsigned long long)res->end);
823 if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
824 done |= IORESOURCE_MEM;
825 }
826 }
827
828
829
830 if (done == (IORESOURCE_MEM | IORESOURCE_IO))
831 s->resource_setup_done = 1;
832
833 return 0;
834}
835
836#else
837
838static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
839{
840 return -ENODEV;
841}
842
843#endif
844
845
846static int nonstatic_init(struct pcmcia_socket *s)
847{
848 struct socket_data *data;
849
850 data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
851 if (!data)
852 return -ENOMEM;
853
854 data->mem_db.next = &data->mem_db;
855 data->io_db.next = &data->io_db;
856
857 s->resource_data = (void *) data;
858
859 nonstatic_autoadd_resources(s);
860
861 return 0;
862}
863
864static void nonstatic_release_resource_db(struct pcmcia_socket *s)
865{
866 struct socket_data *data = s->resource_data;
867 struct resource_map *p, *q;
868
869 mutex_lock(&rsrc_mutex);
870 for (p = data->mem_db.next; p != &data->mem_db; p = q) {
871 q = p->next;
872 kfree(p);
873 }
874 for (p = data->io_db.next; p != &data->io_db; p = q) {
875 q = p->next;
876 kfree(p);
877 }
878 mutex_unlock(&rsrc_mutex);
879}
880
881
882struct pccard_resource_ops pccard_nonstatic_ops = {
883 .validate_mem = pcmcia_nonstatic_validate_mem,
884 .adjust_io_region = nonstatic_adjust_io_region,
885 .find_io = nonstatic_find_io_region,
886 .find_mem = nonstatic_find_mem_region,
887 .add_io = adjust_io,
888 .add_mem = adjust_memory,
889 .init = nonstatic_init,
890 .exit = nonstatic_release_resource_db,
891};
892EXPORT_SYMBOL(pccard_nonstatic_ops);
893
894
895
896
897static ssize_t show_io_db(struct device *dev,
898 struct device_attribute *attr, char *buf)
899{
900 struct pcmcia_socket *s = dev_get_drvdata(dev);
901 struct socket_data *data;
902 struct resource_map *p;
903 ssize_t ret = 0;
904
905 mutex_lock(&rsrc_mutex);
906 data = s->resource_data;
907
908 for (p = data->io_db.next; p != &data->io_db; p = p->next) {
909 if (ret > (PAGE_SIZE - 10))
910 continue;
911 ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
912 "0x%08lx - 0x%08lx\n",
913 ((unsigned long) p->base),
914 ((unsigned long) p->base + p->num - 1));
915 }
916
917 mutex_unlock(&rsrc_mutex);
918 return (ret);
919}
920
921static ssize_t store_io_db(struct device *dev,
922 struct device_attribute *attr,
923 const char *buf, size_t count)
924{
925 struct pcmcia_socket *s = dev_get_drvdata(dev);
926 unsigned long start_addr, end_addr;
927 unsigned int add = ADD_MANAGED_RESOURCE;
928 ssize_t ret = 0;
929
930 ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
931 if (ret != 2) {
932 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
933 add = REMOVE_MANAGED_RESOURCE;
934 if (ret != 2) {
935 ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
936 add = ADD_MANAGED_RESOURCE;
937 if (ret != 2)
938 return -EINVAL;
939 }
940 }
941 if (end_addr < start_addr)
942 return -EINVAL;
943
944 ret = adjust_io(s, add, start_addr, end_addr);
945 if (!ret)
946 s->resource_setup_new = 1;
947
948 return ret ? ret : count;
949}
950static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
951
952static ssize_t show_mem_db(struct device *dev,
953 struct device_attribute *attr, char *buf)
954{
955 struct pcmcia_socket *s = dev_get_drvdata(dev);
956 struct socket_data *data;
957 struct resource_map *p;
958 ssize_t ret = 0;
959
960 mutex_lock(&rsrc_mutex);
961 data = s->resource_data;
962
963 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
964 if (ret > (PAGE_SIZE - 10))
965 continue;
966 ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
967 "0x%08lx - 0x%08lx\n",
968 ((unsigned long) p->base),
969 ((unsigned long) p->base + p->num - 1));
970 }
971
972 mutex_unlock(&rsrc_mutex);
973 return (ret);
974}
975
976static ssize_t store_mem_db(struct device *dev,
977 struct device_attribute *attr,
978 const char *buf, size_t count)
979{
980 struct pcmcia_socket *s = dev_get_drvdata(dev);
981 unsigned long start_addr, end_addr;
982 unsigned int add = ADD_MANAGED_RESOURCE;
983 ssize_t ret = 0;
984
985 ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
986 if (ret != 2) {
987 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
988 add = REMOVE_MANAGED_RESOURCE;
989 if (ret != 2) {
990 ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
991 add = ADD_MANAGED_RESOURCE;
992 if (ret != 2)
993 return -EINVAL;
994 }
995 }
996 if (end_addr < start_addr)
997 return -EINVAL;
998
999 ret = adjust_memory(s, add, start_addr, end_addr);
1000 if (!ret)
1001 s->resource_setup_new = 1;
1002
1003 return ret ? ret : count;
1004}
1005static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1006
1007static struct attribute *pccard_rsrc_attributes[] = {
1008 &dev_attr_available_resources_io.attr,
1009 &dev_attr_available_resources_mem.attr,
1010 NULL,
1011};
1012
1013static const struct attribute_group rsrc_attributes = {
1014 .attrs = pccard_rsrc_attributes,
1015};
1016
1017static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
1018 struct class_interface *class_intf)
1019{
1020 struct pcmcia_socket *s = dev_get_drvdata(dev);
1021
1022 if (s->resource_ops != &pccard_nonstatic_ops)
1023 return 0;
1024 return sysfs_create_group(&dev->kobj, &rsrc_attributes);
1025}
1026
1027static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
1028 struct class_interface *class_intf)
1029{
1030 struct pcmcia_socket *s = dev_get_drvdata(dev);
1031
1032 if (s->resource_ops != &pccard_nonstatic_ops)
1033 return;
1034 sysfs_remove_group(&dev->kobj, &rsrc_attributes);
1035}
1036
1037static struct class_interface pccard_rsrc_interface __refdata = {
1038 .class = &pcmcia_socket_class,
1039 .add_dev = &pccard_sysfs_add_rsrc,
1040 .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
1041};
1042
1043static int __init nonstatic_sysfs_init(void)
1044{
1045 return class_interface_register(&pccard_rsrc_interface);
1046}
1047
1048static void __exit nonstatic_sysfs_exit(void)
1049{
1050 class_interface_unregister(&pccard_rsrc_interface);
1051}
1052
1053module_init(nonstatic_sysfs_init);
1054module_exit(nonstatic_sysfs_exit);
1055