| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: acpi_pci_link.c,v 1.22 2014/09/14 19:54:05 mrg Exp $ */ | | 1 | /* $NetBSD: acpi_pci_link.c,v 1.22.26.1 2020/03/08 11:03:19 martin Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2002 Mitsuru IWASAKI <iwasaki@jp.freebsd.org> | | 4 | * Copyright (c) 2002 Mitsuru IWASAKI <iwasaki@jp.freebsd.org> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,27 +17,27 @@ | | | @@ -17,27 +17,27 @@ |
17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | | 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: acpi_pci_link.c,v 1.22 2014/09/14 19:54:05 mrg Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: acpi_pci_link.c,v 1.22.26.1 2020/03/08 11:03:19 martin Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/malloc.h> | | 33 | #include <sys/malloc.h> |
34 | #include <sys/queue.h> | | 34 | #include <sys/queue.h> |
35 | #include <sys/reboot.h> | | 35 | #include <sys/reboot.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | | | 37 | |
38 | #include <dev/acpi/acpireg.h> | | 38 | #include <dev/acpi/acpireg.h> |
39 | #include <dev/acpi/acpivar.h> | | 39 | #include <dev/acpi/acpivar.h> |
40 | | | 40 | |
41 | #include <dev/pci/pcireg.h> | | 41 | #include <dev/pci/pcireg.h> |
42 | | | 42 | |
43 | #include "opt_acpi.h" | | 43 | #include "opt_acpi.h" |
| @@ -245,26 +245,27 @@ link_add_crs(ACPI_RESOURCE *res, void *c | | | @@ -245,26 +245,27 @@ link_add_crs(ACPI_RESOURCE *res, void *c |
245 | break; | | 245 | break; |
246 | default: | | 246 | default: |
247 | req->res_index++; | | 247 | req->res_index++; |
248 | } | | 248 | } |
249 | return (AE_OK); | | 249 | return (AE_OK); |
250 | } | | 250 | } |
251 | | | 251 | |
252 | /* | | 252 | /* |
253 | * Populate the set of possible IRQs for each device. | | 253 | * Populate the set of possible IRQs for each device. |
254 | */ | | 254 | */ |
255 | static ACPI_STATUS | | 255 | static ACPI_STATUS |
256 | link_add_prs(ACPI_RESOURCE *res, void *context) | | 256 | link_add_prs(ACPI_RESOURCE *res, void *context) |
257 | { | | 257 | { |
| | | 258 | ACPI_RESOURCE *tmp; |
258 | struct link_res_request *req; | | 259 | struct link_res_request *req; |
259 | struct link *link; | | 260 | struct link *link; |
260 | uint8_t *irqs = NULL; | | 261 | uint8_t *irqs = NULL; |
261 | uint32_t *ext_irqs = NULL; | | 262 | uint32_t *ext_irqs = NULL; |
262 | int i, is_ext_irq = 1; | | 263 | int i, is_ext_irq = 1; |
263 | | | 264 | |
264 | req = (struct link_res_request *)context; | | 265 | req = (struct link_res_request *)context; |
265 | switch (res->Type) { | | 266 | switch (res->Type) { |
266 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: | | 267 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: |
267 | switch (req->in_dpf) { | | 268 | switch (req->in_dpf) { |
268 | case DPF_OUTSIDE: | | 269 | case DPF_OUTSIDE: |
269 | /* We've started the first DPF. */ | | 270 | /* We've started the first DPF. */ |
270 | req->in_dpf = DPF_FIRST; | | 271 | req->in_dpf = DPF_FIRST; |
| @@ -291,52 +292,48 @@ link_add_prs(ACPI_RESOURCE *res, void *c | | | @@ -291,52 +292,48 @@ link_add_prs(ACPI_RESOURCE *res, void *c |
291 | if (req->in_dpf == DPF_IGNORE) | | 292 | if (req->in_dpf == DPF_IGNORE) |
292 | break; | | 293 | break; |
293 | | | 294 | |
294 | KASSERT(req->link_index < req->sc->pl_num_links); | | 295 | KASSERT(req->link_index < req->sc->pl_num_links); |
295 | link = &req->sc->pl_links[req->link_index]; | | 296 | link = &req->sc->pl_links[req->link_index]; |
296 | if (link->l_res_index == -1) { | | 297 | if (link->l_res_index == -1) { |
297 | KASSERT(req->sc->pl_crs_bad); | | 298 | KASSERT(req->sc->pl_crs_bad); |
298 | link->l_res_index = req->res_index; | | 299 | link->l_res_index = req->res_index; |
299 | } | | 300 | } |
300 | req->link_index++; | | 301 | req->link_index++; |
301 | req->res_index++; | | 302 | req->res_index++; |
302 | | | 303 | |
303 | /* | | 304 | /* |
304 | * Stash a copy of the resource for later use when | | 305 | * Stash a copy of the resource for later use when doing |
305 | * doing _SRS. | | 306 | * _SRS. |
306 | * | | | |
307 | * Note that in theory res->Length may exceed the size | | | |
308 | * of ACPI_RESOURCE, due to variable length lists in | | | |
309 | * subtypes. However, all uses of l_prs_template only | | | |
310 | * rely on lists lengths of zero or one, for which | | | |
311 | * sizeof(ACPI_RESOURCE) is sufficient space anyway. | | | |
312 | * We cannot read longer than Length bytes, in case we | | | |
313 | * read off the end of mapped memory. So we read | | | |
314 | * whichever length is shortest, Length or | | | |
315 | * sizeof(ACPI_RESOURCE). | | | |
316 | */ | | 307 | */ |
317 | KASSERT(res->Length >= ACPI_RS_SIZE_MIN); | | 308 | tmp = &link->l_prs_template; |
| | | 309 | if (is_ext_irq) { |
| | | 310 | memcpy(tmp, res, ACPI_RS_SIZE(tmp->Data.ExtendedIrq)); |
318 | | | 311 | |
319 | memset(&link->l_prs_template, 0, sizeof(link->l_prs_template)); | | 312 | /* |
320 | memcpy(&link->l_prs_template, res, | | 313 | * XXX acpi_AppendBufferResource() cannot handle |
321 | MIN(res->Length, sizeof(link->l_prs_template))); | | 314 | * optional data. |
| | | 315 | */ |
| | | 316 | memset(&tmp->Data.ExtendedIrq.ResourceSource, 0, |
| | | 317 | sizeof(tmp->Data.ExtendedIrq.ResourceSource)); |
| | | 318 | tmp->Length = ACPI_RS_SIZE(tmp->Data.ExtendedIrq); |
322 | | | 319 | |
323 | if (is_ext_irq) { | | | |
324 | link->l_num_irqs = | | 320 | link->l_num_irqs = |
325 | res->Data.ExtendedIrq.InterruptCount; | | 321 | res->Data.ExtendedIrq.InterruptCount; |
326 | link->l_trig = res->Data.ExtendedIrq.Triggering; | | 322 | link->l_trig = res->Data.ExtendedIrq.Triggering; |
327 | link->l_pol = res->Data.ExtendedIrq.Polarity; | | 323 | link->l_pol = res->Data.ExtendedIrq.Polarity; |
328 | ext_irqs = res->Data.ExtendedIrq.Interrupts; | | 324 | ext_irqs = res->Data.ExtendedIrq.Interrupts; |
329 | } else { | | 325 | } else { |
| | | 326 | memcpy(tmp, res, ACPI_RS_SIZE(tmp->Data.Irq)); |
330 | link->l_num_irqs = res->Data.Irq.InterruptCount; | | 327 | link->l_num_irqs = res->Data.Irq.InterruptCount; |
331 | link->l_trig = res->Data.Irq.Triggering; | | 328 | link->l_trig = res->Data.Irq.Triggering; |
332 | link->l_pol = res->Data.Irq.Polarity; | | 329 | link->l_pol = res->Data.Irq.Polarity; |
333 | irqs = res->Data.Irq.Interrupts; | | 330 | irqs = res->Data.Irq.Interrupts; |
334 | } | | 331 | } |
335 | if (link->l_num_irqs == 0) | | 332 | if (link->l_num_irqs == 0) |
336 | break; | | 333 | break; |
337 | | | 334 | |
338 | /* | | 335 | /* |
339 | * Save a list of the valid IRQs. Also, if all of the | | 336 | * Save a list of the valid IRQs. Also, if all of the |
340 | * valid IRQs are ISA IRQs, then mark this link as | | 337 | * valid IRQs are ISA IRQs, then mark this link as |
341 | * routed via an ISA interrupt. | | 338 | * routed via an ISA interrupt. |
342 | */ | | 339 | */ |
| @@ -727,158 +724,139 @@ acpi_pci_link_add_reference(void *v, int | | | @@ -727,158 +724,139 @@ acpi_pci_link_add_reference(void *v, int |
727 | sc->pl_name, bios_irq, link->l_initial_irq); | | 724 | sc->pl_name, bios_irq, link->l_initial_irq); |
728 | } else if (bios_irq != link->l_bios_irq) | | 725 | } else if (bios_irq != link->l_bios_irq) |
729 | printf( | | 726 | printf( |
730 | "%s: BIOS IRQ %u for %d.%d.INT%c does not match " | | 727 | "%s: BIOS IRQ %u for %d.%d.INT%c does not match " |
731 | "previous BIOS IRQ %u\n", | | 728 | "previous BIOS IRQ %u\n", |
732 | sc->pl_name, bios_irq, (int)bus, slot, pin + 'A', | | 729 | sc->pl_name, bios_irq, (int)bus, slot, pin + 'A', |
733 | link->l_bios_irq); | | 730 | link->l_bios_irq); |
734 | ACPI_SERIAL_END(pci_link); | | 731 | ACPI_SERIAL_END(pci_link); |
735 | } | | 732 | } |
736 | | | 733 | |
737 | static ACPI_STATUS | | 734 | static ACPI_STATUS |
738 | acpi_pci_link_srs_from_crs(struct acpi_pci_link_softc *sc, ACPI_BUFFER *srsbuf) | | 735 | acpi_pci_link_srs_from_crs(struct acpi_pci_link_softc *sc, ACPI_BUFFER *srsbuf) |
739 | { | | 736 | { |
740 | ACPI_RESOURCE *resource, *end, newres, *resptr; | | 737 | ACPI_RESOURCE *end, *res; |
741 | ACPI_BUFFER crsbuf; | | | |
742 | ACPI_STATUS status; | | 738 | ACPI_STATUS status; |
743 | struct link *link; | | 739 | struct link *link; |
744 | int i, in_dpf; | | 740 | int i, in_dpf; |
745 | | | 741 | |
746 | /* Fetch the _CRS. */ | | 742 | /* Fetch the _CRS. */ |
747 | crsbuf.Pointer = NULL; | | 743 | srsbuf->Pointer = NULL; |
748 | crsbuf.Length = ACPI_ALLOCATE_LOCAL_BUFFER; | | 744 | srsbuf->Length = ACPI_ALLOCATE_BUFFER; |
749 | status = AcpiGetCurrentResources(sc->pl_handle, &crsbuf); | | 745 | status = AcpiGetCurrentResources(sc->pl_handle, srsbuf); |
750 | if (ACPI_SUCCESS(status) && crsbuf.Pointer == NULL) | | 746 | if (ACPI_SUCCESS(status) && srsbuf->Pointer == NULL) |
751 | status = AE_NO_MEMORY; | | 747 | status = AE_NO_MEMORY; |
752 | if (ACPI_FAILURE(status)) { | | 748 | if (ACPI_FAILURE(status)) { |
753 | aprint_verbose("%s: Unable to fetch current resources: %s\n", | | 749 | aprint_verbose("%s: Unable to fetch current resources: %s\n", |
754 | sc->pl_name, AcpiFormatException(status)); | | 750 | sc->pl_name, AcpiFormatException(status)); |
755 | return (status); | | 751 | return (status); |
756 | } | | 752 | } |
757 | | | 753 | |
758 | /* Fill in IRQ resources via link structures. */ | | 754 | /* Fill in IRQ resources via link structures. */ |
759 | srsbuf->Pointer = NULL; | | | |
760 | link = sc->pl_links; | | 755 | link = sc->pl_links; |
761 | i = 0; | | 756 | i = 0; |
762 | in_dpf = DPF_OUTSIDE; | | 757 | in_dpf = DPF_OUTSIDE; |
763 | resource = (ACPI_RESOURCE *)crsbuf.Pointer; | | 758 | res = (ACPI_RESOURCE *)srsbuf->Pointer; |
764 | end = (ACPI_RESOURCE *)((char *)crsbuf.Pointer + crsbuf.Length); | | 759 | end = (ACPI_RESOURCE *)((char *)srsbuf->Pointer + srsbuf->Length); |
765 | for (;;) { | | 760 | for (;;) { |
766 | switch (resource->Type) { | | 761 | switch (res->Type) { |
767 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: | | 762 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: |
768 | switch (in_dpf) { | | 763 | switch (in_dpf) { |
769 | case DPF_OUTSIDE: | | 764 | case DPF_OUTSIDE: |
770 | /* We've started the first DPF. */ | | 765 | /* We've started the first DPF. */ |
771 | in_dpf = DPF_FIRST; | | 766 | in_dpf = DPF_FIRST; |
772 | break; | | 767 | break; |
773 | case DPF_FIRST: | | 768 | case DPF_FIRST: |
774 | /* We've started the second DPF. */ | | 769 | /* We've started the second DPF. */ |
775 | panic( | | 770 | panic( |
776 | "%s: Multiple dependent functions within a current resource", | | 771 | "%s: Multiple dependent functions within a current resource", |
777 | __func__); | | 772 | __func__); |
778 | break; | | 773 | break; |
779 | } | | 774 | } |
780 | resptr = NULL; | | | |
781 | break; | | 775 | break; |
782 | case ACPI_RESOURCE_TYPE_END_DEPENDENT: | | 776 | case ACPI_RESOURCE_TYPE_END_DEPENDENT: |
783 | /* We are finished with DPF parsing. */ | | 777 | /* We are finished with DPF parsing. */ |
784 | KASSERT(in_dpf != DPF_OUTSIDE); | | 778 | KASSERT(in_dpf != DPF_OUTSIDE); |
785 | in_dpf = DPF_OUTSIDE; | | 779 | in_dpf = DPF_OUTSIDE; |
786 | resptr = NULL; | | | |
787 | break; | | 780 | break; |
788 | case ACPI_RESOURCE_TYPE_IRQ: | | 781 | case ACPI_RESOURCE_TYPE_IRQ: |
789 | newres = link->l_prs_template; | | 782 | res->Data.Irq.InterruptCount = 1; |
790 | resptr = &newres; | | | |
791 | resptr->Data.Irq.InterruptCount = 1; | | | |
792 | if (PCI_INTERRUPT_VALID(link->l_irq)) { | | 783 | if (PCI_INTERRUPT_VALID(link->l_irq)) { |
793 | KASSERT(link->l_irq < NUM_ISA_INTERRUPTS); | | 784 | KASSERT(link->l_irq < NUM_ISA_INTERRUPTS); |
794 | resptr->Data.Irq.Interrupts[0] = link->l_irq; | | 785 | res->Data.Irq.Interrupts[0] = link->l_irq; |
795 | resptr->Data.Irq.Triggering = link->l_trig; | | 786 | res->Data.Irq.Triggering = link->l_trig; |
796 | resptr->Data.Irq.Polarity = link->l_pol; | | 787 | res->Data.Irq.Polarity = link->l_pol; |
797 | } else | | 788 | } else |
798 | resptr->Data.Irq.Interrupts[0] = 0; | | 789 | res->Data.Irq.Interrupts[0] = 0; |
799 | link++; | | 790 | link++; |
800 | i++; | | 791 | i++; |
801 | break; | | 792 | break; |
802 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: | | 793 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
803 | newres = link->l_prs_template; | | 794 | res->Data.ExtendedIrq.InterruptCount = 1; |
804 | resptr = &newres; | | | |
805 | resptr->Data.ExtendedIrq.InterruptCount = 1; | | | |
806 | if (PCI_INTERRUPT_VALID(link->l_irq)) { | | 795 | if (PCI_INTERRUPT_VALID(link->l_irq)) { |
807 | resptr->Data.ExtendedIrq.Interrupts[0] = | | 796 | res->Data.ExtendedIrq.Interrupts[0] = |
808 | link->l_irq; | | 797 | link->l_irq; |
809 | resptr->Data.ExtendedIrq.Triggering = | | 798 | res->Data.ExtendedIrq.Triggering = |
810 | link->l_trig; | | 799 | link->l_trig; |
811 | resptr->Data.ExtendedIrq.Polarity = link->l_pol; | | 800 | res->Data.ExtendedIrq.Polarity = link->l_pol; |
812 | } else | | 801 | } else |
813 | resptr->Data.ExtendedIrq.Interrupts[0] = 0; | | 802 | res->Data.ExtendedIrq.Interrupts[0] = 0; |
814 | link++; | | 803 | link++; |
815 | i++; | | 804 | i++; |
816 | break; | | 805 | break; |
817 | default: | | | |
818 | resptr = resource; | | | |
819 | } | | | |
820 | if (resptr != NULL) { | | | |
821 | status = acpi_AppendBufferResource(srsbuf, resptr); | | | |
822 | if (ACPI_FAILURE(status)) { | | | |
823 | printf("%s: Unable to build resources: %s\n", | | | |
824 | sc->pl_name, AcpiFormatException(status)); | | | |
825 | if (srsbuf->Pointer != NULL) | | | |
826 | ACPI_FREE(srsbuf->Pointer); | | | |
827 | ACPI_FREE(crsbuf.Pointer); | | | |
828 | return (status); | | | |
829 | } | | | |
830 | } | | 806 | } |
831 | if (resource->Type == ACPI_RESOURCE_TYPE_END_TAG) | | 807 | if (res->Type == ACPI_RESOURCE_TYPE_END_TAG) |
832 | break; | | 808 | break; |
833 | resource = ACPI_NEXT_RESOURCE(resource); | | 809 | res = ACPI_NEXT_RESOURCE(res); |
834 | if (resource >= end) | | 810 | if (res >= end) |
835 | break; | | 811 | break; |
836 | } | | 812 | } |
837 | ACPI_FREE(crsbuf.Pointer); | | | |
838 | return (AE_OK); | | 813 | return (AE_OK); |
839 | } | | 814 | } |
840 | | | 815 | |
841 | static ACPI_STATUS | | 816 | static ACPI_STATUS |
842 | acpi_pci_link_srs_from_links(struct acpi_pci_link_softc *sc, | | 817 | acpi_pci_link_srs_from_links(struct acpi_pci_link_softc *sc, |
843 | ACPI_BUFFER *srsbuf) | | 818 | ACPI_BUFFER *srsbuf) |
844 | { | | 819 | { |
845 | ACPI_RESOURCE newres; | | 820 | ACPI_RESOURCE newres; |
846 | ACPI_STATUS status; | | 821 | ACPI_STATUS status; |
847 | struct link *link; | | 822 | struct link *link; |
848 | int i; | | 823 | int i; |
849 | | | 824 | |
850 | /* Start off with an empty buffer. */ | | 825 | /* Start off with an empty buffer. */ |
851 | srsbuf->Pointer = NULL; | | 826 | srsbuf->Pointer = NULL; |
852 | link = sc->pl_links; | | 827 | link = sc->pl_links; |
853 | for (i = 0; i < sc->pl_num_links; i++) { | | 828 | for (i = 0; i < sc->pl_num_links; i++) { |
854 | | | 829 | |
855 | /* Add a new IRQ resource from each link. */ | | 830 | /* Add a new IRQ resource from each link. */ |
856 | link = &sc->pl_links[i]; | | 831 | link = &sc->pl_links[i]; |
857 | newres = link->l_prs_template; | | 832 | if (link->l_prs_template.Type == ACPI_RESOURCE_TYPE_IRQ) { |
858 | if (newres.Type == ACPI_RESOURCE_TYPE_IRQ) { | | | |
859 | | | 833 | |
860 | /* Build an IRQ resource. */ | | 834 | /* Build an IRQ resource. */ |
| | | 835 | bcopy(&link->l_prs_template, &newres, |
| | | 836 | ACPI_RS_SIZE(newres.Data.Irq)); |
861 | newres.Data.Irq.InterruptCount = 1; | | 837 | newres.Data.Irq.InterruptCount = 1; |
862 | if (PCI_INTERRUPT_VALID(link->l_irq)) { | | 838 | if (PCI_INTERRUPT_VALID(link->l_irq)) { |
863 | KASSERT(link->l_irq < NUM_ISA_INTERRUPTS); | | 839 | KASSERT(link->l_irq < NUM_ISA_INTERRUPTS); |
864 | newres.Data.Irq.Interrupts[0] = link->l_irq; | | 840 | newres.Data.Irq.Interrupts[0] = link->l_irq; |
865 | newres.Data.Irq.Triggering = link->l_trig; | | 841 | newres.Data.Irq.Triggering = link->l_trig; |
866 | newres.Data.Irq.Polarity = link->l_pol; | | 842 | newres.Data.Irq.Polarity = link->l_pol; |
867 | } else | | 843 | } else |
868 | newres.Data.Irq.Interrupts[0] = 0; | | 844 | newres.Data.Irq.Interrupts[0] = 0; |
869 | } else { | | 845 | } else { |
870 | | | 846 | |
871 | /* Build an ExtIRQ resuorce. */ | | 847 | /* Build an ExtIRQ resuorce. */ |
| | | 848 | bcopy(&link->l_prs_template, &newres, |
| | | 849 | ACPI_RS_SIZE(newres.Data.ExtendedIrq)); |
872 | newres.Data.ExtendedIrq.InterruptCount = 1; | | 850 | newres.Data.ExtendedIrq.InterruptCount = 1; |
873 | if (PCI_INTERRUPT_VALID(link->l_irq)) { | | 851 | if (PCI_INTERRUPT_VALID(link->l_irq)) { |
874 | newres.Data.ExtendedIrq.Interrupts[0] = | | 852 | newres.Data.ExtendedIrq.Interrupts[0] = |
875 | link->l_irq; | | 853 | link->l_irq; |
876 | newres.Data.ExtendedIrq.Triggering = | | 854 | newres.Data.ExtendedIrq.Triggering = |
877 | link->l_trig; | | 855 | link->l_trig; |
878 | newres.Data.ExtendedIrq.Polarity = | | 856 | newres.Data.ExtendedIrq.Polarity = |
879 | link->l_pol; | | 857 | link->l_pol; |
880 | } else { | | 858 | } else { |
881 | newres.Data.ExtendedIrq.Interrupts[0] = 0; | | 859 | newres.Data.ExtendedIrq.Interrupts[0] = 0; |
882 | } | | 860 | } |
883 | } | | 861 | } |
884 | | | 862 | |