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