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