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