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

Merge tag 'libnvdimm-for-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm

Pull libnvdimm updates from Dan Williams:
"The libnvdimm pull request is relatively small this time around due to
some development topics being deferred to 4.11.

As for this pull request the bulk of it has been in -next for several
releases leading to one late fix being added (commit 868f036fee4b
("libnvdimm: fix mishandled nvdimm_clear_poison() return value")). It
has received a build success notification from the 0day-kbuild robot
and passes the latest libnvdimm unit tests.

Summary:

- Dynamic label support: To date namespace label support has been
limited to disambiguating cases where PMEM (direct load/store) and
BLK (mmio aperture) accessed-capacity alias on the same DIMM. Since
4.9 added support for multiple namespaces per PMEM-region there is
value to support namespace labels even in the non-aliasing case.
The presence of a valid namespace index block force-enables label
support when the kernel would otherwise rely on region boundaries,
and permits the region to be sub-divided.

- Handle media errors in namespace metadata: Complement the error
handling for media errors in namespace data areas with support for
clearing errors on writes, and downgrading potential machine-check
exceptions to simple i/o errors on read.

- Device-DAX region attributes: Add 'align', 'id', and 'size' as
attributes for device-dax regions. In particular this enables
userspace tooling to generically size memory mapping and i/o
operations. Prevent userspace from growing assumptions /
dependencies about the parent device topology for a dax region. A
libnvdimm namespace may not always be the parent device of a dax
region.

- Various cleanups and small fixes"

* tag 'libnvdimm-for-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
dax: add region 'id', 'size', and 'align' attributes
libnvdimm: fix mishandled nvdimm_clear_poison() return value
libnvdimm: replace mutex_is_locked() warnings with lockdep_assert_held
libnvdimm, pfn: fix align attribute
libnvdimm, e820: use module_platform_driver
libnvdimm, namespace: use octal for permissions
libnvdimm, namespace: avoid multiple sector calculations
libnvdimm: remove else after return in nsio_rw_bytes()
libnvdimm, namespace: fix the type of name variable
libnvdimm: use consistent naming for request_mem_region()
nvdimm: use the right length of "pmem"
libnvdimm: check and clear poison before writing to pmem
tools/testing/nvdimm: dynamic label support
libnvdimm: allow a platform to force enable label support
libnvdimm: use generic iostat interfaces

