2 * ISA Plug & Play support
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
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.
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.
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.
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>
37 #include <linux/config.h>
38 #include <linux/module.h>
39 #include <linux/kernel.h>
40 #include <linux/errno.h>
41 #include <linux/slab.h>
42 #include <linux/delay.h>
43 #include <linux/init.h>
44 #include <linux/isapnp.h>
48 #define ISAPNP_REGION_OK
54 int isapnp_disable
; /* Disable ISA PnP */
55 static int isapnp_rdp
; /* Read Data Port */
56 static int isapnp_reset
= 1; /* reset all PnP cards (deactivate) */
57 static int isapnp_verbose
= 1; /* verbose mode */
59 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
60 MODULE_DESCRIPTION("Generic ISA Plug & Play support");
61 module_param(isapnp_disable
, int, 0);
62 MODULE_PARM_DESC(isapnp_disable
, "ISA Plug & Play disable");
63 module_param(isapnp_rdp
, int, 0);
64 MODULE_PARM_DESC(isapnp_rdp
, "ISA Plug & Play read data port");
65 module_param(isapnp_reset
, int, 0);
66 MODULE_PARM_DESC(isapnp_reset
, "ISA Plug & Play reset all cards");
67 module_param(isapnp_verbose
, int, 0);
68 MODULE_PARM_DESC(isapnp_verbose
, "ISA Plug & Play verbose mode");
69 MODULE_LICENSE("GPL");
75 #define _STAG_PNPVERNO 0x01
76 #define _STAG_LOGDEVID 0x02
77 #define _STAG_COMPATDEVID 0x03
78 #define _STAG_IRQ 0x04
79 #define _STAG_DMA 0x05
80 #define _STAG_STARTDEP 0x06
81 #define _STAG_ENDDEP 0x07
82 #define _STAG_IOPORT 0x08
83 #define _STAG_FIXEDIO 0x09
84 #define _STAG_VENDOR 0x0e
85 #define _STAG_END 0x0f
87 #define _LTAG_MEMRANGE 0x81
88 #define _LTAG_ANSISTR 0x82
89 #define _LTAG_UNICODESTR 0x83
90 #define _LTAG_VENDOR 0x84
91 #define _LTAG_MEM32RANGE 0x85
92 #define _LTAG_FIXEDMEM32RANGE 0x86
94 static unsigned char isapnp_checksum_value
;
95 static DECLARE_MUTEX(isapnp_cfg_mutex
);
96 static int isapnp_detected
;
97 static int isapnp_csn_count
;
101 static inline void write_data(unsigned char x
)
106 static inline void write_address(unsigned char x
)
112 static inline unsigned char read_data(void)
114 unsigned char val
= inb(isapnp_rdp
);
118 unsigned char isapnp_read_byte(unsigned char idx
)
124 static unsigned short isapnp_read_word(unsigned char idx
)
128 val
= isapnp_read_byte(idx
);
129 val
= (val
<< 8) + isapnp_read_byte(idx
+1);
133 void isapnp_write_byte(unsigned char idx
, unsigned char val
)
139 static void isapnp_write_word(unsigned char idx
, unsigned short val
)
141 isapnp_write_byte(idx
, val
>> 8);
142 isapnp_write_byte(idx
+1, val
);
145 static void isapnp_key(void)
147 unsigned char code
= 0x6a, msb
;
156 for (i
= 1; i
< 32; i
++) {
157 msb
= ((code
& 0x01) ^ ((code
& 0x02) >> 1)) << 7;
158 code
= (code
>> 1) | msb
;
163 /* place all pnp cards in wait-for-key state */
164 static void isapnp_wait(void)
166 isapnp_write_byte(0x02, 0x02);
169 static void isapnp_wake(unsigned char csn
)
171 isapnp_write_byte(0x03, csn
);
174 static void isapnp_device(unsigned char logdev
)
176 isapnp_write_byte(0x07, logdev
);
179 static void isapnp_activate(unsigned char logdev
)
181 isapnp_device(logdev
);
182 isapnp_write_byte(ISAPNP_CFG_ACTIVATE
, 1);
186 static void isapnp_deactivate(unsigned char logdev
)
188 isapnp_device(logdev
);
189 isapnp_write_byte(ISAPNP_CFG_ACTIVATE
, 0);
193 static void __init
isapnp_peek(unsigned char *data
, int bytes
)
198 for (i
= 1; i
<= bytes
; i
++) {
199 for (j
= 0; j
< 20; j
++) {
200 d
= isapnp_read_byte(0x05);
210 d
= isapnp_read_byte(0x04); /* PRESDI */
211 isapnp_checksum_value
+= d
;
217 #define RDP_STEP 32 /* minimum is 4 */
219 static int isapnp_next_rdp(void)
221 int rdp
= isapnp_rdp
;
222 static int old_rdp
= 0;
226 release_region(old_rdp
, 1);
229 while (rdp
<= 0x3ff) {
231 * We cannot use NE2000 probe spaces for ISAPnP or we
232 * will lock up machines.
234 if ((rdp
< 0x280 || rdp
> 0x380) && request_region(rdp
, 1, "ISAPnP"))
245 /* Set read port address */
246 static inline void isapnp_set_rdp(void)
248 isapnp_write_byte(0x00, isapnp_rdp
>> 2);
253 * Perform an isolation. The port selection code now tries to avoid
254 * "dangerous to read" ports.
257 static int __init
isapnp_isolate_rdp_select(void)
262 /* Control: reset CSN and conditionally everything else too */
263 isapnp_write_byte(0x02, isapnp_reset
? 0x05 : 0x04);
270 if (isapnp_next_rdp() < 0) {
283 * Isolate (assign uniqued CSN) to all ISA PnP devices.
286 static int __init
isapnp_isolate(void)
288 unsigned char checksum
= 0x6a;
289 unsigned char chksum
= 0x00;
290 unsigned char bit
= 0x00;
297 if (isapnp_isolate_rdp_select() < 0)
301 for (i
= 1; i
<= 64; i
++) {
302 data
= read_data() << 8;
304 data
= data
| read_data();
308 checksum
= ((((checksum
^ (checksum
>> 1)) & 0x01) ^ bit
) << 7) | (checksum
>> 1);
311 for (i
= 65; i
<= 72; i
++) {
312 data
= read_data() << 8;
314 data
= data
| read_data();
317 chksum
|= (1 << (i
- 65));
319 if (checksum
!= 0x00 && checksum
== chksum
) {
322 isapnp_write_byte(0x06, csn
);
332 if (iteration
== 1) {
333 isapnp_rdp
+= RDP_STEP
;
334 if (isapnp_isolate_rdp_select() < 0)
336 } else if (iteration
> 1) {
347 isapnp_csn_count
= csn
;
352 * Read one tag from stream.
355 static int __init
isapnp_read_tag(unsigned char *type
, unsigned short *size
)
357 unsigned char tag
, tmp
[2];
359 isapnp_peek(&tag
, 1);
360 if (tag
== 0) /* invalid tag */
362 if (tag
& 0x80) { /* large item */
365 *size
= (tmp
[1] << 8) | tmp
[0];
367 *type
= (tag
>> 3) & 0x0f;
371 printk(KERN_DEBUG
"tag = 0x%x, type = 0x%x, size = %i\n", tag
, *type
, *size
);
373 if (type
== 0) /* wrong type */
375 if (*type
== 0xff && *size
== 0xffff) /* probably invalid data */
381 * Skip specified number of bytes from stream.
384 static void __init
isapnp_skip_bytes(int count
)
386 isapnp_peek(NULL
, count
);
393 static void isapnp_parse_id(struct pnp_dev
* dev
, unsigned short vendor
, unsigned short device
)
398 id
= kcalloc(1, sizeof(struct pnp_id
), GFP_KERNEL
);
401 sprintf(id
->id
, "%c%c%c%x%x%x%x",
402 'A' + ((vendor
>> 2) & 0x3f) - 1,
403 'A' + (((vendor
& 3) << 3) | ((vendor
>> 13) & 7)) - 1,
404 'A' + ((vendor
>> 8) & 0x1f) - 1,
405 (device
>> 4) & 0x0f,
407 (device
>> 12) & 0x0f,
408 (device
>> 8) & 0x0f);
413 * Parse logical device tag.
416 static struct pnp_dev
* __init
isapnp_parse_device(struct pnp_card
*card
, int size
, int number
)
418 unsigned char tmp
[6];
421 isapnp_peek(tmp
, size
);
422 dev
= kcalloc(1, sizeof(struct pnp_dev
), GFP_KERNEL
);
425 dev
->number
= number
;
426 isapnp_parse_id(dev
, (tmp
[1] << 8) | tmp
[0], (tmp
[3] << 8) | tmp
[2]);
430 dev
->regs
|= tmp
[5] << 8;
431 dev
->protocol
= &isapnp_protocol
;
432 dev
->capabilities
|= PNP_CONFIGURABLE
;
433 dev
->capabilities
|= PNP_READ
;
434 dev
->capabilities
|= PNP_WRITE
;
435 dev
->capabilities
|= PNP_DISABLE
;
436 pnp_init_resource_table(&dev
->res
);
442 * Add IRQ resource to resources list.
445 static void __init
isapnp_parse_irq_resource(struct pnp_option
*option
,
448 unsigned char tmp
[3];
452 isapnp_peek(tmp
, size
);
453 irq
= kcalloc(1, sizeof(struct pnp_irq
), GFP_KERNEL
);
456 bits
= (tmp
[1] << 8) | tmp
[0];
457 bitmap_copy(irq
->map
, &bits
, 16);
461 irq
->flags
= IORESOURCE_IRQ_HIGHEDGE
;
462 pnp_register_irq_resource(option
, irq
);
467 * Add DMA resource to resources list.
470 static void __init
isapnp_parse_dma_resource(struct pnp_option
*option
,
473 unsigned char tmp
[2];
476 isapnp_peek(tmp
, size
);
477 dma
= kcalloc(1, sizeof(struct pnp_dma
), GFP_KERNEL
);
482 pnp_register_dma_resource(option
, dma
);
487 * Add port resource to resources list.
490 static void __init
isapnp_parse_port_resource(struct pnp_option
*option
,
493 unsigned char tmp
[7];
494 struct pnp_port
*port
;
496 isapnp_peek(tmp
, size
);
497 port
= kcalloc(1, sizeof(struct pnp_port
), GFP_KERNEL
);
500 port
->min
= (tmp
[2] << 8) | tmp
[1];
501 port
->max
= (tmp
[4] << 8) | tmp
[3];
502 port
->align
= tmp
[5];
504 port
->flags
= tmp
[0] ? PNP_PORT_FLAG_16BITADDR
: 0;
505 pnp_register_port_resource(option
,port
);
510 * Add fixed port resource to resources list.
513 static void __init
isapnp_parse_fixed_port_resource(struct pnp_option
*option
,
516 unsigned char tmp
[3];
517 struct pnp_port
*port
;
519 isapnp_peek(tmp
, size
);
520 port
= kcalloc(1, sizeof(struct pnp_port
), GFP_KERNEL
);
523 port
->min
= port
->max
= (tmp
[1] << 8) | tmp
[0];
526 port
->flags
= PNP_PORT_FLAG_FIXED
;
527 pnp_register_port_resource(option
,port
);
532 * Add memory resource to resources list.
535 static void __init
isapnp_parse_mem_resource(struct pnp_option
*option
,
538 unsigned char tmp
[9];
541 isapnp_peek(tmp
, size
);
542 mem
= kcalloc(1, sizeof(struct pnp_mem
), GFP_KERNEL
);
545 mem
->min
= ((tmp
[2] << 8) | tmp
[1]) << 8;
546 mem
->max
= ((tmp
[4] << 8) | tmp
[3]) << 8;
547 mem
->align
= (tmp
[6] << 8) | tmp
[5];
548 mem
->size
= ((tmp
[8] << 8) | tmp
[7]) << 8;
550 pnp_register_mem_resource(option
,mem
);
555 * Add 32-bit memory resource to resources list.
558 static void __init
isapnp_parse_mem32_resource(struct pnp_option
*option
,
561 unsigned char tmp
[17];
564 isapnp_peek(tmp
, size
);
565 mem
= kcalloc(1, sizeof(struct pnp_mem
), GFP_KERNEL
);
568 mem
->min
= (tmp
[4] << 24) | (tmp
[3] << 16) | (tmp
[2] << 8) | tmp
[1];
569 mem
->max
= (tmp
[8] << 24) | (tmp
[7] << 16) | (tmp
[6] << 8) | tmp
[5];
570 mem
->align
= (tmp
[12] << 24) | (tmp
[11] << 16) | (tmp
[10] << 8) | tmp
[9];
571 mem
->size
= (tmp
[16] << 24) | (tmp
[15] << 16) | (tmp
[14] << 8) | tmp
[13];
573 pnp_register_mem_resource(option
,mem
);
577 * Add 32-bit fixed memory resource to resources list.
580 static void __init
isapnp_parse_fixed_mem32_resource(struct pnp_option
*option
,
583 unsigned char tmp
[9];
586 isapnp_peek(tmp
, size
);
587 mem
= kcalloc(1, sizeof(struct pnp_mem
), GFP_KERNEL
);
590 mem
->min
= mem
->max
= (tmp
[4] << 24) | (tmp
[3] << 16) | (tmp
[2] << 8) | tmp
[1];
591 mem
->size
= (tmp
[8] << 24) | (tmp
[7] << 16) | (tmp
[6] << 8) | tmp
[5];
594 pnp_register_mem_resource(option
,mem
);
598 * Parse card name for ISA PnP device.
602 isapnp_parse_name(char *name
, unsigned int name_max
, unsigned short *size
)
604 if (name
[0] == '\0') {
605 unsigned short size1
= *size
>= name_max
? (name_max
- 1) : *size
;
606 isapnp_peek(name
, size1
);
610 /* clean whitespace from end of string */
611 while (size1
> 0 && name
[--size1
] == ' ')
617 * Parse resource map for logical device.
620 static int __init
isapnp_create_device(struct pnp_card
*card
,
623 int number
= 0, skip
= 0, priority
= 0, compat
= 0;
624 unsigned char type
, tmp
[17];
625 struct pnp_option
*option
;
627 if ((dev
= isapnp_parse_device(card
, size
, number
++)) == NULL
)
629 option
= pnp_register_independent_option(dev
);
634 pnp_add_card_device(card
,dev
);
637 if (isapnp_read_tag(&type
, &size
)<0)
639 if (skip
&& type
!= _STAG_LOGDEVID
&& type
!= _STAG_END
)
643 if (size
>= 5 && size
<= 6) {
644 if ((dev
= isapnp_parse_device(card
, size
, number
++)) == NULL
)
648 option
= pnp_register_independent_option(dev
);
651 pnp_add_card_device(card
,dev
);
658 case _STAG_COMPATDEVID
:
659 if (size
== 4 && compat
< DEVICE_COUNT_COMPATIBLE
) {
661 isapnp_parse_id(dev
,(tmp
[1] << 8) | tmp
[0], (tmp
[3] << 8) | tmp
[2]);
667 if (size
< 2 || size
> 3)
669 isapnp_parse_irq_resource(option
, size
);
675 isapnp_parse_dma_resource(option
, size
);
681 priority
= 0x100 | PNP_RES_PRIORITY_ACCEPTABLE
;
683 isapnp_peek(tmp
, size
);
684 priority
= 0x100 | tmp
[0];
687 option
= pnp_register_dependent_option(dev
,priority
);
699 isapnp_parse_port_resource(option
, size
);
705 isapnp_parse_fixed_port_resource(option
, size
);
713 isapnp_parse_mem_resource(option
, size
);
717 isapnp_parse_name(dev
->name
, sizeof(dev
->name
), &size
);
719 case _LTAG_UNICODESTR
:
720 /* silently ignore */
721 /* who use unicode for hardware identification? */
725 case _LTAG_MEM32RANGE
:
728 isapnp_parse_mem32_resource(option
, size
);
731 case _LTAG_FIXEDMEM32RANGE
:
734 isapnp_parse_fixed_mem32_resource(option
, size
);
739 isapnp_skip_bytes(size
);
742 printk(KERN_ERR
"isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n", type
, dev
->number
, card
->number
);
746 isapnp_skip_bytes(size
);
752 * Parse resource map for ISA PnP card.
755 static void __init
isapnp_parse_resource_map(struct pnp_card
*card
)
757 unsigned char type
, tmp
[17];
761 if (isapnp_read_tag(&type
, &size
)<0)
768 card
->pnpver
= tmp
[0];
769 card
->productver
= tmp
[1];
773 if (size
>= 5 && size
<= 6) {
774 if (isapnp_create_device(card
, size
)==1)
782 isapnp_parse_name(card
->name
, sizeof(card
->name
), &size
);
784 case _LTAG_UNICODESTR
:
785 /* silently ignore */
786 /* who use unicode for hardware identification? */
792 isapnp_skip_bytes(size
);
795 printk(KERN_ERR
"isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n", type
, card
->number
);
799 isapnp_skip_bytes(size
);
804 * Compute ISA PnP checksum for first eight bytes.
807 static unsigned char __init
isapnp_checksum(unsigned char *data
)
810 unsigned char checksum
= 0x6a, bit
, b
;
812 for (i
= 0; i
< 8; i
++) {
814 for (j
= 0; j
< 8; j
++) {
818 checksum
= ((((checksum
^ (checksum
>> 1)) & 0x01) ^ bit
) << 7) | (checksum
>> 1);
825 * Parse EISA id for ISA PnP card.
828 static void isapnp_parse_card_id(struct pnp_card
* card
, unsigned short vendor
, unsigned short device
)
830 struct pnp_id
* id
= kcalloc(1, sizeof(struct pnp_id
), GFP_KERNEL
);
833 sprintf(id
->id
, "%c%c%c%x%x%x%x",
834 'A' + ((vendor
>> 2) & 0x3f) - 1,
835 'A' + (((vendor
& 3) << 3) | ((vendor
>> 13) & 7)) - 1,
836 'A' + ((vendor
>> 8) & 0x1f) - 1,
837 (device
>> 4) & 0x0f,
839 (device
>> 12) & 0x0f,
840 (device
>> 8) & 0x0f);
841 pnp_add_card_id(id
,card
);
845 * Build device list for all present ISA PnP devices.
848 static int __init
isapnp_build_device_list(void)
851 unsigned char header
[9], checksum
;
852 struct pnp_card
*card
;
856 for (csn
= 1; csn
<= isapnp_csn_count
; csn
++) {
858 isapnp_peek(header
, 9);
859 checksum
= isapnp_checksum(header
);
861 printk(KERN_DEBUG
"vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
862 header
[0], header
[1], header
[2], header
[3],
863 header
[4], header
[5], header
[6], header
[7], header
[8]);
864 printk(KERN_DEBUG
"checksum = 0x%x\n", checksum
);
866 if ((card
= kcalloc(1, sizeof(struct pnp_card
), GFP_KERNEL
)) == NULL
)
870 INIT_LIST_HEAD(&card
->devices
);
871 isapnp_parse_card_id(card
, (header
[1] << 8) | header
[0], (header
[3] << 8) | header
[2]);
872 card
->serial
= (header
[7] << 24) | (header
[6] << 16) | (header
[5] << 8) | header
[4];
873 isapnp_checksum_value
= 0x00;
874 isapnp_parse_resource_map(card
);
875 if (isapnp_checksum_value
!= 0x00)
876 printk(KERN_ERR
"isapnp: checksum for device %i is not valid (0x%x)\n", csn
, isapnp_checksum_value
);
877 card
->checksum
= isapnp_checksum_value
;
878 card
->protocol
= &isapnp_protocol
;
887 * Basic configuration routines.
890 int isapnp_present(void)
892 struct pnp_card
*card
;
893 pnp_for_each_card(card
) {
894 if (card
->protocol
== &isapnp_protocol
)
900 int isapnp_cfg_begin(int csn
, int logdev
)
902 if (csn
< 1 || csn
> isapnp_csn_count
|| logdev
> 10)
904 down(&isapnp_cfg_mutex
);
909 /* to avoid malfunction when the isapnptools package is used */
910 /* we must set RDP to our value again */
911 /* it is possible to set RDP only in the isolation phase */
912 /* Jens Thoms Toerring <Jens.Toerring@physik.fu-berlin.de> */
913 isapnp_write_byte(0x02, 0x04); /* clear CSN of card */
914 mdelay(2); /* is this necessary? */
915 isapnp_wake(csn
); /* bring card into sleep state */
916 isapnp_wake(0); /* bring card into isolation state */
917 isapnp_set_rdp(); /* reset the RDP port */
918 udelay(1000); /* delay 1000us */
919 isapnp_write_byte(0x06, csn
); /* reset CSN to previous value */
920 udelay(250); /* is this necessary? */
923 isapnp_device(logdev
);
927 int isapnp_cfg_end(void)
930 up(&isapnp_cfg_mutex
);
940 EXPORT_SYMBOL(isapnp_protocol
);
941 EXPORT_SYMBOL(isapnp_present
);
942 EXPORT_SYMBOL(isapnp_cfg_begin
);
943 EXPORT_SYMBOL(isapnp_cfg_end
);
945 EXPORT_SYMBOL(isapnp_read_byte
);
947 EXPORT_SYMBOL(isapnp_write_byte
);
949 static int isapnp_read_resources(struct pnp_dev
*dev
, struct pnp_resource_table
*res
)
953 dev
->active
= isapnp_read_byte(ISAPNP_CFG_ACTIVATE
);
955 for (tmp
= 0; tmp
< PNP_MAX_PORT
; tmp
++) {
956 ret
= isapnp_read_word(ISAPNP_CFG_PORT
+ (tmp
<< 1));
959 res
->port_resource
[tmp
].start
= ret
;
960 res
->port_resource
[tmp
].flags
= IORESOURCE_IO
;
962 for (tmp
= 0; tmp
< PNP_MAX_MEM
; tmp
++) {
963 ret
= isapnp_read_word(ISAPNP_CFG_MEM
+ (tmp
<< 3)) << 8;
966 res
->mem_resource
[tmp
].start
= ret
;
967 res
->mem_resource
[tmp
].flags
= IORESOURCE_MEM
;
969 for (tmp
= 0; tmp
< PNP_MAX_IRQ
; tmp
++) {
970 ret
= (isapnp_read_word(ISAPNP_CFG_IRQ
+ (tmp
<< 1)) >> 8);
973 res
->irq_resource
[tmp
].start
= res
->irq_resource
[tmp
].end
= ret
;
974 res
->irq_resource
[tmp
].flags
= IORESOURCE_IRQ
;
976 for (tmp
= 0; tmp
< PNP_MAX_DMA
; tmp
++) {
977 ret
= isapnp_read_byte(ISAPNP_CFG_DMA
+ tmp
);
980 res
->dma_resource
[tmp
].start
= res
->dma_resource
[tmp
].end
= ret
;
981 res
->dma_resource
[tmp
].flags
= IORESOURCE_DMA
;
987 static int isapnp_get_resources(struct pnp_dev
*dev
, struct pnp_resource_table
* res
)
990 pnp_init_resource_table(res
);
991 isapnp_cfg_begin(dev
->card
->number
, dev
->number
);
992 ret
= isapnp_read_resources(dev
, res
);
997 static int isapnp_set_resources(struct pnp_dev
*dev
, struct pnp_resource_table
* res
)
1001 isapnp_cfg_begin(dev
->card
->number
, dev
->number
);
1003 for (tmp
= 0; tmp
< PNP_MAX_PORT
&& (res
->port_resource
[tmp
].flags
& (IORESOURCE_IO
| IORESOURCE_UNSET
)) == IORESOURCE_IO
; tmp
++)
1004 isapnp_write_word(ISAPNP_CFG_PORT
+(tmp
<<1), res
->port_resource
[tmp
].start
);
1005 for (tmp
= 0; tmp
< PNP_MAX_IRQ
&& (res
->irq_resource
[tmp
].flags
& (IORESOURCE_IRQ
| IORESOURCE_UNSET
)) == IORESOURCE_IRQ
; tmp
++) {
1006 int irq
= res
->irq_resource
[tmp
].start
;
1009 isapnp_write_byte(ISAPNP_CFG_IRQ
+(tmp
<<1), irq
);
1011 for (tmp
= 0; tmp
< PNP_MAX_DMA
&& (res
->dma_resource
[tmp
].flags
& (IORESOURCE_DMA
| IORESOURCE_UNSET
)) == IORESOURCE_DMA
; tmp
++)
1012 isapnp_write_byte(ISAPNP_CFG_DMA
+tmp
, res
->dma_resource
[tmp
].start
);
1013 for (tmp
= 0; tmp
< PNP_MAX_MEM
&& (res
->mem_resource
[tmp
].flags
& (IORESOURCE_MEM
| IORESOURCE_UNSET
)) == IORESOURCE_MEM
; tmp
++)
1014 isapnp_write_word(ISAPNP_CFG_MEM
+(tmp
<<3), (res
->mem_resource
[tmp
].start
>> 8) & 0xffff);
1015 /* FIXME: We aren't handling 32bit mems properly here */
1016 isapnp_activate(dev
->number
);
1021 static int isapnp_disable_resources(struct pnp_dev
*dev
)
1023 if (!dev
|| !dev
->active
)
1025 isapnp_cfg_begin(dev
->card
->number
, dev
->number
);
1026 isapnp_deactivate(dev
->number
);
1032 struct pnp_protocol isapnp_protocol
= {
1033 .name
= "ISA Plug and Play",
1034 .get
= isapnp_get_resources
,
1035 .set
= isapnp_set_resources
,
1036 .disable
= isapnp_disable_resources
,
1039 static int __init
isapnp_init(void)
1042 struct pnp_card
*card
;
1043 struct pnp_dev
*dev
;
1045 if (isapnp_disable
) {
1046 isapnp_detected
= 0;
1047 printk(KERN_INFO
"isapnp: ISA Plug & Play support disabled\n");
1050 #ifdef ISAPNP_REGION_OK
1051 if (!request_region(_PIDXR
, 1, "isapnp index")) {
1052 printk(KERN_ERR
"isapnp: Index Register 0x%x already used\n", _PIDXR
);
1056 if (!request_region(_PNPWRP
, 1, "isapnp write")) {
1057 printk(KERN_ERR
"isapnp: Write Data Register 0x%x already used\n", _PNPWRP
);
1058 #ifdef ISAPNP_REGION_OK
1059 release_region(_PIDXR
, 1);
1064 if(pnp_register_protocol(&isapnp_protocol
)<0)
1068 * Print a message. The existing ISAPnP code is hanging machines
1069 * so let the user know where.
1072 printk(KERN_INFO
"isapnp: Scanning for PnP cards...\n");
1073 if (isapnp_rdp
>= 0x203 && isapnp_rdp
<= 0x3ff) {
1075 if (!request_region(isapnp_rdp
, 1, "isapnp read")) {
1076 printk(KERN_ERR
"isapnp: Read Data Register 0x%x already used\n", isapnp_rdp
);
1077 #ifdef ISAPNP_REGION_OK
1078 release_region(_PIDXR
, 1);
1080 release_region(_PNPWRP
, 1);
1085 isapnp_detected
= 1;
1086 if (isapnp_rdp
< 0x203 || isapnp_rdp
> 0x3ff) {
1087 cards
= isapnp_isolate();
1089 (isapnp_rdp
< 0x203 || isapnp_rdp
> 0x3ff)) {
1090 #ifdef ISAPNP_REGION_OK
1091 release_region(_PIDXR
, 1);
1093 release_region(_PNPWRP
, 1);
1094 isapnp_detected
= 0;
1095 printk(KERN_INFO
"isapnp: No Plug & Play device found\n");
1098 request_region(isapnp_rdp
, 1, "isapnp read");
1100 isapnp_build_device_list();
1103 protocol_for_each_card(&isapnp_protocol
,card
) {
1105 if (isapnp_verbose
) {
1106 printk(KERN_INFO
"isapnp: Card '%s'\n", card
->name
[0]?card
->name
:"Unknown");
1107 if (isapnp_verbose
< 2)
1109 card_for_each_dev(card
,dev
) {
1110 printk(KERN_INFO
"isapnp: Device '%s'\n", dev
->name
[0]?dev
->name
:"Unknown");
1115 printk(KERN_INFO
"isapnp: %i Plug & Play card%s detected total\n", cards
, cards
>1?"s":"");
1117 printk(KERN_INFO
"isapnp: No Plug & Play card found\n");
1124 device_initcall(isapnp_init
);
1126 /* format is: noisapnp */
1128 static int __init
isapnp_setup_disable(char *str
)
1134 __setup("noisapnp", isapnp_setup_disable
);
1136 /* format is: isapnp=rdp,reset,skip_pci_scan,verbose */
1138 static int __init
isapnp_setup_isapnp(char *str
)
1140 (void)((get_option(&str
,&isapnp_rdp
) == 2) &&
1141 (get_option(&str
,&isapnp_reset
) == 2) &&
1142 (get_option(&str
,&isapnp_verbose
) == 2));
1146 __setup("isapnp=", isapnp_setup_isapnp
);