--- acpi_pcib.c	Mon Nov 24 21:24:16 2003
+++ acpi_pcib.c.NEW	Mon Nov 24 21:23:59 2003
@@ -324,6 +324,48 @@
 	printf("  %d", Interrupts[i]);
     printf("\n");
 
+    /*************************************************************/
+    /* This is the ugly hack to see if it will be working at all */
+    /* We will look for environment variable 'hw.acpi.pci.preferred_irq' 
+     * then check if IRQ in question is in the list of available ones
+     * and if it is available, we will use it. If it is not available
+     * we will fall back on "unscientific" first available interrupt
+     * (basically the way code worked before).
+     */
+    int preferred_irq_idx = 0;
+    char *pPreferredIRQ = getenv("hw.acpi.pci.preferred_irq");
+    if(pPreferredIRQ != NULL)
+    {
+      register char *pc;
+      /* I'm sure there is a better way ;) */
+      /* strlen + isdigit */
+      register int irq = 0;
+      for(pc = pPreferredIRQ; *pc != '\0'; pc++)
+      {
+	if((*pc < '0') || (*pc > '9'))
+	{
+	  device_printf(pcib, "Invalid preferred IRQ: %s, "
+			"falling back on first available\n", 
+			pPreferredIRQ);
+	  goto fallBackOnZero;
+	}
+	irq = (irq << 3) + (irq << 1) + (*pc - '0');
+      }
+      /* Looking for slot with the IRQ in question */
+      for(register int i = 0; i < NumberOfInterrupts; i++)
+      {
+	if(Interrupts[i] == irq)
+	{
+	  preferred_irq_idx = i;
+	  break;
+	}
+      }
+      device_printf(pcib, "User suggested IRQ: %d (slot %d)\n", 
+		    irq, preferred_irq_idx); 
+    }
+ fallBackOnZero:
+    /*************************************************************/
+
     if (crsbuf.Pointer != NULL)			/* should never happen */
 	AcpiOsFree(crsbuf.Pointer);
     crsbuf.Pointer = NULL;
@@ -332,29 +374,29 @@
 	resbuf.Length = ACPI_SIZEOF_RESOURCE(ACPI_RESOURCE_IRQ);
 	resbuf.Data.Irq = prsres->Data.Irq;		/* structure copy other fields */
 	resbuf.Data.Irq.NumberOfInterrupts = 1;
-	resbuf.Data.Irq.Interrupts[0] = Interrupts[0];	/* just take first... */
+	resbuf.Data.Irq.Interrupts[0] = Interrupts[preferred_irq_idx];	/* just take first... */
     } else {
 	resbuf.Id = ACPI_RSTYPE_EXT_IRQ;
 	resbuf.Length = ACPI_SIZEOF_RESOURCE(ACPI_RESOURCE_IRQ);
 	resbuf.Data.ExtendedIrq = prsres->Data.ExtendedIrq;	/* structure copy other fields */
 	resbuf.Data.ExtendedIrq.NumberOfInterrupts = 1;
-	resbuf.Data.ExtendedIrq.Interrupts[0] = Interrupts[0];	/* just take first... */
+	resbuf.Data.ExtendedIrq.Interrupts[0] = Interrupts[preferred_irq_idx];	/* just take first... */
     }
     if (ACPI_FAILURE(status = acpi_AppendBufferResource(&crsbuf, &resbuf))) {
 	device_printf(pcib, "couldn't route interrupt %d via %s, interrupt resource build failed - %s\n",
-		      Interrupts[0], acpi_name(lnkdev), AcpiFormatException(status));
+		      Interrupts[preferred_irq_idx], acpi_name(lnkdev), AcpiFormatException(status));
 	goto out;
     }
     if (ACPI_FAILURE(status = AcpiSetCurrentResources(lnkdev, &crsbuf))) {
 	device_printf(pcib, "couldn't route interrupt %d via %s - %s\n",
-		      Interrupts[0], acpi_name(lnkdev), AcpiFormatException(status));
+		      Interrupts[preferred_irq_idx], acpi_name(lnkdev), AcpiFormatException(status));
 	goto out;
     }
     
     /* successful, return the interrupt we just routed */
     device_printf(pcib, "slot %d INT%c routed to irq %d via %s\n", 
-	pci_get_slot(dev), 'A' + pin, Interrupts[0], acpi_name(lnkdev));
-    interrupt = Interrupts[0];
+	pci_get_slot(dev), 'A' + pin, Interrupts[preferred_irq_idx], acpi_name(lnkdev));
+    interrupt = Interrupts[preferred_irq_idx];
 
  out:
     if (crsbuf.Pointer != NULL)
