svn commit: r343629 - in head/sys: dev/nvdimm modules/nvdimm

Konstantin Belousov kib at FreeBSD.org
Thu Jan 31 22:47:06 UTC 2019


Author: kib
Date: Thu Jan 31 22:47:04 2019
New Revision: 343629
URL: https://svnweb.freebsd.org/changeset/base/343629

Log:
  nvdimm: only enumerate present nvdimm devices
  
  Not all child devices of the NVDIMM root device represent DIMM devices
  which are present in the system. The spec says (ACPI 6.2, sec 9.20.2):
  
      For each NVDIMM present or intended to be supported by platform,
      platform firmware also exposes an NVDIMM device ... under the
      NVDIMM root device.
  
  Present NVDIMM devices are found by walking all of the NFIT table's
  SPA ranges, then walking the NVDIMM regions mentioned by those SPA
  ranges.
  
  A set of NFIT walking helper functions are introduced to avoid the
  need to splat the enumeration logic across several disparate
  callbacks.
  
  Submitted by:	D Scott Phillips <d.scott.phillips at intel.com>
  Sponsored by:	Intel Corporation
  MFC after:	1 week
  Differential revision:	https://reviews.freebsd.org/D18439

Added:
  head/sys/dev/nvdimm/nvdimm_nfit.c   (contents, props changed)
Modified:
  head/sys/dev/nvdimm/nvdimm.c
  head/sys/dev/nvdimm/nvdimm_var.h
  head/sys/modules/nvdimm/Makefile

Modified: head/sys/dev/nvdimm/nvdimm.c
==============================================================================
--- head/sys/dev/nvdimm/nvdimm.c	Thu Jan 31 22:43:20 2019	(r343628)
+++ head/sys/dev/nvdimm/nvdimm.c	Thu Jan 31 22:47:04 2019	(r343629)
@@ -77,99 +77,6 @@ nvdimm_find_by_handle(nfit_handle_t nv_handle)
 }
 
 static int
