]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/pcmcia/rsrc_nonstatic.c
pcmcia: remove cs_types.h
[karo-tx-linux.git] / drivers / pcmcia / rsrc_nonstatic.c
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 #include <linux/io.h>
28
29 #include <asm/irq.h>
30
31 #include <pcmcia/ss.h>
32 #include <pcmcia/cs.h>
33 #include <pcmcia/cistpl.h>
34 #include "cs_internal.h"
35
36 /* moved to rsrc_mgr.c
37 MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
38 MODULE_LICENSE("GPL");
39 */
40
41 /* Parameters that can be set with 'insmod' */
42
43 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
44
45 INT_MODULE_PARM(probe_mem,      1);             /* memory probe? */
46 #ifdef CONFIG_PCMCIA_PROBE
47 INT_MODULE_PARM(probe_io,       1);             /* IO port probe? */
48 INT_MODULE_PARM(mem_limit,      0x10000);
49 #endif
50
51 /* for io_db and mem_db */
52 struct resource_map {
53         u_long                  base, num;
54         struct resource_map     *next;
55 };
56
57 struct socket_data {
58         struct resource_map             mem_db;
59         struct resource_map             mem_db_valid;
60         struct resource_map             io_db;
61 };
62
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 *
74 claim_region(struct pcmcia_socket *s, resource_size_t base,
75                 resource_size_t size, int type, char *name)
76 {
77         struct resource *res, *parent;
78
79         parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
80         res = pcmcia_make_resource(base, size, type | IORESOURCE_BUSY, name);
81
82         if (res) {
83 #ifdef CONFIG_PCI
84                 if (s && s->cb_dev)
85                         parent = pci_find_parent_resource(s->cb_dev, res);
86 #endif
87                 if (!parent || request_resource(parent, res)) {
88                         kfree(res);
89                         res = NULL;
90                 }
91         }
92         return res;
93 }
94
95 static void free_region(struct resource *res)
96 {
97         if (res) {
98                 release_resource(res);
99                 kfree(res);
100         }
101 }
102
103 /*======================================================================
104
105     These manage the internal databases of available resources.
106
107 ======================================================================*/
108
109 static int add_interval(struct resource_map *map, u_long base, u_long num)
110 {
111         struct resource_map *p, *q;
112
113         for (p = map; ; p = p->next) {
114                 if ((p != map) && (p->base+p->num >= base)) {
115                         p->num = max(num + base - p->base, p->num);
116                         return 0;
117                 }
118                 if ((p->next == map) || (p->next->base > base+num-1))
119                         break;
120         }
121         q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
122         if (!q) {
123                 printk(KERN_WARNING "out of memory to update resources\n");
124                 return -ENOMEM;
125         }
126         q->base = base; q->num = num;
127         q->next = p->next; p->next = q;
128         return 0;
129 }
130
131 /*====================================================================*/
132
133 static int sub_interval(struct resource_map *map, u_long base, u_long num)
134 {
135         struct resource_map *p, *q;
136
137         for (p = map; ; p = q) {
138                 q = p->next;
139                 if (q == map)
140                         break;
141                 if ((q->base+q->num > base) && (base+num > q->base)) {
142                         if (q->base >= base) {
143                                 if (q->base+q->num <= base+num) {
144                                         /* Delete whole block */
145                                         p->next = q->next;
146                                         kfree(q);
147                                         /* don't advance the pointer yet */
148                                         q = p;
149                                 } else {
150                                         /* Cut off bit from the front */
151                                         q->num = q->base + q->num - base - num;
152                                         q->base = base + num;
153                                 }
154                         } else if (q->base+q->num <= base+num) {
155                                 /* Cut off bit from the end */
156                                 q->num = base - q->base;
157                         } else {
158                                 /* Split the block into two pieces */
159                                 p = kmalloc(sizeof(struct resource_map),
160                                         GFP_KERNEL);
161                                 if (!p) {
162                                         printk(KERN_WARNING "out of memory to update resources\n");
163                                         return -ENOMEM;
164                                 }
165                                 p->base = base+num;
166                                 p->num = q->base+q->num - p->base;
167                                 q->num = base - q->base;
168                                 p->next = q->next ; q->next = p;
169                         }
170                 }
171         }
172         return 0;
173 }
174
175 /*======================================================================
176
177     These routines examine a region of IO or memory addresses to
178     determine what ranges might be genuinely available.
179
180 ======================================================================*/
181
182 #ifdef CONFIG_PCMCIA_PROBE
183 static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
184                         unsigned int num)
185 {
186         struct resource *res;
187         struct socket_data *s_data = s->resource_data;
188         unsigned int i, j, bad;
189         int any;
190         u_char *b, hole, most;
191
192         dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
193                 base, base+num-1);
194
195         /* First, what does a floating port look like? */
196         b = kzalloc(256, GFP_KERNEL);
197         if (!b) {
198                 printk("\n");
199                 dev_printk(KERN_ERR, &s->dev,
200                         "do_io_probe: unable to kmalloc 256 bytes");
201                 return;
202         }
203         for (i = base, most = 0; i < base+num; i += 8) {
204                 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
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) {
221                 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
222                 if (!res) {
223                         if (!any)
224                                 printk(" excluding");
225                         if (!bad)
226                                 bad = any = i;
227                         continue;
228                 }
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)
235                                 printk(" excluding");
236                         if (!bad)
237                                 bad = any = i;
238                 } else {
239                         if (bad) {
240                                 sub_interval(&s_data->io_db, bad, i-bad);
241                                 printk(" %#x-%#x", bad, i-1);
242                                 bad = 0;
243                         }
244                 }
245         }
246         if (bad) {
247                 if ((num > 16) && (bad == base) && (i == base+num)) {
248                         sub_interval(&s_data->io_db, bad, i-bad);
249                         printk(" nothing: probe failed.\n");
250                         return;
251                 } else {
252                         sub_interval(&s_data->io_db, bad, i-bad);
253                         printk(" %#x-%#x", bad, i-1);
254                 }
255         }
256
257         printk(any ? "\n" : " clean.\n");
258 }
259 #endif
260
261 /*======================================================================*/
262
263 /**
264  * readable() - iomem validation function for cards with a valid CIS
265  */
266 static int readable(struct pcmcia_socket *s, struct resource *res,
267                     unsigned int *count)
268 {
269         int ret = -EINVAL;
270
271         if (s->fake_cis) {
272                 dev_dbg(&s->dev, "fake CIS is being used: can't validate mem\n");
273                 return 0;
274         }
275
276         s->cis_mem.res = res;
277         s->cis_virt = ioremap(res->start, s->map_size);
278         if (s->cis_virt) {
279                 mutex_unlock(&s->ops_mutex);
280                 /* as we're only called from pcmcia.c, we're safe */
281                 if (s->callback->validate)
282                         ret = s->callback->validate(s, count);
283                 /* invalidate mapping */
284                 mutex_lock(&s->ops_mutex);
285                 iounmap(s->cis_virt);
286                 s->cis_virt = NULL;
287         }
288         s->cis_mem.res = NULL;
289         if ((ret) || (*count == 0))
290                 return -EINVAL;
291         return 0;
292 }
293
294 /**
295  * checksum() - iomem validation function for simple memory cards
296  */
297 static int checksum(struct pcmcia_socket *s, struct resource *res,
298                     unsigned int *value)
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
326         if (b == -1)
327                 return -EINVAL;
328
329         *value = a;
330
331         return 0;
332 }
333
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  */
347 static 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))
352 {
353         struct socket_data *s_data = s->resource_data;
354         struct resource *res1, *res2;
355         unsigned int info1 = 1, info2 = 1;
356         int ret = -EINVAL;
357
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");
361
362         if (res1 && res2) {
363                 ret = 0;
364                 if (validate) {
365                         ret = validate(s, res1, &info1);
366                         ret += validate(s, res2, &info2);
367                 }
368         }
369
370         free_region(res2);
371         free_region(res1);
372
373         dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
374                 base, base+size-1, res1, res2, ret, info1, info2);
375
376         if ((ret) || (info1 != info2) || (info1 == 0))
377                 return -EINVAL;
378
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);
383         }
384
385         return 0;
386 }
387
388
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  */
403 static 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))
410 {
411         struct socket_data *s_data = s->resource_data;
412         u_long i, j, bad, fail, step;
413
414         dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
415                 base, base+num-1);
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) {
427                                 if (!do_validate_mem(s, j, step, validate))
428                                         break;
429                         }
430                         fail = ((i == base) && (j == base+num));
431                 }
432                 if ((fail) && (fallback)) {
433                         for (j = i; j < base+num; j += step)
434                                 if (!do_validate_mem(s, j, step, fallback))
435                                         break;
436                 }
437                 if (i != j) {
438                         if (!bad)
439                                 printk(" excluding");
440                         printk(" %#05lx-%#05lx", i, j-1);
441                         sub_interval(&s_data->mem_db, i, j-i);
442                         bad += j-i;
443                 }
444         }
445         printk(bad ? "\n" : " clean.\n");
446         return num - bad;
447 }
448
449
450 #ifdef CONFIG_PCMCIA_PROBE
451
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  */
457 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
458 {
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;
471         return do_mem_probe(s, m->base, m->num, readable, checksum);
472 }
473
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  */
483 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
484 {
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;
489
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;
494                 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
495                         return 0;
496                 dev_printk(KERN_NOTICE, &s->dev,
497                            "cs: warning: no high memory space available!\n");
498                 return -ENODEV;
499         }
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) {
507                         ok += do_mem_probe(s, mm.base, mm.num, readable,
508                                            checksum);
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
518                                         ok += do_mem_probe(s, b, 0x10000,
519                                                            readable, checksum);
520                         }
521                 }
522         }
523
524         if (ok > 0)
525                 return 0;
526
527         return -ENODEV;
528 }
529
530 #else /* CONFIG_PCMCIA_PROBE */
531
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  */
539 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
540 {
541         struct resource_map *m, mm;
542         struct socket_data *s_data = s->resource_data;
543         unsigned long ok = 0;
544
545         for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
546                 mm = *m;
547                 ok += do_mem_probe(s, mm.base, mm.num, readable, checksum);
548         }
549         if (ok > 0)
550                 return 0;
551         return -ENODEV;
552 }
553
554 #endif /* CONFIG_PCMCIA_PROBE */
555
556
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  *
564  * Locking note: Must be called with skt_mutex held!
565  */
566 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
567 {
568         struct socket_data *s_data = s->resource_data;
569         unsigned int probe_mask = MEM_PROBE_LOW;
570         int ret;
571
572         if (!probe_mem || !(s->state & SOCKET_PRESENT))
573                 return 0;
574
575         if (s->features & SS_CAP_PAGE_REGS)
576                 probe_mask = MEM_PROBE_HIGH;
577
578         ret = validate_mem(s, probe_mask);
579
580         if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
581                 return 0;
582
583         return ret;
584 }
585
586 struct pcmcia_align_data {
587         unsigned long   mask;
588         unsigned long   offset;
589         struct resource_map     *map;
590 };
591
592 static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data,
593                                         resource_size_t start)
594 {
595         resource_size_t ret;
596         /*
597          * Ensure that we have the correct start address
598          */
599         ret = (start & ~align_data->mask) + align_data->offset;
600         if (ret < start)
601                 ret += align_data->mask + 1;
602         return ret;
603 }
604
605 static resource_size_t
606 pcmcia_align(void *align_data, const struct resource *res,
607         resource_size_t size, resource_size_t align)
608 {
609         struct pcmcia_align_data *data = align_data;
610         struct resource_map *m;
611         resource_size_t start;
612
613         start = pcmcia_common_align(data, res->start);
614
615         for (m = data->map->next; m != data->map; m = m->next) {
616                 unsigned long map_start = m->base;
617                 unsigned long map_end = m->base + m->num - 1;
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                  */
624                 if (start < map_start)
625                         start = pcmcia_common_align(data, map_start);
626
627                 /*
628                  * If we're above the area which was passed in, there's
629                  * no point proceeding.
630                  */
631                 if (start >= res->end)
632                         break;
633
634                 if ((start + size - 1) <= map_end)
635                         break;
636         }
637
638         /*
639          * If we failed to find something suitable, ensure we fail.
640          */
641         if (m == data->map)
642                 start = res->end;
643
644         return start;
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  */
651 static int __nonstatic_adjust_io_region(struct pcmcia_socket *s,
652                                         unsigned long r_start,
653                                         unsigned long r_end)
654 {
655         struct resource_map *m;
656         struct socket_data *s_data = s->resource_data;
657         int ret = -ENOMEM;
658
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
666                 ret = 0;
667         }
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
685 static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s,
686                                                 unsigned long base, int num,
687                                                 unsigned long align)
688 {
689         struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO,
690                                                 dev_name(&s->dev));
691         struct socket_data *s_data = s->resource_data;
692         struct pcmcia_align_data data;
693         unsigned long min = base;
694         int ret;
695
696         data.mask = align - 1;
697         data.offset = base & data.mask;
698         data.map = &s_data->io_db;
699
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);
708
709         if (ret != 0) {
710                 kfree(res);
711                 res = NULL;
712         }
713         return res;
714 }
715
716 static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
717                         unsigned int *base, unsigned int num,
718                         unsigned int align)
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;
760                         return 0;
761                 }
762
763                 /* Try to extend top of window */
764                 try = res->end + 1;
765                 if ((*base == 0) || (*base == try)) {
766                         ret =  __nonstatic_adjust_io_region(s, res->start,
767                                                         res->end + num);
768                         if (!ret) {
769                                 ret = adjust_resource(s->io[i].res, res->start,
770                                                res->end - res->start + num + 1);
771                                 if (ret)
772                                         continue;
773                                 *base = try;
774                                 s->io[i].InUse += num;
775                                 return 0;
776                         }
777                 }
778
779                 /* Try to extend bottom of window */
780                 try = res->start - num;
781                 if ((*base == 0) || (*base == try)) {
782                         ret =  __nonstatic_adjust_io_region(s,
783                                                         res->start - num,
784                                                         res->end);
785                         if (!ret) {
786                                 ret = adjust_resource(s->io[i].res,
787                                                res->start - num,
788                                                res->end - res->start + num + 1);
789                                 if (ret)
790                                         continue;
791                                 *base = try;
792                                 s->io[i].InUse += num;
793                                 return 0;
794                         }
795                 }
796         }
797
798         return -EINVAL;
799 }
800
801
802 static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
803                 u_long align, int low, struct pcmcia_socket *s)
804 {
805         struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM,
806                                                 dev_name(&s->dev));
807         struct socket_data *s_data = s->resource_data;
808         struct pcmcia_align_data data;
809         unsigned long min, max;
810         int ret, i, j;
811
812         low = low || !(s->features & SS_CAP_PAGE_REGS);
813
814         data.mask = align - 1;
815         data.offset = base & data.mask;
816
817         for (i = 0; i < 2; i++) {
818                 data.map = &s_data->mem_db_valid;
819                 if (low) {
820                         max = 0x100000UL;
821                         min = base < max ? base : 0;
822                 } else {
823                         max = ~0UL;
824                         min = 0x100000UL + base;
825                 }
826
827                 for (j = 0; j < 2; j++) {
828 #ifdef CONFIG_PCI
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
834 #endif
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                 }
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
857 static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
858 {
859         struct socket_data *data = s->resource_data;
860         unsigned long size = end - start + 1;
861         int ret = 0;
862
863         if (end < start)
864                 return -EINVAL;
865
866         switch (action) {
867         case ADD_MANAGED_RESOURCE:
868                 ret = add_interval(&data->mem_db, start, size);
869                 if (!ret)
870                         do_mem_probe(s, start, size, NULL, NULL);
871                 break;
872         case REMOVE_MANAGED_RESOURCE:
873                 ret = sub_interval(&data->mem_db, start, size);
874                 break;
875         default:
876                 ret = -EINVAL;
877         }
878
879         return ret;
880 }
881
882
883 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
884 {
885         struct socket_data *data = s->resource_data;
886         unsigned long size;
887         int ret = 0;
888
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
896         size = end - start + 1;
897
898         if (end < start)
899                 return -EINVAL;
900
901         if (end > IO_SPACE_LIMIT)
902                 return -EINVAL;
903
904         switch (action) {
905         case ADD_MANAGED_RESOURCE:
906                 if (add_interval(&data->io_db, start, size) != 0) {
907                         ret = -EBUSY;
908                         break;
909                 }
910 #ifdef CONFIG_PCMCIA_PROBE
911                 if (probe_io)
912                         do_io_probe(s, start, size);
913 #endif
914                 break;
915         case REMOVE_MANAGED_RESOURCE:
916                 sub_interval(&data->io_db, start, size);
917                 break;
918         default:
919                 ret = -EINVAL;
920                 break;
921         }
922
923         return ret;
924 }
925
926
927 #ifdef CONFIG_PCI
928 static 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
936 #if defined(CONFIG_X86)
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.
954          */
955         if (s->cb_dev->bus->number == 0)
956                 return -EINVAL;
957
958         for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
959                 res = s->cb_dev->bus->resource[i];
960 #else
961         pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
962 #endif
963                 if (!res)
964                         continue;
965
966                 if (res->flags & IORESOURCE_IO) {
967                         /* safeguard against the root resource, where the
968                          * risk of hitting any other device would be too
969                          * high */
970                         if (res == &ioport_resource)
971                                 continue;
972
973                         dev_printk(KERN_INFO, &s->cb_dev->dev,
974                                    "pcmcia: parent PCI bridge window: %pR\n",
975                                    res);
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) {
982                         /* safeguard against the root resource, where the
983                          * risk of hitting any other device would be too
984                          * high */
985                         if (res == &iomem_resource)
986                                 continue;
987
988                         dev_printk(KERN_INFO, &s->cb_dev->dev,
989                                    "pcmcia: parent PCI bridge window: %pR\n",
990                                    res);
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 */
998         if (done == (IORESOURCE_MEM | IORESOURCE_IO))
999                 s->resource_setup_done = 1;
1000
1001         return 0;
1002 }
1003
1004 #else
1005
1006 static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
1007 {
1008         return -ENODEV;
1009 }
1010
1011 #endif
1012
1013
1014 static int nonstatic_init(struct pcmcia_socket *s)
1015 {
1016         struct socket_data *data;
1017
1018         data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
1019         if (!data)
1020                 return -ENOMEM;
1021
1022         data->mem_db.next = &data->mem_db;
1023         data->mem_db_valid.next = &data->mem_db_valid;
1024         data->io_db.next = &data->io_db;
1025
1026         s->resource_data = (void *) data;
1027
1028         nonstatic_autoadd_resources(s);
1029
1030         return 0;
1031 }
1032
1033 static 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
1038         for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
1039                 q = p->next;
1040                 kfree(p);
1041         }
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         }
1050 }
1051
1052
1053 struct pccard_resource_ops pccard_nonstatic_ops = {
1054         .validate_mem = pcmcia_nonstatic_validate_mem,
1055         .find_io = nonstatic_find_io,
1056         .find_mem = nonstatic_find_mem_region,
1057         .init = nonstatic_init,
1058         .exit = nonstatic_release_resource_db,
1059 };
1060 EXPORT_SYMBOL(pccard_nonstatic_ops);
1061
1062
1063 /* sysfs interface to the resource database */
1064
1065 static ssize_t show_io_db(struct device *dev,
1066                           struct device_attribute *attr, char *buf)
1067 {
1068         struct pcmcia_socket *s = dev_get_drvdata(dev);
1069         struct socket_data *data;
1070         struct resource_map *p;
1071         ssize_t ret = 0;
1072
1073         mutex_lock(&s->ops_mutex);
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;
1079                 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1080                                 "0x%08lx - 0x%08lx\n",
1081                                 ((unsigned long) p->base),
1082                                 ((unsigned long) p->base + p->num - 1));
1083         }
1084
1085         mutex_unlock(&s->ops_mutex);
1086         return ret;
1087 }
1088
1089 static ssize_t store_io_db(struct device *dev,
1090                            struct device_attribute *attr,
1091                            const char *buf, size_t count)
1092 {
1093         struct pcmcia_socket *s = dev_get_drvdata(dev);
1094         unsigned long start_addr, end_addr;
1095         unsigned int add = ADD_MANAGED_RESOURCE;
1096         ssize_t ret = 0;
1097
1098         ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1099         if (ret != 2) {
1100                 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1101                 add = REMOVE_MANAGED_RESOURCE;
1102                 if (ret != 2) {
1103                         ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1104                                 &end_addr);
1105                         add = ADD_MANAGED_RESOURCE;
1106                         if (ret != 2)
1107                                 return -EINVAL;
1108                 }
1109         }
1110         if (end_addr < start_addr)
1111                 return -EINVAL;
1112
1113         mutex_lock(&s->ops_mutex);
1114         ret = adjust_io(s, add, start_addr, end_addr);
1115         mutex_unlock(&s->ops_mutex);
1116
1117         return ret ? ret : count;
1118 }
1119 static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
1120
1121 static ssize_t show_mem_db(struct device *dev,
1122                            struct device_attribute *attr, char *buf)
1123 {
1124         struct pcmcia_socket *s = dev_get_drvdata(dev);
1125         struct socket_data *data;
1126         struct resource_map *p;
1127         ssize_t ret = 0;
1128
1129         mutex_lock(&s->ops_mutex);
1130         data = s->resource_data;
1131
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;
1136                 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1137                                 "0x%08lx - 0x%08lx\n",
1138                                 ((unsigned long) p->base),
1139                                 ((unsigned long) p->base + p->num - 1));
1140         }
1141
1142         for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
1143                 if (ret > (PAGE_SIZE - 10))
1144                         continue;
1145                 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1146                                 "0x%08lx - 0x%08lx\n",
1147                                 ((unsigned long) p->base),
1148                                 ((unsigned long) p->base + p->num - 1));
1149         }
1150
1151         mutex_unlock(&s->ops_mutex);
1152         return ret;
1153 }
1154
1155 static ssize_t store_mem_db(struct device *dev,
1156                             struct device_attribute *attr,
1157                             const char *buf, size_t count)
1158 {
1159         struct pcmcia_socket *s = dev_get_drvdata(dev);
1160         unsigned long start_addr, end_addr;
1161         unsigned int add = ADD_MANAGED_RESOURCE;
1162         ssize_t ret = 0;
1163
1164         ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1165         if (ret != 2) {
1166                 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1167                 add = REMOVE_MANAGED_RESOURCE;
1168                 if (ret != 2) {
1169                         ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1170                                 &end_addr);
1171                         add = ADD_MANAGED_RESOURCE;
1172                         if (ret != 2)
1173                                 return -EINVAL;
1174                 }
1175         }
1176         if (end_addr < start_addr)
1177                 return -EINVAL;
1178
1179         mutex_lock(&s->ops_mutex);
1180         ret = adjust_memory(s, add, start_addr, end_addr);
1181         mutex_unlock(&s->ops_mutex);
1182
1183         return ret ? ret : count;
1184 }
1185 static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1186
1187 static struct attribute *pccard_rsrc_attributes[] = {
1188         &dev_attr_available_resources_io.attr,
1189         &dev_attr_available_resources_mem.attr,
1190         NULL,
1191 };
1192
1193 static const struct attribute_group rsrc_attributes = {
1194         .attrs = pccard_rsrc_attributes,
1195 };
1196
1197 static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
1198                                            struct class_interface *class_intf)
1199 {
1200         struct pcmcia_socket *s = dev_get_drvdata(dev);
1201
1202         if (s->resource_ops != &pccard_nonstatic_ops)
1203                 return 0;
1204         return sysfs_create_group(&dev->kobj, &rsrc_attributes);
1205 }
1206
1207 static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
1208                                                struct class_interface *class_intf)
1209 {
1210         struct pcmcia_socket *s = dev_get_drvdata(dev);
1211
1212         if (s->resource_ops != &pccard_nonstatic_ops)
1213                 return;
1214         sysfs_remove_group(&dev->kobj, &rsrc_attributes);
1215 }
1216
1217 static struct class_interface pccard_rsrc_interface __refdata = {
1218         .class = &pcmcia_socket_class,
1219         .add_dev = &pccard_sysfs_add_rsrc,
1220         .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
1221 };
1222
1223 static int __init nonstatic_sysfs_init(void)
1224 {
1225         return class_interface_register(&pccard_rsrc_interface);
1226 }
1227
1228 static void __exit nonstatic_sysfs_exit(void)
1229 {
1230         class_interface_unregister(&pccard_rsrc_interface);
1231 }
1232
1233 module_init(nonstatic_sysfs_init);
1234 module_exit(nonstatic_sysfs_exit);