Lines Matching full:link
50 ACPI_SERIAL_DECL(pci_link, "ACPI PCI link");
56 * An ACPI PCI link device may contain multiple links. Each link has its
57 * own ACPI resource. _PRT entries specify which link is being used via
86 struct link;
91 struct link *pl_links;
95 struct link { struct
122 static MALLOC_DEFINE(M_PCI_LINK, "pci_link", "ACPI PCI Link structures");
161 device_set_descf(dev, "ACPI PCI Link %s", name); in acpi_pci_link_probe()
163 device_set_desc(dev, "ACPI PCI Link"); in acpi_pci_link_probe()
209 struct link *link; in link_add_crs() local
238 link = &req->sc->pl_links[req->link_index]; in link_add_crs()
239 link->l_res_index = req->res_index; in link_add_crs()
240 link->l_crs_type = res->Type; in link_add_crs()
247 * when the link hasn't been programmed. in link_add_crs()
251 link->l_irq = res->Data.Irq.Interrupts[0]; in link_add_crs()
253 link->l_irq = res->Data.ExtendedIrq.Interrupts[0]; in link_add_crs()
256 * An IRQ of zero means that the link isn't routed. in link_add_crs()
258 if (link->l_irq == 0) in link_add_crs()
259 link->l_irq = PCI_INVALID_IRQ; in link_add_crs()
275 struct link *link; in link_add_prs() local
314 link = &req->sc->pl_links[req->link_index]; in link_add_prs()
315 if (link->l_res_index == -1) { in link_add_prs()
318 link->l_res_index = req->res_index; in link_add_prs()
327 tmp = &link->l_prs_template; in link_add_prs()
339 link->l_num_irqs = in link_add_prs()
344 link->l_num_irqs = res->Data.Irq.InterruptCount; in link_add_prs()
347 if (link->l_num_irqs == 0) in link_add_prs()
352 * valid IRQs are ISA IRQs, then mark this link as in link_add_prs()
355 link->l_isa_irq = true; in link_add_prs()
356 link->l_irqs = malloc(sizeof(int) * link->l_num_irqs, in link_add_prs()
358 for (i = 0; i < link->l_num_irqs; i++) { in link_add_prs()
360 link->l_irqs[i] = ext_irqs[i]; in link_add_prs()
362 link->l_isa_irq = false; in link_add_prs()
364 link->l_irqs[i] = irqs[i]; in link_add_prs()
366 link->l_isa_irq = false; in link_add_prs()
374 if (!req->sc->pl_crs_bad && !link->l_isa_irq && in link_add_prs()
375 link->l_crs_type == ACPI_RESOURCE_TYPE_IRQ) in link_add_prs()
391 link_valid_irq(struct link *link, int irq) in link_valid_irq() argument
402 for (i = 0; i < link->l_num_irqs; i++) in link_valid_irq()
403 if (link->l_irqs[i] == irq) in link_valid_irq()
410 if (link->l_isa_irq && AcpiGbl_FADT.SciInterrupt == irq && in link_valid_irq()
421 struct link *link; in acpi_pci_link_dump() local
432 link = &sc->pl_links[i]; in acpi_pci_link_dump()
434 link->l_irq, link->l_routed ? 'Y' : 'N', in acpi_pci_link_dump()
435 link->l_references); in acpi_pci_link_dump()
436 if (link->l_num_irqs == 0) in acpi_pci_link_dump()
438 else for (j = 0; j < link->l_num_irqs; j++) in acpi_pci_link_dump()
439 printf(" %d", link->l_irqs[j]); in acpi_pci_link_dump()
459 * a link array to allocate. On some systems, _CRS is broken, in acpi_pci_link_attach()
485 sc->pl_links = malloc(sizeof(struct link) * sc->pl_num_links, in acpi_pci_link_attach()
546 * Try to disable this link. If successful, set the current IRQ to in acpi_pci_link_attach()
547 * zero and flags to indicate this link is not routed. If we can't in acpi_pci_link_attach()
620 * Find the link structure that corresponds to the resource index passed in
623 static struct link *
641 struct link *link; in acpi_pci_link_add_reference() local
662 link = acpi_pci_link_lookup(dev, index); in acpi_pci_link_add_reference()
663 if (link == NULL) { in acpi_pci_link_add_reference()
668 link->l_references++; in acpi_pci_link_add_reference()
669 if (link->l_routed) in acpi_pci_link_add_reference()
670 pci_link_interrupt_weights[link->l_irq]++; in acpi_pci_link_add_reference()
674 * (8259As). Thus, if this link is routed via an ISA IRQ, go in acpi_pci_link_add_reference()
675 * look to see if the BIOS routed an IRQ for this link at the in acpi_pci_link_add_reference()
677 * this link and add that IRQ to our list of known-good IRQs. in acpi_pci_link_add_reference()
678 * This provides a good work-around for link devices whose _CRS in acpi_pci_link_add_reference()
683 * If this link is not routed via an ISA IRQ (because we are using in acpi_pci_link_add_reference()
687 if (!link->l_isa_irq) { in acpi_pci_link_add_reference()
700 if (!link_valid_irq(link, bios_irq)) { in acpi_pci_link_add_reference()
703 } else if (!PCI_INTERRUPT_VALID(link->l_bios_irq)) { in acpi_pci_link_add_reference()
704 link->l_bios_irq = bios_irq; in acpi_pci_link_add_reference()
707 if (bios_irq != link->l_initial_irq && in acpi_pci_link_add_reference()
708 PCI_INTERRUPT_VALID(link->l_initial_irq)) in acpi_pci_link_add_reference()
711 bios_irq, link->l_initial_irq); in acpi_pci_link_add_reference()
712 } else if (bios_irq != link->l_bios_irq) in acpi_pci_link_add_reference()
716 link->l_bios_irq); in acpi_pci_link_add_reference()
725 struct link *link; in acpi_pci_link_srs_from_crs() local
743 /* Fill in IRQ resources via link structures. */ in acpi_pci_link_srs_from_crs()
744 link = sc->pl_links; in acpi_pci_link_srs_from_crs()
774 if (PCI_INTERRUPT_VALID(link->l_irq)) { in acpi_pci_link_srs_from_crs()
775 KASSERT(link->l_irq < NUM_ISA_INTERRUPTS, in acpi_pci_link_srs_from_crs()
777 __func__, link->l_irq)); in acpi_pci_link_srs_from_crs()
778 res->Data.Irq.Interrupts[0] = link->l_irq; in acpi_pci_link_srs_from_crs()
781 link++; in acpi_pci_link_srs_from_crs()
787 if (PCI_INTERRUPT_VALID(link->l_irq)) in acpi_pci_link_srs_from_crs()
789 link->l_irq; in acpi_pci_link_srs_from_crs()
792 link++; in acpi_pci_link_srs_from_crs()
811 struct link *link; in acpi_pci_link_srs_from_links() local
816 link = sc->pl_links; in acpi_pci_link_srs_from_links()
818 /* Add a new IRQ resource from each link. */ in acpi_pci_link_srs_from_links()
819 link = &sc->pl_links[i]; in acpi_pci_link_srs_from_links()
820 if (link->l_prs_template.Type == ACPI_RESOURCE_TYPE_IRQ) { in acpi_pci_link_srs_from_links()
822 bcopy(&link->l_prs_template, &newres, in acpi_pci_link_srs_from_links()
825 if (PCI_INTERRUPT_VALID(link->l_irq)) { in acpi_pci_link_srs_from_links()
826 KASSERT(link->l_irq < NUM_ISA_INTERRUPTS, in acpi_pci_link_srs_from_links()
828 __func__, link->l_irq)); in acpi_pci_link_srs_from_links()
829 newres.Data.Irq.Interrupts[0] = link->l_irq; in acpi_pci_link_srs_from_links()
834 bcopy(&link->l_prs_template, &newres, in acpi_pci_link_srs_from_links()
837 if (PCI_INTERRUPT_VALID(link->l_irq)) in acpi_pci_link_srs_from_links()
839 link->l_irq; in acpi_pci_link_srs_from_links()
867 struct link *link; in acpi_pci_link_route_irqs() local
892 link = sc->pl_links; in acpi_pci_link_route_irqs()
906 * weights if this link has a valid IRQ and was in acpi_pci_link_route_irqs()
909 if (!link->l_routed && in acpi_pci_link_route_irqs()
910 PCI_INTERRUPT_VALID(link->l_irq)) { in acpi_pci_link_route_irqs()
911 link->l_routed = true; in acpi_pci_link_route_irqs()
913 pci_link_interrupt_weights[link->l_irq] += in acpi_pci_link_route_irqs()
914 link->l_references; in acpi_pci_link_route_irqs()
916 link++; in acpi_pci_link_route_irqs()
936 * If all of our links are routed, then restore the link via _SRS, in acpi_pci_link_resume()
937 * otherwise, disable the link via _DIS. in acpi_pci_link_resume()
959 * Pick an IRQ to use for this unrouted link.
962 acpi_pci_link_choose_irq(device_t dev, struct link *link) in acpi_pci_link_choose_irq() argument
968 KASSERT(!link->l_routed, ("%s: link already routed", __func__)); in acpi_pci_link_choose_irq()
969 KASSERT(!PCI_INTERRUPT_VALID(link->l_irq), in acpi_pci_link_choose_irq()
970 ("%s: link already has an IRQ", __func__)); in acpi_pci_link_choose_irq()
976 "hw.pci.link.%s.%d.irq", link_name, link->l_res_index); in acpi_pci_link_choose_irq()
978 if (!link_valid_irq(link, i)) in acpi_pci_link_choose_irq()
985 "hw.pci.link.%s.irq", link_name); in acpi_pci_link_choose_irq()
987 if (!link_valid_irq(link, i)) in acpi_pci_link_choose_irq()
997 * says it routed over what _CRS says the link thinks is routed. in acpi_pci_link_choose_irq()
999 if (PCI_INTERRUPT_VALID(link->l_bios_irq)) in acpi_pci_link_choose_irq()
1000 return (link->l_bios_irq); in acpi_pci_link_choose_irq()
1006 if (PCI_INTERRUPT_VALID(link->l_initial_irq)) in acpi_pci_link_choose_irq()
1007 return (link->l_initial_irq); in acpi_pci_link_choose_irq()
1016 for (i = 0; i < link->l_num_irqs; i++) { in acpi_pci_link_choose_irq()
1017 pos_irq = link->l_irqs[i]; in acpi_pci_link_choose_irq()
1032 if (link->l_isa_irq) { in acpi_pci_link_choose_irq()
1053 struct link *link; in acpi_pci_link_route_interrupt() local
1059 link = acpi_pci_link_lookup(dev, index); in acpi_pci_link_route_interrupt()
1060 if (link == NULL) in acpi_pci_link_route_interrupt()
1064 * If this link device is already routed to an interrupt, just return in acpi_pci_link_route_interrupt()
1067 if (link->l_routed) { in acpi_pci_link_route_interrupt()
1068 KASSERT(PCI_INTERRUPT_VALID(link->l_irq), in acpi_pci_link_route_interrupt()
1069 ("%s: link is routed but has an invalid IRQ", __func__)); in acpi_pci_link_route_interrupt()
1071 return (link->l_irq); in acpi_pci_link_route_interrupt()
1075 if (!PCI_INTERRUPT_VALID(link->l_irq)) { in acpi_pci_link_route_interrupt()
1076 link->l_irq = acpi_pci_link_choose_irq(dev, link); in acpi_pci_link_route_interrupt()
1082 if (PCI_INTERRUPT_VALID(link->l_irq)) { in acpi_pci_link_route_interrupt()
1084 if (!link->l_routed) in acpi_pci_link_route_interrupt()
1085 link->l_irq = PCI_INVALID_IRQ; in acpi_pci_link_route_interrupt()
1090 return (link->l_irq); in acpi_pci_link_route_interrupt()