svn commit: r343846 - stable/12/sys/dev/nvdimm

Konstantin Belousov kib at FreeBSD.org
Thu Feb 7 01:50:00 UTC 2019


Author: kib
Date: Thu Feb  7 01:49:59 2019
New Revision: 343846
URL: https://svnweb.freebsd.org/changeset/base/343846

Log:
  MFC r343628:
  nvdimm: enumerate NVDIMM SPA ranges from the root device

Modified:
  stable/12/sys/dev/nvdimm/nvdimm.c
  stable/12/sys/dev/nvdimm/nvdimm_spa.c
  stable/12/sys/dev/nvdimm/nvdimm_var.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/dev/nvdimm/nvdimm.c
==============================================================================
--- stable/12/sys/dev/nvdimm/nvdimm.c	Wed Feb  6 21:24:44 2019	(r343845)
+++ stable/12/sys/dev/nvdimm/nvdimm.c	Thu Feb  7 01:49:59 2019	(r343846)
@@ -227,6 +227,31 @@ nvdimm_resume(device_t dev)
 	return (0);
 }
 
+static int
+nvdimm_root_create_spa(void *nfitsubtbl, void *arg)
+{
+	enum SPA_mapping_type spa_type;
+	ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr;
+	struct SPA_mapping *spa;
+	struct nvdimm_root_dev *dev;
+	int error;
+
+	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);
+	}
+	SLIST_INSERT_HEAD(&dev->spas, spa, link);
+	return (0);
+}
+
 static ACPI_STATUS
 nvdimm_root_create_dev(ACPI_HANDLE handle, UINT32 nesting_level, void *context,
     void **return_value)
@@ -276,6 +301,7 @@ nvdimm_root_attach(device_t dev)
 {
 	ACPI_HANDLE handle;
 	ACPI_STATUS status;
+	ACPI_TABLE_NFIT *nfitbl;
 	int error;
 
 	handle = acpi_get_handle(dev);
@@ -284,15 +310,33 @@ nvdimm_root_attach(device_t dev)
 	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));
