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--