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