linux/drivers/pcmcia/rsrc_nonstatic.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * rsrc_nonstatic.c -- Resource management routines for !SS_CAP_STATIC_MAP sockets
   4 *
   5 * The initial developer of the original code is David A. Hinds
   6 * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
   7 * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
   8 *
   9 * (C) 1999             David A. Hinds
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/moduleparam.h>
  14#include <linux/init.h>
  15#include <linux/interrupt.h>
  16#include <linux/kernel.h>
  17#include <linux/errno.h>
  18#include <linux/types.h>
  19#include <linux/slab.h>
  20#include <linux/ioport.h>
  21#include <linux/timer.h>
  22#include <linux/pci.h>
  23#include <linux/device.h>
  24#include <linux/io.h>
  25
  26#include <asm/irq.h>
  27
  28#include <pcmcia/ss.h>
  29#include <pcmcia/cistpl.h>
  30#include "cs_internal.h"
  31
  32/* moved to rsrc_mgr.c
  33MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
  34MODULE_LICENSE("GPL");
  35*/
  36
  37/* Parameters that can be set with 'insmod' */
  38
  39#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
  40
  41INT_MODULE_PARM(probe_mem,      1);             /* memory probe? */
  42#ifdef CONFIG_PCMCIA_PROBE
  43INT_MODULE_PARM(probe_io,       1);             /* IO port probe? */
  44INT_MODULE_PARM(mem_limit,      0x10000);
  45#endif
  46
  47/* for io_db and mem_db */
  48struct resource_map {
  49        u_long                  base, num;
  50        struct resource_map     *next;
  51};
  52
  53struct socket_data {
  54        struct resource_map             mem_db;
  55        struct resource_map             mem_db_valid;
  56        struct resource_map             io_db;
  57};
  58
  59#define MEM_PROBE_LOW   (1 << 0)
  60#define MEM_PROBE_HIGH  (1 << 1)
  61
  62/* Action field */
  63#define REMOVE_MANAGED_RESOURCE         1
  64#define ADD_MANAGED_RESOURCE            2
  65
  66/*======================================================================
  67
  68    Linux resource management extensions
  69
  70======================================================================*/
  71
  72static struct resource *
  73claim_region(struct pcmcia_socket *s, resource_size_t base,
  74                resource_size_t size, int type, char *name)
  75{
  76        struct resource *res, *parent;
  77
  78        parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
  79        res = pcmcia_make_resource(base, size, type | IORESOURCE_BUSY, name);
  80
  81        if (res) {
  82#ifdef CONFIG_PCI
  83                if (s && s->cb_dev)
  84                        parent = pci_find_parent_resource(s->cb_dev, res);
  85#endif
  86                if (!parent || request_resource(parent, res)) {
  87                        kfree(res);
  88                        res = NULL;
  89                }
  90        }
  91        return res;
  92}
  93
  94static void free_region(struct resource *res)
  95{
  96        if (res) {
  97                release_resource(res);
  98                kfree(res);
  99        }
 100}
 101
 102/*======================================================================
 103
 104    These manage the internal databases of available resources.
 105
 106======================================================================*/
 107
 108static int add_interval(struct resource_map *map, u_long base, u_long num)
 109{
 110        struct resource_map *p, *q;
 111
 112        for (p = map; ; p = p->next) {
 113                if ((p != map) && (p->base+p->num >= base)) {
 114                        p->num = max(num + base - p->base, p->num);
 115                        return 0;
 116                }
 117                if ((p->next == map) || (p->next->base > base+num-1))
 118                        break;
 119        }
 120        q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
 121        if (!q) {
 122                printk(KERN_WARNING "out of memory to update resources\n");
 123                return -ENOMEM;
 124        }
 125        q->base = base; q->num = num;
 126        q->next = p->next; p->next = q;
 127        return 0;
 128}
 129
 130/*====================================================================*/
 131
 132static int sub_interval(struct resource_map *map, u_long base, u_long num)
 133{
 134        struct resource_map *p, *q;
 135
 136        for (p = map; ; p = q) {
 137                q = p->next;
 138                if (q == map)
 139                        break;
 140                if ((q->base+q->num > base) && (base+num > q->base)) {
 141                        if (q->base >= base) {
 142                                if (q->base+q->num <= base+num) {
 143                                        /* Delete whole block */
 144                                        p->next = q->next;
 145                                        kfree(q);
 146                                        /* don't advance the pointer yet */
 147                                        q = p;
 148                                } else {
 149                                        /* Cut off bit from the front */
 150                                        q->num = q->base + q->num - base - num;
 151                                        q->base = base + num;
 152                                }
 153                        } else if (q->base+q->num <= base+num) {
 154                                /* Cut off bit from the end */
 155                                q->num = base - q->base;
 156                        } else {
 157                                /* Split the block into two pieces */
 158                                p = kmalloc(sizeof(struct resource_map),
 159                                        GFP_KERNEL);
 160                                if (!p) {
 161                                        printk(KERN_WARNING "out of memory to update resources\n");
 162                                        return -ENOMEM;
 163                                }
 164                                p->base = base+num;
 165                                p->num = q->base+q->num - p->base;
 166                                q->num = base - q->base;
 167                                p->next = q->next ; q->next = p;
 168                        }
 169                }
 170        }
 171        return 0;
 172}
 173
 174/*======================================================================
 175
 176    These routines examine a region of IO or memory addresses to
 177    determine what ranges might be genuinely available.
 178
 179======================================================================*/
 180
 181#ifdef CONFIG_PCMCIA_PROBE
 182static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
 183                        unsigned int num)
 184{
 185        struct resource *res;
 186        struct socket_data *s_data = s->resource_data;
 187        unsigned int i, j, bad;
 188        int any;
 189        u_char *b, hole, most;
 190
 191        dev_info(&s->dev, "cs: IO port probe %#x-%#x:", base, base+num-1);
 192
 193        /* First, what does a floating port look like? */
 194        b = kzalloc(256, GFP_KERNEL);
 195        if (!b) {
 196                pr_cont("\n");
 197                dev_err(&s->dev, "do_io_probe: unable to kmalloc 256 bytes\n");
 198                return;
 199        }
 200        for (i = base, most = 0; i < base+num; i += 8) {
 201                res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
 202                if (!res)
 203                        continue;
 204                hole = inb(i);
 205                for (j = 1; j < 8; j++)
 206                        if (inb(i+j) != hole)
 207                                break;
 208                free_region(res);
 209                if ((j == 8) && (++b[hole] > b[most]))
 210                        most = hole;
 211                if (b[most] == 127)
 212                        break;
 213        }
 214        kfree(b);
 215
 216        bad = any = 0;
 217        for (i = base; i < base+num; i += 8) {
 218                res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
 219                if (!res) {
 220                        if (!any)
 221                                pr_cont(" excluding");
 222                        if (!bad)
 223                                bad = any = i;
 224                        continue;
 225                }
 226                for (j = 0; j < 8; j++)
 227                        if (inb(i+j) != most)
 228                                break;
 229                free_region(res);
 230                if (j < 8) {
 231                        if (!any)
 232                                pr_cont(" excluding");
 233                        if (!bad)
 234                                bad = any = i;
 235                } else {
 236                        if (bad) {
 237                                sub_interval(&s_data->io_db, bad, i-bad);
 238                                pr_cont(" %#x-%#x", bad, i-1);
 239                                bad = 0;
 240                        }
 241                }
 242        }
 243        if (bad) {
 244                if ((num > 16) && (bad == base) && (i == base+num)) {
 245                        sub_interval(&s_data->io_db, bad, i-bad);
 246                        pr_cont(" nothing: probe failed.\n");
 247                        return;
 248                } else {
 249                        sub_interval(&s_data->io_db, bad, i-bad);
 250                        pr_cont(" %#x-%#x", bad, i-1);
 251                }
 252        }
 253
 254        pr_cont("%s\n", !any ? " clean" : "");
 255}
 256#endif
 257
 258/*======================================================================*/
 259
 260/*
 261 * readable() - iomem validation function for cards with a valid CIS
 262 */
 263static int readable(struct pcmcia_socket *s, struct resource *res,
 264                    unsigned int *count)
 265{
 266        int ret = -EINVAL;
 267
 268        if (s->fake_cis) {
 269                dev_dbg(&s->dev, "fake CIS is being used: can't validate mem\n");
 270                return 0;
 271        }
 272
 273        s->cis_mem.res = res;
 274        s->cis_virt = ioremap(res->start, s->map_size);
 275        if (s->cis_virt) {
 276                mutex_unlock(&s->ops_mutex);
 277                /* as we're only called from pcmcia.c, we're safe */
 278                if (s->callback->validate)
 279                        ret = s->callback->validate(s, count);
 280                /* invalidate mapping */
 281                mutex_lock(&s->ops_mutex);
 282                iounmap(s->cis_virt);
 283                s->cis_virt = NULL;
 284        }
 285        s->cis_mem.res = NULL;
 286        if ((ret) || (*count == 0))
 287                return -EINVAL;
 288        return 0;
 289}
 290
 291/*
 292 * checksum() - iomem validation function for simple memory cards
 293 */
 294static int checksum(struct pcmcia_socket *s, struct resource *res,
 295                    unsigned int *value)
 296{
 297        pccard_mem_map map;
 298        int i, a = 0, b = -1, d;
 299        void __iomem *virt;
 300
 301        virt = ioremap(res->start, s->map_size);
 302        if (virt) {
 303                map.map = 0;
 304                map.flags = MAP_ACTIVE;
 305                map.speed = 0;
 306                map.res = res;
 307                map.card_start = 0;
 308                s->ops->set_mem_map(s, &map);
 309
 310                /* Don't bother checking every word... */
 311                for (i = 0; i < s->map_size; i += 44) {
 312                        d = readl(virt+i);
 313                        a += d;
 314                        b &= d;
 315                }
 316
 317                map.flags = 0;
 318                s->ops->set_mem_map(s, &map);
 319
 320                iounmap(virt);
 321        }
 322
 323        if (b == -1)
 324                return -EINVAL;
 325
 326        *value = a;
 327
 328        return 0;
 329}
 330
 331/**
 332 * do_validate_mem() - low level validate a memory region for PCMCIA use
 333 * @s:          PCMCIA socket to validate
 334 * @base:       start address of resource to check
 335 * @size:       size of resource to check
 336 * @validate:   validation function to use
 337 *
 338 * do_validate_mem() splits up the memory region which is to be checked
 339 * into two parts. Both are passed to the @validate() function. If
 340 * @validate() returns non-zero, or the value parameter to @validate()
 341 * is zero, or the value parameter is different between both calls,
 342 * the check fails, and -EINVAL is returned. Else, 0 is returned.
 343 */
 344static int do_validate_mem(struct pcmcia_socket *s,
 345                           unsigned long base, unsigned long size,
 346                           int (*validate)(struct pcmcia_socket *s,
 347                                           struct resource *res,
 348                                           unsigned int *value))
 349{
 350        struct socket_data *s_data = s->resource_data;
 351        struct resource *res1, *res2;
 352        unsigned int info1 = 1, info2 = 1;
 353        int ret = -EINVAL;
 354
 355        res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
 356        res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
 357                        "PCMCIA memprobe");
 358
 359        if (res1 && res2) {
 360                ret = 0;
 361                if (validate) {
 362                        ret = validate(s, res1, &info1);
 363                        ret += validate(s, res2, &info2);
 364                }
 365        }
 366
 367        dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %pr %pr %u %u %u",
 368                base, base+size-1, res1, res2, ret, info1, info2);
 369
 370        free_region(res2);
 371        free_region(res1);
 372
 373        if ((ret) || (info1 != info2) || (info1 == 0))
 374                return -EINVAL;
 375
 376        if (validate && !s->fake_cis) {
 377                /* move it to the validated data set */
 378                add_interval(&s_data->mem_db_valid, base, size);
 379                sub_interval(&s_data->mem_db, base, size);
 380        }
 381
 382        return 0;
 383}
 384
 385
 386/**
 387 * do_mem_probe() - validate a memory region for PCMCIA use
 388 * @s:          PCMCIA socket to validate
 389 * @base:       start address of resource to check
 390 * @num:        size of resource to check
 391 * @validate:   validation function to use
 392 * @fallback:   validation function to use if validate fails
 393 *
 394 * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
 395 * To do so, the area is split up into sensible parts, and then passed
 396 * into the @validate() function. Only if @validate() and @fallback() fail,
 397 * the area is marked as unavaibale for use by the PCMCIA subsystem. The
 398 * function returns the size of the usable memory area.
 399 */
 400static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
 401                        int (*validate)(struct pcmcia_socket *s,
 402                                        struct resource *res,
 403                                        unsigned int *value),
 404                        int (*fallback)(struct pcmcia_socket *s,
 405                                        struct resource *res,
 406                                        unsigned int *value))
 407{
 408        struct socket_data *s_data = s->resource_data;
 409        u_long i, j, bad, fail, step;
 410
 411        dev_info(&s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
 412                 base, base+num-1);
 413        bad = fail = 0;
 414        step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
 415        /* don't allow too large steps */
 416        if (step > 0x800000)
 417                step = 0x800000;
 418        /* cis_readable wants to map 2x map_size */
 419        if (step < 2 * s->map_size)
 420                step = 2 * s->map_size;
 421        for (i = j = base; i < base+num; i = j + step) {
 422                if (!fail) {
 423                        for (j = i; j < base+num; j += step) {
 424                                if (!do_validate_mem(s, j, step, validate))
 425                                        break;
 426                        }
 427                        fail = ((i == base) && (j == base+num));
 428                }
 429                if ((fail) && (fallback)) {
 430                        for (j = i; j < base+num; j += step)
 431                                if (!do_validate_mem(s, j, step, fallback))
 432                                        break;
 433                }
 434                if (i != j) {
 435                        if (!bad)
 436                                pr_cont(" excluding");
 437                        pr_cont(" %#05lx-%#05lx", i, j-1);
 438                        sub_interval(&s_data->mem_db, i, j-i);
 439                        bad += j-i;
 440                }
 441        }
 442        pr_cont("%s\n", !bad ? " clean" : "");
 443        return num - bad;
 444}
 445
 446
 447#ifdef CONFIG_PCMCIA_PROBE
 448
 449/**
 450 * inv_probe() - top-to-bottom search for one usuable high memory area
 451 * @s:          PCMCIA socket to validate
 452 * @m:          resource_map to check
 453 */
 454static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
 455{
 456        struct socket_data *s_data = s->resource_data;
 457        u_long ok;
 458        if (m == &s_data->mem_db)
 459                return 0;
 460        ok = inv_probe(m->next, s);
 461        if (ok) {
 462                if (m->base >= 0x100000)
 463                        sub_interval(&s_data->mem_db, m->base, m->num);
 464                return ok;
 465        }
 466        if (m->base < 0x100000)
 467                return 0;
 468        return do_mem_probe(s, m->base, m->num, readable, checksum);
 469}
 470
 471/**
 472 * validate_mem() - memory probe function
 473 * @s:          PCMCIA socket to validate
 474 * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
 475 *
 476 * The memory probe.  If the memory list includes a 64K-aligned block
 477 * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
 478 * least mem_limit free space, we quit. Returns 0 on usuable ports.
 479 */
 480static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 481{
 482        struct resource_map *m, mm;
 483        static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
 484        unsigned long b, i, ok = 0;
 485        struct socket_data *s_data = s->resource_data;
 486
 487        /* We do up to four passes through the list */
 488        if (probe_mask & MEM_PROBE_HIGH) {
 489                if (inv_probe(s_data->mem_db.next, s) > 0)
 490                        return 0;
 491                if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
 492                        return 0;
 493                dev_notice(&s->dev,
 494                           "cs: warning: no high memory space available!\n");
 495                return -ENODEV;
 496        }
 497
 498        for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
 499                mm = *m;
 500                /* Only probe < 1 MB */
 501                if (mm.base >= 0x100000)
 502                        continue;
 503                if ((mm.base | mm.num) & 0xffff) {
 504                        ok += do_mem_probe(s, mm.base, mm.num, readable,
 505                                           checksum);
 506                        continue;
 507                }
 508                /* Special probe for 64K-aligned block */
 509                for (i = 0; i < 4; i++) {
 510                        b = order[i] << 12;
 511                        if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
 512                                if (ok >= mem_limit)
 513                                        sub_interval(&s_data->mem_db, b, 0x10000);
 514                                else
 515                                        ok += do_mem_probe(s, b, 0x10000,
 516                                                           readable, checksum);
 517                        }
 518                }
 519        }
 520
 521        if (ok > 0)
 522                return 0;
 523
 524        return -ENODEV;
 525}
 526
 527#else /* CONFIG_PCMCIA_PROBE */
 528
 529/**
 530 * validate_mem() - memory probe function
 531 * @s:          PCMCIA socket to validate
 532 * @probe_mask: ignored
 533 *
 534 * Returns 0 on usuable ports.
 535 */
 536static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 537{
 538        struct resource_map *m, mm;
 539        struct socket_data *s_data = s->resource_data;
 540        unsigned long ok = 0;
 541
 542        for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
 543                mm = *m;
 544                ok += do_mem_probe(s, mm.base, mm.num, readable, checksum);
 545        }
 546        if (ok > 0)
 547                return 0;
 548        return -ENODEV;
 549}
 550
 551#endif /* CONFIG_PCMCIA_PROBE */
 552
 553
 554/**
 555 * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
 556 * @s:          PCMCIA socket to validate
 557 *
 558 * This is tricky... when we set up CIS memory, we try to validate
 559 * the memory window space allocations.
 560 *
 561 * Locking note: Must be called with skt_mutex held!
 562 */
 563static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
 564{
 565        struct socket_data *s_data = s->resource_data;
 566        unsigned int probe_mask = MEM_PROBE_LOW;
 567        int ret;
 568
 569        if (!probe_mem || !(s->state & SOCKET_PRESENT))
 570                return 0;
 571
 572        if (s->features & SS_CAP_PAGE_REGS)
 573                probe_mask = MEM_PROBE_HIGH;
 574
 575        ret = validate_mem(s, probe_mask);
 576
 577        if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
 578                return 0;
 579
 580        return ret;
 581}
 582
 583struct pcmcia_align_data {
 584        unsigned long   mask;
 585        unsigned long   offset;
 586        struct resource_map     *map;
 587};
 588
 589static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data,
 590                                        resource_size_t start)
 591{
 592        resource_size_t ret;
 593        /*
 594         * Ensure that we have the correct start address
 595         */
 596        ret = (start & ~align_data->mask) + align_data->offset;
 597        if (ret < start)
 598                ret += align_data->mask + 1;
 599        return ret;
 600}
 601
 602static resource_size_t
 603pcmcia_align(void *align_data, const struct resource *res,
 604        resource_size_t size, resource_size_t align)
 605{
 606        struct pcmcia_align_data *data = align_data;
 607        struct resource_map *m;
 608        resource_size_t start;
 609
 610        start = pcmcia_common_align(data, res->start);
 611
 612        for (m = data->map->next; m != data->map; m = m->next) {
 613                unsigned long map_start = m->base;
 614                unsigned long map_end = m->base + m->num - 1;
 615
 616                /*
 617                 * If the lower resources are not available, try aligning
 618                 * to this entry of the resource database to see if it'll
 619                 * fit here.
 620                 */
 621                if (start < map_start)
 622                        start = pcmcia_common_align(data, map_start);
 623
 624                /*
 625                 * If we're above the area which was passed in, there's
 626                 * no point proceeding.
 627                 */
 628                if (start >= res->end)
 629                        break;
 630
 631                if ((start + size - 1) <= map_end)
 632                        break;
 633        }
 634
 635        /*
 636         * If we failed to find something suitable, ensure we fail.
 637         */
 638        if (m == data->map)
 639                start = res->end;
 640
 641        return start;
 642}
 643
 644/*
 645 * Adjust an existing IO region allocation, but making sure that we don't
 646 * encroach outside the resources which the user supplied.
 647 */
 648static int __nonstatic_adjust_io_region(struct pcmcia_socket *s,
 649                                        unsigned long r_start,
 650                                        unsigned long r_end)
 651{
 652        struct resource_map *m;
 653        struct socket_data *s_data = s->resource_data;
 654        int ret = -ENOMEM;
 655
 656        for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
 657                unsigned long start = m->base;
 658                unsigned long end = m->base + m->num - 1;
 659
 660                if (start > r_start || r_end > end)
 661                        continue;
 662
 663                ret = 0;
 664        }
 665
 666        return ret;
 667}
 668
 669/*======================================================================
 670
 671    These find ranges of I/O ports or memory addresses that are not
 672    currently allocated by other devices.
 673
 674    The 'align' field should reflect the number of bits of address
 675    that need to be preserved from the initial value of *base.  It
 676    should be a power of two, greater than or equal to 'num'.  A value
 677    of 0 means that all bits of *base are significant.  *base should
 678    also be strictly less than 'align'.
 679
 680======================================================================*/
 681
 682static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s,
 683                                                unsigned long base, int num,
 684                                                unsigned long align)
 685{
 686        struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO,
 687                                                dev_name(&s->dev));
 688        struct socket_data *s_data = s->resource_data;
 689        struct pcmcia_align_data data;
 690        unsigned long min = base;
 691        int ret;
 692
 693        data.mask = align - 1;
 694        data.offset = base & data.mask;
 695        data.map = &s_data->io_db;
 696
 697#ifdef CONFIG_PCI
 698        if (s->cb_dev) {
 699                ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
 700                                             min, 0, pcmcia_align, &data);
 701        } else
 702#endif
 703                ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
 704                                        1, pcmcia_align, &data);
 705
 706        if (ret != 0) {
 707                kfree(res);
 708                res = NULL;
 709        }
 710        return res;
 711}
 712
 713static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
 714                        unsigned int *base, unsigned int num,
 715                        unsigned int align, struct resource **parent)
 716{
 717        int i, ret = 0;
 718
 719        /* Check for an already-allocated window that must conflict with
 720         * what was asked for.  It is a hack because it does not catch all
 721         * potential conflicts, just the most obvious ones.
 722         */
 723        for (i = 0; i < MAX_IO_WIN; i++) {
 724                if (!s->io[i].res)
 725                        continue;
 726
 727                if (!*base)
 728                        continue;
 729
 730                if ((s->io[i].res->start & (align-1)) == *base)
 731                        return -EBUSY;
 732        }
 733
 734        for (i = 0; i < MAX_IO_WIN; i++) {
 735                struct resource *res = s->io[i].res;
 736                unsigned int try;
 737
 738                if (res && (res->flags & IORESOURCE_BITS) !=
 739                        (attr & IORESOURCE_BITS))
 740                        continue;
 741
 742                if (!res) {
 743                        if (align == 0)
 744                                align = 0x10000;
 745
 746                        res = s->io[i].res = __nonstatic_find_io_region(s,
 747                                                                *base, num,
 748                                                                align);
 749                        if (!res)
 750                                return -EINVAL;
 751
 752                        *base = res->start;
 753                        s->io[i].res->flags =
 754                                ((res->flags & ~IORESOURCE_BITS) |
 755                                        (attr & IORESOURCE_BITS));
 756                        s->io[i].InUse = num;
 757                        *parent = res;
 758                        return 0;
 759                }
 760
 761                /* Try to extend top of window */
 762                try = res->end + 1;
 763                if ((*base == 0) || (*base == try)) {
 764                        ret =  __nonstatic_adjust_io_region(s, res->start,
 765                                                        res->end + num);
 766                        if (!ret) {
 767                                ret = adjust_resource(s->io[i].res, res->start,
 768                                                      resource_size(res) + num);
 769                                if (ret)
 770                                        continue;
 771                                *base = try;
 772                                s->io[i].InUse += num;
 773                                *parent = res;
 774                                return 0;
 775                        }
 776                }
 777
 778                /* Try to extend bottom of window */
 779                try = res->start - num;
 780                if ((*base == 0) || (*base == try)) {
 781                        ret =  __nonstatic_adjust_io_region(s,
 782                                                        res->start - num,
 783                                                        res->end);
 784                        if (!ret) {
 785                                ret = adjust_resource(s->io[i].res,
 786                                                      res->start - num,
 787                                                      resource_size(res) + num);
 788                                if (ret)
 789                                        continue;
 790                                *base = try;
 791                                s->io[i].InUse += num;
 792                                *parent = res;
 793                                return 0;
 794                        }
 795                }
 796        }
 797
 798        return -EINVAL;
 799}
 800
 801
 802static 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
 857static 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
 883static 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
 928static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
 929{
 930        struct resource *res;
 931        int i, done = 0;
 932
 933        if (!s->cb_dev || !s->cb_dev->bus)
 934                return -ENODEV;
 935
 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_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_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
1006static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
1007{
1008        return -ENODEV;
1009}
1010
1011#endif
1012
1013
1014static 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
1033static void nonstatic_release_resource_db(struct pcmcia_socket *s)
1034{
1035        struct socket_data *data = s->resource_data;
1036        struct resource_map *p, *q;
1037
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
1053struct 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};
1060EXPORT_SYMBOL(pccard_nonstatic_ops);
1061
1062
1063/* sysfs interface to the resource database */
1064
1065static 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 += scnprintf(&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
1089static 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}
1119static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
1120
1121static 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 += scnprintf(&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 += scnprintf(&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
1155static 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}
1185static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1186
1187static struct attribute *pccard_rsrc_attributes[] = {
1188        &dev_attr_available_resources_io.attr,
1189        &dev_attr_available_resources_mem.attr,
1190        NULL,
1191};
1192
1193static const struct attribute_group rsrc_attributes = {
1194        .attrs = pccard_rsrc_attributes,
1195};
1196
1197static int 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
1207static void 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
1217static struct class_interface pccard_rsrc_interface __refdata = {
1218        .class = &pcmcia_socket_class,
1219        .add_dev = &pccard_sysfs_add_rsrc,
1220        .remove_dev = &pccard_sysfs_remove_rsrc,
1221};
1222
1223static int __init nonstatic_sysfs_init(void)
1224{
1225        return class_interface_register(&pccard_rsrc_interface);
1226}
1227
1228static void __exit nonstatic_sysfs_exit(void)
1229{
1230        class_interface_unregister(&pccard_rsrc_interface);
1231}
1232
1233module_init(nonstatic_sysfs_init);
1234module_exit(nonstatic_sysfs_exit);
1235