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/22/2002 22:44:48
This is a multi-part message in MIME format.
--------------4628E8F4B17A0FB3BE666DBB
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Here is my interrupt routing patch.

    -- Lennart

Masanori Kanaoka wrote:

> $  I found that using ACPI was the only
> $ way to get interrupts properly routed on my Vaio.  I have some code
> $ for it, but it's not committed.
>
> I'm interest in some code.
> If possible,Would you please put some code in some URL?

--------------4628E8F4B17A0FB3BE666DBB
Content-Type: text/plain; charset=us-ascii;
 name="acpi.diffs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="acpi.diffs"

========================== dev/pci/pci_intr_table.h:
struct pci_intr {
	struct pci_intr *pi_next;
	uint pi_bus;
	uint pi_devaddr;
	uint pi_pin;
	uint pi_line;
} *pci_intr_table;
==========================
Index: dev/pci/pci.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/pci.c,v
retrieving revision 1.58
diff -c -r1.58 pci.c
*** dev/pci/pci.c	2001/11/13 07:48:47	1.58
--- dev/pci/pci.c	2002/04/22 15:24:55
***************
*** 47,52 ****
--- 47,53 ----
  #include <dev/pci/pcireg.h>
  #include <dev/pci/pcivar.h>
  #include <dev/pci/pcidevs.h>
+ #include <dev/pci/pci_intr_table.h>
  
  #ifdef PCI_CONFIG_DUMP
  int pci_config_dump = 1;
***************
*** 66,71 ****
--- 67,74 ----
  int	pciprint __P((void *, const char *));
  int	pcisubmatch __P((struct device *, struct cfdata *, void *));
  
+ pcireg_t pci_fixup_intr __P((struct pci_softc *sc, pci_chipset_tag_t pc, pcitag_t tag, int bus, int device, int function));
+ 
  /*
   * Important note about PCI-ISA bridges:
   *
***************
*** 194,200 ****
  			id = pci_conf_read(pc, tag, PCI_ID_REG);
  			csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
  			class = pci_conf_read(pc, tag, PCI_CLASS_REG);
- 			intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
  			bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG);
  
  			/* Invalid vendor ID value? */
--- 197,202 ----
***************
*** 204,209 ****
--- 206,213 ----
  			if (PCI_VENDOR(id) == 0)
  				continue;
  
+ 			intr = pci_fixup_intr(sc, pc, tag, bus, device, function);
+ 
  			pa.pa_iot = iot;
  			pa.pa_memt = memt;
  			pa.pa_dmat = sc->sc_dmat;
***************
*** 392,397 ****
--- 396,433 ----
  	    cf->pcicf_function != pa->pa_function)
  		return 0;
  	return ((*cf->cf_attach->ca_match)(parent, cf, aux));
+ }
+ 
+ pcireg_t
+ pci_fixup_intr(sc, pc, tag, bus, device, function)
+ 	struct pci_softc *sc;
+ 	pci_chipset_tag_t pc;
+ 	pcitag_t tag;
+ 	int bus, device, function;
+ {
+ 	pcireg_t intr;
+ 	struct pci_intr *pi;
+ 
+ 	intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
+ 
+ 	/* Do interrupt fixups */
+ 	for (pi = pci_intr_table; pi; pi = pi->pi_next) {
+ 		if (pi->pi_bus == bus &&
+ 		    pi->pi_devaddr == device &&
+ 		    pi->pi_pin == PCI_INTERRUPT_PIN(intr) &&
+ 		    pi->pi_line != PCI_INTERRUPT_LINE(intr)) {
+ #if 0
+ 			printf("%s: fixup intr %d:%d:%d %c: %d -> %d\n",
+ 			       self->dv_xname, bus, device, function,
+ 			       pi->pi_pin + '@', PCI_INTERRUPT_LINE(intr),
+ 			       pi->pi_line);
+ #endif
+ 			intr &= ~(PCI_INTERRUPT_LINE_MASK << PCI_INTERRUPT_LINE_SHIFT);
+ 			intr |= pi->pi_line << PCI_INTERRUPT_LINE_SHIFT;
+ 			pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);
+ 		}
+ 	}
+ 	return (intr);
  }
  
  int
