import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / drivers / pnp / isapnp.c
1 /*
2  *  ISA Plug & Play support
3  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4  *
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  *  Changelog:
21  *  2000-01-01  Added quirks handling for buggy hardware
22  *              Peter Denison <peterd@pnd-pc.demon.co.uk>
23  *  2000-06-14  Added isapnp_probe_devs() and isapnp_activate_dev()
24  *              Christoph Hellwig <hch@infradead.org>
25  *  2001-06-03  Added release_region calls to correspond with
26  *              request_region calls when a failure occurs.  Also
27  *              added KERN_* constants to printk() calls.
28  *  2001-11-07  Added isapnp_{,un}register_driver calls along the lines
29  *              of the pci driver interface
30  *              Kai Germaschewski <kai.germaschewski@gmx.de>
31  *  2002-06-06  Made the use of dma channel 0 configurable 
32  *              Gerald Teschl <gerald.teschl@univie.ac.at>
33  */
34
35 #include <linux/config.h>
36 #include <linux/version.h>
37 #include <linux/module.h>
38 #include <linux/kernel.h>
39 #include <linux/errno.h>
40 #include <linux/ioport.h>
41 #include <linux/string.h>
42 #include <linux/slab.h>
43 #include <linux/delay.h>
44 #include <asm/io.h>
45 #include <asm/dma.h>
46 #include <asm/irq.h>
47 #include <linux/pci.h>
48 #include <linux/init.h>
49 #include <linux/isapnp.h>
50
51 LIST_HEAD(isapnp_cards);
52 LIST_HEAD(isapnp_devices);
53
54 #if 0
55 #define ISAPNP_REGION_OK
56 #endif
57 #if 0
58 #define ISAPNP_DEBUG
59 #endif
60
61 int isapnp_disable;                     /* Disable ISA PnP */
62 int isapnp_rdp;                         /* Read Data Port */
63 int isapnp_reset = 1;                   /* reset all PnP cards (deactivate) */
64 int isapnp_allow_dma0 = -1;             /* allow dma 0 during auto activation: -1=off (:default), 0=off (set by user), 1=on */
65 int isapnp_skip_pci_scan;               /* skip PCI resource scanning */
66 int isapnp_verbose = 1;                 /* verbose mode */
67 int isapnp_reserve_irq[16] = { [0 ... 15] = -1 };       /* reserve (don't use) some IRQ */
68 int isapnp_reserve_dma[8] = { [0 ... 7] = -1 };         /* reserve (don't use) some DMA */
69 int isapnp_reserve_io[16] = { [0 ... 15] = -1 };        /* reserve (don't use) some I/O region */
70 int isapnp_reserve_mem[16] = { [0 ... 15] = -1 };       /* reserve (don't use) some memory region */
71
72 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
73 MODULE_DESCRIPTION("Generic ISA Plug & Play support");
74 MODULE_PARM(isapnp_disable, "i");
75 MODULE_PARM_DESC(isapnp_disable, "ISA Plug & Play disable");
76 MODULE_PARM(isapnp_rdp, "i");
77 MODULE_PARM_DESC(isapnp_rdp, "ISA Plug & Play read data port");
78 MODULE_PARM(isapnp_reset, "i");
79 MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
80 MODULE_PARM(isapnp_allow_dma0, "i");
81 MODULE_PARM_DESC(isapnp_allow_dma0, "Allow dma value 0 during auto activation");
82 MODULE_PARM(isapnp_skip_pci_scan, "i");
83 MODULE_PARM_DESC(isapnp_skip_pci_scan, "ISA Plug & Play skip PCI resource scanning");
84 MODULE_PARM(isapnp_verbose, "i");
85 MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
86 MODULE_PARM(isapnp_reserve_irq, "1-16i");
87 MODULE_PARM_DESC(isapnp_reserve_irq, "ISA Plug & Play - reserve IRQ line(s)");
88 MODULE_PARM(isapnp_reserve_dma, "1-8i");
89 MODULE_PARM_DESC(isapnp_reserve_dma, "ISA Plug & Play - reserve DMA channel(s)");
90 MODULE_PARM(isapnp_reserve_io, "1-16i");
91 MODULE_PARM_DESC(isapnp_reserve_io, "ISA Plug & Play - reserve I/O region(s) - port,size");
92 MODULE_PARM(isapnp_reserve_mem, "1-16i");
93 MODULE_PARM_DESC(isapnp_reserve_mem, "ISA Plug & Play - reserve memory region(s) - address,size");
94 MODULE_LICENSE("GPL");
95
96 #define _PIDXR          0x279
97 #define _PNPWRP         0xa79
98
99 /* short tags */
100 #define _STAG_PNPVERNO          0x01
101 #define _STAG_LOGDEVID          0x02
102 #define _STAG_COMPATDEVID       0x03
103 #define _STAG_IRQ               0x04
104 #define _STAG_DMA               0x05
105 #define _STAG_STARTDEP          0x06
106 #define _STAG_ENDDEP            0x07
107 #define _STAG_IOPORT            0x08
108 #define _STAG_FIXEDIO           0x09
109 #define _STAG_VENDOR            0x0e
110 #define _STAG_END               0x0f
111 /* long tags */
112 #define _LTAG_MEMRANGE          0x81
113 #define _LTAG_ANSISTR           0x82
114 #define _LTAG_UNICODESTR        0x83
115 #define _LTAG_VENDOR            0x84
116 #define _LTAG_MEM32RANGE        0x85
117 #define _LTAG_FIXEDMEM32RANGE   0x86
118
119 static unsigned char isapnp_checksum_value;
120 static DECLARE_MUTEX(isapnp_cfg_mutex);
121 static int isapnp_detected;
122
123 /* some prototypes */
124
125 static int isapnp_config_prepare(struct pci_dev *dev);
126 static int isapnp_config_activate(struct pci_dev *dev);
127 static int isapnp_config_deactivate(struct pci_dev *dev);
128
129 static inline void write_data(unsigned char x)
130 {
131         outb(x, _PNPWRP);
132 }
133
134 static inline void write_address(unsigned char x)
135 {
136         outb(x, _PIDXR);
137         udelay(20);
138 }
139
140 static inline unsigned char read_data(void)
141 {
142         unsigned char val = inb(isapnp_rdp);
143         return val;
144 }
145
146 unsigned char isapnp_read_byte(unsigned char idx)
147 {
148         write_address(idx);
149         return read_data();
150 }
151
152 unsigned short isapnp_read_word(unsigned char idx)
153 {
154         unsigned short val;
155
156         val = isapnp_read_byte(idx);
157         val = (val << 8) + isapnp_read_byte(idx+1);
158         return val;
159 }
160
161 unsigned int isapnp_read_dword(unsigned char idx)
162 {
163         unsigned int val;
164
165         val = isapnp_read_byte(idx);
166         val = (val << 8) + isapnp_read_byte(idx+1);
167         val = (val << 8) + isapnp_read_byte(idx+2);
168         val = (val << 8) + isapnp_read_byte(idx+3);
169         return val;
170 }
171
172 void isapnp_write_byte(unsigned char idx, unsigned char val)
173 {
174         write_address(idx);
175         write_data(val);
176 }
177
178 void isapnp_write_word(unsigned char idx, unsigned short val)
179 {
180         isapnp_write_byte(idx, val >> 8);
181         isapnp_write_byte(idx+1, val);
182 }
183
184 void isapnp_write_dword(unsigned char idx, unsigned int val)
185 {
186         isapnp_write_byte(idx, val >> 24);
187         isapnp_write_byte(idx+1, val >> 16);
188         isapnp_write_byte(idx+2, val >> 8);
189         isapnp_write_byte(idx+3, val);
190 }
191
192 void *isapnp_alloc(long size)
193 {
194         void *result;
195
196         result = kmalloc(size, GFP_KERNEL);
197         if (!result)
198                 return NULL;
199         memset(result, 0, size);
200         return result;
201 }
202
203 static void isapnp_key(void)
204 {
205         unsigned char code = 0x6a, msb;
206         int i;
207
208         mdelay(1);
209         write_address(0x00);
210         write_address(0x00);
211
212         write_address(code);
213
214         for (i = 1; i < 32; i++) {
215                 msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7;
216                 code = (code >> 1) | msb;
217                 write_address(code);
218         }
219 }
220
221 /* place all pnp cards in wait-for-key state */
222 static void isapnp_wait(void)
223 {
224         isapnp_write_byte(0x02, 0x02);
225 }
226
227 void isapnp_wake(unsigned char csn)
228 {
229         isapnp_write_byte(0x03, csn);
230 }
231
232 void isapnp_device(unsigned char logdev)
233 {
234         isapnp_write_byte(0x07, logdev);
235 }
236
237 void isapnp_activate(unsigned char logdev)
238 {
239         isapnp_device(logdev);
240         isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 1);
241         udelay(250);
242 }
243
244 void isapnp_deactivate(unsigned char logdev)
245 {
246         isapnp_device(logdev);
247         isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 0);
248         udelay(500);
249 }
250
251 static void __init isapnp_peek(unsigned char *data, int bytes)
252 {
253         int i, j;
254         unsigned char d=0;
255
256         for (i = 1; i <= bytes; i++) {
257                 for (j = 0; j < 20; j++) {
258                         d = isapnp_read_byte(0x05);
259                         if (d & 1)
260                                 break;
261                         udelay(100);
262                 }
263                 if (!(d & 1)) {
264                         if (data != NULL)
265                                 *data++ = 0xff;
266                         continue;
267                 }
268                 d = isapnp_read_byte(0x04);     /* PRESDI */
269                 isapnp_checksum_value += d;
270                 if (data != NULL)
271                         *data++ = d;
272         }
273 }
274
275 #define RDP_STEP        32      /* minimum is 4 */
276
277 static int isapnp_next_rdp(void)
278 {
279         int rdp = isapnp_rdp;
280         while (rdp <= 0x3ff) {
281                 /*
282                  *      We cannot use NE2000 probe spaces for ISAPnP or we
283                  *      will lock up machines.
284                  */
285                 if ((rdp < 0x280 || rdp >  0x380) && !check_region(rdp, 1)) 
286                 {
287                         isapnp_rdp = rdp;
288                         return 0;
289                 }
290                 rdp += RDP_STEP;
291         }
292         return -1;
293 }
294
295 /* Set read port address */
296 static inline void isapnp_set_rdp(void)
297 {
298         isapnp_write_byte(0x00, isapnp_rdp >> 2);
299         udelay(100);
300 }
301
302 /*
303  *      Perform an isolation. The port selection code now tries to avoid
304  *      "dangerous to read" ports.
305  */
306
307 static int __init isapnp_isolate_rdp_select(void)
308 {
309         isapnp_wait();
310         isapnp_key();
311
312         /* Control: reset CSN and conditionally everything else too */
313         isapnp_write_byte(0x02, isapnp_reset ? 0x05 : 0x04);
314         mdelay(2);
315
316         isapnp_wait();
317         isapnp_key();
318         isapnp_wake(0x00);
319
320         if (isapnp_next_rdp() < 0) {
321                 isapnp_wait();
322                 return -1;
323         }
324
325         isapnp_set_rdp();
326         udelay(1000);
327         write_address(0x01);
328         udelay(1000);
329         return 0;
330 }
331
332 /*
333  *  Isolate (assign uniqued CSN) to all ISA PnP devices.
334  */
335
336 static int __init isapnp_isolate(void)
337 {
338         unsigned char checksum = 0x6a;
339         unsigned char chksum = 0x00;
340         unsigned char bit = 0x00;
341         int data;
342         int csn = 0;
343         int i;
344         int iteration = 1;
345
346         isapnp_rdp = 0x213;
347         if (isapnp_isolate_rdp_select() < 0)
348                 return -1;
349
350         while (1) {
351                 for (i = 1; i <= 64; i++) {
352                         data = read_data() << 8;
353                         udelay(250);
354                         data = data | read_data();
355                         udelay(250);
356                         if (data == 0x55aa)
357                                 bit = 0x01;
358                         checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1);
359                         bit = 0x00;
360                 }
361                 for (i = 65; i <= 72; i++) {
362                         data = read_data() << 8;
363                         udelay(250);
364                         data = data | read_data();
365                         udelay(250);
366                         if (data == 0x55aa)
367                                 chksum |= (1 << (i - 65));
368                 }
369                 if (checksum != 0x00 && checksum == chksum) {
370                         csn++;
371
372                         isapnp_write_byte(0x06, csn);
373                         udelay(250);
374                         iteration++;
375                         isapnp_wake(0x00);
376                         isapnp_set_rdp();
377                         udelay(1000);
378                         write_address(0x01);
379                         udelay(1000);
380                         goto __next;
381                 }
382                 if (iteration == 1) {
383                         isapnp_rdp += RDP_STEP;
384                         if (isapnp_isolate_rdp_select() < 0)
385                                 return -1;
386                 } else if (iteration > 1) {
387                         break;
388                 }
389               __next:
390                 checksum = 0x6a;
391                 chksum = 0x00;
392                 bit = 0x00;
393         }
394         isapnp_wait();
395         return csn;
396 }
397
398 /*
399  *  Read one tag from stream.
400  */
401
402 static int __init isapnp_read_tag(unsigned char *type, unsigned short *size)
403 {
404         unsigned char tag, tmp[2];
405
406         isapnp_peek(&tag, 1);
407         if (tag == 0)                           /* invalid tag */
408                 return -1;
409         if (tag & 0x80) {       /* large item */
410                 *type = tag;
411                 isapnp_peek(tmp, 2);
412                 *size = (tmp[1] << 8) | tmp[0];
413         } else {
414                 *type = (tag >> 3) & 0x0f;
415                 *size = tag & 0x07;
416         }
417 #if 0
418         printk(KERN_DEBUG "tag = 0x%x, type = 0x%x, size = %i\n", tag, *type, *size);
419 #endif
420         if (type == 0)                          /* wrong type */
421                 return -1;
422         if (*type == 0xff && *size == 0xffff)   /* probably invalid data */
423                 return -1;
424         return 0;
425 }
426
427 /*
428  *  Skip specified number of bytes from stream.
429  */
430  
431 static void __init isapnp_skip_bytes(int count)
432 {
433         isapnp_peek(NULL, count);
434 }
435
436 /*
437  *  Parse logical device tag.
438  */
439
440 static struct pci_dev * __init isapnp_parse_device(struct pci_bus *card, int size, int number)
441 {
442         unsigned char tmp[6];
443         struct pci_dev *dev;
444
445         isapnp_peek(tmp, size);
446         dev = isapnp_alloc(sizeof(struct pci_dev));
447         if (!dev)
448                 return NULL;
449         dev->dma_mask = 0x00ffffff;
450         dev->devfn = number;
451         dev->vendor = (tmp[1] << 8) | tmp[0];
452         dev->device = (tmp[3] << 8) | tmp[2];
453         dev->regs = tmp[4];
454         dev->bus = card;
455         if (size > 5)
456                 dev->regs |= tmp[5] << 8;
457         dev->prepare = isapnp_config_prepare;
458         dev->activate = isapnp_config_activate;
459         dev->deactivate = isapnp_config_deactivate;
460         return dev;
461 }
462
463 /*
464  *  Build new resources structure
465  */
466
467 static struct isapnp_resources * __init isapnp_build_resources(struct pci_dev *dev, int dependent)
468 {
469         struct isapnp_resources *res, *ptr, *ptra;
470         
471         res = isapnp_alloc(sizeof(struct isapnp_resources));
472         if (!res)
473                 return NULL;
474         res->dev = dev;
475         ptr = (struct isapnp_resources *)dev->sysdata;
476         while (ptr && ptr->next)
477                 ptr = ptr->next;
478         if (ptr && ptr->dependent && dependent) { /* add to another list */
479                 ptra = ptr->alt;
480                 while (ptra && ptra->alt)
481                         ptra = ptra->alt;
482                 if (!ptra)
483                         ptr->alt = res;
484                 else
485                         ptra->alt = res;
486         } else {
487                 if (!ptr)
488                         dev->sysdata = res;
489                 else
490                         ptr->next = res;
491         }
492         if (dependent) {
493                 res->priority = dependent & 0xff;
494                 if (res->priority > ISAPNP_RES_PRIORITY_FUNCTIONAL)
495                         res->priority = ISAPNP_RES_PRIORITY_INVALID;
496                 res->dependent = 1;
497         } else {
498                 res->priority = ISAPNP_RES_PRIORITY_PREFERRED;
499                 res->dependent = 0;
500         }
501         return res;
502 }
503
504 /*
505  *  Add IRQ resource to resources list.
506  */
507
508 static void __init isapnp_add_irq_resource(struct pci_dev *dev,
509                                                struct isapnp_resources **res,
510                                                int dependent, int size)
511 {
512         unsigned char tmp[3];
513         struct isapnp_irq *irq, *ptr;
514
515         isapnp_peek(tmp, size);
516         irq = isapnp_alloc(sizeof(struct isapnp_irq));
517         if (!irq)
518                 return;
519         if (*res == NULL) {
520                 *res = isapnp_build_resources(dev, dependent);
521                 if (*res == NULL) {
522                         kfree(irq);
523                         return;
524                 }
525         }
526         irq->map = (tmp[1] << 8) | tmp[0];
527         if (size > 2)
528                 irq->flags = tmp[2];
529         else
530                 irq->flags = IORESOURCE_IRQ_HIGHEDGE;
531         irq->res = *res;
532         ptr = (*res)->irq;
533         while (ptr && ptr->next)
534                 ptr = ptr->next;
535         if (ptr)
536                 ptr->next = irq;
537         else
538                 (*res)->irq = irq;
539 #ifdef CONFIG_PCI
540         {
541                 int i;
542
543                 for (i=0; i<16; i++)
544                         if (irq->map & (1<<i))
545                                 pcibios_penalize_isa_irq(i);
546         }
547 #endif
548 }
549
550 /*
551  *  Add DMA resource to resources list.
552  */
553
554 static void __init isapnp_add_dma_resource(struct pci_dev *dev,
555                                                struct isapnp_resources **res,
556                                                int dependent, int size)
557 {
558         unsigned char tmp[2];
559         struct isapnp_dma *dma, *ptr;
560
561         isapnp_peek(tmp, size);
562         dma = isapnp_alloc(sizeof(struct isapnp_dma));
563         if (!dma)
564                 return;
565         if (*res == NULL) {
566                 *res = isapnp_build_resources(dev, dependent);
567                 if (*res == NULL) {
568                         kfree(dma);
569                         return;
570                 }
571         }
572         dma->map = tmp[0];
573         dma->flags = tmp[1];
574         dma->res = *res;
575         ptr = (*res)->dma;
576         while (ptr && ptr->next)
577                 ptr = ptr->next;
578         if (ptr)
579                 ptr->next = dma;
580         else
581                 (*res)->dma = dma;
582 }
583
584 /*
585  *  Add port resource to resources list.
586  */
587
588 static void __init isapnp_add_port_resource(struct pci_dev *dev,
589                                                 struct isapnp_resources **res,
590                                                 int dependent, int size)
591 {
592         unsigned char tmp[7];
593         struct isapnp_port *port, *ptr;
594
595         isapnp_peek(tmp, size);
596         port = isapnp_alloc(sizeof(struct isapnp_port));
597         if (!port)
598                 return;
599         if (*res == NULL) {
600                 *res = isapnp_build_resources(dev, dependent);
601                 if (*res == NULL) {
602                         kfree(port);
603                         return;
604                 }
605         }
606         port->min = (tmp[2] << 8) | tmp[1];
607         port->max = (tmp[4] << 8) | tmp[3];
608         port->align = tmp[5];
609         port->size = tmp[6];
610         port->flags = tmp[0] ? ISAPNP_PORT_FLAG_16BITADDR : 0;
611         port->res = *res;
612         ptr = (*res)->port;
613         while (ptr && ptr->next)
614                 ptr = ptr->next;
615         if (ptr)
616                 ptr->next = port;
617         else
618                 (*res)->port = port;
619 }
620
621 /*
622  *  Add fixed port resource to resources list.
623  */
624
625 static void __init isapnp_add_fixed_port_resource(struct pci_dev *dev,
626                                                       struct isapnp_resources **res,
627                                                       int dependent, int size)
628 {
629         unsigned char tmp[3];
630         struct isapnp_port *port, *ptr;
631
632         isapnp_peek(tmp, size);
633         port = isapnp_alloc(sizeof(struct isapnp_port));
634         if (!port)
635                 return;
636         if (*res == NULL) {
637                 *res = isapnp_build_resources(dev, dependent);
638                 if (*res == NULL) {
639                         kfree(port);
640                         return;
641                 }
642         }
643         port->min = port->max = (tmp[1] << 8) | tmp[0];
644         port->size = tmp[2];
645         port->align = 0;
646         port->flags = ISAPNP_PORT_FLAG_FIXED;
647         port->res = *res;
648         ptr = (*res)->port;
649         while (ptr && ptr->next)
650                 ptr = ptr->next;
651         if (ptr)
652                 ptr->next = port;
653         else
654                 (*res)->port = port;
655 }
656
657 /*
658  *  Add memory resource to resources list.
659  */
660
661 static void __init isapnp_add_mem_resource(struct pci_dev *dev,
662                                                struct isapnp_resources **res,
663                                                int dependent, int size)
664 {
665         unsigned char tmp[9];
666         struct isapnp_mem *mem, *ptr;
667
668         isapnp_peek(tmp, size);
669         mem = isapnp_alloc(sizeof(struct isapnp_mem));
670         if (!mem)
671                 return;
672         if (*res == NULL) {
673                 *res = isapnp_build_resources(dev, dependent);
674                 if (*res == NULL) {
675                         kfree(mem);
676                         return;
677                 }
678         }
679         mem->min = ((tmp[2] << 8) | tmp[1]) << 8;
680         mem->max = ((tmp[4] << 8) | tmp[3]) << 8;
681         mem->align = (tmp[6] << 8) | tmp[5];
682         mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
683         mem->flags = tmp[0];
684         mem->res = *res;
685         ptr = (*res)->mem;
686         while (ptr && ptr->next)
687                 ptr = ptr->next;
688         if (ptr)
689                 ptr->next = mem;
690         else
691                 (*res)->mem = mem;
692 }
693
694 /*
695  *  Add 32-bit memory resource to resources list.
696  */
697
698 static void __init isapnp_add_mem32_resource(struct pci_dev *dev,
699                                                  struct isapnp_resources **res,
700                                                  int dependent, int size)
701 {
702         unsigned char tmp[17];
703         struct isapnp_mem32 *mem32, *ptr;
704
705         isapnp_peek(tmp, size);
706         mem32 = isapnp_alloc(sizeof(struct isapnp_mem32));
707         if (!mem32)
708                 return;
709         if (*res == NULL) {
710                 *res = isapnp_build_resources(dev, dependent);
711                 if (*res == NULL) {
712                         kfree(mem32);
713                         return;
714                 }
715         }
716         memcpy(mem32->data, tmp, 17);
717         mem32->res = *res;
718         ptr = (*res)->mem32;
719         while (ptr && ptr->next)
720                 ptr = ptr->next;
721         if (ptr)
722                 ptr->next = mem32;
723         else
724                 (*res)->mem32 = mem32;
725 }
726
727 /*
728  *  Add 32-bit fixed memory resource to resources list.
729  */
730
731 static void __init isapnp_add_fixed_mem32_resource(struct pci_dev *dev,
732                                                        struct isapnp_resources **res,
733                                                        int dependent, int size)
734 {
735         unsigned char tmp[17];
736         struct isapnp_mem32 *mem32, *ptr;
737
738         isapnp_peek(tmp, size);
739         mem32 = isapnp_alloc(sizeof(struct isapnp_mem32));
740         if (!mem32)
741                 return;
742         if (*res == NULL) {
743                 *res = isapnp_build_resources(dev, dependent);
744                 if (*res == NULL) {
745                         kfree(mem32);
746                         return;
747                 }
748         }
749         memcpy(mem32->data, tmp, 17);
750         mem32->res = *res;
751         ptr = (*res)->mem32;
752         while (ptr && ptr->next)
753                 ptr = ptr->next;
754         if (ptr)
755                 ptr->next = mem32;
756         else
757                 (*res)->mem32 = mem32;
758 }
759
760 /*
761  *  Parse card name for ISA PnP device.
762  */ 
763  
764 static void __init 
765 isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
766 {
767         if (name[0] == '\0') {
768                 unsigned short size1 = *size >= name_max ? (name_max - 1) : *size;
769                 isapnp_peek(name, size1);
770                 name[size1] = '\0';
771                 *size -= size1;
772                 
773                 /* clean whitespace from end of string */
774                 while (size1 > 0  &&  name[--size1] == ' ') 
775                         name[size1] = '\0';
776         }       
777 }
778
779 /*
780  *  Parse resource map for logical device.
781  */
782
783 static int __init isapnp_create_device(struct pci_bus *card,
784                                            unsigned short size)
785 {
786         int number = 0, skip = 0, dependent = 0, compat = 0;
787         unsigned char type, tmp[17];
788         struct pci_dev *dev;
789         struct isapnp_resources *res = NULL;
790         
791         if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
792                 return 1;
793         list_add(&dev->bus_list, &card->devices);
794         list_add_tail(&dev->global_list, &isapnp_devices);
795         while (1) {
796                 if (isapnp_read_tag(&type, &size)<0)
797                         return 1;
798                 if (skip && type != _STAG_LOGDEVID && type != _STAG_END)
799                         goto __skip;
800                 switch (type) {
801                 case _STAG_LOGDEVID:
802                         if (size >= 5 && size <= 6) {
803                                 isapnp_config_prepare(dev);
804                                 if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
805                                         return 1;
806                                 list_add_tail(&dev->bus_list, &card->devices);
807                                 list_add_tail(&dev->global_list, &isapnp_devices);
808                                 size = 0;
809                                 skip = 0;
810                         } else {
811                                 skip = 1;
812                         }
813                         res = NULL;
814                         dependent = 0;
815                         compat = 0;
816                         break;
817                 case _STAG_COMPATDEVID:
818                         if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {
819                                 isapnp_peek(tmp, 4);
820                                 dev->vendor_compatible[compat] = (tmp[1] << 8) | tmp[0];
821                                 dev->device_compatible[compat] = (tmp[3] << 8) | tmp[2];
822                                 compat++;
823                                 size = 0;
824                         }
825                         break;
826                 case _STAG_IRQ:
827                         if (size < 2 || size > 3)
828                                 goto __skip;
829                         isapnp_add_irq_resource(dev, &res, dependent, size);
830                         size = 0;
831                         break;
832                 case _STAG_DMA:
833                         if (size != 2)
834                                 goto __skip;
835                         isapnp_add_dma_resource(dev, &res, dependent, size);
836                         size = 0;
837                         break;
838                 case _STAG_STARTDEP:
839                         if (size > 1)
840                                 goto __skip;
841                         res = NULL;
842                         dependent = 0x100 | ISAPNP_RES_PRIORITY_ACCEPTABLE;
843                         if (size > 0) {
844                                 isapnp_peek(tmp, size);
845                                 dependent = 0x100 | tmp[0];
846                                 size = 0;
847                         }
848                         break;
849                 case _STAG_ENDDEP:
850                         if (size != 0)
851                                 goto __skip;
852                         res = NULL;
853                         dependent = 0;
854                         break;
855                 case _STAG_IOPORT:
856                         if (size != 7)
857                                 goto __skip;
858                         isapnp_add_port_resource(dev, &res, dependent, size);
859                         size = 0;
860                         break;
861                 case _STAG_FIXEDIO:
862                         if (size != 3)
863                                 goto __skip;
864                         isapnp_add_fixed_port_resource(dev, &res, dependent, size);
865                         size = 0;
866                         break;
867                 case _STAG_VENDOR:
868                         break;
869                 case _LTAG_MEMRANGE:
870                         if (size != 9)
871                                 goto __skip;
872                         isapnp_add_mem_resource(dev, &res, dependent, size);
873                         size = 0;
874                         break;
875                 case _LTAG_ANSISTR:
876                         isapnp_parse_name(dev->name, sizeof(dev->name), &size);
877                         break;
878                 case _LTAG_UNICODESTR:
879                         /* silently ignore */
880                         /* who use unicode for hardware identification? */
881                         break;
882                 case _LTAG_VENDOR:
883                         break;
884                 case _LTAG_MEM32RANGE:
885                         if (size != 17)
886                                 goto __skip;
887                         isapnp_add_mem32_resource(dev, &res, dependent, size);
888                         size = 0;
889                         break;
890                 case _LTAG_FIXEDMEM32RANGE:
891                         if (size != 17)
892                                 goto __skip;
893                         isapnp_add_fixed_mem32_resource(dev, &res, dependent, size);
894                         size = 0;
895                         break;
896                 case _STAG_END:
897                         if (size > 0)
898                                 isapnp_skip_bytes(size);
899                         isapnp_config_prepare(dev);
900                         return 1;
901                 default:
902                         printk(KERN_ERR "isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n", type, dev->devfn, card->number);
903                 }
904               __skip:
905                 if (size > 0)
906                         isapnp_skip_bytes(size);
907         }
908         isapnp_config_prepare(dev);
909         return 0;
910 }
911
912 /*
913  *  Parse resource map for ISA PnP card.
914  */
915  
916 static void __init isapnp_parse_resource_map(struct pci_bus *card)
917 {
918         unsigned char type, tmp[17];
919         unsigned short size;
920         
921         while (1) {
922                 if (isapnp_read_tag(&type, &size)<0)
923                         return;
924                 switch (type) {
925                 case _STAG_PNPVERNO:
926                         if (size != 2)
927                                 goto __skip;
928                         isapnp_peek(tmp, 2);
929                         card->pnpver = tmp[0];
930                         card->productver = tmp[1];
931                         size = 0;
932                         break;
933                 case _STAG_LOGDEVID:
934                         if (size >= 5 && size <= 6) {
935                                 if (isapnp_create_device(card, size)==1)
936                                         return;
937                                 size = 0;
938                         }
939                         break;
940                 case _STAG_VENDOR:
941                         break;
942                 case _LTAG_ANSISTR:
943                         isapnp_parse_name(card->name, sizeof(card->name), &size);
944                         break;
945                 case _LTAG_UNICODESTR:
946                         /* silently ignore */
947                         /* who use unicode for hardware identification? */
948                         break;
949                 case _LTAG_VENDOR:
950                         break;
951                 case _STAG_END:
952                         if (size > 0)
953                                 isapnp_skip_bytes(size);
954                         return;
955                 default:
956                         printk(KERN_ERR "isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n", type, card->number);
957                 }
958               __skip:
959                 if (size > 0)
960                         isapnp_skip_bytes(size);
961         }
962 }
963
964 /*
965  *  Compute ISA PnP checksum for first eight bytes.
966  */
967
968 static unsigned char __init isapnp_checksum(unsigned char *data)
969 {
970         int i, j;
971         unsigned char checksum = 0x6a, bit, b;
972         
973         for (i = 0; i < 8; i++) {
974                 b = data[i];
975                 for (j = 0; j < 8; j++) {
976                         bit = 0;
977                         if (b & (1 << j))
978                                 bit = 1;
979                         checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1);
980                 }
981         }
982         return checksum;
983 }
984
985 /*
986  *  Build device list for all present ISA PnP devices.
987  */
988
989 static int __init isapnp_build_device_list(void)
990 {
991         int csn;
992         unsigned char header[9], checksum;
993         struct pci_bus *card;
994         struct pci_dev *dev;
995
996         isapnp_wait();
997         isapnp_key();
998         for (csn = 1; csn <= 10; csn++) {
999                 isapnp_wake(csn);
1000                 isapnp_peek(header, 9);
1001                 checksum = isapnp_checksum(header);
1002 #if 0
1003                 printk(KERN_DEBUG "vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1004                         header[0], header[1], header[2], header[3],
1005                         header[4], header[5], header[6], header[7], header[8]);
1006                 printk(KERN_DEBUG "checksum = 0x%x\n", checksum);
1007 #endif
1008                 /* Don't be strict on the checksum, here !
1009                    e.g. 'SCM SwapBox Plug and Play' has header[8]==0 (should be: b7)*/
1010                 if (header[8] == 0)
1011                         ;
1012                 else if (checksum == 0x00 || checksum != header[8])     /* not valid CSN */
1013                         continue;
1014                 if ((card = isapnp_alloc(sizeof(struct pci_bus))) == NULL)
1015                         continue;
1016
1017                 card->number = csn;
1018                 card->vendor = (header[1] << 8) | header[0];
1019                 card->device = (header[3] << 8) | header[2];
1020                 card->serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4];
1021                 isapnp_checksum_value = 0x00;
1022                 INIT_LIST_HEAD(&card->children);
1023                 INIT_LIST_HEAD(&card->devices);
1024                 isapnp_parse_resource_map(card);
1025                 if (isapnp_checksum_value != 0x00)
1026                         printk(KERN_ERR "isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value);
1027                 card->checksum = isapnp_checksum_value;
1028
1029                 list_add_tail(&card->node, &isapnp_cards);
1030         }
1031         isapnp_for_each_dev(dev) {
1032                 isapnp_fixup_device(dev);
1033         }
1034         return 0;
1035 }
1036
1037 /*
1038  *  Basic configuration routines.
1039  */
1040
1041 int isapnp_present(void)
1042 {
1043         return !list_empty(&isapnp_devices);
1044 }
1045
1046 int isapnp_cfg_begin(int csn, int logdev)
1047 {
1048         if (csn < 1 || csn > 10 || logdev > 10)
1049                 return -EINVAL;
1050         MOD_INC_USE_COUNT;
1051         down(&isapnp_cfg_mutex);
1052         isapnp_wait();
1053         isapnp_key();
1054         isapnp_wake(csn);
1055 #if 1   /* to avoid malfunction when the isapnptools package is used */
1056         isapnp_set_rdp();
1057         udelay(1000);   /* delay 1000us */
1058         write_address(0x01);
1059         udelay(1000);   /* delay 1000us */
1060 #endif
1061         if (logdev >= 0)
1062                 isapnp_device(logdev);
1063         return 0;
1064 }
1065
1066 int isapnp_cfg_end(void)
1067 {
1068         isapnp_wait();
1069         up(&isapnp_cfg_mutex);
1070         MOD_DEC_USE_COUNT;
1071         return 0;
1072 }
1073
1074 /*
1075  *  Resource manager.
1076  */
1077
1078 static struct isapnp_port *isapnp_find_port(struct pci_dev *dev, int index)
1079 {
1080         struct isapnp_resources *res;
1081         struct isapnp_port *port;
1082         
1083         if (!dev || index < 0 || index > 7)
1084                 return NULL;
1085         for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1086                 for (port = res->port; port; port = port->next) {
1087                         if (!index)
1088                                 return port;
1089                         index--;
1090                 }
1091         }
1092         return NULL;
1093 }
1094
1095 struct isapnp_irq *isapnp_find_irq(struct pci_dev *dev, int index)
1096 {
1097         struct isapnp_resources *res, *resa;
1098         struct isapnp_irq *irq;
1099         int index1, index2, index3;
1100         
1101         if (!dev || index < 0 || index > 7)
1102                 return NULL;
1103         for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1104                 index3 = 0;
1105                 for (resa = res; resa; resa = resa->alt) {
1106                         index1 = index;
1107                         index2 = 0;
1108                         for (irq = resa->irq; irq; irq = irq->next) {
1109                                 if (!index1)
1110                                         return irq;
1111                                 index1--;
1112                                 index2++;
1113                         }
1114                         if (index3 < index2)
1115                                 index3 = index2;
1116                 }
1117                 index -= index3;
1118         }
1119         return NULL;
1120 }
1121
1122 struct isapnp_dma *isapnp_find_dma(struct pci_dev *dev, int index)
1123 {
1124         struct isapnp_resources *res;
1125         struct isapnp_dma *dma;
1126         
1127         if (!dev || index < 0 || index > 7)
1128                 return NULL;
1129         for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1130                 for (dma = res->dma; dma; dma = dma->next) {
1131                         if (!index)
1132                                 return dma;
1133                         index--;
1134                 }
1135         }
1136         return NULL;
1137 }
1138
1139 struct isapnp_mem *isapnp_find_mem(struct pci_dev *dev, int index)
1140 {
1141         struct isapnp_resources *res;
1142         struct isapnp_mem *mem;
1143         
1144         if (!dev || index < 0 || index > 7)
1145                 return NULL;
1146         for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1147                 for (mem = res->mem; mem; mem = mem->next) {
1148                         if (!index)
1149                                 return mem;
1150                         index--;
1151                 }
1152         }
1153         return NULL;
1154 }
1155
1156 struct isapnp_mem32 *isapnp_find_mem32(struct pci_dev *dev, int index)
1157 {
1158         struct isapnp_resources *res;
1159         struct isapnp_mem32 *mem32;
1160         
1161         if (!dev || index < 0 || index > 7)
1162                 return NULL;
1163         for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1164                 for (mem32 = res->mem32; mem32; mem32 = mem32->next) {
1165                         if (!index)
1166                                 return mem32;
1167                         index--;
1168                 }
1169         }
1170         return NULL;
1171 }
1172
1173 /*
1174  *  Device manager.
1175  */
1176
1177 struct pci_bus *isapnp_find_card(unsigned short vendor,
1178                                  unsigned short device,
1179                                  struct pci_bus *from)
1180 {
1181         struct list_head *list;
1182
1183         list = isapnp_cards.next;
1184         if (from)
1185                 list = from->node.next;
1186
1187         while (list != &isapnp_cards) {
1188                 struct pci_bus *card = pci_bus_b(list);
1189                 if (card->vendor == vendor && card->device == device)
1190                         return card;
1191                 list = list->next;
1192         }
1193         return NULL;
1194 }
1195
1196 struct pci_dev *isapnp_find_dev(struct pci_bus *card,
1197                                 unsigned short vendor,
1198                                 unsigned short function,
1199                                 struct pci_dev *from)
1200 {
1201         if (card == NULL) {     /* look for a logical device from all cards */
1202                 struct list_head *list;
1203
1204                 list = isapnp_devices.next;
1205                 if (from)
1206                         list = from->global_list.next;
1207
1208                 while (list != &isapnp_devices) {
1209                         int idx;
1210                         struct pci_dev *dev = pci_dev_g(list);
1211
1212                         if (dev->vendor == vendor && dev->device == function)
1213                                 return dev;
1214                         for (idx = 0; idx < DEVICE_COUNT_COMPATIBLE; idx++)
1215                                 if (dev->vendor_compatible[idx] == vendor &&
1216                                     dev->device_compatible[idx] == function)
1217                                         return dev;
1218                         list = list->next;
1219                 }
1220         } else {
1221                 struct list_head *list;
1222
1223                 list = card->devices.next;
1224                 if (from) {
1225                         list = from->bus_list.next;
1226                         if (from->bus != card)  /* something is wrong */
1227                                 return NULL;
1228                 }
1229                 while (list != &card->devices) {
1230                         int idx;
1231                         struct pci_dev *dev = pci_dev_b(list);
1232
1233                         if (dev->vendor == vendor && dev->device == function)
1234                                 return dev;
1235                         for (idx = 0; idx < DEVICE_COUNT_COMPATIBLE; idx++)
1236                                 if (dev->vendor_compatible[idx] == vendor &&
1237                                     dev->device_compatible[idx] == function)
1238                                         return dev;
1239                         list = list->next;
1240                 }
1241         }
1242         return NULL;
1243 }
1244
1245 static const struct isapnp_card_id *
1246 isapnp_match_card(const struct isapnp_card_id *ids, struct pci_bus *card)
1247 {
1248         int idx;
1249
1250         while (ids->card_vendor || ids->card_device) {
1251                 if ((ids->card_vendor == ISAPNP_ANY_ID || ids->card_vendor == card->vendor) &&
1252                     (ids->card_device == ISAPNP_ANY_ID || ids->card_device == card->device)) {
1253                         for (idx = 0; idx < ISAPNP_CARD_DEVS; idx++) {
1254                                 if (ids->devs[idx].vendor == 0 &&
1255                                     ids->devs[idx].function == 0)
1256                                         return ids;
1257                                 if (isapnp_find_dev(card,
1258                                                     ids->devs[idx].vendor,
1259                                                     ids->devs[idx].function,
1260                                                     NULL) == NULL)
1261                                         goto __next;
1262                         }
1263                         return ids;
1264                 }
1265               __next:
1266                 ids++;
1267         }
1268         return NULL;
1269 }
1270
1271 int isapnp_probe_cards(const struct isapnp_card_id *ids,
1272                        int (*probe)(struct pci_bus *_card,
1273                                     const struct isapnp_card_id *_id))
1274 {
1275         struct pci_bus *card;   
1276         const struct isapnp_card_id *id;
1277         int count = 0;
1278
1279         if (ids == NULL || probe == NULL)
1280                 return -EINVAL;
1281         isapnp_for_each_card(card) {
1282                 id = isapnp_match_card(ids, card);
1283                 if (id != NULL && probe(card, id) >= 0)
1284                         count++;
1285         }
1286         return count;
1287 }
1288
1289 static const struct isapnp_device_id *
1290 isapnp_match_dev(const struct isapnp_device_id *ids, struct pci_dev *dev)
1291 {
1292         while (ids->card_vendor || ids->card_device) {
1293                 if ((ids->card_vendor == ISAPNP_ANY_ID || ids->card_vendor == dev->bus->vendor) &&
1294                     (ids->card_device == ISAPNP_ANY_ID || ids->card_device == dev->bus->device) &&
1295                     (ids->vendor == ISAPNP_ANY_ID || ids->vendor == dev->vendor) &&
1296                     (ids->function == ISAPNP_ANY_ID || ids->function == dev->device))
1297                         return ids;
1298                 ids++;
1299         }
1300         return NULL;
1301 }
1302
1303 int isapnp_probe_devs(const struct isapnp_device_id *ids,
1304                       int (*probe)(struct pci_dev *dev,
1305                                    const struct isapnp_device_id *id))
1306 {
1307         
1308         struct pci_dev *dev;
1309         const struct isapnp_device_id *id;
1310         int count = 0;
1311
1312         if (ids == NULL || probe == NULL)
1313                 return -EINVAL;
1314         isapnp_for_each_dev(dev) {
1315                 id = isapnp_match_dev(ids, dev);
1316                 if (id != NULL && probe(dev, id) >= 0)
1317                         count++;
1318         }
1319         return count;
1320 }
1321
1322 int isapnp_activate_dev(struct pci_dev *dev, const char *name)
1323 {
1324         int err;
1325         
1326         /* Device already active? Let's use it and inform the caller */
1327         if (dev->active)
1328                 return -EBUSY;
1329
1330         if ((err = dev->activate(dev)) < 0) {
1331                 printk(KERN_ERR "isapnp: config of %s failed (out of resources?)[%d]\n", name, err);
1332                 dev->deactivate(dev);
1333                 return err;
1334         }
1335
1336         return 0;
1337 }
1338
1339 static unsigned int isapnp_dma_resource_flags(struct isapnp_dma *dma)
1340 {
1341         return dma->flags | IORESOURCE_DMA | IORESOURCE_AUTO;
1342 }
1343
1344 static unsigned int isapnp_mem_resource_flags(struct isapnp_mem *mem)
1345 {
1346         unsigned int result;
1347
1348         result = mem->flags | IORESOURCE_MEM | IORESOURCE_AUTO;
1349         if (!(mem->flags & IORESOURCE_MEM_WRITEABLE))
1350                 result |= IORESOURCE_READONLY;
1351         if (mem->flags & IORESOURCE_MEM_CACHEABLE)
1352                 result |= IORESOURCE_CACHEABLE;
1353         if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
1354                 result |= IORESOURCE_RANGELENGTH;
1355         if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
1356                 result |= IORESOURCE_SHADOWABLE;
1357         return result;
1358 }
1359
1360 static unsigned int isapnp_irq_resource_flags(struct isapnp_irq *irq)
1361 {
1362         return irq->flags | IORESOURCE_IRQ | IORESOURCE_AUTO;
1363 }
1364
1365 static unsigned int isapnp_port_resource_flags(struct isapnp_port *port)
1366 {
1367         return port->flags | IORESOURCE_IO | IORESOURCE_AUTO;
1368 }
1369
1370 static int isapnp_config_prepare(struct pci_dev *dev)
1371 {
1372         struct isapnp_resources *res, *resa;
1373         struct isapnp_port *port;
1374         struct isapnp_irq *irq;
1375         struct isapnp_dma *dma;
1376         struct isapnp_mem *mem;
1377         int port_count, port_count1;
1378         int irq_count, irq_count1;
1379         int dma_count, dma_count1;
1380         int mem_count, mem_count1;
1381         int idx;
1382
1383         if (dev == NULL)
1384                 return -EINVAL;
1385         if (dev->active || dev->ro)
1386                 return -EBUSY;
1387         for (idx = 0; idx < DEVICE_COUNT_IRQ; idx++) {
1388                 dev->irq_resource[idx].name = NULL;
1389                 dev->irq_resource[idx].start = 0;
1390                 dev->irq_resource[idx].end = 0;
1391                 dev->irq_resource[idx].flags = 0;
1392         }
1393         for (idx = 0; idx < DEVICE_COUNT_DMA; idx++) {
1394                 dev->dma_resource[idx].name = NULL;
1395                 dev->dma_resource[idx].start = 0;
1396                 dev->dma_resource[idx].end = 0;
1397                 dev->dma_resource[idx].flags = 0;
1398         }
1399         for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) {
1400                 dev->resource[idx].name = NULL;
1401                 dev->resource[idx].start = 0;
1402                 dev->resource[idx].end = 0;
1403                 dev->resource[idx].flags = 0;
1404         }
1405         port_count = irq_count = dma_count = mem_count = 0;
1406         for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1407                 port_count1 = irq_count1 = dma_count1 = mem_count1 = 0;
1408                 for (resa = res; resa; resa = resa->alt) {
1409                         for (port = resa->port, idx = 0; port; port = port->next, idx++) {
1410                                 if (dev->resource[port_count + idx].flags == 0) {
1411                                         dev->resource[port_count + idx].flags = isapnp_port_resource_flags(port);
1412                                         dev->resource[port_count + idx].end = port->size;
1413                                 }
1414                         }
1415                         if (port_count1 < idx)
1416                                 port_count1 = idx;
1417                         for (irq = resa->irq, idx = 0; irq; irq = irq->next, idx++) {
1418                                 int count = irq_count + idx;
1419                                 if (count < DEVICE_COUNT_IRQ) {
1420                                         if (dev->irq_resource[count].flags == 0) {
1421                                                 dev->irq_resource[count].flags = isapnp_irq_resource_flags(irq);
1422                                         }
1423                                 }
1424                                 
1425                         }
1426                         if (irq_count1 < idx)
1427                                 irq_count1 = idx;
1428                         for (dma = resa->dma, idx = 0; dma; dma = dma->next, idx++)
1429                                 if (dev->dma_resource[idx].flags == 0) {
1430                                         dev->dma_resource[idx].flags = isapnp_dma_resource_flags(dma);
1431                                 }
1432                         if (dma_count1 < idx)
1433                                 dma_count1 = idx;
1434                         for (mem = resa->mem, idx = 0; mem; mem = mem->next, idx++)
1435                                 if (dev->resource[mem_count + idx + 8].flags == 0) {
1436                                         dev->resource[mem_count + idx + 8].flags = isapnp_mem_resource_flags(mem);
1437                                 }
1438                         if (mem_count1 < idx)
1439                                 mem_count1 = idx;
1440                 }
1441                 port_count += port_count1;
1442                 irq_count += irq_count1;
1443                 dma_count += dma_count1;
1444                 mem_count += mem_count1;
1445         }
1446         return 0;
1447 }
1448
1449 struct isapnp_cfgtmp {
1450         struct isapnp_port *port[8];
1451         struct isapnp_irq *irq[2];
1452         struct isapnp_dma *dma[2];
1453         struct isapnp_mem *mem[4];
1454         struct pci_dev *request;
1455         struct pci_dev result;
1456 };
1457
1458 static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg,
1459                                      struct isapnp_resources *from,
1460                                      struct isapnp_resources *to)
1461 {
1462         int tmp, tmp1;
1463         struct isapnp_port *port;
1464         struct isapnp_irq *irq;
1465         struct isapnp_dma *dma;
1466         struct isapnp_mem *mem;
1467
1468         if (!cfg)
1469                 return -EINVAL;
1470         /* process port settings */
1471         for (tmp = 0; tmp < 8; tmp++) {
1472                 if (!(cfg->request->resource[tmp].flags & IORESOURCE_AUTO))
1473                         continue;               /* don't touch */
1474                 port = cfg->port[tmp];
1475                 if (!port) {
1476                         cfg->port[tmp] = port = isapnp_find_port(cfg->request, tmp);
1477                         if (!port)
1478                                 return -EINVAL;
1479                 }
1480                 if (from && port->res == from) {
1481                         while (port->res != to) {
1482                                 if (!port->res->alt)
1483                                         return -EINVAL;
1484                                 port = port->res->alt->port;
1485                                 for (tmp1 = tmp; tmp1 > 0 && port; tmp1--)
1486                                         port = port->next;
1487                                 cfg->port[tmp] = port;
1488                                 if (!port)
1489                                         return -ENOENT;
1490                                 cfg->result.resource[tmp].flags = isapnp_port_resource_flags(port);
1491                         }
1492                 }
1493         }
1494         /* process irq settings */
1495         for (tmp = 0; tmp < 2; tmp++) {
1496                 if (!(cfg->request->irq_resource[tmp].flags & IORESOURCE_AUTO))
1497                         continue;               /* don't touch */
1498                 irq = cfg->irq[tmp];
1499                 if (!irq) {
1500                         cfg->irq[tmp] = irq = isapnp_find_irq(cfg->request, tmp);
1501                         if (!irq)
1502                                 return -EINVAL;
1503                 }
1504                 if (from && irq->res == from) {
1505                         while (irq->res != to) {
1506                                 if (!irq->res->alt)
1507                                         return -EINVAL;
1508                                 irq = irq->res->alt->irq;
1509                                 for (tmp1 = tmp; tmp1 > 0 && irq; tmp1--)
1510                                         irq = irq->next;
1511                                 cfg->irq[tmp] = irq;
1512                                 if (!irq)
1513                                         return -ENOENT;
1514                                 cfg->result.irq_resource[tmp].flags = isapnp_irq_resource_flags(irq);
1515                         }
1516                 }
1517         }
1518         /* process dma settings */
1519         for (tmp = 0; tmp < 2; tmp++) {
1520                 if (!(cfg->request->dma_resource[tmp].flags & IORESOURCE_AUTO))
1521                         continue;               /* don't touch */
1522                 dma = cfg->dma[tmp];
1523                 if (!dma) {
1524                         cfg->dma[tmp] = dma = isapnp_find_dma(cfg->request, tmp);
1525                         if (!dma)
1526                                 return -EINVAL;
1527                 }
1528                 if (from && dma->res == from) {
1529                         while (dma->res != to) {
1530                                 if (!dma->res->alt)
1531                                         return -EINVAL;
1532                                 dma = dma->res->alt->dma;
1533                                 for (tmp1 = tmp; tmp1 > 0 && dma; tmp1--)
1534                                         dma = dma->next;
1535                                 cfg->dma[tmp] = dma;
1536                                 if (!dma)
1537                                         return -ENOENT;
1538                                 cfg->result.dma_resource[tmp].flags = isapnp_dma_resource_flags(dma);
1539                         }
1540                 }
1541         }
1542         /* process memory settings */
1543         for (tmp = 0; tmp < 4; tmp++) {
1544                 if (!(cfg->request->resource[tmp + 8].flags & IORESOURCE_AUTO))
1545                         continue;               /* don't touch */
1546                 mem = cfg->mem[tmp];
1547                 if (!mem) {
1548                         cfg->mem[tmp] = mem = isapnp_find_mem(cfg->request, tmp);
1549                         if (!mem)
1550                                 return -EINVAL;
1551                 }
1552                 if (from && mem->res == from) {
1553                         while (mem->res != to) {
1554                                 if (!mem->res->alt)
1555                                         return -EINVAL;
1556                                 mem = mem->res->alt->mem;
1557                                 for (tmp1 = tmp; tmp1 > 0 && mem; tmp1--)
1558                                         mem = mem->next;
1559                                 cfg->mem[tmp] = mem;
1560                                 if (!mem)
1561                                         return -ENOENT;
1562                                 cfg->result.resource[tmp + 8].flags = isapnp_mem_resource_flags(mem);
1563                         }
1564                 }
1565         }
1566         return 0;
1567 }
1568
1569 static int isapnp_check_port(struct isapnp_cfgtmp *cfg, int port, int size, int idx)
1570 {
1571         int i, tmp, rport, rsize;
1572         struct isapnp_port *xport;
1573         struct pci_dev *dev;
1574
1575         if (check_region(port, size))
1576                 return 1;
1577         for (i = 0; i < 8; i++) {
1578                 rport = isapnp_reserve_io[i << 1];
1579                 rsize = isapnp_reserve_io[(i << 1) + 1];
1580                 if (port >= rport && port < rport + rsize)
1581                         return 1;
1582                 if (port + size > rport && port + size < (rport + rsize) - 1)
1583                         return 1;
1584         }
1585
1586         isapnp_for_each_dev(dev) {
1587                 if (dev->active) {
1588                         for (tmp = 0; tmp < 8; tmp++) {
1589                                 if (dev->resource[tmp].flags) {
1590                                         rport = dev->resource[tmp].start;
1591                                         rsize = (dev->resource[tmp].end - rport) + 1;
1592                                         if (port >= rport && port < rport + rsize)
1593                                                 return 1;
1594                                         if (port + size > rport && port + size < (rport + rsize) - 1)
1595                                                 return 1;
1596                                 }
1597                         }
1598                 }
1599         }
1600         for (i = 0; i < 8; i++) {
1601                 unsigned int flags;
1602                 if (i == idx)
1603                         continue;
1604                 flags = cfg->request->resource[i].flags;
1605                 if (!flags)
1606                         continue;
1607                 tmp = cfg->request->resource[i].start;
1608                 if (flags & IORESOURCE_AUTO) {          /* auto */
1609                         xport = cfg->port[i];
1610                         if (!xport)
1611                                 return 1;
1612                         if (cfg->result.resource[i].flags & IORESOURCE_AUTO)
1613                                 continue;
1614                         tmp = cfg->result.resource[i].start;
1615                         if (tmp + xport->size >= port && tmp <= port + xport->size)
1616                                 return 1;
1617                         continue;
1618                 }
1619                 if (port == tmp)
1620                         return 1;
1621                 xport = isapnp_find_port(cfg->request, i);
1622                 if (!xport)
1623                         return 1;
1624                 if (tmp + xport->size >= port && tmp <= port + xport->size)
1625                         return 1;
1626         }
1627         return 0;
1628 }
1629
1630 static int isapnp_valid_port(struct isapnp_cfgtmp *cfg, int idx)
1631 {
1632         int err;
1633         unsigned long *value1, *value2;
1634         struct isapnp_port *port;
1635
1636         if (!cfg || idx < 0 || idx > 7)
1637                 return -EINVAL;
1638         if (!(cfg->result.resource[idx].flags & IORESOURCE_AUTO)) /* don't touch */
1639                 return 0;
1640       __again:
1641         port = cfg->port[idx];
1642         if (!port)
1643                 return -EINVAL;
1644         value1 = &cfg->result.resource[idx].start;
1645         value2 = &cfg->result.resource[idx].end;
1646         if (cfg->result.resource[idx].flags & IORESOURCE_AUTO) {
1647                 cfg->result.resource[idx].flags &= ~IORESOURCE_AUTO;
1648                 *value1 = port->min;
1649                 *value2 = port->min + port->size - 1;
1650                 if (!isapnp_check_port(cfg, *value1, port->size, idx))
1651                         return 0;
1652         }
1653         do {
1654                 *value1 += port->align;
1655                 *value2 = *value1 + port->size - 1;
1656                 if (*value1 > port->max || !port->align) {
1657                         if (port->res && port->res->alt) {
1658                                 if ((err = isapnp_alternative_switch(cfg, port->res, port->res->alt))<0)
1659                                         return err;
1660                                 goto __again;
1661                         }
1662                         return -ENOENT;
1663                 }
1664         } while (isapnp_check_port(cfg, *value1, port->size, idx));
1665         return 0;
1666 }
1667
1668 static void isapnp_test_handler(int irq, void *dev_id, struct pt_regs *regs)
1669 {
1670 }
1671
1672 static int isapnp_check_interrupt(struct isapnp_cfgtmp *cfg, int irq, int idx)
1673 {
1674         int i;
1675         struct pci_dev *dev;
1676
1677         if (irq < 0 || irq > 15)
1678                 return 1;
1679         for (i = 0; i < 16; i++) {
1680                 if (isapnp_reserve_irq[i] == irq)
1681                         return 1;
1682         }
1683         isapnp_for_each_dev(dev) {
1684                 if (dev->active) {
1685                         if ((dev->irq_resource[0].flags && dev->irq_resource[0].start == irq) ||
1686                             (dev->irq_resource[1].flags && dev->irq_resource[1].start == irq))
1687                                 return 1;
1688                 }
1689         }
1690 #ifdef CONFIG_PCI
1691         if (!isapnp_skip_pci_scan) {
1692                 pci_for_each_dev(dev) {
1693                         if (dev->irq == irq)
1694                                 return 1;
1695                 }
1696         }
1697 #endif
1698         if (request_irq(irq, isapnp_test_handler, SA_INTERRUPT, "isapnp", NULL))
1699                 return 1;
1700         free_irq(irq, NULL);
1701         for (i = 0; i < DEVICE_COUNT_IRQ; i++) {
1702                 if (i == idx)
1703                         continue;
1704                 if (!cfg->result.irq_resource[i].flags)
1705                         continue;
1706                 if (cfg->result.irq_resource[i].flags & IORESOURCE_AUTO)
1707                         continue;
1708                 if (cfg->result.irq_resource[i].start == irq)
1709                         return 1;
1710         }
1711         return 0;
1712 }
1713
1714 static int isapnp_valid_irq(struct isapnp_cfgtmp *cfg, int idx)
1715 {
1716         /* IRQ priority: this table is good for i386 */
1717         static unsigned short xtab[16] = {
1718                 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
1719         };
1720         int err, i;
1721         unsigned long *value1, *value2;
1722         struct isapnp_irq *irq;
1723
1724         if (!cfg || idx < 0 || idx > 1)
1725                 return -EINVAL;
1726         if (!(cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO))
1727                 return 0;
1728       __again:
1729         irq = cfg->irq[idx];
1730         if (!irq)
1731                 return -EINVAL;
1732         value1 = &cfg->result.irq_resource[idx].start;
1733         value2 = &cfg->result.irq_resource[idx].end;
1734         if (cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO) {
1735                 for (i = 0; i < 16 && !(irq->map & (1<<xtab[i])); i++);
1736                 if (i >= 16)
1737                         return -ENOENT;
1738                 cfg->result.irq_resource[idx].flags &= ~IORESOURCE_AUTO;
1739                 if (!isapnp_check_interrupt(cfg, *value1 = *value2 = xtab[i], idx))
1740                         return 0;
1741         }
1742         do {
1743                 for (i = 0; i < 16 && xtab[i] != *value1; i++);
1744                 for (i++; i < 16 && !(irq->map & (1<<xtab[i])); i++);
1745                 if (i >= 16) {
1746                         if (irq->res && irq->res->alt) {
1747                                 if ((err = isapnp_alternative_switch(cfg, irq->res, irq->res->alt))<0)
1748                                         return err;
1749                                 goto __again;
1750                         }
1751                         return -ENOENT;
1752                 } else {
1753                         *value1 = *value2 = xtab[i];
1754                 }
1755         } while (isapnp_check_interrupt(cfg, *value1, idx));
1756         return 0;
1757 }
1758
1759 static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx)
1760 {
1761         int i, mindma =1;
1762         struct pci_dev *dev;
1763
1764         /* Some machines allow DMA 0, but others don't. In fact on some 
1765            boxes DMA 0 is the memory refresh. Play safe */
1766         if (isapnp_allow_dma0 == 1)
1767                 mindma = 0;
1768         if (dma < mindma || dma == 4 || dma > 7)
1769                 return 1;
1770         for (i = 0; i < 8; i++) {
1771                 if (isapnp_reserve_dma[i] == dma)
1772                         return 1;
1773         }
1774         isapnp_for_each_dev(dev) {
1775                 if (dev->active) {
1776                         if ((dev->dma_resource[0].flags && dev->dma_resource[0].start == dma) ||
1777                             (dev->dma_resource[1].flags && dev->dma_resource[1].start == dma))
1778                                 return 1;
1779                 }
1780         }
1781         if (request_dma(dma, "isapnp"))
1782                 return 1;
1783         free_dma(dma);
1784         for (i = 0; i < 2; i++) {
1785                 if (i == idx)
1786                         continue;
1787                 if (!cfg->result.dma_resource[i].flags ||
1788                     (cfg->result.dma_resource[i].flags & IORESOURCE_AUTO))
1789                         continue;
1790                 if (cfg->result.dma_resource[i].start == dma)
1791                         return 1;
1792         }
1793         return 0;
1794 }
1795
1796 static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx)
1797 {
1798         /* DMA priority: this table is good for i386 */
1799         static unsigned short xtab[16] = {
1800                 1, 3, 5, 6, 7, 0, 2, 4
1801         };
1802         int err, i;
1803         unsigned long *value1, *value2;
1804         struct isapnp_dma *dma;
1805
1806         if (!cfg || idx < 0 || idx > 1)
1807                 return -EINVAL;
1808         if (!(cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO))   /* don't touch */
1809                 return 0;
1810       __again:
1811         dma = cfg->dma[idx];
1812         if (!dma)
1813                 return -EINVAL;
1814         value1 = &cfg->result.dma_resource[idx].start;
1815         value2 = &cfg->result.dma_resource[idx].end;
1816         if (cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO) {
1817                 for (i = 0; i < 8 && !(dma->map & (1<<xtab[i])); i++);
1818                 if (i >= 8)
1819                         return -ENOENT;
1820                 cfg->result.dma_resource[idx].flags &= ~IORESOURCE_AUTO;
1821                 if (!isapnp_check_dma(cfg, *value1 = *value2 = xtab[i], idx))
1822                         return 0;
1823         }
1824         do {
1825                 for (i = 0; i < 8 && xtab[i] != *value1; i++);
1826                 for (i++; i < 8 && !(dma->map & (1<<xtab[i])); i++);
1827                 if (i >= 8) {
1828                         if (dma->res && dma->res->alt) {
1829                                 if ((err = isapnp_alternative_switch(cfg, dma->res, dma->res->alt))<0)
1830                                         return err;
1831                                 goto __again;
1832                         }
1833                         return -ENOENT;
1834                 } else {
1835                         *value1 = *value2 = xtab[i];
1836                 }
1837         } while (isapnp_check_dma(cfg, *value1, idx));
1838         return 0;
1839 }
1840
1841 static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsigned int size, int idx)
1842 {
1843         int i, tmp;
1844         unsigned int raddr, rsize;
1845         struct isapnp_mem *xmem;
1846         struct pci_dev *dev;
1847
1848         for (i = 0; i < 8; i++) {
1849                 raddr = (unsigned int)isapnp_reserve_mem[i << 1];
1850                 rsize = (unsigned int)isapnp_reserve_mem[(i << 1) + 1];
1851                 if (addr >= raddr && addr < raddr + rsize)
1852                         return 1;
1853                 if (addr + size > raddr && addr + size < (raddr + rsize) - 1)
1854                         return 1;
1855                 if (__check_region(&iomem_resource, addr, size))
1856                         return 1;
1857         }
1858         isapnp_for_each_dev(dev) {
1859                 if (dev->active) {
1860                         for (tmp = 0; tmp < 4; tmp++) {
1861                                 if (dev->resource[tmp].flags) {
1862                                         raddr = dev->resource[tmp + 8].start;
1863                                         rsize = (dev->resource[tmp + 8].end - raddr) + 1;
1864                                         if (addr >= raddr && addr < raddr + rsize)
1865                                                 return 1;
1866                                         if (addr + size > raddr && addr + size < (raddr + rsize) - 1)
1867                                                 return 1;
1868                                 }
1869                         }
1870                 }
1871         }
1872         for (i = 0; i < 4; i++) {
1873                 unsigned int flags = cfg->request->resource[i + 8].flags;
1874                 if (i == idx)
1875                         continue;
1876                 if (!flags)
1877                         continue;
1878                 tmp = cfg->result.resource[i + 8].start;
1879                 if (flags & IORESOURCE_AUTO) {          /* auto */
1880                         xmem = cfg->mem[i];
1881                         if (!xmem)
1882                                 return 1;
1883                         if (cfg->result.resource[i + 8].flags & IORESOURCE_AUTO)
1884                                 continue;
1885                         if (tmp + xmem->size >= addr && tmp <= addr + xmem->size)
1886                                 return 1;
1887                         continue;
1888                 }
1889                 if (addr == tmp)
1890                         return 1;
1891                 xmem = isapnp_find_mem(cfg->request, i);
1892                 if (!xmem)
1893                         return 1;
1894                 if (tmp + xmem->size >= addr && tmp <= addr + xmem->size)
1895                         return 1;
1896         }
1897         return 0;
1898 }
1899
1900 static int isapnp_valid_mem(struct isapnp_cfgtmp *cfg, int idx)
1901 {
1902         int err;
1903         unsigned long *value1, *value2;
1904         struct isapnp_mem *mem;
1905
1906         if (!cfg || idx < 0 || idx > 3)
1907                 return -EINVAL;
1908         if (!(cfg->result.resource[idx + 8].flags & IORESOURCE_AUTO)) /* don't touch */
1909                 return 0;
1910       __again:
1911         mem = cfg->mem[idx];
1912         if (!mem)
1913                 return -EINVAL;
1914         value1 = &cfg->result.resource[idx + 8].start;
1915         value2 = &cfg->result.resource[idx + 8].end;
1916         if (cfg->result.resource[idx + 8].flags & IORESOURCE_AUTO) {
1917                 cfg->result.resource[idx + 8].flags &= ~IORESOURCE_AUTO;
1918                 *value1 = mem->min;
1919                 *value2 = mem->min + mem->size - 1;
1920                 if (!isapnp_check_mem(cfg, *value1, mem->size, idx))
1921                         return 0;
1922         }
1923         do {
1924                 *value1 += mem->align;
1925                 *value2 = *value1 + mem->size - 1;
1926                 if (*value1 > mem->max || !mem->align) {
1927                         if (mem->res && mem->res->alt) {
1928                                 if ((err = isapnp_alternative_switch(cfg, mem->res, mem->res->alt))<0)
1929                                         return err;
1930                                 goto __again;
1931                         }
1932                         return -ENOENT;
1933                 }
1934         } while (isapnp_check_mem(cfg, *value1, mem->size, idx));
1935         return 0;
1936 }
1937
1938 static int isapnp_check_valid(struct isapnp_cfgtmp *cfg)
1939 {
1940         int tmp;
1941         
1942         for (tmp = 0; tmp < 8; tmp++)
1943                 if (cfg->result.resource[tmp].flags & IORESOURCE_AUTO)
1944                         return -EAGAIN;
1945         for (tmp = 0; tmp < 2; tmp++)
1946                 if (cfg->result.irq_resource[tmp].flags & IORESOURCE_AUTO)
1947                         return -EAGAIN;
1948         for (tmp = 0; tmp < 2; tmp++)
1949                 if (cfg->result.dma_resource[tmp].flags & IORESOURCE_AUTO)
1950                         return -EAGAIN;
1951         for (tmp = 0; tmp < 4; tmp++)
1952                 if (cfg->result.resource[tmp + 8].flags & IORESOURCE_AUTO)
1953                         return -EAGAIN;
1954         return 0;
1955 }
1956
1957 static int isapnp_config_activate(struct pci_dev *dev)
1958 {
1959         struct isapnp_cfgtmp cfg;
1960         int tmp, fauto, err;
1961         
1962         if (!dev)
1963                 return -EINVAL;
1964         if (dev->active)
1965                 return -EBUSY;
1966         memset(&cfg, 0, sizeof(cfg));
1967         cfg.request = dev;
1968         memcpy(&cfg.result, dev, sizeof(struct pci_dev));
1969         /* check if all values are set, otherwise try auto-configuration */
1970         for (tmp = fauto = 0; !fauto && tmp < 8; tmp++) {
1971                 if (dev->resource[tmp].flags & IORESOURCE_AUTO)
1972                         fauto++;
1973         }
1974         for (tmp = 0; !fauto && tmp < 2; tmp++) {
1975                 if (dev->irq_resource[tmp].flags & IORESOURCE_AUTO)
1976                         fauto++;
1977         }
1978         for (tmp = 0; !fauto && tmp < 2; tmp++) {
1979                 if (dev->dma_resource[tmp].flags & IORESOURCE_AUTO)
1980                         fauto++;
1981         }
1982         for (tmp = 0; !fauto && tmp < 4; tmp++) {
1983                 if (dev->resource[tmp + 8].flags & IORESOURCE_AUTO)
1984                         fauto++;
1985         }
1986         if (!fauto)
1987                 goto __skip_auto;
1988         /* set variables to initial values */
1989         if ((err = isapnp_alternative_switch(&cfg, NULL, NULL))<0)
1990                 return err;
1991         /* find first valid configuration */
1992         fauto = 0;
1993         do {
1994                 for (tmp = 0; tmp < 8 && cfg.result.resource[tmp].flags; tmp++)
1995                         if ((err = isapnp_valid_port(&cfg, tmp))<0)
1996                                 return err;
1997                 for (tmp = 0; tmp < 2 && cfg.result.irq_resource[tmp].flags; tmp++)
1998                         if ((err = isapnp_valid_irq(&cfg, tmp))<0)
1999                                 return err;
2000                 for (tmp = 0; tmp < 2 && cfg.result.dma_resource[tmp].flags; tmp++)
2001                         if ((err = isapnp_valid_dma(&cfg, tmp))<0)
2002                                 return err;
2003                 for (tmp = 0; tmp < 4 && cfg.result.resource[tmp + 8].flags; tmp++)
2004                         if ((err = isapnp_valid_mem(&cfg, tmp))<0)
2005                                 return err;
2006         } while (isapnp_check_valid(&cfg)<0 && fauto++ < 20);
2007         if (fauto >= 20)
2008                 return -EAGAIN;
2009       __skip_auto:
2010         /* we have valid configuration, try configure hardware */
2011         isapnp_cfg_begin(dev->bus->number, dev->devfn);
2012         dev->active = 1;
2013         dev->irq_resource[0] = cfg.result.irq_resource[0];
2014         dev->irq_resource[1] = cfg.result.irq_resource[1];
2015         dev->dma_resource[0] = cfg.result.dma_resource[0];
2016         dev->dma_resource[1] = cfg.result.dma_resource[1];
2017         for (tmp = 0; tmp < 12; tmp++) {
2018                 dev->resource[tmp] = cfg.result.resource[tmp];
2019         }       
2020         for (tmp = 0; tmp < 8 && dev->resource[tmp].flags; tmp++)
2021                 isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), dev->resource[tmp].start);
2022         for (tmp = 0; tmp < 2 && dev->irq_resource[tmp].flags; tmp++) {
2023                 int irq = dev->irq_resource[tmp].start;
2024                 if (irq == 2)
2025                         irq = 9;
2026                 isapnp_write_byte(ISAPNP_CFG_IRQ+(tmp<<1), irq);
2027         }
2028         for (tmp = 0; tmp < 2 && dev->dma_resource[tmp].flags; tmp++)
2029                 isapnp_write_byte(ISAPNP_CFG_DMA+tmp, dev->dma_resource[tmp].start);
2030         for (tmp = 0; tmp < 4 && dev->resource[tmp+8].flags; tmp++)
2031                 isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (dev->resource[tmp + 8].start >> 8) & 0xffff);
2032         isapnp_activate(dev->devfn);
2033         isapnp_cfg_end();
2034         return 0;
2035 }
2036
2037 static int isapnp_config_deactivate(struct pci_dev *dev)
2038 {
2039         if (!dev || !dev->active)
2040                 return -EINVAL;
2041         isapnp_cfg_begin(dev->bus->number, dev->devfn);
2042         isapnp_deactivate(dev->devfn);
2043         dev->active = 0;
2044         isapnp_cfg_end();
2045         return 0;
2046 }
2047
2048 void isapnp_resource_change(struct resource *resource,
2049                             unsigned long start,
2050                             unsigned long size)
2051 {
2052         if (resource == NULL)
2053                 return;
2054         resource->flags &= ~IORESOURCE_AUTO;
2055         resource->start = start;
2056         resource->end = start + size - 1;
2057 }
2058
2059 /*
2060  *  Inititialization.
2061  */
2062
2063 #ifdef MODULE
2064
2065 static void isapnp_free_port(struct isapnp_port *port)
2066 {
2067         struct isapnp_port *next;
2068
2069         while (port) {
2070                 next = port->next;
2071                 kfree(port);
2072                 port = next;
2073         }
2074 }
2075
2076 static void isapnp_free_irq(struct isapnp_irq *irq)
2077 {
2078         struct isapnp_irq *next;
2079
2080         while (irq) {
2081                 next = irq->next;
2082                 kfree(irq);
2083                 irq = next;
2084         }
2085 }
2086
2087 static void isapnp_free_dma(struct isapnp_dma *dma)
2088 {
2089         struct isapnp_dma *next;
2090
2091         while (dma) {
2092                 next = dma->next;
2093                 kfree(dma);
2094                 dma = next;
2095         }
2096 }
2097
2098 static void isapnp_free_mem(struct isapnp_mem *mem)
2099 {
2100         struct isapnp_mem *next;
2101
2102         while (mem) {
2103                 next = mem->next;
2104                 kfree(mem);
2105                 mem = next;
2106         }
2107 }
2108
2109 static void isapnp_free_mem32(struct isapnp_mem32 *mem32)
2110 {
2111         struct isapnp_mem32 *next;
2112
2113         while (mem32) {
2114                 next = mem32->next;
2115                 kfree(mem32);
2116                 mem32 = next;
2117         }
2118 }
2119
2120 static void isapnp_free_resources(struct isapnp_resources *resources, int alt)
2121 {
2122         struct isapnp_resources *next;
2123
2124         while (resources) {
2125                 next = alt ? resources->alt : resources->next;
2126                 isapnp_free_port(resources->port);
2127                 isapnp_free_irq(resources->irq);
2128                 isapnp_free_dma(resources->dma);
2129                 isapnp_free_mem(resources->mem);
2130                 isapnp_free_mem32(resources->mem32);
2131                 if (!alt && resources->alt)
2132                         isapnp_free_resources(resources->alt, 1);
2133                 kfree(resources);
2134                 resources = next;
2135         }
2136 }
2137
2138 static void isapnp_free_card(struct pci_bus *card)
2139 {
2140         while (!list_empty(&card->devices)) {
2141                 struct list_head *list = card->devices.next;
2142                 struct pci_dev *dev = pci_dev_b(list);
2143                 list_del(list);
2144                 isapnp_free_resources((struct isapnp_resources *)dev->sysdata, 0);
2145                 kfree(dev);
2146         }
2147         kfree(card);
2148 }
2149
2150 static void isapnp_free_all_resources(void)
2151 {
2152 #ifdef ISAPNP_REGION_OK
2153         release_region(_PIDXR, 1);
2154 #endif
2155         release_region(_PNPWRP, 1);
2156         release_region(isapnp_rdp, 1);
2157 #ifdef CONFIG_PROC_FS
2158         isapnp_proc_done();
2159 #endif
2160         while (!list_empty(&isapnp_cards)) {
2161                 struct list_head *list = isapnp_cards.next;
2162                 list_del(list);
2163                 isapnp_free_card(pci_bus_b(list));
2164         }
2165 }
2166
2167 #endif /* MODULE */
2168
2169 static int isapnp_announce_device(struct isapnp_driver *drv, 
2170                                   struct pci_dev *dev)
2171 {
2172         const struct isapnp_device_id *id;
2173         int ret = 0;
2174
2175         if (drv->id_table) {
2176                 id = isapnp_match_dev(drv->id_table, dev);
2177                 if (!id) {
2178                         ret = 0;
2179                         goto out;
2180                 }
2181         } else
2182                 id = NULL;
2183
2184         if (drv->probe(dev, id) >= 0) {
2185                 dev->driver = (struct pci_driver *) drv;
2186                 ret = 1;
2187         }
2188 out:
2189         return ret;
2190 }
2191
2192 /**
2193  * isapnp_dev_driver - get the isapnp_driver of a device
2194  * @dev: the device to query
2195  *
2196  * Returns the appropriate isapnp_driver structure or %NULL if there is no 
2197  * registered driver for the device.
2198  */
2199 static struct isapnp_driver *isapnp_dev_driver(const struct pci_dev *dev)
2200 {
2201         return (struct isapnp_driver *) dev->driver;
2202 }
2203
2204 static LIST_HEAD(isapnp_drivers);
2205
2206 /**
2207  * isapnp_register_driver - register a new ISAPnP driver
2208  * @drv: the driver structure to register
2209  * 
2210  * Adds the driver structure to the list of registered ISAPnP drivers
2211  * Returns the number of isapnp devices which were claimed by the driver
2212  * during registration.  The driver remains registered even if the
2213  * return value is zero.
2214  */
2215 int isapnp_register_driver(struct isapnp_driver *drv)
2216 {
2217         struct pci_dev *dev;
2218         int count = 0;
2219
2220         list_add_tail(&drv->node, &isapnp_drivers);
2221
2222         isapnp_for_each_dev(dev) {
2223                 if (!isapnp_dev_driver(dev))
2224                         count += isapnp_announce_device(drv, dev);
2225         }
2226         return count;
2227 }
2228
2229 /**
2230  * isapnp_unregister_driver - unregister an isapnp driver
2231  * @drv: the driver structure to unregister
2232  * 
2233  * Deletes the driver structure from the list of registered ISAPnP drivers,
2234  * gives it a chance to clean up by calling its remove() function for
2235  * each device it was responsible for, and marks those devices as
2236  * driverless.
2237  */
2238 void isapnp_unregister_driver(struct isapnp_driver *drv)
2239 {
2240         struct pci_dev *dev;
2241
2242         list_del(&drv->node);
2243         isapnp_for_each_dev(dev) {
2244                 if (dev->driver == (struct pci_driver *) drv) {
2245                         if (drv->remove)
2246                                 drv->remove(dev);
2247                         dev->driver = NULL;
2248                 }
2249         }
2250 }
2251
2252 EXPORT_SYMBOL(isapnp_cards);
2253 EXPORT_SYMBOL(isapnp_devices);
2254 EXPORT_SYMBOL(isapnp_present);
2255 EXPORT_SYMBOL(isapnp_cfg_begin);
2256 EXPORT_SYMBOL(isapnp_cfg_end);
2257 EXPORT_SYMBOL(isapnp_read_byte);
2258 EXPORT_SYMBOL(isapnp_read_word);
2259 EXPORT_SYMBOL(isapnp_read_dword);
2260 EXPORT_SYMBOL(isapnp_write_byte);
2261 EXPORT_SYMBOL(isapnp_write_word);
2262 EXPORT_SYMBOL(isapnp_write_dword);
2263 EXPORT_SYMBOL(isapnp_wake);
2264 EXPORT_SYMBOL(isapnp_device);
2265 EXPORT_SYMBOL(isapnp_activate);
2266 EXPORT_SYMBOL(isapnp_deactivate);
2267 EXPORT_SYMBOL(isapnp_find_card);
2268 EXPORT_SYMBOL(isapnp_find_dev);
2269 EXPORT_SYMBOL(isapnp_probe_cards);
2270 EXPORT_SYMBOL(isapnp_probe_devs);
2271 EXPORT_SYMBOL(isapnp_activate_dev);
2272 EXPORT_SYMBOL(isapnp_resource_change);
2273 EXPORT_SYMBOL(isapnp_register_driver);
2274 EXPORT_SYMBOL(isapnp_unregister_driver);
2275
2276 int __init isapnp_init(void)
2277 {
2278         int cards;
2279         struct pci_bus *card;
2280
2281         if (isapnp_disable) {
2282                 isapnp_detected = 0;
2283                 printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n");
2284                 return 0;
2285         }
2286 #ifdef ISAPNP_REGION_OK
2287         if (!request_region(_PIDXR, 1, "isapnp index")) {
2288                 printk(KERN_ERR "isapnp: Index Register 0x%x already used\n", _PIDXR);
2289                 return -EBUSY;
2290         }
2291 #endif
2292         if (!request_region(_PNPWRP, 1, "isapnp write")) {
2293                 printk(KERN_ERR "isapnp: Write Data Register 0x%x already used\n", _PNPWRP);
2294 #ifdef ISAPNP_REGION_OK
2295                 release_region(_PIDXR, 1);
2296 #endif
2297                 return -EBUSY;
2298         }
2299         
2300         /*
2301          *      Print a message. The existing ISAPnP code is hanging machines
2302          *      so let the user know where.
2303          */
2304          
2305         printk(KERN_INFO "isapnp: Scanning for PnP cards...\n");
2306         if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {
2307                 isapnp_rdp |= 3;
2308                 if (!request_region(isapnp_rdp, 1, "isapnp read")) {
2309                         printk(KERN_ERR "isapnp: Read Data Register 0x%x already used\n", isapnp_rdp);
2310 #ifdef ISAPNP_REGION_OK
2311                         release_region(_PIDXR, 1);
2312 #endif
2313                         release_region(_PNPWRP, 1);
2314                         return -EBUSY;
2315                 }
2316                 isapnp_set_rdp();
2317         }
2318         isapnp_detected = 1;
2319         if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) {
2320                 cards = isapnp_isolate();
2321                 if (cards < 0 || 
2322                     (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {
2323 #ifdef ISAPNP_REGION_OK
2324                         release_region(_PIDXR, 1);
2325 #endif
2326                         release_region(_PNPWRP, 1);
2327                         isapnp_detected = 0;
2328                         printk(KERN_INFO "isapnp: No Plug & Play device found\n");
2329                         return 0;
2330                 }
2331                 request_region(isapnp_rdp, 1, "isapnp read");
2332         }
2333         isapnp_build_device_list();
2334         cards = 0;
2335
2336         isapnp_for_each_card(card) {
2337                 cards++;
2338                 if (isapnp_verbose) {
2339                         struct list_head *devlist;
2340                         printk(KERN_INFO "isapnp: Card '%s'\n", card->name[0]?card->name:"Unknown");
2341                         if (isapnp_verbose < 2)
2342                                 continue;
2343                         for (devlist = card->devices.next; devlist != &card->devices; devlist = devlist->next) {
2344                                 struct pci_dev *dev = pci_dev_b(devlist);
2345                                 printk(KERN_INFO "isapnp:   Device '%s'\n", dev->name[0]?card->name:"Unknown");
2346                         }
2347                 }
2348         }
2349         if (cards) {
2350                 printk(KERN_INFO "isapnp: %i Plug & Play card%s detected total\n", cards, cards>1?"s":"");
2351         } else {
2352                 printk(KERN_INFO "isapnp: No Plug & Play card found\n");
2353         }
2354 #ifdef CONFIG_PROC_FS
2355         isapnp_proc_init();
2356 #endif
2357         return 0;
2358 }
2359
2360 #ifdef MODULE
2361
2362 int init_module(void)
2363 {
2364         return isapnp_init();
2365 }
2366
2367 void cleanup_module(void)
2368 {
2369         if (isapnp_detected)
2370                 isapnp_free_all_resources();
2371 }
2372
2373 #else
2374
2375 /* format is: noisapnp */
2376
2377 static int __init isapnp_setup_disable(char *str)
2378 {
2379         isapnp_disable = 1;
2380         return 1;
2381 }
2382
2383 __setup("noisapnp", isapnp_setup_disable);
2384
2385 /* format is: isapnp=rdp,reset,skip_pci_scan,verbose */
2386
2387 static int __init isapnp_setup_isapnp(char *str)
2388 {
2389         (void)((get_option(&str,&isapnp_rdp) == 2) &&
2390                (get_option(&str,&isapnp_reset) == 2) &&
2391                (get_option(&str,&isapnp_skip_pci_scan) == 2) &&
2392                (get_option(&str,&isapnp_verbose) == 2));
2393         return 1;
2394 }
2395
2396 __setup("isapnp=", isapnp_setup_isapnp);
2397
2398 /* format is: isapnp_reserve_irq=irq1[,irq2] .... */
2399
2400 static int __init isapnp_setup_reserve_irq(char *str)
2401 {
2402         int i;
2403
2404         for (i = 0; i < 16; i++)
2405                 if (get_option(&str,&isapnp_reserve_irq[i]) != 2)
2406                         break;
2407         return 1;
2408 }
2409
2410 __setup("isapnp_reserve_irq=", isapnp_setup_reserve_irq);
2411
2412 /* format is: isapnp_reserve_dma=dma1[,dma2] .... */
2413
2414 static int __init isapnp_setup_reserve_dma(char *str)
2415 {
2416         int i;
2417
2418         for (i = 0; i < 8; i++)
2419                 if (get_option(&str,&isapnp_reserve_dma[i]) != 2)
2420                         break;
2421         return 1;
2422 }
2423
2424 __setup("isapnp_reserve_dma=", isapnp_setup_reserve_dma);
2425
2426 /* format is: isapnp_reserve_io=io1,size1[,io2,size2] .... */
2427
2428 static int __init isapnp_setup_reserve_io(char *str)
2429 {
2430         int i;
2431
2432         for (i = 0; i < 16; i++)
2433                 if (get_option(&str,&isapnp_reserve_io[i]) != 2)
2434                         break;
2435         return 1;
2436 }
2437
2438 __setup("isapnp_reserve_io=", isapnp_setup_reserve_io);
2439
2440 /* format is: isapnp_reserve_mem=mem1,size1[,mem2,size2] .... */
2441
2442 static int __init isapnp_setup_reserve_mem(char *str)
2443 {
2444         int i;
2445
2446         for (i = 0; i < 16; i++)
2447                 if (get_option(&str,&isapnp_reserve_mem[i]) != 2)
2448                         break;
2449         return 1;
2450 }
2451
2452 __setup("isapnp_reserve_mem=", isapnp_setup_reserve_mem);
2453
2454 #endif