Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/nvdimm

Pull libnvdimm fixes from Dan Williams:
"1) Fixes for a handful of smatch reports (Thanks Dan C.!) and minor
bug fixes (patches 1-6)

2) Correctness fixes to the BLK-mode nvdimm driver (patches 7-10).

Granted these are slightly large for a -rc update. They have been
out for review in one form or another since the end of May and were
deferred from the merge window while we settled on the "PMEM API"
for the PMEM-mode nvdimm driver (ie memremap_pmem, memcpy_to_pmem,
and wmb_pmem).

Now that those apis are merged we implement them in the BLK driver
to guarantee that mmio aperture moves stay ordered with respect to
incoming read/write requests, and that writes are flushed through
those mmio-windows and platform-buffers to be persistent on media.

These pass the sub-system unit tests with the updates to
tools/testing/nvdimm, and have received a successful build-report from
the kbuild robot (468 configs).

With acks from Rafael for the touches to drivers/acpi/"

* 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/nvdimm:
nfit: add support for NVDIMM "latch" flag
nfit: update block I/O path to use PMEM API
tools/testing/nvdimm: add mock acpi_nfit_flush_address entries to nfit_test
tools/testing/nvdimm: fix return code for unimplemented commands
tools/testing/nvdimm: mock ioremap_wt
pmem: add maintainer for include/linux/pmem.h
nfit: fix smatch "use after null check" report
nvdimm: Fix return value of nvdimm_bus_init() if class_create() fails
libnvdimm: smatch cleanups in __nd_ioctl
sparse: fix misplaced __pmem definition

