Subject: Re: Libretto L2 USB IRQ Mapping
To: Masanori Kanaoka <kanaoka@ann.hi-ho.ne.jp>
From: Lennart Augustsson <lennart@augustsson.net>
List: tech-kern
Date: 04/24/2002 01:34:18
This is a multi-part message in MIME format.
--------------0F44C7B179EB5CD696570AC3
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Thanks for the tip.  Here's a simplified version of my patch.  It's local to dev/acpi now.

    -- Lennart


Masanori Kanaoka wrote:

> acpi has some pci access code(such as ApciOsWritePciConfiguration(),
> ApciOsReadPciConfiguration()) in sys/dev/acpi/acpica.

--------------0F44C7B179EB5CD696570AC3
Content-Type: text/plain; charset=us-ascii;
 name="diffs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="diffs"

Index: acpi.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/acpi/acpi.c,v
retrieving revision 1.7
diff -c -r1.7 acpi.c
*** acpi.c	2002/03/24 03:32:14	1.7
--- acpi.c	2002/04/23 23:32:13
***************
*** 53,58 ****
--- 53,69 ----
  #include <dev/acpi/acpivar.h>
  #include <dev/acpi/acpi_osd.h>
  
+ #include <dev/acpi/acpica/Subsystem/acresrc.h>
+ #include <dev/acpi/acpica/Subsystem/acnamesp.h>
+ 
+ #ifndef ACPI_PCI_FIXUP
+ #define ACPI_PCI_FIXUP 1
+ #endif
+ 
+ #if ACPI_PCI_FIXUP
+ #include <dev/pci/pcidevs.h>
+ #endif
+ 
  #ifdef ENABLE_DEBUGGER
  #define	ACPI_DBGR_INIT		0x01
  #define	ACPI_DBGR_TABLES	0x02
***************
*** 63,68 ****
--- 74,84 ----
  int	acpi_dbgr = 0x00;
  #endif
  
+ #ifdef ACPI_DEBUG
+ int acpi_debug_show;
+ int acpi_scan_verbose;
+ #endif
+ 
  int	acpi_match(struct device *, struct cfdata *, void *);
  void	acpi_attach(struct device *, struct device *, void *);
  
***************
*** 93,98 ****
--- 109,118 ----
  ACPI_STATUS	acpi_make_devnode(ACPI_HANDLE, UINT32, void *, void **);
  
  void		acpi_enable_fixed_events(struct acpi_softc *);
+ #if ACPI_PCI_FIXUP
+ void		acpi_pci_fixup(struct acpi_softc *);
+ #endif
+ void		acpi_allocate_resources(ACPI_HANDLE handle);
  
  /*
   * acpi_probe:
***************
*** 109,114 ****
--- 129,137 ----
  	static int beenhere;
  	ACPI_STATUS rv;
  
+ 	extern UINT32 AcpiDbgLevel;
+ 	AcpiDbgLevel |= ACPI_LV_RESOURCES;
+ 
  	if (beenhere != 0)
  		panic("acpi_probe: ACPI has already been probed");
  	beenhere = 1;
***************
*** 260,265 ****
--- 283,295 ----
  	acpi_enable_fixed_events(sc);
  
  	/*
+ 	 * Fix up PCI devices.
+ 	 */
+ #if ACPI_PCI_FIXUP
+ 	acpi_pci_fixup(sc);
+ #endif
+ 
+ 	/*
  	 * Scan the namespace and build our device tree.
  	 */
  #ifdef ENABLE_DEBUGGER
