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