Index: dev/acpi/acpi.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/acpi/acpi.c,v
retrieving revision 1.7
diff -c -r1.7 acpi.c
*** dev/acpi/acpi.c	2002/03/24 03:32:14	1.7
--- dev/acpi/acpi.c	2002/04/22 20:42:00
***************
*** 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/pci_intr_table.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,664 ----
  	}
  }
  
+ 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);
+ 
+ }
+ #endif
+ 
+ #if 0
+ 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 ****
--- 672,746 ----
  #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);
  }
  
  /*
--- 749,770 ----
  			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 ****
--- 785,791 ----
  #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,661 ****
--- 954,985 ----
  }
  #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));
  }
--- 1009,1131 ----
  	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);
+ 
+ 	{
+ 		struct pci_intr *pi;
+ 		printf("acpi_pci_fixup table:\n");
+ 		for (pi = pci_intr_table; pi; pi = pi->pi_next)
+ 			printf("dev %02d pin=%c line=%d\n",
+ 			       pi->pi_devaddr, pi->pi_pin + '@', pi->pi_line);
+ 	}
+ }
+ 
+ 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);
+ }
+ 
  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;
+ 	struct pci_intr *pi;
+ 	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;
! 			}
! 		}
  
! 		pi = malloc(sizeof *pi, M_DEVBUF, M_WAITOK);
! 		pi->pi_bus = sc->sc_pci_bus;
! 		pi->pi_next = pci_intr_table;
! 		pi->pi_devaddr = PrtElement->Address >> 16;
! 		pi->pi_pin = PrtElement->Pin + 1;
! 		pi->pi_line = line;
! 		pci_intr_table = pi;
! 	}
  
! 	sc->sc_pci_bus++;
! 
! 	free(buf.Pointer, M_DEVBUF);
! 	return (AE_OK);
  }
+ #endif
Index: dev/acpi/acpi_bat.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/acpi/acpi_bat.c,v
retrieving revision 1.1
diff -c -r1.1 acpi_bat.c
*** dev/acpi/acpi_bat.c	2002/03/24 03:46:10	1.1
--- dev/acpi/acpi_bat.c	2002/04/22 20:42:00
***************
*** 149,155 ****
  	 * in the future, when we have an API, let userland do this polling
  	 */
  	callout_init(&sc->sc_callout);
! 	callout_reset(&sc->sc_callout, 60*hz, acpibat_tick, sc);
  
  	/* Display the current state. */
  	sc->sc_flags = ABAT_F_VERBOSE;
--- 149,155 ----
  	 * in the future, when we have an API, let userland do this polling
  	 */
  	callout_init(&sc->sc_callout);
! 	callout_reset(&sc->sc_callout, 300*hz, acpibat_tick, sc);
  
  	/* Display the current state. */
  	sc->sc_flags = ABAT_F_VERBOSE;
***************
*** 257,263 ****
  	sc->sc_capacity = p2[2].Integer.Value;
  	sc->sc_mv = p2[3].Integer.Value;
  
! 	if (sc->sc_flags & ABAT_F_VERBOSE) {
  		printf("%s: %s%s: %dmV cap %d%s (%d%%) rate %d%s\n",
  		    sc->sc_dev.dv_xname,
  		    (sc->sc_status&4) ? "CRITICAL ":"",
--- 257,264 ----
  	sc->sc_capacity = p2[2].Integer.Value;
  	sc->sc_mv = p2[3].Integer.Value;
  
! 	if ((sc->sc_flags & ABAT_F_VERBOSE) &&
! 	    !(sc->sc_status & 2)) {
  		printf("%s: %s%s: %dmV cap %d%s (%d%%) rate %d%s\n",
  		    sc->sc_dev.dv_xname,
  		    (sc->sc_status&4) ? "CRITICAL ":"",
Index: dev/acpi/acpivar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/acpi/acpivar.h,v
retrieving revision 1.4
diff -c -r1.4 acpivar.h
*** dev/acpi/acpivar.h	2002/03/24 03:32:14	1.4
--- dev/acpi/acpivar.h	2002/04/22 20:42:00
***************
*** 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 */
  

--------------4628E8F4B17A0FB3BE666DBB--