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