linux/drivers/pcmcia/rsrc_nonstatic.c
<<
>>
Prefs
   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_info(&s->dev, "cs: IO port probe %#x-%#x:", base, base+num-1);
 195
 196        /* First, what does a floating port look like? */
 197        b = kzalloc(256, GFP_KERNEL);
 198        if (!b) {
 199                pr_cont("\n");
 200                dev_err(&s->dev, "do_io_probe: unable to kmalloc 256 bytes\n");
 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                                pr_cont(" 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                                pr_cont(" excluding");
 236                        if (!bad)
 237                                bad = any = i;
 238                } else {
 239                        if (bad) {
 240                                sub_interval(&s_data->io_db, bad, i-bad);
 241                                pr_cont(" %#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                        pr_cont(" nothing: probe failed.\n");
 250                        return;
 251                } else {
 252                        sub_interval(&s_data->io_db, bad, i-bad);
 253                        pr_cont(" %#x-%#x", bad, i-1);
 254                }
 255        }
 256
 257        pr_cont("%s\n", !any ? " clean" : "");
 258}
 259#endif
 260
 261/*======================================================================*/
 262
 263/**
 264 * readable() - iomem validation function for cards with a valid CIS
 265 */
 266static 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 */
 297static 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 */
 347static int do_validate_mem(struct pcmcia_socket *s,
 348                           unsigned long base, unsigned long size,
 349                           int validate (struct pcmcia_socket *s,
 350                                         struct resource *res,
 351                                         unsigned int *value))
 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        dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
 371                base, base+size-1, res1, res2, ret, info1, info2);
 372
 373        free_region(res2);
 374        free_region(res1);
 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 */
 403static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
 404                        int validate (struct pcmcia_socket *s,
 405                                      struct resource *res,
 406                                      unsigned int *value),
 407                        int fallback (struct pcmcia_socket *s,
 408                                      struct resource *res,
 409                                      unsigned int *value))
 410{
 411        struct socket_data *s_data = s->resource_data;
 412        u_long i, j, bad, fail, step;
 413
 414        dev_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                                pr_cont(" excluding");
 440                        pr_cont(" %#05lx-%#05lx", i, j-1);
 441                        sub_interval(&s_data->mem_db, i, j-i);
 442                        bad += j-i;
 443                }
 444        }
 445        pr_cont("%s\n", !bad ? " clean" : "");
 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 */
 457static 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 */
 483static 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_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 */
 539static 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 */
 566static 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
 586struct pcmcia_align_data {
 587        unsigned long   mask;
 588        unsigned long   offset;
 589        struct resource_map     *map;
 590};
 591
 592static 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
 605static resource_size_t
 606pcmcia_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 */
 651static 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
 685static 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
 716static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
 717                        unsigned int *base, unsigned int num,
 718                        unsigned int align, struct resource **parent)
 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                        *parent = res;
 761                        return 0;
 762                }
 763
 764                /* Try to extend top of window */
 765                try = res->end + 1;
 766                if ((*base == 0) || (*base == try)) {
 767                        ret =  __nonstatic_adjust_io_region(s, res->start,
 768                                                        res->end + num);
 769                        if (!ret) {
 770                                ret = adjust_resource(s->io[i].res, res->start,
 771                                                      resource_size(res) + num);
 772                                if (ret)
 773                                        continue;
 774                                *base = try;
 775                                s->io[i].InUse += num;
 776                                *parent = res;
 777                                return 0;
 778                        }
 779                }
 780
 781                /* Try to extend bottom of window */
 782                try = res->start - num;
 783                if ((*base == 0) || (*base == try)) {
 784                        ret =  __nonstatic_adjust_io_region(s,
 785                                                        res->start - num,
 786                                                        res->end);
 787                        if (!ret) {
 788                                ret = adjust_resource(s->io[i].res,
 789                                                      res->start - num,
 790                                                      resource_size(res) + num);
 791                                if (ret)
 792                                        continue;
 793                                *base = try;
 794                                s->io[i].InUse += num;
 795                                *parent = res;
 796                                return 0;
 797                        }
 798                }
 799        }
 800
 801        return -EINVAL;
 802}
 803
 804
 805static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
 806                u_long align, int low, struct pcmcia_socket *s)
 807{
 808        struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM,
 809                                                dev_name(&s->dev));
 810        struct socket_data *s_data = s->resource_data;
 811        struct pcmcia_align_data data;
 812        unsigned long min, max;
 813        int ret, i, j;
 814
 815        low = low || !(s->features & SS_CAP_PAGE_REGS);
 816
 817        data.mask = align - 1;
 818        data.offset = base & data.mask;
 819
 820        for (i = 0; i < 2; i++) {
 821                data.map = &s_data->mem_db_valid;
 822                if (low) {
 823                        max = 0x100000UL;
 824                        min = base < max ? base : 0;
 825                } else {
 826                        max = ~0UL;
 827                        min = 0x100000UL + base;
 828                }
 829
 830                for (j = 0; j < 2; j++) {
 831#ifdef CONFIG_PCI
 832                        if (s->cb_dev) {
 833                                ret = pci_bus_alloc_resource(s->cb_dev->bus,
 834                                                        res, num, 1, min, 0,
 835                                                        pcmcia_align, &data);
 836                        } else
 837#endif
 838                        {
 839                                ret = allocate_resource(&iomem_resource,
 840                                                        res, num, min, max, 1,
 841                                                        pcmcia_align, &data);
 842                        }
 843                        if (ret == 0)
 844                                break;
 845                        data.map = &s_data->mem_db;
 846                }
 847                if (ret == 0 || low)
 848                        break;
 849                low = 1;
 850        }
 851
 852        if (ret != 0) {
 853                kfree(res);
 854                res = NULL;
 855        }
 856        return res;
 857}
 858
 859
 860static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
 861{
 862        struct socket_data *data = s->resource_data;
 863        unsigned long size = end - start + 1;
 864        int ret = 0;
 865
 866        if (end < start)
 867                return -EINVAL;
 868
 869        switch (action) {
 870        case ADD_MANAGED_RESOURCE:
 871                ret = add_interval(&data->mem_db, start, size);
 872                if (!ret)
 873                        do_mem_probe(s, start, size, NULL, NULL);
 874                break;
 875        case REMOVE_MANAGED_RESOURCE:
 876                ret = sub_interval(&data->mem_db, start, size);
 877                break;
 878        default:
 879                ret = -EINVAL;
 880        }
 881
 882        return ret;
 883}
 884
 885
 886static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
 887{
 888        struct socket_data *data = s->resource_data;
 889        unsigned long size;
 890        int ret = 0;
 891
 892#if defined(CONFIG_X86)
 893        /* on x86, avoid anything < 0x100 for it is often used for
 894         * legacy platform devices */
 895        if (start < 0x100)
 896                start = 0x100;
 897#endif
 898
 899        size = end - start + 1;
 900
 901        if (end < start)
 902                return -EINVAL;
 903
 904        if (end > IO_SPACE_LIMIT)
 905                return -EINVAL;
 906
 907        switch (action) {
 908        case ADD_MANAGED_RESOURCE:
 909                if (add_interval(&data->io_db, start, size) != 0) {
 910                        ret = -EBUSY;
 911                        break;
 912                }
 913#ifdef CONFIG_PCMCIA_PROBE
 914                if (probe_io)
 915                        do_io_probe(s, start, size);
 916#endif
 917                break;
 918        case REMOVE_MANAGED_RESOURCE:
 919                sub_interval(&data->io_db, start, size);
 920                break;
 921        default:
 922                ret = -EINVAL;
 923                break;
 924        }
 925
 926        return ret;
 927}
 928
 929
 930#ifdef CONFIG_PCI
 931static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
 932{
 933        struct resource *res;
 934        int i, done = 0;
 935
 936        if (!s->cb_dev || !s->cb_dev->bus)
 937                return -ENODEV;
 938
 939#if defined(CONFIG_X86)
 940        /* If this is the root bus, the risk of hitting some strange
 941         * system devices is too high: If a driver isn't loaded, the
 942         * resources are not claimed; even if a driver is loaded, it
 943         * may not request all resources or even the wrong one. We
 944         * can neither trust the rest of the kernel nor ACPI/PNP and
 945         * CRS parsing to get it right. Therefore, use several
 946         * safeguards:
 947         *
 948         * - Do not auto-add resources if the CardBus bridge is on
 949         *   the PCI root bus
 950         *
 951         * - Avoid any I/O ports < 0x100.
 952         *
 953         * - On PCI-PCI bridges, only use resources which are set up
 954         *   exclusively for the secondary PCI bus: the risk of hitting
 955         *   system devices is quite low, as they usually aren't
 956         *   connected to the secondary PCI bus.
 957         */
 958        if (s->cb_dev->bus->number == 0)
 959                return -EINVAL;
 960
 961        for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
 962                res = s->cb_dev->bus->resource[i];
 963#else
 964        pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
 965#endif
 966                if (!res)
 967                        continue;
 968
 969                if (res->flags & IORESOURCE_IO) {
 970                        /* safeguard against the root resource, where the
 971                         * risk of hitting any other device would be too
 972                         * high */
 973                        if (res == &ioport_resource)
 974                                continue;
 975
 976                        dev_info(&s->cb_dev->dev,
 977                                 "pcmcia: parent PCI bridge window: %pR\n",
 978                                 res);
 979                        if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
 980                                done |= IORESOURCE_IO;
 981
 982                }
 983
 984                if (res->flags & IORESOURCE_MEM) {
 985                        /* safeguard against the root resource, where the
 986                         * risk of hitting any other device would be too
 987                         * high */
 988                        if (res == &iomem_resource)
 989                                continue;
 990
 991                        dev_info(&s->cb_dev->dev,
 992                                 "pcmcia: parent PCI bridge window: %pR\n",
 993                                 res);
 994                        if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
 995                                done |= IORESOURCE_MEM;
 996                }
 997        }
 998
 999        /* if we got at least one of IO, and one of MEM, we can be glad and
1000         * activate the PCMCIA subsystem */
1001        if (done == (IORESOURCE_MEM | IORESOURCE_IO))
1002                s->resource_setup_done = 1;
1003
1004        return 0;
1005}
1006
1007#else
1008
1009static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
1010{
1011        return -ENODEV;
1012}
1013
1014#endif
1015
1016
1017static int nonstatic_init(struct pcmcia_socket *s)
1018{
1019        struct socket_data *data;
1020
1021        data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
1022        if (!data)
1023                return -ENOMEM;
1024
1025        data->mem_db.next = &data->mem_db;
1026        data->mem_db_valid.next = &data->mem_db_valid;
1027        data->io_db.next = &data->io_db;
1028
1029        s->resource_data = (void *) data;
1030
1031        nonstatic_autoadd_resources(s);
1032
1033        return 0;
1034}
1035
1036static void nonstatic_release_resource_db(struct pcmcia_socket *s)
1037{
1038        struct socket_data *data = s->resource_data;
1039        struct resource_map *p, *q;
1040
1041        for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
1042                q = p->next;
1043                kfree(p);
1044        }
1045        for (p = data->mem_db.next; p != &data->mem_db; p = q) {
1046                q = p->next;
1047                kfree(p);
1048        }
1049        for (p = data->io_db.next; p != &data->io_db; p = q) {
1050                q = p->next;
1051                kfree(p);
1052        }
1053}
1054
1055
1056struct pccard_resource_ops pccard_nonstatic_ops = {
1057        .validate_mem = pcmcia_nonstatic_validate_mem,
1058        .find_io = nonstatic_find_io,
1059        .find_mem = nonstatic_find_mem_region,
1060        .init = nonstatic_init,
1061        .exit = nonstatic_release_resource_db,
1062};
1063EXPORT_SYMBOL(pccard_nonstatic_ops);
1064
1065
1066/* sysfs interface to the resource database */
1067
1068static ssize_t show_io_db(struct device *dev,
1069                          struct device_attribute *attr, char *buf)
1070{
1071        struct pcmcia_socket *s = dev_get_drvdata(dev);
1072        struct socket_data *data;
1073        struct resource_map *p;
1074        ssize_t ret = 0;
1075
1076        mutex_lock(&s->ops_mutex);
1077        data = s->resource_data;
1078
1079        for (p = data->io_db.next; p != &data->io_db; p = p->next) {
1080                if (ret > (PAGE_SIZE - 10))
1081                        continue;
1082                ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1083                                "0x%08lx - 0x%08lx\n",
1084                                ((unsigned long) p->base),
1085                                ((unsigned long) p->base + p->num - 1));
1086        }
1087
1088        mutex_unlock(&s->ops_mutex);
1089        return ret;
1090}
1091
1092static ssize_t store_io_db(struct device *dev,
1093                           struct device_attribute *attr,
1094                           const char *buf, size_t count)
1095{
1096        struct pcmcia_socket *s = dev_get_drvdata(dev);
1097        unsigned long start_addr, end_addr;
1098        unsigned int add = ADD_MANAGED_RESOURCE;
1099        ssize_t ret = 0;
1100
1101        ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1102        if (ret != 2) {
1103                ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1104                add = REMOVE_MANAGED_RESOURCE;
1105                if (ret != 2) {
1106                        ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1107                                &end_addr);
1108                        add = ADD_MANAGED_RESOURCE;
1109                        if (ret != 2)
1110                                return -EINVAL;
1111                }
1112        }
1113        if (end_addr < start_addr)
1114                return -EINVAL;
1115
1116        mutex_lock(&s->ops_mutex);
1117        ret = adjust_io(s, add, start_addr, end_addr);
1118        mutex_unlock(&s->ops_mutex);
1119
1120        return ret ? ret : count;
1121}
1122static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
1123
1124static ssize_t show_mem_db(struct device *dev,
1125                           struct device_attribute *attr, char *buf)
1126{
1127        struct pcmcia_socket *s = dev_get_drvdata(dev);
1128        struct socket_data *data;
1129        struct resource_map *p;
1130        ssize_t ret = 0;
1131
1132        mutex_lock(&s->ops_mutex);
1133        data = s->resource_data;
1134
1135        for (p = data->mem_db_valid.next; p != &data->mem_db_valid;
1136             p = p->next) {
1137                if (ret > (PAGE_SIZE - 10))
1138                        continue;
1139                ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1140                                "0x%08lx - 0x%08lx\n",
1141                                ((unsigned long) p->base),
1142                                ((unsigned long) p->base + p->num - 1));
1143        }
1144
1145        for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
1146                if (ret > (PAGE_SIZE - 10))
1147                        continue;
1148                ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1149                                "0x%08lx - 0x%08lx\n",
1150                                ((unsigned long) p->base),
1151                                ((unsigned long) p->base + p->num - 1));
1152        }
1153
1154        mutex_unlock(&s->ops_mutex);
1155        return ret;
1156}
1157
1158static ssize_t store_mem_db(struct device *dev,
1159                            struct device_attribute *attr,
1160                            const char *buf, size_t count)
1161{
1162        struct pcmcia_socket *s = dev_get_drvdata(dev);
1163        unsigned long start_addr, end_addr;
1164        unsigned int add = ADD_MANAGED_RESOURCE;
1165        ssize_t ret = 0;
1166
1167        ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1168        if (ret != 2) {
1169                ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1170                add = REMOVE_MANAGED_RESOURCE;
1171                if (ret != 2) {
1172                        ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1173                                &end_addr);
1174                        add = ADD_MANAGED_RESOURCE;
1175                        if (ret != 2)
1176                                return -EINVAL;
1177                }
1178        }
1179        if (end_addr < start_addr)
1180                return -EINVAL;
1181
1182        mutex_lock(&s->ops_mutex);
1183        ret = adjust_memory(s, add, start_addr, end_addr);
1184        mutex_unlock(&s->ops_mutex);
1185
1186        return ret ? ret : count;
1187}
1188static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1189
1190static struct attribute *pccard_rsrc_attributes[] = {
1191        &dev_attr_available_resources_io.attr,
1192        &dev_attr_available_resources_mem.attr,
1193        NULL,
1194};
1195
1196static const struct attribute_group rsrc_attributes = {
1197        .attrs = pccard_rsrc_attributes,
1198};
1199
1200static int pccard_sysfs_add_rsrc(struct device *dev,
1201                                           struct class_interface *class_intf)
1202{
1203        struct pcmcia_socket *s = dev_get_drvdata(dev);
1204
1205        if (s->resource_ops != &pccard_nonstatic_ops)
1206                return 0;
1207        return sysfs_create_group(&dev->kobj, &rsrc_attributes);
1208}
1209
1210static void pccard_sysfs_remove_rsrc(struct device *dev,
1211                                               struct class_interface *class_intf)
1212{
1213        struct pcmcia_socket *s = dev_get_drvdata(dev);
1214
1215        if (s->resource_ops != &pccard_nonstatic_ops)
1216                return;
1217        sysfs_remove_group(&dev->kobj, &rsrc_attributes);
1218}
1219
1220static struct class_interface pccard_rsrc_interface __refdata = {
1221        .class = &pcmcia_socket_class,
1222        .add_dev = &pccard_sysfs_add_rsrc,
1223        .remove_dev = &pccard_sysfs_remove_rsrc,
1224};
1225
1226static int __init nonstatic_sysfs_init(void)
1227{
1228        return class_interface_register(&pccard_rsrc_interface);
1229}
1230
1231static void __exit nonstatic_sysfs_exit(void)
1232{
1233        class_interface_unregister(&pccard_rsrc_interface);
1234}
1235
1236module_init(nonstatic_sysfs_init);
1237module_exit(nonstatic_sysfs_exit);
1238