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