• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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>
27 
28 #include <asm/irq.h>
29 #include <asm/io.h>
30 
31 #include <pcmcia/cs_types.h>
32 #include <pcmcia/ss.h>
33 #include <pcmcia/cs.h>
34 #include <pcmcia/cistpl.h>
35 #include "cs_internal.h"
36 
37 MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
38 MODULE_LICENSE("GPL");
39 
40 /* Parameters that can be set with 'insmod' */
41 
42 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
43 
44 INT_MODULE_PARM(probe_mem,	1);		/* memory probe? */
45 #ifdef CONFIG_PCMCIA_PROBE
46 INT_MODULE_PARM(probe_io,	1);		/* IO port probe? */
47 INT_MODULE_PARM(mem_limit,	0x10000);
48 #endif
49 
50 /* for io_db and mem_db */
51 struct resource_map {
52 	u_long			base, num;
53 	struct resource_map	*next;
54 };
55 
56 struct socket_data {
57 	struct resource_map		mem_db;
58 	struct resource_map		io_db;
59 	unsigned int			rsrc_mem_probe;
60 };
61 
62 static DEFINE_MUTEX(rsrc_mutex);
63 #define MEM_PROBE_LOW	(1 << 0)
64 #define MEM_PROBE_HIGH	(1 << 1)
65 
66 
67 /*======================================================================
68 
69     Linux resource management extensions
70 
71 ======================================================================*/
72 
73 static struct resource *
make_resource(resource_size_t b,resource_size_t n,int flags,const char * name)74 make_resource(resource_size_t b, resource_size_t n, int flags, const char *name)
75 {
76 	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
77 
78 	if (res) {
79 		res->name = name;
80 		res->start = b;
81 		res->end = b + n - 1;
82 		res->flags = flags;
83 	}
84 	return res;
85 }
86 
87 static struct resource *
claim_region(struct pcmcia_socket * s,resource_size_t base,resource_size_t size,int type,char * name)88 claim_region(struct pcmcia_socket *s, resource_size_t base,
89 		resource_size_t size, int type, char *name)
90 {
91 	struct resource *res, *parent;
92 
93 	parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
94 	res = make_resource(base, size, type | IORESOURCE_BUSY, name);
95 
96 	if (res) {
97 #ifdef CONFIG_PCI
98 		if (s && s->cb_dev)
99 			parent = pci_find_parent_resource(s->cb_dev, res);
100 #endif
101 		if (!parent || request_resource(parent, res)) {
102 			kfree(res);
103 			res = NULL;
104 		}
105 	}
106 	return res;
107 }
108 
free_region(struct resource * res)109 static void free_region(struct resource *res)
110 {
111 	if (res) {
112 		release_resource(res);
113 		kfree(res);
114 	}
115 }
116 
117 /*======================================================================
118 
119     These manage the internal databases of available resources.
120 
121 ======================================================================*/
122 
add_interval(struct resource_map * map,u_long base,u_long num)123 static int add_interval(struct resource_map *map, u_long base, u_long num)
124 {
125 	struct resource_map *p, *q;
126 
127 	for (p = map; ; p = p->next) {
128 		if ((p != map) && (p->base+p->num-1 >= base))
129 			return -1;
130 		if ((p->next == map) || (p->next->base > base+num-1))
131 			break;
132 	}
133 	q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
134 	if (!q) {
135 		printk(KERN_WARNING "out of memory to update resources\n");
136 		return -ENOMEM;
137 	}
138 	q->base = base; q->num = num;
139 	q->next = p->next; p->next = q;
140 	return 0;
141 }
142 
143 /*====================================================================*/
144 
sub_interval(struct resource_map * map,u_long base,u_long num)145 static int sub_interval(struct resource_map *map, u_long base, u_long num)
146 {
147     struct resource_map *p, *q;
148 
149     for (p = map; ; p = q) {
150 	q = p->next;
151 	if (q == map)
152 	    break;
153 	if ((q->base+q->num > base) && (base+num > q->base)) {
154 	    if (q->base >= base) {
155 		if (q->base+q->num <= base+num) {
156 		    /* Delete whole block */
157 		    p->next = q->next;
158 		    kfree(q);
159 		    /* don't advance the pointer yet */
160 		    q = p;
161 		} else {
162 		    /* Cut off bit from the front */
163 		    q->num = q->base + q->num - base - num;
164 		    q->base = base + num;
165 		}
166 	    } else if (q->base+q->num <= base+num) {
167 		/* Cut off bit from the end */
168 		q->num = base - q->base;
169 	    } else {
170 		/* Split the block into two pieces */
171 		p = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
172 		if (!p) {
173 		    printk(KERN_WARNING "out of memory to update resources\n");
174 		    return -ENOMEM;
175 		}
176 		p->base = base+num;
177 		p->num = q->base+q->num - p->base;
178 		q->num = base - q->base;
179 		p->next = q->next ; q->next = p;
180 	    }
181 	}
182     }
183     return 0;
184 }
185 
186 /*======================================================================
187 
188     These routines examine a region of IO or memory addresses to
189     determine what ranges might be genuinely available.
190 
191 ======================================================================*/
192 
193 #ifdef CONFIG_PCMCIA_PROBE
do_io_probe(struct pcmcia_socket * s,unsigned int base,unsigned int num)194 static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
195 			unsigned int num)
196 {
197     struct resource *res;
198     struct socket_data *s_data = s->resource_data;
199     unsigned int i, j, bad;
200     int any;
201     u_char *b, hole, most;
202 
203     dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
204 	       base, base+num-1);
205 
206     /* First, what does a floating port look like? */
207     b = kzalloc(256, GFP_KERNEL);
208     if (!b) {
209 	    dev_printk(KERN_ERR, &s->dev,
210 		   "do_io_probe: unable to kmalloc 256 bytes");
211             return;
212     }
213     for (i = base, most = 0; i < base+num; i += 8) {
214 	res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
215 	if (!res)
216 	    continue;
217 	hole = inb(i);
218 	for (j = 1; j < 8; j++)
219 	    if (inb(i+j) != hole) break;
220 	free_region(res);
221 	if ((j == 8) && (++b[hole] > b[most]))
222 	    most = hole;
223 	if (b[most] == 127) break;
224     }
225     kfree(b);
226 
227     bad = any = 0;
228     for (i = base; i < base+num; i += 8) {
229 	res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
230 	if (!res)
231 	    continue;
232 	for (j = 0; j < 8; j++)
233 	    if (inb(i+j) != most) 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)) {
250 	    printk(" nothing: probe failed.\n");
251 	    return;
252 	} else {
253 	    sub_interval(&s_data->io_db, bad, i-bad);
254 	    printk(" %#x-%#x", bad, i-1);
255 	}
256     }
257 
258     printk(any ? "\n" : " clean.\n");
259 }
260 #endif
261 
262 /*======================================================================
263 
264     This is tricky... when we set up CIS memory, we try to validate
265     the memory window space allocations.
266 
267 ======================================================================*/
268 
269 /* Validation function for cards with a valid CIS */
readable(struct pcmcia_socket * s,struct resource * res,unsigned int * count)270 static int readable(struct pcmcia_socket *s, struct resource *res,
271 		    unsigned int *count)
272 {
273 	int ret = -1;
274 
275 	s->cis_mem.res = res;
276 	s->cis_virt = ioremap(res->start, s->map_size);
277 	if (s->cis_virt) {
278 		ret = pccard_validate_cis(s, BIND_FN_ALL, count);
279 		/* invalidate mapping and CIS cache */
280 		iounmap(s->cis_virt);
281 		s->cis_virt = NULL;
282 		destroy_cis_cache(s);
283 	}
284 	s->cis_mem.res = NULL;
285 	if ((ret != 0) || (*count == 0))
286 		return 0;
287 	return 1;
288 }
289 
290 /* Validation function for simple memory cards */
checksum(struct pcmcia_socket * s,struct resource * res)291 static int checksum(struct pcmcia_socket *s, struct resource *res)
292 {
293 	pccard_mem_map map;
294 	int i, a = 0, b = -1, d;
295 	void __iomem *virt;
296 
297 	virt = ioremap(res->start, s->map_size);
298 	if (virt) {
299 		map.map = 0;
300 		map.flags = MAP_ACTIVE;
301 		map.speed = 0;
302 		map.res = res;
303 		map.card_start = 0;
304 		s->ops->set_mem_map(s, &map);
305 
306 		/* Don't bother checking every word... */
307 		for (i = 0; i < s->map_size; i += 44) {
308 			d = readl(virt+i);
309 			a += d;
310 			b &= d;
311 		}
312 
313 		map.flags = 0;
314 		s->ops->set_mem_map(s, &map);
315 
316 		iounmap(virt);
317 	}
318 
319 	return (b == -1) ? -1 : (a>>1);
320 }
321 
322 static int
cis_readable(struct pcmcia_socket * s,unsigned long base,unsigned long size)323 cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
324 {
325 	struct resource *res1, *res2;
326 	unsigned int info1, info2;
327 	int ret = 0;
328 
329 	res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
330 	res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
331 
332 	if (res1 && res2) {
333 		ret = readable(s, res1, &info1);
334 		ret += readable(s, res2, &info2);
335 	}
336 
337 	free_region(res2);
338 	free_region(res1);
339 
340 	return (ret == 2) && (info1 == info2);
341 }
342 
343 static int
checksum_match(struct pcmcia_socket * s,unsigned long base,unsigned long size)344 checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size)
345 {
346 	struct resource *res1, *res2;
347 	int a = -1, b = -1;
348 
349 	res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
350 	res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
351 
352 	if (res1 && res2) {
353 		a = checksum(s, res1);
354 		b = checksum(s, res2);
355 	}
356 
357 	free_region(res2);
358 	free_region(res1);
359 
360 	return (a == b) && (a >= 0);
361 }
362 
363 /*======================================================================
364 
365     The memory probe.  If the memory list includes a 64K-aligned block
366     below 1MB, we probe in 64K chunks, and as soon as we accumulate at
367     least mem_limit free space, we quit.
368 
369 ======================================================================*/
370 
do_mem_probe(u_long base,u_long num,struct pcmcia_socket * s)371 static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
372 {
373     struct socket_data *s_data = s->resource_data;
374     u_long i, j, bad, fail, step;
375 
376     dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
377 	       base, base+num-1);
378     bad = fail = 0;
379     step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
380     /* don't allow too large steps */
381     if (step > 0x800000)
382 	step = 0x800000;
383     /* cis_readable wants to map 2x map_size */
384     if (step < 2 * s->map_size)
385 	step = 2 * s->map_size;
386     for (i = j = base; i < base+num; i = j + step) {
387 	if (!fail) {
388 	    for (j = i; j < base+num; j += step) {
389 		if (cis_readable(s, j, step))
390 		    break;
391 	    }
392 	    fail = ((i == base) && (j == base+num));
393 	}
394 	if (fail) {
395 	    for (j = i; j < base+num; j += 2*step)
396 		if (checksum_match(s, j, step) &&
397 		    checksum_match(s, j + step, step))
398 		    break;
399 	}
400 	if (i != j) {
401 	    if (!bad) printk(" excluding");
402 	    printk(" %#05lx-%#05lx", i, j-1);
403 	    sub_interval(&s_data->mem_db, i, j-i);
404 	    bad += j-i;
405 	}
406     }
407     printk(bad ? "\n" : " clean.\n");
408     return (num - bad);
409 }
410 
411 #ifdef CONFIG_PCMCIA_PROBE
412 
inv_probe(struct resource_map * m,struct pcmcia_socket * s)413 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
414 {
415 	struct socket_data *s_data = s->resource_data;
416 	u_long ok;
417 	if (m == &s_data->mem_db)
418 		return 0;
419 	ok = inv_probe(m->next, s);
420 	if (ok) {
421 		if (m->base >= 0x100000)
422 			sub_interval(&s_data->mem_db, m->base, m->num);
423 		return ok;
424 	}
425 	if (m->base < 0x100000)
426 		return 0;
427 	return do_mem_probe(m->base, m->num, s);
428 }
429 
validate_mem(struct pcmcia_socket * s,unsigned int probe_mask)430 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
431 {
432 	struct resource_map *m, mm;
433 	static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
434 	unsigned long b, i, ok = 0;
435 	struct socket_data *s_data = s->resource_data;
436 
437 	/* We do up to four passes through the list */
438 	if (probe_mask & MEM_PROBE_HIGH) {
439 		if (inv_probe(s_data->mem_db.next, s) > 0)
440 			return 0;
441 		dev_printk(KERN_NOTICE, &s->dev,
442 			   "cs: warning: no high memory space available!\n");
443 		return -ENODEV;
444 	}
445 
446 	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
447 		mm = *m;
448 		/* Only probe < 1 MB */
449 		if (mm.base >= 0x100000)
450 			continue;
451 		if ((mm.base | mm.num) & 0xffff) {
452 			ok += do_mem_probe(mm.base, mm.num, s);
453 			continue;
454 		}
455 		/* Special probe for 64K-aligned block */
456 		for (i = 0; i < 4; i++) {
457 			b = order[i] << 12;
458 			if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
459 				if (ok >= mem_limit)
460 					sub_interval(&s_data->mem_db, b, 0x10000);
461 				else
462 					ok += do_mem_probe(b, 0x10000, s);
463 			}
464 		}
465 	}
466 
467 	if (ok > 0)
468 		return 0;
469 
470 	return -ENODEV;
471 }
472 
473 #else /* CONFIG_PCMCIA_PROBE */
474 
validate_mem(struct pcmcia_socket * s,unsigned int probe_mask)475 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
476 {
477 	struct resource_map *m, mm;
478 	struct socket_data *s_data = s->resource_data;
479 	unsigned long ok = 0;
480 
481 	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
482 		mm = *m;
483 		ok += do_mem_probe(mm.base, mm.num, s);
484 	}
485 	if (ok > 0)
486 		return 0;
487 	return -ENODEV;
488 }
489 
490 #endif /* CONFIG_PCMCIA_PROBE */
491 
492 
493 /*
494  * Locking note: Must be called with skt_mutex held!
495  */
pcmcia_nonstatic_validate_mem(struct pcmcia_socket * s)496 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
497 {
498 	struct socket_data *s_data = s->resource_data;
499 	unsigned int probe_mask = MEM_PROBE_LOW;
500 	int ret = 0;
501 
502 	if (!probe_mem)
503 		return 0;
504 
505 	mutex_lock(&rsrc_mutex);
506 
507 	if (s->features & SS_CAP_PAGE_REGS)
508 		probe_mask = MEM_PROBE_HIGH;
509 
510 	if (probe_mask & ~s_data->rsrc_mem_probe) {
511 		if (s->state & SOCKET_PRESENT)
512 			ret = validate_mem(s, probe_mask);
513 		if (!ret)
514 			s_data->rsrc_mem_probe |= probe_mask;
515 	}
516 
517 	mutex_unlock(&rsrc_mutex);
518 
519 	return ret;
520 }
521 
522 struct pcmcia_align_data {
523 	unsigned long	mask;
524 	unsigned long	offset;
525 	struct resource_map	*map;
526 };
527 
528 static void
pcmcia_common_align(void * align_data,struct resource * res,resource_size_t size,resource_size_t align)529 pcmcia_common_align(void *align_data, struct resource *res,
530 			resource_size_t size, resource_size_t align)
531 {
532 	struct pcmcia_align_data *data = align_data;
533 	resource_size_t start;
534 	/*
535 	 * Ensure that we have the correct start address
536 	 */
537 	start = (res->start & ~data->mask) + data->offset;
538 	if (start < res->start)
539 		start += data->mask + 1;
540 	res->start = start;
541 }
542 
543 static void
pcmcia_align(void * align_data,struct resource * res,resource_size_t size,resource_size_t align)544 pcmcia_align(void *align_data, struct resource *res, resource_size_t size,
545 		resource_size_t align)
546 {
547 	struct pcmcia_align_data *data = align_data;
548 	struct resource_map *m;
549 
550 	pcmcia_common_align(data, res, size, align);
551 
552 	for (m = data->map->next; m != data->map; m = m->next) {
553 		unsigned long start = m->base;
554 		unsigned long end = m->base + m->num - 1;
555 
556 		/*
557 		 * If the lower resources are not available, try aligning
558 		 * to this entry of the resource database to see if it'll
559 		 * fit here.
560 		 */
561 		if (res->start < start) {
562 			res->start = start;
563 			pcmcia_common_align(data, res, size, align);
564 		}
565 
566 		/*
567 		 * If we're above the area which was passed in, there's
568 		 * no point proceeding.
569 		 */
570 		if (res->start >= res->end)
571 			break;
572 
573 		if ((res->start + size - 1) <= end)
574 			break;
575 	}
576 
577 	/*
578 	 * If we failed to find something suitable, ensure we fail.
579 	 */
580 	if (m == data->map)
581 		res->start = res->end;
582 }
583 
584 /*
585  * Adjust an existing IO region allocation, but making sure that we don't
586  * encroach outside the resources which the user supplied.
587  */
nonstatic_adjust_io_region(struct resource * res,unsigned long r_start,unsigned long r_end,struct pcmcia_socket * s)588 static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
589 				      unsigned long r_end, struct pcmcia_socket *s)
590 {
591 	struct resource_map *m;
592 	struct socket_data *s_data = s->resource_data;
593 	int ret = -ENOMEM;
594 
595 	mutex_lock(&rsrc_mutex);
596 	for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
597 		unsigned long start = m->base;
598 		unsigned long end = m->base + m->num - 1;
599 
600 		if (start > r_start || r_end > end)
601 			continue;
602 
603 		ret = adjust_resource(res, r_start, r_end - r_start + 1);
604 		break;
605 	}
606 	mutex_unlock(&rsrc_mutex);
607 
608 	return ret;
609 }
610 
611 /*======================================================================
612 
613     These find ranges of I/O ports or memory addresses that are not
614     currently allocated by other devices.
615 
616     The 'align' field should reflect the number of bits of address
617     that need to be preserved from the initial value of *base.  It
618     should be a power of two, greater than or equal to 'num'.  A value
619     of 0 means that all bits of *base are significant.  *base should
620     also be strictly less than 'align'.
621 
622 ======================================================================*/
623 
nonstatic_find_io_region(unsigned long base,int num,unsigned long align,struct pcmcia_socket * s)624 static struct resource *nonstatic_find_io_region(unsigned long base, int num,
625 		   unsigned long align, struct pcmcia_socket *s)
626 {
627 	struct resource *res = make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev));
628 	struct socket_data *s_data = s->resource_data;
629 	struct pcmcia_align_data data;
630 	unsigned long min = base;
631 	int ret;
632 
633 	if (align == 0)
634 		align = 0x10000;
635 
636 	data.mask = align - 1;
637 	data.offset = base & data.mask;
638 	data.map = &s_data->io_db;
639 
640 	mutex_lock(&rsrc_mutex);
641 #ifdef CONFIG_PCI
642 	if (s->cb_dev) {
643 		ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
644 					     min, 0, pcmcia_align, &data);
645 	} else
646 #endif
647 		ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
648 					1, pcmcia_align, &data);
649 	mutex_unlock(&rsrc_mutex);
650 
651 	if (ret != 0) {
652 		kfree(res);
653 		res = NULL;
654 	}
655 	return res;
656 }
657 
nonstatic_find_mem_region(u_long base,u_long num,u_long align,int low,struct pcmcia_socket * s)658 static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
659 		u_long align, int low, struct pcmcia_socket *s)
660 {
661 	struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev));
662 	struct socket_data *s_data = s->resource_data;
663 	struct pcmcia_align_data data;
664 	unsigned long min, max;
665 	int ret, i;
666 
667 	low = low || !(s->features & SS_CAP_PAGE_REGS);
668 
669 	data.mask = align - 1;
670 	data.offset = base & data.mask;
671 	data.map = &s_data->mem_db;
672 
673 	for (i = 0; i < 2; i++) {
674 		if (low) {
675 			max = 0x100000UL;
676 			min = base < max ? base : 0;
677 		} else {
678 			max = ~0UL;
679 			min = 0x100000UL + base;
680 		}
681 
682 		mutex_lock(&rsrc_mutex);
683 #ifdef CONFIG_PCI
684 		if (s->cb_dev) {
685 			ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
686 						     1, min, 0,
687 						     pcmcia_align, &data);
688 		} else
689 #endif
690 			ret = allocate_resource(&iomem_resource, res, num, min,
691 						max, 1, pcmcia_align, &data);
692 		mutex_unlock(&rsrc_mutex);
693 		if (ret == 0 || low)
694 			break;
695 		low = 1;
696 	}
697 
698 	if (ret != 0) {
699 		kfree(res);
700 		res = NULL;
701 	}
702 	return res;
703 }
704 
705 
adjust_memory(struct pcmcia_socket * s,unsigned int action,unsigned long start,unsigned long end)706 static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
707 {
708 	struct socket_data *data = s->resource_data;
709 	unsigned long size = end - start + 1;
710 	int ret = 0;
711 
712 	if (end < start)
713 		return -EINVAL;
714 
715 	mutex_lock(&rsrc_mutex);
716 	switch (action) {
717 	case ADD_MANAGED_RESOURCE:
718 		ret = add_interval(&data->mem_db, start, size);
719 		break;
720 	case REMOVE_MANAGED_RESOURCE:
721 		ret = sub_interval(&data->mem_db, start, size);
722 		if (!ret) {
723 			struct pcmcia_socket *socket;
724 			down_read(&pcmcia_socket_list_rwsem);
725 			list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
726 				release_cis_mem(socket);
727 			up_read(&pcmcia_socket_list_rwsem);
728 		}
729 		break;
730 	default:
731 		ret = -EINVAL;
732 	}
733 	mutex_unlock(&rsrc_mutex);
734 
735 	return ret;
736 }
737 
738 
adjust_io(struct pcmcia_socket * s,unsigned int action,unsigned long start,unsigned long end)739 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
740 {
741 	struct socket_data *data = s->resource_data;
742 	unsigned long size = end - start + 1;
743 	int ret = 0;
744 
745 	if (end < start)
746 		return -EINVAL;
747 
748 	if (end > IO_SPACE_LIMIT)
749 		return -EINVAL;
750 
751 	mutex_lock(&rsrc_mutex);
752 	switch (action) {
753 	case ADD_MANAGED_RESOURCE:
754 		if (add_interval(&data->io_db, start, size) != 0) {
755 			ret = -EBUSY;
756 			break;
757 		}
758 #ifdef CONFIG_PCMCIA_PROBE
759 		if (probe_io)
760 			do_io_probe(s, start, size);
761 #endif
762 		break;
763 	case REMOVE_MANAGED_RESOURCE:
764 		sub_interval(&data->io_db, start, size);
765 		break;
766 	default:
767 		ret = -EINVAL;
768 		break;
769 	}
770 	mutex_unlock(&rsrc_mutex);
771 
772 	return ret;
773 }
774 
775 
776 #ifdef CONFIG_PCI
nonstatic_autoadd_resources(struct pcmcia_socket * s)777 static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
778 {
779 	struct resource *res;
780 	int i, done = 0;
781 
782 	if (!s->cb_dev || !s->cb_dev->bus)
783 		return -ENODEV;
784 
785 #if defined(CONFIG_X86)
786 	/* If this is the root bus, the risk of hitting
787 	 * some strange system devices which aren't protected
788 	 * by either ACPI resource tables or properly requested
789 	 * resources is too big. Therefore, don't do auto-adding
790 	 * of resources at the moment.
791 	 */
792 	if (s->cb_dev->bus->number == 0)
793 		return -EINVAL;
794 #endif
795 
796 	for (i=0; i < PCI_BUS_NUM_RESOURCES; i++) {
797 		res = s->cb_dev->bus->resource[i];
798 		if (!res)
799 			continue;
800 
801 		if (res->flags & IORESOURCE_IO) {
802 			if (res == &ioport_resource)
803 				continue;
804 			dev_printk(KERN_INFO, &s->cb_dev->dev,
805 				   "pcmcia: parent PCI bridge I/O "
806 				   "window: 0x%llx - 0x%llx\n",
807 				   (unsigned long long)res->start,
808 				   (unsigned long long)res->end);
809 			if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
810 				done |= IORESOURCE_IO;
811 
812 		}
813 
814 		if (res->flags & IORESOURCE_MEM) {
815 			if (res == &iomem_resource)
816 				continue;
817 			dev_printk(KERN_INFO, &s->cb_dev->dev,
818 				   "pcmcia: parent PCI bridge Memory "
819 				   "window: 0x%llx - 0x%llx\n",
820 				   (unsigned long long)res->start,
821 				   (unsigned long long)res->end);
822 			if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
823 				done |= IORESOURCE_MEM;
824 		}
825 	}
826 
827 	/* if we got at least one of IO, and one of MEM, we can be glad and
828 	 * activate the PCMCIA subsystem */
829 	if (done == (IORESOURCE_MEM | IORESOURCE_IO))
830 		s->resource_setup_done = 1;
831 
832 	return 0;
833 }
834 
835 #else
836 
nonstatic_autoadd_resources(struct pcmcia_socket * s)837 static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
838 {
839 	return -ENODEV;
840 }
841 
842 #endif
843 
844 
nonstatic_init(struct pcmcia_socket * s)845 static int nonstatic_init(struct pcmcia_socket *s)
846 {
847 	struct socket_data *data;
848 
849 	data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
850 	if (!data)
851 		return -ENOMEM;
852 
853 	data->mem_db.next = &data->mem_db;
854 	data->io_db.next = &data->io_db;
855 
856 	s->resource_data = (void *) data;
857 
858 	nonstatic_autoadd_resources(s);
859 
860 	return 0;
861 }
862 
nonstatic_release_resource_db(struct pcmcia_socket * s)863 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
864 {
865 	struct socket_data *data = s->resource_data;
866 	struct resource_map *p, *q;
867 
868 	mutex_lock(&rsrc_mutex);
869 	for (p = data->mem_db.next; p != &data->mem_db; p = q) {
870 		q = p->next;
871 		kfree(p);
872 	}
873 	for (p = data->io_db.next; p != &data->io_db; p = q) {
874 		q = p->next;
875 		kfree(p);
876 	}
877 	mutex_unlock(&rsrc_mutex);
878 }
879 
880 
881 struct pccard_resource_ops pccard_nonstatic_ops = {
882 	.validate_mem = pcmcia_nonstatic_validate_mem,
883 	.adjust_io_region = nonstatic_adjust_io_region,
884 	.find_io = nonstatic_find_io_region,
885 	.find_mem = nonstatic_find_mem_region,
886 	.add_io = adjust_io,
887 	.add_mem = adjust_memory,
888 	.init = nonstatic_init,
889 	.exit = nonstatic_release_resource_db,
890 };
891 EXPORT_SYMBOL(pccard_nonstatic_ops);
892 
893 
894 /* sysfs interface to the resource database */
895 
show_io_db(struct device * dev,struct device_attribute * attr,char * buf)896 static ssize_t show_io_db(struct device *dev,
897 			  struct device_attribute *attr, char *buf)
898 {
899 	struct pcmcia_socket *s = dev_get_drvdata(dev);
900 	struct socket_data *data;
901 	struct resource_map *p;
902 	ssize_t ret = 0;
903 
904 	mutex_lock(&rsrc_mutex);
905 	data = s->resource_data;
906 
907 	for (p = data->io_db.next; p != &data->io_db; p = p->next) {
908 		if (ret > (PAGE_SIZE - 10))
909 			continue;
910 		ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
911 				 "0x%08lx - 0x%08lx\n",
912 				 ((unsigned long) p->base),
913 				 ((unsigned long) p->base + p->num - 1));
914 	}
915 
916 	mutex_unlock(&rsrc_mutex);
917 	return (ret);
918 }
919 
store_io_db(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)920 static ssize_t store_io_db(struct device *dev,
921 			   struct device_attribute *attr,
922 			   const char *buf, size_t count)
923 {
924 	struct pcmcia_socket *s = dev_get_drvdata(dev);
925 	unsigned long start_addr, end_addr;
926 	unsigned int add = ADD_MANAGED_RESOURCE;
927 	ssize_t ret = 0;
928 
929 	ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
930 	if (ret != 2) {
931 		ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
932 		add = REMOVE_MANAGED_RESOURCE;
933 		if (ret != 2) {
934 			ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
935 			add = ADD_MANAGED_RESOURCE;
936 			if (ret != 2)
937 				return -EINVAL;
938 		}
939 	}
940 	if (end_addr < start_addr)
941 		return -EINVAL;
942 
943 	ret = adjust_io(s, add, start_addr, end_addr);
944 	if (!ret)
945 		s->resource_setup_new = 1;
946 
947 	return ret ? ret : count;
948 }
949 static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
950 
show_mem_db(struct device * dev,struct device_attribute * attr,char * buf)951 static ssize_t show_mem_db(struct device *dev,
952 			   struct device_attribute *attr, char *buf)
953 {
954 	struct pcmcia_socket *s = dev_get_drvdata(dev);
955 	struct socket_data *data;
956 	struct resource_map *p;
957 	ssize_t ret = 0;
958 
959 	mutex_lock(&rsrc_mutex);
960 	data = s->resource_data;
961 
962 	for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
963 		if (ret > (PAGE_SIZE - 10))
964 			continue;
965 		ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
966 				 "0x%08lx - 0x%08lx\n",
967 				 ((unsigned long) p->base),
968 				 ((unsigned long) p->base + p->num - 1));
969 	}
970 
971 	mutex_unlock(&rsrc_mutex);
972 	return (ret);
973 }
974 
store_mem_db(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)975 static ssize_t store_mem_db(struct device *dev,
976 			    struct device_attribute *attr,
977 			    const char *buf, size_t count)
978 {
979 	struct pcmcia_socket *s = dev_get_drvdata(dev);
980 	unsigned long start_addr, end_addr;
981 	unsigned int add = ADD_MANAGED_RESOURCE;
982 	ssize_t ret = 0;
983 
984 	ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
985 	if (ret != 2) {
986 		ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
987 		add = REMOVE_MANAGED_RESOURCE;
988 		if (ret != 2) {
989 			ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
990 			add = ADD_MANAGED_RESOURCE;
991 			if (ret != 2)
992 				return -EINVAL;
993 		}
994 	}
995 	if (end_addr < start_addr)
996 		return -EINVAL;
997 
998 	ret = adjust_memory(s, add, start_addr, end_addr);
999 	if (!ret)
1000 		s->resource_setup_new = 1;
1001 
1002 	return ret ? ret : count;
1003 }
1004 static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1005 
1006 static struct attribute *pccard_rsrc_attributes[] = {
1007 	&dev_attr_available_resources_io.attr,
1008 	&dev_attr_available_resources_mem.attr,
1009 	NULL,
1010 };
1011 
1012 static const struct attribute_group rsrc_attributes = {
1013 	.attrs = pccard_rsrc_attributes,
1014 };
1015 
pccard_sysfs_add_rsrc(struct device * dev,struct class_interface * class_intf)1016 static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
1017 					   struct class_interface *class_intf)
1018 {
1019 	struct pcmcia_socket *s = dev_get_drvdata(dev);
1020 
1021 	if (s->resource_ops != &pccard_nonstatic_ops)
1022 		return 0;
1023 	return sysfs_create_group(&dev->kobj, &rsrc_attributes);
1024 }
1025 
pccard_sysfs_remove_rsrc(struct device * dev,struct class_interface * class_intf)1026 static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
1027 					       struct class_interface *class_intf)
1028 {
1029 	struct pcmcia_socket *s = dev_get_drvdata(dev);
1030 
1031 	if (s->resource_ops != &pccard_nonstatic_ops)
1032 		return;
1033 	sysfs_remove_group(&dev->kobj, &rsrc_attributes);
1034 }
1035 
1036 static struct class_interface pccard_rsrc_interface __refdata = {
1037 	.class = &pcmcia_socket_class,
1038 	.add_dev = &pccard_sysfs_add_rsrc,
1039 	.remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
1040 };
1041 
nonstatic_sysfs_init(void)1042 static int __init nonstatic_sysfs_init(void)
1043 {
1044 	return class_interface_register(&pccard_rsrc_interface);
1045 }
1046 
nonstatic_sysfs_exit(void)1047 static void __exit nonstatic_sysfs_exit(void)
1048 {
1049 	class_interface_unregister(&pccard_rsrc_interface);
1050 }
1051 
1052 module_init(nonstatic_sysfs_init);
1053 module_exit(nonstatic_sysfs_exit);
1054