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