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 <non...@netbsd.org>
@@ -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);

Reply via email to