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