+223 -27
+1
MAINTAINERS
··· 6160 6160 Q: https://patchwork.kernel.org/project/linux-nvdimm/list/ 6161 6161 S: Supported 6162 6162 F: drivers/nvdimm/pmem.c 6163 + F: include/linux/pmem.h 6163 6164 6164 6165 LINUX FOR IBM pSERIES (RS/6000) 6165 6166 M: Paul Mackerras <paulus@au.ibm.com>
+120 -14
drivers/acpi/nfit.c
··· 18 18 #include <linux/list.h> 19 19 #include <linux/acpi.h> 20 20 #include <linux/sort.h> 21 + #include <linux/pmem.h> 21 22 #include <linux/io.h> 22 23 #include "nfit.h" 23 24 ··· 306 305 return true; 307 306 } 308 307 308 + static bool add_flush(struct acpi_nfit_desc *acpi_desc, 309 + struct acpi_nfit_flush_address *flush) 310 + { 311 + struct device *dev = acpi_desc->dev; 312 + struct nfit_flush *nfit_flush = devm_kzalloc(dev, sizeof(*nfit_flush), 313 + GFP_KERNEL); 314 + 315 + if (!nfit_flush) 316 + return false; 317 + INIT_LIST_HEAD(&nfit_flush->list); 318 + nfit_flush->flush = flush; 319 + list_add_tail(&nfit_flush->list, &acpi_desc->flushes); 320 + dev_dbg(dev, "%s: nfit_flush handle: %d hint_count: %d\n", __func__, 321 + flush->device_handle, flush->hint_count); 322 + return true; 323 + } 324 + 309 325 static void *add_table(struct acpi_nfit_desc *acpi_desc, void *table, 310 326 const void *end) 311 327 { ··· 356 338 return err; 357 339 break; 358 340 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 359 - dev_dbg(dev, "%s: flush\n", __func__); 341 + if (!add_flush(acpi_desc, table)) 342 + return err; 360 343 break; 361 344 case ACPI_NFIT_TYPE_SMBIOS: 362 345 dev_dbg(dev, "%s: smbios\n", __func__); ··· 408 389 { 409 390 u16 dcr = __to_nfit_memdev(nfit_mem)->region_index; 410 391 struct nfit_memdev *nfit_memdev; 392 + struct nfit_flush *nfit_flush; 411 393 struct nfit_dcr *nfit_dcr; 412 394 struct nfit_bdw *nfit_bdw; 413 395 struct nfit_idt *nfit_idt; ··· 460 440 if (nfit_idt->idt->interleave_index != idt_idx) 461 441 continue; 462 442 nfit_mem->idt_bdw = nfit_idt->idt; 443 + break; 444 + } 445 + 446 + list_for_each_entry(nfit_flush, &acpi_desc->flushes, list) { 447 + if (nfit_flush->flush->device_handle != 448 + nfit_memdev->memdev->device_handle) 449 + continue; 450 + nfit_mem->nfit_flush = nfit_flush; 463 451 break; 464 452 } 465 453 break; ··· 1006 978 return mmio->base_offset + line_offset + table_offset + sub_line_offset; 1007 979 } 1008 980 981 + static void wmb_blk(struct nfit_blk *nfit_blk) 982 + { 983 + 984 + if (nfit_blk->nvdimm_flush) { 985 + /* 986 + * The first wmb() is needed to 'sfence' all previous writes 987 + * such that they are architecturally visible for the platform 988 + * buffer flush. Note that we've already arranged for pmem 989 + * writes to avoid the cache via arch_memcpy_to_pmem(). The 990 + * final wmb() ensures ordering for the NVDIMM flush write. 991 + */ 992 + wmb(); 993 + writeq(1, nfit_blk->nvdimm_flush); 994 + wmb(); 995 + } else 996 + wmb_pmem(); 997 + } 998 + 1009 999 static u64 read_blk_stat(struct nfit_blk *nfit_blk, unsigned int bw) 1010 1000 { 1011 1001 struct nfit_blk_mmio *mmio = &nfit_blk->mmio[DCR]; ··· 1058 1012 offset = to_interleave_offset(offset, mmio); 1059 1013 1060 1014 writeq(cmd, mmio->base + offset); 1061 - /* FIXME: conditionally perform read-back if mandated by firmware */ 1015 + wmb_blk(nfit_blk); 1016 + 1017 + if (nfit_blk->dimm_flags & ND_BLK_DCR_LATCH) 1018 + readq(mmio->base + offset); 1062 1019 } 1063 1020 1064 1021 static int acpi_nfit_blk_single_io(struct nfit_blk *nfit_blk, ··· 1075 1026 1076 1027 base_offset = nfit_blk->bdw_offset + dpa % L1_CACHE_BYTES 1077 1028 + lane * mmio->size; 1078 - /* TODO: non-temporal access, flush hints, cache management etc... */ 1079 1029 write_blk_ctl(nfit_blk, lane, dpa, len, rw); 1080 1030 while (len) { 1081 1031 unsigned int c; ··· 1093 1045 } 1094 1046 1095 1047 if (rw) 1096 - memcpy(mmio->aperture + offset, iobuf + copied, c); 1048 + memcpy_to_pmem(mmio->aperture + offset, 1049 + iobuf + copied, c); 1097 1050 else 1098 - memcpy(iobuf + copied, mmio->aperture + offset, c); 1051 + memcpy_from_pmem(iobuf + copied, 1052 + mmio->aperture + offset, c); 1099 1053 1100 1054 copied += c; 1101 1055 len -= c; 1102 1056 } 1057 + 1058 + if (rw) 1059 + wmb_blk(nfit_blk); 1060 + 1103 1061 rc = read_blk_stat(nfit_blk, lane) ? -EIO : 0; 1104 1062 return rc; 1105 1063 } ··· 1178 1124 } 1179 1125 1180 1126 static void __iomem *__nfit_spa_map(struct acpi_nfit_desc *acpi_desc, 1181 - struct acpi_nfit_system_address *spa) 1127 + struct acpi_nfit_system_address *spa, enum spa_map_type type) 1182 1128 { 1183 1129 resource_size_t start = spa->address; 1184 1130 resource_size_t n = spa->length; ··· 1206 1152 if (!res) 1207 1153 goto err_mem; 1208 1154 1209 - /* TODO: cacheability based on the spa type */ 1210 - spa_map->iomem = ioremap_nocache(start, n); 1155 + if (type == SPA_MAP_APERTURE) { 1156 + /* 1157 + * TODO: memremap_pmem() support, but that requires cache 1158 + * flushing when the aperture is moved. 1159 + */ 1160 + spa_map->iomem = ioremap_wc(start, n); 1161 + } else 1162 + spa_map->iomem = ioremap_nocache(start, n); 1163 + 1211 1164 if (!spa_map->iomem) 1212 1165 goto err_map; 1213 1166 ··· 1232 1171 * nfit_spa_map - interleave-aware managed-mappings of acpi_nfit_system_address ranges 1233 1172 * @nvdimm_bus: NFIT-bus that provided the spa table entry 1234 1173 * @nfit_spa: spa table to map 1174 + * @type: aperture or control region 1235 1175 * 1236 1176 * In the case where block-data-window apertures and 1237 1177 * dimm-control-regions are interleaved they will end up sharing a ··· 1242 1180 * unbound. 1243 1181 */ 1244 1182 static void __iomem *nfit_spa_map(struct acpi_nfit_desc *acpi_desc, 1245 - struct acpi_nfit_system_address *spa) 1183 + struct acpi_nfit_system_address *spa, enum spa_map_type type) 1246 1184 { 1247 1185 void __iomem *iomem; 1248 1186 1249 1187 mutex_lock(&acpi_desc->spa_map_mutex); 1250 - iomem = __nfit_spa_map(acpi_desc, spa); 1188 + iomem = __nfit_spa_map(acpi_desc, spa, type); 1251 1189 mutex_unlock(&acpi_desc->spa_map_mutex); 1252 1190 1253 1191 return iomem; ··· 1268 1206 return 0; 1269 1207 } 1270 1208 1209 + static int acpi_nfit_blk_get_flags(struct nvdimm_bus_descriptor *nd_desc, 1210 + struct nvdimm *nvdimm, struct nfit_blk *nfit_blk) 1211 + { 1212 + struct nd_cmd_dimm_flags flags; 1213 + int rc; 1214 + 1215 + memset(&flags, 0, sizeof(flags)); 1216 + rc = nd_desc->ndctl(nd_desc, nvdimm, ND_CMD_DIMM_FLAGS, &flags, 1217 + sizeof(flags)); 1218 + 1219 + if (rc >= 0 && flags.status == 0) 1220 + nfit_blk->dimm_flags = flags.flags; 1221 + else if (rc == -ENOTTY) { 1222 + /* fall back to a conservative default */ 1223 + nfit_blk->dimm_flags = ND_BLK_DCR_LATCH; 1224 + rc = 0; 1225 + } else 1226 + rc = -ENXIO; 1227 + 1228 + return rc; 1229 + } 1230 + 1271 1231 static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus, 1272 1232 struct device *dev) 1273 1233 { 1274 1234 struct nvdimm_bus_descriptor *nd_desc = to_nd_desc(nvdimm_bus); 1275 1235 struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); 1276 1236 struct nd_blk_region *ndbr = to_nd_blk_region(dev); 1237 + struct nfit_flush *nfit_flush; 1277 1238 struct nfit_blk_mmio *mmio; 1278 1239 struct nfit_blk *nfit_blk; 1279 1240 struct nfit_mem *nfit_mem; ··· 1308 1223 if (!nfit_mem || !nfit_mem->dcr || !nfit_mem->bdw) { 1309 1224 dev_dbg(dev, "%s: missing%s%s%s\n", __func__, 1310 1225 nfit_mem ? "" : " nfit_mem", 1311 - nfit_mem->dcr ? "" : " dcr", 1312 - nfit_mem->bdw ? "" : " bdw"); 1226 + (nfit_mem && nfit_mem->dcr) ? "" : " dcr", 1227 + (nfit_mem && nfit_mem->bdw) ? "" : " bdw"); 1313 1228 return -ENXIO; 1314 1229 } 1315 1230 ··· 1322 1237 /* map block aperture memory */ 1323 1238 nfit_blk->bdw_offset = nfit_mem->bdw->offset; 1324 1239 mmio = &nfit_blk->mmio[BDW]; 1325 - mmio->base = nfit_spa_map(acpi_desc, nfit_mem->spa_bdw); 1240 + mmio->base = nfit_spa_map(acpi_desc, nfit_mem->spa_bdw, 1241 + SPA_MAP_APERTURE); 1326 1242 if (!mmio->base) { 1327 1243 dev_dbg(dev, "%s: %s failed to map bdw\n", __func__, 1328 1244 nvdimm_name(nvdimm)); ··· 1345 1259 nfit_blk->cmd_offset = nfit_mem->dcr->command_offset; 1346 1260 nfit_blk->stat_offset = nfit_mem->dcr->status_offset; 1347 1261 mmio = &nfit_blk->mmio[DCR]; 1348 - mmio->base = nfit_spa_map(acpi_desc, nfit_mem->spa_dcr); 1262 + mmio->base = nfit_spa_map(acpi_desc, nfit_mem->spa_dcr, 1263 + SPA_MAP_CONTROL); 1349 1264 if (!mmio->base) { 1350 1265 dev_dbg(dev, "%s: %s failed to map dcr\n", __func__, 1351 1266 nvdimm_name(nvdimm)); ··· 1363 1276 __func__, nvdimm_name(nvdimm)); 1364 1277 return rc; 1365 1278 } 1279 + 1280 + rc = acpi_nfit_blk_get_flags(nd_desc, nvdimm, nfit_blk); 1281 + if (rc < 0) { 1282 + dev_dbg(dev, "%s: %s failed get DIMM flags\n", 1283 + __func__, nvdimm_name(nvdimm)); 1284 + return rc; 1285 + } 1286 + 1287 + nfit_flush = nfit_mem->nfit_flush; 1288 + if (nfit_flush && nfit_flush->flush->hint_count != 0) { 1289 + nfit_blk->nvdimm_flush = devm_ioremap_nocache(dev, 1290 + nfit_flush->flush->hint_address[0], 8); 1291 + if (!nfit_blk->nvdimm_flush) 1292 + return -ENOMEM; 1293 + } 1294 + 1295 + if (!arch_has_pmem_api() && !nfit_blk->nvdimm_flush) 1296 + dev_warn(dev, "unable to guarantee persistence of writes\n"); 1366 1297 1367 1298 if (mmio->line_size == 0) 1368 1299 return 0; ··· 1564 1459 INIT_LIST_HEAD(&acpi_desc->dcrs); 1565 1460 INIT_LIST_HEAD(&acpi_desc->bdws); 1566 1461 INIT_LIST_HEAD(&acpi_desc->idts); 1462 + INIT_LIST_HEAD(&acpi_desc->flushes); 1567 1463 INIT_LIST_HEAD(&acpi_desc->memdevs); 1568 1464 INIT_LIST_HEAD(&acpi_desc->dimms); 1569 1465 mutex_init(&acpi_desc->spa_map_mutex);
+19 -1
drivers/acpi/nfit.h
··· 40 40 NFIT_UUID_MAX, 41 41 }; 42 42 43 + enum { 44 + ND_BLK_DCR_LATCH = 2, 45 + }; 46 + 43 47 struct nfit_spa { 44 48 struct acpi_nfit_system_address *spa; 45 49 struct list_head list; ··· 64 60 struct list_head list; 65 61 }; 66 62 63 + struct nfit_flush { 64 + struct acpi_nfit_flush_address *flush; 65 + struct list_head list; 66 + }; 67 + 67 68 struct nfit_memdev { 68 69 struct acpi_nfit_memory_map *memdev; 69 70 struct list_head list; ··· 86 77 struct acpi_nfit_system_address *spa_bdw; 87 78 struct acpi_nfit_interleave *idt_dcr; 88 79 struct acpi_nfit_interleave *idt_bdw; 80 + struct nfit_flush *nfit_flush; 89 81 struct list_head list; 90 82 struct acpi_device *adev; 91 83 unsigned long dsm_mask; ··· 98 88 struct mutex spa_map_mutex; 99 89 struct list_head spa_maps; 100 90 struct list_head memdevs; 91 + struct list_head flushes; 101 92 struct list_head dimms; 102 93 struct list_head spas; 103 94 struct list_head dcrs; ··· 120 109 struct nfit_blk_mmio { 121 110 union { 122 111 void __iomem *base; 123 - void *aperture; 112 + void __pmem *aperture; 124 113 }; 125 114 u64 size; 126 115 u64 base_offset; ··· 134 123 u64 bdw_offset; /* post interleave offset */ 135 124 u64 stat_offset; 136 125 u64 cmd_offset; 126 + void __iomem *nvdimm_flush; 127 + u32 dimm_flags; 128 + }; 129 + 130 + enum spa_map_type { 131 + SPA_MAP_CONTROL, 132 + SPA_MAP_APERTURE, 137 133 }; 138 134 139 135 struct nfit_spa_mapping {
+3 -8
drivers/nvdimm/bus.c
··· 535 535 __func__, dimm_name, cmd_name, i); 536 536 return -ENXIO; 537 537 } 538 - if (!access_ok(VERIFY_READ, p + in_len, in_size)) 539 - return -EFAULT; 540 538 if (in_len < sizeof(in_env)) 541 539 copy = min_t(u32, sizeof(in_env) - in_len, in_size); 542 540 else ··· 555 557 __func__, dimm_name, cmd_name, i); 556 558 return -EFAULT; 557 559 } 558 - if (!access_ok(VERIFY_WRITE, p + in_len + out_len, out_size)) 559 - return -EFAULT; 560 560 if (out_len < sizeof(out_env)) 561 561 copy = min_t(u32, sizeof(out_env) - out_len, out_size); 562 562 else ··· 566 570 } 567 571 568 572 buf_len = out_len + in_len; 569 - if (!access_ok(VERIFY_WRITE, p, sizeof(buf_len))) 570 - return -EFAULT; 571 - 572 573 if (buf_len > ND_IOCTL_MAX_BUFLEN) { 573 574 dev_dbg(dev, "%s:%s cmd: %s buf_len: %zu > %d\n", __func__, 574 575 dimm_name, cmd_name, buf_len, ··· 699 706 nvdimm_major = rc; 700 707 701 708 nd_class = class_create(THIS_MODULE, "nd"); 702 - if (IS_ERR(nd_class)) 709 + if (IS_ERR(nd_class)) { 710 + rc = PTR_ERR(nd_class); 703 711 goto err_class; 712 + } 704 713 705 714 return 0; 706 715
+1 -1
include/linux/compiler.h
··· 17 17 # define __release(x) __context__(x,-1) 18 18 # define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) 19 19 # define __percpu __attribute__((noderef, address_space(3))) 20 + # define __pmem __attribute__((noderef, address_space(5))) 20 21 #ifdef CONFIG_SPARSE_RCU_POINTER 21 22 # define __rcu __attribute__((noderef, address_space(4))) 22 23 #else 23 24 # define __rcu 24 - # define __pmem __attribute__((noderef, address_space(5))) 25 25 #endif 26 26 extern void __chk_user_ptr(const volatile void __user *); 27 27 extern void __chk_io_ptr(const volatile void __iomem *);
+3
tools/testing/nvdimm/Kbuild
··· 1 + ldflags-y += --wrap=ioremap_wt 2 + ldflags-y += --wrap=ioremap_wc 3 + ldflags-y += --wrap=devm_ioremap_nocache 1 4 ldflags-y += --wrap=ioremap_cache 2 5 ldflags-y += --wrap=ioremap_nocache 3 6 ldflags-y += --wrap=iounmap
+27
tools/testing/nvdimm/test/iomap.c
··· 65 65 return fallback_fn(offset, size); 66 66 } 67 67 68 + void __iomem *__wrap_devm_ioremap_nocache(struct device *dev, 69 + resource_size_t offset, unsigned long size) 70 + { 71 + struct nfit_test_resource *nfit_res; 72 + 73 + rcu_read_lock(); 74 + nfit_res = get_nfit_res(offset); 75 + rcu_read_unlock(); 76 + if (nfit_res) 77 + return (void __iomem *) nfit_res->buf + offset 78 + - nfit_res->res->start; 79 + return devm_ioremap_nocache(dev, offset, size); 80 + } 81 + EXPORT_SYMBOL(__wrap_devm_ioremap_nocache); 82 + 68 83 void __iomem *__wrap_ioremap_cache(resource_size_t offset, unsigned long size) 69 84 { 70 85 return __nfit_test_ioremap(offset, size, ioremap_cache); ··· 91 76 return __nfit_test_ioremap(offset, size, ioremap_nocache); 92 77 } 93 78 EXPORT_SYMBOL(__wrap_ioremap_nocache); 79 + 80 + void __iomem *__wrap_ioremap_wt(resource_size_t offset, unsigned long size) 81 + { 82 + return __nfit_test_ioremap(offset, size, ioremap_wt); 83 + } 84 + EXPORT_SYMBOL(__wrap_ioremap_wt); 85 + 86 + void __iomem *__wrap_ioremap_wc(resource_size_t offset, unsigned long size) 87 + { 88 + return __nfit_test_ioremap(offset, size, ioremap_wc); 89 + } 90 + EXPORT_SYMBOL(__wrap_ioremap_wc); 94 91 95 92 void __wrap_iounmap(volatile void __iomem *addr) 96 93 {
+49 -3
tools/testing/nvdimm/test/nfit.c
··· 128 128 int num_pm; 129 129 void **dimm; 130 130 dma_addr_t *dimm_dma; 131 + void **flush; 132 + dma_addr_t *flush_dma; 131 133 void **label; 132 134 dma_addr_t *label_dma; 133 135 void **spa_set; ··· 157 155 int i, rc; 158 156 159 157 if (!nfit_mem || !test_bit(cmd, &nfit_mem->dsm_mask)) 160 - return -ENXIO; 158 + return -ENOTTY; 161 159 162 160 /* lookup label space for the given dimm */ 163 161 for (i = 0; i < ARRAY_SIZE(handle); i++) ··· 333 331 + sizeof(struct acpi_nfit_system_address) * NUM_SPA 334 332 + sizeof(struct acpi_nfit_memory_map) * NUM_MEM 335 333 + sizeof(struct acpi_nfit_control_region) * NUM_DCR 336 - + sizeof(struct acpi_nfit_data_region) * NUM_BDW; 334 + + sizeof(struct acpi_nfit_data_region) * NUM_BDW 335 + + sizeof(struct acpi_nfit_flush_address) * NUM_DCR; 337 336 int i; 338 337 339 338 t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma); ··· 359 356 if (!t->label[i]) 360 357 return -ENOMEM; 361 358 sprintf(t->label[i], "label%d", i); 359 + 360 + t->flush[i] = test_alloc(t, 8, &t->flush_dma[i]); 361 + if (!t->flush[i]) 362 + return -ENOMEM; 362 363 } 363 364 364 365 for (i = 0; i < NUM_DCR; i++) { ··· 415 408 struct acpi_nfit_system_address *spa; 416 409 struct acpi_nfit_control_region *dcr; 417 410 struct acpi_nfit_data_region *bdw; 411 + struct acpi_nfit_flush_address *flush; 418 412 unsigned int offset; 419 413 420 414 nfit_test_init_header(nfit_buf, size); ··· 839 831 bdw->capacity = DIMM_SIZE; 840 832 bdw->start_address = 0; 841 833 834 + offset = offset + sizeof(struct acpi_nfit_data_region) * 4; 835 + /* flush0 (dimm0) */ 836 + flush = nfit_buf + offset; 837 + flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 838 + flush->header.length = sizeof(struct acpi_nfit_flush_address); 839 + flush->device_handle = handle[0]; 840 + flush->hint_count = 1; 841 + flush->hint_address[0] = t->flush_dma[0]; 842 + 843 + /* flush1 (dimm1) */ 844 + flush = nfit_buf + offset + sizeof(struct acpi_nfit_flush_address) * 1; 845 + flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 846 + flush->header.length = sizeof(struct acpi_nfit_flush_address); 847 + flush->device_handle = handle[1]; 848 + flush->hint_count = 1; 849 + flush->hint_address[0] = t->flush_dma[1]; 850 + 851 + /* flush2 (dimm2) */ 852 + flush = nfit_buf + offset + sizeof(struct acpi_nfit_flush_address) * 2; 853 + flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 854 + flush->header.length = sizeof(struct acpi_nfit_flush_address); 855 + flush->device_handle = handle[2]; 856 + flush->hint_count = 1; 857 + flush->hint_address[0] = t->flush_dma[2]; 858 + 859 + /* flush3 (dimm3) */ 860 + flush = nfit_buf + offset + sizeof(struct acpi_nfit_flush_address) * 3; 861 + flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 862 + flush->header.length = sizeof(struct acpi_nfit_flush_address); 863 + flush->device_handle = handle[3]; 864 + flush->hint_count = 1; 865 + flush->hint_address[0] = t->flush_dma[3]; 866 + 842 867 acpi_desc = &t->acpi_desc; 843 868 set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_dsm_force_en); 844 869 set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en); ··· 974 933 GFP_KERNEL); 975 934 nfit_test->dimm_dma = devm_kcalloc(dev, num, sizeof(dma_addr_t), 976 935 GFP_KERNEL); 936 + nfit_test->flush = devm_kcalloc(dev, num, sizeof(void *), 937 + GFP_KERNEL); 938 + nfit_test->flush_dma = devm_kcalloc(dev, num, sizeof(dma_addr_t), 939 + GFP_KERNEL); 977 940 nfit_test->label = devm_kcalloc(dev, num, sizeof(void *), 978 941 GFP_KERNEL); 979 942 nfit_test->label_dma = devm_kcalloc(dev, num, ··· 988 943 sizeof(dma_addr_t), GFP_KERNEL); 989 944 if (nfit_test->dimm && nfit_test->dimm_dma && nfit_test->label 990 945 && nfit_test->label_dma && nfit_test->dcr 991 - && nfit_test->dcr_dma) 946 + && nfit_test->dcr_dma && nfit_test->flush 947 + && nfit_test->flush_dma) 992 948 /* pass */; 993 949 else 994 950 return -ENOMEM;