37 #include <linux/module.h>
38 #include <linux/kernel.h>
39 #include <linux/errno.h>
49 #define ISAPNP_REGION_OK
53 static int isapnp_rdp;
54 static int isapnp_reset = 1;
55 static int isapnp_verbose = 1;
73 #define _STAG_PNPVERNO 0x01
74 #define _STAG_LOGDEVID 0x02
75 #define _STAG_COMPATDEVID 0x03
76 #define _STAG_IRQ 0x04
77 #define _STAG_DMA 0x05
78 #define _STAG_STARTDEP 0x06
79 #define _STAG_ENDDEP 0x07
80 #define _STAG_IOPORT 0x08
81 #define _STAG_FIXEDIO 0x09
82 #define _STAG_VENDOR 0x0e
83 #define _STAG_END 0x0f
85 #define _LTAG_MEMRANGE 0x81
86 #define _LTAG_ANSISTR 0x82
87 #define _LTAG_UNICODESTR 0x83
88 #define _LTAG_VENDOR 0x84
89 #define _LTAG_MEM32RANGE 0x85
90 #define _LTAG_FIXEDMEM32RANGE 0x86
94 #define ISAPNP_CFG_ACTIVATE 0x30
95 #define ISAPNP_CFG_MEM 0x40
96 #define ISAPNP_CFG_PORT 0x60
97 #define ISAPNP_CFG_IRQ 0x70
98 #define ISAPNP_CFG_DMA 0x74
104 #define ISAPNP_MAX_MEM 4
105 #define ISAPNP_MAX_PORT 8
106 #define ISAPNP_MAX_IRQ 2
107 #define ISAPNP_MAX_DMA 2
109 static unsigned char isapnp_checksum_value;
111 static int isapnp_csn_count;
115 static inline void write_data(
unsigned char x)
120 static inline void write_address(
unsigned char x)
126 static inline unsigned char read_data(
void)
128 unsigned char val =
inb(isapnp_rdp);
138 static unsigned short isapnp_read_word(
unsigned char idx)
153 static void isapnp_write_word(
unsigned char idx,
unsigned short val)
159 static void isapnp_key(
void)
161 unsigned char code = 0x6a,
msb;
170 for (i = 1; i < 32; i++) {
171 msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7;
172 code = (code >> 1) |
msb;
178 static void isapnp_wait(
void)
183 static void isapnp_wake(
unsigned char csn)
188 static void isapnp_device(
unsigned char logdev)
193 static void isapnp_activate(
unsigned char logdev)
195 isapnp_device(logdev);
200 static void isapnp_deactivate(
unsigned char logdev)
202 isapnp_device(logdev);
212 for (i = 1; i <=
bytes; i++) {
213 for (j = 0; j < 20; j++) {
225 isapnp_checksum_value +=
d;
233 static int isapnp_next_rdp(
void)
235 int rdp = isapnp_rdp;
236 static int old_rdp = 0;
242 while (rdp <= 0x3ff) {
247 if ((rdp < 0x280 || rdp > 0x380)
259 static inline void isapnp_set_rdp(
void)
269 static int __init isapnp_isolate_rdp_select(
void)
282 if (isapnp_next_rdp() < 0) {
297 static int __init isapnp_isolate(
void)
300 unsigned char chksum = 0x00;
301 unsigned char bit = 0x00;
308 if (isapnp_isolate_rdp_select() < 0)
312 for (i = 1; i <= 64; i++) {
313 data = read_data() << 8;
315 data = data | read_data();
320 ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7)
324 for (i = 65; i <= 72; i++) {
325 data = read_data() << 8;
327 data = data | read_data();
330 chksum |= (1 << (i - 65));
332 if (checksum != 0x00 && checksum == chksum) {
345 if (iteration == 1) {
347 if (isapnp_isolate_rdp_select() < 0)
349 }
else if (iteration > 1) {
360 isapnp_csn_count = csn;
367 static int __init isapnp_read_tag(
unsigned char *
type,
unsigned short *
size)
369 unsigned char tag,
tmp[2];
371 isapnp_peek(&tag, 1);
377 *size = (tmp[1] << 8) | tmp[0];
379 *type = (tag >> 3) & 0x0f;
386 if (*type == 0xff && *size == 0xffff)
396 isapnp_peek(
NULL, count);
405 unsigned char tmp[6];
410 isapnp_peek(tmp, size);
411 eisa_id = tmp[0] | tmp[1] << 8 | tmp[2] << 16 | tmp[3] << 24;
430 static void __init isapnp_parse_irq_resource(
struct pnp_dev *dev,
431 unsigned int option_flags,
434 unsigned char tmp[3];
439 isapnp_peek(tmp, size);
440 bits = (tmp[1] << 8) | tmp[0];
443 bitmap_copy(map.bits, &bits, 16);
454 static void __init isapnp_parse_dma_resource(
struct pnp_dev *dev,
455 unsigned int option_flags,
458 unsigned char tmp[2];
460 isapnp_peek(tmp, size);
467 static void __init isapnp_parse_port_resource(
struct pnp_dev *dev,
468 unsigned int option_flags,
471 unsigned char tmp[7];
475 isapnp_peek(tmp, size);
476 min = (tmp[2] << 8) | tmp[1];
477 max = (tmp[4] << 8) | tmp[3];
482 min, max, align, len, flags);
488 static void __init isapnp_parse_fixed_port_resource(
struct pnp_dev *dev,
489 unsigned int option_flags,
492 unsigned char tmp[3];
495 isapnp_peek(tmp, size);
496 base = (tmp[1] << 8) | tmp[0];
505 static void __init isapnp_parse_mem_resource(
struct pnp_dev *dev,
506 unsigned int option_flags,
509 unsigned char tmp[9];
513 isapnp_peek(tmp, size);
514 min = ((tmp[2] << 8) | tmp[1]) << 8;
515 max = ((tmp[4] << 8) | tmp[3]) << 8;
516 align = (tmp[6] << 8) | tmp[5];
517 len = ((tmp[8] << 8) | tmp[7]) << 8;
520 min, max, align, len, flags);
526 static void __init isapnp_parse_mem32_resource(
struct pnp_dev *dev,
527 unsigned int option_flags,
530 unsigned char tmp[17];
534 isapnp_peek(tmp, size);
535 min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
536 max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
537 align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
538 len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
541 min, max, align, len, flags);
547 static void __init isapnp_parse_fixed_mem32_resource(
struct pnp_dev *dev,
548 unsigned int option_flags,
551 unsigned char tmp[9];
555 isapnp_peek(tmp, size);
556 base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
557 len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
566 isapnp_parse_name(
char *
name,
unsigned int name_max,
unsigned short *size)
568 if (name[0] ==
'\0') {
569 unsigned short size1 =
570 *size >= name_max ? (name_max - 1) : *size;
571 isapnp_peek(name, size1);
576 while (size1 > 0 && name[--size1] ==
' ')
588 unsigned char type, tmp[17];
589 unsigned int option_flags;
594 if ((dev = isapnp_parse_device(card, size, number++)) ==
NULL)
600 if (isapnp_read_tag(&type, &size) < 0)
606 if (size >= 5 && size <= 6) {
608 isapnp_parse_device(card, size,
621 if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {
623 eisa_id = tmp[0] | tmp[1] << 8 |
624 tmp[2] << 16 | tmp[3] << 24;
632 if (size < 2 || size > 3)
634 isapnp_parse_irq_resource(dev, option_flags, size);
640 isapnp_parse_dma_resource(dev, option_flags, size);
648 isapnp_peek(tmp, size);
652 option_flags = pnp_new_dependent_set(dev,
priority);
662 isapnp_parse_port_resource(dev, option_flags, size);
668 isapnp_parse_fixed_port_resource(dev, option_flags,
677 isapnp_parse_mem_resource(dev, option_flags, size);
681 isapnp_parse_name(dev->
name,
sizeof(dev->
name), &size);
692 isapnp_parse_mem32_resource(dev, option_flags, size);
698 isapnp_parse_fixed_mem32_resource(dev, option_flags,
704 isapnp_skip_bytes(size);
707 dev_err(&dev->
dev,
"unknown tag %#x (card %i), "
708 "ignored\n", type, card->
number);
712 isapnp_skip_bytes(size);
720 static void __init isapnp_parse_resource_map(
struct pnp_card *card)
722 unsigned char type, tmp[17];
726 if (isapnp_read_tag(&type, &size) < 0)
738 if (size >= 5 && size <= 6) {
739 if (isapnp_create_device(card, size) == 1)
747 isapnp_parse_name(card->
name,
sizeof(card->
name),
758 isapnp_skip_bytes(size);
761 dev_err(&card->
dev,
"unknown tag %#x, ignored\n",
766 isapnp_skip_bytes(size);
773 static unsigned char __init isapnp_checksum(
unsigned char *data)
776 unsigned char checksum = 0x6a,
bit,
b;
778 for (i = 0; i < 8; i++) {
780 for (j = 0; j < 8; j++) {
785 ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7)
795 static int __init isapnp_build_device_list(
void)
805 for (csn = 1; csn <= isapnp_csn_count; csn++) {
807 isapnp_peek(header, 9);
808 checksum = isapnp_checksum(header);
809 eisa_id = header[0] | header[1] << 8 |
810 header[2] << 16 | header[3] << 24;
818 "vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
819 header[0], header[1], header[2], header[3], header[4],
820 header[5], header[6], header[7], header[8]);
821 dev_info(&card->
dev,
"checksum = %#x\n", checksum);
823 INIT_LIST_HEAD(&card->
devices);
825 (header[7] << 24) | (header[6] << 16) | (header[5] << 8) |
827 isapnp_checksum_value = 0x00;
828 isapnp_parse_resource_map(card);
829 if (isapnp_checksum_value != 0x00)
831 isapnp_checksum_value);
832 card->
checksum = isapnp_checksum_value;
857 if (csn < 1 || csn > isapnp_csn_count || logdev > 10)
878 isapnp_device(logdev);
899 static int isapnp_get_resources(
struct pnp_dev *dev)
936 static int isapnp_set_resources(
struct pnp_dev *dev)
946 if (pnp_resource_enabled(res)) {
948 tmp, (
unsigned long long) res->
start);
955 if (pnp_resource_enabled(res)) {
959 pnp_dbg(&dev->
dev,
" set irq %d to %d\n", tmp, irq);
965 if (pnp_resource_enabled(res)) {
967 tmp, (
unsigned long long) res->
start);
973 if (pnp_resource_enabled(res)) {
975 tmp, (
unsigned long long) res->
start);
977 (res->
start >> 8) & 0xffff);
981 isapnp_activate(dev->
number);
986 static int isapnp_disable_resources(
struct pnp_dev *dev)
991 isapnp_deactivate(dev->
number);
998 .name =
"ISA Plug and Play",
999 .get = isapnp_get_resources,
1000 .set = isapnp_set_resources,
1001 .disable = isapnp_disable_resources,
1004 static int __init isapnp_init(
void)
1018 #ifdef ISAPNP_REGION_OK
1027 "isapnp: Write Data Register 0x%x already used\n",
1029 #ifdef ISAPNP_REGION_OK
1044 if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {
1048 "isapnp: Read Data Register 0x%x already used\n",
1050 #ifdef ISAPNP_REGION_OK
1058 if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) {
1059 cards = isapnp_isolate();
1060 if (cards < 0 || (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {
1061 #ifdef ISAPNP_REGION_OK
1066 "isapnp: No Plug & Play device found\n");
1071 isapnp_build_device_list();
1076 if (isapnp_verbose) {
1078 card->
name[0] ? card->
name :
"unknown");
1079 if (isapnp_verbose < 2)
1083 dev->
name[0] ? dev->
name :
"unknown");
1089 "isapnp: %i Plug & Play card%s detected total\n", cards,
1090 cards > 1 ?
"s" :
"");
1102 static int __init isapnp_setup_disable(
char *
str)
1108 __setup(
"noisapnp", isapnp_setup_disable);
1112 static int __init isapnp_setup_isapnp(
char *
str)
1120 __setup(
"isapnp=", isapnp_setup_isapnp);