***************
*** 392,399 ****
  			     (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
  			      ACPI_STA_DEV_SHOW|ACPI_STA_DEV_OK)) !=
  			    (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
! 			     ACPI_STA_DEV_SHOW|ACPI_STA_DEV_OK))
  				continue;
  
  			/*
  			 * XXX Same problem as above...
--- 422,435 ----
  			     (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
  			      ACPI_STA_DEV_SHOW|ACPI_STA_DEV_OK)) !=
  			    (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
! 			     ACPI_STA_DEV_SHOW|ACPI_STA_DEV_OK)) {
! #ifdef ACPI_DEBUG
! 				printf("skip %s, status=%x\n",
! 				       ad->ad_devinfo.HardwareId,
! 				       ad->ad_devinfo.CurrentStatus);
! #endif
  				continue;
+ 			}
  
  			/*
  			 * XXX Same problem as above...
***************
*** 407,412 ****
--- 443,662 ----
  	}
  }
  
+ static ACPI_STATUS acpi_run_with_buf(ACPI_STATUS (*fun)(ACPI_HANDLE, ACPI_BUFFER *),
+ 				     ACPI_BUFFER *buf, ACPI_HANDLE handle);
+ 
+ static ACPI_HANDLE
+ acpi_get_node(char *name)
+ {
+ 	ACPI_NAMESPACE_NODE *ObjDesc;
+ 	ACPI_STATUS Status;
+ 
+ 	Status = AcpiNsGetNode(name, NULL, &ObjDesc);
+ 	if (ACPI_FAILURE (Status)) {
+ 		printf("Could not find: %s\n", AcpiFormatException (Status));
+ 		return NULL;
+ 	}
+ 	return ObjDesc;
+ }
+ 
+ static void
+ show_current(ACPI_HANDLE handle)
+ {
+ 	ACPI_BUFFER ReturnObj;
+ 	ACPI_STATUS Status;
+ 
+ 	printf("current:\n");
+ 
+ 	Status = acpi_run_with_buf(AcpiGetCurrentResources, &ReturnObj,handle);
+ 	if (ACPI_FAILURE (Status)) {
+ 		printf("AcpiGetCurrentResources failed: %s\n",
+ 		       AcpiFormatException (Status));
+ 	} else {
+ 		AcpiRsDumpResourceList(ReturnObj.Pointer);
+ 		free(ReturnObj.Pointer, M_DEVBUF);
+ 	}
+ 
+ }
+ 
+ #if 0
+ static void
+ show_possible(ACPI_HANDLE handle)
+ {
+ 	ACPI_BUFFER ReturnObj;
+ 	double data[200];
+ 	ACPI_STATUS Status;
+ 
+ 	printf("possible:\n");
+ 
+ 	ReturnObj.Pointer = data;
+ 	ReturnObj.Length = sizeof data;
+ 
+ 	Status = AcpiGetPossibleResources(handle, &ReturnObj);
+ 	if (ACPI_FAILURE (Status)) {
+ 		printf("AcpiGetPossibleResources failed: %s\n",
+ 		       AcpiFormatException (Status));
+ 	} else
+ 		AcpiRsDumpResourceList((ACPI_RESOURCE *)data);
+ 
+ }
+ 
+ static void
+ show_irqs(void *v)
+ {
+ 	UINT8               *Buffer = v;
+ 	UINT8               Count = 0;
+ 	PCI_ROUTING_TABLE   *PrtElement;
+ 
+         for (Buffer = v; ; Buffer += PrtElement->Length) {
+ 		PrtElement = (PCI_ROUTING_TABLE *)Buffer;
+ 		if (PrtElement->Length == 0)
+ 			break;
+ 		printf("PCI IRQ Routing Table structure %X.\n", Count++);
+ 		printf("    Address: %X\n", (unsigned)PrtElement->Address);
+ 		printf("    Pin: %X\n", PrtElement->Pin);
+ 		printf("    Source: %s\n", PrtElement->Source);
+ 		printf("    SourceIndex: %X\n", PrtElement->SourceIndex);
+ 
+ 		if (PrtElement->Source != NULL) {
+ 			ACPI_HANDLE handle = acpi_get_node(PrtElement->Source);
+ 			if (handle) {
+ 				show_current(handle);
+ 				show_possible(handle);
+ 			}
+ 		}
+ 	}
+ }
+ #endif
+ 
+ static ACPI_STATUS
+ acpi_run_with_buf(ACPI_STATUS (*fun)(ACPI_HANDLE, ACPI_BUFFER *),
+ 		  ACPI_BUFFER *buf, ACPI_HANDLE handle)
+ {
+ 	ACPI_STATUS rv;
+ 
+ 	buf->Pointer = NULL;
+ 	buf->Length = 0;
+ 	rv = (*fun)(handle, buf);
+ 	if (rv != AE_BUFFER_OVERFLOW)
+ 		return (rv);
+ 	buf->Pointer = malloc(buf->Length, M_DEVBUF, M_WAITOK);
+ 	rv = (*fun)(handle, buf);
+ 	if (ACPI_FAILURE(rv))
+ 		free(buf->Pointer, M_DEVBUF);
+ 	return (rv);
+ }
+ 
+ void
+ acpi_allocate_resources(ACPI_HANDLE handle)
+ {
+ 	ACPI_BUFFER bufp, bufc, bufn;
+ 	ACPI_RESOURCE *resp, *resc, *resn;
+ 	ACPI_RESOURCE_IRQ *irq;
+ 	ACPI_STATUS rv;
+ 	uint delta;
+ #if 0
+ 	printf("acpi_allocate_resources: enter\n");
+ #endif
+ 	rv = acpi_run_with_buf(AcpiGetPossibleResources, &bufp, handle);
+ 	if (ACPI_FAILURE(rv))
+ 		goto out;
+ 	rv = acpi_run_with_buf(AcpiGetCurrentResources, &bufc, handle);
+ 	if (ACPI_FAILURE(rv)) {
+ 		goto out1;
+ 	}
+ 
+ 	bufn.Length = 1000;
+ 	bufn.Pointer = resn = malloc(bufn.Length, M_DEVBUF, M_WAITOK);
+ 	resp = bufp.Pointer;
+ 	resc = bufc.Pointer;
+ #if 0
+ 	printf("acpi_allocate_resources: current\n");
+ 	AcpiRsDumpResourceList(resc);
+ 	printf("acpi_allocate_resources: possible\n");
+ 	AcpiRsDumpResourceList(resp);
+ #endif
+ 	while (resc->Id != ACPI_RSTYPE_END_TAG &&
+ 	       resp->Id != ACPI_RSTYPE_END_TAG) {
+ 		while (resc->Id != resp->Id && resp->Id != ACPI_RSTYPE_END_TAG)
+ 			resp = NEXT_RESOURCE(resp);
+ 		if (resp->Id == ACPI_RSTYPE_END_TAG)
+ 			break;
+ 		/* Found identical Id */
+ 		resn->Id = resc->Id;
+ 		switch (resc->Id) {
+ 		case ACPI_RSTYPE_IRQ:
+ 			memcpy(&resn->Data, &resp->Data,
+ 			       sizeof(ACPI_RESOURCE_IRQ));
+ 			irq = (ACPI_RESOURCE_IRQ *)&resn->Data;
+ 			irq->Interrupts[0] =
+ 			    ((ACPI_RESOURCE_IRQ *)&resp->Data)->Interrupts[irq->NumberOfInterrupts-1];
+ 			irq->NumberOfInterrupts = 1;
+ 			resn->Length = SIZEOF_RESOURCE(ACPI_RESOURCE_IRQ);
+ 			break;
+ 		case ACPI_RSTYPE_IO:
+ 			memcpy(&resn->Data, &resp->Data,
+ 			       sizeof(ACPI_RESOURCE_IO));
+ 			resn->Length = resp->Length;
+ 			break;
+ 		default:
+ 			printf("acpi_allocate_resources: res=%d\n", resc->Id);
+ 			goto out2;
+ 		}
+ 		resc = NEXT_RESOURCE(resc);
+ 		resn = NEXT_RESOURCE(resn);
+ 		delta = (UINT8 *)resn - (UINT8 *)bufn.Pointer;
+ 		if (delta >= bufn.Length-SIZEOF_RESOURCE(ACPI_RESOURCE_DATA)){
+ 			bufn.Length *= 2;
+ 			bufn.Pointer = realloc(bufn.Pointer, bufn.Length,
+ 					       M_DEVBUF, M_WAITOK);
+ 			resn = (ACPI_RESOURCE *)((UINT8 *)bufn.Pointer + delta);
+ 		}
+ 	}
+ 	if (resc->Id != ACPI_RSTYPE_END_TAG) {
+ 		printf("acpi_allocate_resources: resc not exhausted\n");
+ 		goto out3;
+ 	}
+ 
+ 	resn->Id = ACPI_RSTYPE_END_TAG;
+ #if 0
+ 	printf("acpi_allocate_resources: new\n");
+ 	AcpiRsDumpResourceList(bufn.Pointer);
+ #endif
+ 	rv = AcpiSetCurrentResources(handle, &bufn);
+ 	if (ACPI_FAILURE(rv)) {
+ 		printf("acpi_allocate_resources: AcpiSetCurrentResources %s\n",
+ 		       AcpiFormatException(rv));
+ 	}
+ #if 0
+ 	printf("acpi_allocate_resources: done\n");
+ #endif
+ 
+ out3:
+ 	free(bufn.Pointer, M_DEVBUF);
+ out2:
+ 	free(bufc.Pointer, M_DEVBUF);
+ out1:
+ 	free(bufp.Pointer, M_DEVBUF);
+ out:
+ 	;
+ }
+ 
+ static void
+ acpi_activate_device(ACPI_HANDLE handle, ACPI_DEVICE_INFO *di)
+ {
+ 	printf("acpi_activate_device: %s, status=%x\n", 
+ 	       di->HardwareId, di->CurrentStatus);
+ #if 0
+ 	show_current(handle);
+ 	show_possible(handle);
+ #endif
+ 	acpi_allocate_resources(handle);
+ 	show_current(handle);
+ 
+ 	(void)AcpiGetObjectInfo(handle, di);
+ }
+ 
  /*
   * acpi_make_devnode:
   *
***************
*** 420,436 ****
--- 670,744 ----
  #ifdef ACPI_DEBUG
  	struct acpi_softc *sc = state->softc;
  #endif
+ 	ACPI_BUFFER namebuf;
+ 	char name[1000];
+ 	ACPI_DEVICE_INFO devinfo;
  	struct acpi_scope *as = state->scope;
  	struct acpi_devnode *ad;
  	ACPI_OBJECT_TYPE type;
  	ACPI_STATUS rv;
  
  	if (AcpiGetType(handle, &type) == AE_OK) {
+ 		namebuf.Length = sizeof name;
+ 		namebuf.Pointer = name;
+ 		rv = AcpiGetName(handle, ACPI_FULL_PATHNAME, &namebuf);
+ 		if (rv != AE_OK) {
+ #ifdef ACPI_DEBUG
+ 			printf("%s: AcpiGetName failed\n", sc->sc_dev.dv_xname);
+ #endif
+ 			goto out;
+ 		}
+ 		rv = AcpiGetObjectInfo(handle, &devinfo);
+ 		if (rv != AE_OK) {
+ #ifdef ACPI_DEBUG
+ 			printf("%s: AcpiGetObjectInfo failed\n",
+ 			    sc->sc_dev.dv_xname);
+ #endif
+ 			goto out; /* XXX why return OK */
+ 		}
+ 
+ #ifdef ACPI_DEBUG
+ 		if (acpi_scan_verbose)
+ 		printf("%s: object %s type %s level %d\n",
+ 		    sc->sc_dev.dv_xname, name, AcpiUtGetTypeName(type), level);
+ #endif
  		switch (type) {
  		case ACPI_TYPE_DEVICE:
+ #ifdef ACPI_DEBUG
+ 			if (acpi_scan_verbose) {
+ 			if (devinfo.Valid & ACPI_VALID_HID)
+ 				printf("  HID %s\n", devinfo.HardwareId);
+ 			if (devinfo.Valid & ACPI_VALID_UID)
+ 				printf("  UID %s\n", devinfo.UniqueId);
+ 			if (devinfo.Valid & ACPI_VALID_ADR)
+ 				printf("  ADR 0x%016qx\n", devinfo.Address);
+ 			if (devinfo.Valid & ACPI_VALID_STA) {
+ 				printf("  STA 0x%08x\n", devinfo.CurrentStatus);
+ 				if (acpi_debug_show)
+ 					show_current(handle);
+ 			}
+ 			}
+ #endif
+ 			if ((devinfo.Valid & ACPI_VALID_STA) &&
+ 			    (devinfo.CurrentStatus &
+ 			     (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED)) ==
+ 			    ACPI_STA_DEV_PRESENT) {
+ 				acpi_activate_device(handle, &devinfo);
+ 			}
+ 			/* FALLTHROUGH */
+ 
  		case ACPI_TYPE_PROCESSOR:
  		case ACPI_TYPE_THERMAL:
  		case ACPI_TYPE_POWER:
+ 			if (!(devinfo.Valid & ACPI_VALID_HID)) {
+ #ifdef ACPI_DEBUG
+ 				if (acpi_scan_verbose)
+ 					printf("%s: skip non-HID\n",
+ 					       sc->sc_dev.dv_xname);
+ #endif
+ 				goto out;
+ 			}
+ 
  			ad = malloc(sizeof(*ad), M_DEVBUF, M_NOWAIT|M_ZERO);
  			if (ad == NULL)
  				return (AE_NO_MEMORY);
***************
*** 439,472 ****
  			ad->ad_level = level;
  			ad->ad_scope = as;
  			ad->ad_type = type;
  
  			TAILQ_INSERT_TAIL(&as->as_devnodes, ad, ad_list);
! 
! 			rv = AcpiGetObjectInfo(handle, &ad->ad_devinfo);
! 			if (rv != AE_OK)
! 				goto out;
! 
! 			if ((ad->ad_devinfo.Valid & ACPI_VALID_HID) == 0)
! 				goto out;
  
  #ifdef ACPI_DEBUG
! 			printf("%s: HID %s found in scope %s level %d\n",
! 			    sc->sc_dev.dv_xname, ad->ad_devinfo.HardwareId,
! 			    as->as_name, ad->ad_level);
! 			if (ad->ad_devinfo.Valid & ACPI_VALID_UID)
! 				printf("       UID %s\n",
! 				    ad->ad_devinfo.UniqueId);
! 			if (ad->ad_devinfo.Valid & ACPI_VALID_ADR)
! 				printf("       ADR 0x%016qx\n",
! 				    ad->ad_devinfo.Address);
! 			if (ad->ad_devinfo.Valid & ACPI_VALID_STA)
! 				printf("       STA 0x%08x\n",
! 				    ad->ad_devinfo.CurrentStatus);
  #endif
  		}
  	}
