summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica/acpi_pcib_acpi.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>2001-07-30 09:01:18 +0000
committermsmith <msmith@FreeBSD.org>2001-07-30 09:01:18 +0000
commit9b55e30943ee0f5f3cdbce56160cf5830b35453f (patch)
tree9caa0422e079b11d5e02c76e15a6ede258c9e784 /sys/dev/acpica/acpi_pcib_acpi.c
parentf3637b944d3ff9ce2560aca5c4ebfb9546237ab3 (diff)
downloadFreeBSD-src-9b55e30943ee0f5f3cdbce56160cf5830b35453f.zip
FreeBSD-src-9b55e30943ee0f5f3cdbce56160cf5830b35453f.tar.gz
The current resource buffer returned from an interrupt link device
in the case where there are no interrupts routed for it does not contain enough space to use it to route an interrupt. In the case where we need to route an interrupt, throw away the returned buffer and create a new one containing the interrupt we want.
Diffstat (limited to 'sys/dev/acpica/acpi_pcib_acpi.c')
-rw-r--r--sys/dev/acpica/acpi_pcib_acpi.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/sys/dev/acpica/acpi_pcib_acpi.c b/sys/dev/acpica/acpi_pcib_acpi.c
index 7bbd429..44821e6 100644
--- a/sys/dev/acpica/acpi_pcib_acpi.c
+++ b/sys/dev/acpica/acpi_pcib_acpi.c
@@ -283,7 +283,7 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
PCI_ROUTING_TABLE *prt;
ACPI_HANDLE lnkdev;
ACPI_BUFFER crsbuf, prsbuf;
- ACPI_RESOURCE *crsres, *prsres;
+ ACPI_RESOURCE *crsres, *prsres, resbuf;
ACPI_DEVICE_INFO devinfo;
ACPI_STATUS status;
u_int8_t *prtp;
@@ -403,7 +403,7 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
*
* The Source Index points to the particular resource entry we're interested in.
*/
- if (ACPI_FAILURE(acpi_FindIndexedResource((ACPI_RESOURCE *)crsbuf.Pointer, prt->SourceIndex, &crsres))) {
+ if (ACPI_FAILURE(acpi_FindIndexedResource(&crsbuf, prt->SourceIndex, &crsres))) {
device_printf(sc->ap_dev, "_CRS buffer corrupt, cannot route interrupt\n");
goto out;
}
@@ -442,7 +442,7 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
device_printf(sc->ap_dev, "device has no routed interrupt and no _PRS on PCI interrupt link device\n");
goto out;
}
- if (ACPI_FAILURE(acpi_FindIndexedResource((ACPI_RESOURCE *)prsbuf.Pointer, prt->SourceIndex, &prsres))) {
+ if (ACPI_FAILURE(acpi_FindIndexedResource(&prsbuf, prt->SourceIndex, &prsres))) {
device_printf(sc->ap_dev, "_PRS buffer corrupt, cannot route interrupt\n");
goto out;
}
@@ -467,15 +467,28 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
* seem to offer a similar mechanism, so picking a "good" interrupt here is a
* difficult task.
*
- * Populate our copy of _CRS and pass it back to _SRS to set the interrupt.
+ * Build a resource buffer and pass it to AcpiSetCurrentResources to route the
+ * new interrupt.
*/
device_printf(sc->ap_dev, "possible interrupts:");
for (i = 0; i < prsres->Data.Irq.NumberOfInterrupts; i++)
printf(" %d", prsres->Data.Irq.Interrupts[i]);
printf("\n");
- crsres->Data.Irq.Interrupts[0] = prsres->Data.Irq.Interrupts[0];
- crsres->Data.Irq.NumberOfInterrupts = 1;
- if (ACPI_FAILURE(status = AcpiSetCurrentResources(lnkdev, &crsbuf))) {
+
+ if (crsbuf.Pointer != NULL) /* should never happen */
+ AcpiOsFree(crsbuf.Pointer);
+ crsbuf.Pointer = NULL;
+ resbuf.Id = ACPI_RSTYPE_IRQ;
+ resbuf.Length = 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] = prsres->Data.Irq.Interrupts[0]; /* just take first... */
+ if (ACPI_FAILURE(status = acpi_AppendBufferResource(&crsbuf, &resbuf))) {
+ device_printf(sc->ap_dev, "couldn't route interrupt %d via %s, interupt resource build failed - %s\n",
+ prsres->Data.Irq.Interrupts[0], acpi_name(lnkdev), AcpiFormatException(status));
+ goto out;
+ }
+ if (ACPI_FAILURE(status = AcpiSetCurrentResources(lnkdev, &resbuf))) {
device_printf(sc->ap_dev, "couldn't route interrupt %d via %s - %s\n",
prsres->Data.Irq.Interrupts[0], acpi_name(lnkdev), AcpiFormatException(status));
goto out;
OpenPOWER on IntegriCloud