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

Archive Download this file



interactive