!  out:
! 	return (AE_OK);
  }
  
  /*
--- 747,768 ----
  			ad->ad_level = level;
  			ad->ad_scope = as;
  			ad->ad_type = type;
+ 			ad->ad_devinfo = devinfo;
  
  			TAILQ_INSERT_TAIL(&as->as_devnodes, ad, ad_list);
! 			break;
  
+ 		default:
  #ifdef ACPI_DEBUG
! 			if (acpi_scan_verbose)
! 				printf("%s: skip type\n", sc->sc_dev.dv_xname);
  #endif
+ 			break;
  		}
  	}
! out:
! 	rv = AE_OK;
! 	return (rv);
  }
  
  /*
***************
*** 487,492 ****
--- 783,789 ----
  #if 0 /* Not until we fix acpi_eval_string */
  		if (acpi_eval_string(aa->aa_node->ad_handle,
  		    "_STR", &str) == AE_OK) {
+ 			/* XXX str is Unicode */
  			printf("[%s] ", str);
  			AcpiOsFree(str);
  		}
***************
*** 655,660 ****
--- 952,982 ----
  }
  #endif
  
+ /*
+  * acpi_get:
+  *
+  *	Fetch data info the specified (empty) ACPI buffer.
+  */
+ ACPI_STATUS
+ acpi_get(ACPI_HANDLE handle, ACPI_BUFFER *buf,
+     ACPI_STATUS (*getit)(ACPI_HANDLE, ACPI_BUFFER *))
+ {
+ 	ACPI_STATUS rv;
+ 
+ 	buf->Pointer = NULL;
+ 	buf->Length = 0;
+ 
+ 	rv = (*getit)(handle, buf);
+ 	if (rv != AE_BUFFER_OVERFLOW)
+ 		return (rv);
+ 
+ 	buf->Pointer = AcpiOsCallocate(buf->Length);
+ 	if (buf->Pointer == NULL)
+ 		return (AE_NO_MEMORY);
+ 
+ 	return ((*getit)(handle, buf));
+ }
+ 
  
  /*
   * acpi_eval_struct:
***************
*** 685,711 ****
  	return (rv);
  }
  
  /*
!  * acpi_get:
   *
!  *	Fetch data info the specified (empty) ACPI buffer.
   */
  ACPI_STATUS