-nvdimm_parse_flush_addr(void *nfitsubtbl, void *arg)
-{
-	ACPI_NFIT_FLUSH_ADDRESS *nfitflshaddr;
-	struct nvdimm_dev *nv;
-	int i;
-
-	nfitflshaddr = nfitsubtbl;
-	nv = arg;
-	if (nfitflshaddr->DeviceHandle != nv->nv_handle)
-		return (0);
-
-	MPASS(nv->nv_flush_addr == NULL && nv->nv_flush_addr_cnt == 0);
-	nv->nv_flush_addr = mallocarray(nfitflshaddr->HintCount,
-	    sizeof(uint64_t *), M_NVDIMM, M_WAITOK);
-	for (i = 0; i < nfitflshaddr->HintCount; i++)
-		nv->nv_flush_addr[i] = (uint64_t *)nfitflshaddr->HintAddress[i];
-	nv->nv_flush_addr_cnt = nfitflshaddr->HintCount;
-	return (0);
-}
-
-int
-nvdimm_iterate_nfit(ACPI_TABLE_NFIT *nfitbl, enum AcpiNfitType type,
-    int (*cb)(void *, void *), void *arg)
-{
-	ACPI_NFIT_HEADER *nfithdr;
-	ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr;
-	ACPI_NFIT_MEMORY_MAP *nfitmap;
-	ACPI_NFIT_INTERLEAVE *nfitintrl;
-	ACPI_NFIT_SMBIOS *nfitsmbios;
-	ACPI_NFIT_CONTROL_REGION *nfitctlreg;
-	ACPI_NFIT_DATA_REGION *nfitdtreg;
-	ACPI_NFIT_FLUSH_ADDRESS *nfitflshaddr;
-	char *ptr;
-	int error;
-
-	error = 0;
-	for (ptr = (char *)(nfitbl + 1);
-	    ptr < (char *)nfitbl + nfitbl->Header.Length;
-	    ptr += nfithdr->Length) {
-		nfithdr = (ACPI_NFIT_HEADER *)ptr;
-		if (nfithdr->Type != type)
-			continue;
-		switch (nfithdr->Type) {
-		case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
-			nfitaddr = __containerof(nfithdr,
-			    ACPI_NFIT_SYSTEM_ADDRESS, Header);
-			error = cb(nfitaddr, arg);
-			break;
-		case ACPI_NFIT_TYPE_MEMORY_MAP:
-			nfitmap = __containerof(nfithdr,
-			    ACPI_NFIT_MEMORY_MAP, Header);
-			error = cb(nfitmap, arg);
-			break;
-		case ACPI_NFIT_TYPE_INTERLEAVE:
-			nfitintrl = __containerof(nfithdr,
-			    ACPI_NFIT_INTERLEAVE, Header);
-			error = cb(nfitintrl, arg);
-			break;
-		case ACPI_NFIT_TYPE_SMBIOS:
-			nfitsmbios = __containerof(nfithdr,
-			    ACPI_NFIT_SMBIOS, Header);
-			error = cb(nfitsmbios, arg);
-			break;
-		case ACPI_NFIT_TYPE_CONTROL_REGION:
-			nfitctlreg = __containerof(nfithdr,
-			    ACPI_NFIT_CONTROL_REGION, Header);
-			error = cb(nfitctlreg, arg);
-			break;
-		case ACPI_NFIT_TYPE_DATA_REGION:
-			nfitdtreg = __containerof(nfithdr,
-			    ACPI_NFIT_DATA_REGION, Header);
-			error = cb(nfitdtreg, arg);
-			break;
-		case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
-			nfitflshaddr = __containerof(nfithdr,
-			    ACPI_NFIT_FLUSH_ADDRESS, Header);
-			error = cb(nfitflshaddr, arg);
-			break;
-		case ACPI_NFIT_TYPE_RESERVED:
-		default:
-			if (bootverbose)
-				printf("NFIT subtype %d unknown\n",
-				    nfithdr->Type);
-			error = 0;
-			break;
-		}
-		if (error != 0)
-			break;
-	}
-	return (error);
-}
-
-static int
 nvdimm_probe(device_t dev)
 {
 
@@ -197,8 +104,8 @@ nvdimm_attach(device_t dev)
 			device_printf(dev, "cannot get NFIT\n");
 		return (ENXIO);
 	}
-	nvdimm_iterate_nfit(nfitbl, ACPI_NFIT_TYPE_FLUSH_ADDRESS,
-	    nvdimm_parse_flush_addr, nv);
+	acpi_nfit_get_flush_addrs(nfitbl, nv->nv_handle, &nv->nv_flush_addr,
+	    &nv->nv_flush_addr_cnt);
 	AcpiPutTable(&nfitbl->Header);
 	return (0);
 }
@@ -227,57 +134,92 @@ nvdimm_resume(device_t dev)
 	return (0);
 }
 
