PERFORCE change 42354 for review
John Baldwin
jhb at FreeBSD.org
Fri Nov 14 13:21:02 PST 2003
On 14-Nov-2003 Peter Wemm wrote:
> http://perforce.freebsd.org/chv.cgi?CH=42354
>
> Change 42354 by peter at peter_daintree on 2003/11/14 11:00:47
>
> commit jhb's acpi_extirq.patch - remerging it all the time is driving me nuts. I have
> two different machines that need it now. :-/
Does this really help? Do they actualyl route interrupts correctly when
they didn't before? If so, I can commit the patch to CVS, or at least
parts of it.
> Affected files ...
>
> .. //depot/projects/hammer/sys/dev/acpica/acpi_pci_link.c#7 edit
> .. //depot/projects/hammer/sys/dev/acpica/acpi_pcib.c#9 edit
>
> Differences ...
>
> ==== //depot/projects/hammer/sys/dev/acpica/acpi_pci_link.c#7 (text+ko) ====
>
> @@ -43,7 +43,7 @@
> #define _COMPONENT ACPI_BUS
> ACPI_MODULE_NAME("PCI_LINK")
>
> -#define MAX_POSSIBLE_INTERRUPTS 16
> +#define MAX_POSSIBLE_INTERRUPTS 240
> #define MAX_ISA_INTERRUPTS 16
> #define MAX_ACPI_INTERRUPTS 255
>
> @@ -87,10 +87,68 @@
> */
>
> 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 @@
> }
> 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;
> }
>
> @@ -527,10 +549,12 @@
> }
> }
>
> +#if 0
> /* allow initial IRQ as valid one. */
> if (link->initial_irq == irq) {
> return (1);
> }
> +#endif
>
> return (0);
> }
> @@ -565,34 +589,35 @@
>
> 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,
>
> ==== //depot/projects/hammer/sys/dev/acpica/acpi_pcib.c#9 (text+ko) ====
>
> @@ -118,6 +118,8 @@
> 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 @@
> }
>
> /* 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 @@
> *
> * 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 @@
> }
>
> /* 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 @@
> * 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)
--
John Baldwin <jhb at FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve!" - http://www.FreeBSD.org/
More information about the p4-projects
mailing list