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