-static int
-nvdimm_root_create_spa(void *nfitsubtbl, void *arg)
+static ACPI_STATUS
+find_dimm(ACPI_HANDLE handle, UINT32 nesting_level, void *context,
+    void **return_value)
 {
-	enum SPA_mapping_type spa_type;
-	ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr;
-	struct SPA_mapping *spa;
-	struct nvdimm_root_dev *dev;
-	int error;
+	ACPI_DEVICE_INFO *device_info;
+	ACPI_STATUS status;
 
-	nfitaddr = nfitsubtbl;
-	dev = arg;
-	spa_type = nvdimm_spa_type_from_uuid(
-	    (struct uuid *)nfitaddr->RangeGuid);
-	if (spa_type == SPA_TYPE_UNKNOWN)
-		return (0);
-	spa = malloc(sizeof(struct SPA_mapping), M_NVDIMM, M_WAITOK | M_ZERO);
-	error = nvdimm_spa_init(spa, nfitaddr, spa_type);
-	if (error != 0) {
-		nvdimm_spa_fini(spa);
-		free(spa, M_NVDIMM);
+	status = AcpiGetObjectInfo(handle, &device_info);
+	if (ACPI_FAILURE(status))
+		return_ACPI_STATUS(AE_ERROR);
+	if (device_info->Address == (uintptr_t)context) {
+		*(ACPI_HANDLE *)return_value = handle;
+		return_ACPI_STATUS(AE_CTRL_TERMINATE);
 	}
-	SLIST_INSERT_HEAD(&dev->spas, spa, link);
-	return (0);
+	return_ACPI_STATUS(AE_OK);
 }
 
-static ACPI_STATUS
-nvdimm_root_create_dev(ACPI_HANDLE handle, UINT32 nesting_level, void *context,
-    void **return_value)
+static ACPI_HANDLE
+get_dimm_acpi_handle(ACPI_HANDLE root_handle, nfit_handle_t adr)
 {
+	ACPI_HANDLE res;
 	ACPI_STATUS status;
-	ACPI_DEVICE_INFO *device_info;
-	device_t parent, child;
+
+	res = NULL;
+	status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, root_handle, 1, find_dimm,
+	    NULL, (void *)(uintptr_t)adr, &res);
+	if (ACPI_FAILURE(status))
+		res = NULL;
+	return (res);
+}
+
+static int
+nvdimm_root_create_devs(device_t dev, ACPI_TABLE_NFIT *nfitbl)
+{
+	ACPI_HANDLE root_handle, dimm_handle;
+	device_t child;
+	nfit_handle_t *dimm_ids, *dimm;
 	uintptr_t *ivars;
+	int num_dimm_ids;
 
-	parent = context;
-	child = BUS_ADD_CHILD(parent, 100, "nvdimm", -1);
-	if (child == NULL) {
-		device_printf(parent, "failed to create nvdimm\n");
-		return_ACPI_STATUS(AE_ERROR);
+	root_handle = acpi_get_handle(dev);
+	acpi_nfit_get_dimm_ids(nfitbl, &dimm_ids, &num_dimm_ids);
+	for (dimm = dimm_ids; dimm < dimm_ids + num_dimm_ids; dimm++) {
+		dimm_handle = get_dimm_acpi_handle(root_handle, *dimm);
+		child = BUS_ADD_CHILD(dev, 100, "nvdimm", -1);
+		if (child == NULL) {
+			device_printf(dev, "failed to create nvdimm\n");
+			return (ENXIO);
+		}
+		ivars = mallocarray(NVDIMM_ROOT_IVAR_MAX, sizeof(uintptr_t),
+		    M_NVDIMM, M_ZERO | M_WAITOK);
+		device_set_ivars(child, ivars);
+		nvdimm_root_set_acpi_handle(child, dimm_handle);
+		nvdimm_root_set_device_handle(child, *dimm);
 	}
-	status = AcpiGetObjectInfo(handle, &device_info);
-	if (ACPI_FAILURE(status)) {
-		device_printf(parent, "failed to get nvdimm device info\n");
-		return_ACPI_STATUS(AE_ERROR);
+	free(dimm_ids, M_NVDIMM);
+	return (0);
+}
+
+static int
+nvdimm_root_create_spas(struct nvdimm_root_dev *dev, ACPI_TABLE_NFIT *nfitbl)
+{
+	ACPI_NFIT_SYSTEM_ADDRESS **spas, **spa;
+	struct SPA_mapping *spa_mapping;
+	enum SPA_mapping_type spa_type;
+	int error, num_spas;
+
+	error = 0;
+	acpi_nfit_get_spa_ranges(nfitbl, &spas, &num_spas);
+	for (spa = spas; spa < spas + num_spas; spa++) {
+		spa_type = nvdimm_spa_type_from_uuid(
+			(struct uuid *)(*spa)->RangeGuid);
+		if (spa_type == SPA_TYPE_UNKNOWN)
+			continue;
+		spa_mapping = malloc(sizeof(struct SPA_mapping), M_NVDIMM,
+		    M_WAITOK | M_ZERO);
+		error = nvdimm_spa_init(spa_mapping, *spa, spa_type);
+		if (error != 0) {
+			nvdimm_spa_fini(spa_mapping);
+			free(spa, M_NVDIMM);
+			break;
+		}
+		SLIST_INSERT_HEAD(&dev->spas, spa_mapping, link);
 	}
-	ivars = mallocarray(NVDIMM_ROOT_IVAR_MAX - 1, sizeof(uintptr_t),
-	    M_NVDIMM, M_ZERO | M_WAITOK);
-	device_set_ivars(child, ivars);
-	nvdimm_root_set_acpi_handle(child, handle);
-	nvdimm_root_set_device_handle(child, device_info->Address);
-	return_ACPI_STATUS(AE_OK);
+	free(spas, M_NVDIMM);
+	return (error);
 }
 
 static char *nvdimm_root_id[] = {"ACPI0012", NULL};
@@ -299,26 +241,24 @@ nvdimm_root_probe(device_t dev)
 static int
 nvdimm_root_attach(device_t dev)
 {
-	ACPI_HANDLE handle;
-	ACPI_STATUS status;
+	struct nvdimm_root_dev *root;
 	ACPI_TABLE_NFIT *nfitbl;
+	ACPI_STATUS status;
 	int error;
 
-	handle = acpi_get_handle(dev);
-	status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, handle, 1,
-	    nvdimm_root_create_dev, NULL, dev, NULL);
-	if (ACPI_FAILURE(status))
-		device_printf(dev, "failed adding children\n");
-	error = bus_generic_attach(dev);
-	if (error != 0)
-		return (error);
 	status = AcpiGetTable(ACPI_SIG_NFIT, 1, (ACPI_TABLE_HEADER **)&nfitbl);
 	if (ACPI_FAILURE(status)) {
 		device_printf(dev, "cannot get NFIT\n");
 		return (ENXIO);
 	}
-	error = nvdimm_iterate_nfit(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS,
-	    nvdimm_root_create_spa, device_get_softc(dev));
+	error = nvdimm_root_create_devs(dev, nfitbl);
+	if (error != 0)
+		return (error);
+	error = bus_generic_attach(dev);
+	if (error != 0)
+		return (error);
+	root = device_get_softc(dev);
+	error = nvdimm_root_create_spas(root, nfitbl);
 	AcpiPutTable(&nfitbl->Header);
 	return (error);
 }

Added: head/sys/dev/nvdimm/nvdimm_nfit.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/nvdimm/nvdimm_nfit.c	Thu Jan 31 22:47:04 2019	(r343629)
@@ -0,0 +1,203 @@
+/*-
+ * Copyright (c) 2018 Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/uuid.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <dev/acpica/acpivar.h>
+#include <dev/nvdimm/nvdimm_var.h>
+
+static int
+uint32_t_compare(const void *a, const void *b)
+{
+
+	return (*(const uint32_t *)a - *(const uint32_t *)b);
+}
+
+static int
+find_matches(ACPI_TABLE_NFIT *nfitbl, uint16_t type, uint16_t offset,
+    uint64_t mask, uint64_t value, void **ptrs, int ptrs_len)
+{
+	ACPI_NFIT_HEADER *h, *end;
+	uint64_t val;
+	size_t load_size;
+	int count;
+
+	h = (ACPI_NFIT_HEADER *)(nfitbl + 1);
+	end = (ACPI_NFIT_HEADER *)((char *)nfitbl +
+	    nfitbl->Header.Length);
+	load_size = roundup2(flsl(mask), 8) / 8;
+	count = 0;
+
+	while (h < end) {
+		if (h->Type == type) {
+			bcopy((char *)h + offset, &val, load_size);
+			val &= mask;
+			if (val == value) {
+				if (ptrs_len > 0) {
+					ptrs[count] = h;
+					ptrs_len--;
+				}
+				count++;
+			}
+		}
+		if (h->Length == 0)
+			break;
+		h = (ACPI_NFIT_HEADER *)((char *)h + h->Length);
+	}
+	return (count);
+}
+
+static void
+malloc_find_matches(ACPI_TABLE_NFIT *nfitbl, uint16_t type, uint16_t offset,
+    uint64_t mask, uint64_t value, void ***ptrs, int *ptrs_len)
+{
+	int count;
+
+	count = find_matches(nfitbl, type, offset, mask, value, NULL, 0);
+	*ptrs_len = count;
+	if (count == 0) {
+		*ptrs = NULL;
+		return;
+	}
+	*ptrs = mallocarray(count, sizeof(void *), M_NVDIMM, M_WAITOK);
+	find_matches(nfitbl, type, offset, mask, value, *ptrs, *ptrs_len);
+}
+
+void
+acpi_nfit_get_dimm_ids(ACPI_TABLE_NFIT *nfitbl, nfit_handle_t **listp,
+    int *countp)
+{
+	ACPI_NFIT_SYSTEM_ADDRESS **spas;
+	ACPI_NFIT_MEMORY_MAP ***regions;
+	int i, j, k, maxids, num_spas, *region_counts;
+
+	acpi_nfit_get_spa_ranges(nfitbl, &spas, &num_spas);
+	if (num_spas == 0) {
+		*listp = NULL;
+		*countp = 0;
+		return;
+	}
+	regions = mallocarray(num_spas, sizeof(uint16_t *), M_NVDIMM,
+	    M_WAITOK);
+	region_counts = mallocarray(num_spas, sizeof(int), M_NVDIMM, M_WAITOK);
+	for (i = 0; i < num_spas; i++) {
+		acpi_nfit_get_region_mappings_by_spa_range(nfitbl,
+		    spas[i]->RangeIndex, &regions[i], &region_counts[i]);
+	}
+	maxids = 0;
+	for (i = 0; i < num_spas; i++) {
+		maxids += region_counts[i];
+	}
+	*listp = mallocarray(maxids, sizeof(nfit_handle_t), M_NVDIMM, M_WAITOK);
+	k = 0;
+	for (i = 0; i < num_spas; i++) {
+		for (j = 0; j < region_counts[i]; j++)
+			(*listp)[k++] = regions[i][j]->DeviceHandle;
+	}
+	qsort((*listp), maxids, sizeof(uint32_t), uint32_t_compare);
+	i = 0;
+	for (j = 1; j < maxids; j++) {
+		if ((*listp)[i] != (*listp)[j])
+			(*listp)[++i] = (*listp)[j];
+	}
+	*countp = i + 1;
+	free(region_counts, M_NVDIMM);
+	for (i = 0; i < num_spas; i++)
+		free(regions[i], M_NVDIMM);
+	free(regions, M_NVDIMM);
+	free(spas, M_NVDIMM);
+}
+
+void
+acpi_nfit_get_spa_range(ACPI_TABLE_NFIT *nfitbl, uint16_t range_index,
+    ACPI_NFIT_SYSTEM_ADDRESS **spa)
+{
+
+	*spa = NULL;
+	find_matches(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS,
+	    offsetof(ACPI_NFIT_SYSTEM_ADDRESS, RangeIndex), UINT16_MAX,
+	    range_index, (void **)spa, 1);
+}
+
+void
+acpi_nfit_get_spa_ranges(ACPI_TABLE_NFIT *nfitbl,
+    ACPI_NFIT_SYSTEM_ADDRESS ***listp, int *countp)
+{
+
+	malloc_find_matches(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS, 0, 0, 0,
+	    (void ***)listp, countp);
+}
+
+void
+acpi_nfit_get_region_mappings_by_spa_range(ACPI_TABLE_NFIT *nfitbl,
+    uint16_t spa_range_index, ACPI_NFIT_MEMORY_MAP ***listp, int *countp)
+{
+
+	malloc_find_matches(nfitbl, ACPI_NFIT_TYPE_MEMORY_MAP,
+	    offsetof(ACPI_NFIT_MEMORY_MAP, RangeIndex), UINT16_MAX,
+	    spa_range_index, (void ***)listp, countp);
+}
+
+void acpi_nfit_get_control_region(ACPI_TABLE_NFIT *nfitbl,
+    uint16_t control_region_index, ACPI_NFIT_CONTROL_REGION **out)
+{
+
+	*out = NULL;
+	find_matches(nfitbl, ACPI_NFIT_TYPE_CONTROL_REGION,
+	    offsetof(ACPI_NFIT_CONTROL_REGION, RegionIndex), UINT16_MAX,
+	    control_region_index, (void **)out, 1);
+}
+
+void
+acpi_nfit_get_flush_addrs(ACPI_TABLE_NFIT *nfitbl, nfit_handle_t dimm,
+    uint64_t ***listp, int *countp)
+{
+	ACPI_NFIT_FLUSH_ADDRESS *subtable;
+	int i;
+
+	subtable = NULL;
+	find_matches(nfitbl, ACPI_NFIT_TYPE_FLUSH_ADDRESS,
+	    offsetof(ACPI_NFIT_FLUSH_ADDRESS, DeviceHandle), UINT32_MAX,
+	    dimm, (void **)&subtable, 1);
+	if (subtable == NULL || subtable->HintCount == 0) {
+		*listp = NULL;
+		*countp = 0;
+		return;
+	}
+	*countp = subtable->HintCount;
+	*listp = mallocarray(subtable->HintCount, sizeof(uint64_t *), M_NVDIMM,
+	    M_WAITOK);
+	for (i = 0; i < subtable->HintCount; i++)
+		(*listp)[i] = (uint64_t *)(intptr_t)subtable->HintAddress[i];
+}

Modified: head/sys/dev/nvdimm/nvdimm_var.h
==============================================================================
--- head/sys/dev/nvdimm/nvdimm_var.h	Thu Jan 31 22:43:20 2019	(r343628)
+++ head/sys/dev/nvdimm/nvdimm_var.h	Thu Jan 31 22:47:04 2019	(r343629)
@@ -91,10 +91,20 @@ struct SPA_mapping {
 
 MALLOC_DECLARE(M_NVDIMM);
 
+void acpi_nfit_get_dimm_ids(ACPI_TABLE_NFIT *nfitbl, nfit_handle_t **listp,
+    int *countp);
+void acpi_nfit_get_spa_range(ACPI_TABLE_NFIT *nfitbl, uint16_t range_index,
+    ACPI_NFIT_SYSTEM_ADDRESS **spa);
+void acpi_nfit_get_spa_ranges(ACPI_TABLE_NFIT *nfitbl,
+    ACPI_NFIT_SYSTEM_ADDRESS ***listp, int *countp);
+void acpi_nfit_get_region_mappings_by_spa_range(ACPI_TABLE_NFIT *nfitbl,
+    uint16_t spa_range_index, ACPI_NFIT_MEMORY_MAP ***listp, int *countp);
+void acpi_nfit_get_control_region(ACPI_TABLE_NFIT *nfitbl,
+    uint16_t control_region_index, ACPI_NFIT_CONTROL_REGION **out);
+void acpi_nfit_get_flush_addrs(ACPI_TABLE_NFIT *nfitbl, nfit_handle_t dimm,
+    uint64_t ***listp, int *countp);
 enum SPA_mapping_type nvdimm_spa_type_from_uuid(struct uuid *);
 struct nvdimm_dev *nvdimm_find_by_handle(nfit_handle_t nv_handle);
-int nvdimm_iterate_nfit(ACPI_TABLE_NFIT *nfitbl, enum AcpiNfitType type,
-    int (*cb)(void *, void *), void *arg);
 int nvdimm_spa_init(struct SPA_mapping *spa, ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr,
     enum SPA_mapping_type spa_type);
 void nvdimm_spa_fini(struct SPA_mapping *spa);

Modified: head/sys/modules/nvdimm/Makefile
==============================================================================
--- head/sys/modules/nvdimm/Makefile	Thu Jan 31 22:43:20 2019	(r343628)
+++ head/sys/modules/nvdimm/Makefile	Thu Jan 31 22:47:04 2019	(r343629)
@@ -4,6 +4,7 @@
 
 KMOD=	nvdimm
 SRCS=	nvdimm.c \
+	nvdimm_nfit.c \
 	nvdimm_spa.c
 
 SRCS+=	acpi_if.h bus_if.h device_if.h


More information about the svn-src-head mailing list