Module Name: src
Committed By: jmcneill
Date: Wed Oct 17 01:16:23 UTC 2018
Modified Files:
src/sys/dev/acpi: acpi_mcfg.c
Log Message:
Allow access to PCI configuration space for devices without extended
config support.
ok nonaka@
To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/acpi/acpi_mcfg.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/acpi/acpi_mcfg.c
diff -u src/sys/dev/acpi/acpi_mcfg.c:1.9 src/sys/dev/acpi/acpi_mcfg.c:1.10
--- src/sys/dev/acpi/acpi_mcfg.c:1.9 Mon Oct 15 12:46:43 2018
+++ src/sys/dev/acpi/acpi_mcfg.c Wed Oct 17 01:16:23 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_mcfg.c,v 1.9 2018/10/15 12:46:43 jmcneill Exp $ */
+/* $NetBSD: acpi_mcfg.c,v 1.10 2018/10/17 01:16:23 jmcneill Exp $ */
/*-
* Copyright (C) 2015 NONAKA Kimihiro <[email protected]>
@@ -28,7 +28,7 @@
#include "opt_pci.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_mcfg.c,v 1.9 2018/10/15 12:46:43 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_mcfg.c,v 1.10 2018/10/17 01:16:23 jmcneill Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -52,9 +52,13 @@ ACPI_MODULE_NAME ("acpi_mcfg")
#define EXTCONF_OFFSET(d, f, r) ((((d) * 8 + (f)) * PCI_EXTCONF_SIZE) + (r))
-#define EXTCONF_SET_VALID(mb, d, f) ((mb)->valid_devs[(d)] |= __BIT((f)))
-#define EXTCONF_SET_INVALID(mb, d, f) ((mb)->valid_devs[(d)] &= ~__BIT((f)))
-#define EXTCONF_IS_VALID(mb, d, f) ((mb)->valid_devs[(d)] & __BIT((f)))
+#define PCIDEV_SET_VALID(mb, d, f) ((mb)->valid_devs[(d)] |= __BIT((f)))
+#define PCIDEV_SET_INVALID(mb, d, f) ((mb)->valid_devs[(d)] &= ~__BIT((f)))
+#define PCIDEV_IS_VALID(mb, d, f) ((mb)->valid_devs[(d)] & __BIT((f)))
+
+#define EXTCONF_SET_VALID(mb, d, f) ((mb)->valid_extconf[(d)] |= __BIT((f)))
+#define EXTCONF_SET_INVALID(mb, d, f) ((mb)->valid_extconf[(d)] &= ~__BIT((f)))
+#define EXTCONF_IS_VALID(mb, d, f) ((mb)->valid_extconf[(d)] & __BIT((f)))
struct mcfg_segment {
uint64_t ms_address; /* Base address */
@@ -65,6 +69,7 @@ struct mcfg_segment {
struct mcfg_bus {
bus_space_handle_t bsh[32][8];
uint8_t valid_devs[32];
+ uint8_t valid_extconf[32];
int valid_ndevs;
pcitag_t last_probed;
} *ms_bus;
@@ -489,7 +494,7 @@ acpimcfg_device_probe(const struct pci_a
for (j = last_func; j < end_func; j++) {
if (i == last_dev && j == last_func)
continue;
- EXTCONF_SET_INVALID(mb, i, j);
+ PCIDEV_SET_INVALID(mb, i, j);
}
last_func = 0;
}
@@ -513,13 +518,14 @@ acpimcfg_device_probe(const struct pci_a
"(cfg[0x%03x]=0x%08x, alias=%s)\n", bus, dev, func,
PCI_CONF_SIZE, reg, alias ? "true" : "false");
EXTCONF_SET_INVALID(mb, dev, func);
- } else {
- aprint_debug_dev(acpi_sc->sc_dev,
- "MCFG: %03d:%02d:%d: Ok (cfg[0x%03x]=0x%08x)\n",
- bus, dev, func, PCI_CONF_SIZE, reg);
- mb->valid_ndevs++;
}
+ aprint_debug_dev(acpi_sc->sc_dev,
+ "MCFG: %03d:%02d:%d: Ok (cfg[0x%03x]=0x%08x extconf=%c)\n",
+ bus, dev, func, PCI_CONF_SIZE, reg,
+ EXTCONF_IS_VALID(mb, dev, func) ? 'Y' : 'N');
+ mb->valid_ndevs++;
+
return 0;
}
@@ -587,6 +593,7 @@ acpimcfg_map_bus(device_t self, pci_chip
/* Probe extended configuration space of all devices. */
memset(mb->valid_devs, 0xff, sizeof(mb->valid_devs));
+ memset(mb->valid_extconf, 0xff, sizeof(mb->valid_extconf));
mb->valid_ndevs = 0;
mb->last_probed = pci_make_tag(pc, bus, 0, 0);
@@ -613,7 +620,7 @@ acpimcfg_map_bus(device_t self, pci_chip
pci_conf_write(pc, tag, 0x54, reg);
}
- /* Unmap extended configration space of all dev/func. */
+ /* Unmap configuration space of all dev/func. */
bus_space_unmap(seg->ms_bst, bsh, ACPIMCFG_SIZE_PER_BUS);
memset(mb->bsh, 0, sizeof(mb->bsh));
@@ -632,15 +639,15 @@ acpimcfg_map_bus(device_t self, pci_chip
/* Don't mark invalid to last probed device. */
continue;
}
- EXTCONF_SET_INVALID(mb, i, j);
+ PCIDEV_SET_INVALID(mb, i, j);
}
last_func = 0;
}
- /* Map extended configuration space per dev/func. */
+ /* Map configuration space per dev/func. */
for (i = 0; i < 32; i++) {
for (j = 0; j < 8; j++) {
- if (!EXTCONF_IS_VALID(mb, i, j))
+ if (!PCIDEV_IS_VALID(mb, i, j))
continue;
error = bus_space_map(seg->ms_bst,
baddr + EXTCONF_OFFSET(i, j, 0), PCI_EXTCONF_SIZE,
@@ -649,7 +656,7 @@ acpimcfg_map_bus(device_t self, pci_chip
/* Unmap all handles when map failed. */
do {
while (--j >= 0) {
- if (!EXTCONF_IS_VALID(mb, i, j))
+ if (!PCIDEV_IS_VALID(mb, i, j))
continue;
bus_space_unmap(seg->ms_bst,
mb->bsh[i][j],
@@ -667,7 +674,7 @@ acpimcfg_map_bus(device_t self, pci_chip
aprint_debug_dev(acpi_sc->sc_dev, "MCFG: bus %d: valid devices\n", bus);
for (i = 0; i < 32; i++) {
for (j = 0; j < 8; j++) {
- if (EXTCONF_IS_VALID(mb, i, j)) {
+ if (PCIDEV_IS_VALID(mb, i, j)) {
aprint_debug_dev(acpi_sc->sc_dev,
"MCFG: %03d:%02d:%d\n", bus, i, j);
}
@@ -908,7 +915,11 @@ acpimcfg_conf_read(pci_chipset_tag_t pc,
}
mb = &seg->ms_bus[bus - seg->ms_bus_start];
- if (!EXTCONF_IS_VALID(mb, dev, func)) {
+ if (!PCIDEV_IS_VALID(mb, dev, func)) {
+ *data = -1;
+ return EINVAL;
+ }
+ if (!EXTCONF_IS_VALID(mb, dev, func) && reg >= PCI_CONF_SIZE) {
*data = -1;
return EINVAL;
}
@@ -937,7 +948,9 @@ acpimcfg_conf_write(pci_chipset_tag_t pc
return ERANGE;
mb = &seg->ms_bus[bus - seg->ms_bus_start];
- if (!EXTCONF_IS_VALID(mb, dev, func))
+ if (!PCIDEV_IS_VALID(mb, dev, func))
+ return EINVAL;
+ if (!EXTCONF_IS_VALID(mb, dev, func) && reg >= PCI_CONF_SIZE)
return EINVAL;
mcfg_ops->ao_write(seg->ms_bst, mb->bsh[dev][func], reg, data);