pcmcia: use ops_mutex for rsrc_{mgr,nonstatic} locking
[deliverable/linux.git] / drivers / pcmcia / rsrc_nonstatic.c
1 /*
2 * rsrc_nonstatic.c -- Resource management routines for !SS_CAP_STATIC_MAP sockets
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * The initial developer of the original code is David A. Hinds
9 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
10 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
11 *
12 * (C) 1999 David A. Hinds
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/cs_types.h>
32 #include <pcmcia/ss.h>
33 #include <pcmcia/cs.h>
34 #include <pcmcia/cistpl.h>
35 #include "cs_internal.h"
36
37 MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
38 MODULE_LICENSE("GPL");
39
40 /* Parameters that can be set with 'insmod' */
41
42 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
43
44 INT_MODULE_PARM(probe_mem, 1); /* memory probe? */
45 #ifdef CONFIG_PCMCIA_PROBE
46 INT_MODULE_PARM(probe_io, 1); /* IO port probe? */
47 INT_MODULE_PARM(mem_limit, 0x10000);
48 #endif
49
50 /* for io_db and mem_db */
51 struct resource_map {
52 u_long base, num;
53 struct resource_map *next;
54 };
55
56 struct socket_data {
57 struct resource_map mem_db;
58 struct resource_map io_db;
59 unsigned int rsrc_mem_probe;
60 };
61
62 #define MEM_PROBE_LOW (1 << 0)
63 #define MEM_PROBE_HIGH (1 << 1)
64
65
66 /*======================================================================
67
68 Linux resource management extensions
69
70 ======================================================================*/
71
72 static struct resource *
73 make_resource(resource_size_t b, resource_size_t n, int flags, const char *name)
74 {
75 struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
76
77 if (res) {
78 res->name = name;
79 res->start = b;
80 res->end = b + n - 1;
81 res->flags = flags;
82 }
83 return res;
84 }
85
86 static struct resource *
87 claim_region(struct pcmcia_socket *s, resource_size_t base,
88 resource_size_t size, int type, char *name)
89 {
90 struct resource *res, *parent;
91
92 parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
93 res = make_resource(base, size, type | IORESOURCE_BUSY, name);
94
95 if (res) {
96 #ifdef CONFIG_PCI
97 if (s && s->cb_dev)
98 parent = pci_find_parent_resource(s->cb_dev, res);
99 #endif
100 if (!parent || request_resource(parent, res)) {
101 kfree(res);
102 res = NULL;
103 }
104 }
105 return res;
106 }
107
108 static void free_region(struct resource *res)
109 {
110 if (res) {
111 release_resource(res);
112 kfree(res);
113 }
114 }
115
116 /*======================================================================
117
118 These manage the internal databases of available resources.
119
120 ======================================================================*/
121
122 static int add_interval(struct resource_map *map, u_long base, u_long num)
123 {
124 struct resource_map *p, *q;
125
126 for (p = map; ; p = p->next) {
127 if ((p != map) && (p->base+p->num-1 >= base))
128 return -1;
129 if ((p->next == map) || (p->next->base > base+num-1))
130 break;
131 }
132 q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
133 if (!q) {
134 printk(KERN_WARNING "out of memory to update resources\n");
135 return -ENOMEM;
136 }
137 q->base = base; q->num = num;
138 q->next = p->next; p->next = q;
139 return 0;
140 }
141
142 /*====================================================================*/
143
144 static int sub_interval(struct resource_map *map, u_long base, u_long num)
145 {
146 struct resource_map *p, *q;
147
148 for (p = map; ; p = q) {
149 q = p->next;
150 if (q == map)
151 break;
152 if ((q->base+q->num > base) && (base+num > q->base)) {
153 if (q->base >= base) {
154 if (q->base+q->num <= base+num) {
155 /* Delete whole block */
156 p->next = q->next;
157 kfree(q);
158 /* don't advance the pointer yet */
159 q = p;
160 } else {
161 /* Cut off bit from the front */
162 q->num = q->base + q->num - base - num;
163 q->base = base + num;
164 }
165 } else if (q->base+q->num <= base+num) {
166 /* Cut off bit from the end */
167 q->num = base - q->base;
168 } else {
169 /* Split the block into two pieces */
170 p = kmalloc(sizeof(struct resource_map),
171 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 These routines examine a region of IO or memory addresses to
189 determine what ranges might be genuinely available.
190
191 ======================================================================*/
192
193 #ifdef CONFIG_PCMCIA_PROBE
194 static 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 /* First, what does a floating port look like? */
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 ioprobe");
216 if (!res)
217 continue;
218 hole = inb(i);
219 for (j = 1; j < 8; j++)
220 if (inb(i+j) != hole)
221 break;
222 free_region(res);
223 if ((j == 8) && (++b[hole] > b[most]))
224 most = hole;
225 if (b[most] == 127)
226 break;
227 }
228 kfree(b);
229
230 bad = any = 0;
231 for (i = base; i < base+num; i += 8) {
232 res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
233 if (!res)
234 continue;
235 for (j = 0; j < 8; j++)
236 if (inb(i+j) != most)
237 break;
238 free_region(res);
239 if (j < 8) {
240 if (!any)
241 printk(" excluding");
242 if (!bad)
243 bad = any = i;
244 } else {
245 if (bad) {
246 sub_interval(&s_data->io_db, bad, i-bad);
247 printk(" %#x-%#x", bad, i-1);
248 bad = 0;
249 }
250 }
251 }
252 if (bad) {
253 if ((num > 16) && (bad == base) && (i == base+num)) {
254 printk(" nothing: probe failed.\n");
255 return;
256 } else {
257 sub_interval(&s_data->io_db, bad, i-bad);
258 printk(" %#x-%#x", bad, i-1);
259 }
260 }
261
262 printk(any ? "\n" : " clean.\n");
263 }
264 #endif
265
266 /*======================================================================*/
267
268 /**
269 * readable() - iomem validation function for cards with a valid CIS
270 */
271 static int readable(struct pcmcia_socket *s, struct resource *res,
272 unsigned int *count)
273 {
274 int ret = -EINVAL;
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 /* as we're only called from pcmcia.c, we're safe */
281 if (s->callback->validate)
282 ret = s->callback->validate(s, count);
283 /* invalidate mapping */
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 * checksum() - iomem validation function for simple memory cards
296 */
297 static 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 /* Don't bother checking every word... */
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 * do_validate_mem() - low level validate a memory region for PCMCIA use
336 * @s: PCMCIA socket to validate
337 * @base: start address of resource to check
338 * @size: size of resource to check
339 * @validate: validation function to use
340 *
341 * do_validate_mem() splits up the memory region which is to be checked
342 * into two parts. Both are passed to the @validate() function. If
343 * @validate() returns non-zero, or the value parameter to @validate()
344 * is zero, or the value parameter is different between both calls,
345 * the check fails, and -EINVAL is returned. Else, 0 is returned.
346 */
347 static 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 resource *res1, *res2;
354 unsigned int info1 = 1, info2 = 1;
355 int ret = -EINVAL;
356
357 res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
358 res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
359 "PCMCIA memprobe");
360
361 if (res1 && res2) {
362 ret = 0;
363 if (validate) {
364 ret = validate(s, res1, &info1);
365 ret += validate(s, res2, &info2);
366 }
367 }
368
369 free_region(res2);
370 free_region(res1);
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 if ((ret) || (info1 != info2) || (info1 == 0))
376 return -EINVAL;
377
378 return 0;
379 }
380
381
382 /**
383 * do_mem_probe() - validate a memory region for PCMCIA use
384 * @s: PCMCIA socket to validate
385 * @base: start address of resource to check
386 * @num: size of resource to check
387 * @validate: validation function to use
388 * @fallback: validation function to use if validate fails
389 *
390 * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
391 * To do so, the area is split up into sensible parts, and then passed
392 * into the @validate() function. Only if @validate() and @fallback() fail,
393 * the area is marked as unavaibale for use by the PCMCIA subsystem. The
394 * function returns the size of the usable memory area.
395 */
396 static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
397 int validate (struct pcmcia_socket *s,
398 struct resource *res,
399 unsigned int *value),
400 int fallback (struct pcmcia_socket *s,
401 struct resource *res,
402 unsigned int *value))
403 {
404 struct socket_data *s_data = s->resource_data;
405 u_long i, j, bad, fail, step;
406
407 dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
408 base, base+num-1);
409 bad = fail = 0;
410 step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
411 /* don't allow too large steps */
412 if (step > 0x800000)
413 step = 0x800000;
414 /* cis_readable wants to map 2x map_size */
415 if (step < 2 * s->map_size)
416 step = 2 * s->map_size;
417 for (i = j = base; i < base+num; i = j + step) {
418 if (!fail) {
419 for (j = i; j < base+num; j += step) {
420 if (!do_validate_mem(s, j, step, validate))
421 break;
422 }
423 fail = ((i == base) && (j == base+num));
424 }
425 if ((fail) && (fallback)) {
426 for (j = i; j < base+num; j += step)
427 if (!do_validate_mem(s, j, step, fallback))
428 break;
429 }
430 if (i != j) {
431 if (!bad)
432 printk(" excluding");
433 printk(" %#05lx-%#05lx", i, j-1);
434 sub_interval(&s_data->mem_db, i, j-i);
435 bad += j-i;
436 }
437 }
438 printk(bad ? "\n" : " clean.\n");
439 return num - bad;
440 }
441
442
443 #ifdef CONFIG_PCMCIA_PROBE
444
445 /**
446 * inv_probe() - top-to-bottom search for one usuable high memory area
447 * @s: PCMCIA socket to validate
448 * @m: resource_map to check
449 */
450 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
451 {
452 struct socket_data *s_data = s->resource_data;
453 u_long ok;
454 if (m == &s_data->mem_db)
455 return 0;
456 ok = inv_probe(m->next, s);
457 if (ok) {
458 if (m->base >= 0x100000)
459 sub_interval(&s_data->mem_db, m->base, m->num);
460 return ok;
461 }
462 if (m->base < 0x100000)
463 return 0;
464 return do_mem_probe(s, m->base, m->num, readable, checksum);
465 }
466
467 /**
468 * validate_mem() - memory probe function
469 * @s: PCMCIA socket to validate
470 * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
471 *
472 * The memory probe. If the memory list includes a 64K-aligned block
473 * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
474 * least mem_limit free space, we quit. Returns 0 on usuable ports.
475 */
476 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
477 {
478 struct resource_map *m, mm;
479 static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
480 unsigned long b, i, ok = 0;
481 struct socket_data *s_data = s->resource_data;
482
483 /* We do up to four passes through the list */
484 if (probe_mask & MEM_PROBE_HIGH) {
485 if (inv_probe(s_data->mem_db.next, s) > 0)
486 return 0;
487 dev_printk(KERN_NOTICE, &s->dev,
488 "cs: warning: no high memory space available!\n");
489 return -ENODEV;
490 }
491
492 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
493 mm = *m;
494 /* Only probe < 1 MB */
495 if (mm.base >= 0x100000)
496 continue;
497 if ((mm.base | mm.num) & 0xffff) {
498 ok += do_mem_probe(s, mm.base, mm.num, readable,
499 checksum);
500 continue;
501 }
502 /* Special probe for 64K-aligned block */
503 for (i = 0; i < 4; i++) {
504 b = order[i] << 12;
505 if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
506 if (ok >= mem_limit)
507 sub_interval(&s_data->mem_db, b, 0x10000);
508 else
509 ok += do_mem_probe(s, b, 0x10000,
510 readable, checksum);
511 }
512 }
513 }
514
515 if (ok > 0)
516 return 0;
517
518 return -ENODEV;
519 }
520
521 #else /* CONFIG_PCMCIA_PROBE */
522
523 /**
524 * validate_mem() - memory probe function
525 * @s: PCMCIA socket to validate
526 * @probe_mask: ignored
527 *
528 * Returns 0 on usuable ports.
529 */
530 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
531 {
532 struct resource_map *m, mm;
533 struct socket_data *s_data = s->resource_data;
534 unsigned long ok = 0;
535
536 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
537 mm = *m;
538 ok += do_mem_probe(s, mm.base, mm.num, readable, checksum);
539 }
540 if (ok > 0)
541 return 0;
542 return -ENODEV;
543 }
544
545 #endif /* CONFIG_PCMCIA_PROBE */
546
547
548 /**
549 * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
550 * @s: PCMCIA socket to validate
551 *
552 * This is tricky... when we set up CIS memory, we try to validate
553 * the memory window space allocations.
554 *
555 * Locking note: Must be called with skt_mutex held!
556 */
557 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
558 {
559 struct socket_data *s_data = s->resource_data;
560 unsigned int probe_mask = MEM_PROBE_LOW;
561 int ret = 0;
562
563 if (!probe_mem)
564 return 0;
565
566 if (s->features & SS_CAP_PAGE_REGS)
567 probe_mask = MEM_PROBE_HIGH;
568
569 if (probe_mask & ~s_data->rsrc_mem_probe) {
570 if (s->state & SOCKET_PRESENT) {
571 ret = validate_mem(s, probe_mask);
572 if (!ret)
573 s_data->rsrc_mem_probe |= probe_mask;
574 }
575 }
576
577 return ret;
578 }
579
580 struct pcmcia_align_data {
581 unsigned long mask;
582 unsigned long offset;
583 struct resource_map *map;
584 };
585
586 static void
587 pcmcia_common_align(void *align_data, struct resource *res,
588 resource_size_t size, resource_size_t align)
589 {
590 struct pcmcia_align_data *data = align_data;
591 resource_size_t start;
592 /*
593 * Ensure that we have the correct start address
594 */
595 start = (res->start & ~data->mask) + data->offset;
596 if (start < res->start)
597 start += data->mask + 1;
598 res->start = start;
599 }
600
601 static void
602 pcmcia_align(void *align_data, struct resource *res, resource_size_t size,
603 resource_size_t align)
604 {
605 struct pcmcia_align_data *data = align_data;
606 struct resource_map *m;
607
608 pcmcia_common_align(data, res, size, align);
609
610 for (m = data->map->next; m != data->map; m = m->next) {
611 unsigned long start = m->base;
612 unsigned long end = m->base + m->num - 1;
613
614 /*
615 * If the lower resources are not available, try aligning
616 * to this entry of the resource database to see if it'll
617 * fit here.
618 */
619 if (res->start < start) {
620 res->start = start;
621 pcmcia_common_align(data, res, size, align);
622 }
623
624 /*
625 * If we're above the area which was passed in, there's
626 * no point proceeding.
627 */
628 if (res->start >= res->end)
629 break;
630
631 if ((res->start + size - 1) <= end)
632 break;
633 }
634
635 /*
636 * If we failed to find something suitable, ensure we fail.
637 */
638 if (m == data->map)
639 res->start = res->end;
640 }
641
642 /*
643 * Adjust an existing IO region allocation, but making sure that we don't
644 * encroach outside the resources which the user supplied.
645 */
646 static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
647 unsigned long r_end, struct pcmcia_socket *s)
648 {
649 struct resource_map *m;
650 struct socket_data *s_data = s->resource_data;
651 int ret = -ENOMEM;
652
653 for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
654 unsigned long start = m->base;
655 unsigned long end = m->base + m->num - 1;
656
657 if (start > r_start || r_end > end)
658 continue;
659
660 ret = adjust_resource(res, r_start, r_end - r_start + 1);
661 break;
662 }
663
664 return ret;
665 }
666
667 /*======================================================================
668
669 These find ranges of I/O ports or memory addresses that are not
670 currently allocated by other devices.
671
672 The 'align' field should reflect the number of bits of address
673 that need to be preserved from the initial value of *base. It
674 should be a power of two, greater than or equal to 'num'. A value
675 of 0 means that all bits of *base are significant. *base should
676 also be strictly less than 'align'.
677
678 ======================================================================*/
679
680 static struct resource *nonstatic_find_io_region(unsigned long base, int num,
681 unsigned long align, struct pcmcia_socket *s)
682 {
683 struct resource *res = make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev));
684 struct socket_data *s_data = s->resource_data;
685 struct pcmcia_align_data data;
686 unsigned long min = base;
687 int ret;
688
689 if (align == 0)
690 align = 0x10000;
691
692 data.mask = align - 1;
693 data.offset = base & data.mask;
694 data.map = &s_data->io_db;
695
696 #ifdef CONFIG_PCI
697 if (s->cb_dev) {
698 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
699 min, 0, pcmcia_align, &data);
700 } else
701 #endif
702 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
703 1, pcmcia_align, &data);
704
705 if (ret != 0) {
706 kfree(res);
707 res = NULL;
708 }
709 return res;
710 }
711
712 static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
713 u_long align, int low, struct pcmcia_socket *s)
714 {
715 struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev));
716 struct socket_data *s_data = s->resource_data;
717 struct pcmcia_align_data data;
718 unsigned long min, max;
719 int ret, i;
720
721 low = low || !(s->features & SS_CAP_PAGE_REGS);
722
723 data.mask = align - 1;
724 data.offset = base & data.mask;
725 data.map = &s_data->mem_db;
726
727 for (i = 0; i < 2; i++) {
728 if (low) {
729 max = 0x100000UL;
730 min = base < max ? base : 0;
731 } else {
732 max = ~0UL;
733 min = 0x100000UL + base;
734 }
735
736 #ifdef CONFIG_PCI
737 if (s->cb_dev) {
738 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
739 1, min, 0,
740 pcmcia_align, &data);
741 } else
742 #endif
743 ret = allocate_resource(&iomem_resource, res, num, min,
744 max, 1, pcmcia_align, &data);
745 if (ret == 0 || low)
746 break;
747 low = 1;
748 }
749
750 if (ret != 0) {
751 kfree(res);
752 res = NULL;
753 }
754 return res;
755 }
756
757
758 static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
759 {
760 struct socket_data *data = s->resource_data;
761 unsigned long size = end - start + 1;
762 int ret = 0;
763
764 if (end < start)
765 return -EINVAL;
766
767 switch (action) {
768 case ADD_MANAGED_RESOURCE:
769 ret = add_interval(&data->mem_db, start, size);
770 if (!ret)
771 do_mem_probe(s, start, size, NULL, NULL);
772 break;
773 case REMOVE_MANAGED_RESOURCE:
774 ret = sub_interval(&data->mem_db, start, size);
775 break;
776 default:
777 ret = -EINVAL;
778 }
779
780 return ret;
781 }
782
783
784 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
785 {
786 struct socket_data *data = s->resource_data;
787 unsigned long size = end - start + 1;
788 int ret = 0;
789
790 if (end < start)
791 return -EINVAL;
792
793 if (end > IO_SPACE_LIMIT)
794 return -EINVAL;
795
796 switch (action) {
797 case ADD_MANAGED_RESOURCE:
798 if (add_interval(&data->io_db, start, size) != 0) {
799 ret = -EBUSY;
800 break;
801 }
802 #ifdef CONFIG_PCMCIA_PROBE
803 if (probe_io)
804 do_io_probe(s, start, size);
805 #endif
806 break;
807 case REMOVE_MANAGED_RESOURCE:
808 sub_interval(&data->io_db, start, size);
809 break;
810 default:
811 ret = -EINVAL;
812 break;
813 }
814
815 return ret;
816 }
817
818
819 #ifdef CONFIG_PCI
820 static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
821 {
822 struct resource *res;
823 int i, done = 0;
824
825 if (!s->cb_dev || !s->cb_dev->bus)
826 return -ENODEV;
827
828 #if defined(CONFIG_X86)
829 /* If this is the root bus, the risk of hitting
830 * some strange system devices which aren't protected
831 * by either ACPI resource tables or properly requested
832 * resources is too big. Therefore, don't do auto-adding
833 * of resources at the moment.
834 */
835 if (s->cb_dev->bus->number == 0)
836 return -EINVAL;
837 #endif
838
839 for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
840 res = s->cb_dev->bus->resource[i];
841 if (!res)
842 continue;
843
844 if (res->flags & IORESOURCE_IO) {
845 if (res == &ioport_resource)
846 continue;
847 dev_printk(KERN_INFO, &s->cb_dev->dev,
848 "pcmcia: parent PCI bridge I/O "
849 "window: 0x%llx - 0x%llx\n",
850 (unsigned long long)res->start,
851 (unsigned long long)res->end);
852 if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
853 done |= IORESOURCE_IO;
854
855 }
856
857 if (res->flags & IORESOURCE_MEM) {
858 if (res == &iomem_resource)
859 continue;
860 dev_printk(KERN_INFO, &s->cb_dev->dev,
861 "pcmcia: parent PCI bridge Memory "
862 "window: 0x%llx - 0x%llx\n",
863 (unsigned long long)res->start,
864 (unsigned long long)res->end);
865 if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
866 done |= IORESOURCE_MEM;
867 }
868 }
869
870 /* if we got at least one of IO, and one of MEM, we can be glad and
871 * activate the PCMCIA subsystem */
872 if (done == (IORESOURCE_MEM | IORESOURCE_IO))
873 s->resource_setup_done = 1;
874
875 return 0;
876 }
877
878 #else
879
880 static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
881 {
882 return -ENODEV;
883 }
884
885 #endif
886
887
888 static int nonstatic_init(struct pcmcia_socket *s)
889 {
890 struct socket_data *data;
891
892 data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
893 if (!data)
894 return -ENOMEM;
895
896 data->mem_db.next = &data->mem_db;
897 data->io_db.next = &data->io_db;
898
899 s->resource_data = (void *) data;
900
901 nonstatic_autoadd_resources(s);
902
903 return 0;
904 }
905
906 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
907 {
908 struct socket_data *data = s->resource_data;
909 struct resource_map *p, *q;
910
911 for (p = data->mem_db.next; p != &data->mem_db; p = q) {
912 q = p->next;
913 kfree(p);
914 }
915 for (p = data->io_db.next; p != &data->io_db; p = q) {
916 q = p->next;
917 kfree(p);
918 }
919 }
920
921
922 struct pccard_resource_ops pccard_nonstatic_ops = {
923 .validate_mem = pcmcia_nonstatic_validate_mem,
924 .adjust_io_region = nonstatic_adjust_io_region,
925 .find_io = nonstatic_find_io_region,
926 .find_mem = nonstatic_find_mem_region,
927 .add_io = adjust_io,
928 .add_mem = adjust_memory,
929 .init = nonstatic_init,
930 .exit = nonstatic_release_resource_db,
931 };
932 EXPORT_SYMBOL(pccard_nonstatic_ops);
933
934
935 /* sysfs interface to the resource database */
936
937 static ssize_t show_io_db(struct device *dev,
938 struct device_attribute *attr, char *buf)
939 {
940 struct pcmcia_socket *s = dev_get_drvdata(dev);
941 struct socket_data *data;
942 struct resource_map *p;
943 ssize_t ret = 0;
944
945 mutex_lock(&s->ops_mutex);
946 data = s->resource_data;
947
948 for (p = data->io_db.next; p != &data->io_db; p = p->next) {
949 if (ret > (PAGE_SIZE - 10))
950 continue;
951 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
952 "0x%08lx - 0x%08lx\n",
953 ((unsigned long) p->base),
954 ((unsigned long) p->base + p->num - 1));
955 }
956
957 mutex_unlock(&s->ops_mutex);
958 return ret;
959 }
960
961 static ssize_t store_io_db(struct device *dev,
962 struct device_attribute *attr,
963 const char *buf, size_t count)
964 {
965 struct pcmcia_socket *s = dev_get_drvdata(dev);
966 unsigned long start_addr, end_addr;
967 unsigned int add = ADD_MANAGED_RESOURCE;
968 ssize_t ret = 0;
969
970 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
971 if (ret != 2) {
972 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
973 add = REMOVE_MANAGED_RESOURCE;
974 if (ret != 2) {
975 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
976 &end_addr);
977 add = ADD_MANAGED_RESOURCE;
978 if (ret != 2)
979 return -EINVAL;
980 }
981 }
982 if (end_addr < start_addr)
983 return -EINVAL;
984
985 mutex_lock(&s->ops_mutex);
986 ret = adjust_io(s, add, start_addr, end_addr);
987 if (!ret)
988 s->resource_setup_new = 1;
989 mutex_unlock(&s->ops_mutex);
990
991 return ret ? ret : count;
992 }
993 static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
994
995 static ssize_t show_mem_db(struct device *dev,
996 struct device_attribute *attr, char *buf)
997 {
998 struct pcmcia_socket *s = dev_get_drvdata(dev);
999 struct socket_data *data;
1000 struct resource_map *p;
1001 ssize_t ret = 0;
1002
1003 mutex_lock(&s->ops_mutex);
1004 data = s->resource_data;
1005
1006 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
1007 if (ret > (PAGE_SIZE - 10))
1008 continue;
1009 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1010 "0x%08lx - 0x%08lx\n",
1011 ((unsigned long) p->base),
1012 ((unsigned long) p->base + p->num - 1));
1013 }
1014
1015 mutex_unlock(&s->ops_mutex);
1016 return ret;
1017 }
1018
1019 static ssize_t store_mem_db(struct device *dev,
1020 struct device_attribute *attr,
1021 const char *buf, size_t count)
1022 {
1023 struct pcmcia_socket *s = dev_get_drvdata(dev);
1024 unsigned long start_addr, end_addr;
1025 unsigned int add = ADD_MANAGED_RESOURCE;
1026 ssize_t ret = 0;
1027
1028 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1029 if (ret != 2) {
1030 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1031 add = REMOVE_MANAGED_RESOURCE;
1032 if (ret != 2) {
1033 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1034 &end_addr);
1035 add = ADD_MANAGED_RESOURCE;
1036 if (ret != 2)
1037 return -EINVAL;
1038 }
1039 }
1040 if (end_addr < start_addr)
1041 return -EINVAL;
1042
1043 mutex_lock(&s->ops_mutex);
1044 ret = adjust_memory(s, add, start_addr, end_addr);
1045 if (!ret)
1046 s->resource_setup_new = 1;
1047 mutex_unlock(&s->ops_mutex);
1048
1049 return ret ? ret : count;
1050 }
1051 static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1052
1053 static struct attribute *pccard_rsrc_attributes[] = {
1054 &dev_attr_available_resources_io.attr,
1055 &dev_attr_available_resources_mem.attr,
1056 NULL,
1057 };
1058
1059 static const struct attribute_group rsrc_attributes = {
1060 .attrs = pccard_rsrc_attributes,
1061 };
1062
1063 static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
1064 struct class_interface *class_intf)
1065 {
1066 struct pcmcia_socket *s = dev_get_drvdata(dev);
1067
1068 if (s->resource_ops != &pccard_nonstatic_ops)
1069 return 0;
1070 return sysfs_create_group(&dev->kobj, &rsrc_attributes);
1071 }
1072
1073 static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
1074 struct class_interface *class_intf)
1075 {
1076 struct pcmcia_socket *s = dev_get_drvdata(dev);
1077
1078 if (s->resource_ops != &pccard_nonstatic_ops)
1079 return;
1080 sysfs_remove_group(&dev->kobj, &rsrc_attributes);
1081 }
1082
1083 static struct class_interface pccard_rsrc_interface __refdata = {
1084 .class = &pcmcia_socket_class,
1085 .add_dev = &pccard_sysfs_add_rsrc,
1086 .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
1087 };
1088
1089 static int __init nonstatic_sysfs_init(void)
1090 {
1091 return class_interface_register(&pccard_rsrc_interface);
1092 }
1093
1094 static void __exit nonstatic_sysfs_exit(void)
1095 {
1096 class_interface_unregister(&pccard_rsrc_interface);
1097 }
1098
1099 module_init(nonstatic_sysfs_init);
1100 module_exit(nonstatic_sysfs_exit);
This page took 0.110187 seconds and 5 git commands to generate.