summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2017-01-08 12:39:16 +0000
committerkettenis <kettenis@openbsd.org>2017-01-08 12:39:16 +0000
commit6f0b623a19a0e5eb6b7db5d55e3529d223fe91af (patch)
tree6f832a0256a09f0493a4b86ceb2577d196064849
parentDisplay color depth alongside resolution when attaching inteldrm and (diff)
downloadwireguard-openbsd-6f0b623a19a0e5eb6b7db5d55e3529d223fe91af.tar.xz
wireguard-openbsd-6f0b623a19a0e5eb6b7db5d55e3529d223fe91af.zip
Make aml_rdpciaddr() work for for devices behind bridges. The code now
uses the mapping between AML nodes and PCI devices that we establish. Because _INIT methods may end up calling aml_rdpciaddr(), make sure we create that mapping early. Also handle devices that aren't actually present. These devices are now included in the mapping and reads will return an all-ones patterm whereas writes are a no-op.. ok mlarkin@
-rw-r--r--sys/dev/acpi/acpi.c22
-rw-r--r--sys/dev/acpi/dsdt.c34
2 files changed, 26 insertions, 30 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index cd1ee4b44da..b2e94dbc103 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.317 2016/10/25 06:48:58 pirofti Exp $ */
+/* $OpenBSD: acpi.c,v 1.318 2017/01/08 12:39:16 kettenis Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -614,6 +614,7 @@ acpi_getpci(struct aml_node *node, void *arg)
pci->dev = ACPI_ADR_PCIDEV(val);
pci->fun = ACPI_ADR_PCIFUN(val);
pci->node = node;
+ node->pci = pci;
pci->sub = -1;
dnprintf(10, "%.2x:%.2x.%x -> %s\n",
@@ -639,17 +640,12 @@ acpi_getpci(struct aml_node *node, void *arg)
pci->_s4w = -1;
/* Check if PCI device exists */
- if (pci->dev > 0x1F || pci->fun > 7) {
- free(pci, M_DEVBUF, sizeof(*pci));
- return (1);
- }
+ if (pci->dev > 31 || pci->fun > 7)
+ return 1;
tag = pci_make_tag(pc, pci->bus, pci->dev, pci->fun);
reg = pci_conf_read(pc, tag, PCI_ID_REG);
- if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID) {
- free(pci, M_DEVBUF, sizeof(*pci));
- return (1);
- }
- node->pci = pci;
+ if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID)
+ return 1;
TAILQ_INSERT_TAIL(&acpi_pcidevs, pci, next);
@@ -1066,12 +1062,12 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
config_found_sm(self, &aaa, acpi_print, acpi_submatch);
}
+ /* get PCI mapping */
+ aml_walknodes(&aml_root, AML_WALK_PRE, acpi_getpci, sc);
+
/* initialize runtime environment */
aml_find_node(&aml_root, "_INI", acpi_inidev, sc);
- /* Get PCI mapping */
- aml_walknodes(&aml_root, AML_WALK_PRE, acpi_getpci, sc);
-
/* attach pci interrupt routing tables */
aml_find_node(&aml_root, "_PRT", acpi_foundprt, sc);
diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c
index 078883256b2..dd9e7d28feb 100644
--- a/sys/dev/acpi/dsdt.c
+++ b/sys/dev/acpi/dsdt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.c,v 1.228 2016/12/18 15:59:22 kettenis Exp $ */
+/* $OpenBSD: dsdt.c,v 1.229 2017/01/08 12:39:16 kettenis Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
@@ -2218,21 +2218,16 @@ aml_rdpciaddr(struct aml_node *pcidev, union amlpci_t *addr)
{
int64_t res;
- if (aml_evalinteger(acpi_softc, pcidev, "_ADR", 0, NULL, &res) == 0) {
- addr->fun = res & 0xFFFF;
- addr->dev = res >> 16;
- }
- while (pcidev != NULL) {
- /* HID device (PCI or PCIE root): eval _BBN */
- if (__aml_search(pcidev, "_HID", 0)) {
- if (aml_evalinteger(acpi_softc, pcidev, "_BBN", 0, NULL, &res) == 0) {
- addr->bus = res;
- break;
- }
- }
- pcidev = pcidev->parent;
- }
- return (0);
+ if (pcidev->pci == NULL)
+ return -1;
+
+ if (aml_evalinteger(acpi_softc, pcidev, "_ADR", 0, NULL, &res))
+ return -1;
+
+ addr->fun = res & 0xffff;
+ addr->dev = res >> 16;
+ addr->bus = pcidev->pci->bus;
+ return 0;
}
/* Read/Write from opregion object */
@@ -2274,7 +2269,12 @@ aml_rwgas(struct aml_value *rgn, int bpos, int blen, struct aml_value *val,
if (rgn->v_opregion.iospace == GAS_PCI_CFG_SPACE) {
/* Get PCI Root Address for this opregion */
- aml_rdpciaddr(rgn->node->parent, &pi);
+ if (aml_rdpciaddr(rgn->node->parent, &pi)) {
+ if (mode == ACPI_IOREAD)
+ pi.fun = 0xffff;
+ else
+ return;
+ }
}
tbit = &tmp.v_integer;