+	AcpiPutTable(&nfitbl->Header);
 	return (error);
 }
 
 static int
 nvdimm_root_detach(device_t dev)
 {
+	struct nvdimm_root_dev *root;
+	struct SPA_mapping *spa, *next;
 	device_t *children;
 	int i, error, num_children;
 
+	root = device_get_softc(dev);
+	SLIST_FOREACH_SAFE(spa, &root->spas, link, next) {
+		nvdimm_spa_fini(spa);
+		SLIST_REMOVE_HEAD(&root->spas, link);
+		free(spa, M_NVDIMM);
+	}
 	error = bus_generic_detach(dev);
 	if (error != 0)
 		return (error);
@@ -356,6 +400,7 @@ static device_method_t nvdimm_root_methods[] = {
 static driver_t	nvdimm_root_driver = {
 	"nvdimm_root",
 	nvdimm_root_methods,
+	sizeof(struct nvdimm_root_dev),
 };
 
 DRIVER_MODULE(nvdimm_root, acpi, nvdimm_root_driver, nvdimm_root_devclass, NULL,

Modified: stable/12/sys/dev/nvdimm/nvdimm_spa.c
==============================================================================
--- stable/12/sys/dev/nvdimm/nvdimm_spa.c	Wed Feb  6 21:24:44 2019	(r343845)
+++ stable/12/sys/dev/nvdimm/nvdimm_spa.c	Thu Feb  7 01:49:59 2019	(r343846)
@@ -82,19 +82,6 @@ __FBSDID("$FreeBSD$");
 #define UUID_INITIALIZER_PERSISTENT_VIRTUAL_CD \
     {0x08018188,0x42cd,0xbb48,0x10,0x0f,{0x53,0x87,0xd5,0x3d,0xed,0x3d}}
 
-struct SPA_mapping *spa_mappings;
-int spa_mappings_cnt;
-
-static int
-nvdimm_spa_count(void *nfitsubtbl __unused, void *arg)
-{
-	int *cnt;
-
-	cnt = arg;
-	(*cnt)++;
-	return (0);
-}
-
 static struct nvdimm_SPA_uuid_list_elm {
 	const char		*u_name;
 	struct uuid		u_id;
@@ -418,22 +405,17 @@ nvdimm_spa_g_access(struct g_provider *pp, int r, int 
 	return (0);
 }
 
-static g_init_t nvdimm_spa_g_init;
-static g_fini_t nvdimm_spa_g_fini;
-
 struct g_class nvdimm_spa_g_class = {
 	.name =		"SPA",
 	.version =	G_VERSION,
 	.start =	nvdimm_spa_g_start,
 	.access =	nvdimm_spa_g_access,
-	.init =		nvdimm_spa_g_init,
-	.fini =		nvdimm_spa_g_fini,
 };
 DECLARE_GEOM_CLASS(nvdimm_spa_g_class, g_spa);
 
-static int
-nvdimm_spa_init_one(struct SPA_mapping *spa, ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr,
-    int spa_type)
+int
+nvdimm_spa_init(struct SPA_mapping *spa, ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr,
+    enum SPA_mapping_type spa_type)
 {
 	struct make_dev_args mda;
 	struct sglist *spa_sg;
@@ -511,7 +493,7 @@ nvdimm_spa_init_one(struct SPA_mapping *spa, ACPI_NFIT
 		if (error1 == 0)
 			error1 = error;
 	} else {
-		g_topology_assert();
+		g_topology_lock();
 		spa->spa_g = g_new_geomf(&nvdimm_spa_g_class, "spa%d",
 		    spa->spa_nfit_idx);
 		spa->spa_g->softc = spa;
@@ -525,12 +507,13 @@ nvdimm_spa_init_one(struct SPA_mapping *spa, ACPI_NFIT
 		spa->spa_g_devstat = devstat_new_entry("spa", spa->spa_nfit_idx,
 		    DEV_BSIZE, DEVSTAT_ALL_SUPPORTED, DEVSTAT_TYPE_DIRECT,
 		    DEVSTAT_PRIORITY_MAX);
+		g_topology_unlock();
 	}
 	return (error1);
 }
 
-static void
-nvdimm_spa_fini_one(struct SPA_mapping *spa)
+void
+nvdimm_spa_fini(struct SPA_mapping *spa)
 {
 
 	mtx_lock(&spa->spa_g_mtx);
@@ -561,88 +544,4 @@ nvdimm_spa_fini_one(struct SPA_mapping *spa)
 	}
 	mtx_destroy(&spa->spa_g_mtx);
 	mtx_destroy(&spa->spa_g_stat_mtx);
-}
-
-static int
-nvdimm_spa_parse(void *nfitsubtbl, void *arg)
-{
-	ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr;
-	struct SPA_mapping *spa;
-	enum SPA_mapping_type spa_type;
-	int error, *i;
-
-	i = arg;
-	spa = &spa_mappings[(*i)++];
-	nfitaddr = nfitsubtbl;
-	spa_type = nvdimm_spa_type_from_uuid(
-	    (struct uuid *)&nfitaddr->RangeGuid);
-	if (spa_type == SPA_TYPE_UNKNOWN) {
-		printf("Unknown SPA UUID %d ", nfitaddr->RangeIndex);
-		printf_uuid((struct uuid *)&nfitaddr->RangeGuid);
-		printf("\n");
-		return (0);
-	}
-	error = nvdimm_spa_init_one(spa, nfitaddr, spa_type);
-	if (error != 0)
-		nvdimm_spa_fini_one(spa);
-	return (0);
-}
-
-static int
-nvdimm_spa_init1(ACPI_TABLE_NFIT *nfitbl)
-{
-	int error, i;
-
-	error = nvdimm_iterate_nfit(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS,
-	    nvdimm_spa_count, &spa_mappings_cnt);
-	if (error != 0)
-		return (error);
-	spa_mappings = malloc(sizeof(struct SPA_mapping) * spa_mappings_cnt,
-	    M_NVDIMM, M_WAITOK | M_ZERO);
-	i = 0;
-	error = nvdimm_iterate_nfit(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS,
-	    nvdimm_spa_parse, &i);
-	if (error != 0) {
-		free(spa_mappings, M_NVDIMM);
-		spa_mappings = NULL;
-		return (error);
-	}
-	return (0);
-}
-
-static void
-nvdimm_spa_g_init(struct g_class *mp __unused)
-{
-	ACPI_TABLE_NFIT *nfitbl;
-	ACPI_STATUS status;
-	int error;
-
-	spa_mappings_cnt = 0;
-	spa_mappings = NULL;
-	if (acpi_disabled("nvdimm"))
-		return;
-	status = AcpiGetTable(ACPI_SIG_NFIT, 1, (ACPI_TABLE_HEADER **)&nfitbl);
-	if (ACPI_FAILURE(status)) {
-		if (bootverbose)
-			printf("nvdimm_spa_g_init: cannot find NFIT\n");
-		return;
-	}
-	error = nvdimm_spa_init1(nfitbl);
-	if (error != 0)
-		printf("nvdimm_spa_g_init: error %d\n", error);
-	AcpiPutTable(&nfitbl->Header);
-}
-
-static void
-nvdimm_spa_g_fini(struct g_class *mp __unused)
-{
-	int i;
-
-	if (spa_mappings == NULL)
-		return;
-	for (i = 0; i < spa_mappings_cnt; i++)
-		nvdimm_spa_fini_one(&spa_mappings[i]);
-	free(spa_mappings, M_NVDIMM);
-	spa_mappings = NULL;
-	spa_mappings_cnt = 0;
 }

Modified: stable/12/sys/dev/nvdimm/nvdimm_var.h
==============================================================================
--- stable/12/sys/dev/nvdimm/nvdimm_var.h	Wed Feb  6 21:24:44 2019	(r343845)
+++ stable/12/sys/dev/nvdimm/nvdimm_var.h	Thu Feb  7 01:49:59 2019	(r343846)
@@ -44,6 +44,10 @@ __BUS_ACCESSOR(nvdimm_root, acpi_handle, NVDIMM_ROOT, 
 __BUS_ACCESSOR(nvdimm_root, device_handle, NVDIMM_ROOT, DEVICE_HANDLE,
     nfit_handle_t)
 
+struct nvdimm_root_dev {
+	SLIST_HEAD(, SPA_mapping) spas;
+};
+
 struct nvdimm_dev {
 	device_t	nv_dev;
 	nfit_handle_t	nv_handle;
@@ -64,6 +68,7 @@ enum SPA_mapping_type {
 };
 
 struct SPA_mapping {
+	SLIST_ENTRY(SPA_mapping) link;
 	enum SPA_mapping_type	spa_type;
 	int			spa_domain;
 	int			spa_nfit_idx;
@@ -84,14 +89,14 @@ struct SPA_mapping {
 	bool			spa_g_proc_exiting;
 };
 
-extern struct SPA_mapping *spa_mappings;
-extern int spa_mappings_cnt;
-
 MALLOC_DECLARE(M_NVDIMM);
 
 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);
 
 #endif		/* __DEV_NVDIMM_VAR_H__ */


More information about the svn-src-all mailing list