Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  ISA Plug & Play support
0004  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
0005  *
0006  *  Changelog:
0007  *  2000-01-01  Added quirks handling for buggy hardware
0008  *      Peter Denison <peterd@pnd-pc.demon.co.uk>
0009  *  2000-06-14  Added isapnp_probe_devs() and isapnp_activate_dev()
0010  *      Christoph Hellwig <hch@infradead.org>
0011  *  2001-06-03  Added release_region calls to correspond with
0012  *      request_region calls when a failure occurs.  Also
0013  *      added KERN_* constants to printk() calls.
0014  *  2001-11-07  Added isapnp_{,un}register_driver calls along the lines
0015  *              of the pci driver interface
0016  *              Kai Germaschewski <kai.germaschewski@gmx.de>
0017  *  2002-06-06  Made the use of dma channel 0 configurable
0018  *              Gerald Teschl <gerald.teschl@univie.ac.at>
0019  *  2002-10-06  Ported to PnP Layer - Adam Belay <ambx1@neo.rr.com>
0020  *  2003-08-11  Resource Management Updates - Adam Belay <ambx1@neo.rr.com>
0021  */
0022 
0023 #include <linux/moduleparam.h>
0024 #include <linux/kernel.h>
0025 #include <linux/errno.h>
0026 #include <linux/delay.h>
0027 #include <linux/init.h>
0028 #include <linux/isapnp.h>
0029 #include <linux/mutex.h>
0030 #include <asm/io.h>
0031 
0032 #include "../base.h"
0033 
0034 #if 0
0035 #define ISAPNP_REGION_OK
0036 #endif
0037 
0038 int isapnp_disable;     /* Disable ISA PnP */
0039 static int isapnp_rdp;      /* Read Data Port */
0040 static int isapnp_reset = 1;    /* reset all PnP cards (deactivate) */
0041 static int isapnp_verbose = 1;  /* verbose mode */
0042 
0043 module_param(isapnp_disable, int, 0);
0044 MODULE_PARM_DESC(isapnp_disable, "ISA Plug & Play disable");
0045 module_param(isapnp_rdp, int, 0);
0046 MODULE_PARM_DESC(isapnp_rdp, "ISA Plug & Play read data port");
0047 module_param(isapnp_reset, int, 0);
0048 MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
0049 module_param(isapnp_verbose, int, 0);
0050 MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
0051 
0052 #define _PIDXR      0x279
0053 #define _PNPWRP     0xa79
0054 
0055 /* short tags */
0056 #define _STAG_PNPVERNO      0x01
0057 #define _STAG_LOGDEVID      0x02
0058 #define _STAG_COMPATDEVID   0x03
0059 #define _STAG_IRQ       0x04
0060 #define _STAG_DMA       0x05
0061 #define _STAG_STARTDEP      0x06
0062 #define _STAG_ENDDEP        0x07
0063 #define _STAG_IOPORT        0x08
0064 #define _STAG_FIXEDIO       0x09
0065 #define _STAG_VENDOR        0x0e
0066 #define _STAG_END       0x0f
0067 /* long tags */
0068 #define _LTAG_MEMRANGE      0x81
0069 #define _LTAG_ANSISTR       0x82
0070 #define _LTAG_UNICODESTR    0x83
0071 #define _LTAG_VENDOR        0x84
0072 #define _LTAG_MEM32RANGE    0x85
0073 #define _LTAG_FIXEDMEM32RANGE   0x86
0074 
0075 /* Logical device control and configuration registers */
0076 
0077 #define ISAPNP_CFG_ACTIVATE 0x30    /* byte */
0078 #define ISAPNP_CFG_MEM      0x40    /* 4 * dword */
0079 #define ISAPNP_CFG_PORT     0x60    /* 8 * word */
0080 #define ISAPNP_CFG_IRQ      0x70    /* 2 * word */
0081 #define ISAPNP_CFG_DMA      0x74    /* 2 * byte */
0082 
0083 /*
0084  * Sizes of ISAPNP logical device configuration register sets.
0085  * See PNP-ISA-v1.0a.pdf, Appendix A.
0086  */
0087 #define ISAPNP_MAX_MEM      4
0088 #define ISAPNP_MAX_PORT     8
0089 #define ISAPNP_MAX_IRQ      2
0090 #define ISAPNP_MAX_DMA      2
0091 
0092 static unsigned char isapnp_checksum_value;
0093 static DEFINE_MUTEX(isapnp_cfg_mutex);
0094 static int isapnp_csn_count;
0095 
0096 /* some prototypes */
0097 
0098 static inline void write_data(unsigned char x)
0099 {
0100     outb(x, _PNPWRP);
0101 }
0102 
0103 static inline void write_address(unsigned char x)
0104 {
0105     outb(x, _PIDXR);
0106     udelay(20);
0107 }
0108 
0109 static inline unsigned char read_data(void)
0110 {
0111     unsigned char val = inb(isapnp_rdp);
0112     return val;
0113 }
0114 
0115 unsigned char isapnp_read_byte(unsigned char idx)
0116 {
0117     write_address(idx);
0118     return read_data();
0119 }
0120 
0121 static unsigned short isapnp_read_word(unsigned char idx)
0122 {
0123     unsigned short val;
0124 
0125     val = isapnp_read_byte(idx);
0126     val = (val << 8) + isapnp_read_byte(idx + 1);
0127     return val;
0128 }
0129 
0130 void isapnp_write_byte(unsigned char idx, unsigned char val)
0131 {
0132     write_address(idx);
0133     write_data(val);
0134 }
0135 
0136 static void isapnp_write_word(unsigned char idx, unsigned short val)
0137 {
0138     isapnp_write_byte(idx, val >> 8);
0139     isapnp_write_byte(idx + 1, val);
0140 }
0141 
0142 static void isapnp_key(void)
0143 {
0144     unsigned char code = 0x6a, msb;
0145     int i;
0146 
0147     mdelay(1);
0148     write_address(0x00);
0149     write_address(0x00);
0150 
0151     write_address(code);
0152 
0153     for (i = 1; i < 32; i++) {
0154         msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7;
0155         code = (code >> 1) | msb;
0156         write_address(code);
0157     }
0158 }
0159 
0160 /* place all pnp cards in wait-for-key state */
0161 static void isapnp_wait(void)
0162 {
0163     isapnp_write_byte(0x02, 0x02);
0164 }
0165 
0166 static void isapnp_wake(unsigned char csn)
0167 {
0168     isapnp_write_byte(0x03, csn);
0169 }
0170 
0171 static void isapnp_device(unsigned char logdev)
0172 {
0173     isapnp_write_byte(0x07, logdev);
0174 }
0175 
0176 static void isapnp_activate(unsigned char logdev)
0177 {
0178     isapnp_device(logdev);
0179     isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 1);
0180     udelay(250);
0181 }
0182 
0183 static void isapnp_deactivate(unsigned char logdev)
0184 {
0185     isapnp_device(logdev);
0186     isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 0);
0187     udelay(500);
0188 }
0189 
0190 static void __init isapnp_peek(unsigned char *data, int bytes)
0191 {
0192     int i, j;
0193     unsigned char d = 0;
0194 
0195     for (i = 1; i <= bytes; i++) {
0196         for (j = 0; j < 20; j++) {
0197             d = isapnp_read_byte(0x05);
0198             if (d & 1)
0199                 break;
0200             udelay(100);
0201         }
0202         if (!(d & 1)) {
0203             if (data != NULL)
0204                 *data++ = 0xff;
0205             continue;
0206         }
0207         d = isapnp_read_byte(0x04); /* PRESDI */
0208         isapnp_checksum_value += d;
0209         if (data != NULL)
0210             *data++ = d;
0211     }
0212 }
0213 
0214 #define RDP_STEP    32  /* minimum is 4 */
0215 
0216 static int isapnp_next_rdp(void)
0217 {
0218     int rdp = isapnp_rdp;
0219     static int old_rdp = 0;
0220 
0221     if (old_rdp) {
0222         release_region(old_rdp, 1);
0223         old_rdp = 0;
0224     }
0225     while (rdp <= 0x3ff) {
0226         /*
0227          *      We cannot use NE2000 probe spaces for ISAPnP or we
0228          *      will lock up machines.
0229          */
0230         if ((rdp < 0x280 || rdp > 0x380)
0231             && request_region(rdp, 1, "ISAPnP")) {
0232             isapnp_rdp = rdp;
0233             old_rdp = rdp;
0234             return 0;
0235         }
0236         rdp += RDP_STEP;
0237     }
0238     return -1;
0239 }
0240 
0241 /* Set read port address */
0242 static inline void isapnp_set_rdp(void)
0243 {
0244     isapnp_write_byte(0x00, isapnp_rdp >> 2);
0245     udelay(100);
0246 }
0247 
0248 /*
0249  *  Perform an isolation. The port selection code now tries to avoid
0250  *  "dangerous to read" ports.
0251  */
0252 static int __init isapnp_isolate_rdp_select(void)
0253 {
0254     isapnp_wait();
0255     isapnp_key();
0256 
0257     /* Control: reset CSN and conditionally everything else too */
0258     isapnp_write_byte(0x02, isapnp_reset ? 0x05 : 0x04);
0259     mdelay(2);
0260 
0261     isapnp_wait();
0262     isapnp_key();
0263     isapnp_wake(0x00);
0264 
0265     if (isapnp_next_rdp() < 0) {
0266         isapnp_wait();
0267         return -1;
0268     }
0269 
0270     isapnp_set_rdp();
0271     udelay(1000);
0272     write_address(0x01);
0273     udelay(1000);
0274     return 0;
0275 }
0276 
0277 /*
0278  *  Isolate (assign uniqued CSN) to all ISA PnP devices.
0279  */
0280 static int __init isapnp_isolate(void)
0281 {
0282     unsigned char checksum = 0x6a;
0283     unsigned char chksum = 0x00;
0284     unsigned char bit = 0x00;
0285     int data;
0286     int csn = 0;
0287     int i;
0288     int iteration = 1;
0289 
0290     isapnp_rdp = 0x213;
0291     if (isapnp_isolate_rdp_select() < 0)
0292         return -1;
0293 
0294     while (1) {
0295         for (i = 1; i <= 64; i++) {
0296             data = read_data() << 8;
0297             udelay(250);
0298             data = data | read_data();
0299             udelay(250);
0300             if (data == 0x55aa)
0301                 bit = 0x01;
0302             checksum =
0303                 ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7)
0304                 | (checksum >> 1);
0305             bit = 0x00;
0306         }
0307         for (i = 65; i <= 72; i++) {
0308             data = read_data() << 8;
0309             udelay(250);
0310             data = data | read_data();
0311             udelay(250);
0312             if (data == 0x55aa)
0313                 chksum |= (1 << (i - 65));
0314         }
0315         if (checksum != 0x00 && checksum == chksum) {
0316             csn++;
0317 
0318             isapnp_write_byte(0x06, csn);
0319             udelay(250);
0320             iteration++;
0321             isapnp_wake(0x00);
0322             isapnp_set_rdp();
0323             udelay(1000);
0324             write_address(0x01);
0325             udelay(1000);
0326             goto __next;
0327         }
0328         if (iteration == 1) {
0329             isapnp_rdp += RDP_STEP;
0330             if (isapnp_isolate_rdp_select() < 0)
0331                 return -1;
0332         } else if (iteration > 1) {
0333             break;
0334         }
0335 __next:
0336         if (csn == 255)
0337             break;
0338         checksum = 0x6a;
0339         chksum = 0x00;
0340         bit = 0x00;
0341     }
0342     isapnp_wait();
0343     isapnp_csn_count = csn;
0344     return csn;
0345 }
0346 
0347 /*
0348  *  Read one tag from stream.
0349  */
0350 static int __init isapnp_read_tag(unsigned char *type, unsigned short *size)
0351 {
0352     unsigned char tag, tmp[2];
0353 
0354     isapnp_peek(&tag, 1);
0355     if (tag == 0)       /* invalid tag */
0356         return -1;
0357     if (tag & 0x80) {   /* large item */
0358         *type = tag;
0359         isapnp_peek(tmp, 2);
0360         *size = (tmp[1] << 8) | tmp[0];
0361     } else {
0362         *type = (tag >> 3) & 0x0f;
0363         *size = tag & 0x07;
0364     }
0365     if (*type == 0xff && *size == 0xffff)   /* probably invalid data */
0366         return -1;
0367     return 0;
0368 }
0369 
0370 /*
0371  *  Skip specified number of bytes from stream.
0372  */
0373 static void __init isapnp_skip_bytes(int count)
0374 {
0375     isapnp_peek(NULL, count);
0376 }
0377 
0378 /*
0379  *  Parse logical device tag.
0380  */
0381 static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
0382                           int size, int number)
0383 {
0384     unsigned char tmp[6];
0385     struct pnp_dev *dev;
0386     u32 eisa_id;
0387     char id[8];
0388 
0389     isapnp_peek(tmp, size);
0390     eisa_id = tmp[0] | tmp[1] << 8 | tmp[2] << 16 | tmp[3] << 24;
0391     pnp_eisa_id_to_string(eisa_id, id);
0392 
0393     dev = pnp_alloc_dev(&isapnp_protocol, number, id);
0394     if (!dev)
0395         return NULL;
0396 
0397     dev->card = card;
0398     dev->capabilities |= PNP_CONFIGURABLE;
0399     dev->capabilities |= PNP_READ;
0400     dev->capabilities |= PNP_WRITE;
0401     dev->capabilities |= PNP_DISABLE;
0402     pnp_init_resources(dev);
0403     return dev;
0404 }
0405 
0406 /*
0407  *  Add IRQ resource to resources list.
0408  */
0409 static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
0410                          unsigned int option_flags,
0411                          int size)
0412 {
0413     unsigned char tmp[3];
0414     unsigned long bits;
0415     pnp_irq_mask_t map;
0416     unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
0417 
0418     isapnp_peek(tmp, size);
0419     bits = (tmp[1] << 8) | tmp[0];
0420 
0421     bitmap_zero(map.bits, PNP_IRQ_NR);
0422     bitmap_copy(map.bits, &bits, 16);
0423 
0424     if (size > 2)
0425         flags = tmp[2];
0426 
0427     pnp_register_irq_resource(dev, option_flags, &map, flags);
0428 }
0429 
0430 /*
0431  *  Add DMA resource to resources list.
0432  */
0433 static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
0434                          unsigned int option_flags,
0435                          int size)
0436 {
0437     unsigned char tmp[2];
0438 
0439     isapnp_peek(tmp, size);
0440     pnp_register_dma_resource(dev, option_flags, tmp[0], tmp[1]);
0441 }
0442 
0443 /*
0444  *  Add port resource to resources list.
0445  */
0446 static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
0447                           unsigned int option_flags,
0448                           int size)
0449 {
0450     unsigned char tmp[7];
0451     resource_size_t min, max, align, len;
0452     unsigned char flags;
0453 
0454     isapnp_peek(tmp, size);
0455     min = (tmp[2] << 8) | tmp[1];
0456     max = (tmp[4] << 8) | tmp[3];
0457     align = tmp[5];
0458     len = tmp[6];
0459     flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
0460     pnp_register_port_resource(dev, option_flags,
0461                    min, max, align, len, flags);
0462 }
0463 
0464 /*
0465  *  Add fixed port resource to resources list.
0466  */
0467 static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
0468                             unsigned int option_flags,
0469                             int size)
0470 {
0471     unsigned char tmp[3];
0472     resource_size_t base, len;
0473 
0474     isapnp_peek(tmp, size);
0475     base = (tmp[1] << 8) | tmp[0];
0476     len = tmp[2];
0477     pnp_register_port_resource(dev, option_flags, base, base, 0, len,
0478                    IORESOURCE_IO_FIXED);
0479 }
0480 
0481 /*
0482  *  Add memory resource to resources list.
0483  */
0484 static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
0485                          unsigned int option_flags,
0486                          int size)
0487 {
0488     unsigned char tmp[9];
0489     resource_size_t min, max, align, len;
0490     unsigned char flags;
0491 
0492     isapnp_peek(tmp, size);
0493     min = ((tmp[2] << 8) | tmp[1]) << 8;
0494     max = ((tmp[4] << 8) | tmp[3]) << 8;
0495     align = (tmp[6] << 8) | tmp[5];
0496     len = ((tmp[8] << 8) | tmp[7]) << 8;
0497     flags = tmp[0];
0498     pnp_register_mem_resource(dev, option_flags,
0499                   min, max, align, len, flags);
0500 }
0501 
0502 /*
0503  *  Add 32-bit memory resource to resources list.
0504  */
0505 static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
0506                            unsigned int option_flags,
0507                            int size)
0508 {
0509     unsigned char tmp[17];
0510     resource_size_t min, max, align, len;
0511     unsigned char flags;
0512 
0513     isapnp_peek(tmp, size);
0514     min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
0515     max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
0516     align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
0517     len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
0518     flags = tmp[0];
0519     pnp_register_mem_resource(dev, option_flags,
0520                   min, max, align, len, flags);
0521 }
0522 
0523 /*
0524  *  Add 32-bit fixed memory resource to resources list.
0525  */
0526 static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
0527                              unsigned int option_flags,
0528                              int size)
0529 {
0530     unsigned char tmp[9];
0531     resource_size_t base, len;
0532     unsigned char flags;
0533 
0534     isapnp_peek(tmp, size);
0535     base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
0536     len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
0537     flags = tmp[0];
0538     pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
0539 }
0540 
0541 /*
0542  *  Parse card name for ISA PnP device.
0543  */
0544 static void __init
0545 isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
0546 {
0547     if (name[0] == '\0') {
0548         unsigned short size1 =
0549             *size >= name_max ? (name_max - 1) : *size;
0550         isapnp_peek(name, size1);
0551         name[size1] = '\0';
0552         *size -= size1;
0553 
0554         /* clean whitespace from end of string */
0555         while (size1 > 0 && name[--size1] == ' ')
0556             name[size1] = '\0';
0557     }
0558 }
0559 
0560 /*
0561  *  Parse resource map for logical device.
0562  */
0563 static int __init isapnp_create_device(struct pnp_card *card,
0564                        unsigned short size)
0565 {
0566     int number = 0, skip = 0, priority, compat = 0;
0567     unsigned char type, tmp[17];
0568     unsigned int option_flags;
0569     struct pnp_dev *dev;
0570     u32 eisa_id;
0571     char id[8];
0572 
0573     if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
0574         return 1;
0575     option_flags = 0;
0576     pnp_add_card_device(card, dev);
0577 
0578     while (1) {
0579         if (isapnp_read_tag(&type, &size) < 0)
0580             return 1;
0581         if (skip && type != _STAG_LOGDEVID && type != _STAG_END)
0582             goto __skip;
0583         switch (type) {
0584         case _STAG_LOGDEVID:
0585             if (size >= 5 && size <= 6) {
0586                 if ((dev =
0587                      isapnp_parse_device(card, size,
0588                              number++)) == NULL)
0589                     return 1;
0590                 size = 0;
0591                 skip = 0;
0592                 option_flags = 0;
0593                 pnp_add_card_device(card, dev);
0594             } else {
0595                 skip = 1;
0596             }
0597             compat = 0;
0598             break;
0599         case _STAG_COMPATDEVID:
0600             if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {
0601                 isapnp_peek(tmp, 4);
0602                 eisa_id = tmp[0] | tmp[1] << 8 |
0603                       tmp[2] << 16 | tmp[3] << 24;
0604                 pnp_eisa_id_to_string(eisa_id, id);
0605                 pnp_add_id(dev, id);
0606                 compat++;
0607                 size = 0;
0608             }
0609             break;
0610         case _STAG_IRQ:
0611             if (size < 2 || size > 3)
0612                 goto __skip;
0613             isapnp_parse_irq_resource(dev, option_flags, size);
0614             size = 0;
0615             break;
0616         case _STAG_DMA:
0617             if (size != 2)
0618                 goto __skip;
0619             isapnp_parse_dma_resource(dev, option_flags, size);
0620             size = 0;
0621             break;
0622         case _STAG_STARTDEP:
0623             if (size > 1)
0624                 goto __skip;
0625             priority = PNP_RES_PRIORITY_ACCEPTABLE;
0626             if (size > 0) {
0627                 isapnp_peek(tmp, size);
0628                 priority = tmp[0];
0629                 size = 0;
0630             }
0631             option_flags = pnp_new_dependent_set(dev, priority);
0632             break;
0633         case _STAG_ENDDEP:
0634             if (size != 0)
0635                 goto __skip;
0636             option_flags = 0;
0637             break;
0638         case _STAG_IOPORT:
0639             if (size != 7)
0640                 goto __skip;
0641             isapnp_parse_port_resource(dev, option_flags, size);
0642             size = 0;
0643             break;
0644         case _STAG_FIXEDIO:
0645             if (size != 3)
0646                 goto __skip;
0647             isapnp_parse_fixed_port_resource(dev, option_flags,
0648                              size);
0649             size = 0;
0650             break;
0651         case _STAG_VENDOR:
0652             break;
0653         case _LTAG_MEMRANGE:
0654             if (size != 9)
0655                 goto __skip;
0656             isapnp_parse_mem_resource(dev, option_flags, size);
0657             size = 0;
0658             break;
0659         case _LTAG_ANSISTR:
0660             isapnp_parse_name(dev->name, sizeof(dev->name), &size);
0661             break;
0662         case _LTAG_UNICODESTR:
0663             /* silently ignore */
0664             /* who use unicode for hardware identification? */
0665             break;
0666         case _LTAG_VENDOR:
0667             break;
0668         case _LTAG_MEM32RANGE:
0669             if (size != 17)
0670                 goto __skip;
0671             isapnp_parse_mem32_resource(dev, option_flags, size);
0672             size = 0;
0673             break;
0674         case _LTAG_FIXEDMEM32RANGE:
0675             if (size != 9)
0676                 goto __skip;
0677             isapnp_parse_fixed_mem32_resource(dev, option_flags,
0678                               size);
0679             size = 0;
0680             break;
0681         case _STAG_END:
0682             if (size > 0)
0683                 isapnp_skip_bytes(size);
0684             return 1;
0685         default:
0686             dev_err(&dev->dev, "unknown tag %#x (card %i), "
0687                 "ignored\n", type, card->number);
0688         }
0689 __skip:
0690         if (size > 0)
0691             isapnp_skip_bytes(size);
0692     }
0693     return 0;
0694 }
0695 
0696 /*
0697  *  Parse resource map for ISA PnP card.
0698  */
0699 static void __init isapnp_parse_resource_map(struct pnp_card *card)
0700 {
0701     unsigned char type, tmp[17];
0702     unsigned short size;
0703 
0704     while (1) {
0705         if (isapnp_read_tag(&type, &size) < 0)
0706             return;
0707         switch (type) {
0708         case _STAG_PNPVERNO:
0709             if (size != 2)
0710                 goto __skip;
0711             isapnp_peek(tmp, 2);
0712             card->pnpver = tmp[0];
0713             card->productver = tmp[1];
0714             size = 0;
0715             break;
0716         case _STAG_LOGDEVID:
0717             if (size >= 5 && size <= 6) {
0718                 if (isapnp_create_device(card, size) == 1)
0719                     return;
0720                 size = 0;
0721             }
0722             break;
0723         case _STAG_VENDOR:
0724             break;
0725         case _LTAG_ANSISTR:
0726             isapnp_parse_name(card->name, sizeof(card->name),
0727                       &size);
0728             break;
0729         case _LTAG_UNICODESTR:
0730             /* silently ignore */
0731             /* who use unicode for hardware identification? */
0732             break;
0733         case _LTAG_VENDOR:
0734             break;
0735         case _STAG_END:
0736             if (size > 0)
0737                 isapnp_skip_bytes(size);
0738             return;
0739         default:
0740             dev_err(&card->dev, "unknown tag %#x, ignored\n",
0741                    type);
0742         }
0743 __skip:
0744         if (size > 0)
0745             isapnp_skip_bytes(size);
0746     }
0747 }
0748 
0749 /*
0750  *  Build device list for all present ISA PnP devices.
0751  */
0752 static int __init isapnp_build_device_list(void)
0753 {
0754     int csn;
0755     unsigned char header[9];
0756     struct pnp_card *card;
0757     u32 eisa_id;
0758     char id[8];
0759 
0760     isapnp_wait();
0761     isapnp_key();
0762     for (csn = 1; csn <= isapnp_csn_count; csn++) {
0763         isapnp_wake(csn);
0764         isapnp_peek(header, 9);
0765         eisa_id = header[0] | header[1] << 8 |
0766               header[2] << 16 | header[3] << 24;
0767         pnp_eisa_id_to_string(eisa_id, id);
0768         card = pnp_alloc_card(&isapnp_protocol, csn, id);
0769         if (!card)
0770             continue;
0771 
0772         INIT_LIST_HEAD(&card->devices);
0773         card->serial =
0774             (header[7] << 24) | (header[6] << 16) | (header[5] << 8) |
0775             header[4];
0776         isapnp_checksum_value = 0x00;
0777         isapnp_parse_resource_map(card);
0778         if (isapnp_checksum_value != 0x00)
0779             dev_err(&card->dev, "invalid checksum %#x\n",
0780                 isapnp_checksum_value);
0781         card->checksum = isapnp_checksum_value;
0782 
0783         pnp_add_card(card);
0784     }
0785     isapnp_wait();
0786     return 0;
0787 }
0788 
0789 /*
0790  *  Basic configuration routines.
0791  */
0792 
0793 int isapnp_present(void)
0794 {
0795     struct pnp_card *card;
0796 
0797     pnp_for_each_card(card) {
0798         if (card->protocol == &isapnp_protocol)
0799             return 1;
0800     }
0801     return 0;
0802 }
0803 
0804 int isapnp_cfg_begin(int csn, int logdev)
0805 {
0806     if (csn < 1 || csn > isapnp_csn_count || logdev > 10)
0807         return -EINVAL;
0808     mutex_lock(&isapnp_cfg_mutex);
0809     isapnp_wait();
0810     isapnp_key();
0811     isapnp_wake(csn);
0812 #if 0
0813     /* to avoid malfunction when the isapnptools package is used */
0814     /* we must set RDP to our value again */
0815     /* it is possible to set RDP only in the isolation phase */
0816     /*   Jens Thoms Toerring <Jens.Toerring@physik.fu-berlin.de> */
0817     isapnp_write_byte(0x02, 0x04);  /* clear CSN of card */
0818     mdelay(2);      /* is this necessary? */
0819     isapnp_wake(csn);   /* bring card into sleep state */
0820     isapnp_wake(0);     /* bring card into isolation state */
0821     isapnp_set_rdp();   /* reset the RDP port */
0822     udelay(1000);       /* delay 1000us */
0823     isapnp_write_byte(0x06, csn);   /* reset CSN to previous value */
0824     udelay(250);        /* is this necessary? */
0825 #endif
0826     if (logdev >= 0)
0827         isapnp_device(logdev);
0828     return 0;
0829 }
0830 
0831 int isapnp_cfg_end(void)
0832 {
0833     isapnp_wait();
0834     mutex_unlock(&isapnp_cfg_mutex);
0835     return 0;
0836 }
0837 
0838 /*
0839  *  Initialization.
0840  */
0841 
0842 EXPORT_SYMBOL(isapnp_protocol);
0843 EXPORT_SYMBOL(isapnp_present);
0844 EXPORT_SYMBOL(isapnp_cfg_begin);
0845 EXPORT_SYMBOL(isapnp_cfg_end);
0846 EXPORT_SYMBOL(isapnp_write_byte);
0847 
0848 static int isapnp_get_resources(struct pnp_dev *dev)
0849 {
0850     int i, ret;
0851 
0852     pnp_dbg(&dev->dev, "get resources\n");
0853     pnp_init_resources(dev);
0854     isapnp_cfg_begin(dev->card->number, dev->number);
0855     dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
0856     if (!dev->active)
0857         goto __end;
0858 
0859     for (i = 0; i < ISAPNP_MAX_PORT; i++) {
0860         ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1));
0861         pnp_add_io_resource(dev, ret, ret,
0862                     ret == 0 ? IORESOURCE_DISABLED : 0);
0863     }
0864     for (i = 0; i < ISAPNP_MAX_MEM; i++) {
0865         ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8;
0866         pnp_add_mem_resource(dev, ret, ret,
0867                      ret == 0 ? IORESOURCE_DISABLED : 0);
0868     }
0869     for (i = 0; i < ISAPNP_MAX_IRQ; i++) {
0870         ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8;
0871         pnp_add_irq_resource(dev, ret,
0872                      ret == 0 ? IORESOURCE_DISABLED : 0);
0873     }
0874     for (i = 0; i < ISAPNP_MAX_DMA; i++) {
0875         ret = isapnp_read_byte(ISAPNP_CFG_DMA + i);
0876         pnp_add_dma_resource(dev, ret,
0877                      ret == 4 ? IORESOURCE_DISABLED : 0);
0878     }
0879 
0880 __end:
0881     isapnp_cfg_end();
0882     return 0;
0883 }
0884 
0885 static int isapnp_set_resources(struct pnp_dev *dev)
0886 {
0887     struct resource *res;
0888     int tmp;
0889 
0890     pnp_dbg(&dev->dev, "set resources\n");
0891     isapnp_cfg_begin(dev->card->number, dev->number);
0892     dev->active = 1;
0893     for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
0894         res = pnp_get_resource(dev, IORESOURCE_IO, tmp);
0895         if (pnp_resource_enabled(res)) {
0896             pnp_dbg(&dev->dev, "  set io  %d to %#llx\n",
0897                 tmp, (unsigned long long) res->start);
0898             isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
0899                       res->start);
0900         }
0901     }
0902     for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
0903         res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp);
0904         if (pnp_resource_enabled(res)) {
0905             int irq = res->start;
0906             if (irq == 2)
0907                 irq = 9;
0908             pnp_dbg(&dev->dev, "  set irq %d to %d\n", tmp, irq);
0909             isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq);
0910         }
0911     }
0912     for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
0913         res = pnp_get_resource(dev, IORESOURCE_DMA, tmp);
0914         if (pnp_resource_enabled(res)) {
0915             pnp_dbg(&dev->dev, "  set dma %d to %lld\n",
0916                 tmp, (unsigned long long) res->start);
0917             isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start);
0918         }
0919     }
0920     for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
0921         res = pnp_get_resource(dev, IORESOURCE_MEM, tmp);
0922         if (pnp_resource_enabled(res)) {
0923             pnp_dbg(&dev->dev, "  set mem %d to %#llx\n",
0924                 tmp, (unsigned long long) res->start);
0925             isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
0926                       (res->start >> 8) & 0xffff);
0927         }
0928     }
0929     /* FIXME: We aren't handling 32bit mems properly here */
0930     isapnp_activate(dev->number);
0931     isapnp_cfg_end();
0932     return 0;
0933 }
0934 
0935 static int isapnp_disable_resources(struct pnp_dev *dev)
0936 {
0937     if (!dev->active)
0938         return -EINVAL;
0939     isapnp_cfg_begin(dev->card->number, dev->number);
0940     isapnp_deactivate(dev->number);
0941     dev->active = 0;
0942     isapnp_cfg_end();
0943     return 0;
0944 }
0945 
0946 struct pnp_protocol isapnp_protocol = {
0947     .name = "ISA Plug and Play",
0948     .get = isapnp_get_resources,
0949     .set = isapnp_set_resources,
0950     .disable = isapnp_disable_resources,
0951 };
0952 
0953 static int __init isapnp_init(void)
0954 {
0955     int cards;
0956     struct pnp_card *card;
0957     struct pnp_dev *dev;
0958 
0959     if (isapnp_disable) {
0960         printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n");
0961         return 0;
0962     }
0963 #ifdef CONFIG_PPC
0964     if (check_legacy_ioport(_PIDXR) || check_legacy_ioport(_PNPWRP))
0965         return -EINVAL;
0966 #endif
0967 #ifdef ISAPNP_REGION_OK
0968     if (!request_region(_PIDXR, 1, "isapnp index")) {
0969         printk(KERN_ERR "isapnp: Index Register 0x%x already used\n",
0970                _PIDXR);
0971         return -EBUSY;
0972     }
0973 #endif
0974     if (!request_region(_PNPWRP, 1, "isapnp write")) {
0975         printk(KERN_ERR
0976                "isapnp: Write Data Register 0x%x already used\n",
0977                _PNPWRP);
0978 #ifdef ISAPNP_REGION_OK
0979         release_region(_PIDXR, 1);
0980 #endif
0981         return -EBUSY;
0982     }
0983 
0984     if (pnp_register_protocol(&isapnp_protocol) < 0)
0985         return -EBUSY;
0986 
0987     /*
0988      *      Print a message. The existing ISAPnP code is hanging machines
0989      *      so let the user know where.
0990      */
0991 
0992     printk(KERN_INFO "isapnp: Scanning for PnP cards...\n");
0993     if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {
0994         isapnp_rdp |= 3;
0995         if (!request_region(isapnp_rdp, 1, "isapnp read")) {
0996             printk(KERN_ERR
0997                    "isapnp: Read Data Register 0x%x already used\n",
0998                    isapnp_rdp);
0999 #ifdef ISAPNP_REGION_OK
1000             release_region(_PIDXR, 1);
1001 #endif
1002             release_region(_PNPWRP, 1);
1003             return -EBUSY;
1004         }
1005         isapnp_set_rdp();
1006     }
1007     if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) {
1008         cards = isapnp_isolate();
1009         if (cards < 0 || (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {
1010 #ifdef ISAPNP_REGION_OK
1011             release_region(_PIDXR, 1);
1012 #endif
1013             release_region(_PNPWRP, 1);
1014             printk(KERN_INFO
1015                    "isapnp: No Plug & Play device found\n");
1016             return 0;
1017         }
1018         request_region(isapnp_rdp, 1, "isapnp read");
1019     }
1020     isapnp_build_device_list();
1021     cards = 0;
1022 
1023     protocol_for_each_card(&isapnp_protocol, card) {
1024         cards++;
1025         if (isapnp_verbose) {
1026             dev_info(&card->dev, "card '%s'\n",
1027                    card->name[0] ? card->name : "unknown");
1028             if (isapnp_verbose < 2)
1029                 continue;
1030             card_for_each_dev(card, dev) {
1031                 dev_info(&card->dev, "device '%s'\n",
1032                        dev->name[0] ? dev->name : "unknown");
1033             }
1034         }
1035     }
1036     if (cards)
1037         printk(KERN_INFO
1038                "isapnp: %i Plug & Play card%s detected total\n", cards,
1039                cards > 1 ? "s" : "");
1040     else
1041         printk(KERN_INFO "isapnp: No Plug & Play card found\n");
1042 
1043     isapnp_proc_init();
1044     return 0;
1045 }
1046 
1047 device_initcall(isapnp_init);
1048 
1049 /* format is: noisapnp */
1050 
1051 static int __init isapnp_setup_disable(char *str)
1052 {
1053     isapnp_disable = 1;
1054     return 1;
1055 }
1056 
1057 __setup("noisapnp", isapnp_setup_disable);
1058 
1059 /* format is: isapnp=rdp,reset,skip_pci_scan,verbose */
1060 
1061 static int __init isapnp_setup_isapnp(char *str)
1062 {
1063     (void)((get_option(&str, &isapnp_rdp) == 2) &&
1064            (get_option(&str, &isapnp_reset) == 2) &&
1065            (get_option(&str, &isapnp_verbose) == 2));
1066     return 1;
1067 }
1068 
1069 __setup("isapnp=", isapnp_setup_isapnp);