+190 -80
+94
drivers/dax/dax.c
··· 75 75 struct resource res[0]; 76 76 }; 77 77 78 + static ssize_t id_show(struct device *dev, 79 + struct device_attribute *attr, char *buf) 80 + { 81 + struct dax_region *dax_region; 82 + ssize_t rc = -ENXIO; 83 + 84 + device_lock(dev); 85 + dax_region = dev_get_drvdata(dev); 86 + if (dax_region) 87 + rc = sprintf(buf, "%d\n", dax_region->id); 88 + device_unlock(dev); 89 + 90 + return rc; 91 + } 92 + static DEVICE_ATTR_RO(id); 93 + 94 + static ssize_t region_size_show(struct device *dev, 95 + struct device_attribute *attr, char *buf) 96 + { 97 + struct dax_region *dax_region; 98 + ssize_t rc = -ENXIO; 99 + 100 + device_lock(dev); 101 + dax_region = dev_get_drvdata(dev); 102 + if (dax_region) 103 + rc = sprintf(buf, "%llu\n", (unsigned long long) 104 + resource_size(&dax_region->res)); 105 + device_unlock(dev); 106 + 107 + return rc; 108 + } 109 + static struct device_attribute dev_attr_region_size = __ATTR(size, 0444, 110 + region_size_show, NULL); 111 + 112 + static ssize_t align_show(struct device *dev, 113 + struct device_attribute *attr, char *buf) 114 + { 115 + struct dax_region *dax_region; 116 + ssize_t rc = -ENXIO; 117 + 118 + device_lock(dev); 119 + dax_region = dev_get_drvdata(dev); 120 + if (dax_region) 121 + rc = sprintf(buf, "%u\n", dax_region->align); 122 + device_unlock(dev); 123 + 124 + return rc; 125 + } 126 + static DEVICE_ATTR_RO(align); 127 + 128 + static struct attribute *dax_region_attributes[] = { 129 + &dev_attr_region_size.attr, 130 + &dev_attr_align.attr, 131 + &dev_attr_id.attr, 132 + NULL, 133 + }; 134 + 135 + static const struct attribute_group dax_region_attribute_group = { 136 + .name = "dax_region", 137 + .attrs = dax_region_attributes, 138 + }; 139 + 140 + static const struct attribute_group *dax_region_attribute_groups[] = { 141 + &dax_region_attribute_group, 142 + NULL, 143 + }; 144 + 78 145 static struct inode *dax_alloc_inode(struct super_block *sb) 79 146 { 80 147 return kmem_cache_alloc(dax_cache, GFP_KERNEL); ··· 267 200 } 268 201 EXPORT_SYMBOL_GPL(dax_region_put); 269 202 203 + static void dax_region_unregister(void *region) 204 + { 205 + struct dax_region *dax_region = region; 206 + 207 + sysfs_remove_groups(&dax_region->dev->kobj, 208 + dax_region_attribute_groups); 209 + dax_region_put(dax_region); 210 + } 211 + 270 212 struct dax_region *alloc_dax_region(struct device *parent, int region_id, 271 213 struct resource *res, unsigned int align, void *addr, 272 214 unsigned long pfn_flags) 273 215 { 274 216 struct dax_region *dax_region; 217 + 218 + /* 219 + * The DAX core assumes that it can store its private data in 220 + * parent->driver_data. This WARN is a reminder / safeguard for 221 + * developers of device-dax drivers. 222 + */ 223 + if (dev_get_drvdata(parent)) { 224 + dev_WARN(parent, "dax core failed to setup private data\n"); 225 + return NULL; 226 + } 275 227 276 228 if (!IS_ALIGNED(res->start, align) 277 229 || !IS_ALIGNED(resource_size(res), align)) ··· 300 214 if (!dax_region) 301 215 return NULL; 302 216 217 + dev_set_drvdata(parent, dax_region); 303 218 memcpy(&dax_region->res, res, sizeof(*res)); 304 219 dax_region->pfn_flags = pfn_flags; 305 220 kref_init(&dax_region->kref); ··· 309 222 dax_region->align = align; 310 223 dax_region->dev = parent; 311 224 dax_region->base = addr; 225 + if (sysfs_create_groups(&parent->kobj, dax_region_attribute_groups)) { 226 + kfree(dax_region); 227 + return NULL;; 228 + } 312 229 230 + kref_get(&dax_region->kref); 231 + if (devm_add_action_or_reset(parent, dax_region_unregister, dax_region)) 232 + return NULL; 313 233 return dax_region; 314 234 } 315 235 EXPORT_SYMBOL_GPL(alloc_dax_region);
+2 -1
drivers/dax/pmem.c
··· 89 89 pfn_sb = nd_pfn->pfn_sb; 90 90 91 91 if (!devm_request_mem_region(dev, nsio->res.start, 92 - resource_size(&nsio->res), dev_name(dev))) { 92 + resource_size(&nsio->res), 93 + dev_name(&ndns->dev))) { 93 94 dev_warn(dev, "could not reserve region %pR\n", &nsio->res); 94 95 return -EBUSY; 95 96 }
+32 -14
drivers/nvdimm/claim.c
··· 22 22 { 23 23 struct nd_namespace_common *ndns = *_ndns; 24 24 25 - dev_WARN_ONCE(dev, !mutex_is_locked(&ndns->dev.mutex) 26 - || ndns->claim != dev, 27 - "%s: invalid claim\n", __func__); 25 + lockdep_assert_held(&ndns->dev.mutex); 26 + dev_WARN_ONCE(dev, ndns->claim != dev, "%s: invalid claim\n", __func__); 28 27 ndns->claim = NULL; 29 28 *_ndns = NULL; 30 29 put_device(&ndns->dev); ··· 48 49 { 49 50 if (attach->claim) 50 51 return false; 51 - dev_WARN_ONCE(dev, !mutex_is_locked(&attach->dev.mutex) 52 - || *_ndns, 53 - "%s: invalid claim\n", __func__); 52 + lockdep_assert_held(&attach->dev.mutex); 53 + dev_WARN_ONCE(dev, *_ndns, "%s: invalid claim\n", __func__); 54 54 attach->claim = dev; 55 55 *_ndns = attach; 56 56 get_device(&attach->dev); ··· 224 226 resource_size_t offset, void *buf, size_t size, int rw) 225 227 { 226 228 struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev); 229 + unsigned int sz_align = ALIGN(size + (offset & (512 - 1)), 512); 230 + sector_t sector = offset >> 9; 231 + int rc = 0; 232 + 233 + if (unlikely(!size)) 234 + return 0; 227 235 228 236 if (unlikely(offset + size > nsio->size)) { 229 237 dev_WARN_ONCE(&ndns->dev, 1, "request out of range\n"); ··· 237 233 } 238 234 239 235 if (rw == READ) { 240 - unsigned int sz_align = ALIGN(size + (offset & (512 - 1)), 512); 241 - 242 - if (unlikely(is_bad_pmem(&nsio->bb, offset / 512, sz_align))) 236 + if (unlikely(is_bad_pmem(&nsio->bb, sector, sz_align))) 243 237 return -EIO; 244 238 return memcpy_from_pmem(buf, nsio->addr + offset, size); 245 - } else { 246 - memcpy_to_pmem(nsio->addr + offset, buf, size); 247 - nvdimm_flush(to_nd_region(ndns->dev.parent)); 248 239 } 249 240 250 - return 0; 241 + if (unlikely(is_bad_pmem(&nsio->bb, sector, sz_align))) { 242 + if (IS_ALIGNED(offset, 512) && IS_ALIGNED(size, 512)) { 243 + long cleared; 244 + 245 + cleared = nvdimm_clear_poison(&ndns->dev, offset, size); 246 + if (cleared < size) 247 + rc = -EIO; 248 + if (cleared > 0 && cleared / 512) { 249 + cleared /= 512; 250 + badblocks_clear(&nsio->bb, sector, cleared); 251 + } 252 + invalidate_pmem(nsio->addr + offset, size); 253 + } else 254 + rc = -EIO; 255 + } 256 + 257 + memcpy_to_pmem(nsio->addr + offset, buf, size); 258 + nvdimm_flush(to_nd_region(ndns->dev.parent)); 259 + 260 + return rc; 251 261 } 252 262 253 263 int devm_nsio_enable(struct device *dev, struct nd_namespace_io *nsio) ··· 271 253 272 254 nsio->size = resource_size(res); 273 255 if (!devm_request_mem_region(dev, res->start, resource_size(res), 274 - dev_name(dev))) { 256 + dev_name(&ndns->dev))) { 275 257 dev_warn(dev, "could not reserve region %pR\n", res); 276 258 return -EBUSY; 277 259 }
-29
drivers/nvdimm/core.c
··· 317 317 } 318 318 } 319 319 320 - void __nd_iostat_start(struct bio *bio, unsigned long *start) 321 - { 322 - struct gendisk *disk = bio->bi_bdev->bd_disk; 323 - const int rw = bio_data_dir(bio); 324 - int cpu = part_stat_lock(); 325 - 326 - *start = jiffies; 327 - part_round_stats(cpu, &disk->part0); 328 - part_stat_inc(cpu, &disk->part0, ios[rw]); 329 - part_stat_add(cpu, &disk->part0, sectors[rw], bio_sectors(bio)); 330 - part_inc_in_flight(&disk->part0, rw); 331 - part_stat_unlock(); 332 - } 333 - EXPORT_SYMBOL(__nd_iostat_start); 334 - 335 - void nd_iostat_end(struct bio *bio, unsigned long start) 336 - { 337 - struct gendisk *disk = bio->bi_bdev->bd_disk; 338 - unsigned long duration = jiffies - start; 339 - const int rw = bio_data_dir(bio); 340 - int cpu = part_stat_lock(); 341 - 342 - part_stat_add(cpu, &disk->part0, ticks[rw], duration); 343 - part_round_stats(cpu, &disk->part0); 344 - part_dec_in_flight(&disk->part0, rw); 345 - part_stat_unlock(); 346 - } 347 - EXPORT_SYMBOL(nd_iostat_end); 348 - 349 320 static ssize_t commands_show(struct device *dev, 350 321 struct device_attribute *attr, char *buf) 351 322 {
+2
drivers/nvdimm/dimm.c
··· 64 64 nd_label_copy(ndd, to_next_namespace_index(ndd), 65 65 to_current_namespace_index(ndd)); 66 66 rc = nd_label_reserve_dpa(ndd); 67 + if (ndd->ns_current >= 0) 68 + nvdimm_set_aliasing(dev); 67 69 nvdimm_bus_unlock(dev); 68 70 69 71 if (rc)
+7
drivers/nvdimm/dimm_devs.c
··· 184 184 return rc; 185 185 } 186 186 187 + void nvdimm_set_aliasing(struct device *dev) 188 + { 189 + struct nvdimm *nvdimm = to_nvdimm(dev); 190 + 191 + nvdimm->flags |= NDD_ALIASING; 192 + } 193 + 187 194 static void nvdimm_release(struct device *dev) 188 195 { 189 196 struct nvdimm *nvdimm = to_nvdimm(dev);
+1 -11
drivers/nvdimm/e820.c
··· 84 84 }, 85 85 }; 86 86 87 - static __init int e820_pmem_init(void) 88 - { 89 - return platform_driver_register(&e820_pmem_driver); 90 - } 91 - 92 - static __exit void e820_pmem_exit(void) 93 - { 94 - platform_driver_unregister(&e820_pmem_driver); 95 - } 87 + module_platform_driver(e820_pmem_driver); 96 88 97 89 MODULE_ALIAS("platform:e820_pmem*"); 98 90 MODULE_LICENSE("GPL v2"); 99 91 MODULE_AUTHOR("Intel Corporation"); 100 - module_init(e820_pmem_init); 101 - module_exit(e820_pmem_exit);
+1 -1
drivers/nvdimm/label.c
··· 938 938 } 939 939 940 940 for_each_dpa_resource(ndd, res) 941 - if (strncmp(res->name, "pmem", 3) == 0) 941 + if (strncmp(res->name, "pmem", 4) == 0) 942 942 count++; 943 943 WARN_ON_ONCE(!count); 944 944
+4 -4
drivers/nvdimm/namespace_devs.c
··· 1132 1132 return sprintf(buf, "%llu\n", (unsigned long long) 1133 1133 nvdimm_namespace_capacity(to_ndns(dev))); 1134 1134 } 1135 - static DEVICE_ATTR(size, S_IRUGO, size_show, size_store); 1135 + static DEVICE_ATTR(size, 0444, size_show, size_store); 1136 1136 1137 1137 static u8 *namespace_to_uuid(struct device *dev) 1138 1138 { ··· 1456 1456 1457 1457 if (is_namespace_pmem(dev) || is_namespace_blk(dev)) { 1458 1458 if (a == &dev_attr_size.attr) 1459 - return S_IWUSR | S_IRUGO; 1459 + return 0644; 1460 1460 1461 1461 if (is_namespace_pmem(dev) && a == &dev_attr_sector_size.attr) 1462 1462 return 0; ··· 1653 1653 u64 hw_start, hw_end, pmem_start, pmem_end; 1654 1654 struct nd_label_ent *label_ent; 1655 1655 1656 - WARN_ON(!mutex_is_locked(&nd_mapping->lock)); 1656 + lockdep_assert_held(&nd_mapping->lock); 1657 1657 list_for_each_entry(label_ent, &nd_mapping->labels, list) { 1658 1658 nd_label = label_ent->label; 1659 1659 if (!nd_label) ··· 1997 1997 struct nd_mapping *nd_mapping = &nd_region->mapping[0]; 1998 1998 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 1999 1999 struct nd_namespace_blk *nsblk; 2000 - char *name[NSLABEL_NAME_LEN]; 2000 + char name[NSLABEL_NAME_LEN]; 2001 2001 struct device *dev = NULL; 2002 2002 struct resource *res; 2003 2003
+10 -2
drivers/nvdimm/nd.h
··· 238 238 void *buf, size_t len); 239 239 long nvdimm_clear_poison(struct device *dev, phys_addr_t phys, 240 240 unsigned int len); 241 + void nvdimm_set_aliasing(struct device *dev); 241 242 struct nd_btt *to_nd_btt(struct device *dev); 242 243 243 244 struct nd_gen_sb { ··· 378 377 if (!blk_queue_io_stat(disk->queue)) 379 378 return false; 380 379 381 - __nd_iostat_start(bio, start); 380 + *start = jiffies; 381 + generic_start_io_acct(bio_data_dir(bio), 382 + bio_sectors(bio), &disk->part0); 382 383 return true; 383 384 } 384 - void nd_iostat_end(struct bio *bio, unsigned long start); 385 + static inline void nd_iostat_end(struct bio *bio, unsigned long start) 386 + { 387 + struct gendisk *disk = bio->bi_bdev->bd_disk; 388 + 389 + generic_end_io_acct(bio_data_dir(bio), &disk->part0, start); 390 + } 385 391 static inline bool is_bad_pmem(struct badblocks *bb, sector_t sector, 386 392 unsigned int len) 387 393 {
+1 -1
drivers/nvdimm/pfn_devs.c
··· 108 108 { 109 109 struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); 110 110 111 - return sprintf(buf, "%lx\n", nd_pfn->align); 111 + return sprintf(buf, "%ld\n", nd_pfn->align); 112 112 } 113 113 114 114 static ssize_t __align_store(struct nd_pfn *nd_pfn, const char *buf)
+12 -9
drivers/nvdimm/pmem.c
··· 53 53 struct device *dev = to_dev(pmem); 54 54 sector_t sector; 55 55 long cleared; 56 + int rc = 0; 56 57 57 58 sector = (offset - pmem->data_offset) / 512; 58 - cleared = nvdimm_clear_poison(dev, pmem->phys_addr + offset, len); 59 59 60 + cleared = nvdimm_clear_poison(dev, pmem->phys_addr + offset, len); 61 + if (cleared < len) 62 + rc = -EIO; 60 63 if (cleared > 0 && cleared / 512) { 61 - dev_dbg(dev, "%s: %#llx clear %ld sector%s\n", 62 - __func__, (unsigned long long) sector, 63 - cleared / 512, cleared / 512 > 1 ? "s" : ""); 64 - badblocks_clear(&pmem->bb, sector, cleared / 512); 65 - } else { 66 - return -EIO; 64 + cleared /= 512; 65 + dev_dbg(dev, "%s: %#llx clear %ld sector%s\n", __func__, 66 + (unsigned long long) sector, cleared, 67 + cleared > 1 ? "s" : ""); 68 + badblocks_clear(&pmem->bb, sector, cleared); 67 69 } 68 70 69 71 invalidate_pmem(pmem->virt_addr + offset, len); 70 - return 0; 72 + 73 + return rc; 71 74 } 72 75 73 76 static void write_pmem(void *pmem_addr, struct page *page, ··· 273 270 dev_warn(dev, "unable to guarantee persistence of writes\n"); 274 271 275 272 if (!devm_request_mem_region(dev, res->start, resource_size(res), 276 - dev_name(dev))) { 273 + dev_name(&ndns->dev))) { 277 274 dev_warn(dev, "could not reserve region %pR\n", res); 278 275 return -EBUSY; 279 276 }
+1 -1
drivers/nvdimm/region_devs.c
··· 509 509 { 510 510 struct nd_label_ent *label_ent, *e; 511 511 512 - WARN_ON(!mutex_is_locked(&nd_mapping->lock)); 512 + lockdep_assert_held(&nd_mapping->lock); 513 513 list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) { 514 514 list_del(&label_ent->list); 515 515 kfree(label_ent);
+23 -7
tools/testing/nvdimm/test/nfit.c
··· 125 125 (((node & 0xfff) << 16) | ((socket & 0xf) << 12) \ 126 126 | ((imc & 0xf) << 8) | ((chan & 0xf) << 4) | (dimm & 0xf)) 127 127 128 - static u32 handle[NUM_DCR] = { 128 + static u32 handle[] = { 129 129 [0] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 0), 130 130 [1] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 1), 131 131 [2] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 0), 132 132 [3] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 1), 133 133 [4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0), 134 + [5] = NFIT_DIMM_HANDLE(1, 0, 0, 0, 0), 134 135 }; 135 136 136 137 static unsigned long dimm_fail_cmd_flags[NUM_DCR]; ··· 143 142 void *nfit_buf; 144 143 dma_addr_t nfit_dma; 145 144 size_t nfit_size; 145 + int dcr_idx; 146 146 int num_dcr; 147 147 int num_pm; 148 148 void **dimm; ··· 428 426 break; 429 427 case ND_CMD_GET_CONFIG_DATA: 430 428 rc = nfit_test_cmd_get_config_data(buf, buf_len, 431 - t->label[i]); 429 + t->label[i - t->dcr_idx]); 432 430 break; 433 431 case ND_CMD_SET_CONFIG_DATA: 434 432 rc = nfit_test_cmd_set_config_data(buf, buf_len, 435 - t->label[i]); 433 + t->label[i - t->dcr_idx]); 436 434 break; 437 435 case ND_CMD_SMART: 438 436 rc = nfit_test_cmd_smart(buf, buf_len); ··· 684 682 if (!t->spa_set[2]) 685 683 return -ENOMEM; 686 684 687 - for (i = 0; i < NUM_DCR; i++) { 685 + for (i = 0; i < t->num_dcr; i++) { 688 686 t->dimm[i] = test_alloc(t, DIMM_SIZE, &t->dimm_dma[i]); 689 687 if (!t->dimm[i]) 690 688 return -ENOMEM; ··· 701 699 return -ENOMEM; 702 700 } 703 701 704 - for (i = 0; i < NUM_DCR; i++) { 702 + for (i = 0; i < t->num_dcr; i++) { 705 703 t->dcr[i] = test_alloc(t, LABEL_SIZE, &t->dcr_dma[i]); 706 704 if (!t->dcr[i]) 707 705 return -ENOMEM; ··· 730 728 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * 2 731 729 + sizeof(struct acpi_nfit_memory_map) 732 730 + offsetof(struct acpi_nfit_control_region, window_size); 731 + int i; 733 732 734 733 t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma); 735 734 if (!t->nfit_buf) ··· 740 737 t->spa_set[0] = test_alloc(t, SPA2_SIZE, &t->spa_set_dma[0]); 741 738 if (!t->spa_set[0]) 742 739 return -ENOMEM; 740 + 741 + for (i = 0; i < t->num_dcr; i++) { 742 + t->label[i] = test_alloc(t, LABEL_SIZE, &t->label_dma[i]); 743 + if (!t->label[i]) 744 + return -ENOMEM; 745 + sprintf(t->label[i], "label%d", i); 746 + } 743 747 744 748 t->spa_set[1] = test_alloc(t, SPA_VCD_SIZE, &t->spa_set_dma[1]); 745 749 if (!t->spa_set[1]) ··· 1460 1450 memdev = nfit_buf + offset; 1461 1451 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1462 1452 memdev->header.length = sizeof(*memdev); 1463 - memdev->device_handle = 0; 1453 + memdev->device_handle = handle[5]; 1464 1454 memdev->physical_id = 0; 1465 1455 memdev->region_id = 0; 1466 1456 memdev->range_index = 0+1; ··· 1482 1472 window_size); 1483 1473 dcr->region_index = 0+1; 1484 1474 dcr_common_init(dcr); 1485 - dcr->serial_number = ~0; 1475 + dcr->serial_number = ~handle[5]; 1486 1476 dcr->code = NFIT_FIC_BYTE; 1487 1477 dcr->windows = 0; 1488 1478 ··· 1493 1483 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en); 1494 1484 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en); 1495 1485 set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en); 1486 + set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_cmd_force_en); 1487 + set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en); 1488 + set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en); 1496 1489 } 1497 1490 1498 1491 static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa, ··· 1899 1886 switch (i) { 1900 1887 case 0: 1901 1888 nfit_test->num_pm = NUM_PM; 1889 + nfit_test->dcr_idx = 0; 1902 1890 nfit_test->num_dcr = NUM_DCR; 1903 1891 nfit_test->alloc = nfit_test0_alloc; 1904 1892 nfit_test->setup = nfit_test0_setup; 1905 1893 break; 1906 1894 case 1: 1907 1895 nfit_test->num_pm = 1; 1896 + nfit_test->dcr_idx = NUM_DCR; 1897 + nfit_test->num_dcr = 1; 1908 1898 nfit_test->alloc = nfit_test1_alloc; 1909 1899 nfit_test->setup = nfit_test1_setup; 1910 1900 break;