setup enviroment for compilation
[linux-2.4.21-pre4.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         int i;
514         struct isapnp_irq *irq, *ptr;
515
516         isapnp_peek(tmp, size);
517         irq = isapnp_alloc(sizeof(struct isapnp_irq));
518         if (!irq)
519                 return;
520         if (*res == NULL) {
521                 *res = isapnp_build_resources(dev, dependent);
522                 if (*res == NULL) {
523                         kfree(irq);
524                         return;
525                 }
526         }
527         irq->map = (tmp[1] << 8) | tmp[0];
528         if (size > 2)
529                 irq->flags = tmp[2];
530         else
531                 irq->flags = IORESOURCE_IRQ_HIGHEDGE;
532         irq->res = *res;
533         ptr = (*res)->irq;
534         while (ptr && ptr->next)
535                 ptr = ptr->next;
536         if (ptr)
537                 ptr->next = irq;
538         else
539                 (*res)->irq = irq;
540 #ifdef CONFIG_PCI
541         for (i=0; i<16; i++)
542                 if (irq->map & (1<<i))
543                         pcibios_penalize_isa_irq(i);
544 #endif
545 }
546
547 /*
548  *  Add DMA resource to resources list.
549  */
550
551 static void __init isapnp_add_dma_resource(struct pci_dev *dev,
552                                                struct isapnp_resources **res,
553                                                int dependent, int size)
554 {
555         unsigned char tmp[2];
556         struct isapnp_dma *dma, *ptr;
557
558         isapnp_peek(tmp, size);
559         dma = isapnp_alloc(sizeof(struct isapnp_dma));
560         if (!dma)
561                 return;
562         if (*res == NULL) {
563                 *res = isapnp_build_resources(dev, dependent);
564                 if (*res == NULL) {
565                         kfree(dma);
566                         return;
567                 }
568         }
569         dma->map = tmp[0];
570         dma->flags = tmp[1];
571         dma->res = *res;
572         ptr = (*res)->dma;
573         while (ptr && ptr->next)
574                 ptr = ptr->next;
575         if (ptr)
576                 ptr->next = dma;
577         else
578                 (*res)->dma = dma;
579 }
580
581 /*
582  *  Add port resource to resources list.
583  */
584
585 static void __init isapnp_add_port_resource(struct pci_dev *dev,
586                                                 struct isapnp_resources **res,
587                                                 int dependent, int size)
588 {
589         unsigned char tmp[7];
590         struct isapnp_port *port, *ptr;
591
592         isapnp_peek(tmp, size);
593         port = isapnp_alloc(sizeof(struct isapnp_port));
594         if (!port)
595                 return;
596         if (*res == NULL) {
597                 *res = isapnp_build_resources(dev, dependent);
598                 if (*res == NULL) {
599                         kfree(port);
600                         return;
601                 }
602         }
603         port->min = (tmp[2] << 8) | tmp[1];
604         port->max = (tmp[4] << 8) | tmp[3];
605         port->align = tmp[5];
606         port->size = tmp[6];
607         port->flags = tmp[0] ? ISAPNP_PORT_FLAG_16BITADDR : 0;
608         port->res = *res;
609         ptr = (*res)->port;
610         while (ptr && ptr->next)
611                 ptr = ptr->next;
612         if (ptr)
613                 ptr->next = port;
614         else
615                 (*res)->port = port;
616 }
617
618 /*
619  *  Add fixed port resource to resources list.
620  */
621
622 static void __init isapnp_add_fixed_port_resource(struct pci_dev *dev,
623                                                       struct isapnp_resources **res,
624                                                       int dependent, int size)
625 {
626         unsigned char tmp[3];
627         struct isapnp_port *port, *ptr;
628
629         isapnp_peek(tmp, size);
630         port = isapnp_alloc(sizeof(struct isapnp_port));
631         if (!port)
632                 return;
633         if (*res == NULL) {
634                 *res = isapnp_build_resources(dev, dependent);
635                 if (*res == NULL) {
636                         kfree(port);
637                         return;
638                 }
639         }
640         port->min = port->max = (tmp[1] << 8) | tmp[0];
641         port->size = tmp[2];
642         port->align = 0;
643         port->flags = ISAPNP_PORT_FLAG_FIXED;
644         port->res = *res;
645         ptr = (*res)->port;
646         while (ptr && ptr->next)
647                 ptr = ptr->next;
648         if (ptr)
649                 ptr->next = port;
650         else
651                 (*res)->port = port;
652 }
653
654 /*
655  *  Add memory resource to resources list.
656  */
657
658 static void __init isapnp_add_mem_resource(struct pci_dev *dev,
659                                                struct isapnp_resources **res,
660                                                int dependent, int size)
661 {
662         unsigned char tmp[9];
663         struct isapnp_mem *mem, *ptr;
664
665         isapnp_peek(tmp, size);
666         mem = isapnp_alloc(sizeof(struct isapnp_mem));
667         if (!mem)
668                 return;
669         if (*res == NULL) {
670                 *res = isapnp_build_resources(dev, dependent);
671                 if (*res == NULL) {
672                         kfree(mem);
673                         return;
674                 }
675         }
676         mem->min = ((tmp[2] << 8) | tmp[1]) << 8;
677         mem->max = ((tmp[4] << 8) | tmp[3]) << 8;
678         mem->align = (tmp[6] << 8) | tmp[5];
679         mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
680         mem->flags = tmp[0];
681         mem->res = *res;
682         ptr = (*res)->mem;
683         while (ptr && ptr->next)
684                 ptr = ptr->next;
685         if (ptr)
686                 ptr->next = mem;
687         else
688                 (*res)->mem = mem;
689 }
690
691 /*
692  *  Add 32-bit memory resource to resources list.
693  */
694
695 static void __init isapnp_add_mem32_resource(struct pci_dev *dev,
696                                                  struct isapnp_resources **res,
697                                                  int dependent, int size)
698 {
699         unsigned char tmp[17];
700         struct isapnp_mem32 *mem32, *ptr;
701
702         isapnp_peek(tmp, size);
703         mem32 = isapnp_alloc(sizeof(struct isapnp_mem32));
704         if (!mem32)
705                 return;
706         if (*res == NULL) {
707                 *res = isapnp_build_resources(dev, dependent);
708                 if (*res == NULL) {
709                         kfree(mem32);
710                         return;
711                 }
712         }
713         memcpy(mem32->data, tmp, 17);
714         mem32->res = *res;
715         ptr = (*res)->mem32;
716         while (ptr && ptr->next)
717                 ptr = ptr->next;
718         if (ptr)
719                 ptr->next = mem32;
720         else
721                 (*res)->mem32 = mem32;
722 }
723
724 /*
725  *  Add 32-bit fixed memory resource to resources list.
726  */
727
728 static void __init isapnp_add_fixed_mem32_resource(struct pci_dev *dev,
729                                                        struct isapnp_resources **res,
730                                                        int dependent, int size)
731 {
732         unsigned char tmp[17];
733         struct isapnp_mem32 *mem32, *ptr;
734
735         isapnp_peek(tmp, size);
736         mem32 = isapnp_alloc(sizeof(struct isapnp_mem32));
737         if (!mem32)
738                 return;
739         if (*res == NULL) {
740                 *res = isapnp_build_resources(dev, dependent);
741                 if (*res == NULL) {
742                         kfree(mem32);
743                         return;
744                 }
745         }
746         memcpy(mem32->data, tmp, 17);
747         mem32->res = *res;
748         ptr = (*res)->mem32;
749         while (ptr && ptr->next)
750                 ptr = ptr->next;
751         if (ptr)
752                 ptr->next = mem32;
753         else
754                 (*res)->mem32 = mem32;
755 }
756
757 /*
758  *  Parse card name for ISA PnP device.
759  */ 
760  
761 static void __init 
762 isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
763 {
764         if (name[0] == '\0') {
765                 unsigned short size1 = *size >= name_max ? (name_max - 1) : *size;
766                 isapnp_peek(name, size1);
767                 name[size1] = '\0';
768                 *size -= size1;
769                 
770                 /* clean whitespace from end of string */
771                 while (size1 > 0  &&  name[--size1] == ' ') 
772                         name[size1] = '\0';
773         }       
774 }
775
776 /*
777  *  Parse resource map for logical device.
778  */
779
780 static int __init isapnp_create_device(struct pci_bus *card,
781                                            unsigned short size)
782 {
783         int number = 0, skip = 0, dependent = 0, compat = 0;
784         unsigned char type, tmp[17];
785         struct pci_dev *dev;
786         struct isapnp_resources *res = NULL;
787         
788         if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
789                 return 1;
790         list_add(&dev->bus_list, &card->devices);
791         list_add_tail(&dev->global_list, &isapnp_devices);
792         while (1) {
793                 if (isapnp_read_tag(&type, &size)<0)
794                         return 1;
795                 if (skip && type != _STAG_LOGDEVID && type != _STAG_END)
796                         goto __skip;
797                 switch (type) {
798                 case _STAG_LOGDEVID:
799                         if (size >= 5 && size <= 6) {
800                                 isapnp_config_prepare(dev);
801                                 if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
802                                         return 1;
803                                 list_add_tail(&dev->bus_list, &card->devices);
804                                 list_add_tail(&dev->global_list, &isapnp_devices);
805                                 size = 0;
806                                 skip = 0;
807                         } else {
808                                 skip = 1;
809                         }
810                         res = NULL;
811                         dependent = 0;
812                         compat = 0;
813                         break;
814                 case _STAG_COMPATDEVID:
815                         if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {
816                                 isapnp_peek(tmp, 4);
817                                 dev->vendor_compatible[compat] = (tmp[1] << 8) | tmp[0];
818                                 dev->device_compatible[compat] = (tmp[3] << 8) | tmp[2];
819                                 compat++;
820                                 size = 0;
821                         }
822                         break;
823                 case _STAG_IRQ:
824                         if (size < 2 || size > 3)
825                                 goto __skip;
826                         isapnp_add_irq_resource(dev, &res, dependent, size);
827                         size = 0;
828                         break;
829                 case _STAG_DMA:
830                         if (size != 2)
831                                 goto __skip;
832                         isapnp_add_dma_resource(dev, &res, dependent, size);
833                         size = 0;
834                         break;
835                 case _STAG_STARTDEP:
836                         if (size > 1)
837                                 goto __skip;
838                         res = NULL;
839                         dependent = 0x100 | ISAPNP_RES_PRIORITY_ACCEPTABLE;
840                         if (size > 0) {
841                                 isapnp_peek(tmp, size);
842                                 dependent = 0x100 | tmp[0];
843                                 size = 0;
844                         }
845                         break;
846                 case _STAG_ENDDEP:
847                         if (size != 0)
848                                 goto __skip;
849                         res = NULL;
850                         dependent = 0;
851                         break;
852                 case _STAG_IOPORT:
853                         if (size != 7)
854                                 goto __skip;
855                         isapnp_add_port_resource(dev, &res, dependent, size);
856                         size = 0;
857                         break;
858                 case _STAG_FIXEDIO:
859                         if (size != 3)
860                                 goto __skip;
861                         isapnp_add_fixed_port_resource(dev, &res, dependent, size);
862                         size = 0;
863                         break;
864                 case _STAG_VENDOR:
865                         break;
866                 case _LTAG_MEMRANGE:
867                         if (size != 9)
868                                 goto __skip;
869                         isapnp_add_mem_resource(dev, &res, dependent, size);
870                         size = 0;
871                         break;
872                 case _LTAG_ANSISTR:
873                         isapnp_parse_name(dev->name, sizeof(dev->name), &size);
874                         break;
875                 case _LTAG_UNICODESTR:
876                         /* silently ignore */
877                         /* who use unicode for hardware identification? */
878                         break;
879                 case _LTAG_VENDOR:
880                         break;
881                 case _LTAG_MEM32RANGE:
882                         if (size != 17)
883                                 goto __skip;
884                         isapnp_add_mem32_resource(dev, &res, dependent, size);
885                         size = 0;
886                         break;
887                 case _LTAG_FIXEDMEM32RANGE:
888                         if (size != 17)
889                                 goto __skip;
890                         isapnp_add_fixed_mem32_resource(dev, &res, dependent, size);
891                         size = 0;
892                         break;
893                 case _STAG_END:
894                         if (size > 0)
895                                 isapnp_skip_bytes(size);
896                         isapnp_config_prepare(dev);
897                         return 1;
898                 default:
899                         printk(KERN_ERR "isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n", type, dev->devfn, card->number);
900                 }
901               __skip:
902                 if (size > 0)
903                         isapnp_skip_bytes(size);
904         }
905         isapnp_config_prepare(dev);
906         return 0;
907 }
908
909 /*
910  *  Parse resource map for ISA PnP card.
911  */
912  
913 static void __init isapnp_parse_resource_map(struct pci_bus *card)
914 {
915         unsigned char type, tmp[17];
916         unsigned short size;
917         
918         while (1) {
919                 if (isapnp_read_tag(&type, &size)<0)
920                         return;
921                 switch (type) {
922                 case _STAG_PNPVERNO:
923                         if (size != 2)
924                                 goto __skip;
925                         isapnp_peek(tmp, 2);
926                         card->pnpver = tmp[0];
927                         card->productver = tmp[1];
928                         size = 0;
929                         break;
930                 case _STAG_LOGDEVID:
931                         if (size >= 5 && size <= 6) {
932                                 if (isapnp_create_device(card, size)==1)
933                                         return;
934                                 size = 0;
935                         }
936                         break;
937                 case _STAG_VENDOR:
938                         break;
939                 case _LTAG_ANSISTR:
940                         isapnp_parse_name(card->name, sizeof(card->name), &size);
941                         break;
942                 case _LTAG_UNICODESTR:
943                         /* silently ignore */
944                         /* who use unicode for hardware identification? */
945                         break;
946                 case _LTAG_VENDOR:
947                         break;
948                 case _STAG_END:
949                         if (size > 0)
950                                 isapnp_skip_bytes(size);
951                         return;
952                 default:
953                         printk(KERN_ERR "isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n", type, card->number);
954                 }
955               __skip:
956                 if (size > 0)
957                         isapnp_skip_bytes(size);
958         }
959 }
960
961 /*
962  *  Compute ISA PnP checksum for first eight bytes.
963  */
964
965 static unsigned char __init isapnp_checksum(unsigned char *data)
966 {
967         int i, j;
968         unsigned char checksum = 0x6a, bit, b;
969         
970         for (i = 0; i < 8; i++) {
971                 b = data[i];
972                 for (j = 0; j < 8; j++) {
973                         bit = 0;
974                         if (b & (1 << j))
975                                 bit = 1;
976                         checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1);
977                 }
978         }
979         return checksum;
980 }
981
982 /*
983  *  Build device list for all present ISA PnP devices.
984  */
985
986 static int __init isapnp_build_device_list(void)
987 {
988         int csn;
989         unsigned char header[9], checksum;
990         struct pci_bus *card;
991         struct pci_dev *dev;
992
993         isapnp_wait();
994         isapnp_key();
995         for (csn = 1; csn <= 10; csn++) {
996                 isapnp_wake(csn);
997                 isapnp_peek(header, 9);
998                 checksum = isapnp_checksum(header);
999 #if 0
1000                 printk(KERN_DEBUG "vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1001                         header[0], header[1], header[2], header[3],
1002                         header[4], header[5], header[6], header[7], header[8]);
1003                 printk(KERN_DEBUG "checksum = 0x%x\n", checksum);
1004 #endif
1005                 /* Don't be strict on the checksum, here !
1006                    e.g. 'SCM SwapBox Plug and Play' has header[8]==0 (should be: b7)*/
1007                 if (header[8] == 0)
1008                         ;
1009                 else if (checksum == 0x00 || checksum != header[8])     /* not valid CSN */
1010                         continue;
1011                 if ((card = isapnp_alloc(sizeof(struct pci_bus))) == NULL)
1012                         continue;
1013
1014                 card->number = csn;
1015                 card->vendor = (header[1] << 8) | header[0];
1016                 card->device = (header[3] << 8) | header[2];
1017                 card->serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4];
1018                 isapnp_checksum_value = 0x00;
1019                 INIT_LIST_HEAD(&card->children);
1020                 INIT_LIST_HEAD(&card->devices);
1021                 isapnp_parse_resource_map(card);
1022                 if (isapnp_checksum_value != 0x00)
1023                         printk(KERN_ERR "isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value);
1024                 card->checksum = isapnp_checksum_value;
1025
1026                 list_add_tail(&card->node, &isapnp_cards);
1027         }
1028         isapnp_for_each_dev(dev) {
1029                 isapnp_fixup_device(dev);
1030         }
1031         return 0;
1032 }
1033
1034 /*
1035  *  Basic configuration routines.
1036  */
1037
1038 int isapnp_present(void)
1039 {
1040         return !list_empty(&isapnp_devices);
1041 }
1042
1043 int isapnp_cfg_begin(int csn, int logdev)
1044 {
1045         if (csn < 1 || csn > 10 || logdev > 10)
1046                 return -EINVAL;
1047         MOD_INC_USE_COUNT;
1048         down(&isapnp_cfg_mutex);
1049         isapnp_wait();
1050         isapnp_key();
1051         isapnp_wake(csn);
1052 #if 1   /* to avoid malfunction when the isapnptools package is used */
1053         isapnp_set_rdp();
1054         udelay(1000);   /* delay 1000us */
1055         write_address(0x01);
1056         udelay(1000);   /* delay 1000us */
1057 #endif
1058         if (logdev >= 0)
1059                 isapnp_device(logdev);
1060         return 0;
1061 }
1062
1063 int isapnp_cfg_end(void)
1064 {
1065         isapnp_wait();
1066         up(&isapnp_cfg_mutex);
1067         MOD_DEC_USE_COUNT;
1068         return 0;
1069 }
1070
1071 /*
1072  *  Resource manager.
1073  */
1074
1075 static struct isapnp_port *isapnp_find_port(struct pci_dev *dev, int index)
1076 {
1077         struct isapnp_resources *res;
1078         struct isapnp_port *port;
1079         
1080         if (!dev || index < 0 || index > 7)
1081                 return NULL;
1082         for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1083                 for (port = res->port; port; port = port->next) {
1084                         if (!index)
1085                                 return port;
1086                         index--;
1087                 }
1088         }
1089         return NULL;
1090 }
1091
1092 struct isapnp_irq *isapnp_find_irq(struct pci_dev *dev, int index)
1093 {
1094         struct isapnp_resources *res, *resa;
1095         struct isapnp_irq *irq;
1096         int index1, index2, index3;
1097         
1098         if (!dev || index < 0 || index > 7)
1099                 return NULL;
1100         for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1101                 index3 = 0;
1102                 for (resa = res; resa; resa = resa->alt) {
1103                         index1 = index;
1104                         index2 = 0;
1105                         for (irq = resa->irq; irq; irq = irq->next) {
1106                                 if (!index1)
1107                                         return irq;
1108                                 index1--;
1109                                 index2++;
1110                         }
1111                         if (index3 < index2)
1112                                 index3 = index2;
1113                 }
1114                 index -= index3;
1115         }
1116         return NULL;
1117 }
1118
1119 struct isapnp_dma *isapnp_find_dma(struct pci_dev *dev, int index)
1120 {
1121         struct isapnp_resources *res;
1122         struct isapnp_dma *dma;
1123         
1124         if (!dev || index < 0 || index > 7)
1125                 return NULL;
1126         for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1127                 for (dma = res->dma; dma; dma = dma->next) {
1128                         if (!index)
1129                                 return dma;
1130                         index--;
1131                 }
1132         }
1133         return NULL;
1134 }
1135
1136 struct isapnp_mem *isapnp_find_mem(struct pci_dev *dev, int index)
1137 {
1138         struct isapnp_resources *res;
1139         struct isapnp_mem *mem;
1140         
1141         if (!dev || index < 0 || index > 7)
1142                 return NULL;
1143         for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1144                 for (mem = res->mem; mem; mem = mem->next) {
1145                         if (!index)
1146                                 return mem;
1147                         index--;
1148                 }
1149         }
1150         return NULL;
1151 }
1152
1153 struct isapnp_mem32 *isapnp_find_mem32(struct pci_dev *dev, int index)
1154 {
1155         struct isapnp_resources *res;
1156         struct isapnp_mem32 *mem32;
1157         
1158         if (!dev || index < 0 || index > 7)
1159                 return NULL;
1160         for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1161                 for (mem32 = res->mem32; mem32; mem32 = mem32->next) {
1162                         if (!index)
1163                                 return mem32;
1164                         index--;
1165                 }
1166         }
1167         return NULL;
1168 }
1169
1170 /*
1171  *  Device manager.
1172  */
1173
1174 struct pci_bus *isapnp_find_card(unsigned short vendor,
1175                                  unsigned short device,
1176                                  struct pci_bus *from)
1177 {
1178         struct list_head *list;
1179
1180         list = isapnp_cards.next;
1181         if (from)
1182                 list = from->node.next;
1183
1184         while (list != &isapnp_cards) {
1185                 struct pci_bus *card = pci_bus_b(list);
1186                 if (card->vendor == vendor && card->device == device)
1187                         return card;
1188                 list = list->next;
1189         }
1190         return NULL;
1191 }
1192
1193 struct pci_dev *isapnp_find_dev(struct pci_bus *card,
1194                                 unsigned short vendor,
1195                                 unsigned short function,
1196                                 struct pci_dev *from)
1197 {
1198         if (card == NULL) {     /* look for a logical device from all cards */
1199                 struct list_head *list;
1200
1201                 list = isapnp_devices.next;
1202                 if (from)
1203                         list = from->global_list.next;
1204
1205                 while (list != &isapnp_devices) {
1206                         int idx;
1207                         struct pci_dev *dev = pci_dev_g(list);
1208
1209                         if (dev->vendor == vendor && dev->device == function)
1210                                 return dev;
1211                         for (idx = 0; idx < DEVICE_COUNT_COMPATIBLE; idx++)
1212                                 if (dev->vendor_compatible[idx] == vendor &&
1213                                     dev->device_compatible[idx] == function)
1214                                         return dev;
1215                         list = list->next;
1216                 }
1217         } else {
1218                 struct list_head *list;
1219
1220                 list = card->devices.next;
1221                 if (from) {
1222                         list = from->bus_list.next;
1223                         if (from->bus != card)  /* something is wrong */
1224                                 return NULL;
1225                 }
1226                 while (list != &card->devices) {
1227                         int idx;
1228                         struct pci_dev *dev = pci_dev_b(list);
1229
1230                         if (dev->vendor == vendor && dev->device == function)
1231                                 return dev;
1232                         for (idx = 0; idx < DEVICE_COUNT_COMPATIBLE; idx++)
1233                                 if (dev->vendor_compatible[idx] == vendor &&
1234                                     dev->device_compatible[idx] == function)
1235                                         return dev;
1236                         list = list->next;
1237                 }
1238         }
1239         return NULL;
1240 }
1241
1242 static const struct isapnp_card_id *
1243 isapnp_match_card(const struct isapnp_card_id *ids, struct pci_bus *card)
1244 {
1245         int idx;
1246
1247         while (ids->card_vendor || ids->card_device) {
1248                 if ((ids->card_vendor == ISAPNP_ANY_ID || ids->card_vendor == card->vendor) &&
1249                     (ids->card_device == ISAPNP_ANY_ID || ids->card_device == card->device)) {
1250                         for (idx = 0; idx < ISAPNP_CARD_DEVS; idx++) {
1251                                 if (ids->devs[idx].vendor == 0 &&
1252                                     ids->devs[idx].function == 0)
1253                                         return ids;
1254                                 if (isapnp_find_dev(card,
1255                                                     ids->devs[idx].vendor,
1256                                                     ids->devs[idx].function,
1257                                                     NULL) == NULL)
1258                                         goto __next;
1259                         }
1260                         return ids;
1261                 }
1262               __next:
1263                 ids++;
1264         }
1265         return NULL;
1266 }
1267
1268 int isapnp_probe_cards(const struct isapnp_card_id *ids,
1269                        int (*probe)(struct pci_bus *_card,
1270                                     const struct isapnp_card_id *_id))
1271 {
1272         struct pci_bus *card;   
1273         const struct isapnp_card_id *id;
1274         int count = 0;
1275
1276         if (ids == NULL || probe == NULL)
1277                 return -EINVAL;
1278         isapnp_for_each_card(card) {
1279                 id = isapnp_match_card(ids, card);
1280                 if (id != NULL && probe(card, id) >= 0)
1281                         count++;
1282         }
1283         return count;
1284 }
1285
1286 static const struct isapnp_device_id *
1287 isapnp_match_dev(const struct isapnp_device_id *ids, struct pci_dev *dev)
1288 {
1289         while (ids->card_vendor || ids->card_device) {
1290                 if ((ids->card_vendor == ISAPNP_ANY_ID || ids->card_vendor == dev->bus->vendor) &&
1291                     (ids->card_device == ISAPNP_ANY_ID || ids->card_device == dev->bus->device) &&
1292                     (ids->vendor == ISAPNP_ANY_ID || ids->vendor == dev->vendor) &&
1293                     (ids->function == ISAPNP_ANY_ID || ids->function == dev->device))
1294                         return ids;
1295                 ids++;
1296         }
1297         return NULL;
1298 }
1299
1300 int isapnp_probe_devs(const struct isapnp_device_id *ids,
1301                       int (*probe)(struct pci_dev *dev,
1302                                    const struct isapnp_device_id *id))
1303 {
1304         
1305         struct pci_dev *dev;
1306         const struct isapnp_device_id *id;
1307         int count = 0;
1308
1309         if (ids == NULL || probe == NULL)
1310                 return -EINVAL;
1311         isapnp_for_each_dev(dev) {
1312                 id = isapnp_match_dev(ids, dev);
1313                 if (id != NULL && probe(dev, id) >= 0)
1314                         count++;
1315         }
1316         return count;
1317 }
1318
1319 int isapnp_activate_dev(struct pci_dev *dev, const char *name)
1320 {
1321         int err;
1322         
1323         /* Device already active? Let's use it and inform the caller */
1324         if (dev->active)
1325                 return -EBUSY;
1326
1327         if ((err = dev->activate(dev)) < 0) {
1328                 printk(KERN_ERR "isapnp: config of %s failed (out of resources?)[%d]\n", name, err);
1329                 dev->deactivate(dev);
1330                 return err;
1331         }
1332
1333         return 0;
1334 }
1335
1336 static unsigned int isapnp_dma_resource_flags(struct isapnp_dma *dma)
1337 {
1338         return dma->flags | IORESOURCE_DMA | IORESOURCE_AUTO;
1339 }
1340
1341 static unsigned int isapnp_mem_resource_flags(struct isapnp_mem *mem)
1342 {
1343         unsigned int result;
1344
1345         result = mem->flags | IORESOURCE_MEM | IORESOURCE_AUTO;
1346         if (!(mem->flags & IORESOURCE_MEM_WRITEABLE))
1347                 result |= IORESOURCE_READONLY;
1348         if (mem->flags & IORESOURCE_MEM_CACHEABLE)
1349                 result |= IORESOURCE_CACHEABLE;
1350         if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
1351                 result |= IORESOURCE_RANGELENGTH;
1352         if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
1353                 result |= IORESOURCE_SHADOWABLE;
1354         return result;
1355 }
1356
1357 static unsigned int isapnp_irq_resource_flags(struct isapnp_irq *irq)
1358 {
1359         return irq->flags | IORESOURCE_IRQ | IORESOURCE_AUTO;
1360 }
1361
1362 static unsigned int isapnp_port_resource_flags(struct isapnp_port *port)
1363 {
1364         return port->flags | IORESOURCE_IO | IORESOURCE_AUTO;
1365 }
1366
1367 static int isapnp_config_prepare(struct pci_dev *dev)
1368 {
1369         struct isapnp_resources *res, *resa;
1370         struct isapnp_port *port;
1371         struct isapnp_irq *irq;
1372         struct isapnp_dma *dma;
1373         struct isapnp_mem *mem;
1374         int port_count, port_count1;
1375         int irq_count, irq_count1;
1376         int dma_count, dma_count1;
1377         int mem_count, mem_count1;
1378         int idx;
1379
1380         if (dev == NULL)
1381                 return -EINVAL;
1382         if (dev->active || dev->ro)
1383                 return -EBUSY;
1384         for (idx = 0; idx < DEVICE_COUNT_IRQ; idx++) {
1385                 dev->irq_resource[idx].name = NULL;
1386                 dev->irq_resource[idx].start = 0;
1387                 dev->irq_resource[idx].end = 0;
1388                 dev->irq_resource[idx].flags = 0;
1389         }
1390         for (idx = 0; idx < DEVICE_COUNT_DMA; idx++) {
1391                 dev->dma_resource[idx].name = NULL;
1392                 dev->dma_resource[idx].start = 0;
1393                 dev->dma_resource[idx].end = 0;
1394                 dev->dma_resource[idx].flags = 0;
1395         }
1396         for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) {
1397                 dev->resource[idx].name = NULL;
1398                 dev->resource[idx].start = 0;
1399                 dev->resource[idx].end = 0;
1400                 dev->resource[idx].flags = 0;
1401         }
1402         port_count = irq_count = dma_count = mem_count = 0;
1403         for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
1404                 port_count1 = irq_count1 = dma_count1 = mem_count1 = 0;
1405                 for (resa = res; resa; resa = resa->alt) {
1406                         for (port = resa->port, idx = 0; port; port = port->next, idx++) {
1407                                 if (dev->resource[port_count + idx].flags == 0) {
1408                                         dev->resource[port_count + idx].flags = isapnp_port_resource_flags(port);
1409                                         dev->resource[port_count + idx].end = port->size;
1410                                 }
1411                         }
1412                         if (port_count1 < idx)
1413                                 port_count1 = idx;
1414                         for (irq = resa->irq, idx = 0; irq; irq = irq->next, idx++) {
1415                                 int count = irq_count + idx;
1416                                 if (count < DEVICE_COUNT_IRQ) {
1417                                         if (dev->irq_resource[count].flags == 0) {
1418                                                 dev->irq_resource[count].flags = isapnp_irq_resource_flags(irq);
1419                                         }
1420                                 }
1421                                 
1422                         }
1423                         if (irq_count1 < idx)
1424                                 irq_count1 = idx;
1425                         for (dma = resa->dma, idx = 0; dma; dma = dma->next, idx++)
1426                                 if (dev->dma_resource[idx].flags == 0) {
1427                                         dev->dma_resource[idx].flags = isapnp_dma_resource_flags(dma);
1428                                 }
1429                         if (dma_count1 < idx)
1430                                 dma_count1 = idx;
1431                         for (mem = resa->mem, idx = 0; mem; mem = mem->next, idx++)
1432                                 if (dev->resource[mem_count + idx + 8].flags == 0) {
1433                                         dev->resource[mem_count + idx + 8].flags = isapnp_mem_resource_flags(mem);
1434                                 }
1435                         if (mem_count1 < idx)
1436                                 mem_count1 = idx;
1437                 }
1438                 port_count += port_count1;
1439                 irq_count += irq_count1;
1440                 dma_count += dma_count1;
1441                 mem_count += mem_count1;
1442         }
1443         return 0;
1444 }
1445
1446 struct isapnp_cfgtmp {
1447         struct isapnp_port *port[8];
1448         struct isapnp_irq *irq[2];
1449         struct isapnp_dma *dma[2];
1450         struct isapnp_mem *mem[4];
1451         struct pci_dev *request;
1452         struct pci_dev result;
1453 };
1454
1455 static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg,
1456                                      struct isapnp_resources *from,
1457                                      struct isapnp_resources *to)
1458 {
1459         int tmp, tmp1;
1460         struct isapnp_port *port;
1461         struct isapnp_irq *irq;
1462         struct isapnp_dma *dma;
1463         struct isapnp_mem *mem;
1464
1465         if (!cfg)
1466                 return -EINVAL;
1467         /* process port settings */
1468         for (tmp = 0; tmp < 8; tmp++) {
1469                 if (!(cfg->request->resource[tmp].flags & IORESOURCE_AUTO))
1470                         continue;               /* don't touch */
1471                 port = cfg->port[tmp];
1472                 if (!port) {
1473                         cfg->port[tmp] = port = isapnp_find_port(cfg->request, tmp);
1474                         if (!port)
1475                                 return -EINVAL;
1476                 }
1477                 if (from && port->res == from) {
1478                         while (port->res != to) {
1479                                 if (!port->res->alt)
1480                                         return -EINVAL;
1481                                 port = port->res->alt->port;
1482                                 for (tmp1 = tmp; tmp1 > 0 && port; tmp1--)
1483                                         port = port->next;
1484                                 cfg->port[tmp] = port;
1485                                 if (!port)
1486                                         return -ENOENT;
1487                                 cfg->result.resource[tmp].flags = isapnp_port_resource_flags(port);
1488                         }
1489                 }
1490         }
1491         /* process irq settings */
1492         for (tmp = 0; tmp < 2; tmp++) {
1493                 if (!(cfg->request->irq_resource[tmp].flags & IORESOURCE_AUTO))
1494                         continue;               /* don't touch */
1495                 irq = cfg->irq[tmp];
1496                 if (!irq) {
1497                         cfg->irq[tmp] = irq = isapnp_find_irq(cfg->request, tmp);
1498                         if (!irq)
1499                                 return -EINVAL;
1500                 }
1501                 if (from && irq->res == from) {
1502                         while (irq->res != to) {
1503                                 if (!irq->res->alt)
1504                                         return -EINVAL;
1505                                 irq = irq->res->alt->irq;
1506                                 for (tmp1 = tmp; tmp1 > 0 && irq; tmp1--)
1507                                         irq = irq->next;
1508                                 cfg->irq[tmp] = irq;
1509                                 if (!irq)
1510                                         return -ENOENT;
1511                                 cfg->result.irq_resource[tmp].flags = isapnp_irq_resource_flags(irq);
1512                         }
1513                 }
1514         }
1515         /* process dma settings */
1516         for (tmp = 0; tmp < 2; tmp++) {
1517                 if (!(cfg->request->dma_resource[tmp].flags & IORESOURCE_AUTO))
1518                         continue;               /* don't touch */
1519                 dma = cfg->dma[tmp];
1520                 if (!dma) {
1521                         cfg->dma[tmp] = dma = isapnp_find_dma(cfg->request, tmp);
1522                         if (!dma)
1523                                 return -EINVAL;
1524                 }
1525                 if (from && dma->res == from) {
1526                         while (dma->res != to) {
1527                                 if (!dma->res->alt)
1528                                         return -EINVAL;
1529                                 dma = dma->res->alt->dma;
1530                                 for (tmp1 = tmp; tmp1 > 0 && dma; tmp1--)
1531                                         dma = dma->next;
1532                                 cfg->dma[tmp] = dma;
1533                                 if (!dma)
1534                                         return -ENOENT;
1535                                 cfg->result.dma_resource[tmp].flags = isapnp_dma_resource_flags(dma);
1536                         }
1537                 }
1538         }
1539         /* process memory settings */
1540         for (tmp = 0; tmp < 4; tmp++) {
1541                 if (!(cfg->request->resource[tmp + 8].flags & IORESOURCE_AUTO))
1542                         continue;               /* don't touch */
1543                 mem = cfg->mem[tmp];
1544                 if (!mem) {
1545                         cfg->mem[tmp] = mem = isapnp_find_mem(cfg->request, tmp);
1546                         if (!mem)
1547                                 return -EINVAL;
1548                 }
1549                 if (from && mem->res == from) {
1550                         while (mem->res != to) {
1551                                 if (!mem->res->alt)
1552                                         return -EINVAL;
1553                                 mem = mem->res->alt->mem;
1554                                 for (tmp1 = tmp; tmp1 > 0 && mem; tmp1--)
1555                                         mem = mem->next;
1556                                 cfg->mem[tmp] = mem;
1557                                 if (!mem)
1558                                         return -ENOENT;
1559                                 cfg->result.resource[tmp + 8].flags = isapnp_mem_resource_flags(mem);
1560                         }
1561                 }
1562         }
1563         return 0;
1564 }
1565
1566 static int isapnp_check_port(struct isapnp_cfgtmp *cfg, int port, int size, int idx)
1567 {
1568         int i, tmp, rport, rsize;
1569         struct isapnp_port *xport;
1570         struct pci_dev *dev;
1571
1572         if (check_region(port, size))
1573                 return 1;
1574         for (i = 0; i < 8; i++) {
1575                 rport = isapnp_reserve_io[i << 1];
1576                 rsize = isapnp_reserve_io[(i << 1) + 1];
1577                 if (port >= rport && port < rport + rsize)
1578                         return 1;
1579                 if (port + size > rport && port + size < (rport + rsize) - 1)
1580                         return 1;
1581         }
1582
1583         isapnp_for_each_dev(dev) {
1584                 if (dev->active) {
1585                         for (tmp = 0; tmp < 8; tmp++) {
1586                                 if (dev->resource[tmp].flags) {
1587                                         rport = dev->resource[tmp].start;
1588                                         rsize = (dev->resource[tmp].end - rport) + 1;
1589                                         if (port >= rport && port < rport + rsize)
1590                                                 return 1;
1591                                         if (port + size > rport && port + size < (rport + rsize) - 1)
1592                                                 return 1;
1593                                 }
1594                         }
1595                 }
1596         }
1597         for (i = 0; i < 8; i++) {
1598                 unsigned int flags;
1599                 if (i == idx)
1600                         continue;
1601                 flags = cfg->request->resource[i].flags;
1602                 if (!flags)
1603                         continue;
1604                 tmp = cfg->request->resource[i].start;
1605                 if (flags & IORESOURCE_AUTO) {          /* auto */
1606                         xport = cfg->port[i];
1607                         if (!xport)
1608                                 return 1;
1609                         if (cfg->result.resource[i].flags & IORESOURCE_AUTO)
1610                                 continue;
1611                         tmp = cfg->result.resource[i].start;
1612                         if (tmp + xport->size >= port && tmp <= port + xport->size)
1613                                 return 1;
1614                         continue;
1615                 }
1616                 if (port == tmp)
1617                         return 1;
1618                 xport = isapnp_find_port(cfg->request, i);
1619                 if (!xport)
1620                         return 1;
1621                 if (tmp + xport->size >= port && tmp <= port + xport->size)
1622                         return 1;
1623         }
1624         return 0;
1625 }
1626
1627 static int isapnp_valid_port(struct isapnp_cfgtmp *cfg, int idx)
1628 {
1629         int err;
1630         unsigned long *value1, *value2;
1631         struct isapnp_port *port;
1632
1633         if (!cfg || idx < 0 || idx > 7)
1634                 return -EINVAL;
1635         if (!(cfg->result.resource[idx].flags & IORESOURCE_AUTO)) /* don't touch */
1636                 return 0;
1637       __again:
1638         port = cfg->port[idx];
1639         if (!port)
1640                 return -EINVAL;
1641         value1 = &cfg->result.resource[idx].start;
1642         value2 = &cfg->result.resource[idx].end;
1643         if (cfg->result.resource[idx].flags & IORESOURCE_AUTO) {
1644                 cfg->result.resource[idx].flags &= ~IORESOURCE_AUTO;
1645                 *value1 = port->min;
1646                 *value2 = port->min + port->size - 1;
1647                 if (!isapnp_check_port(cfg, *value1, port->size, idx))
1648                         return 0;
1649         }
1650         do {
1651                 *value1 += port->align;
1652                 *value2 = *value1 + port->size - 1;
1653                 if (*value1 > port->max || !port->align) {
1654                         if (port->res && port->res->alt) {
1655                                 if ((err = isapnp_alternative_switch(cfg, port->res, port->res->alt))<0)
1656                                         return err;
1657                                 goto __again;
1658                         }
1659                         return -ENOENT;
1660                 }
1661         } while (isapnp_check_port(cfg, *value1, port->size, idx));
1662         return 0;
1663 }
1664
1665 static void isapnp_test_handler(int irq, void *dev_id, struct pt_regs *regs)
1666 {
1667 }
1668
1669 static int isapnp_check_interrupt(struct isapnp_cfgtmp *cfg, int irq, int idx)
1670 {
1671         int i;
1672         struct pci_dev *dev;
1673
1674         if (irq < 0 || irq > 15)
1675                 return 1;
1676         for (i = 0; i < 16; i++) {
1677                 if (isapnp_reserve_irq[i] == irq)
1678                         return 1;
1679         }
1680         isapnp_for_each_dev(dev) {
1681                 if (dev->active) {
1682                         if ((dev->irq_resource[0].flags && dev->irq_resource[0].start == irq) ||
1683                             (dev->irq_resource[1].flags && dev->irq_resource[1].start == irq))
1684                                 return 1;
1685                 }
1686         }
1687 #ifdef CONFIG_PCI
1688         if (!isapnp_skip_pci_scan) {
1689                 pci_for_each_dev(dev) {
1690                         if (dev->irq == irq)
1691                                 return 1;
1692                 }
1693         }
1694 #endif
1695         if (request_irq(irq, isapnp_test_handler, SA_INTERRUPT, "isapnp", NULL))
1696                 return 1;
1697         free_irq(irq, NULL);
1698         for (i = 0; i < DEVICE_COUNT_IRQ; i++) {
1699                 if (i == idx)
1700                         continue;
1701                 if (!cfg->result.irq_resource[i].flags)
1702                         continue;
1703                 if (cfg->result.irq_resource[i].flags & IORESOURCE_AUTO)
1704                         continue;
1705                 if (cfg->result.irq_resource[i].start == irq)
1706                         return 1;
1707         }
1708         return 0;
1709 }
1710
1711 static int isapnp_valid_irq(struct isapnp_cfgtmp *cfg, int idx)
1712 {
1713         /* IRQ priority: this table is good for i386 */
1714         static unsigned short xtab[16] = {
1715                 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
1716         };
1717         int err, i;
1718         unsigned long *value1, *value2;
1719         struct isapnp_irq *irq;
1720
1721         if (!cfg || idx < 0 || idx > 1)
1722                 return -EINVAL;
1723         if (!(cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO))
1724                 return 0;
1725       __again:
1726         irq = cfg->irq[idx];
1727         if (!irq)
1728                 return -EINVAL;
1729         value1 = &cfg->result.irq_resource[idx].start;
1730         value2 = &cfg->result.irq_resource[idx].end;
1731         if (cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO) {
1732                 for (i = 0; i < 16 && !(irq->map & (1<<xtab[i])); i++);
1733                 if (i >= 16)
1734                         return -ENOENT;
1735                 cfg->result.irq_resource[idx].flags &= ~IORESOURCE_AUTO;
1736                 if (!isapnp_check_interrupt(cfg, *value1 = *value2 = xtab[i], idx))
1737                         return 0;
1738         }
1739         do {
1740                 for (i = 0; i < 16 && xtab[i] != *value1; i++);
1741                 for (i++; i < 16 && !(irq->map & (1<<xtab[i])); i++);
1742                 if (i >= 16) {
1743                         if (irq->res && irq->res->alt) {
1744                                 if ((err = isapnp_alternative_switch(cfg, irq->res, irq->res->alt))<0)
1745                                         return err;
1746                                 goto __again;
1747                         }
1748                         return -ENOENT;
1749                 } else {
1750                         *value1 = *value2 = xtab[i];
1751                 }
1752         } while (isapnp_check_interrupt(cfg, *value1, idx));
1753         return 0;
1754 }
1755
1756 static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx)
1757 {
1758         int i, mindma =1;
1759         struct pci_dev *dev;
1760
1761         /* Some machines allow DMA 0, but others don't. In fact on some 
1762            boxes DMA 0 is the memory refresh. Play safe */
1763         if (isapnp_allow_dma0 == 1)
1764                 mindma = 0;
1765         if (dma < mindma || dma == 4 || dma > 7)
1766                 return 1;
1767         for (i = 0; i < 8; i++) {
1768                 if (isapnp_reserve_dma[i] == dma)
1769                         return 1;
1770         }
1771         isapnp_for_each_dev(dev) {
1772                 if (dev->active) {
1773                         if ((dev->dma_resource[0].flags && dev->dma_resource[0].start == dma) ||
1774                             (dev->dma_resource[1].flags && dev->dma_resource[1].start == dma))
1775                                 return 1;
1776                 }
1777         }
1778         if (request_dma(dma, "isapnp"))
1779                 return 1;
1780         free_dma(dma);
1781         for (i = 0; i < 2; i++) {
1782                 if (i == idx)
1783                         continue;
1784                 if (!cfg->result.dma_resource[i].flags ||
1785                     (cfg->result.dma_resource[i].flags & IORESOURCE_AUTO))
1786                         continue;
1787                 if (cfg->result.dma_resource[i].start == dma)
1788                         return 1;
1789         }
1790         return 0;
1791 }
1792
1793 static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx)
1794 {
1795         /* DMA priority: this table is good for i386 */
1796         static unsigned short xtab[16] = {
1797                 1, 3, 5, 6, 7, 0, 2, 4
1798         };
1799         int err, i;
1800         unsigned long *value1, *value2;
1801         struct isapnp_dma *dma;
1802
1803         if (!cfg || idx < 0 || idx > 1)
1804                 return -EINVAL;
1805         if (!(cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO))   /* don't touch */
1806                 return 0;
1807       __again:
1808         dma = cfg->dma[idx];
1809         if (!dma)
1810                 return -EINVAL;
1811         value1 = &cfg->result.dma_resource[idx].start;
1812         value2 = &cfg->result.dma_resource[idx].end;
1813         if (cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO) {
1814                 for (i = 0; i < 8 && !(dma->map & (1<<xtab[i])); i++);
1815                 if (i >= 8)
1816                         return -ENOENT;
1817                 cfg->result.dma_resource[idx].flags &= ~IORESOURCE_AUTO;
1818                 if (!isapnp_check_dma(cfg, *value1 = *value2 = xtab[i], idx))
1819                         return 0;
1820         }
1821         do {
1822                 for (i = 0; i < 8 && xtab[i] != *value1; i++);
1823                 for (i++; i < 8 && !(dma->map & (1<<xtab[i])); i++);
1824                 if (i >= 8) {
1825                         if (dma->res && dma->res->alt) {
1826                                 if ((err = isapnp_alternative_switch(cfg, dma->res, dma->res->alt))<0)
1827                                         return err;
1828                                 goto __again;
1829                         }
1830                         return -ENOENT;
1831                 } else {
1832                         *value1 = *value2 = xtab[i];
1833                 }
1834         } while (isapnp_check_dma(cfg, *value1, idx));
1835         return 0;
1836 }
1837
1838 static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsigned int size, int idx)
1839 {
1840         int i, tmp;
1841         unsigned int raddr, rsize;
1842         struct isapnp_mem *xmem;
1843         struct pci_dev *dev;
1844
1845         for (i = 0; i < 8; i++) {
1846                 raddr = (unsigned int)isapnp_reserve_mem[i << 1];
1847                 rsize = (unsigned int)isapnp_reserve_mem[(i << 1) + 1];
1848                 if (addr >= raddr && addr < raddr + rsize)
1849                         return 1;
1850                 if (addr + size > raddr && addr + size < (raddr + rsize) - 1)
1851                         return 1;
1852                 if (__check_region(&iomem_resource, addr, size))
1853                         return 1;
1854         }
1855         isapnp_for_each_dev(dev) {
1856                 if (dev->active) {
1857                         for (tmp = 0; tmp < 4; tmp++) {
1858                                 if (dev->resource[tmp].flags) {
1859                                         raddr = dev->resource[tmp + 8].start;
1860                                         rsize = (dev->resource[tmp + 8].end - raddr) + 1;
1861                                         if (addr >= raddr && addr < raddr + rsize)
1862                                                 return 1;
1863                                         if (addr + size > raddr && addr + size < (raddr + rsize) - 1)
1864                                                 return 1;
1865                                 }
1866                         }
1867                 }
1868         }
1869         for (i = 0; i < 4; i++) {
1870                 unsigned int flags = cfg->request->resource[i + 8].flags;
1871                 if (i == idx)
1872                         continue;
1873                 if (!flags)
1874                         continue;
1875                 tmp = cfg->result.resource[i + 8].start;
1876                 if (flags & IORESOURCE_AUTO) {          /* auto */
1877                         xmem = cfg->mem[i];
1878                         if (!xmem)
1879                                 return 1;
1880                         if (cfg->result.resource[i + 8].flags & IORESOURCE_AUTO)
1881                                 continue;
1882                         if (tmp + xmem->size >= addr && tmp <= addr + xmem->size)
1883                                 return 1;
1884                         continue;
1885                 }
1886                 if (addr == tmp)
1887                         return 1;
1888                 xmem = isapnp_find_mem(cfg->request, i);
1889                 if (!xmem)
1890                         return 1;
1891                 if (tmp + xmem->size >= addr && tmp <= addr + xmem->size)
1892                         return 1;
1893         }
1894         return 0;
1895 }
1896
1897 static int isapnp_valid_mem(struct isapnp_cfgtmp *cfg, int idx)
1898 {
1899         int err;
1900         unsigned long *value1, *value2;
1901         struct isapnp_mem *mem;
1902
1903         if (!cfg || idx < 0 || idx > 3)
1904                 return -EINVAL;
1905         if (!(cfg->result.resource[idx + 8].flags & IORESOURCE_AUTO)) /* don't touch */
1906                 return 0;
1907       __again:
1908         mem = cfg->mem[idx];
1909         if (!mem)
1910                 return -EINVAL;
1911         value1 = &cfg->result.resource[idx + 8].start;
1912         value2 = &cfg->result.resource[idx + 8].end;
1913         if (cfg->result.resource[idx + 8].flags & IORESOURCE_AUTO) {
1914                 cfg->result.resource[idx + 8].flags &= ~IORESOURCE_AUTO;
1915                 *value1 = mem->min;
1916                 *value2 = mem->min + mem->size - 1;
1917                 if (!isapnp_check_mem(cfg, *value1, mem->size, idx))
1918                         return 0;
1919         }
1920         do {
1921                 *value1 += mem->align;
1922                 *value2 = *value1 + mem->size - 1;
1923                 if (*value1 > mem->max || !mem->align) {
1924                         if (mem->res && mem->res->alt) {
1925                                 if ((err = isapnp_alternative_switch(cfg, mem->res, mem->res->alt))<0)
1926                                         return err;
1927                                 goto __again;
1928                         }
1929                         return -ENOENT;
1930                 }
1931         } while (isapnp_check_mem(cfg, *value1, mem->size, idx));
1932         return 0;
1933 }
1934
1935 static int isapnp_check_valid(struct isapnp_cfgtmp *cfg)
1936 {
1937         int tmp;
1938         
1939         for (tmp = 0; tmp < 8; tmp++)
1940                 if (cfg->result.resource[tmp].flags & IORESOURCE_AUTO)
1941                         return -EAGAIN;
1942         for (tmp = 0; tmp < 2; tmp++)
1943                 if (cfg->result.irq_resource[tmp].flags & IORESOURCE_AUTO)
1944                         return -EAGAIN;
1945         for (tmp = 0; tmp < 2; tmp++)
1946                 if (cfg->result.dma_resource[tmp].flags & IORESOURCE_AUTO)
1947                         return -EAGAIN;
1948         for (tmp = 0; tmp < 4; tmp++)
1949                 if (cfg->result.resource[tmp + 8].flags & IORESOURCE_AUTO)
1950                         return -EAGAIN;
1951         return 0;
1952 }
1953
1954 static int isapnp_config_activate(struct pci_dev *dev)
1955 {
1956         struct isapnp_cfgtmp cfg;
1957         int tmp, fauto, err;
1958         
1959         if (!dev)
1960                 return -EINVAL;
1961         if (dev->active)
1962                 return -EBUSY;
1963         memset(&cfg, 0, sizeof(cfg));
1964         cfg.request = dev;
1965         memcpy(&cfg.result, dev, sizeof(struct pci_dev));
1966         /* check if all values are set, otherwise try auto-configuration */
1967         for (tmp = fauto = 0; !fauto && tmp < 8; tmp++) {
1968                 if (dev->resource[tmp].flags & IORESOURCE_AUTO)
1969                         fauto++;
1970         }
1971         for (tmp = 0; !fauto && tmp < 2; tmp++) {
1972                 if (dev->irq_resource[tmp].flags & IORESOURCE_AUTO)
1973                         fauto++;
1974         }
1975         for (tmp = 0; !fauto && tmp < 2; tmp++) {
1976                 if (dev->dma_resource[tmp].flags & IORESOURCE_AUTO)
1977                         fauto++;
1978         }
1979         for (tmp = 0; !fauto && tmp < 4; tmp++) {
1980                 if (dev->resource[tmp + 8].flags & IORESOURCE_AUTO)
1981                         fauto++;
1982         }
1983         if (!fauto)
1984                 goto __skip_auto;
1985         /* set variables to initial values */
1986         if ((err = isapnp_alternative_switch(&cfg, NULL, NULL))<0)
1987                 return err;
1988         /* find first valid configuration */
1989         fauto = 0;
1990         do {
1991                 for (tmp = 0; tmp < 8 && cfg.result.resource[tmp].flags; tmp++)
1992                         if ((err = isapnp_valid_port(&cfg, tmp))<0)
1993                                 return err;
1994                 for (tmp = 0; tmp < 2 && cfg.result.irq_resource[tmp].flags; tmp++)
1995                         if ((err = isapnp_valid_irq(&cfg, tmp))<0)
1996                                 return err;
1997                 for (tmp = 0; tmp < 2 && cfg.result.dma_resource[tmp].flags; tmp++)
1998                         if ((err = isapnp_valid_dma(&cfg, tmp))<0)
1999                                 return err;
2000                 for (tmp = 0; tmp < 4 && cfg.result.resource[tmp + 8].flags; tmp++)
2001                         if ((err = isapnp_valid_mem(&cfg, tmp))<0)
2002                                 return err;
2003         } while (isapnp_check_valid(&cfg)<0 && fauto++ < 20);
2004         if (fauto >= 20)
2005                 return -EAGAIN;
2006       __skip_auto:
2007         /* we have valid configuration, try configure hardware */
2008         isapnp_cfg_begin(dev->bus->number, dev->devfn);
2009         dev->active = 1;
2010         dev->irq_resource[0] = cfg.result.irq_resource[0];
2011         dev->irq_resource[1] = cfg.result.irq_resource[1];
2012         dev->dma_resource[0] = cfg.result.dma_resource[0];
2013         dev->dma_resource[1] = cfg.result.dma_resource[1];
2014         for (tmp = 0; tmp < 12; tmp++) {
2015                 dev->resource[tmp] = cfg.result.resource[tmp];
2016         }       
2017         for (tmp = 0; tmp < 8 && dev->resource[tmp].flags; tmp++)
2018                 isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), dev->resource[tmp].start);
2019         for (tmp = 0; tmp < 2 && dev->irq_resource[tmp].flags; tmp++) {
2020                 int irq = dev->irq_resource[tmp].start;
2021                 if (irq == 2)
2022                         irq = 9;
2023                 isapnp_write_byte(ISAPNP_CFG_IRQ+(tmp<<1), irq);
2024         }
2025         for (tmp = 0; tmp < 2 && dev->dma_resource[tmp].flags; tmp++)
2026                 isapnp_write_byte(ISAPNP_CFG_DMA+tmp, dev->dma_resource[tmp].start);
2027         for (tmp = 0; tmp < 4 && dev->resource[tmp+8].flags; tmp++)
2028                 isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (dev->resource[tmp + 8].start >> 8) & 0xffff);
2029         isapnp_activate(dev->devfn);
2030         isapnp_cfg_end();
2031         return 0;
2032 }
2033
2034 static int isapnp_config_deactivate(struct pci_dev *dev)
2035 {
2036         if (!dev || !dev->active)
2037                 return -EINVAL;
2038         isapnp_cfg_begin(dev->bus->number, dev->devfn);
2039         isapnp_deactivate(dev->devfn);
2040         dev->active = 0;
2041         isapnp_cfg_end();
2042         return 0;
2043 }
2044
2045 void isapnp_resource_change(struct resource *resource,
2046                             unsigned long start,
2047                             unsigned long size)
2048 {
2049         if (resource == NULL)
2050                 return;
2051         resource->flags &= ~IORESOURCE_AUTO;
2052         resource->start = start;
2053         resource->end = start + size - 1;
2054 }
2055
2056 /*
2057  *  Inititialization.
2058  */
2059
2060 #ifdef MODULE
2061
2062 static void isapnp_free_port(struct isapnp_port *port)
2063 {
2064         struct isapnp_port *next;
2065
2066         while (port) {
2067                 next = port->next;
2068                 kfree(port);
2069                 port = next;
2070         }
2071 }
2072
2073 static void isapnp_free_irq(struct isapnp_irq *irq)
2074 {
2075         struct isapnp_irq *next;
2076
2077         while (irq) {
2078                 next = irq->next;
2079                 kfree(irq);
2080                 irq = next;
2081         }
2082 }
2083
2084 static void isapnp_free_dma(struct isapnp_dma *dma)
2085 {
2086         struct isapnp_dma *next;
2087
2088         while (dma) {
2089                 next = dma->next;
2090                 kfree(dma);
2091                 dma = next;
2092         }
2093 }
2094
2095 static void isapnp_free_mem(struct isapnp_mem *mem)
2096 {
2097         struct isapnp_mem *next;
2098
2099         while (mem) {
2100                 next = mem->next;
2101                 kfree(mem);
2102                 mem = next;
2103         }
2104 }
2105
2106 static void isapnp_free_mem32(struct isapnp_mem32 *mem32)
2107 {
2108         struct isapnp_mem32 *next;
2109
2110         while (mem32) {
2111                 next = mem32->next;
2112                 kfree(mem32);
2113                 mem32 = next;
2114         }
2115 }
2116
2117 static void isapnp_free_resources(struct isapnp_resources *resources, int alt)
2118 {
2119         struct isapnp_resources *next;
2120
2121         while (resources) {
2122                 next = alt ? resources->alt : resources->next;
2123                 isapnp_free_port(resources->port);
2124                 isapnp_free_irq(resources->irq);
2125                 isapnp_free_dma(resources->dma);
2126                 isapnp_free_mem(resources->mem);
2127                 isapnp_free_mem32(resources->mem32);
2128                 if (!alt && resources->alt)
2129                         isapnp_free_resources(resources->alt, 1);
2130                 kfree(resources);
2131                 resources = next;
2132         }
2133 }
2134
2135 static void isapnp_free_card(struct pci_bus *card)
2136 {
2137         while (!list_empty(&card->devices)) {
2138                 struct list_head *list = card->devices.next;
2139                 struct pci_dev *dev = pci_dev_b(list);
2140                 list_del(list);
2141                 isapnp_free_resources((struct isapnp_resources *)dev->sysdata, 0);
2142                 kfree(dev);
2143         }
2144         kfree(card);
2145 }
2146
2147 static void isapnp_free_all_resources(void)
2148 {
2149 #ifdef ISAPNP_REGION_OK
2150         release_region(_PIDXR, 1);
2151 #endif
2152         release_region(_PNPWRP, 1);
2153         release_region(isapnp_rdp, 1);
2154 #ifdef CONFIG_PROC_FS
2155         isapnp_proc_done();
2156 #endif
2157         while (!list_empty(&isapnp_cards)) {
2158                 struct list_head *list = isapnp_cards.next;
2159                 list_del(list);
2160                 isapnp_free_card(pci_bus_b(list));
2161         }
2162 }
2163
2164 #endif /* MODULE */
2165
2166 static int isapnp_announce_device(struct isapnp_driver *drv, 
2167                                   struct pci_dev *dev)
2168 {
2169         const struct isapnp_device_id *id;
2170         int ret = 0;
2171
2172         if (drv->id_table) {
2173                 id = isapnp_match_dev(drv->id_table, dev);
2174                 if (!id) {
2175                         ret = 0;
2176                         goto out;
2177                 }
2178         } else
2179                 id = NULL;
2180
2181         if (drv->probe(dev, id) >= 0) {
2182                 dev->driver = (struct pci_driver *) drv;
2183                 ret = 1;
2184         }
2185 out:
2186         return ret;
2187 }
2188
2189 /**
2190  * isapnp_dev_driver - get the isapnp_driver of a device
2191  * @dev: the device to query
2192  *
2193  * Returns the appropriate isapnp_driver structure or %NULL if there is no 
2194  * registered driver for the device.
2195  */
2196 static struct isapnp_driver *isapnp_dev_driver(const struct pci_dev *dev)
2197 {
2198         return (struct isapnp_driver *) dev->driver;
2199 }
2200
2201 static LIST_HEAD(isapnp_drivers);
2202
2203 /**
2204  * isapnp_register_driver - register a new ISAPnP driver
2205  * @drv: the driver structure to register
2206  * 
2207  * Adds the driver structure to the list of registered ISAPnP drivers
2208  * Returns the number of isapnp devices which were claimed by the driver
2209  * during registration.  The driver remains registered even if the
2210  * return value is zero.
2211  */
2212 int isapnp_register_driver(struct isapnp_driver *drv)
2213 {
2214         struct pci_dev *dev;
2215         int count = 0;
2216
2217         list_add_tail(&drv->node, &isapnp_drivers);
2218
2219         isapnp_for_each_dev(dev) {
2220                 if (!isapnp_dev_driver(dev))
2221                         count += isapnp_announce_device(drv, dev);
2222         }
2223         return count;
2224 }
2225
2226 /**
2227  * isapnp_unregister_driver - unregister an isapnp driver
2228  * @drv: the driver structure to unregister
2229  * 
2230  * Deletes the driver structure from the list of registered ISAPnP drivers,
2231  * gives it a chance to clean up by calling its remove() function for
2232  * each device it was responsible for, and marks those devices as
2233  * driverless.
2234  */
2235 void isapnp_unregister_driver(struct isapnp_driver *drv)
2236 {
2237         struct pci_dev *dev;
2238
2239         list_del(&drv->node);
2240         isapnp_for_each_dev(dev) {
2241                 if (dev->driver == (struct pci_driver *) drv) {
2242                         if (drv->remove)
2243                                 drv->remove(dev);
2244                         dev->driver = NULL;
2245                 }
2246         }
2247 }
2248
2249 EXPORT_SYMBOL(isapnp_cards);
2250 EXPORT_SYMBOL(isapnp_devices);
2251 EXPORT_SYMBOL(isapnp_present);
2252 EXPORT_SYMBOL(isapnp_cfg_begin);
2253 EXPORT_SYMBOL(isapnp_cfg_end);
2254 EXPORT_SYMBOL(isapnp_read_byte);
2255 EXPORT_SYMBOL(isapnp_read_word);
2256 EXPORT_SYMBOL(isapnp_read_dword);
2257 EXPORT_SYMBOL(isapnp_write_byte);
2258 EXPORT_SYMBOL(isapnp_write_word);
2259 EXPORT_SYMBOL(isapnp_write_dword);
2260 EXPORT_SYMBOL(isapnp_wake);
2261 EXPORT_SYMBOL(isapnp_device);
2262 EXPORT_SYMBOL(isapnp_activate);
2263 EXPORT_SYMBOL(isapnp_deactivate);
2264 EXPORT_SYMBOL(isapnp_find_card);
2265 EXPORT_SYMBOL(isapnp_find_dev);
2266 EXPORT_SYMBOL(isapnp_probe_cards);
2267 EXPORT_SYMBOL(isapnp_probe_devs);
2268 EXPORT_SYMBOL(isapnp_activate_dev);
2269 EXPORT_SYMBOL(isapnp_resource_change);
2270 EXPORT_SYMBOL(isapnp_register_driver);
2271 EXPORT_SYMBOL(isapnp_unregister_driver);
2272
2273 int __init isapnp_init(void)
2274 {
2275         int cards;
2276         struct pci_bus *card;
2277
2278         if (isapnp_disable) {
2279                 isapnp_detected = 0;
2280                 printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n");
2281                 return 0;
2282         }
2283 #ifdef ISAPNP_REGION_OK
2284         if (!request_region(_PIDXR, 1, "isapnp index")) {
2285                 printk(KERN_ERR "isapnp: Index Register 0x%x already used\n", _PIDXR);
2286                 return -EBUSY;
2287         }
2288 #endif
2289         if (!request_region(_PNPWRP, 1, "isapnp write")) {
2290                 printk(KERN_ERR "isapnp: Write Data Register 0x%x already used\n", _PNPWRP);
2291 #ifdef ISAPNP_REGION_OK
2292                 release_region(_PIDXR, 1);
2293 #endif
2294                 return -EBUSY;
2295         }
2296         
2297         /*
2298          *      Print a message. The existing ISAPnP code is hanging machines
2299          *      so let the user know where.
2300          */
2301          
2302         printk(KERN_INFO "isapnp: Scanning for PnP cards...\n");
2303         if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {
2304                 isapnp_rdp |= 3;
2305                 if (!request_region(isapnp_rdp, 1, "isapnp read")) {
2306                         printk(KERN_ERR "isapnp: Read Data Register 0x%x already used\n", isapnp_rdp);
2307 #ifdef ISAPNP_REGION_OK
2308                         release_region(_PIDXR, 1);
2309 #endif
2310                         release_region(_PNPWRP, 1);
2311                         return -EBUSY;
2312                 }
2313                 isapnp_set_rdp();
2314         }
2315         isapnp_detected = 1;
2316         if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) {
2317                 cards = isapnp_isolate();
2318                 if (cards < 0 || 
2319                     (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {
2320 #ifdef ISAPNP_REGION_OK
2321                         release_region(_PIDXR, 1);
2322 #endif
2323                         release_region(_PNPWRP, 1);
2324                         isapnp_detected = 0;
2325                         printk(KERN_INFO "isapnp: No Plug & Play device found\n");
2326                         return 0;
2327                 }
2328                 request_region(isapnp_rdp, 1, "isapnp read");
2329         }
2330         isapnp_build_device_list();
2331         cards = 0;
2332
2333         isapnp_for_each_card(card) {
2334                 cards++;
2335                 if (isapnp_verbose) {
2336                         struct list_head *devlist;
2337                         printk(KERN_INFO "isapnp: Card '%s'\n", card->name[0]?card->name:"Unknown");
2338                         if (isapnp_verbose < 2)
2339                                 continue;
2340                         for (devlist = card->devices.next; devlist != &card->devices; devlist = devlist->next) {
2341                                 struct pci_dev *dev = pci_dev_b(devlist);
2342                                 printk(KERN_INFO "isapnp:   Device '%s'\n", dev->name[0]?card->name:"Unknown");
2343                         }
2344                 }
2345         }
2346         if (cards) {
2347                 printk(KERN_INFO "isapnp: %i Plug & Play card%s detected total\n", cards, cards>1?"s":"");
2348         } else {
2349                 printk(KERN_INFO "isapnp: No Plug & Play card found\n");
2350         }
2351 #ifdef CONFIG_PROC_FS
2352         isapnp_proc_init();
2353 #endif
2354         return 0;
2355 }
2356
2357 #ifdef MODULE
2358
2359 int init_module(void)
2360 {
2361         return isapnp_init();
2362 }
2363
2364 void cleanup_module(void)
2365 {
2366         if (isapnp_detected)
2367                 isapnp_free_all_resources();
2368 }
2369
2370 #else
2371
2372 /* format is: noisapnp */
2373
2374 static int __init isapnp_setup_disable(char *str)
2375 {
2376         isapnp_disable = 1;
2377         return 1;
2378 }
2379
2380 __setup("noisapnp", isapnp_setup_disable);
2381
2382 /* format is: isapnp=rdp,reset,skip_pci_scan,verbose */
2383
2384 static int __init isapnp_setup_isapnp(char *str)
2385 {
2386         (void)((get_option(&str,&isapnp_rdp) == 2) &&
2387                (get_option(&str,&isapnp_reset) == 2) &&
2388                (get_option(&str,&isapnp_skip_pci_scan) == 2) &&
2389                (get_option(&str,&isapnp_verbose) == 2));
2390         return 1;
2391 }
2392
2393 __setup("isapnp=", isapnp_setup_isapnp);
2394
2395 /* format is: isapnp_reserve_irq=irq1[,irq2] .... */
2396
2397 static int __init isapnp_setup_reserve_irq(char *str)
2398 {
2399         int i;
2400
2401         for (i = 0; i < 16; i++)
2402                 if (get_option(&str,&isapnp_reserve_irq[i]) != 2)
2403                         break;
2404         return 1;
2405 }
2406
2407 __setup("isapnp_reserve_irq=", isapnp_setup_reserve_irq);
2408
2409 /* format is: isapnp_reserve_dma=dma1[,dma2] .... */
2410
2411 static int __init isapnp_setup_reserve_dma(char *str)
2412 {
2413         int i;
2414
2415         for (i = 0; i < 8; i++)
2416                 if (get_option(&str,&isapnp_reserve_dma[i]) != 2)
2417                         break;
2418         return 1;
2419 }
2420
2421 __setup("isapnp_reserve_dma=", isapnp_setup_reserve_dma);
2422
2423 /* format is: isapnp_reserve_io=io1,size1[,io2,size2] .... */
2424
2425 static int __init isapnp_setup_reserve_io(char *str)
2426 {
2427         int i;
2428
2429         for (i = 0; i < 16; i++)
2430                 if (get_option(&str,&isapnp_reserve_io[i]) != 2)
2431                         break;
2432         return 1;
2433 }
2434
2435 __setup("isapnp_reserve_io=", isapnp_setup_reserve_io);
2436
2437 /* format is: isapnp_reserve_mem=mem1,size1[,mem2,size2] .... */
2438
2439 static int __init isapnp_setup_reserve_mem(char *str)
2440 {
2441         int i;
2442
2443         for (i = 0; i < 16; i++)
2444                 if (get_option(&str,&isapnp_reserve_mem[i]) != 2)
2445                         break;
2446         return 1;
2447 }
2448
2449 __setup("isapnp_reserve_mem=", isapnp_setup_reserve_mem);
2450
2451 #endif