! acpi_get(ACPI_HANDLE handle, ACPI_BUFFER *buf,
!     ACPI_STATUS (*getit)(ACPI_HANDLE, ACPI_BUFFER *))
  {
  	ACPI_STATUS rv;
  
! 	buf->Pointer = NULL;
! 	buf->Length = 0;
  
! 	rv = (*getit)(handle, buf);
! 	if (rv != AE_BUFFER_OVERFLOW)
! 		return (rv);
  
! 	buf->Pointer = AcpiOsCallocate(buf->Length);
! 	if (buf->Pointer == NULL)
! 		return (AE_NO_MEMORY);
  
! 	return ((*getit)(handle, buf));
  }
--- 1007,1171 ----
  	return (rv);
  }
  
+ #if ACPI_PCI_FIXUP
+ ACPI_STATUS acpi_pci_fixup_bus(ACPI_HANDLE, UINT32, void *, void **);
  /*
!  * acpi_pci_fixup:
   *
!  *	Set up PCI devices that BIOS didn't handle right.
!  *	Iterate through all devices and try to get the _PTR
!  *	(PCI Routing Table).  If it exists then make sure all
!  *	interrupt links that it uses are working.
   */
+ void
+ acpi_pci_fixup(struct acpi_softc *sc)
+ {
+ 	ACPI_HANDLE parent;
+ 
+ #ifdef ACPI_DEBUG
+ 	printf("acpi_pci_fixup starts:\n");
+ #endif
+ 	if (AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &parent) != AE_OK)
+ 		return;
+ 	sc->sc_pci_bus = 0;
+ 	AcpiWalkNamespace(ACPI_TYPE_DEVICE, parent, 100,
+ 	    acpi_pci_fixup_bus, sc, NULL);
+ }
+ 
+ static uint
+ acpi_get_intr(ACPI_HANDLE handle)
+ {
+ 	ACPI_BUFFER ret;
+ 	ACPI_STATUS rv;
+ 	ACPI_RESOURCE *res;
+ 	ACPI_RESOURCE_IRQ *irq;
+ 	uint intr;
+ 
+ 	intr = -1;
+ 	rv = acpi_run_with_buf(AcpiGetCurrentResources, &ret, handle);
+ 	if (ACPI_FAILURE(rv))
+ 		return (intr);
+ 	for (res = ret.Pointer; res->Id != ACPI_RSTYPE_END_TAG;
+ 	     res = POINTER_ADD(ACPI_RESOURCE, res, res->Length)) {
+ 		if (res->Id == ACPI_RSTYPE_IRQ) {
+ 			irq = (ACPI_RESOURCE_IRQ *)&res->Data;
+ 			if (irq->NumberOfInterrupts == 1)
+ 				intr = irq->Interrupts[0];
+ 			break;
+ 		}
+ 	}
+ 	free(ret.Pointer, M_DEVBUF);
+ 	return (intr);
+ }
+ 
+ static void
+ acpi_pci_set_line(int bus, int dev, int pin, int line)
+ {
+ 	ACPI_STATUS err;
+ 	ACPI_PCI_ID pid;
+ 	UINT32 intr, id, bhlc;
+ 	int func, nfunc;
+ 
+ 	pid.Bus = bus;
+ 	pid.Device = dev;
+ 	pid.Function = 0;
+ 	
+ 	err = AcpiOsReadPciConfiguration(&pid, PCI_BHLC_REG, &bhlc, 32);
+ 	if (err)
+ 		return;
+ 	if (PCI_HDRTYPE_MULTIFN(bhlc))
+ 		nfunc = 8;
+ 	else
+ 		nfunc = 1;
+ 
+ 	for (func = 0; func < nfunc; func++) {
+ 		pid.Function = func;
+ 
+ 		err = AcpiOsReadPciConfiguration(&pid, PCI_ID_REG, &id, 32);
+ 		if (err || PCI_VENDOR(id) == PCI_VENDOR_INVALID ||
+ 		    PCI_VENDOR(id) == 0)
+ 			continue;
+ 
+ 		err = AcpiOsReadPciConfiguration(&pid, PCI_INTERRUPT_REG,
+ 			  &intr, 32);
+ 		if (err) {
+ 			printf("AcpiOsReadPciConfiguration failed %d\n", err);
+ 			return;
+ 		}
+ 		if (pin == PCI_INTERRUPT_PIN(intr) &&
+ 		    line != PCI_INTERRUPT_LINE(intr)) {
+ #ifdef ACPI_DEBUG
+ 			printf("acpi fixup pci intr: %d:%d:%d %c: %d -> %d\n",
+ 			       bus, dev, func,
+ 			       pin + '@', PCI_INTERRUPT_LINE(intr),
+ 			       line);
+ #endif
+ 			intr &= ~(PCI_INTERRUPT_LINE_MASK <<
+ 				  PCI_INTERRUPT_LINE_SHIFT);
+ 			intr |= line << PCI_INTERRUPT_LINE_SHIFT;
+ 			err = AcpiOsWritePciConfiguration(&pid,
+ 				  PCI_INTERRUPT_REG, intr, 32);
+ 			if (err) {
+ 				printf("AcpiOsWritePciConfiguration failed"
+ 				       " %d\n", err);
+ 				return;
+ 			}
+ 		}
+ 	}
+ }
+ 
  ACPI_STATUS
