summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/acpica')
-rw-r--r--sys/dev/acpica/acpi_pci_link.c137
-rw-r--r--sys/dev/acpica/acpi_pcib.c67
2 files changed, 127 insertions, 77 deletions
diff --git a/sys/dev/acpica/acpi_pci_link.c b/sys/dev/acpica/acpi_pci_link.c
index 9549f68..88d6c0a 100644
--- a/sys/dev/acpica/acpi_pci_link.c
+++ b/sys/dev/acpica/acpi_pci_link.c
@@ -87,10 +87,68 @@ static int irq_penalty[MAX_ACPI_INTERRUPTS];
*/
static void
+acpi_pci_link_dump_polarity(UINT32 ActiveHighLow)
+{
+
+ switch (ActiveHighLow) {
+ case ACPI_ACTIVE_HIGH:
+ printf("high,");
+ break;
+
+ case ACPI_ACTIVE_LOW:
+ printf("low,");
+ break;
+
+ default:
+ printf("unknown,");
+ break;
+ }
+}
+
+static void
+acpi_pci_link_dump_trigger(UINT32 EdgeLevel)
+{
+
+ switch (EdgeLevel) {
+ case ACPI_EDGE_SENSITIVE:
+ printf("edge,");
+ break;
+
+ case ACPI_LEVEL_SENSITIVE:
+ printf("level,");
+ break;
+
+ default:
+ printf("unknown,");
+ break;
+ }
+}
+
+static void
+acpi_pci_link_dump_sharemode(UINT32 SharedExclusive)
+{
+
+ switch (SharedExclusive) {
+ case ACPI_EXCLUSIVE:
+ printf("exclusive");
+ break;
+
+ case ACPI_SHARED:
+ printf("sharable");
+ break;
+
+ default:
+ printf("unknown");
+ break;
+ }
+}
+
+static void
acpi_pci_link_entry_dump(struct acpi_prt_entry *entry)
{
UINT8 i;
ACPI_RESOURCE_IRQ *Irq;
+ ACPI_RESOURCE_EXT_IRQ *ExtIrq;
if (entry == NULL || entry->pci_link == NULL) {
return;
@@ -105,57 +163,21 @@ acpi_pci_link_entry_dump(struct acpi_prt_entry *entry)
}
printf("] ");
- Irq = NULL;
switch (entry->pci_link->possible_resources.Id) {
case ACPI_RSTYPE_IRQ:
Irq = &entry->pci_link->possible_resources.Data.Irq;
- switch (Irq->ActiveHighLow) {
- case ACPI_ACTIVE_HIGH:
- printf("high,");
- break;
-
- case ACPI_ACTIVE_LOW:
- printf("low,");
- break;
-
- default:
- printf("unknown,");
- break;
- }
-
- switch (Irq->EdgeLevel) {
- case ACPI_EDGE_SENSITIVE:
- printf("edge,");
- break;
-
- case ACPI_LEVEL_SENSITIVE:
- printf("level,");
- break;
-
- default:
- printf("unknown,");
- break;
- }
-
- switch (Irq->SharedExclusive) {
- case ACPI_EXCLUSIVE:
- printf("exclusive");
- break;
-
- case ACPI_SHARED:
- printf("sharable");
- break;
-
- default:
- printf("unknown");
- break;
- }
-
+ acpi_pci_link_dump_polarity(Irq->ActiveHighLow);
+ acpi_pci_link_dump_trigger(Irq->EdgeLevel);
+ acpi_pci_link_dump_sharemode(Irq->SharedExclusive);
break;
case ACPI_RSTYPE_EXT_IRQ:
- /* TBD */
+ ExtIrq = &entry->pci_link->possible_resources.Data.ExtendedIrq;
+
+ acpi_pci_link_dump_polarity(ExtIrq->ActiveHighLow);
+ acpi_pci_link_dump_trigger(ExtIrq->EdgeLevel);
+ acpi_pci_link_dump_sharemode(ExtIrq->SharedExclusive);
break;
}
@@ -565,34 +587,35 @@ acpi_pci_link_set_irq(struct acpi_pci_link_entry *link, UINT8 irq)
bzero(&resbuf, sizeof(resbuf));
crsbuf.Pointer = NULL;
- resbuf.Id = ACPI_RSTYPE_IRQ;
- resbuf.Length = ACPI_SIZEOF_RESOURCE(ACPI_RESOURCE_IRQ);
- if (link->possible_resources.Id != ACPI_RSTYPE_IRQ &&
- link->possible_resources.Id != ACPI_RSTYPE_EXT_IRQ) {
+ switch (link->possible_resources.Id) {
+ default:
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Resource is not an IRQ entry %s - %d\n",
acpi_name(link->handle), link->possible_resources.Id));
return_ACPI_STATUS (AE_TYPE);
- }
- switch (link->possible_resources.Id) {
case ACPI_RSTYPE_IRQ:
+ resbuf.Id = ACPI_RSTYPE_IRQ;
+ resbuf.Length = ACPI_SIZEOF_RESOURCE(ACPI_RESOURCE_IRQ);
+
/* structure copy other fields */
resbuf.Data.Irq = link->possible_resources.Data.Irq;
+ resbuf.Data.Irq.NumberOfInterrupts = 1;
+ resbuf.Data.Irq.Interrupts[0] = irq;
break;
case ACPI_RSTYPE_EXT_IRQ:
- /* XXX */
- resbuf.Data.Irq.EdgeLevel = ACPI_LEVEL_SENSITIVE;
- resbuf.Data.Irq.ActiveHighLow = ACPI_ACTIVE_LOW;
- resbuf.Data.Irq.SharedExclusive = ACPI_SHARED;
+ resbuf.Id = ACPI_RSTYPE_EXT_IRQ;
+ resbuf.Length = ACPI_SIZEOF_RESOURCE(ACPI_RESOURCE_EXT_IRQ);
+
+ /* structure copy other fields */
+ resbuf.Data.ExtendedIrq = link->possible_resources.Data.ExtendedIrq;
+ resbuf.Data.ExtendedIrq.NumberOfInterrupts = 1;
+ resbuf.Data.ExtendedIrq.Interrupts[0] = irq;
break;
}
- resbuf.Data.Irq.NumberOfInterrupts = 1;
- resbuf.Data.Irq.Interrupts[0] = irq;
-
error = acpi_AppendBufferResource(&crsbuf, &resbuf);
if (ACPI_FAILURE(error)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
diff --git a/sys/dev/acpica/acpi_pcib.c b/sys/dev/acpica/acpi_pcib.c
index ab721df..731b040 100644
--- a/sys/dev/acpica/acpi_pcib.c
+++ b/sys/dev/acpica/acpi_pcib.c
@@ -118,6 +118,8 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,
ACPI_DEVICE_INFO devinfo;
ACPI_BUFFER buf = {sizeof(devinfo), &devinfo};
ACPI_STATUS status;
+ UINT32 NumberOfInterrupts;
+ UINT32 *Interrupts;
u_int8_t *prtp;
int interrupt;
int i;
@@ -234,16 +236,25 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,
}
/* type-check the resource we've got */
- if (crsres->Id != ACPI_RSTYPE_IRQ) { /* XXX ACPI_RSTYPE_EXT_IRQ */
+ if (crsres->Id != ACPI_RSTYPE_IRQ && crsres->Id != ACPI_RSTYPE_EXT_IRQ) {
device_printf(pcib, "_CRS resource entry has unsupported type %d\n",
crsres->Id);
goto out;
}
+ /* set variables based on resource type */
+ if (crsres->Id == ACPI_RSTYPE_IRQ) {
+ NumberOfInterrupts = crsres->Data.Irq.NumberOfInterrupts;
+ Interrupts = crsres->Data.Irq.Interrupts;
+ } else {
+ NumberOfInterrupts = crsres->Data.ExtendedIrq.NumberOfInterrupts;
+ Interrupts = crsres->Data.ExtendedIrq.Interrupts;
+ }
+
/* if there's more than one interrupt, we are confused */
- if (crsres->Data.Irq.NumberOfInterrupts > 1) {
+ if (NumberOfInterrupts > 1) {
device_printf(pcib, "device has too many interrupts (%d)\n",
- crsres->Data.Irq.NumberOfInterrupts);
+ NumberOfInterrupts);
goto out;
}
@@ -255,10 +266,10 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,
*
* XXX check ASL examples to see if this is an acceptable set of tests
*/
- if ((crsres->Data.Irq.NumberOfInterrupts == 1) && (crsres->Data.Irq.Interrupts[0] != 0)) {
+ if ((NumberOfInterrupts == 1) && (Interrupts[0] != 0)) {
device_printf(pcib, "slot %d INT%c is routed to irq %d\n",
- pci_get_slot(dev), 'A' + pin, crsres->Data.Irq.Interrupts[0]);
- interrupt = crsres->Data.Irq.Interrupts[0];
+ pci_get_slot(dev), 'A' + pin, Interrupts[0]);
+ interrupt = Interrupts[0];
goto out;
}
@@ -276,14 +287,23 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,
}
/* type-check the resource we've got */
- if (prsres->Id != ACPI_RSTYPE_IRQ) { /* XXX ACPI_RSTYPE_EXT_IRQ */
+ if (prsres->Id != ACPI_RSTYPE_IRQ || prsres->Id != ACPI_RSTYPE_EXT_IRQ) {
device_printf(pcib, "_PRS resource entry has unsupported type %d\n",
prsres->Id);
goto out;
}
+ /* set variables based on resource type */
+ if (prsres->Id == ACPI_RSTYPE_IRQ) {
+ NumberOfInterrupts = prsres->Data.Irq.NumberOfInterrupts;
+ Interrupts = prsres->Data.Irq.Interrupts;
+ } else {
+ NumberOfInterrupts = prsres->Data.ExtendedIrq.NumberOfInterrupts;
+ Interrupts = prsres->Data.ExtendedIrq.Interrupts;
+ }
+
/* there has to be at least one interrupt available */
- if (prsres->Data.Irq.NumberOfInterrupts < 1) {
+ if (NumberOfInterrupts < 1) {
device_printf(pcib, "device has no interrupts\n");
goto out;
}
@@ -300,34 +320,41 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,
* new interrupt.
*/
device_printf(pcib, "possible interrupts:");
- for (i = 0; i < prsres->Data.Irq.NumberOfInterrupts; i++)
- printf(" %d", prsres->Data.Irq.Interrupts[i]);
+ for (i = 0; i < NumberOfInterrupts; i++)
+ printf(" %d", Interrupts[i]);
printf("\n");
if (crsbuf.Pointer != NULL) /* should never happen */
AcpiOsFree(crsbuf.Pointer);
crsbuf.Pointer = NULL;
- resbuf.Id = ACPI_RSTYPE_IRQ;
- 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] = prsres->Data.Irq.Interrupts[0]; /* just take first... */
+ if (prsres->Id == ACPI_RSTYPE_IRQ) {
+ resbuf.Id = ACPI_RSTYPE_IRQ;
+ 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... */
+ } 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... */
+ }
if (ACPI_FAILURE(status = acpi_AppendBufferResource(&crsbuf, &resbuf))) {
device_printf(pcib, "couldn't route interrupt %d via %s, interrupt resource build failed - %s\n",
- prsres->Data.Irq.Interrupts[0], acpi_name(lnkdev), AcpiFormatException(status));
+ Interrupts[0], 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",
- prsres->Data.Irq.Interrupts[0], acpi_name(lnkdev), AcpiFormatException(status));
+ Interrupts[0], 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, prsres->Data.Irq.Interrupts[0],
- acpi_name(lnkdev));
- interrupt = prsres->Data.Irq.Interrupts[0];
+ pci_get_slot(dev), 'A' + pin, Interrupts[0], acpi_name(lnkdev));
+ interrupt = Interrupts[0];
out:
if (crsbuf.Pointer != NULL)
OpenPOWER on IntegriCloud