linux/drivers/pnp/isapnp/core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  ISA Plug & Play support
   4 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   5 *
   6 *  Changelog:
   7 *  2000-01-01  Added quirks handling for buggy hardware
   8 *              Peter Denison <peterd@pnd-pc.demon.co.uk>
   9 *  2000-06-14  Added isapnp_probe_devs() and isapnp_activate_dev()
  10 *              Christoph Hellwig <hch@infradead.org>
  11 *  2001-06-03  Added release_region calls to correspond with
  12 *              request_region calls when a failure occurs.  Also
  13 *              added KERN_* constants to printk() calls.
  14 *  2001-11-07  Added isapnp_{,un}register_driver calls along the lines
  15 *              of the pci driver interface
  16 *              Kai Germaschewski <kai.germaschewski@gmx.de>
  17 *  2002-06-06  Made the use of dma channel 0 configurable
  18 *              Gerald Teschl <gerald.teschl@univie.ac.at>
  19 *  2002-10-06  Ported to PnP Layer - Adam Belay <ambx1@neo.rr.com>
  20 *  2003-08-11  Resource Management Updates - Adam Belay <ambx1@neo.rr.com>
  21 */
  22
  23#include <linux/moduleparam.h>
  24#include <linux/kernel.h>
  25#include <linux/errno.h>
  26#include <linux/delay.h>
  27#include <linux/init.h>
  28#include <linux/isapnp.h>
  29#include <linux/mutex.h>
  30#include <asm/io.h>
  31
  32#include "../base.h"
  33
  34#if 0
  35#define ISAPNP_REGION_OK
  36#endif
  37
  38int isapnp_disable;             /* Disable ISA PnP */
  39static int isapnp_rdp;          /* Read Data Port */
  40static int isapnp_reset = 1;    /* reset all PnP cards (deactivate) */
  41static int isapnp_verbose = 1;  /* verbose mode */
  42
  43module_param(isapnp_disable, int, 0);
  44MODULE_PARM_DESC(isapnp_disable, "ISA Plug & Play disable");
  45module_param(isapnp_rdp, int, 0);
  46MODULE_PARM_DESC(isapnp_rdp, "ISA Plug & Play read data port");
  47module_param(isapnp_reset, int, 0);
  48MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
  49module_param(isapnp_verbose, int, 0);
  50MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
  51
  52#define _PIDXR          0x279
  53#define _PNPWRP         0xa79
  54
  55/* short tags */
  56#define _STAG_PNPVERNO          0x01
  57#define _STAG_LOGDEVID          0x02
  58#define _STAG_COMPATDEVID       0x03
  59#define _STAG_IRQ               0x04
  60#define _STAG_DMA               0x05
  61#define _STAG_STARTDEP          0x06
  62#define _STAG_ENDDEP            0x07
  63#define _STAG_IOPORT            0x08
  64#define _STAG_FIXEDIO           0x09
  65#define _STAG_VENDOR            0x0e
  66#define _STAG_END               0x0f
  67/* long tags */
  68#define _LTAG_MEMRANGE          0x81
  69#define _LTAG_ANSISTR           0x82
  70#define _LTAG_UNICODESTR        0x83
  71#define _LTAG_VENDOR            0x84
  72#define _LTAG_MEM32RANGE        0x85
  73#define _LTAG_FIXEDMEM32RANGE   0x86
  74
  75/* Logical device control and configuration registers */
  76
  77#define ISAPNP_CFG_ACTIVATE     0x30    /* byte */
  78#define ISAPNP_CFG_MEM          0x40    /* 4 * dword */
  79#define ISAPNP_CFG_PORT         0x60    /* 8 * word */
  80#define ISAPNP_CFG_IRQ          0x70    /* 2 * word */
  81#define ISAPNP_CFG_DMA          0x74    /* 2 * byte */
  82
  83/*
  84 * Sizes of ISAPNP logical device configuration register sets.
  85 * See PNP-ISA-v1.0a.pdf, Appendix A.
  86 */
  87#define ISAPNP_MAX_MEM          4
  88#define ISAPNP_MAX_PORT         8
  89#define ISAPNP_MAX_IRQ          2
  90#define ISAPNP_MAX_DMA          2
  91
  92static unsigned char isapnp_checksum_value;
  93static DEFINE_MUTEX(isapnp_cfg_mutex);
  94static int isapnp_csn_count;
  95
  96/* some prototypes */
  97
  98static inline void write_data(unsigned char x)
  99{
 100        outb(x, _PNPWRP);
 101}
 102
 103static inline void write_address(unsigned char x)
 104{
 105        outb(x, _PIDXR);
 106        udelay(20);
 107}
 108
 109static inline unsigned char read_data(void)
 110{
 111        unsigned char val = inb(isapnp_rdp);
 112        return val;
 113}
 114
 115unsigned char isapnp_read_byte(unsigned char idx)
 116{
 117        write_address(idx);
 118        return read_data();
 119}
 120
 121static unsigned short isapnp_read_word(unsigned char idx)
 122{
 123        unsigned short val;
 124
 125        val = isapnp_read_byte(idx);
 126        val = (val << 8) + isapnp_read_byte(idx + 1);
 127        return val;
 128}
 129
 130void isapnp_write_byte(unsigned char idx, unsigned char val)
 131{
 132        write_address(idx);
 133        write_data(val);
 134}
 135
 136static void isapnp_write_word(unsigned char idx, unsigned short val)
 137{
 138        isapnp_write_byte(idx, val >> 8);
 139        isapnp_write_byte(idx + 1, val);
 140}
 141
 142static void isapnp_key(void)
 143{
 144        unsigned char code = 0x6a, msb;
 145        int i;
 146
 147        mdelay(1);
 148        write_address(0x00);
 149        write_address(0x00);
 150
 151        write_address(code);
 152
 153        for (i = 1; i < 32; i++) {
 154                msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7;
 155                code = (code >> 1) | msb;
 156                write_address(code);
 157        }
 158}
 159
 160/* place all pnp cards in wait-for-key state */
 161static void isapnp_wait(void)
 162{
 163        isapnp_write_byte(0x02, 0x02);
 164}
 165
 166static void isapnp_wake(unsigned char csn)
 167{
 168        isapnp_write_byte(0x03, csn);
 169}
 170
 171static void isapnp_device(unsigned char logdev)
 172{
 173        isapnp_write_byte(0x07, logdev);
 174}
 175
 176static void isapnp_activate(unsigned char logdev)
 177{
 178        isapnp_device(logdev);
 179        isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 1);
 180        udelay(250);
 181}
 182
 183static void isapnp_deactivate(unsigned char logdev)
 184{
 185        isapnp_device(logdev);
 186        isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 0);
 187        udelay(500);
 188}
 189
 190static void __init isapnp_peek(unsigned char *data, int bytes)
 191{
 192        int i, j;
 193        unsigned char d = 0;
 194
 195        for (i = 1; i <= bytes; i++) {
 196                for (j = 0; j < 20; j++) {
 197                        d = isapnp_read_byte(0x05);
 198                        if (d & 1)
 199                                break;
 200                        udelay(100);
 201                }
 202                if (!(d & 1)) {
 203                        if (data != NULL)
 204                                *data++ = 0xff;
 205                        continue;
 206                }
 207                d = isapnp_read_byte(0x04);     /* PRESDI */
 208                isapnp_checksum_value += d;
 209                if (data != NULL)
 210                        *data++ = d;
 211        }
 212}
 213
 214#define RDP_STEP        32      /* minimum is 4 */
 215
 216static int isapnp_next_rdp(void)
 217{
 218        int rdp = isapnp_rdp;
 219        static int old_rdp = 0;
 220
 221        if (old_rdp) {
 222                release_region(old_rdp, 1);
 223                old_rdp = 0;
 224        }
 225        while (rdp <= 0x3ff) {
 226                /*
 227                 *      We cannot use NE2000 probe spaces for ISAPnP or we
 228                 *      will lock up machines.
 229                 */
 230                if ((rdp < 0x280 || rdp > 0x380)
 231                    && request_region(rdp, 1, "ISAPnP")) {
 232                        isapnp_rdp = rdp;
 233                        old_rdp = rdp;
 234                        return 0;
 235                }
 236                rdp += RDP_STEP;
 237        }
 238        return -1;
 239}
 240
 241/* Set read port address */
 242static inline void isapnp_set_rdp(void)
 243{
 244        isapnp_write_byte(0x00, isapnp_rdp >> 2);
 245        udelay(100);
 246}
 247
 248/*
 249 *      Perform an isolation. The port selection code now tries to avoid
 250 *      "dangerous to read" ports.
 251 */
 252static int __init isapnp_isolate_rdp_select(void)
 253{
 254        isapnp_wait();
 255        isapnp_key();
 256
 257        /* Control: reset CSN and conditionally everything else too */
 258        isapnp_write_byte(0x02, isapnp_reset ? 0x05 : 0x04);
 259        mdelay(2);
 260
 261        isapnp_wait();
 262        isapnp_key();
 263        isapnp_wake(0x00);
 264
 265        if (isapnp_next_rdp() < 0) {
 266                isapnp_wait();
 267                return -1;
 268        }
 269
 270        isapnp_set_rdp();
 271        udelay(1000);
 272        write_address(0x01);
 273        udelay(1000);
 274        return 0;
 275}
 276
 277/*
 278 *  Isolate (assign uniqued CSN) to all ISA PnP devices.
 279 */
 280static int __init isapnp_isolate(void)
 281{
 282        unsigned char checksum = 0x6a;
 283        unsigned char chksum = 0x00;
 284        unsigned char bit = 0x00;
 285        int data;
 286        int csn = 0;
 287        int i;
 288        int iteration = 1;
 289
 290        isapnp_rdp = 0x213;
 291        if (isapnp_isolate_rdp_select() < 0)
 292                return -1;
 293
 294        while (1) {
 295                for (i = 1; i <= 64; i++) {
 296                        data = read_data() << 8;
 297                        udelay(250);
 298                        data = data | read_data();
 299                        udelay(250);
 300                        if (data == 0x55aa)
 301                                bit = 0x01;
 302                        checksum =
 303                            ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7)
 304                            | (checksum >> 1);
 305                        bit = 0x00;
 306                }
 307                for (i = 65; i <= 72; i++) {
 308                        data = read_data() << 8;
 309                        udelay(250);
 310                        data = data | read_data();
 311                        udelay(250);
 312                        if (data == 0x55aa)
 313                                chksum |= (1 << (i - 65));
 314                }
 315                if (checksum != 0x00 && checksum == chksum) {
 316                        csn++;
 317
 318                        isapnp_write_byte(0x06, csn);
 319                        udelay(250);
 320                        iteration++;
 321                        isapnp_wake(0x00);
 322                        isapnp_set_rdp();
 323                        udelay(1000);
 324                        write_address(0x01);
 325                        udelay(1000);
 326                        goto __next;
 327                }
 328                if (iteration == 1) {
 329                        isapnp_rdp += RDP_STEP;
 330                        if (isapnp_isolate_rdp_select() < 0)
 331                                return -1;
 332                } else if (iteration > 1) {
 333                        break;
 334                }
 335__next:
 336                if (csn == 255)
 337                        break;
 338                checksum = 0x6a;
 339                chksum = 0x00;
 340                bit = 0x00;
 341        }
 342        isapnp_wait();
 343        isapnp_csn_count = csn;
 344        return csn;
 345}
 346
 347/*
 348 *  Read one tag from stream.
 349 */
 350static int __init isapnp_read_tag(unsigned char *type, unsigned short *size)
 351{
 352        unsigned char tag, tmp[2];
 353
 354        isapnp_peek(&tag, 1);
 355        if (tag == 0)           /* invalid tag */
 356                return -1;
 357        if (tag & 0x80) {       /* large item */
 358                *type = tag;
 359                isapnp_peek(tmp, 2);
 360                *size = (tmp[1] << 8) | tmp[0];
 361        } else {
 362                *type = (tag >> 3) & 0x0f;
 363                *size = tag & 0x07;
 364        }
 365        if (*type == 0xff && *size == 0xffff)   /* probably invalid data */
 366                return -1;
 367        return 0;
 368}
 369
 370/*
 371 *  Skip specified number of bytes from stream.
 372 */
 373static void __init isapnp_skip_bytes(int count)
 374{
 375        isapnp_peek(NULL, count);
 376}
 377
 378/*
 379 *  Parse logical device tag.
 380 */
 381static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
 382                                                  int size, int number)
 383{
 384        unsigned char tmp[6];
 385        struct pnp_dev *dev;
 386        u32 eisa_id;
 387        char id[8];
 388
 389        isapnp_peek(tmp, size);
 390        eisa_id = tmp[0] | tmp[1] << 8 | tmp[2] << 16 | tmp[3] << 24;
 391        pnp_eisa_id_to_string(eisa_id, id);
 392
 393        dev = pnp_alloc_dev(&isapnp_protocol, number, id);
 394        if (!dev)
 395                return NULL;
 396
 397        dev->card = card;
 398        dev->capabilities |= PNP_CONFIGURABLE;
 399        dev->capabilities |= PNP_READ;
 400        dev->capabilities |= PNP_WRITE;
 401        dev->capabilities |= PNP_DISABLE;
 402        pnp_init_resources(dev);
 403        return dev;
 404}
 405
 406/*
 407 *  Add IRQ resource to resources list.
 408 */
 409static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
 410                                             unsigned int option_flags,
 411                                             int size)
 412{
 413        unsigned char tmp[3];
 414        unsigned long bits;
 415        pnp_irq_mask_t map;
 416        unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
 417
 418        isapnp_peek(tmp, size);
 419        bits = (tmp[1] << 8) | tmp[0];
 420
 421        bitmap_zero(map.bits, PNP_IRQ_NR);
 422        bitmap_copy(map.bits, &bits, 16);
 423
 424        if (size > 2)
 425                flags = tmp[2];
 426
 427        pnp_register_irq_resource(dev, option_flags, &map, flags);
 428}
 429
 430/*
 431 *  Add DMA resource to resources list.
 432 */
 433static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
 434                                             unsigned int option_flags,
 435                                             int size)
 436{
 437        unsigned char tmp[2];
 438
 439        isapnp_peek(tmp, size);
 440        pnp_register_dma_resource(dev, option_flags, tmp[0], tmp[1]);
 441}
 442
 443/*
 444 *  Add port resource to resources list.
 445 */
 446static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
 447                                              unsigned int option_flags,
 448                                              int size)
 449{
 450        unsigned char tmp[7];
 451        resource_size_t min, max, align, len;
 452        unsigned char flags;
 453
 454        isapnp_peek(tmp, size);
 455        min = (tmp[2] << 8) | tmp[1];
 456        max = (tmp[4] << 8) | tmp[3];
 457        align = tmp[5];
 458        len = tmp[6];
 459        flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
 460        pnp_register_port_resource(dev, option_flags,
 461                                   min, max, align, len, flags);
 462}
 463
 464/*
 465 *  Add fixed port resource to resources list.
 466 */
 467static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
 468                                                    unsigned int option_flags,
 469                                                    int size)
 470{
 471        unsigned char tmp[3];
 472        resource_size_t base, len;
 473
 474        isapnp_peek(tmp, size);
 475        base = (tmp[1] << 8) | tmp[0];
 476        len = tmp[2];
 477        pnp_register_port_resource(dev, option_flags, base, base, 0, len,
 478                                   IORESOURCE_IO_FIXED);
 479}
 480
 481/*
 482 *  Add memory resource to resources list.
 483 */
 484static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
 485                                             unsigned int option_flags,
 486                                             int size)
 487{
 488        unsigned char tmp[9];
 489        resource_size_t min, max, align, len;
 490        unsigned char flags;
 491
 492        isapnp_peek(tmp, size);
 493        min = ((tmp[2] << 8) | tmp[1]) << 8;
 494        max = ((tmp[4] << 8) | tmp[3]) << 8;
 495        align = (tmp[6] << 8) | tmp[5];
 496        len = ((tmp[8] << 8) | tmp[7]) << 8;
 497        flags = tmp[0];
 498        pnp_register_mem_resource(dev, option_flags,
 499                                  min, max, align, len, flags);
 500}
 501
 502/*
 503 *  Add 32-bit memory resource to resources list.
 504 */
 505static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
 506                                               unsigned int option_flags,
 507                                               int size)
 508{
 509        unsigned char tmp[17];
 510        resource_size_t min, max, align, len;
 511        unsigned char flags;
 512
 513        isapnp_peek(tmp, size);
 514        min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
 515        max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
 516        align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
 517        len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
 518        flags = tmp[0];
 519        pnp_register_mem_resource(dev, option_flags,
 520                                  min, max, align, len, flags);
 521}
 522
 523/*
 524 *  Add 32-bit fixed memory resource to resources list.
 525 */
 526static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
 527                                                     unsigned int option_flags,
 528                                                     int size)
 529{
 530        unsigned char tmp[9];
 531        resource_size_t base, len;
 532        unsigned char flags;
 533
 534        isapnp_peek(tmp, size);
 535        base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
 536        len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
 537        flags = tmp[0];
 538        pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
 539}
 540
 541/*
 542 *  Parse card name for ISA PnP device.
 543 */
 544static void __init
 545isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
 546{
 547        if (name[0] == '\0') {
 548                unsigned short size1 =
 549                    *size >= name_max ? (name_max - 1) : *size;
 550                isapnp_peek(name, size1);
 551                name[size1] = '\0';
 552                *size -= size1;
 553
 554                /* clean whitespace from end of string */
 555                while (size1 > 0 && name[--size1] == ' ')
 556                        name[size1] = '\0';
 557        }
 558}
 559
 560/*
 561 *  Parse resource map for logical device.
 562 */
 563static int __init isapnp_create_device(struct pnp_card *card,
 564                                       unsigned short size)
 565{
 566        int number = 0, skip = 0, priority, compat = 0;
 567        unsigned char type, tmp[17];
 568        unsigned int option_flags;
 569        struct pnp_dev *dev;
 570        u32 eisa_id;
 571        char id[8];
 572
 573        if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
 574                return 1;
 575        option_flags = 0;
 576        pnp_add_card_device(card, dev);
 577
 578        while (1) {
 579                if (isapnp_read_tag(&type, &size) < 0)
 580                        return 1;
 581                if (skip && type != _STAG_LOGDEVID && type != _STAG_END)
 582                        goto __skip;
 583                switch (type) {
 584                case _STAG_LOGDEVID:
 585                        if (size >= 5 && size <= 6) {
 586                                if ((dev =
 587                                     isapnp_parse_device(card, size,
 588                                                         number++)) == NULL)
 589                                        return 1;
 590                                size = 0;
 591                                skip = 0;
 592                                option_flags = 0;
 593                                pnp_add_card_device(card, dev);
 594                        } else {
 595                                skip = 1;
 596                        }
 597                        compat = 0;
 598                        break;
 599                case _STAG_COMPATDEVID:
 600                        if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {
 601                                isapnp_peek(tmp, 4);
 602                                eisa_id = tmp[0] | tmp[1] << 8 |
 603                                          tmp[2] << 16 | tmp[3] << 24;
 604                                pnp_eisa_id_to_string(eisa_id, id);
 605                                pnp_add_id(dev, id);
 606                                compat++;
 607                                size = 0;
 608                        }
 609                        break;
 610                case _STAG_IRQ:
 611                        if (size < 2 || size > 3)
 612                                goto __skip;
 613                        isapnp_parse_irq_resource(dev, option_flags, size);
 614                        size = 0;
 615                        break;
 616                case _STAG_DMA:
 617                        if (size != 2)
 618                                goto __skip;
 619                        isapnp_parse_dma_resource(dev, option_flags, size);
 620                        size = 0;
 621                        break;
 622                case _STAG_STARTDEP:
 623                        if (size > 1)
 624                                goto __skip;
 625                        priority = PNP_RES_PRIORITY_ACCEPTABLE;
 626                        if (size > 0) {
 627                                isapnp_peek(tmp, size);
 628                                priority = tmp[0];
 629                                size = 0;
 630                        }
 631                        option_flags = pnp_new_dependent_set(dev, priority);
 632                        break;
 633                case _STAG_ENDDEP:
 634                        if (size != 0)
 635                                goto __skip;
 636                        option_flags = 0;
 637                        break;
 638                case _STAG_IOPORT:
 639                        if (size != 7)
 640                                goto __skip;
 641                        isapnp_parse_port_resource(dev, option_flags, size);
 642                        size = 0;
 643                        break;
 644                case _STAG_FIXEDIO:
 645                        if (size != 3)
 646                                goto __skip;
 647                        isapnp_parse_fixed_port_resource(dev, option_flags,
 648                                                         size);
 649                        size = 0;
 650                        break;
 651                case _STAG_VENDOR:
 652                        break;
 653                case _LTAG_MEMRANGE:
 654                        if (size != 9)
 655                                goto __skip;
 656                        isapnp_parse_mem_resource(dev, option_flags, size);
 657                        size = 0;
 658                        break;
 659                case _LTAG_ANSISTR:
 660                        isapnp_parse_name(dev->name, sizeof(dev->name), &size);
 661                        break;
 662                case _LTAG_UNICODESTR:
 663                        /* silently ignore */
 664                        /* who use unicode for hardware identification? */
 665                        break;
 666                case _LTAG_VENDOR:
 667                        break;
 668                case _LTAG_MEM32RANGE:
 669                        if (size != 17)
 670                                goto __skip;
 671                        isapnp_parse_mem32_resource(dev, option_flags, size);
 672                        size = 0;
 673                        break;
 674                case _LTAG_FIXEDMEM32RANGE:
 675                        if (size != 9)
 676                                goto __skip;
 677                        isapnp_parse_fixed_mem32_resource(dev, option_flags,
 678                                                          size);
 679                        size = 0;
 680                        break;
 681                case _STAG_END:
 682                        if (size > 0)
 683                                isapnp_skip_bytes(size);
 684                        return 1;
 685                default:
 686                        dev_err(&dev->dev, "unknown tag %#x (card %i), "
 687                                "ignored\n", type, card->number);
 688                }
 689__skip:
 690                if (size > 0)
 691                        isapnp_skip_bytes(size);
 692        }
 693        return 0;
 694}
 695
 696/*
 697 *  Parse resource map for ISA PnP card.
 698 */
 699static void __init isapnp_parse_resource_map(struct pnp_card *card)
 700{
 701        unsigned char type, tmp[17];
 702        unsigned short size;
 703
 704        while (1) {
 705                if (isapnp_read_tag(&type, &size) < 0)
 706                        return;
 707                switch (type) {
 708                case _STAG_PNPVERNO:
 709                        if (size != 2)
 710                                goto __skip;
 711                        isapnp_peek(tmp, 2);
 712                        card->pnpver = tmp[0];
 713                        card->productver = tmp[1];
 714                        size = 0;
 715                        break;
 716                case _STAG_LOGDEVID:
 717                        if (size >= 5 && size <= 6) {
 718                                if (isapnp_create_device(card, size) == 1)
 719                                        return;
 720                                size = 0;
 721                        }
 722                        break;
 723                case _STAG_VENDOR:
 724                        break;
 725                case _LTAG_ANSISTR:
 726                        isapnp_parse_name(card->name, sizeof(card->name),
 727                                          &size);
 728                        break;
 729                case _LTAG_UNICODESTR:
 730                        /* silently ignore */
 731                        /* who use unicode for hardware identification? */
 732                        break;
 733                case _LTAG_VENDOR:
 734                        break;
 735                case _STAG_END:
 736                        if (size > 0)
 737                                isapnp_skip_bytes(size);
 738                        return;
 739                default:
 740                        dev_err(&card->dev, "unknown tag %#x, ignored\n",
 741                               type);
 742                }
 743__skip:
 744                if (size > 0)
 745                        isapnp_skip_bytes(size);
 746        }
 747}
 748
 749/*
 750 *  Build device list for all present ISA PnP devices.
 751 */
 752static int __init isapnp_build_device_list(void)
 753{
 754        int csn;
 755        unsigned char header[9];
 756        struct pnp_card *card;
 757        u32 eisa_id;
 758        char id[8];
 759
 760        isapnp_wait();
 761        isapnp_key();
 762        for (csn = 1; csn <= isapnp_csn_count; csn++) {
 763                isapnp_wake(csn);
 764                isapnp_peek(header, 9);
 765                eisa_id = header[0] | header[1] << 8 |
 766                          header[2] << 16 | header[3] << 24;
 767                pnp_eisa_id_to_string(eisa_id, id);
 768                card = pnp_alloc_card(&isapnp_protocol, csn, id);
 769                if (!card)
 770                        continue;
 771
 772                INIT_LIST_HEAD(&card->devices);
 773                card->serial =
 774                    (header[7] << 24) | (header[6] << 16) | (header[5] << 8) |
 775                    header[4];
 776                isapnp_checksum_value = 0x00;
 777                isapnp_parse_resource_map(card);
 778                if (isapnp_checksum_value != 0x00)
 779                        dev_err(&card->dev, "invalid checksum %#x\n",
 780                                isapnp_checksum_value);
 781                card->checksum = isapnp_checksum_value;
 782
 783                pnp_add_card(card);
 784        }
 785        isapnp_wait();
 786        return 0;
 787}
 788
 789/*
 790 *  Basic configuration routines.
 791 */
 792
 793int isapnp_present(void)
 794{
 795        struct pnp_card *card;
 796
 797        pnp_for_each_card(card) {
 798                if (card->protocol == &isapnp_protocol)
 799                        return 1;
 800        }
 801        return 0;
 802}
 803
 804int isapnp_cfg_begin(int csn, int logdev)
 805{
 806        if (csn < 1 || csn > isapnp_csn_count || logdev > 10)
 807                return -EINVAL;
 808        mutex_lock(&isapnp_cfg_mutex);
 809        isapnp_wait();
 810        isapnp_key();
 811        isapnp_wake(csn);
 812#if 0
 813        /* to avoid malfunction when the isapnptools package is used */
 814        /* we must set RDP to our value again */
 815        /* it is possible to set RDP only in the isolation phase */
 816        /*   Jens Thoms Toerring <Jens.Toerring@physik.fu-berlin.de> */
 817        isapnp_write_byte(0x02, 0x04);  /* clear CSN of card */
 818        mdelay(2);              /* is this necessary? */
 819        isapnp_wake(csn);       /* bring card into sleep state */
 820        isapnp_wake(0);         /* bring card into isolation state */
 821        isapnp_set_rdp();       /* reset the RDP port */
 822        udelay(1000);           /* delay 1000us */
 823        isapnp_write_byte(0x06, csn);   /* reset CSN to previous value */
 824        udelay(250);            /* is this necessary? */
 825#endif
 826        if (logdev >= 0)
 827                isapnp_device(logdev);
 828        return 0;
 829}
 830
 831int isapnp_cfg_end(void)
 832{
 833        isapnp_wait();
 834        mutex_unlock(&isapnp_cfg_mutex);
 835        return 0;
 836}
 837
 838/*
 839 *  Initialization.
 840 */
 841
 842EXPORT_SYMBOL(isapnp_protocol);
 843EXPORT_SYMBOL(isapnp_present);
 844EXPORT_SYMBOL(isapnp_cfg_begin);
 845EXPORT_SYMBOL(isapnp_cfg_end);
 846EXPORT_SYMBOL(isapnp_write_byte);
 847
 848static int isapnp_get_resources(struct pnp_dev *dev)
 849{
 850        int i, ret;
 851
 852        pnp_dbg(&dev->dev, "get resources\n");
 853        pnp_init_resources(dev);
 854        isapnp_cfg_begin(dev->card->number, dev->number);
 855        dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
 856        if (!dev->active)
 857                goto __end;
 858
 859        for (i = 0; i < ISAPNP_MAX_PORT; i++) {
 860                ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1));
 861                pnp_add_io_resource(dev, ret, ret,
 862                                    ret == 0 ? IORESOURCE_DISABLED : 0);
 863        }
 864        for (i = 0; i < ISAPNP_MAX_MEM; i++) {
 865                ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8;
 866                pnp_add_mem_resource(dev, ret, ret,
 867                                     ret == 0 ? IORESOURCE_DISABLED : 0);
 868        }
 869        for (i = 0; i < ISAPNP_MAX_IRQ; i++) {
 870                ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8;
 871                pnp_add_irq_resource(dev, ret,
 872                                     ret == 0 ? IORESOURCE_DISABLED : 0);
 873        }
 874        for (i = 0; i < ISAPNP_MAX_DMA; i++) {
 875                ret = isapnp_read_byte(ISAPNP_CFG_DMA + i);
 876                pnp_add_dma_resource(dev, ret,
 877                                     ret == 4 ? IORESOURCE_DISABLED : 0);
 878        }
 879
 880__end:
 881        isapnp_cfg_end();
 882        return 0;
 883}
 884
 885static int isapnp_set_resources(struct pnp_dev *dev)
 886{
 887        struct resource *res;
 888        int tmp;
 889
 890        pnp_dbg(&dev->dev, "set resources\n");
 891        isapnp_cfg_begin(dev->card->number, dev->number);
 892        dev->active = 1;
 893        for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
 894                res = pnp_get_resource(dev, IORESOURCE_IO, tmp);
 895                if (pnp_resource_enabled(res)) {
 896                        pnp_dbg(&dev->dev, "  set io  %d to %#llx\n",
 897                                tmp, (unsigned long long) res->start);
 898                        isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
 899                                          res->start);
 900                }
 901        }
 902        for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
 903                res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp);
 904                if (pnp_resource_enabled(res)) {
 905                        int irq = res->start;
 906                        if (irq == 2)
 907                                irq = 9;
 908                        pnp_dbg(&dev->dev, "  set irq %d to %d\n", tmp, irq);
 909                        isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq);
 910                }
 911        }
 912        for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
 913                res = pnp_get_resource(dev, IORESOURCE_DMA, tmp);
 914                if (pnp_resource_enabled(res)) {
 915                        pnp_dbg(&dev->dev, "  set dma %d to %lld\n",
 916                                tmp, (unsigned long long) res->start);
 917                        isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start);
 918                }
 919        }
 920        for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
 921                res = pnp_get_resource(dev, IORESOURCE_MEM, tmp);
 922                if (pnp_resource_enabled(res)) {
 923                        pnp_dbg(&dev->dev, "  set mem %d to %#llx\n",
 924                                tmp, (unsigned long long) res->start);
 925                        isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
 926                                          (res->start >> 8) & 0xffff);
 927                }
 928        }
 929        /* FIXME: We aren't handling 32bit mems properly here */
 930        isapnp_activate(dev->number);
 931        isapnp_cfg_end();
 932        return 0;
 933}
 934
 935static int isapnp_disable_resources(struct pnp_dev *dev)
 936{
 937        if (!dev->active)
 938                return -EINVAL;
 939        isapnp_cfg_begin(dev->card->number, dev->number);
 940        isapnp_deactivate(dev->number);
 941        dev->active = 0;
 942        isapnp_cfg_end();
 943        return 0;
 944}
 945
 946struct pnp_protocol isapnp_protocol = {
 947        .name = "ISA Plug and Play",
 948        .get = isapnp_get_resources,
 949        .set = isapnp_set_resources,
 950        .disable = isapnp_disable_resources,
 951};
 952
 953static int __init isapnp_init(void)
 954{
 955        int cards;
 956        struct pnp_card *card;
 957        struct pnp_dev *dev;
 958
 959        if (isapnp_disable) {
 960                printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n");
 961                return 0;
 962        }
 963#ifdef CONFIG_PPC
 964        if (check_legacy_ioport(_PIDXR) || check_legacy_ioport(_PNPWRP))
 965                return -EINVAL;
 966#endif
 967#ifdef ISAPNP_REGION_OK
 968        if (!request_region(_PIDXR, 1, "isapnp index")) {
 969                printk(KERN_ERR "isapnp: Index Register 0x%x already used\n",
 970                       _PIDXR);
 971                return -EBUSY;
 972        }
 973#endif
 974        if (!request_region(_PNPWRP, 1, "isapnp write")) {
 975                printk(KERN_ERR
 976                       "isapnp: Write Data Register 0x%x already used\n",
 977                       _PNPWRP);
 978#ifdef ISAPNP_REGION_OK
 979                release_region(_PIDXR, 1);
 980#endif
 981                return -EBUSY;
 982        }
 983
 984        if (pnp_register_protocol(&isapnp_protocol) < 0)
 985                return -EBUSY;
 986
 987        /*
 988         *      Print a message. The existing ISAPnP code is hanging machines
 989         *      so let the user know where.
 990         */
 991
 992        printk(KERN_INFO "isapnp: Scanning for PnP cards...\n");
 993        if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {
 994                isapnp_rdp |= 3;
 995                if (!request_region(isapnp_rdp, 1, "isapnp read")) {
 996                        printk(KERN_ERR
 997                               "isapnp: Read Data Register 0x%x already used\n",
 998                               isapnp_rdp);
 999#ifdef ISAPNP_REGION_OK
1000                        release_region(_PIDXR, 1);
1001#endif
1002                        release_region(_PNPWRP, 1);
1003                        return -EBUSY;
1004                }
1005                isapnp_set_rdp();
1006        }
1007        if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) {
1008                cards = isapnp_isolate();
1009                if (cards < 0 || (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {
1010#ifdef ISAPNP_REGION_OK
1011                        release_region(_PIDXR, 1);
1012#endif
1013                        release_region(_PNPWRP, 1);
1014                        printk(KERN_INFO
1015                               "isapnp: No Plug & Play device found\n");
1016                        return 0;
1017                }
1018                request_region(isapnp_rdp, 1, "isapnp read");
1019        }
1020        isapnp_build_device_list();
1021        cards = 0;
1022
1023        protocol_for_each_card(&isapnp_protocol, card) {
1024                cards++;
1025                if (isapnp_verbose) {
1026                        dev_info(&card->dev, "card '%s'\n",
1027                               card->name[0] ? card->name : "unknown");
1028                        if (isapnp_verbose < 2)
1029                                continue;
1030                        card_for_each_dev(card, dev) {
1031                                dev_info(&card->dev, "device '%s'\n",
1032                                       dev->name[0] ? dev->name : "unknown");
1033                        }
1034                }
1035        }
1036        if (cards)
1037                printk(KERN_INFO
1038                       "isapnp: %i Plug & Play card%s detected total\n", cards,
1039                       cards > 1 ? "s" : "");
1040        else
1041                printk(KERN_INFO "isapnp: No Plug & Play card found\n");
1042
1043        isapnp_proc_init();
1044        return 0;
1045}
1046
1047device_initcall(isapnp_init);
1048
1049/* format is: noisapnp */
1050
1051static int __init isapnp_setup_disable(char *str)
1052{
1053        isapnp_disable = 1;
1054        return 1;
1055}
1056
1057__setup("noisapnp", isapnp_setup_disable);
1058
1059/* format is: isapnp=rdp,reset,skip_pci_scan,verbose */
1060
1061static int __init isapnp_setup_isapnp(char *str)
1062{
1063        (void)((get_option(&str, &isapnp_rdp) == 2) &&
1064               (get_option(&str, &isapnp_reset) == 2) &&
1065               (get_option(&str, &isapnp_verbose) == 2));
1066        return 1;
1067}
1068
1069__setup("isapnp=", isapnp_setup_isapnp);
1070