! acpi_pci_fixup_bus(ACPI_HANDLE handle, UINT32 level, void *context,
! 		   void **status)
  {
+ 	struct acpi_softc *sc = context;
  	ACPI_STATUS rv;
+ 	ACPI_BUFFER buf;
+ 	UINT8 *Buffer;
+ 	PCI_ROUTING_TABLE *PrtElement;
+ 	ACPI_HANDLE link;
+ 	uint line;
+ 
+ 	rv = acpi_run_with_buf(AcpiGetIrqRoutingTable, &buf, handle);
+ 	if (ACPI_FAILURE(rv))
+ 		return (AE_OK);
  
! #ifdef ACPI_DEBUG
! 	printf("%s: fixing up PCI\n", sc->sc_dev.dv_xname);
! #endif
  
!         for (Buffer = buf.Pointer; ; Buffer += PrtElement->Length) {
! 		PrtElement = (PCI_ROUTING_TABLE *)Buffer;
! 		if (PrtElement->Length == 0)
! 			break;
! 		if (PrtElement->Source == NULL)
! 			continue;
! 
! 		link = acpi_get_node(PrtElement->Source);
! 		if (link == NULL)
! 			continue;
! 		line = acpi_get_intr(link);
! 		if (line == -1) {
! #ifdef ACPI_DEBUG
! 			printf("%s: fixing up link %s\n", sc->sc_dev.dv_xname,
! 			       PrtElement->Source);
! #endif
! 			acpi_allocate_resources(link);
! 			line = acpi_get_intr(link);
! 			if (line == -1) {
! 				printf("%s: interrupt allocation failed %s\n",
! 				       sc->sc_dev.dv_xname, PrtElement->Source);
! 				continue;
! 			}
! 		}
  
! 		acpi_pci_set_line(sc->sc_pci_bus, PrtElement->Address >> 16,
! 				  PrtElement->Pin + 1, line);
! 	}
  
! 	sc->sc_pci_bus++;
! 
! 	free(buf.Pointer, M_DEVBUF);
! 	return (AE_OK);
  }
+ #endif
Index: acpivar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/acpi/acpivar.h,v
retrieving revision 1.4
diff -c -r1.4 acpivar.h
*** acpivar.h	2002/03/24 03:32:14	1.4
--- acpivar.h	2002/04/23 23:32:13
***************
*** 107,112 ****
--- 107,113 ----
  	bus_space_tag_t sc_memt;	/* PCI MEM space tag */
  	pci_chipset_tag_t sc_pc;	/* PCI chipset tag */
  	int sc_pciflags;		/* PCI bus flags */
+ 	int sc_pci_bus;			/* internal PCI fixup */
  
  	void *sc_sdhook;		/* shutdown hook */
  

--------------0F44C7B179EB5CD696570AC3--