-/* $OpenBSD: acpipci.c,v 1.1 2018/07/05 19:25:38 kettenis Exp $ */
+/* $OpenBSD: acpipci.c,v 1.2 2018/07/10 17:11:42 kettenis Exp $ */
/*
* Copyright (c) 2018 Mark Kettenis
*
int ih_msi;
};
-struct aml_node *acpi_pci_match(struct device *, struct pci_attach_args *);
-
int
acpipci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
{
+ struct acpipci_softc *sc = pa->pa_pc->pc_intr_v;
+ struct aml_node *node;
+ struct aml_value res;
+ uint64_t addr, pin, source, index;
+ struct acpipci_intr_handle *ih;
+ int i;
+
+ if (pa->pa_bridgetag == NULL)
+ return -1;
+
+ node = acpi_find_pci(pa->pa_pc, *pa->pa_bridgetag);
+ if (node == NULL)
+ return -1;
+
+ if (aml_evalname(sc->sc_acpi, node, "_PRT", 0, NULL, &res))
+ return -1;
+
+ if (res.type != AML_OBJTYPE_PACKAGE)
+ return -1;
+
+ for (i = 0; i < res.length; i++) {
+ struct aml_value *val = res.v_package[i];
+
+ if (val->type != AML_OBJTYPE_PACKAGE)
+ continue;
+ if (val->length != 4)
+ continue;
+ if (val->v_package[0]->type != AML_OBJTYPE_INTEGER ||
+ val->v_package[1]->type != AML_OBJTYPE_INTEGER ||
+ val->v_package[2]->type != AML_OBJTYPE_INTEGER ||
+ val->v_package[3]->type != AML_OBJTYPE_INTEGER)
+ continue;
+
+ addr = val->v_package[0]->v_integer;
+ pin = val->v_package[1]->v_integer;
+ source = val->v_package[2]->v_integer;
+ index = val->v_package[3]->v_integer;
+ if (ACPI_ADR_PCIDEV(addr) != pa->pa_device ||
+ ACPI_ADR_PCIFUN(addr) != 0xffff ||
+ pin != pa->pa_intrpin - 1 || source != 0)
+ continue;
+
+ ih = malloc(sizeof(struct acpipci_intr_handle),
+ M_DEVBUF, M_WAITOK);
+ ih->ih_pc = pa->pa_pc;
+ ih->ih_tag = pa->pa_tag;
+ ih->ih_intrpin = index;
+ ih->ih_msi = 0;
+ *ihp = (pci_intr_handle_t)ih;
+
+ return 0;
+ }
+
return -1;
}
acpipci_intr_string(void *v, pci_intr_handle_t ihp)
{
struct acpipci_intr_handle *ih = (struct acpipci_intr_handle *)ihp;
+ static char irqstr[32];
if (ih->ih_msi)
return "msi";
- return "intx";
+ snprintf(irqstr, sizeof(irqstr), "irq %d", ih->ih_intrpin);
+ return irqstr;
}
void *
}
pci_conf_write(ih->ih_pc, ih->ih_tag,
off, reg | PCI_MSI_MC_MSIE);
+ } else {
+ cookie = acpi_intr_establish(ih->ih_intrpin, 0, level,
+ func, arg, name);
}
free(ih, M_DEVBUF, sizeof(struct acpipci_intr_handle));
-/* $OpenBSD: acpi.c,v 1.354 2018/07/05 19:25:38 kettenis Exp $ */
+/* $OpenBSD: acpi.c,v 1.355 2018/07/10 17:11:42 kettenis Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
return (1);
}
+struct aml_node *
+acpi_find_pci(pci_chipset_tag_t pc, pcitag_t tag)
+{
+ struct acpi_pci *pdev;
+ int bus, dev, fun;
+
+ pci_decompose_tag(pc, tag, &bus, &dev, &fun);
+ TAILQ_FOREACH(pdev, &acpi_pcidevs, next) {
+ if (pdev->bus == bus && pdev->dev == dev && pdev->fun == fun)
+ return pdev->node;
+ }
+
+ return NULL;
+}
+
struct aml_node *
acpi_pci_match(struct device *dev, struct pci_attach_args *pa)
{
-/* $OpenBSD: acpivar.h,v 1.95 2018/07/04 20:46:22 kettenis Exp $ */
+/* $OpenBSD: acpivar.h,v 1.96 2018/07/10 17:11:42 kettenis Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
void acpi_pciroots_attach(struct device *, void *, cfprint_t);
void acpi_attach_deps(struct acpi_softc *, struct aml_node *);
+struct aml_node *acpi_find_pci(pci_chipset_tag_t, pcitag_t);
+
void *acpi_intr_establish(int, int, int, int (*)(void *), void *,
const char *);