]> git.pld-linux.org Git - packages/kernel.git/blob - acpi-irq-fixes.patch
- License is GPL v2
[packages/kernel.git] / acpi-irq-fixes.patch
1
2 From: Andrew de Quincey <adq_dvb@lidskialf.net>
3
4 Hi, this is my next round of ACPI IRQ fixes.  Attached are patches for
5 linux-2.4.23-pre3 and linux-2.6.0-test4.
6
7 Please CC me on any replies.  I seem to be having issues with
8 vger.kernel.org right now.
9
10 This patch addresses the following issues:
11
12 1) ACPI now drops back to PIC mode if configuration in APIC mode fails.
13
14 2) Removed 2 lines of erroneous code in mpparse.c which causes
15    IO-APICs to be misconfigured.
16
17 3) ACPI now supports PIC controllers properly.
18
19 4) This patch includes a patch by "Jun Nakajima"
20    <jun.nakajima@intel.com> which fixes ACPI IRQ routing for all VIA
21    motherboards I have had tested so far.  I've included it in this
22    patch as it changes one of the same files.
23
24 5) Now retries with an extended IRQ descriptor if programming a link
25    device with a "standard" IRQ descriptor fails.
26
27 This has already been tested successfully by multiple people.
28
29
30
31  arch/i386/kernel/acpi/Makefile   |    2 
32  arch/i386/kernel/acpi/pic.c      |  102 ++++++++++++++++++
33  arch/i386/kernel/mpparse.c       |   27 ++++
34  arch/ia64/kernel/iosapic.c       |   19 +++
35  arch/x86_64/kernel/acpi/Makefile |    2 
36  arch/x86_64/kernel/acpi/pic.c    |  102 ++++++++++++++++++
37  arch/x86_64/kernel/mpparse.c     |   22 +++
38  drivers/acpi/bus.c               |    2 
39  drivers/acpi/pci_irq.c           |  218 +++++++++++++++++++++++++++++----------
40  drivers/acpi/pci_link.c          |   89 ++++++++++++---
41  include/acpi/acpi_bus.h          |    2 
42  include/acpi/acpi_drivers.h      |    8 +
43  include/asm-i386/acpi.h          |    3 
44  include/asm-i386/mpspec.h        |    2 
45  include/asm-ia64/acpi.h          |    3 
46  include/asm-ia64/iosapic.h       |    2 
47  include/asm-x86_64/acpi.h        |    3 
48  include/asm-x86_64/mpspec.h      |    2 
49  include/linux/acpi.h             |    2 
50  19 files changed, 522 insertions(+), 90 deletions(-)
51
52 diff -puN arch/i386/kernel/acpi/Makefile~acpi-irq-fixes arch/i386/kernel/acpi/Makefile
53 --- 25/arch/i386/kernel/acpi/Makefile~acpi-irq-fixes    2003-09-06 19:47:12.000000000 -0700
54 +++ 25-akpm/arch/i386/kernel/acpi/Makefile      2003-09-06 19:47:12.000000000 -0700
55 @@ -1,3 +1,3 @@
56 -obj-$(CONFIG_ACPI_BOOT)                := boot.o
57 +obj-$(CONFIG_ACPI_BOOT)                := boot.o pic.o
58  obj-$(CONFIG_ACPI_SLEEP)       += sleep.o wakeup.o
59  
60 diff -puN /dev/null arch/i386/kernel/acpi/pic.c
61 --- /dev/null   2002-08-30 16:31:37.000000000 -0700
62 +++ 25-akpm/arch/i386/kernel/acpi/pic.c 2003-09-06 19:47:12.000000000 -0700
63 @@ -0,0 +1,102 @@
64 +/* ----------------------------------------------------------------------- *
65 + *
66 + *   Copyright 2003 Andrew de Quincey - All Rights Reserved
67 + *
68 + *   This program is free software; you can redistribute it and/or modify
69 + *   it under the terms of the GNU General Public License as published by
70 + *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
71 + *   USA; either version 2 of the License, or (at your option) any later
72 + *   version; incorporated herein by reference.
73 + *
74 + * ----------------------------------------------------------------------- */
75 +
76 +#include <linux/mm.h>
77 +#include <linux/irq.h>
78 +#include <linux/init.h>
79 +#include <linux/acpi.h>
80 +#include <linux/delay.h>
81 +#include <linux/config.h>
82 +#include <linux/bootmem.h>
83 +#include <linux/smp_lock.h>
84 +#include <linux/kernel_stat.h>
85 +
86 +#include <asm/acpi.h>
87 +
88 +#ifdef CONFIG_ACPI_PCI
89 +
90 +extern void eisa_set_level_irq(unsigned int irq);
91 +
92 +int __init pic_parse_prt (void)
93 +{
94 +       struct list_head        *node = NULL;
95 +       struct acpi_prt_entry   *entry = NULL;
96 +       struct acpi_prt_list    *prt_list = NULL;
97 +       int                     edge_level = 0;
98 +       int                     active_high_low = 0;
99 +       int                     irq = 0;
100 +       int                     programmed[16];
101 +
102 +       /* Get the current PRT */
103 +       prt_list = acpi_pci_get_prt_list();
104 +
105 +       if (!prt_list->count) {
106 +               acpi_pci_destroy_prt_list(prt_list);
107 +               printk(KERN_WARNING PREFIX "ACPI tables contain no PIC PCI IRQ "
108 +                       "routing entries\n");
109 +               return_VALUE(-ENODEV);
110 +       }
111 +
112 +       /* mark all IRQs as unprogrammed */
113 +       memset(programmed, 0, sizeof(programmed));
114 +
115 +       /*
116 +        * Parsing through the PCI Interrupt Routing Table (PRT) and program
117 +        * IRQs if necessary.
118 +        */
119 +       list_for_each(node, &prt_list->entries) {
120 +               entry = list_entry(node, struct acpi_prt_entry, node);
121 +
122 +               /* Need to get irq for dynamic entry */
123 +               if (entry->link.handle) {
124 +                       irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
125 +                       if (irq < 0) {
126 +                               acpi_pci_destroy_prt_list(prt_list);
127 +                               return -ENODEV;
128 +                       }
129 +                       if (!irq)
130 +                               continue;
131 +               }
132 +
133 +               /* sanity check + update entry */
134 +               if ((irq < 0) || (irq > 15)) {
135 +                       printk(KERN_ERR "Invalid IRQ (%i) passed to PIC programming code\n", irq);
136 +                       entry->irq = 0;
137 +                       continue;
138 +               }
139 +               entry->irq = irq;
140 +
141 +               /* check if it has already been dealt with */
142 +               if (programmed[irq]) {
143 +                       printk(KERN_DEBUG "PIC: IRQ (%i) already programmed\n", irq);
144 +                       continue;
145 +               }
146 +               programmed[irq] = 1;
147 +
148 +               /* program it */
149 +               if (edge_level) {
150 +                       eisa_set_level_irq(irq);
151 +               }
152 +
153 +               printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> IRQ %d Mode %d Trigger %d\n",
154 +                       entry->id.segment, entry->id.bus,
155 +                       entry->id.device, ('A' + entry->pin),
156 +                       entry->irq, edge_level, active_high_low);
157 +       }
158 +
159 +       /* if we get here, the PRT was fine. commit it */
160 +       acpi_pci_commit_prt_list(prt_list);
161 +
162 +       return 0;
163 +}
164 +
165 +#endif /*CONFIG_ACPI_PCI*/
166 diff -puN arch/i386/kernel/mpparse.c~acpi-irq-fixes arch/i386/kernel/mpparse.c
167 --- 25/arch/i386/kernel/mpparse.c~acpi-irq-fixes        2003-09-06 19:47:12.000000000 -0700
168 +++ 25-akpm/arch/i386/kernel/mpparse.c  2003-09-06 19:47:12.000000000 -0700
169 @@ -1073,10 +1073,11 @@ void __init mp_config_ioapic_for_sci(int
170  
171  #ifdef CONFIG_ACPI_PCI
172  
173 -void __init mp_parse_prt (void)
174 +int __init mp_parse_prt (void)
175  {
176         struct list_head        *node = NULL;
177         struct acpi_prt_entry   *entry = NULL;
178 +       struct acpi_prt_list    *prt_list = NULL;
179         int                     ioapic = -1;
180         int                     ioapic_pin = 0;
181         int                     irq = 0;
182 @@ -1084,16 +1085,31 @@ void __init mp_parse_prt (void)
183         int                     edge_level = 0;
184         int                     active_high_low = 0;
185  
186 +       /* Get the current PRT */
187 +       prt_list = acpi_pci_get_prt_list();
188 +
189 +       if (!prt_list->count) {
190 +               acpi_pci_destroy_prt_list(prt_list);
191 +               printk(KERN_WARNING PREFIX "ACPI tables contain no IO-APIC PCI IRQ "
192 +                       "routing entries\n");
193 +               return_VALUE(-ENODEV);
194 +       }
195 +
196         /*
197          * Parsing through the PCI Interrupt Routing Table (PRT) and program
198          * routing for all entries.
199          */
200 -       list_for_each(node, &acpi_prt.entries) {
201 +       list_for_each(node, &prt_list->entries) {
202                 entry = list_entry(node, struct acpi_prt_entry, node);
203  
204                 /* Need to get irq for dynamic entry */
205                 if (entry->link.handle) {
206                         irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
207 +                       if (irq < 0) {
208 +                               acpi_pci_destroy_prt_list(prt_list);
209 +                               return -ENODEV;
210 +                       }
211 +
212                         if (!irq)
213                                 continue;
214                 }
215 @@ -1113,8 +1129,6 @@ void __init mp_parse_prt (void)
216                         continue;
217                 ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
218  
219 -               if (!ioapic && (irq < 16))
220 -                       irq += 16;
221                 /* 
222                  * Avoid pin reprogramming.  PRTs typically include entries  
223                  * with redundant pin->irq mappings (but unique PCI devices);
224 @@ -1146,6 +1160,11 @@ void __init mp_parse_prt (void)
225                         mp_ioapic_routing[ioapic].apic_id, ioapic_pin, 
226                         entry->irq);
227         }
228 +
229 +       /* if we get here, the PRT was fine. commit it */
230 +       acpi_pci_commit_prt_list(prt_list);
231 +
232 +       return 0;
233  }
234  
235  #endif /*CONFIG_ACPI_PCI*/
236 diff -puN arch/ia64/kernel/iosapic.c~acpi-irq-fixes arch/ia64/kernel/iosapic.c
237 --- 25/arch/ia64/kernel/iosapic.c~acpi-irq-fixes        2003-09-06 19:47:12.000000000 -0700
238 +++ 25-akpm/arch/ia64/kernel/iosapic.c  2003-09-06 19:47:12.000000000 -0700
239 @@ -680,7 +680,7 @@ iosapic_enable_intr (unsigned int vector
240  
241  #ifdef CONFIG_ACPI_PCI
242  
243 -void __init
244 +int __init
245  iosapic_parse_prt (void)
246  {
247         struct acpi_prt_entry *entry;
248 @@ -690,8 +690,19 @@ iosapic_parse_prt (void)
249         char pci_id[16];
250         struct hw_interrupt_type *irq_type = &irq_type_iosapic_level;
251         irq_desc_t *idesc;
252 +       struct acpi_prt_list    *prt_list = NULL;
253  
254 -       list_for_each(node, &acpi_prt.entries) {
255 +       /* Get the current PRT */
256 +       prt_list = acpi_pci_get_prt_list();
257 +
258 +       if (!prt_list->count) {
259 +               acpi_pci_destroy_prt_list(prt_list);
260 +               printk(KERN_WARNING PREFIX "ACPI tables contain no IO-APIC PCI IRQ "
261 +                       "routing entries\n");
262 +               return_VALUE(-ENODEV);
263 +       }
264 +
265 +       list_for_each(node, &prt_list->entries) {
266                 entry = list_entry(node, struct acpi_prt_entry, node);
267  
268                 /* We're only interested in static (non-link) entries.  */
269 @@ -729,6 +740,10 @@ iosapic_parse_prt (void)
270                                       IOSAPIC_LEVEL);
271  
272         }
273 +
274 +       /* if we get here, the PRT was fine. commit it */
275 +       acpi_pci_commit_prt_list(prt_list);
276 +       return 0;
277  }
278  
279  #endif /* CONFIG_ACPI */
280 diff -puN arch/x86_64/kernel/acpi/Makefile~acpi-irq-fixes arch/x86_64/kernel/acpi/Makefile
281 --- 25/arch/x86_64/kernel/acpi/Makefile~acpi-irq-fixes  2003-09-06 19:47:12.000000000 -0700
282 +++ 25-akpm/arch/x86_64/kernel/acpi/Makefile    2003-09-06 19:47:12.000000000 -0700
283 @@ -1,3 +1,3 @@
284 -obj-$(CONFIG_ACPI_BOOT)                := boot.o
285 +obj-$(CONFIG_ACPI_BOOT)                := boot.o pic.o
286  obj-$(CONFIG_ACPI_SLEEP)       += sleep.o wakeup.o
287  
288 diff -puN /dev/null arch/x86_64/kernel/acpi/pic.c
289 --- /dev/null   2002-08-30 16:31:37.000000000 -0700
290 +++ 25-akpm/arch/x86_64/kernel/acpi/pic.c       2003-09-06 19:47:12.000000000 -0700
291 @@ -0,0 +1,102 @@
292 +/* ----------------------------------------------------------------------- *
293 + *
294 + *   Copyright 2003 Andrew de Quincey - All Rights Reserved
295 + *
296 + *   This program is free software; you can redistribute it and/or modify
297 + *   it under the terms of the GNU General Public License as published by
298 + *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
299 + *   USA; either version 2 of the License, or (at your option) any later
300 + *   version; incorporated herein by reference.
301 + *
302 + * ----------------------------------------------------------------------- */
303 +
304 +#include <linux/mm.h>
305 +#include <linux/irq.h>
306 +#include <linux/init.h>
307 +#include <linux/acpi.h>
308 +#include <linux/delay.h>
309 +#include <linux/config.h>
310 +#include <linux/bootmem.h>
311 +#include <linux/smp_lock.h>
312 +#include <linux/kernel_stat.h>
313 +
314 +#include <asm/acpi.h>
315 +
316 +#ifdef CONFIG_ACPI_PCI
317 +
318 +extern void eisa_set_level_irq(unsigned int irq);
319 +
320 +int __init pic_parse_prt (void)
321 +{
322 +       struct list_head        *node = NULL;
323 +       struct acpi_prt_entry   *entry = NULL;
324 +       struct acpi_prt_list    *prt_list = NULL;
325 +       int                     edge_level = 0;
326 +       int                     active_high_low = 0;
327 +       int                     irq = 0;
328 +       int                     programmed[16];
329 +
330 +       /* Get the current PRT */
331 +       prt_list = acpi_pci_get_prt_list();
332 +
333 +       if (!prt_list->count) {
334 +               acpi_pci_destroy_prt_list(prt_list);
335 +               printk(KERN_WARNING PREFIX "ACPI tables contain no PIC PCI IRQ "
336 +                       "routing entries\n");
337 +               return_VALUE(-ENODEV);
338 +       }
339 +
340 +       /* mark all IRQs as unprogrammed */
341 +       memset(programmed, 0, sizeof(programmed));
342 +
343 +       /*
344 +        * Parsing through the PCI Interrupt Routing Table (PRT) and program
345 +        * IRQs if necessary.
346 +        */
347 +       list_for_each(node, &prt_list->entries) {
348 +               entry = list_entry(node, struct acpi_prt_entry, node);
349 +
350 +               /* Need to get irq for dynamic entry */
351 +               if (entry->link.handle) {
352 +                       irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
353 +                       if (irq < 0) {
354 +                               acpi_pci_destroy_prt_list(prt_list);
355 +                               return -ENODEV;
356 +                       }
357 +                       if (!irq)
358 +                               continue;
359 +               }
360 +
361 +               /* sanity check + update entry */
362 +               if ((irq < 0) || (irq > 15)) {
363 +                       printk(KERN_ERR "Invalid IRQ (%i) passed to PIC programming code\n", irq);
364 +                       entry->irq = 0;
365 +                       continue;
366 +               }
367 +               entry->irq = irq;
368 +
369 +               /* check if it has already been dealt with */
370 +               if (programmed[irq]) {
371 +                       printk(KERN_DEBUG "PIC: IRQ (%i) already programmed\n", irq);
372 +                       continue;
373 +               }
374 +               programmed[irq] = 1;
375 +
376 +               /* program it */
377 +               if (edge_level) {
378 +                       eisa_set_level_irq(irq);
379 +               }
380 +
381 +               printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> IRQ %d Mode %d Trigger %d\n",
382 +                       entry->id.segment, entry->id.bus,
383 +                       entry->id.device, ('A' + entry->pin),
384 +                       entry->irq, edge_level, active_high_low);
385 +       }
386 +
387 +       /* if we get here, the PRT was fine. commit it */
388 +       acpi_pci_commit_prt_list(prt_list);
389 +
390 +       return 0;
391 +}
392 +
393 +#endif /*CONFIG_ACPI_PCI*/
394 diff -puN arch/x86_64/kernel/mpparse.c~acpi-irq-fixes arch/x86_64/kernel/mpparse.c
395 --- 25/arch/x86_64/kernel/mpparse.c~acpi-irq-fixes      2003-09-06 19:47:12.000000000 -0700
396 +++ 25-akpm/arch/x86_64/kernel/mpparse.c        2003-09-06 19:47:12.000000000 -0700
397 @@ -889,16 +889,31 @@ void __init mp_parse_prt (void)
398         int                     edge_level = 0;
399         int                     active_high_low = 0;
400  
401 +       /* Get the current PRT */
402 +       prt_list = acpi_pci_get_prt_list();
403 +
404 +       if (!prt_list->count) {
405 +               acpi_pci_destroy_prt_list(prt_list);
406 +               printk(KERN_WARNING PREFIX "ACPI tables contain no IO-APIC PCI IRQ "
407 +                       "routing entries\n");
408 +               return_VALUE(-ENODEV);
409 +       }
410 +
411         /*
412          * Parsing through the PCI Interrupt Routing Table (PRT) and program
413          * routing for all static (IOAPIC-direct) entries.
414          */
415 -       list_for_each(node, &acpi_prt.entries) {
416 +       list_for_each(node, &acpi_prt->entries) {
417                 entry = list_entry(node, struct acpi_prt_entry, node);
418  
419                 /* Need to get irq for dynamic entry */
420                 if (entry->link.handle) {
421                         irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
422 +                       if (irq < 0) {
423 +                               acpi_pci_destroy_prt_list(prt_list);
424 +                               return -ENODEV;
425 +                       }
426 +
427                         if (!irq)
428                                 continue;
429                 } else {
430 @@ -949,8 +964,11 @@ void __init mp_parse_prt (void)
431                         mp_ioapic_routing[ioapic].apic_id, ioapic_pin, vector, 
432                         entry->irq);
433         }
434 +
435 +       /* if we get here, the PRT was fine. commit it */
436 +       acpi_pci_commit_prt_list(prt_list);
437         
438 -       return;
439 +       return 0;
440  }
441  
442  #endif /*CONFIG_ACPI_PCI*/
443 diff -puN drivers/acpi/bus.c~acpi-irq-fixes drivers/acpi/bus.c
444 --- 25/drivers/acpi/bus.c~acpi-irq-fixes        2003-09-06 19:47:12.000000000 -0700
445 +++ 25-akpm/drivers/acpi/bus.c  2003-09-06 19:47:12.000000000 -0700
446 @@ -536,7 +536,7 @@ acpi_bus_notify (
447                               Initialization/Cleanup
448     -------------------------------------------------------------------------- */
449  
450 -static int __init
451 +int
452  acpi_bus_init_irq (void)
453  {
454         acpi_status             status = AE_OK;
455 diff -puN drivers/acpi/pci_irq.c~acpi-irq-fixes drivers/acpi/pci_irq.c
456 --- 25/drivers/acpi/pci_irq.c~acpi-irq-fixes    2003-09-06 19:47:12.000000000 -0700
457 +++ 25-akpm/drivers/acpi/pci_irq.c      2003-09-06 19:47:12.000000000 -0700
458 @@ -48,7 +48,22 @@
459  #define _COMPONENT             ACPI_PCI_COMPONENT
460  ACPI_MODULE_NAME               ("pci_irq")
461  
462 -struct acpi_prt_list           acpi_prt;
463 +struct acpi_prt_list*          acpi_prt = NULL;
464 +
465 +struct acpi_prt_ref {
466 +       struct list_head        node;
467 +       struct acpi_device      *device;
468 +       acpi_handle             handle;
469 +       int segment;
470 +       int bus;
471 +};
472 +
473 +struct acpi_prt_ref_list {
474 +       int                     count;
475 +       struct list_head        entries;
476 +};
477 +
478 +struct acpi_prt_ref_list acpi_prt_ref_list;
479  
480  #ifdef CONFIG_X86
481  extern void eisa_set_level_irq(unsigned int irq);
482 @@ -71,13 +86,19 @@ acpi_pci_irq_find_prt_entry (
483  
484         ACPI_FUNCTION_TRACE("acpi_pci_irq_find_prt_entry");
485  
486 +       /* ensure we're not called before the routing table has been determined */
487 +       if (acpi_prt == NULL) {
488 +               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Called before acpi_prt determined"));
489 +               return_PTR(NULL);
490 +       }
491 +
492         /*
493          * Parse through all PRT entries looking for a match on the specified
494          * PCI device's segment, bus, device, and pin (don't care about func).
495          *
496          * TBD: Acquire/release lock
497          */
498 -       list_for_each(node, &acpi_prt.entries) {
499 +       list_for_each(node, &acpi_prt->entries) {
500                 entry = list_entry(node, struct acpi_prt_entry, node);
501                 if ((segment == entry->id.segment) 
502                         && (bus == entry->id.bus) 
503 @@ -93,6 +114,7 @@ acpi_pci_irq_find_prt_entry (
504  
505  static int
506  acpi_pci_irq_add_entry (
507 +       struct acpi_prt_list*           prt_list,
508         acpi_handle                     handle,
509         int                             segment,
510         int                             bus,
511 @@ -149,12 +171,116 @@ acpi_pci_irq_add_entry (
512                 ('A' + entry->pin), prt->source, entry->link.index));
513  
514         /* TBD: Acquire/release lock */
515 -       list_add_tail(&entry->node, &acpi_prt.entries);
516 -       acpi_prt.count++;
517 +       list_add_tail(&entry->node, &prt_list->entries);
518 +       prt_list->count++;
519 +
520 +       return_VALUE(0);
521 +}
522 +
523 +
524 +struct acpi_prt_list*
525 +acpi_pci_get_prt_list (void)
526 +{
527 +       acpi_status                     status = AE_OK;
528 +       struct acpi_buffer              buffer = {0, NULL};
529 +       struct acpi_pci_routing_table   *prt = NULL;
530 +       struct acpi_pci_routing_table   *entry = NULL;
531 +       struct acpi_prt_list            *prt_list = NULL;
532 +       struct acpi_prt_ref             *prt_ref_entry = NULL;
533 +       struct list_head                *node = NULL;
534 +
535 +       ACPI_FUNCTION_TRACE("acpi_pci_irq_get_prt_list");
536 +
537 +       /* Create a brand new acpi_prt_list */
538 +       prt_list = kmalloc(sizeof(struct acpi_prt_list), GFP_KERNEL);
539 +       if (!prt_list)
540 +               return_PTR(NULL);
541 +       memset(prt_list, 0, sizeof(struct acpi_prt_list));
542 +
543 +       prt_list->count = 0;
544 +       INIT_LIST_HEAD(&prt_list->entries);
545 +
546 +       /* iterate over all entries in acpi_prt_ref_list, extracting the current _PRT entries */
547 +       list_for_each(node, &acpi_prt_ref_list.entries) {
548 +               prt_ref_entry = list_entry(node, struct acpi_prt_ref, node);
549 +
550 +               /*
551 +                * Evaluate this _PRT and add its entries to our local list (prt_list).
552 +                */
553 +
554 +               buffer.length = 0;
555 +               buffer.pointer = NULL;
556 +               status = acpi_get_irq_routing_table(prt_ref_entry->handle, &buffer);
557 +               if (status != AE_BUFFER_OVERFLOW) {
558 +                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n",
559 +                               acpi_format_exception(status)));
560 +                       kfree(prt_list);
561 +                       return_PTR(NULL);
562 +               }
563 +
564 +               prt = kmalloc(buffer.length, GFP_KERNEL);
565 +               if (!prt) {
566 +                       kfree(prt_list);
567 +                       return_VALUE(NULL);
568 +               }
569 +               memset(prt, 0, buffer.length);
570 +               buffer.pointer = prt;
571 +
572 +               status = acpi_get_irq_routing_table(prt_ref_entry->handle, &buffer);
573 +               if (ACPI_FAILURE(status)) {
574 +                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n",
575 +                               acpi_format_exception(status)));
576 +                       kfree(buffer.pointer);
577 +                       kfree(prt_list);
578 +                       return_PTR(NULL);
579 +               }
580 +
581 +               entry = prt;
582 +
583 +               while (entry && (entry->length > 0)) {
584 +                       acpi_pci_irq_add_entry(prt_list, prt_ref_entry->handle, prt_ref_entry->segment,
585 +                               prt_ref_entry->bus, entry);
586 +                       entry = (struct acpi_pci_routing_table *)
587 +                               ((unsigned long) entry + entry->length);
588 +               }
589 +
590 +               kfree(prt);
591 +       }
592 +
593 +       return_PTR(prt_list);
594 +}
595 +
596 +int
597 +acpi_pci_destroy_prt_list (struct acpi_prt_list* prt_list) {
598 +       struct list_head        *node = NULL;
599 +       struct list_head        *tmp = NULL;
600 +       struct acpi_prt_entry   *entry = NULL;
601 +
602 +       ACPI_FUNCTION_TRACE("acpi_pci_irq_destroy_prt_list");
603 +
604 +       list_for_each_safe(node, tmp, &prt_list->entries) {
605 +               entry = list_entry(node, struct acpi_prt_entry, node);
606 +               list_del(node);
607 +               kfree(entry);
608 +       }
609 +       kfree(prt_list);
610  
611         return_VALUE(0);
612  }
613  
614 +int
615 +acpi_pci_commit_prt_list (struct acpi_prt_list* prt_list) {
616 +
617 +       ACPI_FUNCTION_TRACE("acpi_pci_irq_commit_prt_list");
618 +
619 +       if (acpi_prt != NULL) {
620 +               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Attempt to commit acpi_prt twice\n"));
621 +               return_VALUE(-ENODEV);
622 +       }
623 +
624 +       acpi_prt = prt_list;
625 +       return_VALUE(0);
626 +}
627  
628  int
629  acpi_pci_irq_add_prt (
630 @@ -162,21 +288,20 @@ acpi_pci_irq_add_prt (
631         int                     segment,
632         int                     bus)
633  {
634 -       acpi_status                     status = AE_OK;
635 -       char                            pathname[ACPI_PATHNAME_MAX] = {0};
636 -       struct acpi_buffer              buffer = {0, NULL};
637 -       struct acpi_pci_routing_table   *prt = NULL;
638 -       struct acpi_pci_routing_table   *entry = NULL;
639 -       static int                      first_time = 1;
640 +       static int              first_time = 1;
641 +       struct acpi_prt_ref     *entry = NULL;
642 +       struct acpi_buffer      buffer = {0, NULL};
643 +       char                    pathname[ACPI_PATHNAME_MAX] = {0};
644  
645         ACPI_FUNCTION_TRACE("acpi_pci_irq_add_prt");
646  
647         if (first_time) {
648 -               acpi_prt.count = 0;
649 -               INIT_LIST_HEAD(&acpi_prt.entries);
650 +               acpi_prt_ref_list.count = 0;
651 +               INIT_LIST_HEAD(&acpi_prt_ref_list.entries);
652                 first_time = 0;
653         }
654  
655 +
656         /* 
657          * NOTE: We're given a 'handle' to the _PRT object's parent device
658          *       (either a PCI root bridge or PCI-PCI bridge).
659 @@ -189,42 +314,19 @@ acpi_pci_irq_add_prt (
660         printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n",
661                 pathname);
662  
663 -       /* 
664 -        * Evaluate this _PRT and add its entries to our global list (acpi_prt).
665 -        */
666  
667 -       buffer.length = 0;
668 -       buffer.pointer = NULL;
669 -       status = acpi_get_irq_routing_table(handle, &buffer);
670 -       if (status != AE_BUFFER_OVERFLOW) {
671 -               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n",
672 -                       acpi_format_exception(status)));
673 -               return_VALUE(-ENODEV);
674 -       }
675  
676 -       prt = kmalloc(buffer.length, GFP_KERNEL);
677 -       if (!prt)
678 +       entry = kmalloc(sizeof(struct acpi_prt_ref), GFP_KERNEL);
679 +       if (!entry)
680                 return_VALUE(-ENOMEM);
681 -       memset(prt, 0, buffer.length);
682 -       buffer.pointer = prt;
683 -
684 -       status = acpi_get_irq_routing_table(handle, &buffer);
685 -       if (ACPI_FAILURE(status)) {
686 -               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n",
687 -                       acpi_format_exception(status)));
688 -               kfree(buffer.pointer);
689 -               return_VALUE(-ENODEV);
690 -       }
691 +       memset(entry, 0, sizeof(struct acpi_prt_ref));
692  
693 -       entry = prt;
694 -
695 -       while (entry && (entry->length > 0)) {
696 -               acpi_pci_irq_add_entry(handle, segment, bus, entry);
697 -               entry = (struct acpi_pci_routing_table *)
698 -                       ((unsigned long) entry + entry->length);
699 -       }
700 +       entry->handle = handle;
701 +       entry->segment = segment;
702 +       entry->bus = bus;
703  
704 -       kfree(prt);
705 +       list_add_tail(&entry->node, &acpi_prt_ref_list.entries);
706 +       acpi_prt_ref_list.count++;
707  
708         return_VALUE(0);
709  }
710 @@ -383,6 +485,14 @@ acpi_pci_irq_enable (
711         return_VALUE(dev->irq);
712  }
713  
714 +static void __init acpi_irq_pic_mode(void)
715 +{
716 +       acpi_irq_model = ACPI_IRQ_MODEL_PIC;
717 +       acpi_bus_init_irq();
718 +
719 +        /* recalculate penalties */
720 +       acpi_pci_link_calc_penalties();
721 +}
722  
723  int __init
724  acpi_pci_irq_init (void)
725 @@ -391,27 +501,27 @@ acpi_pci_irq_init (void)
726  
727         ACPI_FUNCTION_TRACE("acpi_pci_irq_init");
728  
729 -       if (!acpi_prt.count) {
730 -               printk(KERN_WARNING PREFIX "ACPI tables contain no PCI IRQ "
731 -                       "routing entries\n");
732 -               return_VALUE(-ENODEV);
733 -       }
734  
735 -       /* Make sure all link devices have a valid IRQ. */
736 -       if (acpi_pci_link_check()) {
737 -               return_VALUE(-ENODEV);
738 -       }
739 +       /* Calculate IRQ penalties for each link device */
740 +       acpi_pci_link_calc_penalties();
741  
742  #ifdef CONFIG_X86_IO_APIC
743         /* Program IOAPICs using data from PRT entries. */
744         if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
745 -               mp_parse_prt();
746 +               if (mp_parse_prt())
747 +                       acpi_irq_pic_mode();
748  #endif
749  #ifdef CONFIG_IOSAPIC
750         if (acpi_irq_model == ACPI_IRQ_MODEL_IOSAPIC)
751 -               iosapic_parse_prt();
752 +               if (iosapic_parse_prt())
753 +                       return_VALUE(-ENODEV);
754  #endif
755  
756 +       /* This one is last, as a catchall */
757 +       if (acpi_irq_model == ACPI_IRQ_MODEL_PIC)
758 +               if (pic_parse_prt())
759 +                       return_VALUE(-ENODEV);
760 +
761         while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
762                 acpi_pci_irq_enable(dev);
763  
764 diff -puN drivers/acpi/pci_link.c~acpi-irq-fixes drivers/acpi/pci_link.c
765 --- 25/drivers/acpi/pci_link.c~acpi-irq-fixes   2003-09-06 19:47:12.000000000 -0700
766 +++ 25-akpm/drivers/acpi/pci_link.c     2003-09-06 19:47:12.000000000 -0700
767 @@ -281,6 +281,32 @@ end:
768  
769  
770  static int
771 +acpi_pci_link_try_get_current (
772 +       struct acpi_pci_link *link,
773 +       int irq)
774 +{
775 +       int result;
776 +
777 +       ACPI_FUNCTION_TRACE("acpi_pci_link_try_get_current");
778 +
779 +       result = acpi_pci_link_get_current(link);
780 +       if (result && link->irq.active)
781 +       {
782 +               return_VALUE(result);
783 +       }
784 +
785 +       if (!link->irq.active)
786 +       {
787 +               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No active IRQ resource found\n"));
788 +               printk(KERN_WARNING "_CRS returns NULL! Using IRQ %d for device (%s [%s]).\n", irq, acpi_device_name(link->device), acpi_device_bid(link->device));
789 +               link->irq.active = irq;
790 +       }
791 +
792 +       return 0;
793 +}
794 +
795 +
796 +static int
797  acpi_pci_link_set (
798         struct acpi_pci_link    *link,
799         int                     irq)
800 @@ -294,6 +320,7 @@ acpi_pci_link_set (
801         struct acpi_buffer      buffer = {sizeof(resource)+1, &resource};
802         int                     i = 0;
803         int                     valid = 0;
804 +       int                     resource_type = 0;
805  
806         ACPI_FUNCTION_TRACE("acpi_pci_link_set");
807  
808 @@ -317,20 +344,32 @@ acpi_pci_link_set (
809                 }
810         }
811  
812 +       /* If IRQ<=15, first try with a "normal" IRQ descriptor. If that fails, try with
813 +        * an extended one */
814 +       if (irq <= 15) {
815 +               resource_type = ACPI_RSTYPE_IRQ;
816 +       } else {
817 +               resource_type = ACPI_RSTYPE_EXT_IRQ;
818 +       }
819 +
820 +retry_programming:
821 +
822         memset(&resource, 0, sizeof(resource));
823  
824         /* NOTE: PCI interrupts are always level / active_low / shared. But not all
825            interrupts > 15 are PCI interrupts. Rely on the ACPI IRQ definition for 
826            parameters */
827 -       if (irq <= 15) {
828 +       switch(resource_type) {
829 +       case ACPI_RSTYPE_IRQ:
830                 resource.res.id = ACPI_RSTYPE_IRQ;
831                 resource.res.length = sizeof(struct acpi_resource);
832                 resource.res.data.irq.edge_level = link->irq.edge_level;
833                 resource.res.data.irq.active_high_low = link->irq.active_high_low;
834                 resource.res.data.irq.number_of_interrupts = 1;
835                 resource.res.data.irq.interrupts[0] = irq;
836 -       }
837 -       else {
838 +               break;
839 +
840 +       case ACPI_RSTYPE_EXT_IRQ:
841                 resource.res.id = ACPI_RSTYPE_EXT_IRQ;
842                 resource.res.length = sizeof(struct acpi_resource);
843                 resource.res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
844 @@ -339,11 +378,21 @@ acpi_pci_link_set (
845                 resource.res.data.extended_irq.number_of_interrupts = 1;
846                 resource.res.data.extended_irq.interrupts[0] = irq;
847                 /* ignore resource_source, it's optional */
848 +               break;
849         }
850         resource.end.id = ACPI_RSTYPE_END_TAG;
851  
852         /* Attempt to set the resource */
853         status = acpi_set_current_resources(link->handle, &buffer);
854 +
855 +       /* if we failed and IRQ <= 15, try again with an extended descriptor */
856 +       if (ACPI_FAILURE(status) && (resource_type == ACPI_RSTYPE_IRQ)) {
857 +                resource_type = ACPI_RSTYPE_EXT_IRQ;
858 +                printk(PREFIX "Retrying with extended IRQ descriptor\n");
859 +                goto retry_programming;
860 +       }
861 +
862 +       /* check for total failure */
863         if (ACPI_FAILURE(status)) {
864                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n"));
865                 return_VALUE(-ENODEV);
866 @@ -361,7 +410,7 @@ acpi_pci_link_set (
867         }
868  
869         /* Make sure the active IRQ is the one we requested. */
870 -       result = acpi_pci_link_get_current(link);
871 +       result = acpi_pci_link_try_get_current(link, irq);
872         if (result) {
873                 return_VALUE(result);
874         }
875 @@ -401,22 +450,25 @@ acpi_pci_link_set (
876   * as 'best bets' for PCI use.
877   */
878  
879 -static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
880 +static int acpi_irq_default_penalty[ACPI_MAX_IRQS] = {
881         1000000,  1000000,  1000000,    10000, 
882           10000,        0,    10000,    10000,
883           10000,        0,        0,        0, 
884           10000,   100000,   100000,   100000,
885  };
886  
887 +static int acpi_irq_penalty[ACPI_MAX_IRQS] = { 0 };
888  
889  int
890 -acpi_pci_link_check (void)
891 +acpi_pci_link_calc_penalties (void)
892  {
893         struct list_head        *node = NULL;
894         struct acpi_pci_link    *link = NULL;
895         int                     i = 0;
896  
897 -       ACPI_FUNCTION_TRACE("acpi_pci_link_check");
898 +       ACPI_FUNCTION_TRACE("acpi_pci_link_calc_penalties");
899 +
900 +       memcpy(&acpi_irq_penalty, &acpi_irq_default_penalty, sizeof(acpi_irq_default_penalty));
901  
902         /*
903          * Update penalties to facilitate IRQ balancing.
904 @@ -428,6 +480,7 @@ acpi_pci_link_check (void)
905                         ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
906                         continue;
907                 }
908 +               link->irq.setonboot = 0;
909  
910                 if (link->irq.active)
911                         acpi_irq_penalty[link->irq.active] += 100;
912 @@ -458,18 +511,18 @@ static int acpi_pci_link_allocate(struct
913                 irq = link->irq.possible[0];
914         }
915  
916 -               /* 
917 -                * Select the best IRQ.  This is done in reverse to promote 
918 -                * the use of IRQs 9, 10, 11, and >15.
919 -                */
920 -               for (i=(link->irq.possible_count-1); i>0; i--) {
921 -                       if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]])
922 -                               irq = link->irq.possible[i];
923 -               }
924 +       /*
925 +        * Select the best IRQ.  This is done in reverse to promote
926 +        * the use of IRQs 9, 10, 11, and >15.
927 +        */
928 +       for (i=(link->irq.possible_count-1); i>0; i--) {
929 +               if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]])
930 +                       irq = link->irq.possible[i];
931 +       }
932  
933         /* Attempt to enable the link device at this IRQ. */
934         if (acpi_pci_link_set(link, irq)) {
935 -               printk(PREFIX "Unable to set IRQ for %s [%s] (likely buggy ACPI BIOS). Aborting ACPI-based IRQ routing. Try pci=noacpi or acpi=off\n",
936 +               printk(PREFIX "Unable to set IRQ for %s [%s] (likely buggy ACPI BIOS, please report to acpi-devel!)\n",
937                         acpi_device_name(link->device),
938                         acpi_device_bid(link->device));
939                 return_VALUE(-ENODEV);
940 @@ -574,10 +627,6 @@ acpi_pci_link_add (
941                 else
942                         printk(" %d", link->irq.possible[i]);
943         }
944 -       if (!link->irq.active)
945 -               printk(", disabled");
946 -       else if (!found)
947 -               printk(", enabled at IRQ %d", link->irq.active);
948         printk(")\n");
949  
950         /* TBD: Acquire/release lock */
951 diff -puN include/acpi/acpi_bus.h~acpi-irq-fixes include/acpi/acpi_bus.h
952 --- 25/include/acpi/acpi_bus.h~acpi-irq-fixes   2003-09-06 19:47:12.000000000 -0700
953 +++ 25-akpm/include/acpi/acpi_bus.h     2003-09-06 19:47:12.000000000 -0700
954 @@ -307,6 +307,8 @@ int acpi_bus_unregister_driver (struct a
955  int acpi_create_dir(struct acpi_device *);
956  void acpi_remove_dir(struct acpi_device *);
957  
958 +int acpi_bus_init_irq (void);
959 +
960  #endif /*CONFIG_ACPI_BUS*/
961  
962  #endif /*__ACPI_BUS_H__*/
963 diff -puN include/acpi/acpi_drivers.h~acpi-irq-fixes include/acpi/acpi_drivers.h
964 --- 25/include/acpi/acpi_drivers.h~acpi-irq-fixes       2003-09-06 19:47:12.000000000 -0700
965 +++ 25-akpm/include/acpi/acpi_drivers.h 2003-09-06 19:47:12.000000000 -0700
966 @@ -26,6 +26,9 @@
967  #ifndef __ACPI_DRIVERS_H__
968  #define __ACPI_DRIVERS_H__
969  
970 +/* forward definitions */
971 +struct acpi_prt_list;
972 +
973  #include <linux/acpi.h>
974  #include <acpi/acpi_bus.h>
975  
976 @@ -59,12 +62,15 @@ void acpi_pci_get_translations (struct a
977  
978  /* ACPI PCI Interrupt Link (pci_link.c) */
979  
980 -int acpi_pci_link_check (void);
981 +int acpi_pci_link_calc_penalties (void);
982  int acpi_pci_link_get_irq (acpi_handle handle, int index, int* edge_level, int* active_high_low);
983  
984  /* ACPI PCI Interrupt Routing (pci_irq.c) */
985  
986  int acpi_pci_irq_add_prt (acpi_handle handle, int segment, int bus);
987 +int acpi_pci_commit_prt_list (struct acpi_prt_list* prt_list);
988 +int acpi_pci_destroy_prt_list (struct acpi_prt_list* prt_list);
989 +struct acpi_prt_list* acpi_pci_get_prt_list (void);
990  
991  /* ACPI PCI Device Binding (pci_bind.c) */
992  
993 diff -puN include/asm-i386/acpi.h~acpi-irq-fixes include/asm-i386/acpi.h
994 --- 25/include/asm-i386/acpi.h~acpi-irq-fixes   2003-09-06 19:47:12.000000000 -0700
995 +++ 25-akpm/include/asm-i386/acpi.h     2003-09-06 19:47:12.000000000 -0700
996 @@ -151,6 +151,9 @@ extern unsigned long acpi_wakeup_address
997  /* early initialization routine */
998  extern void acpi_reserve_bootmem(void);
999  
1000 +/* ACPI-based PIC initialisation */
1001 +extern int pic_parse_prt (void);
1002 +
1003  #endif /*CONFIG_ACPI_SLEEP*/
1004  
1005  #endif /*__KERNEL__*/
1006 diff -puN include/asm-i386/mpspec.h~acpi-irq-fixes include/asm-i386/mpspec.h
1007 --- 25/include/asm-i386/mpspec.h~acpi-irq-fixes 2003-09-06 19:47:12.000000000 -0700
1008 +++ 25-akpm/include/asm-i386/mpspec.h   2003-09-06 19:47:12.000000000 -0700
1009 @@ -37,7 +37,7 @@ extern void mp_register_lapic_address (u
1010  extern void mp_register_ioapic (u8 id, u32 address, u32 irq_base);
1011  extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 global_irq);
1012  extern void mp_config_acpi_legacy_irqs (void);
1013 -extern void mp_parse_prt (void);
1014 +extern int mp_parse_prt (void);
1015  
1016  #ifdef CONFIG_X86_IO_APIC
1017  extern void mp_config_ioapic_for_sci(int irq);
1018 diff -puN include/asm-ia64/acpi.h~acpi-irq-fixes include/asm-ia64/acpi.h
1019 --- 25/include/asm-ia64/acpi.h~acpi-irq-fixes   2003-09-06 19:47:12.000000000 -0700
1020 +++ 25-akpm/include/asm-ia64/acpi.h     2003-09-06 19:47:12.000000000 -0700
1021 @@ -112,6 +112,9 @@ extern int __initdata pxm_to_nid_map[MAX
1022  extern int __initdata nid_to_pxm_map[NR_NODES];
1023  #endif
1024  
1025 +/* ia64 machines don't have PIC controllers */
1026 +static inline int pic_parse_prt(void) { return -1; }
1027 +
1028  #endif /*__KERNEL__*/
1029  
1030  #endif /*_ASM_ACPI_H*/
1031 diff -puN include/asm-ia64/iosapic.h~acpi-irq-fixes include/asm-ia64/iosapic.h
1032 --- 25/include/asm-ia64/iosapic.h~acpi-irq-fixes        2003-09-06 19:47:12.000000000 -0700
1033 +++ 25-akpm/include/asm-ia64/iosapic.h  2003-09-06 19:47:12.000000000 -0700
1034 @@ -57,7 +57,7 @@ extern void __init iosapic_init (unsigne
1035                                     unsigned int gsi_base);
1036  extern int gsi_to_vector (unsigned int gsi);
1037  extern int gsi_to_irq (unsigned int gsi);
1038 -extern void __init iosapic_parse_prt (void);
1039 +extern int __init iosapic_parse_prt (void);
1040  extern void iosapic_enable_intr (unsigned int vector);
1041  extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity,
1042                                   unsigned long trigger);
1043 diff -puN include/asm-x86_64/acpi.h~acpi-irq-fixes include/asm-x86_64/acpi.h
1044 --- 25/include/asm-x86_64/acpi.h~acpi-irq-fixes 2003-09-06 19:47:12.000000000 -0700
1045 +++ 25-akpm/include/asm-x86_64/acpi.h   2003-09-06 19:47:12.000000000 -0700
1046 @@ -146,6 +146,9 @@ extern int acpi_disabled;
1047  #define BROKEN_ACPI_Sx         0x0001
1048  #define BROKEN_INIT_AFTER_S1   0x0002
1049  
1050 +/* ACPI-based PIC initialisation */
1051 +extern int pic_parse_prt (void);
1052 +
1053  #endif /*__KERNEL__*/
1054  
1055  #endif /*_ASM_ACPI_H*/
1056 diff -puN include/asm-x86_64/mpspec.h~acpi-irq-fixes include/asm-x86_64/mpspec.h
1057 --- 25/include/asm-x86_64/mpspec.h~acpi-irq-fixes       2003-09-06 19:47:12.000000000 -0700
1058 +++ 25-akpm/include/asm-x86_64/mpspec.h 2003-09-06 19:47:12.000000000 -0700
1059 @@ -189,7 +189,7 @@ extern void mp_register_lapic_address (u
1060  extern void mp_register_ioapic (u8 id, u32 address, u32 irq_base);
1061  extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 global_irq);
1062  extern void mp_config_acpi_legacy_irqs (void);
1063 -extern void mp_parse_prt (void);
1064 +extern int mp_parse_prt (void);
1065  #endif /*CONFIG_X86_IO_APIC*/
1066  #endif
1067  
1068 diff -puN include/linux/acpi.h~acpi-irq-fixes include/linux/acpi.h
1069 --- 25/include/linux/acpi.h~acpi-irq-fixes      2003-09-06 19:47:12.000000000 -0700
1070 +++ 25-akpm/include/linux/acpi.h        2003-09-06 19:47:12.000000000 -0700
1071 @@ -399,7 +399,7 @@ struct acpi_prt_list {
1072         struct list_head        entries;
1073  };
1074  
1075 -extern struct acpi_prt_list    acpi_prt;
1076 +extern struct acpi_prt_list*   acpi_prt;
1077  
1078  struct pci_dev;
1079  
1080
1081 --- linux-2.6.0test5-work/arch/i386/pci/acpi.c-o        2003-08-23 13:03:09.000000000 +0200
1082 +++ linux-2.6.0test5-work/arch/i386/pci/acpi.c  2003-09-09 21:01:49.000000000 +0200
1083 @@ -15,10 +15,11 @@
1084  
1085  static int __init pci_acpi_init(void)
1086  {
1087 +       extern int acpi_disabled;
1088         if (pcibios_scanned)
1089                 return 0;
1090  
1091 -       if (!(pci_probe & PCI_NO_ACPI_ROUTING)) {
1092 +       if (!(pci_probe & PCI_NO_ACPI_ROUTING) && !acpi_disabled) {
1093                 if (!acpi_pci_irq_init()) {
1094                         printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
1095                         printk(KERN_INFO "PCI: if you experience problems, try using option 'pci=noacpi' or even 'acpi=off'\n");
1096
1097
1098 --- 2.6.0-test5-mm3/drivers/acpi/pci_link.c~acpi_pci_irq_fix    2003-09-22 10:00:16.000000000 -0700
1099 +++ 2.6.0-test5-mm3/drivers/acpi/pci_link.c     2003-09-22 10:10:06.000000000 -0700
1100 @@ -500,15 +500,15 @@ static int acpi_pci_link_allocate(struct
1101                 irq = link->irq.active;
1102         } else {
1103                 irq = link->irq.possible[0];
1104 -       }
1105  
1106 -       /* 
1107 -        * Select the best IRQ.  This is done in reverse to promote 
1108 -        * the use of IRQs 9, 10, 11, and >15.
1109 -        */
1110 -       for (i=(link->irq.possible_count-1); i>0; i--) {
1111 -               if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]])
1112 -                       irq = link->irq.possible[i];
1113 +               /* 
1114 +                * Select the best IRQ.  This is done in reverse to promote 
1115 +                * the use of IRQs 9, 10, 11, and >15.
1116 +                */
1117 +               for (i=(link->irq.possible_count-1); i>0; i--) {
1118 +                       if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]])
1119 +                               irq = link->irq.possible[i];
1120 +               }
1121         }
1122  
1123         /* Attempt to enable the link device at this IRQ. */
1124
1125
This page took 0.115897 seconds and 3 git commands to generate.