]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/pcmcia/rsrc_nonstatic.c
pcmcia: re-start on MFC override
[mirror_ubuntu-bionic-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;
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;
22916638
DB
813 unsigned long size = end - start + 1;
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
1146bc74 823 if (end < start)
22916638
DB
824 return -EINVAL;
825
826 if (end > IO_SPACE_LIMIT)
827 return -EINVAL;
1da177e4 828
22916638 829 switch (action) {
1da177e4 830 case ADD_MANAGED_RESOURCE:
22916638
DB
831 if (add_interval(&data->io_db, start, size) != 0) {
832 ret = -EBUSY;
1da177e4
LT
833 break;
834 }
835#ifdef CONFIG_PCMCIA_PROBE
836 if (probe_io)
22916638 837 do_io_probe(s, start, size);
1da177e4
LT
838#endif
839 break;
840 case REMOVE_MANAGED_RESOURCE:
22916638 841 sub_interval(&data->io_db, start, size);
1da177e4
LT
842 break;
843 default:
22916638 844 ret = -EINVAL;
1da177e4
LT
845 break;
846 }
1da177e4
LT
847
848 return ret;
849}
850
851
3c29976a
DB
852#ifdef CONFIG_PCI
853static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
854{
855 struct resource *res;
856 int i, done = 0;
857
858 if (!s->cb_dev || !s->cb_dev->bus)
859 return -ENODEV;
860
0d078f6f 861#if defined(CONFIG_X86)
b6d00f0d
DB
862 /* If this is the root bus, the risk of hitting
863 * some strange system devices which aren't protected
864 * by either ACPI resource tables or properly requested
865 * resources is too big. Therefore, don't do auto-adding
866 * of resources at the moment.
867 */
868 if (s->cb_dev->bus->number == 0)
869 return -EINVAL;
870#endif
871
89a74ecc 872 pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
3c29976a
DB
873 if (!res)
874 continue;
875
876 if (res->flags & IORESOURCE_IO) {
877 if (res == &ioport_resource)
878 continue;
dbe4ea5f 879 dev_printk(KERN_INFO, &s->cb_dev->dev,
e1944c6b
BH
880 "pcmcia: parent PCI bridge window: %pR\n",
881 res);
3c29976a
DB
882 if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
883 done |= IORESOURCE_IO;
884
885 }
886
887 if (res->flags & IORESOURCE_MEM) {
888 if (res == &iomem_resource)
889 continue;
dbe4ea5f 890 dev_printk(KERN_INFO, &s->cb_dev->dev,
e1944c6b
BH
891 "pcmcia: parent PCI bridge window: %pR\n",
892 res);
3c29976a
DB
893 if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
894 done |= IORESOURCE_MEM;
895 }
896 }
897
898 /* if we got at least one of IO, and one of MEM, we can be glad and
899 * activate the PCMCIA subsystem */
54bb5675 900 if (done == (IORESOURCE_MEM | IORESOURCE_IO))
3c29976a
DB
901 s->resource_setup_done = 1;
902
903 return 0;
904}
905
906#else
907
908static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
909{
910 return -ENODEV;
911}
912
913#endif
914
915
1da177e4
LT
916static int nonstatic_init(struct pcmcia_socket *s)
917{
918 struct socket_data *data;
919
8084b372 920 data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
1da177e4
LT
921 if (!data)
922 return -ENOMEM;
1da177e4
LT
923
924 data->mem_db.next = &data->mem_db;
7b4884ca 925 data->mem_db_valid.next = &data->mem_db_valid;
1da177e4
LT
926 data->io_db.next = &data->io_db;
927
928 s->resource_data = (void *) data;
929
3c29976a
DB
930 nonstatic_autoadd_resources(s);
931
1da177e4
LT
932 return 0;
933}
934
935static void nonstatic_release_resource_db(struct pcmcia_socket *s)
936{
937 struct socket_data *data = s->resource_data;
938 struct resource_map *p, *q;
939
7b4884ca
DB
940 for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
941 q = p->next;
942 kfree(p);
943 }
1da177e4
LT
944 for (p = data->mem_db.next; p != &data->mem_db; p = q) {
945 q = p->next;
946 kfree(p);
947 }
948 for (p = data->io_db.next; p != &data->io_db; p = q) {
949 q = p->next;
950 kfree(p);
951 }
1da177e4
LT
952}
953
954
955struct pccard_resource_ops pccard_nonstatic_ops = {
956 .validate_mem = pcmcia_nonstatic_validate_mem,
957 .adjust_io_region = nonstatic_adjust_io_region,
958 .find_io = nonstatic_find_io_region,
959 .find_mem = nonstatic_find_mem_region,
c5023801
DB
960 .add_io = adjust_io,
961 .add_mem = adjust_memory,
1da177e4
LT
962 .init = nonstatic_init,
963 .exit = nonstatic_release_resource_db,
964};
965EXPORT_SYMBOL(pccard_nonstatic_ops);
966
967
968/* sysfs interface to the resource database */
969
87373318
GKH
970static ssize_t show_io_db(struct device *dev,
971 struct device_attribute *attr, char *buf)
1da177e4 972{
87373318 973 struct pcmcia_socket *s = dev_get_drvdata(dev);
1da177e4
LT
974 struct socket_data *data;
975 struct resource_map *p;
976 ssize_t ret = 0;
977
cfe5d809 978 mutex_lock(&s->ops_mutex);
1da177e4
LT
979 data = s->resource_data;
980
981 for (p = data->io_db.next; p != &data->io_db; p = p->next) {
982 if (ret > (PAGE_SIZE - 10))
983 continue;
9fea84f4
DB
984 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
985 "0x%08lx - 0x%08lx\n",
986 ((unsigned long) p->base),
987 ((unsigned long) p->base + p->num - 1));
1da177e4
LT
988 }
989
cfe5d809 990 mutex_unlock(&s->ops_mutex);
9fea84f4 991 return ret;
1da177e4
LT
992}
993
87373318
GKH
994static ssize_t store_io_db(struct device *dev,
995 struct device_attribute *attr,
996 const char *buf, size_t count)
1da177e4 997{
87373318 998 struct pcmcia_socket *s = dev_get_drvdata(dev);
1da177e4 999 unsigned long start_addr, end_addr;
22916638 1000 unsigned int add = ADD_MANAGED_RESOURCE;
1da177e4
LT
1001 ssize_t ret = 0;
1002
9fea84f4 1003 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1da177e4 1004 if (ret != 2) {
9fea84f4 1005 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
22916638 1006 add = REMOVE_MANAGED_RESOURCE;
1da177e4 1007 if (ret != 2) {
9fea84f4
DB
1008 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1009 &end_addr);
22916638 1010 add = ADD_MANAGED_RESOURCE;
1da177e4
LT
1011 if (ret != 2)
1012 return -EINVAL;
1013 }
1014 }
1146bc74 1015 if (end_addr < start_addr)
1da177e4
LT
1016 return -EINVAL;
1017
cfe5d809 1018 mutex_lock(&s->ops_mutex);
22916638 1019 ret = adjust_io(s, add, start_addr, end_addr);
3c29976a
DB
1020 if (!ret)
1021 s->resource_setup_new = 1;
cfe5d809 1022 mutex_unlock(&s->ops_mutex);
1da177e4
LT
1023
1024 return ret ? ret : count;
1025}
87373318 1026static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
1da177e4 1027
87373318
GKH
1028static ssize_t show_mem_db(struct device *dev,
1029 struct device_attribute *attr, char *buf)
1da177e4 1030{
87373318 1031 struct pcmcia_socket *s = dev_get_drvdata(dev);
1da177e4
LT
1032 struct socket_data *data;
1033 struct resource_map *p;
1034 ssize_t ret = 0;
1035
cfe5d809 1036 mutex_lock(&s->ops_mutex);
1da177e4
LT
1037 data = s->resource_data;
1038
7b4884ca
DB
1039 for (p = data->mem_db_valid.next; p != &data->mem_db_valid;
1040 p = p->next) {
1041 if (ret > (PAGE_SIZE - 10))
1042 continue;
1043 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1044 "0x%08lx - 0x%08lx\n",
1045 ((unsigned long) p->base),
1046 ((unsigned long) p->base + p->num - 1));
1047 }
1048
1da177e4
LT
1049 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
1050 if (ret > (PAGE_SIZE - 10))
1051 continue;
9fea84f4
DB
1052 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1053 "0x%08lx - 0x%08lx\n",
1054 ((unsigned long) p->base),
1055 ((unsigned long) p->base + p->num - 1));
1da177e4
LT
1056 }
1057
cfe5d809 1058 mutex_unlock(&s->ops_mutex);
9fea84f4 1059 return ret;
1da177e4
LT
1060}
1061
87373318
GKH
1062static ssize_t store_mem_db(struct device *dev,
1063 struct device_attribute *attr,
1064 const char *buf, size_t count)
1da177e4 1065{
87373318 1066 struct pcmcia_socket *s = dev_get_drvdata(dev);
1da177e4 1067 unsigned long start_addr, end_addr;
22916638 1068 unsigned int add = ADD_MANAGED_RESOURCE;
1da177e4
LT
1069 ssize_t ret = 0;
1070
9fea84f4 1071 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1da177e4 1072 if (ret != 2) {
9fea84f4 1073 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
22916638 1074 add = REMOVE_MANAGED_RESOURCE;
1da177e4 1075 if (ret != 2) {
9fea84f4
DB
1076 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1077 &end_addr);
22916638 1078 add = ADD_MANAGED_RESOURCE;
1da177e4
LT
1079 if (ret != 2)
1080 return -EINVAL;
1081 }
1082 }
1146bc74 1083 if (end_addr < start_addr)
1da177e4
LT
1084 return -EINVAL;
1085
cfe5d809 1086 mutex_lock(&s->ops_mutex);
22916638 1087 ret = adjust_memory(s, add, start_addr, end_addr);
3c29976a
DB
1088 if (!ret)
1089 s->resource_setup_new = 1;
cfe5d809 1090 mutex_unlock(&s->ops_mutex);
1da177e4
LT
1091
1092 return ret ? ret : count;
1093}
87373318 1094static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1da177e4 1095
7d578961
DB
1096static struct attribute *pccard_rsrc_attributes[] = {
1097 &dev_attr_available_resources_io.attr,
1098 &dev_attr_available_resources_mem.attr,
1da177e4
LT
1099 NULL,
1100};
1101
7d578961
DB
1102static const struct attribute_group rsrc_attributes = {
1103 .attrs = pccard_rsrc_attributes,
1104};
1105
87373318 1106static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
d8539d81 1107 struct class_interface *class_intf)
1da177e4 1108{
87373318 1109 struct pcmcia_socket *s = dev_get_drvdata(dev);
7d578961 1110
1da177e4
LT
1111 if (s->resource_ops != &pccard_nonstatic_ops)
1112 return 0;
7d578961 1113 return sysfs_create_group(&dev->kobj, &rsrc_attributes);
1da177e4
LT
1114}
1115
87373318 1116static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
d8539d81 1117 struct class_interface *class_intf)
1da177e4 1118{
87373318 1119 struct pcmcia_socket *s = dev_get_drvdata(dev);
1da177e4
LT
1120
1121 if (s->resource_ops != &pccard_nonstatic_ops)
1122 return;
7d578961 1123 sysfs_remove_group(&dev->kobj, &rsrc_attributes);
1da177e4
LT
1124}
1125
ed49f5d0 1126static struct class_interface pccard_rsrc_interface __refdata = {
1da177e4 1127 .class = &pcmcia_socket_class,
87373318
GKH
1128 .add_dev = &pccard_sysfs_add_rsrc,
1129 .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
1da177e4
LT
1130};
1131
1132static int __init nonstatic_sysfs_init(void)
1133{
1134 return class_interface_register(&pccard_rsrc_interface);
1135}
1136
1137static void __exit nonstatic_sysfs_exit(void)
1138{
1139 class_interface_unregister(&pccard_rsrc_interface);
1140}
1141
1142module_init(nonstatic_sysfs_init);
1143module_exit(nonstatic_sysfs_exit);