Page MenuHomeFreeBSD

D18439.id51841.diff
No OneTemporary

D18439.id51841.diff

Index: sys/dev/nvdimm/nvdimm.c
===================================================================
--- sys/dev/nvdimm/nvdimm.c
+++ sys/dev/nvdimm/nvdimm.c
@@ -51,250 +51,126 @@
ACPI_MODULE_NAME("NVDIMM")
static devclass_t nvdimm_devclass;
-static device_t *nvdimm_devs;
-static int nvdimm_devcnt;
MALLOC_DEFINE(M_NVDIMM, "nvdimm", "NVDIMM driver memory");
-struct nvdimm_dev *
-nvdimm_find_by_handle(nfit_handle_t nv_handle)
-{
- device_t dev;
- struct nvdimm_dev *res, *nv;
- int i;
-
- res = NULL;
- for (i = 0; i < nvdimm_devcnt; i++) {
- dev = nvdimm_devs[i];
- if (dev == NULL)
- continue;
- nv = device_get_softc(dev);
- if (nv->nv_handle == nv_handle) {
- res = nv;
- break;
- }
- }
- return (res);
-}
-
-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 = malloc(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)
+static ACPI_STATUS
+nvdimm_find_root_handle_callback(ACPI_HANDLE handle, UINT32 level, void *ctx,
+ void **st)
{
- 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;
+ ACPI_HANDLE *out_handle;
- 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);
+ if (acpi_MatchHid(handle, "ACPI0012") == ACPI_MATCHHID_NOMATCH)
+ return_ACPI_STATUS(AE_OK);
+ out_handle = st;
+ *out_handle = handle;
+ return_ACPI_STATUS(AE_CTRL_TERMINATE);
}
static ACPI_STATUS
-nvdimm_walk_dev(ACPI_HANDLE handle, UINT32 level, void *ctx, void **st)
+nvdimm_find_root_handle(ACPI_HANDLE *handle)
{
ACPI_STATUS status;
- struct nvdimm_ns_walk_ctx *wctx;
+ ACPI_HANDLE sb_handle;
- wctx = ctx;
- status = wctx->func(handle, wctx->arg);
+ status = AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &sb_handle);
+ if (!ACPI_SUCCESS(status))
+ return_ACPI_STATUS(status);
+ *handle = NULL;
+ status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, sb_handle, 1,
+ nvdimm_find_root_handle_callback, NULL, NULL, handle);
+ if (ACPI_SUCCESS(status) && *handle == NULL)
+ status = AE_NOT_FOUND;
return_ACPI_STATUS(status);
}
static ACPI_STATUS
-nvdimm_walk_root(ACPI_HANDLE handle, UINT32 level, void *ctx, void **st)
+nvdimm_find_handle_callback(ACPI_HANDLE handle, UINT32 level, void *ctx,
+ void **st)
{
+ ACPI_DEVICE_INFO *info;
+ ACPI_HANDLE *out_handle;
ACPI_STATUS status;
+ nfit_handle_t adr;
- if (!acpi_MatchHid(handle, "ACPI0012"))
- return_ACPI_STATUS(AE_OK);
- status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, handle, 100,
- nvdimm_walk_dev, NULL, ctx, NULL);
- if (ACPI_FAILURE(status))
+ status = AcpiGetObjectInfo(handle, &info);
+ if (!ACPI_SUCCESS(status))
return_ACPI_STATUS(status);
+ adr = (intptr_t)ctx;
+ if (adr != info->Address)
+ return_ACPI_STATUS(AE_OK);
+ out_handle = st;
+ *out_handle = handle;
return_ACPI_STATUS(AE_CTRL_TERMINATE);
}
static ACPI_STATUS
-nvdimm_foreach_acpi(ACPI_STATUS (*func)(ACPI_HANDLE, void *), void *arg)
+nvdimm_find_handle(ACPI_HANDLE *handle, ACPI_HANDLE root_handle,
+ nfit_handle_t adr)
{
- struct nvdimm_ns_walk_ctx wctx;
ACPI_STATUS status;
- wctx.func = func;
- wctx.arg = arg;
- status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 100,
- nvdimm_walk_root, NULL, &wctx, NULL);
+ *handle = NULL;
+ status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, root_handle, 1,
+ nvdimm_find_handle_callback, NULL, (void *)(intptr_t)adr, handle);
+ if (ACPI_SUCCESS(status) && *handle == NULL)
+ status = AE_NOT_FOUND;
return_ACPI_STATUS(status);
}
-static ACPI_STATUS
-nvdimm_count_devs(ACPI_HANDLE handle __unused, void *arg)
-{
- int *cnt;
-
- cnt = arg;
- (*cnt)++;
-
- ACPI_BUFFER name;
- ACPI_STATUS status;
- if (bootverbose) {
- name.Length = ACPI_ALLOCATE_BUFFER;
- status = AcpiGetName(handle, ACPI_FULL_PATHNAME, &name);
- if (ACPI_FAILURE(status))
- return_ACPI_STATUS(status);
- printf("nvdimm: enumerated %s\n", (char *)name.Pointer);
- AcpiOsFree(name.Pointer);
- }
-
- return_ACPI_STATUS(AE_OK);
-}
-
-struct nvdimm_create_dev_arg {
- device_t acpi0;
- int *cnt;
-};
-
-static ACPI_STATUS
-nvdimm_create_dev(ACPI_HANDLE handle, void *arg)
-{
- struct nvdimm_create_dev_arg *narg;
- device_t child;
- int idx;
-
- narg = arg;
- idx = *(narg->cnt);
- child = device_find_child(narg->acpi0, "nvdimm", idx);
- if (child == NULL)
- child = BUS_ADD_CHILD(narg->acpi0, 1, "nvdimm", idx);
- if (child == NULL) {
- if (bootverbose)
- device_printf(narg->acpi0,
- "failed to create nvdimm%d\n", idx);
- return_ACPI_STATUS(AE_ERROR);
- }
- acpi_set_handle(child, handle);
- KASSERT(nvdimm_devs[idx] == NULL, ("nvdimm_devs[%d] not NULL", idx));
- nvdimm_devs[idx] = child;
-
- (*(narg->cnt))++;
- return_ACPI_STATUS(AE_OK);
-}
-
-static bool
-nvdimm_init(void)
+struct nvdimm_dev *
+nvdimm_find_by_handle(nfit_handle_t nv_handle)
{
+ struct nvdimm_dev *res;
+ device_t dev;
+ ACPI_HANDLE root_handle, handle;
ACPI_STATUS status;
- if (nvdimm_devcnt != 0)
- return (true);
- if (acpi_disabled("nvdimm"))
- return (false);
- status = nvdimm_foreach_acpi(nvdimm_count_devs, &nvdimm_devcnt);
- if (ACPI_FAILURE(status)) {
- if (bootverbose)
- printf("nvdimm_init: count failed\n");
- return (false);
+ res = NULL;
+ status = nvdimm_find_root_handle(&root_handle);
+ if (ACPI_SUCCESS(status)) {
+ status = nvdimm_find_handle(&handle, root_handle, nv_handle);
+ if (ACPI_SUCCESS(status)) {
+ dev = acpi_get_device(handle);
+ if (dev != NULL)
+ res = device_get_softc(dev);
+ }
}
- nvdimm_devs = malloc(nvdimm_devcnt * sizeof(device_t), M_NVDIMM,
- M_WAITOK | M_ZERO);
- return (true);
+ return (res);
}
static void
nvdimm_identify(driver_t *driver, device_t parent)
{
- struct nvdimm_create_dev_arg narg;
+ device_t child;
+ nfit_handle_t *dimm_ids;
+ ACPI_TABLE_NFIT *nfitbl;
ACPI_STATUS status;
- int i;
-
- if (!nvdimm_init())
+ ACPI_HANDLE handle, root_handle;
+ int i, dimm_count;
+
+ if (acpi_disabled("nvdimm"))
+ return;
+ status = nvdimm_find_root_handle(&root_handle);
+ if (!ACPI_SUCCESS(status))
return;
- narg.acpi0 = parent;
- narg.cnt = &i;
- i = 0;
- status = nvdimm_foreach_acpi(nvdimm_create_dev, &narg);
- if (ACPI_FAILURE(status) && bootverbose)
- printf("nvdimm_identify: create failed\n");
+ status = AcpiGetTable(ACPI_SIG_NFIT, 1, (ACPI_TABLE_HEADER **)&nfitbl);
+ if (!ACPI_SUCCESS(status))
+ return;
+ acpi_nfit_get_dimm_ids(nfitbl, &dimm_ids, &dimm_count);
+ for (i = 0; i < dimm_count; i++) {
+ status = nvdimm_find_handle(&handle, root_handle, dimm_ids[i]);
+ if (!ACPI_SUCCESS(status)) {
+ device_printf(parent, "nvdimm with _ADR %x not found\n",
+ dimm_ids[i]);
+ continue;
+ }
+ child = device_find_child(parent, "nvdimm", dimm_ids[i]);
+ if (child == NULL)
+ child = BUS_ADD_CHILD(parent, 1, "nvdimm", dimm_ids[i]);
+ acpi_set_handle(child, handle);
+ }
+ free(dimm_ids, M_NVDIMM);
+ AcpiPutTable(&nfitbl->Header);
}
static int
@@ -311,33 +187,25 @@
ACPI_TABLE_NFIT *nfitbl;
ACPI_HANDLE handle;
ACPI_STATUS status;
- int i;
nv = device_get_softc(dev);
handle = acpi_get_handle(dev);
if (handle == NULL)
return (EINVAL);
nv->nv_dev = dev;
- for (i = 0; i < nvdimm_devcnt; i++) {
- if (nvdimm_devs[i] == dev) {
- nv->nv_devs_idx = i;
- break;
- }
- }
- MPASS(i < nvdimm_devcnt);
- if (ACPI_FAILURE(acpi_GetInteger(handle, "_ADR", &nv->nv_handle))) {
+ status = acpi_GetInteger(handle, "_ADR", &nv->nv_handle);
+ if (!ACPI_SUCCESS(status)) {
device_printf(dev, "cannot get handle\n");
return (ENXIO);
}
status = AcpiGetTable(ACPI_SIG_NFIT, 1, (ACPI_TABLE_HEADER **)&nfitbl);
- if (ACPI_FAILURE(status)) {
- if (bootverbose)
- device_printf(dev, "cannot get NFIT\n");
+ if (!ACPI_SUCCESS(status)) {
+ device_printf(dev, "cannot NFIT table\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);
}
@@ -348,7 +216,6 @@
struct nvdimm_dev *nv;
nv = device_get_softc(dev);
- nvdimm_devs[nv->nv_devs_idx] = NULL;
free(nv->nv_flush_addr, M_NVDIMM);
return (0);
}
@@ -383,41 +250,5 @@
sizeof(struct nvdimm_dev),
};
-static void
-nvdimm_fini(void)
-{
-
- free(nvdimm_devs, M_NVDIMM);
- nvdimm_devs = NULL;
- nvdimm_devcnt = 0;
-}
-
-static int
-nvdimm_modev(struct module *mod, int what, void *arg)
-{
- int error;
-
- switch (what) {
- case MOD_LOAD:
- error = 0;
- break;
-
- case MOD_UNLOAD:
- nvdimm_fini();
- error = 0;
- break;
-
- case MOD_QUIESCE:
- error = 0;
- break;
-
- default:
- error = EOPNOTSUPP;
- break;
- }
-
- return (error);
-}
-
-DRIVER_MODULE(nvdimm, acpi, nvdimm_driver, nvdimm_devclass, nvdimm_modev, NULL);
+DRIVER_MODULE(nvdimm, acpi, nvdimm_driver, nvdimm_devclass, NULL, NULL);
MODULE_DEPEND(nvdimm, acpi, 1, 1, 1);
Index: sys/dev/nvdimm/nvdimm_nfit.c
===================================================================
--- /dev/null
+++ sys/dev/nvdimm/nvdimm_nfit.c
@@ -0,0 +1,199 @@
+/*-
+ * 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 <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) {
+ const uint32_t *a, *b;
+
+ a = _a;
+ b = _b;
+ return *a - *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;
+ int count;
+
+ h = (ACPI_NFIT_HEADER *)(nfitbl + 1);
+ end = (ACPI_NFIT_HEADER *)((char *)nfitbl +
+ nfitbl->Header.Length);
+ count = 0;
+
+ while (h < end) {
+ if (h->Type == type) {
+ val = *(uint64_t *)((char *)h + offset) & 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];
+}
Index: sys/dev/nvdimm/nvdimm_spa.c
===================================================================
--- sys/dev/nvdimm/nvdimm_spa.c
+++ sys/dev/nvdimm/nvdimm_spa.c
@@ -564,6 +564,7 @@
nvdimm_spa_init1(ACPI_TABLE_NFIT *nfitbl)
{
struct nvdimm_SPA_uuid_list_elm *sle;
+ ACPI_NFIT_SYSTEM_ADDRESS **spas;
int error, i;
for (i = 0; i < nitems(nvdimm_SPA_uuid_list); i++) {
@@ -578,21 +579,20 @@
}
}
- error = nvdimm_iterate_nfit(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS,
- nvdimm_spa_count, &spa_mappings_cnt);
- if (error != 0)
- return (error);
+ acpi_nfit_get_spa_ranges(nfitbl, &spas, &spa_mappings_cnt);
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);
+ for (i = 0; i < spa_mappings_cnt; i++) {
+ error = nvdimm_spa_parse(spas[i], &spa_mappings[i]);
+ if (error != 0)
+ break;
+ }
+ free(spas, M_NVDIMM);
if (error != 0) {
free(spa_mappings, M_NVDIMM);
spa_mappings = NULL;
- return (error);
}
- return (0);
+ return (error);
}
static void
Index: sys/dev/nvdimm/nvdimm_var.h
===================================================================
--- sys/dev/nvdimm/nvdimm_var.h
+++ sys/dev/nvdimm/nvdimm_var.h
@@ -39,7 +39,6 @@
nfit_handle_t nv_handle;
uint64_t **nv_flush_addr;
int nv_flush_addr_cnt;
- int nv_devs_idx;
};
enum SPA_mapping_type {
@@ -74,18 +73,24 @@
bool spa_g_proc_exiting;
};
-struct nvdimm_ns_walk_ctx {
- ACPI_STATUS (*func)(ACPI_HANDLE, void *);
- void *arg;
-};
-
extern struct SPA_mapping *spa_mappings;
extern int spa_mappings_cnt;
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);
+
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);
#endif /* __DEV_NVDIMM_VAR_H__ */
Index: sys/modules/nvdimm/Makefile
===================================================================
--- sys/modules/nvdimm/Makefile
+++ sys/modules/nvdimm/Makefile
@@ -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

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 28, 11:04 AM (12 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26281955
Default Alt Text
D18439.id51841.diff (19 KB)

Event Timeline