Linux 2.4.0-test9pre8
[davej-history.git] / drivers / pnp / isapnp.c
blob45f7f05f135131a351f9ef2ceb8cb2147c30b460
1 /*
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.
20 * Changelog:
21 * 2000-01-01 Added quirks handling for buggy hardware
22 * Peter Denison <peterd@pnd-pc.demon.co.uk>
25 #include <linux/config.h>
26 #include <linux/version.h>
27 #include <linux/module.h>
28 #include <linux/kernel.h>
29 #include <linux/errno.h>
30 #include <linux/ioport.h>
31 #include <linux/string.h>
32 #include <linux/malloc.h>
33 #include <linux/delay.h>
34 #include <asm/io.h>
35 #include <asm/dma.h>
36 #include <asm/irq.h>
37 #include <linux/pci.h>
38 #include <linux/init.h>
39 #include <linux/isapnp.h>
41 LIST_HEAD(isapnp_cards);
42 LIST_HEAD(isapnp_devices);
44 #if 0
45 #define ISAPNP_REGION_OK
46 #endif
47 #if 0
48 #define ISAPNP_DEBUG
49 #endif
51 struct resource *pidxr_res;
52 struct resource *pnpwrp_res;
53 struct resource *isapnp_rdp_res;
55 int isapnp_disable; /* Disable ISA PnP */
56 int isapnp_rdp; /* Read Data Port */
57 int isapnp_reset = 1; /* reset all PnP cards (deactivate) */
58 int isapnp_skip_pci_scan; /* skip PCI resource scanning */
59 int isapnp_verbose = 1; /* verbose mode */
60 int isapnp_reserve_irq[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some IRQ */
61 int isapnp_reserve_dma[8] = { [0 ... 7] = -1 }; /* reserve (don't use) some DMA */
62 int isapnp_reserve_io[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some I/O region */
63 int isapnp_reserve_mem[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some memory region */
65 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
66 MODULE_DESCRIPTION("Generic ISA Plug & Play support");
67 MODULE_PARM(isapnp_disable, "i");
68 MODULE_PARM_DESC(isapnp_disable, "ISA Plug & Play disable");
69 MODULE_PARM(isapnp_rdp, "i");
70 MODULE_PARM_DESC(isapnp_rdp, "ISA Plug & Play read data port");
71 MODULE_PARM(isapnp_reset, "i");
72 MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
73 MODULE_PARM(isapnp_skip_pci_scan, "i");
74 MODULE_PARM_DESC(isapnp_skip_pci_scan, "ISA Plug & Play skip PCI resource scanning");
75 MODULE_PARM(isapnp_verbose, "i");
76 MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
77 MODULE_PARM(isapnp_reserve_irq, "1-16i");
78 MODULE_PARM_DESC(isapnp_reserve_irq, "ISA Plug & Play - reserve IRQ line(s)");
79 MODULE_PARM(isapnp_reserve_dma, "1-8i");
80 MODULE_PARM_DESC(isapnp_reserve_dma, "ISA Plug & Play - reserve DMA channel(s)");
81 MODULE_PARM(isapnp_reserve_io, "1-16i");
82 MODULE_PARM_DESC(isapnp_reserve_io, "ISA Plug & Play - reserve I/O region(s) - port,size");
83 MODULE_PARM(isapnp_reserve_mem, "1-16i");
84 MODULE_PARM_DESC(isapnp_reserve_mem, "ISA Plug & Play - reserve memory region(s) - address,size");
86 #define _PIDXR 0x279
87 #define _PNPWRP 0xa79
89 /* short tags */
90 #define _STAG_PNPVERNO 0x01
91 #define _STAG_LOGDEVID 0x02
92 #define _STAG_COMPATDEVID 0x03
93 #define _STAG_IRQ 0x04
94 #define _STAG_DMA 0x05
95 #define _STAG_STARTDEP 0x06
96 #define _STAG_ENDDEP 0x07
97 #define _STAG_IOPORT 0x08
98 #define _STAG_FIXEDIO 0x09
99 #define _STAG_VENDOR 0x0e
100 #define _STAG_END 0x0f
101 /* long tags */
102 #define _LTAG_MEMRANGE 0x81
103 #define _LTAG_ANSISTR 0x82
104 #define _LTAG_UNICODESTR 0x83
105 #define _LTAG_VENDOR 0x84
106 #define _LTAG_MEM32RANGE 0x85
107 #define _LTAG_FIXEDMEM32RANGE 0x86
109 static unsigned char isapnp_checksum_value;
110 static DECLARE_MUTEX(isapnp_cfg_mutex);
111 static int isapnp_detected;
113 /* some prototypes */
115 static int isapnp_config_prepare(struct pci_dev *dev);
116 static int isapnp_config_activate(struct pci_dev *dev);
117 static int isapnp_config_deactivate(struct pci_dev *dev);
119 static inline void write_data(unsigned char x)
121 outb(x, _PNPWRP);
124 static inline void write_address(unsigned char x)
126 outb(x, _PIDXR);
127 udelay(20);
130 static inline unsigned char read_data(void)
132 unsigned char val = inb(isapnp_rdp);
133 return val;
136 unsigned char isapnp_read_byte(unsigned char idx)
138 write_address(idx);
139 return read_data();
142 unsigned short isapnp_read_word(unsigned char idx)
144 unsigned short val;
146 val = isapnp_read_byte(idx);
147 val = (val << 8) + isapnp_read_byte(idx+1);
148 return val;
151 unsigned int isapnp_read_dword(unsigned char idx)
153 unsigned int val;
155 val = isapnp_read_byte(idx);
156 val = (val << 8) + isapnp_read_byte(idx+1);
157 val = (val << 8) + isapnp_read_byte(idx+2);
158 val = (val << 8) + isapnp_read_byte(idx+3);
159 return val;
162 void isapnp_write_byte(unsigned char idx, unsigned char val)
164 write_address(idx);
165 write_data(val);
168 void isapnp_write_word(unsigned char idx, unsigned short val)
170 isapnp_write_byte(idx, val >> 8);
171 isapnp_write_byte(idx+1, val);
174 void isapnp_write_dword(unsigned char idx, unsigned int val)
176 isapnp_write_byte(idx, val >> 24);
177 isapnp_write_byte(idx+1, val >> 16);
178 isapnp_write_byte(idx+2, val >> 8);
179 isapnp_write_byte(idx+3, val);
182 void *isapnp_alloc(long size)
184 void *result;
186 result = kmalloc(size, GFP_KERNEL);
187 if (!result)
188 return NULL;
189 memset(result, 0, size);
190 return result;
193 static void isapnp_key(void)
195 unsigned char code = 0x6a, msb;
196 int i;
198 mdelay(1);
199 write_address(0x00);
200 write_address(0x00);
202 write_address(code);
204 for (i = 1; i < 32; i++) {
205 msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7;
206 code = (code >> 1) | msb;
207 write_address(code);
211 /* place all pnp cards in wait-for-key state */
212 static void isapnp_wait(void)
214 isapnp_write_byte(0x02, 0x02);
217 void isapnp_wake(unsigned char csn)
219 isapnp_write_byte(0x03, csn);
222 void isapnp_device(unsigned char logdev)
224 isapnp_write_byte(0x07, logdev);
227 void isapnp_activate(unsigned char logdev)
229 isapnp_device(logdev);
230 isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 1);
231 udelay(250);
234 void isapnp_deactivate(unsigned char logdev)
236 isapnp_device(logdev);
237 isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 0);
238 udelay(500);
241 static void __init isapnp_peek(unsigned char *data, int bytes)
243 int i, j;
244 unsigned char d=0;
246 for (i = 1; i <= bytes; i++) {
247 for (j = 0; j < 10; j++) {
248 d = isapnp_read_byte(0x05);
249 if (d & 1)
250 break;
251 udelay(100);
253 if (!(d & 1)) {
254 *data++ = 0xff;
255 continue;
257 d = isapnp_read_byte(0x04); /* PRESDI */
258 isapnp_checksum_value += d;
259 if (data != NULL)
260 *data++ = d;
264 #define RDP_STEP 32 /* minimum is 4 */
266 static int isapnp_next_rdp(void)
268 int rdp = isapnp_rdp;
269 while (rdp <= 0x3ff) {
270 if (!check_region(rdp, 1)) {
271 isapnp_rdp = rdp;
272 return 0;
274 rdp += RDP_STEP;
276 * We cannot use NE2000 probe spaces for ISAPnP or we
277 * will lock up machines.
279 if(rdp >= 0x280 && rdp <= 0x380)
280 continue;
282 return -1;
285 /* Set read port address */
286 static inline void isapnp_set_rdp(void)
288 isapnp_write_byte(0x00, isapnp_rdp >> 2);
289 udelay(100);
293 * Perform an isolation. The port selection code now tries to avoid
294 * "dangerous to read" ports.
297 static int __init isapnp_isolate_rdp_select(void)
299 isapnp_wait();
300 isapnp_key();
302 /* Control: reset CSN and conditionally everything else too */
303 isapnp_write_byte(0x02, isapnp_reset ? 0x05 : 0x04);
304 mdelay(2);
306 isapnp_wait();
307 isapnp_key();
308 isapnp_wake(0x00);
310 if (isapnp_next_rdp() < 0) {
311 isapnp_wait();
312 return -1;
315 isapnp_set_rdp();
316 udelay(1000);
317 write_address(0x01);
318 udelay(1000);
319 return 0;
323 * Isolate (assign uniqued CSN) to all ISA PnP devices.
326 static int __init isapnp_isolate(void)
328 unsigned char checksum = 0x6a;
329 unsigned char chksum = 0x00;
330 unsigned char bit = 0x00;
331 int data;
332 int csn = 0;
333 int i;
334 int iteration = 1;
336 isapnp_rdp = 0x213;
337 if (isapnp_isolate_rdp_select() < 0)
338 return -1;
340 while (1) {
341 for (i = 1; i <= 64; i++) {
342 data = read_data() << 8;
343 udelay(250);
344 data = data | read_data();
345 udelay(250);
346 if (data == 0x55aa)
347 bit = 0x01;
348 checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1);
349 bit = 0x00;
351 for (i = 65; i <= 72; i++) {
352 data = read_data() << 8;
353 udelay(250);
354 data = data | read_data();
355 udelay(250);
356 if (data == 0x55aa)
357 chksum |= (1 << (i - 65));
359 if (checksum != 0x00 && checksum == chksum) {
360 csn++;
362 isapnp_write_byte(0x06, csn);
363 udelay(250);
364 iteration++;
365 isapnp_wake(0x00);
366 isapnp_set_rdp();
367 udelay(1000);
368 write_address(0x01);
369 udelay(1000);
370 goto __next;
372 if (iteration == 1) {
373 isapnp_rdp += RDP_STEP;
374 if (isapnp_isolate_rdp_select() < 0)
375 return -1;
376 } else if (iteration > 1) {
377 break;
379 __next:
380 checksum = 0x6a;
381 chksum = 0x00;
382 bit = 0x00;
384 isapnp_wait();
385 return csn;
389 * Read one tag from stream.
392 static int __init isapnp_read_tag(unsigned char *type, unsigned short *size)
394 unsigned char tag, tmp[2];
396 isapnp_peek(&tag, 1);
397 if (tag == 0) /* invalid tag */
398 return -1;
399 if (tag & 0x80) { /* large item */
400 *type = tag;
401 isapnp_peek(tmp, 2);
402 *size = (tmp[1] << 8) | tmp[0];
403 } else {
404 *type = (tag >> 3) & 0x0f;
405 *size = tag & 0x07;
407 #if 0
408 printk("tag = 0x%x, type = 0x%x, size = %i\n", tag, *type, *size);
409 #endif
410 if (type == 0) /* wrong type */
411 return -1;
412 if (*type == 0xff && *size == 0xffff) /* probably invalid data */
413 return -1;
414 return 0;
418 * Skip specified number of bytes from stream.
421 static void __init isapnp_skip_bytes(int count)
423 isapnp_peek(NULL, count);
427 * Parse logical device tag.
430 static struct pci_dev * __init isapnp_parse_device(struct pci_bus *card, int size, int number)
432 unsigned char tmp[6];
433 struct pci_dev *dev;
435 isapnp_peek(tmp, size);
436 dev = isapnp_alloc(sizeof(struct pci_dev));
437 if (!dev)
438 return NULL;
439 dev->dma_mask = 0x00ffffff;
440 dev->devfn = number;
441 dev->vendor = (tmp[1] << 8) | tmp[0];
442 dev->device = (tmp[3] << 8) | tmp[2];
443 dev->regs = tmp[4];
444 dev->bus = card;
445 if (size > 5)
446 dev->regs |= tmp[5] << 8;
447 dev->prepare = isapnp_config_prepare;
448 dev->activate = isapnp_config_activate;
449 dev->deactivate = isapnp_config_deactivate;
450 return dev;
454 * Build new resources structure
457 static struct isapnp_resources * __init isapnp_build_resources(struct pci_dev *dev, int dependent)
459 struct isapnp_resources *res, *ptr, *ptra;
461 res = isapnp_alloc(sizeof(struct isapnp_resources));
462 if (!res)
463 return NULL;
464 res->dev = dev;
465 ptr = (struct isapnp_resources *)dev->sysdata;
466 while (ptr && ptr->next)
467 ptr = ptr->next;
468 if (ptr && ptr->dependent && dependent) { /* add to another list */
469 ptra = ptr->alt;
470 while (ptra && ptra->alt)
471 ptra = ptra->alt;
472 if (!ptra)
473 ptr->alt = res;
474 else
475 ptra->alt = res;
476 } else {
477 if (!ptr)
478 dev->sysdata = res;
479 else
480 ptr->next = res;
482 if (dependent) {
483 res->priority = dependent & 0xff;
484 if (res->priority > ISAPNP_RES_PRIORITY_FUNCTIONAL)
485 res->priority = ISAPNP_RES_PRIORITY_INVALID;
486 res->dependent = 1;
487 } else {
488 res->priority = ISAPNP_RES_PRIORITY_PREFERRED;
489 res->dependent = 0;
491 return res;
495 * Add IRQ resource to resources list.
498 static void __init isapnp_add_irq_resource(struct pci_dev *dev,
499 struct isapnp_resources **res,
500 int dependent, int size)
502 unsigned char tmp[3];
503 int i;
504 struct isapnp_irq *irq, *ptr;
506 isapnp_peek(tmp, size);
507 irq = isapnp_alloc(sizeof(struct isapnp_irq));
508 if (!irq)
509 return;
510 if (*res == NULL) {
511 *res = isapnp_build_resources(dev, dependent);
512 if (*res == NULL) {
513 kfree(irq);
514 return;
517 irq->map = (tmp[1] << 8) | tmp[0];
518 if (size > 2)
519 irq->flags = tmp[2];
520 else
521 irq->flags = IORESOURCE_IRQ_HIGHEDGE;
522 irq->res = *res;
523 ptr = (*res)->irq;
524 while (ptr && ptr->next)
525 ptr = ptr->next;
526 if (ptr)
527 ptr->next = irq;
528 else
529 (*res)->irq = irq;
530 #ifdef CONFIG_PCI
531 for (i=0; i<16; i++)
532 if (irq->map & (1<<i))
533 pcibios_penalize_isa_irq(i);
534 #endif
538 * Add DMA resource to resources list.
541 static void __init isapnp_add_dma_resource(struct pci_dev *dev,
542 struct isapnp_resources **res,
543 int dependent, int size)
545 unsigned char tmp[2];
546 struct isapnp_dma *dma, *ptr;
548 isapnp_peek(tmp, size);
549 dma = isapnp_alloc(sizeof(struct isapnp_dma));
550 if (!dma)
551 return;
552 if (*res == NULL) {
553 *res = isapnp_build_resources(dev, dependent);
554 if (*res == NULL) {
555 kfree(dma);
556 return;
559 dma->map = tmp[0];
560 dma->flags = tmp[1];
561 dma->res = *res;
562 ptr = (*res)->dma;
563 while (ptr && ptr->next)
564 ptr = ptr->next;
565 if (ptr)
566 ptr->next = dma;
567 else
568 (*res)->dma = dma;
572 * Add port resource to resources list.
575 static void __init isapnp_add_port_resource(struct pci_dev *dev,
576 struct isapnp_resources **res,
577 int dependent, int size)
579 unsigned char tmp[7];
580 struct isapnp_port *port, *ptr;
582 isapnp_peek(tmp, size);
583 port = isapnp_alloc(sizeof(struct isapnp_port));
584 if (!port)
585 return;
586 if (*res == NULL) {
587 *res = isapnp_build_resources(dev, dependent);
588 if (*res == NULL) {
589 kfree(port);
590 return;
593 port->min = (tmp[2] << 8) | tmp[1];
594 port->max = (tmp[4] << 8) | tmp[3];
595 port->align = tmp[5];
596 port->size = tmp[6];
597 port->flags = tmp[0] ? ISAPNP_PORT_FLAG_16BITADDR : 0;
598 port->res = *res;
599 ptr = (*res)->port;
600 while (ptr && ptr->next)
601 ptr = ptr->next;
602 if (ptr)
603 ptr->next = port;
604 else
605 (*res)->port = port;
609 * Add fixed port resource to resources list.
612 static void __init isapnp_add_fixed_port_resource(struct pci_dev *dev,
613 struct isapnp_resources **res,
614 int dependent, int size)
616 unsigned char tmp[3];
617 struct isapnp_port *port, *ptr;
619 isapnp_peek(tmp, size);
620 port = isapnp_alloc(sizeof(struct isapnp_port));
621 if (!port)
622 return;
623 if (*res == NULL) {
624 *res = isapnp_build_resources(dev, dependent);
625 if (*res == NULL) {
626 kfree(port);
627 return;
630 port->min = port->max = (tmp[1] << 8) | tmp[0];
631 port->size = tmp[2];
632 port->align = 0;
633 port->flags = ISAPNP_PORT_FLAG_FIXED;
634 port->res = *res;
635 ptr = (*res)->port;
636 while (ptr && ptr->next)
637 ptr = ptr->next;
638 if (ptr)
639 ptr->next = port;
640 else
641 (*res)->port = port;
645 * Add memory resource to resources list.
648 static void __init isapnp_add_mem_resource(struct pci_dev *dev,
649 struct isapnp_resources **res,
650 int dependent, int size)
652 unsigned char tmp[9];
653 struct isapnp_mem *mem, *ptr;
655 isapnp_peek(tmp, size);
656 mem = isapnp_alloc(sizeof(struct isapnp_mem));
657 if (!mem)
658 return;
659 if (*res == NULL) {
660 *res = isapnp_build_resources(dev, dependent);
661 if (*res == NULL) {
662 kfree(mem);
663 return;
666 mem->min = ((tmp[2] << 8) | tmp[1]) << 8;
667 mem->max = ((tmp[4] << 8) | tmp[3]) << 8;
668 mem->align = (tmp[6] << 8) | tmp[5];
669 mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
670 mem->flags = tmp[0];
671 mem->res = *res;
672 ptr = (*res)->mem;
673 while (ptr && ptr->next)
674 ptr = ptr->next;
675 if (ptr)
676 ptr->next = mem;
677 else
678 (*res)->mem = mem;
682 * Add 32-bit memory resource to resources list.
685 static void __init isapnp_add_mem32_resource(struct pci_dev *dev,
686 struct isapnp_resources **res,
687 int dependent, int size)
689 unsigned char tmp[17];
690 struct isapnp_mem32 *mem32, *ptr;
692 isapnp_peek(tmp, size);
693 mem32 = isapnp_alloc(sizeof(struct isapnp_mem32));
694 if (!mem32)
695 return;
696 if (*res == NULL) {
697 *res = isapnp_build_resources(dev, dependent);
698 if (*res == NULL) {
699 kfree(mem32);
700 return;
703 memcpy(mem32->data, tmp, 17);
704 mem32->res = *res;
705 ptr = (*res)->mem32;
706 while (ptr && ptr->next)
707 ptr = ptr->next;
708 if (ptr)
709 ptr->next = mem32;
710 else
711 (*res)->mem32 = mem32;
715 * Add 32-bit fixed memory resource to resources list.
718 static void __init isapnp_add_fixed_mem32_resource(struct pci_dev *dev,
719 struct isapnp_resources **res,
720 int dependent, int size)
722 unsigned char tmp[17];
723 struct isapnp_mem32 *mem32, *ptr;
725 isapnp_peek(tmp, size);
726 mem32 = isapnp_alloc(sizeof(struct isapnp_mem32));
727 if (!mem32)
728 return;
729 if (*res == NULL) {
730 *res = isapnp_build_resources(dev, dependent);
731 if (*res == NULL) {
732 kfree(mem32);
733 return;
736 memcpy(mem32->data, tmp, 17);
737 mem32->res = *res;
738 ptr = (*res)->mem32;
739 while (ptr && ptr->next)
740 ptr = ptr->next;
741 if (ptr)
742 ptr->next = mem32;
743 else
744 (*res)->mem32 = mem32;
748 * Parse resource map for logical device.
751 static int __init isapnp_create_device(struct pci_bus *card,
752 unsigned short size)
754 int number = 0, skip = 0, dependent = 0, compat = 0;
755 unsigned char type, tmp[17];
756 struct pci_dev *dev;
757 struct isapnp_resources *res = NULL;
759 if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
760 return 1;
761 list_add(&dev->bus_list, &card->devices);
762 list_add_tail(&dev->global_list, &isapnp_devices);
763 while (1) {
764 if (isapnp_read_tag(&type, &size)<0)
765 return 1;
766 if (skip && type != _STAG_LOGDEVID && type != _STAG_END)
767 goto __skip;
768 switch (type) {
769 case _STAG_LOGDEVID:
770 if (size >= 5 && size <= 6) {
771 isapnp_config_prepare(dev);
772 if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
773 return 1;
774 list_add_tail(&dev->bus_list, &card->devices);
775 list_add_tail(&dev->global_list, &isapnp_devices);
776 size = 0;
777 skip = 0;
778 } else {
779 skip = 1;
781 res = NULL;
782 dependent = 0;
783 compat = 0;
784 break;
785 case _STAG_COMPATDEVID:
786 if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {
787 isapnp_peek(tmp, 4);
788 dev->vendor_compatible[compat] = (tmp[1] << 8) | tmp[0];
789 dev->device_compatible[compat] = (tmp[3] << 8) | tmp[2];
790 compat++;
791 size = 0;
793 break;
794 case _STAG_IRQ:
795 if (size < 2 || size > 3)
796 goto __skip;
797 isapnp_add_irq_resource(dev, &res, dependent, size);
798 size = 0;
799 break;
800 case _STAG_DMA:
801 if (size != 2)
802 goto __skip;
803 isapnp_add_dma_resource(dev, &res, dependent, size);
804 size = 0;
805 break;
806 case _STAG_STARTDEP:
807 if (size > 1)
808 goto __skip;
809 res = NULL;
810 dependent = 0x100 | ISAPNP_RES_PRIORITY_ACCEPTABLE;
811 if (size > 0) {
812 isapnp_peek(tmp, size);
813 dependent = 0x100 | tmp[0];
814 size = 0;
816 break;
817 case _STAG_ENDDEP:
818 if (size != 0)
819 goto __skip;
820 res = NULL;
821 dependent = 0;
822 break;
823 case _STAG_IOPORT:
824 if (size != 7)
825 goto __skip;
826 isapnp_add_port_resource(dev, &res, dependent, size);
827 size = 0;
828 break;
829 case _STAG_FIXEDIO:
830 if (size != 3)
831 goto __skip;
832 isapnp_add_fixed_port_resource(dev, &res, dependent, size);
833 size = 0;
834 break;
835 case _STAG_VENDOR:
836 break;
837 case _LTAG_MEMRANGE:
838 if (size != 9)
839 goto __skip;
840 isapnp_add_mem_resource(dev, &res, dependent, size);
841 size = 0;
842 break;
843 case _LTAG_ANSISTR:
844 if (dev->name[0] == '\0') {
845 unsigned short size1 = size > 47 ? 47 : size;
846 isapnp_peek(dev->name, size1);
847 dev->name[size1] = '\0';
848 size -= size1;
850 break;
851 case _LTAG_UNICODESTR:
852 /* silently ignore */
853 /* who use unicode for hardware identification? */
854 break;
855 case _LTAG_VENDOR:
856 break;
857 case _LTAG_MEM32RANGE:
858 if (size != 17)
859 goto __skip;
860 isapnp_add_mem32_resource(dev, &res, dependent, size);
861 size = 0;
862 break;
863 case _LTAG_FIXEDMEM32RANGE:
864 if (size != 17)
865 goto __skip;
866 isapnp_add_fixed_mem32_resource(dev, &res, dependent, size);
867 size = 0;
868 break;
869 case _STAG_END:
870 if (size > 0)
871 isapnp_skip_bytes(size);
872 return 1;
873 default:
874 printk("isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n", type, dev->devfn, card->number);
876 __skip:
877 if (size > 0)
878 isapnp_skip_bytes(size);
880 isapnp_config_prepare(dev);
881 return 0;
885 * Parse resource map for ISA PnP card.
888 static void __init isapnp_parse_resource_map(struct pci_bus *card)
890 unsigned char type, tmp[17];
891 unsigned short size;
893 while (1) {
894 if (isapnp_read_tag(&type, &size)<0)
895 return;
896 switch (type) {
897 case _STAG_PNPVERNO:
898 if (size != 2)
899 goto __skip;
900 isapnp_peek(tmp, 2);
901 card->pnpver = tmp[0];
902 card->productver = tmp[1];
903 size = 0;
904 break;
905 case _STAG_LOGDEVID:
906 if (size >= 5 && size <= 6) {
907 if (isapnp_create_device(card, size)==1)
908 return;
909 size = 0;
911 break;
912 case _STAG_VENDOR:
913 break;
914 case _LTAG_ANSISTR:
915 if (card->name[0] == '\0') {
916 unsigned short size1 = size > 47 ? 47 : size;
917 isapnp_peek(card->name, size1);
918 card->name[size1] = '\0';
919 size -= size1;
921 break;
922 case _LTAG_UNICODESTR:
923 /* silently ignore */
924 /* who use unicode for hardware identification? */
925 break;
926 case _LTAG_VENDOR:
927 break;
928 case _STAG_END:
929 if (size > 0)
930 isapnp_skip_bytes(size);
931 return;
932 default:
933 printk("isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n", type, card->number);
935 __skip:
936 if (size > 0)
937 isapnp_skip_bytes(size);
942 * Compute ISA PnP checksum for first eight bytes.
945 static unsigned char __init isapnp_checksum(unsigned char *data)
947 int i, j;
948 unsigned char checksum = 0x6a, bit, b;
950 for (i = 0; i < 8; i++) {
951 b = data[i];
952 for (j = 0; j < 8; j++) {
953 bit = 0;
954 if (b & (1 << j))
955 bit = 1;
956 checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1);
959 return checksum;
963 * Build device list for all present ISA PnP devices.
966 static int __init isapnp_build_device_list(void)
968 int csn;
969 unsigned char header[9], checksum;
970 struct pci_bus *card;
971 struct pci_dev *dev;
973 isapnp_wait();
974 isapnp_key();
975 for (csn = 1; csn <= 10; csn++) {
976 isapnp_wake(csn);
977 isapnp_peek(header, 9);
978 checksum = isapnp_checksum(header);
979 #if 0
980 printk("vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
981 header[0], header[1], header[2], header[3],
982 header[4], header[5], header[6], header[7], header[8]);
983 printk("checksum = 0x%x\n", checksum);
984 #endif
985 if (checksum == 0x00 || checksum != header[8]) /* not valid CSN */
986 continue;
987 if ((card = isapnp_alloc(sizeof(struct pci_bus))) == NULL)
988 continue;
989 card->number = csn;
990 card->vendor = (header[1] << 8) | header[0];
991 card->device = (header[3] << 8) | header[2];
992 card->serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4];
993 isapnp_checksum_value = 0x00;
994 INIT_LIST_HEAD(&card->children);
995 INIT_LIST_HEAD(&card->devices);
996 isapnp_parse_resource_map(card);
997 if (isapnp_checksum_value != 0x00)
998 printk("isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value);
999 card->checksum = isapnp_checksum_value;
1001 list_add_tail(&card->node, &isapnp_cards);
1003 isapnp_for_each_dev(dev) {
1004 isapnp_fixup_device(dev);
1006 return 0;
1010 * Basic configuration routines.
1013 int isapnp_present(void)
1015 return !list_empty(&isapnp_devices);
1018 int isapnp_cfg_begin(int csn, int logdev)
1020 if (csn < 1 || csn > 10 || logdev > 10)
1021 return -EINVAL;
1022 MOD_INC_USE_COUNT;
1023 down(&isapnp_cfg_mutex);
1024 isapnp_wait();
1025 isapnp_key();
1026 isapnp_wake(csn);
1027 #if 1 /* to avoid malfunction when the isapnptools package is used */
1028 isapnp_set_rdp();
1029 udelay(1000); /* delay 1000us */
1030 write_address(0x01);
1031 udelay(1000); /* delay 1000us */
1032 #endif
1033 if (logdev >= 0)
1034 isapnp_device(logdev);
1035 return 0;
1038 int isapnp_cfg_end(void)
1040 isapnp_wait();
1041 up(&isapnp_cfg_mutex);
1042 MOD_DEC_USE_COUNT;
1043 return 0;
1047 * Resource manager.
1050 static struct isapnp_port *isapnp_find_port(struct pci_dev *dev, int index)
1052 struct isapnp_resources *res;
1053 struct isapnp_port *port;
1055 if (!dev || index < 0 || index > 7)
1056 return NULL;
1057 for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1058 for (port = res->port; port; port = port->next) {
1059 if (!index)
1060 return port;
1061 index--;
1064 return NULL;
1067 struct isapnp_irq *isapnp_find_irq(struct pci_dev *dev, int index)
1069 struct isapnp_resources *res, *resa;
1070 struct isapnp_irq *irq;
1071 int index1, index2, index3;
1073 if (!dev || index < 0 || index > 7)
1074 return NULL;
1075 for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1076 index3 = 0;
1077 for (resa = res; resa; resa = resa->alt) {
1078 index1 = index;
1079 index2 = 0;
1080 for (irq = resa->irq; irq; irq = irq->next) {
1081 if (!index1)
1082 return irq;
1083 index1--;
1084 index2++;
1086 if (index3 < index2)
1087 index3 = index2;
1089 index -= index3;
1091 return NULL;
1094 struct isapnp_dma *isapnp_find_dma(struct pci_dev *dev, int index)
1096 struct isapnp_resources *res;
1097 struct isapnp_dma *dma;
1099 if (!dev || index < 0 || index > 7)
1100 return NULL;
1101 for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1102 for (dma = res->dma; dma; dma = dma->next) {
1103 if (!index)
1104 return dma;
1105 index--;
1108 return NULL;
1111 struct isapnp_mem *isapnp_find_mem(struct pci_dev *dev, int index)
1113 struct isapnp_resources *res;
1114 struct isapnp_mem *mem;
1116 if (!dev || index < 0 || index > 7)
1117 return NULL;
1118 for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1119 for (mem = res->mem; mem; mem = mem->next) {
1120 if (!index)
1121 return mem;
1122 index--;
1125 return NULL;
1128 struct isapnp_mem32 *isapnp_find_mem32(struct pci_dev *dev, int index)
1130 struct isapnp_resources *res;
1131 struct isapnp_mem32 *mem32;
1133 if (!dev || index < 0 || index > 7)
1134 return NULL;
1135 for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1136 for (mem32 = res->mem32; mem32; mem32 = mem32->next) {
1137 if (!index)
1138 return mem32;
1139 index--;
1142 return NULL;
1146 * Device manager.
1149 struct pci_bus *isapnp_find_card(unsigned short vendor,
1150 unsigned short device,
1151 struct pci_bus *from)
1153 struct list_head *list;
1155 list = isapnp_cards.next;
1156 if (from)
1157 list = from->node.next;
1159 while (list != &isapnp_cards) {
1160 struct pci_bus *card = pci_bus_b(list);
1161 if (card->vendor == vendor && card->device == device)
1162 return card;
1163 list = list->next;
1165 return NULL;
1168 struct pci_dev *isapnp_find_dev(struct pci_bus *card,
1169 unsigned short vendor,
1170 unsigned short function,
1171 struct pci_dev *from)
1173 if (card == NULL) { /* look for a logical device from all cards */
1174 struct list_head *list;
1176 list = isapnp_devices.next;
1177 if (from)
1178 list = from->global_list.next;
1180 while (list != &isapnp_devices) {
1181 int idx;
1182 struct pci_dev *dev = pci_dev_g(list);
1184 if (dev->vendor == vendor && dev->device == function)
1185 return dev;
1186 for (idx = 0; idx < DEVICE_COUNT_COMPATIBLE; idx++)
1187 if (dev->vendor_compatible[idx] == vendor &&
1188 dev->device_compatible[idx] == function)
1189 return dev;
1190 list = list->next;
1192 } else {
1193 struct list_head *list;
1195 list = card->devices.next;
1196 if (from) {
1197 list = from->bus_list.next;
1198 if (from->bus != card) /* something is wrong */
1199 return NULL;
1201 while (list != &card->devices) {
1202 int idx;
1203 struct pci_dev *dev = pci_dev_b(list);
1205 if (dev->vendor == vendor && dev->device == function)
1206 return dev;
1207 for (idx = 0; idx < DEVICE_COUNT_COMPATIBLE; idx++)
1208 if (dev->vendor_compatible[idx] == vendor &&
1209 dev->device_compatible[idx] == function)
1210 return dev;
1211 list = list->next;
1214 return NULL;
1217 static const struct isapnp_card_id *
1218 isapnp_match_card(const struct isapnp_card_id *ids, struct pci_bus *card)
1220 int idx;
1222 while (ids->vendor || ids->device) {
1223 if ((ids->vendor == ISAPNP_ANY_ID || ids->vendor == card->vendor) &&
1224 (ids->device == ISAPNP_ANY_ID || ids->device == card->device)) {
1225 for (idx = 0; idx < ISAPNP_CARD_DEVS; idx++) {
1226 if (ids->devs[idx].vendor == 0 &&
1227 ids->devs[idx].function == 0)
1228 return ids;
1229 if (isapnp_find_dev(card,
1230 ids->devs[idx].vendor,
1231 ids->devs[idx].function,
1232 NULL) == NULL)
1233 goto __next;
1235 return ids;
1237 __next:
1238 ids++;
1240 return NULL;
1243 int isapnp_probe_cards(const struct isapnp_card_id *ids,
1244 int (*probe)(struct pci_bus *_card,
1245 const struct isapnp_card_id *_id))
1247 struct pci_bus *card;
1248 const struct isapnp_card_id *id;
1249 int count = 0;
1251 if (ids == NULL || probe == NULL)
1252 return -EINVAL;
1253 isapnp_for_each_card(card) {
1254 id = isapnp_match_card(ids, card);
1255 if (id != NULL && probe(card, id) >= 0)
1256 count++;
1258 return count;
1261 static unsigned int isapnp_dma_resource_flags(struct isapnp_dma *dma)
1263 return dma->flags | IORESOURCE_DMA | IORESOURCE_AUTO;
1266 static unsigned int isapnp_mem_resource_flags(struct isapnp_mem *mem)
1268 unsigned int result;
1270 result = mem->flags | IORESOURCE_MEM | IORESOURCE_AUTO;
1271 if (!(mem->flags & IORESOURCE_MEM_WRITEABLE))
1272 result |= IORESOURCE_READONLY;
1273 if (mem->flags & IORESOURCE_MEM_CACHEABLE)
1274 result |= IORESOURCE_CACHEABLE;
1275 if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
1276 result |= IORESOURCE_RANGELENGTH;
1277 if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
1278 result |= IORESOURCE_SHADOWABLE;
1279 return result;
1282 static unsigned int isapnp_irq_resource_flags(struct isapnp_irq *irq)
1284 return irq->flags | IORESOURCE_IRQ | IORESOURCE_AUTO;
1287 static unsigned int isapnp_port_resource_flags(struct isapnp_port *port)
1289 return port->flags | IORESOURCE_IO | IORESOURCE_AUTO;
1292 static int isapnp_config_prepare(struct pci_dev *dev)
1294 struct isapnp_resources *res, *resa;
1295 struct isapnp_port *port;
1296 struct isapnp_irq *irq;
1297 struct isapnp_dma *dma;
1298 struct isapnp_mem *mem;
1299 int port_count, port_count1;
1300 int irq_count, irq_count1;
1301 int dma_count, dma_count1;
1302 int mem_count, mem_count1;
1303 int idx;
1305 if (dev == NULL)
1306 return -EINVAL;
1307 if (dev->active || dev->ro)
1308 return -EBUSY;
1309 for (idx = 0; idx < DEVICE_COUNT_IRQ; idx++) {
1310 dev->irq_resource[idx].name = NULL;
1311 dev->irq_resource[idx].start = 0;
1312 dev->irq_resource[idx].end = 0;
1313 dev->irq_resource[idx].flags = 0;
1315 for (idx = 0; idx < DEVICE_COUNT_DMA; idx++) {
1316 dev->dma_resource[idx].name = NULL;
1317 dev->dma_resource[idx].start = 0;
1318 dev->dma_resource[idx].end = 0;
1319 dev->dma_resource[idx].flags = 0;
1321 for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) {
1322 dev->resource[idx].name = NULL;
1323 dev->resource[idx].start = 0;
1324 dev->resource[idx].end = 0;
1325 dev->resource[idx].flags = 0;
1327 port_count = irq_count = dma_count = mem_count = 0;
1328 for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1329 port_count1 = irq_count1 = dma_count1 = mem_count1 = 0;
1330 for (resa = res; resa; resa = resa->alt) {
1331 for (port = resa->port, idx = 0; port; port = port->next, idx++) {
1332 if (dev->resource[port_count + idx].flags == 0) {
1333 dev->resource[port_count + idx].flags = isapnp_port_resource_flags(port);
1334 dev->resource[port_count + idx].end = port->size;
1337 if (port_count1 < idx)
1338 port_count1 = idx;
1339 for (irq = resa->irq, idx = 0; irq; irq = irq->next, idx++) {
1340 int count = irq_count + idx;
1341 if (count < DEVICE_COUNT_IRQ) {
1342 if (dev->irq_resource[count].flags == 0) {
1343 dev->irq_resource[count].flags = isapnp_irq_resource_flags(irq);
1348 if (irq_count1 < idx)
1349 irq_count1 = idx;
1350 for (dma = resa->dma, idx = 0; dma; dma = dma->next, idx++)
1351 if (dev->dma_resource[idx].flags == 0) {
1352 dev->dma_resource[idx].flags = isapnp_dma_resource_flags(dma);
1354 if (dma_count1 < idx)
1355 dma_count1 = idx;
1356 for (mem = resa->mem, idx = 0; mem; mem = mem->next, idx++)
1357 if (dev->resource[mem_count + idx + 8].flags == 0) {
1358 dev->resource[mem_count + idx + 8].flags = isapnp_mem_resource_flags(mem);
1360 if (mem_count1 < idx)
1361 mem_count1 = idx;
1363 port_count += port_count1;
1364 irq_count += irq_count1;
1365 dma_count += dma_count1;
1366 mem_count += mem_count1;
1368 return 0;
1371 struct isapnp_cfgtmp {
1372 struct isapnp_port *port[8];
1373 struct isapnp_irq *irq[2];
1374 struct isapnp_dma *dma[2];
1375 struct isapnp_mem *mem[4];
1376 struct pci_dev *request;
1377 struct pci_dev result;
1380 static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg,
1381 struct isapnp_resources *from,
1382 struct isapnp_resources *to)
1384 int tmp, tmp1;
1385 struct isapnp_port *port;
1386 struct isapnp_irq *irq;
1387 struct isapnp_dma *dma;
1388 struct isapnp_mem *mem;
1390 if (!cfg)
1391 return -EINVAL;
1392 /* process port settings */
1393 for (tmp = 0; tmp < 8; tmp++) {
1394 if (!(cfg->request->resource[tmp].flags & IORESOURCE_AUTO))
1395 continue; /* don't touch */
1396 port = cfg->port[tmp];
1397 if (!port) {
1398 cfg->port[tmp] = port = isapnp_find_port(cfg->request, tmp);
1399 if (!port)
1400 return -EINVAL;
1402 if (from && port->res == from) {
1403 while (port->res != to) {
1404 if (!port->res->alt)
1405 return -EINVAL;
1406 port = port->res->alt->port;
1407 for (tmp1 = tmp; tmp1 > 0 && port; tmp1--)
1408 port = port->next;
1409 cfg->port[tmp] = port;
1410 if (!port)
1411 return -ENOENT;
1412 cfg->result.resource[tmp].flags = isapnp_port_resource_flags(port);
1416 /* process irq settings */
1417 for (tmp = 0; tmp < 2; tmp++) {
1418 if (!(cfg->request->irq_resource[tmp].flags & IORESOURCE_AUTO))
1419 continue; /* don't touch */
1420 irq = cfg->irq[tmp];
1421 if (!irq) {
1422 cfg->irq[tmp] = irq = isapnp_find_irq(cfg->request, tmp);
1423 if (!irq)
1424 return -EINVAL;
1426 if (from && irq->res == from) {
1427 while (irq->res != to) {
1428 if (!irq->res->alt)
1429 return -EINVAL;
1430 irq = irq->res->alt->irq;
1431 for (tmp1 = tmp; tmp1 > 0 && irq; tmp1--)
1432 irq = irq->next;
1433 cfg->irq[tmp] = irq;
1434 if (!irq)
1435 return -ENOENT;
1436 cfg->result.irq_resource[tmp].flags = isapnp_irq_resource_flags(irq);
1440 /* process dma settings */
1441 for (tmp = 0; tmp < 2; tmp++) {
1442 if (!(cfg->request->dma_resource[tmp].flags & IORESOURCE_AUTO))
1443 continue; /* don't touch */
1444 dma = cfg->dma[tmp];
1445 if (!dma) {
1446 cfg->dma[tmp] = dma = isapnp_find_dma(cfg->request, tmp);
1447 if (!dma)
1448 return -EINVAL;
1450 if (from && dma->res == from) {
1451 while (dma->res != to) {
1452 if (!dma->res->alt)
1453 return -EINVAL;
1454 dma = dma->res->alt->dma;
1455 for (tmp1 = tmp; tmp1 > 0 && dma; tmp1--)
1456 dma = dma->next;
1457 cfg->dma[tmp] = dma;
1458 if (!dma)
1459 return -ENOENT;
1460 cfg->result.dma_resource[tmp].flags = isapnp_dma_resource_flags(dma);
1464 /* process memory settings */
1465 for (tmp = 0; tmp < 4; tmp++) {
1466 if (!(cfg->request->resource[tmp + 8].flags & IORESOURCE_AUTO))
1467 continue; /* don't touch */
1468 mem = cfg->mem[tmp];
1469 if (!mem) {
1470 cfg->mem[tmp] = mem = isapnp_find_mem(cfg->request, tmp);
1471 if (!mem)
1472 return -EINVAL;
1474 if (from && mem->res == from) {
1475 while (mem->res != to) {
1476 if (!mem->res->alt)
1477 return -EINVAL;
1478 mem = mem->res->alt->mem;
1479 for (tmp1 = tmp; tmp1 > 0 && mem; tmp1--)
1480 mem = mem->next;
1481 cfg->mem[tmp] = mem;
1482 if (!mem)
1483 return -ENOENT;
1484 cfg->result.resource[tmp + 8].flags = isapnp_mem_resource_flags(mem);
1488 return 0;
1491 static int isapnp_check_port(struct isapnp_cfgtmp *cfg, int port, int size, int idx)
1493 int i, tmp, rport, rsize;
1494 struct isapnp_port *xport;
1495 struct pci_dev *dev;
1497 if (check_region(port, size))
1498 return 1;
1499 for (i = 0; i < 8; i++) {
1500 rport = isapnp_reserve_io[i << 1];
1501 rsize = isapnp_reserve_io[(i << 1) + 1];
1502 if (port >= rport && port < rport + rsize)
1503 return 1;
1504 if (port + size > rport && port + size < (rport + rsize) - 1)
1505 return 1;
1508 isapnp_for_each_dev(dev) {
1509 if (dev->active) {
1510 for (tmp = 0; tmp < 8; tmp++) {
1511 if (dev->resource[tmp].flags) {
1512 rport = dev->resource[tmp].start;
1513 rsize = (dev->resource[tmp].end - rport) + 1;
1514 if (port >= rport && port < rport + rsize)
1515 return 1;
1516 if (port + size > rport && port + size < (rport + rsize) - 1)
1517 return 1;
1522 for (i = 0; i < 8; i++) {
1523 unsigned int flags;
1524 if (i == idx)
1525 continue;
1526 flags = cfg->request->resource[i].flags;
1527 if (!flags)
1528 continue;
1529 tmp = cfg->request->resource[i].start;
1530 if (flags & IORESOURCE_AUTO) { /* auto */
1531 xport = cfg->port[i];
1532 if (!xport)
1533 return 1;
1534 if (cfg->result.resource[i].flags & IORESOURCE_AUTO)
1535 continue;
1536 tmp = cfg->result.resource[i].start;
1537 if (tmp + xport->size >= port && tmp <= port + xport->size)
1538 return 1;
1539 continue;
1541 if (port == tmp)
1542 return 1;
1543 xport = isapnp_find_port(cfg->request, i);
1544 if (!xport)
1545 return 1;
1546 if (tmp + xport->size >= port && tmp <= port + xport->size)
1547 return 1;
1549 return 0;
1552 static int isapnp_valid_port(struct isapnp_cfgtmp *cfg, int idx)
1554 int err;
1555 unsigned long *value1, *value2;
1556 struct isapnp_port *port;
1558 if (!cfg || idx < 0 || idx > 7)
1559 return -EINVAL;
1560 if (!(cfg->result.resource[idx].flags & IORESOURCE_AUTO)) /* don't touch */
1561 return 0;
1562 __again:
1563 port = cfg->port[idx];
1564 if (!port)
1565 return -EINVAL;
1566 value1 = &cfg->result.resource[idx].start;
1567 value2 = &cfg->result.resource[idx].end;
1568 if (cfg->result.resource[idx].flags & IORESOURCE_AUTO) {
1569 cfg->result.resource[idx].flags &= ~IORESOURCE_AUTO;
1570 *value1 = port->min;
1571 *value2 = port->min + port->size - 1;
1572 if (!isapnp_check_port(cfg, *value1, port->size, idx))
1573 return 0;
1575 do {
1576 *value1 += port->align;
1577 *value2 = *value1 + port->size - 1;
1578 if (*value1 > port->max || !port->align) {
1579 if (port->res && port->res->alt) {
1580 if ((err = isapnp_alternative_switch(cfg, port->res, port->res->alt))<0)
1581 return err;
1582 goto __again;
1584 return -ENOENT;
1586 } while (isapnp_check_port(cfg, *value1, port->size, idx));
1587 return 0;
1590 static void isapnp_test_handler(int irq, void *dev_id, struct pt_regs *regs)
1594 static int isapnp_check_interrupt(struct isapnp_cfgtmp *cfg, int irq, int idx)
1596 int i;
1597 struct pci_dev *dev;
1599 if (irq < 0 || irq > 15)
1600 return 1;
1601 for (i = 0; i < 16; i++) {
1602 if (isapnp_reserve_irq[i] == irq)
1603 return 1;
1605 isapnp_for_each_dev(dev) {
1606 if (dev->active) {
1607 if (dev->irq_resource[0].start == irq ||
1608 dev->irq_resource[1].start == irq)
1609 return 1;
1612 #ifdef CONFIG_PCI
1613 if (!isapnp_skip_pci_scan) {
1614 pci_for_each_dev(dev) {
1615 if (dev->irq == irq)
1616 return 1;
1619 #endif
1620 if (request_irq(irq, isapnp_test_handler, SA_INTERRUPT, "isapnp", NULL))
1621 return 1;
1622 free_irq(irq, NULL);
1623 for (i = 0; i < DEVICE_COUNT_IRQ; i++) {
1624 if (i == idx)
1625 continue;
1626 if (!cfg->result.irq_resource[i].flags)
1627 continue;
1628 if (cfg->result.irq_resource[i].flags & IORESOURCE_AUTO)
1629 continue;
1630 if (cfg->result.irq_resource[i].start == irq)
1631 return 1;
1633 return 0;
1636 static int isapnp_valid_irq(struct isapnp_cfgtmp *cfg, int idx)
1638 /* IRQ priority: this table is good for i386 */
1639 static unsigned short xtab[16] = {
1640 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
1642 int err, i;
1643 unsigned long *value1, *value2;
1644 struct isapnp_irq *irq;
1646 if (!cfg || idx < 0 || idx > 1)
1647 return -EINVAL;
1648 if (!(cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO))
1649 return 0;
1650 __again:
1651 irq = cfg->irq[idx];
1652 if (!irq)
1653 return -EINVAL;
1654 value1 = &cfg->result.irq_resource[idx].start;
1655 value2 = &cfg->result.irq_resource[idx].end;
1656 if (cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO) {
1657 for (i = 0; i < 16 && !(irq->map & (1<<xtab[i])); i++);
1658 if (i >= 16)
1659 return -ENOENT;
1660 cfg->result.irq_resource[idx].flags &= ~IORESOURCE_AUTO;
1661 if (!isapnp_check_interrupt(cfg, *value1 = *value2 = xtab[i], idx))
1662 return 0;
1664 do {
1665 for (i = 0; i < 16 && xtab[i] != *value1; i++);
1666 for (i++; i < 16 && !(irq->map & (1<<xtab[i])); i++);
1667 if (i >= 16) {
1668 if (irq->res && irq->res->alt) {
1669 if ((err = isapnp_alternative_switch(cfg, irq->res, irq->res->alt))<0)
1670 return err;
1671 goto __again;
1673 return -ENOENT;
1674 } else {
1675 *value1 = *value2 = xtab[i];
1677 } while (isapnp_check_interrupt(cfg, *value1, idx));
1678 return 0;
1681 static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx)
1683 int i;
1684 struct pci_dev *dev;
1686 /* Some machines allow DMA 0, but others don't. In fact on some
1687 boxes DMA 0 is the memory refresh. Play safe */
1689 if (dma < 1 || dma == 4 || dma > 7)
1690 return 1;
1691 for (i = 0; i < 8; i++) {
1692 if (isapnp_reserve_dma[i] == dma)
1693 return 1;
1695 isapnp_for_each_dev(dev) {
1696 if (dev->active) {
1697 if (dev->dma_resource[0].start == dma || dev->dma_resource[1].start == dma)
1698 return 1;
1701 if (request_dma(dma, "isapnp"))
1702 return 1;
1703 free_dma(dma);
1704 for (i = 0; i < 2; i++) {
1705 if (i == idx)
1706 continue;
1707 if (!cfg->result.dma_resource[i].flags ||
1708 (cfg->result.dma_resource[i].flags & IORESOURCE_AUTO))
1709 continue;
1710 if (cfg->result.dma_resource[i].start == dma)
1711 return 1;
1713 return 0;
1716 static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx)
1718 int err, i;
1719 unsigned long *value1, *value2;
1720 struct isapnp_dma *dma;
1722 if (!cfg || idx < 0 || idx > 1)
1723 return -EINVAL;
1724 if (!(cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO)) /* don't touch */
1725 return 0;
1726 __again:
1727 dma = cfg->dma[idx];
1728 if (!dma)
1729 return -EINVAL;
1730 value1 = &cfg->result.dma_resource[idx].start;
1731 value2 = &cfg->result.dma_resource[idx].end;
1732 if (cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO) {
1733 for (i = 0; i < 8 && !(dma->map & (1<<i)); i++);
1734 if (i >= 8)
1735 return -ENOENT;
1736 cfg->result.dma_resource[idx].flags &= ~IORESOURCE_AUTO;
1737 if (!isapnp_check_dma(cfg, *value1 = *value2 = i, idx))
1738 return 0;
1740 do {
1741 for (i = *value1 + 1; i < 8 && !(dma->map & (1<<i)); i++);
1742 if (i >= 8) {
1743 if (dma->res && dma->res->alt) {
1744 if ((err = isapnp_alternative_switch(cfg, dma->res, dma->res->alt))<0)
1745 return err;
1746 goto __again;
1748 return -ENOENT;
1749 } else {
1750 *value1 = *value2 = i;
1752 } while (isapnp_check_dma(cfg, *value1, idx));
1753 return 0;
1756 static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsigned int size, int idx)
1758 int i, tmp;
1759 unsigned int raddr, rsize;
1760 struct isapnp_mem *xmem;
1761 struct pci_dev *dev;
1763 for (i = 0; i < 8; i++) {
1764 raddr = (unsigned int)isapnp_reserve_mem[i << 1];
1765 rsize = (unsigned int)isapnp_reserve_mem[(i << 1) + 1];
1766 if (addr >= raddr && addr < raddr + rsize)
1767 return 1;
1768 if (addr + size > raddr && addr + size < (raddr + rsize) - 1)
1769 return 1;
1770 if (__check_region(&iomem_resource, addr, size))
1771 return 1;
1773 isapnp_for_each_dev(dev) {
1774 if (dev->active) {
1775 for (tmp = 0; tmp < 4; tmp++) {
1776 if (dev->resource[tmp].flags) {
1777 raddr = dev->resource[tmp + 8].start;
1778 rsize = (dev->resource[tmp + 8].end - raddr) + 1;
1779 if (addr >= raddr && addr < raddr + rsize)
1780 return 1;
1781 if (addr + size > raddr && addr + size < (raddr + rsize) - 1)
1782 return 1;
1787 for (i = 0; i < 4; i++) {
1788 unsigned int flags = cfg->request->resource[i + 8].flags;
1789 if (i == idx)
1790 continue;
1791 if (!flags)
1792 continue;
1793 tmp = cfg->result.resource[i + 8].start;
1794 if (flags & IORESOURCE_AUTO) { /* auto */
1795 xmem = cfg->mem[i];
1796 if (!xmem)
1797 return 1;
1798 if (cfg->result.resource[i + 8].flags & IORESOURCE_AUTO)
1799 continue;
1800 if (tmp + xmem->size >= addr && tmp <= addr + xmem->size)
1801 return 1;
1802 continue;
1804 if (addr == tmp)
1805 return 1;
1806 xmem = isapnp_find_mem(cfg->request, i);
1807 if (!xmem)
1808 return 1;
1809 if (tmp + xmem->size >= addr && tmp <= addr + xmem->size)
1810 return 1;
1812 return 0;
1815 static int isapnp_valid_mem(struct isapnp_cfgtmp *cfg, int idx)
1817 int err;
1818 unsigned long *value1, *value2;
1819 struct isapnp_mem *mem;
1821 if (!cfg || idx < 0 || idx > 3)
1822 return -EINVAL;
1823 if (!(cfg->result.resource[idx + 8].flags & IORESOURCE_AUTO)) /* don't touch */
1824 return 0;
1825 __again:
1826 mem = cfg->mem[idx];
1827 if (!mem)
1828 return -EINVAL;
1829 value1 = &cfg->result.resource[idx + 8].start;
1830 value2 = &cfg->result.resource[idx + 8].end;
1831 if (cfg->result.resource[idx + 8].flags & IORESOURCE_AUTO) {
1832 cfg->result.resource[idx + 8].flags &= ~IORESOURCE_AUTO;
1833 *value1 = mem->min;
1834 *value2 = mem->min + mem->size - 1;
1835 if (!isapnp_check_mem(cfg, *value1, mem->size, idx))
1836 return 0;
1838 do {
1839 *value1 += mem->align;
1840 *value2 = *value1 + mem->size - 1;
1841 if (*value1 > mem->max || !mem->align) {
1842 if (mem->res && mem->res->alt) {
1843 if ((err = isapnp_alternative_switch(cfg, mem->res, mem->res->alt))<0)
1844 return err;
1845 goto __again;
1847 return -ENOENT;
1849 } while (isapnp_check_mem(cfg, *value1, mem->size, idx));
1850 return 0;
1853 static int isapnp_check_valid(struct isapnp_cfgtmp *cfg)
1855 int tmp;
1857 for (tmp = 0; tmp < 8; tmp++)
1858 if (cfg->result.resource[tmp].flags & IORESOURCE_AUTO)
1859 return -EAGAIN;
1860 for (tmp = 0; tmp < 2; tmp++)
1861 if (cfg->result.irq_resource[tmp].flags & IORESOURCE_AUTO)
1862 return -EAGAIN;
1863 for (tmp = 0; tmp < 2; tmp++)
1864 if (cfg->result.dma_resource[tmp].flags & IORESOURCE_AUTO)
1865 return -EAGAIN;
1866 for (tmp = 0; tmp < 4; tmp++)
1867 if (cfg->result.resource[tmp + 8].flags & IORESOURCE_AUTO)
1868 return -EAGAIN;
1869 return 0;
1872 static int isapnp_config_activate(struct pci_dev *dev)
1874 struct isapnp_cfgtmp cfg;
1875 int tmp, fauto, err;
1877 if (!dev)
1878 return -EINVAL;
1879 if (dev->active)
1880 return -EBUSY;
1881 memset(&cfg, 0, sizeof(cfg));
1882 cfg.request = dev;
1883 memcpy(&cfg.result, dev, sizeof(struct pci_dev));
1884 /* check if all values are set, otherwise try auto-configuration */
1885 for (tmp = fauto = 0; !fauto && tmp < 8; tmp++) {
1886 if (dev->resource[tmp].flags & IORESOURCE_AUTO)
1887 fauto++;
1889 for (tmp = 0; !fauto && tmp < 2; tmp++) {
1890 if (dev->irq_resource[tmp].flags & IORESOURCE_AUTO)
1891 fauto++;
1893 for (tmp = 0; !fauto && tmp < 2; tmp++) {
1894 if (dev->dma_resource[tmp].flags & IORESOURCE_AUTO)
1895 fauto++;
1897 for (tmp = 0; !fauto && tmp < 4; tmp++) {
1898 if (dev->resource[tmp + 8].flags & IORESOURCE_AUTO)
1899 fauto++;
1901 if (!fauto)
1902 goto __skip_auto;
1903 /* set variables to initial values */
1904 if ((err = isapnp_alternative_switch(&cfg, NULL, NULL))<0)
1905 return err;
1906 /* find first valid configuration */
1907 fauto = 0;
1908 do {
1909 for (tmp = 0; tmp < 8 && cfg.result.resource[tmp].flags; tmp++)
1910 if ((err = isapnp_valid_port(&cfg, tmp))<0)
1911 return err;
1912 for (tmp = 0; tmp < 2 && cfg.result.irq_resource[tmp].flags; tmp++)
1913 if ((err = isapnp_valid_irq(&cfg, tmp))<0)
1914 return err;
1915 for (tmp = 0; tmp < 2 && cfg.result.dma_resource[tmp].flags; tmp++)
1916 if ((err = isapnp_valid_dma(&cfg, tmp))<0)
1917 return err;
1918 for (tmp = 0; tmp < 4 && cfg.result.resource[tmp + 8].flags; tmp++)
1919 if ((err = isapnp_valid_mem(&cfg, tmp))<0)
1920 return err;
1921 } while (isapnp_check_valid(&cfg)<0 && fauto++ < 20);
1922 if (fauto >= 20)
1923 return -EAGAIN;
1924 __skip_auto:
1925 /* we have valid configuration, try configure hardware */
1926 isapnp_cfg_begin(dev->bus->number, dev->devfn);
1927 dev->active = 1;
1928 dev->irq_resource[0] = cfg.result.irq_resource[0];
1929 dev->irq_resource[1] = cfg.result.irq_resource[1];
1930 dev->dma_resource[0] = cfg.result.dma_resource[0];
1931 dev->dma_resource[1] = cfg.result.dma_resource[1];
1932 for (tmp = 0; tmp < 12; tmp++) {
1933 dev->resource[tmp] = cfg.result.resource[tmp];
1935 for (tmp = 0; tmp < 8 && dev->resource[tmp].flags; tmp++)
1936 isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), dev->resource[tmp].start);
1937 for (tmp = 0; tmp < 2 && dev->irq_resource[tmp].flags; tmp++) {
1938 int irq = dev->irq_resource[tmp].start;
1939 if (irq == 2)
1940 irq = 9;
1941 isapnp_write_byte(ISAPNP_CFG_IRQ+(tmp<<1), irq);
1943 for (tmp = 0; tmp < 2 && dev->dma_resource[tmp].flags; tmp++)
1944 isapnp_write_byte(ISAPNP_CFG_DMA+tmp, dev->dma_resource[tmp].start);
1945 for (tmp = 0; tmp < 4 && dev->resource[tmp+8].flags; tmp++)
1946 isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (dev->resource[tmp + 8].start >> 8) & 0xffff);
1947 isapnp_activate(dev->devfn);
1948 isapnp_cfg_end();
1949 return 0;
1952 static int isapnp_config_deactivate(struct pci_dev *dev)
1954 if (!dev || !dev->active)
1955 return -EINVAL;
1956 isapnp_cfg_begin(dev->bus->number, dev->devfn);
1957 isapnp_deactivate(dev->devfn);
1958 dev->active = 0;
1959 isapnp_cfg_end();
1960 return 0;
1963 void isapnp_resource_change(struct resource *resource,
1964 unsigned long start,
1965 unsigned long size)
1967 if (resource == NULL)
1968 return;
1969 resource->flags &= ~IORESOURCE_AUTO;
1970 resource->start = start;
1971 resource->end = start + size - 1;
1975 * Inititialization.
1978 #ifdef MODULE
1980 static void isapnp_free_port(struct isapnp_port *port)
1982 struct isapnp_port *next;
1984 while (port) {
1985 next = port->next;
1986 kfree(port);
1987 port = next;
1991 static void isapnp_free_irq(struct isapnp_irq *irq)
1993 struct isapnp_irq *next;
1995 while (irq) {
1996 next = irq->next;
1997 kfree(irq);
1998 irq = next;
2002 static void isapnp_free_dma(struct isapnp_dma *dma)
2004 struct isapnp_dma *next;
2006 while (dma) {
2007 next = dma->next;
2008 kfree(dma);
2009 dma = next;
2013 static void isapnp_free_mem(struct isapnp_mem *mem)
2015 struct isapnp_mem *next;
2017 while (mem) {
2018 next = mem->next;
2019 kfree(mem);
2020 mem = next;
2024 static void isapnp_free_mem32(struct isapnp_mem32 *mem32)
2026 struct isapnp_mem32 *next;
2028 while (mem32) {
2029 next = mem32->next;
2030 kfree(mem32);
2031 mem32 = next;
2035 static void isapnp_free_resources(struct isapnp_resources *resources, int alt)
2037 struct isapnp_resources *next;
2039 while (resources) {
2040 next = alt ? resources->alt : resources->next;
2041 isapnp_free_port(resources->port);
2042 isapnp_free_irq(resources->irq);
2043 isapnp_free_dma(resources->dma);
2044 isapnp_free_mem(resources->mem);
2045 isapnp_free_mem32(resources->mem32);
2046 if (!alt && resources->alt)
2047 isapnp_free_resources(resources->alt, 1);
2048 kfree(resources);
2049 resources = next;
2053 static void isapnp_free_card(struct pci_bus *card)
2055 while (!list_empty(&card->devices)) {
2056 struct list_head *list = card->devices.next;
2057 struct pci_dev *dev = pci_dev_b(list);
2058 list_del(list);
2059 isapnp_free_resources((struct isapnp_resources *)dev->sysdata, 0);
2060 kfree(dev);
2062 kfree(card);
2065 #endif /* MODULE */
2067 static void isapnp_free_all_resources(void)
2069 #ifdef ISAPNP_REGION_OK
2070 if (pidxr_res)
2071 release_resource(pidxr_res);
2072 #endif
2073 if (pnpwrp_res)
2074 release_resource(pnpwrp_res);
2075 if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff && isapnp_rdp_res)
2076 release_resource(isapnp_rdp_res);
2077 #ifdef MODULE
2078 #ifdef CONFIG_PROC_FS
2079 isapnp_proc_done();
2080 #endif
2081 while (!list_empty(&isapnp_cards)) {
2082 struct list_head *list = isapnp_cards.next;
2083 list_del(list);
2084 isapnp_free_card(pci_bus_b(list));
2086 #endif
2089 EXPORT_SYMBOL(isapnp_cards);
2090 EXPORT_SYMBOL(isapnp_devices);
2091 EXPORT_SYMBOL(isapnp_present);
2092 EXPORT_SYMBOL(isapnp_cfg_begin);
2093 EXPORT_SYMBOL(isapnp_cfg_end);
2094 EXPORT_SYMBOL(isapnp_read_byte);
2095 EXPORT_SYMBOL(isapnp_read_word);
2096 EXPORT_SYMBOL(isapnp_read_dword);
2097 EXPORT_SYMBOL(isapnp_write_byte);
2098 EXPORT_SYMBOL(isapnp_write_word);
2099 EXPORT_SYMBOL(isapnp_write_dword);
2100 EXPORT_SYMBOL(isapnp_wake);
2101 EXPORT_SYMBOL(isapnp_device);
2102 EXPORT_SYMBOL(isapnp_activate);
2103 EXPORT_SYMBOL(isapnp_deactivate);
2104 EXPORT_SYMBOL(isapnp_find_card);
2105 EXPORT_SYMBOL(isapnp_find_dev);
2106 EXPORT_SYMBOL(isapnp_probe_cards);
2107 EXPORT_SYMBOL(isapnp_resource_change);
2109 int __init isapnp_init(void)
2111 int cards;
2112 struct pci_bus *card;
2114 if (isapnp_disable) {
2115 isapnp_detected = 0;
2116 printk("isapnp: ISA Plug & Play support disabled\n");
2117 return 0;
2119 #ifdef ISAPNP_REGION_OK
2120 pidxr_res=request_region(_PIDXR, 1, "isapnp index");
2121 if(!pidxr_res) {
2122 printk("isapnp: Index Register 0x%x already used\n", _PIDXR);
2123 return -EBUSY;
2125 #endif
2126 pnpwrp_res=request_region(_PNPWRP, 1, "isapnp write");
2127 if(!pnpwrp_res) {
2128 printk("isapnp: Write Data Register 0x%x already used\n", _PNPWRP);
2129 return -EBUSY;
2133 * Print a message. The existing ISAPnP code is hanging machines
2134 * so let the user know where.
2137 printk("isapnp: Scanning for Pnp cards...\n");
2138 if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {
2139 isapnp_rdp |= 3;
2140 isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read");
2141 if(!isapnp_rdp_res) {
2142 printk("isapnp: Read Data Register 0x%x already used\n", isapnp_rdp);
2143 return -EBUSY;
2145 isapnp_set_rdp();
2147 isapnp_detected = 1;
2148 if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) {
2149 cards = isapnp_isolate();
2150 if (cards < 0 ||
2151 (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {
2152 isapnp_free_all_resources();
2153 isapnp_detected = 0;
2154 printk("isapnp: No Plug & Play device found\n");
2155 return 0;
2157 isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read");
2159 isapnp_build_device_list();
2160 cards = 0;
2162 isapnp_for_each_card(card) {
2163 cards++;
2164 if (isapnp_verbose) {
2165 struct list_head *devlist;
2166 printk( "isapnp: Card '%s'\n", card->name[0]?card->name:"Unknown");
2167 if (isapnp_verbose < 2)
2168 continue;
2169 for (devlist = card->devices.next; devlist != &card->devices; devlist = devlist->next) {
2170 struct pci_dev *dev = pci_dev_b(devlist);
2171 printk("isapnp: Device '%s'\n", dev->name[0]?card->name:"Unknown");
2175 if (cards) {
2176 printk("isapnp: %i Plug & Play card%s detected total\n", cards, cards>1?"s":"");
2177 } else {
2178 printk("isapnp: No Plug & Play card found\n");
2180 #ifdef CONFIG_PROC_FS
2181 isapnp_proc_init();
2182 #endif
2183 return 0;
2186 #ifdef MODULE
2188 int init_module(void)
2190 return isapnp_init();
2193 void cleanup_module(void)
2195 if (isapnp_detected)
2196 isapnp_free_all_resources();
2199 #endif