~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/nvdimm/test/nfit.c

Version: ~ [ linux-5.2-rc1 ] ~ [ linux-5.1.2 ] ~ [ linux-5.0.16 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.43 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.119 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.176 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.179 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.139 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.67 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
  3  *
  4  * This program is free software; you can redistribute it and/or modify
  5  * it under the terms of version 2 of the GNU General Public License as
  6  * published by the Free Software Foundation.
  7  *
  8  * This program is distributed in the hope that it will be useful, but
  9  * WITHOUT ANY WARRANTY; without even the implied warranty of
 10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 11  * General Public License for more details.
 12  */
 13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 14 #include <linux/platform_device.h>
 15 #include <linux/dma-mapping.h>
 16 #include <linux/workqueue.h>
 17 #include <linux/libnvdimm.h>
 18 #include <linux/vmalloc.h>
 19 #include <linux/device.h>
 20 #include <linux/module.h>
 21 #include <linux/mutex.h>
 22 #include <linux/ndctl.h>
 23 #include <linux/sizes.h>
 24 #include <linux/list.h>
 25 #include <linux/slab.h>
 26 #include <nd-core.h>
 27 #include <nfit.h>
 28 #include <nd.h>
 29 #include "nfit_test.h"
 30 
 31 /*
 32  * Generate an NFIT table to describe the following topology:
 33  *
 34  * BUS0: Interleaved PMEM regions, and aliasing with BLK regions
 35  *
 36  *                     (a)                       (b)            DIMM   BLK-REGION
 37  *           +----------+--------------+----------+---------+
 38  * +------+  |  blk2.0  |     pm0.0    |  blk2.1  |  pm1.0  |    0      region2
 39  * | imc0 +--+- - - - - region0 - - - -+----------+         +
 40  * +--+---+  |  blk3.0  |     pm0.0    |  blk3.1  |  pm1.0  |    1      region3
 41  *    |      +----------+--------------v----------v         v
 42  * +--+---+                            |                    |
 43  * | cpu0 |                                    region1
 44  * +--+---+                            |                    |
 45  *    |      +-------------------------^----------^         ^
 46  * +--+---+  |                 blk4.0             |  pm1.0  |    2      region4
 47  * | imc1 +--+-------------------------+----------+         +
 48  * +------+  |                 blk5.0             |  pm1.0  |    3      region5
 49  *           +-------------------------+----------+-+-------+
 50  *
 51  * +--+---+
 52  * | cpu1 |
 53  * +--+---+                   (Hotplug DIMM)
 54  *    |      +----------------------------------------------+
 55  * +--+---+  |                 blk6.0/pm7.0                 |    4      region6/7
 56  * | imc0 +--+----------------------------------------------+
 57  * +------+
 58  *
 59  *
 60  * *) In this layout we have four dimms and two memory controllers in one
 61  *    socket.  Each unique interface (BLK or PMEM) to DPA space
 62  *    is identified by a region device with a dynamically assigned id.
 63  *
 64  * *) The first portion of dimm0 and dimm1 are interleaved as REGION0.
 65  *    A single PMEM namespace "pm0.0" is created using half of the
 66  *    REGION0 SPA-range.  REGION0 spans dimm0 and dimm1.  PMEM namespace
 67  *    allocate from from the bottom of a region.  The unallocated
 68  *    portion of REGION0 aliases with REGION2 and REGION3.  That
 69  *    unallacted capacity is reclaimed as BLK namespaces ("blk2.0" and
 70  *    "blk3.0") starting at the base of each DIMM to offset (a) in those
 71  *    DIMMs.  "pm0.0", "blk2.0" and "blk3.0" are free-form readable
 72  *    names that can be assigned to a namespace.
 73  *
 74  * *) In the last portion of dimm0 and dimm1 we have an interleaved
 75  *    SPA range, REGION1, that spans those two dimms as well as dimm2
 76  *    and dimm3.  Some of REGION1 allocated to a PMEM namespace named
 77  *    "pm1.0" the rest is reclaimed in 4 BLK namespaces (for each
 78  *    dimm in the interleave set), "blk2.1", "blk3.1", "blk4.0", and
 79  *    "blk5.0".
 80  *
 81  * *) The portion of dimm2 and dimm3 that do not participate in the
 82  *    REGION1 interleaved SPA range (i.e. the DPA address below offset
 83  *    (b) are also included in the "blk4.0" and "blk5.0" namespaces.
 84  *    Note, that BLK namespaces need not be contiguous in DPA-space, and
 85  *    can consume aliased capacity from multiple interleave sets.
 86  *
 87  * BUS1: Legacy NVDIMM (single contiguous range)
 88  *
 89  *  region2
 90  * +---------------------+
 91  * |---------------------|
 92  * ||       pm2.0       ||
 93  * |---------------------|
 94  * +---------------------+
 95  *
 96  * *) A NFIT-table may describe a simple system-physical-address range
 97  *    with no BLK aliasing.  This type of region may optionally
 98  *    reference an NVDIMM.
 99  */
100 enum {
101         NUM_PM  = 3,
102         NUM_DCR = 5,
103         NUM_HINTS = 8,
104         NUM_BDW = NUM_DCR,
105         NUM_SPA = NUM_PM + NUM_DCR + NUM_BDW,
106         NUM_MEM = NUM_DCR + NUM_BDW + 2 /* spa0 iset */ + 4 /* spa1 iset */,
107         DIMM_SIZE = SZ_32M,
108         LABEL_SIZE = SZ_128K,
109         SPA_VCD_SIZE = SZ_4M,
110         SPA0_SIZE = DIMM_SIZE,
111         SPA1_SIZE = DIMM_SIZE*2,
112         SPA2_SIZE = DIMM_SIZE,
113         BDW_SIZE = 64 << 8,
114         DCR_SIZE = 12,
115         NUM_NFITS = 2, /* permit testing multiple NFITs per system */
116 };
117 
118 struct nfit_test_dcr {
119         __le64 bdw_addr;
120         __le32 bdw_status;
121         __u8 aperature[BDW_SIZE];
122 };
123 
124 #define NFIT_DIMM_HANDLE(node, socket, imc, chan, dimm) \
125         (((node & 0xfff) << 16) | ((socket & 0xf) << 12) \
126          | ((imc & 0xf) << 8) | ((chan & 0xf) << 4) | (dimm & 0xf))
127 
128 static u32 handle[] = {
129         [0] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 0),
130         [1] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 1),
131         [2] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 0),
132         [3] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 1),
133         [4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0),
134         [5] = NFIT_DIMM_HANDLE(1, 0, 0, 0, 0),
135 };
136 
137 static unsigned long dimm_fail_cmd_flags[NUM_DCR];
138 
139 struct nfit_test {
140         struct acpi_nfit_desc acpi_desc;
141         struct platform_device pdev;
142         struct list_head resources;
143         void *nfit_buf;
144         dma_addr_t nfit_dma;
145         size_t nfit_size;
146         int dcr_idx;
147         int num_dcr;
148         int num_pm;
149         void **dimm;
150         dma_addr_t *dimm_dma;
151         void **flush;
152         dma_addr_t *flush_dma;
153         void **label;
154         dma_addr_t *label_dma;
155         void **spa_set;
156         dma_addr_t *spa_set_dma;
157         struct nfit_test_dcr **dcr;
158         dma_addr_t *dcr_dma;
159         int (*alloc)(struct nfit_test *t);
160         void (*setup)(struct nfit_test *t);
161         int setup_hotplug;
162         union acpi_object **_fit;
163         dma_addr_t _fit_dma;
164         struct ars_state {
165                 struct nd_cmd_ars_status *ars_status;
166                 unsigned long deadline;
167                 spinlock_t lock;
168         } ars_state;
169         struct device *dimm_dev[NUM_DCR];
170 };
171 
172 static struct nfit_test *to_nfit_test(struct device *dev)
173 {
174         struct platform_device *pdev = to_platform_device(dev);
175 
176         return container_of(pdev, struct nfit_test, pdev);
177 }
178 
179 static int nfit_test_cmd_get_config_size(struct nd_cmd_get_config_size *nd_cmd,
180                 unsigned int buf_len)
181 {
182         if (buf_len < sizeof(*nd_cmd))
183                 return -EINVAL;
184 
185         nd_cmd->status = 0;
186         nd_cmd->config_size = LABEL_SIZE;
187         nd_cmd->max_xfer = SZ_4K;
188 
189         return 0;
190 }
191 
192 static int nfit_test_cmd_get_config_data(struct nd_cmd_get_config_data_hdr
193                 *nd_cmd, unsigned int buf_len, void *label)
194 {
195         unsigned int len, offset = nd_cmd->in_offset;
196         int rc;
197 
198         if (buf_len < sizeof(*nd_cmd))
199                 return -EINVAL;
200         if (offset >= LABEL_SIZE)
201                 return -EINVAL;
202         if (nd_cmd->in_length + sizeof(*nd_cmd) > buf_len)
203                 return -EINVAL;
204 
205         nd_cmd->status = 0;
206         len = min(nd_cmd->in_length, LABEL_SIZE - offset);
207         memcpy(nd_cmd->out_buf, label + offset, len);
208         rc = buf_len - sizeof(*nd_cmd) - len;
209 
210         return rc;
211 }
212 
213 static int nfit_test_cmd_set_config_data(struct nd_cmd_set_config_hdr *nd_cmd,
214                 unsigned int buf_len, void *label)
215 {
216         unsigned int len, offset = nd_cmd->in_offset;
217         u32 *status;
218         int rc;
219 
220         if (buf_len < sizeof(*nd_cmd))
221                 return -EINVAL;
222         if (offset >= LABEL_SIZE)
223                 return -EINVAL;
224         if (nd_cmd->in_length + sizeof(*nd_cmd) + 4 > buf_len)
225                 return -EINVAL;
226 
227         status = (void *)nd_cmd + nd_cmd->in_length + sizeof(*nd_cmd);
228         *status = 0;
229         len = min(nd_cmd->in_length, LABEL_SIZE - offset);
230         memcpy(label + offset, nd_cmd->in_buf, len);
231         rc = buf_len - sizeof(*nd_cmd) - (len + 4);
232 
233         return rc;
234 }
235 
236 #define NFIT_TEST_ARS_RECORDS 4
237 #define NFIT_TEST_CLEAR_ERR_UNIT 256
238 
239 static int nfit_test_cmd_ars_cap(struct nd_cmd_ars_cap *nd_cmd,
240                 unsigned int buf_len)
241 {
242         if (buf_len < sizeof(*nd_cmd))
243                 return -EINVAL;
244 
245         nd_cmd->max_ars_out = sizeof(struct nd_cmd_ars_status)
246                 + NFIT_TEST_ARS_RECORDS * sizeof(struct nd_ars_record);
247         nd_cmd->status = (ND_ARS_PERSISTENT | ND_ARS_VOLATILE) << 16;
248         nd_cmd->clear_err_unit = NFIT_TEST_CLEAR_ERR_UNIT;
249 
250         return 0;
251 }
252 
253 /*
254  * Initialize the ars_state to return an ars_result 1 second in the future with
255  * a 4K error range in the middle of the requested address range.
256  */
257 static void post_ars_status(struct ars_state *ars_state, u64 addr, u64 len)
258 {
259         struct nd_cmd_ars_status *ars_status;
260         struct nd_ars_record *ars_record;
261 
262         ars_state->deadline = jiffies + 1*HZ;
263         ars_status = ars_state->ars_status;
264         ars_status->status = 0;
265         ars_status->out_length = sizeof(struct nd_cmd_ars_status)
266                 + sizeof(struct nd_ars_record);
267         ars_status->address = addr;
268         ars_status->length = len;
269         ars_status->type = ND_ARS_PERSISTENT;
270         ars_status->num_records = 1;
271         ars_record = &ars_status->records[0];
272         ars_record->handle = 0;
273         ars_record->err_address = addr + len / 2;
274         ars_record->length = SZ_4K;
275 }
276 
277 static int nfit_test_cmd_ars_start(struct ars_state *ars_state,
278                 struct nd_cmd_ars_start *ars_start, unsigned int buf_len,
279                 int *cmd_rc)
280 {
281         if (buf_len < sizeof(*ars_start))
282                 return -EINVAL;
283 
284         spin_lock(&ars_state->lock);
285         if (time_before(jiffies, ars_state->deadline)) {
286                 ars_start->status = NFIT_ARS_START_BUSY;
287                 *cmd_rc = -EBUSY;
288         } else {
289                 ars_start->status = 0;
290                 ars_start->scrub_time = 1;
291                 post_ars_status(ars_state, ars_start->address,
292                                 ars_start->length);
293                 *cmd_rc = 0;
294         }
295         spin_unlock(&ars_state->lock);
296 
297         return 0;
298 }
299 
300 static int nfit_test_cmd_ars_status(struct ars_state *ars_state,
301                 struct nd_cmd_ars_status *ars_status, unsigned int buf_len,
302                 int *cmd_rc)
303 {
304         if (buf_len < ars_state->ars_status->out_length)
305                 return -EINVAL;
306 
307         spin_lock(&ars_state->lock);
308         if (time_before(jiffies, ars_state->deadline)) {
309                 memset(ars_status, 0, buf_len);
310                 ars_status->status = NFIT_ARS_STATUS_BUSY;
311                 ars_status->out_length = sizeof(*ars_status);
312                 *cmd_rc = -EBUSY;
313         } else {
314                 memcpy(ars_status, ars_state->ars_status,
315                                 ars_state->ars_status->out_length);
316                 *cmd_rc = 0;
317         }
318         spin_unlock(&ars_state->lock);
319         return 0;
320 }
321 
322 static int nfit_test_cmd_clear_error(struct nd_cmd_clear_error *clear_err,
323                 unsigned int buf_len, int *cmd_rc)
324 {
325         const u64 mask = NFIT_TEST_CLEAR_ERR_UNIT - 1;
326         if (buf_len < sizeof(*clear_err))
327                 return -EINVAL;
328 
329         if ((clear_err->address & mask) || (clear_err->length & mask))
330                 return -EINVAL;
331 
332         /*
333          * Report 'all clear' success for all commands even though a new
334          * scrub will find errors again.  This is enough to have the
335          * error removed from the 'badblocks' tracking in the pmem
336          * driver.
337          */
338         clear_err->status = 0;
339         clear_err->cleared = clear_err->length;
340         *cmd_rc = 0;
341         return 0;
342 }
343 
344 static int nfit_test_cmd_smart(struct nd_cmd_smart *smart, unsigned int buf_len)
345 {
346         static const struct nd_smart_payload smart_data = {
347                 .flags = ND_SMART_HEALTH_VALID | ND_SMART_TEMP_VALID
348                         | ND_SMART_SPARES_VALID | ND_SMART_ALARM_VALID
349                         | ND_SMART_USED_VALID | ND_SMART_SHUTDOWN_VALID,
350                 .health = ND_SMART_NON_CRITICAL_HEALTH,
351                 .temperature = 23 * 16,
352                 .spares = 75,
353                 .alarm_flags = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
354                 .life_used = 5,
355                 .shutdown_state = 0,
356                 .vendor_size = 0,
357         };
358 
359         if (buf_len < sizeof(*smart))
360                 return -EINVAL;
361         memcpy(smart->data, &smart_data, sizeof(smart_data));
362         return 0;
363 }
364 
365 static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold *smart_t,
366                 unsigned int buf_len)
367 {
368         static const struct nd_smart_threshold_payload smart_t_data = {
369                 .alarm_control = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
370                 .temperature = 40 * 16,
371                 .spares = 5,
372         };
373 
374         if (buf_len < sizeof(*smart_t))
375                 return -EINVAL;
376         memcpy(smart_t->data, &smart_t_data, sizeof(smart_t_data));
377         return 0;
378 }
379 
380 static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
381                 struct nvdimm *nvdimm, unsigned int cmd, void *buf,
382                 unsigned int buf_len, int *cmd_rc)
383 {
384         struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
385         struct nfit_test *t = container_of(acpi_desc, typeof(*t), acpi_desc);
386         unsigned int func = cmd;
387         int i, rc = 0, __cmd_rc;
388 
389         if (!cmd_rc)
390                 cmd_rc = &__cmd_rc;
391         *cmd_rc = 0;
392 
393         if (nvdimm) {
394                 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
395                 unsigned long cmd_mask = nvdimm_cmd_mask(nvdimm);
396 
397                 if (!nfit_mem)
398                         return -ENOTTY;
399 
400                 if (cmd == ND_CMD_CALL) {
401                         struct nd_cmd_pkg *call_pkg = buf;
402 
403                         buf_len = call_pkg->nd_size_in + call_pkg->nd_size_out;
404                         buf = (void *) call_pkg->nd_payload;
405                         func = call_pkg->nd_command;
406                         if (call_pkg->nd_family != nfit_mem->family)
407                                 return -ENOTTY;
408                 }
409 
410                 if (!test_bit(cmd, &cmd_mask)
411                                 || !test_bit(func, &nfit_mem->dsm_mask))
412                         return -ENOTTY;
413 
414                 /* lookup label space for the given dimm */
415                 for (i = 0; i < ARRAY_SIZE(handle); i++)
416                         if (__to_nfit_memdev(nfit_mem)->device_handle ==
417                                         handle[i])
418                                 break;
419                 if (i >= ARRAY_SIZE(handle))
420                         return -ENXIO;
421 
422                 if ((1 << func) & dimm_fail_cmd_flags[i])
423                         return -EIO;
424 
425                 switch (func) {
426                 case ND_CMD_GET_CONFIG_SIZE:
427                         rc = nfit_test_cmd_get_config_size(buf, buf_len);
428                         break;
429                 case ND_CMD_GET_CONFIG_DATA:
430                         rc = nfit_test_cmd_get_config_data(buf, buf_len,
431                                 t->label[i - t->dcr_idx]);
432                         break;
433                 case ND_CMD_SET_CONFIG_DATA:
434                         rc = nfit_test_cmd_set_config_data(buf, buf_len,
435                                 t->label[i - t->dcr_idx]);
436                         break;
437                 case ND_CMD_SMART:
438                         rc = nfit_test_cmd_smart(buf, buf_len);
439                         break;
440                 case ND_CMD_SMART_THRESHOLD:
441                         rc = nfit_test_cmd_smart_threshold(buf, buf_len);
442                         device_lock(&t->pdev.dev);
443                         __acpi_nvdimm_notify(t->dimm_dev[i], 0x81);
444                         device_unlock(&t->pdev.dev);
445                         break;
446                 default:
447                         return -ENOTTY;
448                 }
449         } else {
450                 struct ars_state *ars_state = &t->ars_state;
451 
452                 if (!nd_desc || !test_bit(cmd, &nd_desc->cmd_mask))
453                         return -ENOTTY;
454 
455                 switch (func) {
456                 case ND_CMD_ARS_CAP:
457                         rc = nfit_test_cmd_ars_cap(buf, buf_len);
458                         break;
459                 case ND_CMD_ARS_START:
460                         rc = nfit_test_cmd_ars_start(ars_state, buf, buf_len,
461                                         cmd_rc);
462                         break;
463                 case ND_CMD_ARS_STATUS:
464                         rc = nfit_test_cmd_ars_status(ars_state, buf, buf_len,
465                                         cmd_rc);
466                         break;
467                 case ND_CMD_CLEAR_ERROR:
468                         rc = nfit_test_cmd_clear_error(buf, buf_len, cmd_rc);
469                         break;
470                 default:
471                         return -ENOTTY;
472                 }
473         }
474 
475         return rc;
476 }
477 
478 static DEFINE_SPINLOCK(nfit_test_lock);
479 static struct nfit_test *instances[NUM_NFITS];
480 
481 static void release_nfit_res(void *data)
482 {
483         struct nfit_test_resource *nfit_res = data;
484 
485         spin_lock(&nfit_test_lock);
486         list_del(&nfit_res->list);
487         spin_unlock(&nfit_test_lock);
488 
489         vfree(nfit_res->buf);
490         kfree(nfit_res);
491 }
492 
493 static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
494                 void *buf)
495 {
496         struct device *dev = &t->pdev.dev;
497         struct nfit_test_resource *nfit_res = kzalloc(sizeof(*nfit_res),
498                         GFP_KERNEL);
499         int rc;
500 
501         if (!buf || !nfit_res)
502                 goto err;
503         rc = devm_add_action(dev, release_nfit_res, nfit_res);
504         if (rc)
505                 goto err;
506         INIT_LIST_HEAD(&nfit_res->list);
507         memset(buf, 0, size);
508         nfit_res->dev = dev;
509         nfit_res->buf = buf;
510         nfit_res->res.start = *dma;
511         nfit_res->res.end = *dma + size - 1;
512         nfit_res->res.name = "NFIT";
513         spin_lock_init(&nfit_res->lock);
514         INIT_LIST_HEAD(&nfit_res->requests);
515         spin_lock(&nfit_test_lock);
516         list_add(&nfit_res->list, &t->resources);
517         spin_unlock(&nfit_test_lock);
518 
519         return nfit_res->buf;
520  err:
521         if (buf)
522                 vfree(buf);
523         kfree(nfit_res);
524         return NULL;
525 }
526 
527 static void *test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma)
528 {
529         void *buf = vmalloc(size);
530 
531         *dma = (unsigned long) buf;
532         return __test_alloc(t, size, dma, buf);
533 }
534 
535 static struct nfit_test_resource *nfit_test_lookup(resource_size_t addr)
536 {
537         int i;
538 
539         for (i = 0; i < ARRAY_SIZE(instances); i++) {
540                 struct nfit_test_resource *n, *nfit_res = NULL;
541                 struct nfit_test *t = instances[i];
542 
543                 if (!t)
544                         continue;
545                 spin_lock(&nfit_test_lock);
546                 list_for_each_entry(n, &t->resources, list) {
547                         if (addr >= n->res.start && (addr < n->res.start
548                                                 + resource_size(&n->res))) {
549                                 nfit_res = n;
550                                 break;
551                         } else if (addr >= (unsigned long) n->buf
552                                         && (addr < (unsigned long) n->buf
553                                                 + resource_size(&n->res))) {
554                                 nfit_res = n;
555                                 break;
556                         }
557                 }
558                 spin_unlock(&nfit_test_lock);
559                 if (nfit_res)
560                         return nfit_res;
561         }
562 
563         return NULL;
564 }
565 
566 static int ars_state_init(struct device *dev, struct ars_state *ars_state)
567 {
568         ars_state->ars_status = devm_kzalloc(dev,
569                         sizeof(struct nd_cmd_ars_status)
570                         + sizeof(struct nd_ars_record) * NFIT_TEST_ARS_RECORDS,
571                         GFP_KERNEL);
572         if (!ars_state->ars_status)
573                 return -ENOMEM;
574         spin_lock_init(&ars_state->lock);
575         return 0;
576 }
577 
578 static void put_dimms(void *data)
579 {
580         struct device **dimm_dev = data;
581         int i;
582 
583         for (i = 0; i < NUM_DCR; i++)
584                 if (dimm_dev[i])
585                         device_unregister(dimm_dev[i]);
586 }
587 
588 static struct class *nfit_test_dimm;
589 
590 static int dimm_name_to_id(struct device *dev)
591 {
592         int dimm;
593 
594         if (sscanf(dev_name(dev), "test_dimm%d", &dimm) != 1
595                         || dimm >= NUM_DCR || dimm < 0)
596                 return -ENXIO;
597         return dimm;
598 }
599 
600 
601 static ssize_t handle_show(struct device *dev, struct device_attribute *attr,
602                 char *buf)
603 {
604         int dimm = dimm_name_to_id(dev);
605 
606         if (dimm < 0)
607                 return dimm;
608 
609         return sprintf(buf, "%#x", handle[dimm]);
610 }
611 DEVICE_ATTR_RO(handle);
612 
613 static ssize_t fail_cmd_show(struct device *dev, struct device_attribute *attr,
614                 char *buf)
615 {
616         int dimm = dimm_name_to_id(dev);
617 
618         if (dimm < 0)
619                 return dimm;
620 
621         return sprintf(buf, "%#lx\n", dimm_fail_cmd_flags[dimm]);
622 }
623 
624 static ssize_t fail_cmd_store(struct device *dev, struct device_attribute *attr,
625                 const char *buf, size_t size)
626 {
627         int dimm = dimm_name_to_id(dev);
628         unsigned long val;
629         ssize_t rc;
630 
631         if (dimm < 0)
632                 return dimm;
633 
634         rc = kstrtol(buf, 0, &val);
635         if (rc)
636                 return rc;
637 
638         dimm_fail_cmd_flags[dimm] = val;
639         return size;
640 }
641 static DEVICE_ATTR_RW(fail_cmd);
642 
643 static struct attribute *nfit_test_dimm_attributes[] = {
644         &dev_attr_fail_cmd.attr,
645         &dev_attr_handle.attr,
646         NULL,
647 };
648 
649 static struct attribute_group nfit_test_dimm_attribute_group = {
650         .attrs = nfit_test_dimm_attributes,
651 };
652 
653 static const struct attribute_group *nfit_test_dimm_attribute_groups[] = {
654         &nfit_test_dimm_attribute_group,
655         NULL,
656 };
657 
658 static int nfit_test0_alloc(struct nfit_test *t)
659 {
660         size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA
661                         + sizeof(struct acpi_nfit_memory_map) * NUM_MEM
662                         + sizeof(struct acpi_nfit_control_region) * NUM_DCR
663                         + offsetof(struct acpi_nfit_control_region,
664                                         window_size) * NUM_DCR
665                         + sizeof(struct acpi_nfit_data_region) * NUM_BDW
666                         + (sizeof(struct acpi_nfit_flush_address)
667                                         + sizeof(u64) * NUM_HINTS) * NUM_DCR;
668         int i;
669 
670         t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma);
671         if (!t->nfit_buf)
672                 return -ENOMEM;
673         t->nfit_size = nfit_size;
674 
675         t->spa_set[0] = test_alloc(t, SPA0_SIZE, &t->spa_set_dma[0]);
676         if (!t->spa_set[0])
677                 return -ENOMEM;
678 
679         t->spa_set[1] = test_alloc(t, SPA1_SIZE, &t->spa_set_dma[1]);
680         if (!t->spa_set[1])
681                 return -ENOMEM;
682 
683         t->spa_set[2] = test_alloc(t, SPA0_SIZE, &t->spa_set_dma[2]);
684         if (!t->spa_set[2])
685                 return -ENOMEM;
686 
687         for (i = 0; i < t->num_dcr; i++) {
688                 t->dimm[i] = test_alloc(t, DIMM_SIZE, &t->dimm_dma[i]);
689                 if (!t->dimm[i])
690                         return -ENOMEM;
691 
692                 t->label[i] = test_alloc(t, LABEL_SIZE, &t->label_dma[i]);
693                 if (!t->label[i])
694                         return -ENOMEM;
695                 sprintf(t->label[i], "label%d", i);
696 
697                 t->flush[i] = test_alloc(t, max(PAGE_SIZE,
698                                         sizeof(u64) * NUM_HINTS),
699                                 &t->flush_dma[i]);
700                 if (!t->flush[i])
701                         return -ENOMEM;
702         }
703 
704         for (i = 0; i < t->num_dcr; i++) {
705                 t->dcr[i] = test_alloc(t, LABEL_SIZE, &t->dcr_dma[i]);
706                 if (!t->dcr[i])
707                         return -ENOMEM;
708         }
709 
710         t->_fit = test_alloc(t, sizeof(union acpi_object **), &t->_fit_dma);
711         if (!t->_fit)
712                 return -ENOMEM;
713 
714         if (devm_add_action_or_reset(&t->pdev.dev, put_dimms, t->dimm_dev))
715                 return -ENOMEM;
716         for (i = 0; i < NUM_DCR; i++) {
717                 t->dimm_dev[i] = device_create_with_groups(nfit_test_dimm,
718                                 &t->pdev.dev, 0, NULL,
719                                 nfit_test_dimm_attribute_groups,
720                                 "test_dimm%d", i);
721                 if (!t->dimm_dev[i])
722                         return -ENOMEM;
723         }
724 
725         return ars_state_init(&t->pdev.dev, &t->ars_state);
726 }
727 
728 static int nfit_test1_alloc(struct nfit_test *t)
729 {
730         size_t nfit_size = sizeof(struct acpi_nfit_system_address) * 2
731                 + sizeof(struct acpi_nfit_memory_map)
732                 + offsetof(struct acpi_nfit_control_region, window_size);
733         int i;
734 
735         t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma);
736         if (!t->nfit_buf)
737                 return -ENOMEM;
738         t->nfit_size = nfit_size;
739 
740         t->spa_set[0] = test_alloc(t, SPA2_SIZE, &t->spa_set_dma[0]);
741         if (!t->spa_set[0])
742                 return -ENOMEM;
743 
744         for (i = 0; i < t->num_dcr; i++) {
745                 t->label[i] = test_alloc(t, LABEL_SIZE, &t->label_dma[i]);
746                 if (!t->label[i])
747                         return -ENOMEM;
748                 sprintf(t->label[i], "label%d", i);
749         }
750 
751         t->spa_set[1] = test_alloc(t, SPA_VCD_SIZE, &t->spa_set_dma[1]);
752         if (!t->spa_set[1])
753                 return -ENOMEM;
754 
755         return ars_state_init(&t->pdev.dev, &t->ars_state);
756 }
757 
758 static void dcr_common_init(struct acpi_nfit_control_region *dcr)
759 {
760         dcr->vendor_id = 0xabcd;
761         dcr->device_id = 0;
762         dcr->revision_id = 1;
763         dcr->valid_fields = 1;
764         dcr->manufacturing_location = 0xa;
765         dcr->manufacturing_date = cpu_to_be16(2016);
766 }
767 
768 static void nfit_test0_setup(struct nfit_test *t)
769 {
770         const int flush_hint_size = sizeof(struct acpi_nfit_flush_address)
771                 + (sizeof(u64) * NUM_HINTS);
772         struct acpi_nfit_desc *acpi_desc;
773         struct acpi_nfit_memory_map *memdev;
774         void *nfit_buf = t->nfit_buf;
775         struct acpi_nfit_system_address *spa;
776         struct acpi_nfit_control_region *dcr;
777         struct acpi_nfit_data_region *bdw;
778         struct acpi_nfit_flush_address *flush;
779         unsigned int offset, i;
780 
781         /*
782          * spa0 (interleave first half of dimm0 and dimm1, note storage
783          * does not actually alias the related block-data-window
784          * regions)
785          */
786         spa = nfit_buf;
787         spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
788         spa->header.length = sizeof(*spa);
789         memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
790         spa->range_index = 0+1;
791         spa->address = t->spa_set_dma[0];
792         spa->length = SPA0_SIZE;
793 
794         /*
795          * spa1 (interleave last half of the 4 DIMMS, note storage
796          * does not actually alias the related block-data-window
797          * regions)
798          */
799         spa = nfit_buf + sizeof(*spa);
800         spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
801         spa->header.length = sizeof(*spa);
802         memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
803         spa->range_index = 1+1;
804         spa->address = t->spa_set_dma[1];
805         spa->length = SPA1_SIZE;
806 
807         /* spa2 (dcr0) dimm0 */
808         spa = nfit_buf + sizeof(*spa) * 2;
809         spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
810         spa->header.length = sizeof(*spa);
811         memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
812         spa->range_index = 2+1;
813         spa->address = t->dcr_dma[0];
814         spa->length = DCR_SIZE;
815 
816         /* spa3 (dcr1) dimm1 */
817         spa = nfit_buf + sizeof(*spa) * 3;
818         spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
819         spa->header.length = sizeof(*spa);
820         memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
821         spa->range_index = 3+1;
822         spa->address = t->dcr_dma[1];
823         spa->length = DCR_SIZE;
824 
825         /* spa4 (dcr2) dimm2 */
826         spa = nfit_buf + sizeof(*spa) * 4;
827         spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
828         spa->header.length = sizeof(*spa);
829         memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
830         spa->range_index = 4+1;
831         spa->address = t->dcr_dma[2];
832         spa->length = DCR_SIZE;
833 
834         /* spa5 (dcr3) dimm3 */
835         spa = nfit_buf + sizeof(*spa) * 5;
836         spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
837         spa->header.length = sizeof(*spa);
838         memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
839         spa->range_index = 5+1;
840         spa->address = t->dcr_dma[3];
841         spa->length = DCR_SIZE;
842 
843         /* spa6 (bdw for dcr0) dimm0 */
844         spa = nfit_buf + sizeof(*spa) * 6;
845         spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
846         spa->header.length = sizeof(*spa);
847         memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
848         spa->range_index = 6+1;
849         spa->address = t->dimm_dma[0];
850         spa->length = DIMM_SIZE;
851 
852         /* spa7 (bdw for dcr1) dimm1 */
853         spa = nfit_buf + sizeof(*spa) * 7;
854         spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
855         spa->header.length = sizeof(*spa);
856         memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
857         spa->range_index = 7+1;
858         spa->address = t->dimm_dma[1];
859         spa->length = DIMM_SIZE;
860 
861         /* spa8 (bdw for dcr2) dimm2 */
862         spa = nfit_buf + sizeof(*spa) * 8;
863         spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
864         spa->header.length = sizeof(*spa);
865         memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
866         spa->range_index = 8+1;
867         spa->address = t->dimm_dma[2];
868         spa->length = DIMM_SIZE;
869 
870         /* spa9 (bdw for dcr3) dimm3 */
871         spa = nfit_buf + sizeof(*spa) * 9;
872         spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
873         spa->header.length = sizeof(*spa);
874         memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
875         spa->range_index = 9+1;
876         spa->address = t->dimm_dma[3];
877         spa->length = DIMM_SIZE;
878 
879         offset = sizeof(*spa) * 10;
880         /* mem-region0 (spa0, dimm0) */
881         memdev = nfit_buf + offset;
882         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
883         memdev->header.length = sizeof(*memdev);
884         memdev->device_handle = handle[0];
885         memdev->physical_id = 0;
886         memdev->region_id = 0;
887         memdev->range_index = 0+1;
888         memdev->region_index = 4+1;
889         memdev->region_size = SPA0_SIZE/2;
890         memdev->region_offset = t->spa_set_dma[0];
891         memdev->address = 0;
892         memdev->interleave_index = 0;
893         memdev->interleave_ways = 2;
894 
895         /* mem-region1 (spa0, dimm1) */
896         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map);
897         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
898         memdev->header.length = sizeof(*memdev);
899         memdev->device_handle = handle[1];
900         memdev->physical_id = 1;
901         memdev->region_id = 0;
902         memdev->range_index = 0+1;
903         memdev->region_index = 5+1;
904         memdev->region_size = SPA0_SIZE/2;
905         memdev->region_offset = t->spa_set_dma[0] + SPA0_SIZE/2;
906         memdev->address = 0;
907         memdev->interleave_index = 0;
908         memdev->interleave_ways = 2;
909 
910         /* mem-region2 (spa1, dimm0) */
911         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 2;
912         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
913         memdev->header.length = sizeof(*memdev);
914         memdev->device_handle = handle[0];
915         memdev->physical_id = 0;
916         memdev->region_id = 1;
917         memdev->range_index = 1+1;
918         memdev->region_index = 4+1;
919         memdev->region_size = SPA1_SIZE/4;
920         memdev->region_offset = t->spa_set_dma[1];
921         memdev->address = SPA0_SIZE/2;
922         memdev->interleave_index = 0;
923         memdev->interleave_ways = 4;
924 
925         /* mem-region3 (spa1, dimm1) */
926         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 3;
927         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
928         memdev->header.length = sizeof(*memdev);
929         memdev->device_handle = handle[1];
930         memdev->physical_id = 1;
931         memdev->region_id = 1;
932         memdev->range_index = 1+1;
933         memdev->region_index = 5+1;
934         memdev->region_size = SPA1_SIZE/4;
935         memdev->region_offset = t->spa_set_dma[1] + SPA1_SIZE/4;
936         memdev->address = SPA0_SIZE/2;
937         memdev->interleave_index = 0;
938         memdev->interleave_ways = 4;
939 
940         /* mem-region4 (spa1, dimm2) */
941         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 4;
942         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
943         memdev->header.length = sizeof(*memdev);
944         memdev->device_handle = handle[2];
945         memdev->physical_id = 2;
946         memdev->region_id = 0;
947         memdev->range_index = 1+1;
948         memdev->region_index = 6+1;
949         memdev->region_size = SPA1_SIZE/4;
950         memdev->region_offset = t->spa_set_dma[1] + 2*SPA1_SIZE/4;
951         memdev->address = SPA0_SIZE/2;
952         memdev->interleave_index = 0;
953         memdev->interleave_ways = 4;
954 
955         /* mem-region5 (spa1, dimm3) */
956         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 5;
957         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
958         memdev->header.length = sizeof(*memdev);
959         memdev->device_handle = handle[3];
960         memdev->physical_id = 3;
961         memdev->region_id = 0;
962         memdev->range_index = 1+1;
963         memdev->region_index = 7+1;
964         memdev->region_size = SPA1_SIZE/4;
965         memdev->region_offset = t->spa_set_dma[1] + 3*SPA1_SIZE/4;
966         memdev->address = SPA0_SIZE/2;
967         memdev->interleave_index = 0;
968         memdev->interleave_ways = 4;
969 
970         /* mem-region6 (spa/dcr0, dimm0) */
971         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 6;
972         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
973         memdev->header.length = sizeof(*memdev);
974         memdev->device_handle = handle[0];
975         memdev->physical_id = 0;
976         memdev->region_id = 0;
977         memdev->range_index = 2+1;
978         memdev->region_index = 0+1;
979         memdev->region_size = 0;
980         memdev->region_offset = 0;
981         memdev->address = 0;
982         memdev->interleave_index = 0;
983         memdev->interleave_ways = 1;
984 
985         /* mem-region7 (spa/dcr1, dimm1) */
986         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 7;
987         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
988         memdev->header.length = sizeof(*memdev);
989         memdev->device_handle = handle[1];
990         memdev->physical_id = 1;
991         memdev->region_id = 0;
992         memdev->range_index = 3+1;
993         memdev->region_index = 1+1;
994         memdev->region_size = 0;
995         memdev->region_offset = 0;
996         memdev->address = 0;
997         memdev->interleave_index = 0;
998         memdev->interleave_ways = 1;
999 
1000         /* mem-region8 (spa/dcr2, dimm2) */
1001         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 8;
1002         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1003         memdev->header.length = sizeof(*memdev);
1004         memdev->device_handle = handle[2];
1005         memdev->physical_id = 2;
1006         memdev->region_id = 0;
1007         memdev->range_index = 4+1;
1008         memdev->region_index = 2+1;
1009         memdev->region_size = 0;
1010         memdev->region_offset = 0;
1011         memdev->address = 0;
1012         memdev->interleave_index = 0;
1013         memdev->interleave_ways = 1;
1014 
1015         /* mem-region9 (spa/dcr3, dimm3) */
1016         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 9;
1017         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1018         memdev->header.length = sizeof(*memdev);
1019         memdev->device_handle = handle[3];
1020         memdev->physical_id = 3;
1021         memdev->region_id = 0;
1022         memdev->range_index = 5+1;
1023         memdev->region_index = 3+1;
1024         memdev->region_size = 0;
1025         memdev->region_offset = 0;
1026         memdev->address = 0;
1027         memdev->interleave_index = 0;
1028         memdev->interleave_ways = 1;
1029 
1030         /* mem-region10 (spa/bdw0, dimm0) */
1031         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 10;
1032         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1033         memdev->header.length = sizeof(*memdev);
1034         memdev->device_handle = handle[0];
1035         memdev->physical_id = 0;
1036         memdev->region_id = 0;
1037         memdev->range_index = 6+1;
1038         memdev->region_index = 0+1;
1039         memdev->region_size = 0;
1040         memdev->region_offset = 0;
1041         memdev->address = 0;
1042         memdev->interleave_index = 0;
1043         memdev->interleave_ways = 1;
1044 
1045         /* mem-region11 (spa/bdw1, dimm1) */
1046         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 11;
1047         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1048         memdev->header.length = sizeof(*memdev);
1049         memdev->device_handle = handle[1];
1050         memdev->physical_id = 1;
1051         memdev->region_id = 0;
1052         memdev->range_index = 7+1;
1053         memdev->region_index = 1+1;
1054         memdev->region_size = 0;
1055         memdev->region_offset = 0;
1056         memdev->address = 0;
1057         memdev->interleave_index = 0;
1058         memdev->interleave_ways = 1;
1059 
1060         /* mem-region12 (spa/bdw2, dimm2) */
1061         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 12;
1062         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1063         memdev->header.length = sizeof(*memdev);
1064         memdev->device_handle = handle[2];
1065         memdev->physical_id = 2;
1066         memdev->region_id = 0;
1067         memdev->range_index = 8+1;
1068         memdev->region_index = 2+1;
1069         memdev->region_size = 0;
1070         memdev->region_offset = 0;
1071         memdev->address = 0;
1072         memdev->interleave_index = 0;
1073         memdev->interleave_ways = 1;
1074 
1075         /* mem-region13 (spa/dcr3, dimm3) */
1076         memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 13;
1077         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1078         memdev->header.length = sizeof(*memdev);
1079         memdev->device_handle = handle[3];
1080         memdev->physical_id = 3;
1081         memdev->region_id = 0;
1082         memdev->range_index = 9+1;
1083         memdev->region_index = 3+1;
1084         memdev->region_size = 0;
1085         memdev->region_offset = 0;
1086         memdev->address = 0;
1087         memdev->interleave_index = 0;
1088         memdev->interleave_ways = 1;
1089 
1090         offset = offset + sizeof(struct acpi_nfit_memory_map) * 14;
1091         /* dcr-descriptor0: blk */
1092         dcr = nfit_buf + offset;
1093         dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1094         dcr->header.length = sizeof(struct acpi_nfit_control_region);
1095         dcr->region_index = 0+1;
1096         dcr_common_init(dcr);
1097         dcr->serial_number = ~handle[0];
1098         dcr->code = NFIT_FIC_BLK;
1099         dcr->windows = 1;
1100         dcr->window_size = DCR_SIZE;
1101         dcr->command_offset = 0;
1102         dcr->command_size = 8;
1103         dcr->status_offset = 8;
1104         dcr->status_size = 4;
1105 
1106         /* dcr-descriptor1: blk */
1107         dcr = nfit_buf + offset + sizeof(struct acpi_nfit_control_region);
1108         dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1109         dcr->header.length = sizeof(struct acpi_nfit_control_region);
1110         dcr->region_index = 1+1;
1111         dcr_common_init(dcr);
1112         dcr->serial_number = ~handle[1];
1113         dcr->code = NFIT_FIC_BLK;
1114         dcr->windows = 1;
1115         dcr->window_size = DCR_SIZE;
1116         dcr->command_offset = 0;
1117         dcr->command_size = 8;
1118         dcr->status_offset = 8;
1119         dcr->status_size = 4;
1120 
1121         /* dcr-descriptor2: blk */
1122         dcr = nfit_buf + offset + sizeof(struct acpi_nfit_control_region) * 2;
1123         dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1124         dcr->header.length = sizeof(struct acpi_nfit_control_region);
1125         dcr->region_index = 2+1;
1126         dcr_common_init(dcr);
1127         dcr->serial_number = ~handle[2];
1128         dcr->code = NFIT_FIC_BLK;
1129         dcr->windows = 1;
1130         dcr->window_size = DCR_SIZE;
1131         dcr->command_offset = 0;
1132         dcr->command_size = 8;
1133         dcr->status_offset = 8;
1134         dcr->status_size = 4;
1135 
1136         /* dcr-descriptor3: blk */
1137         dcr = nfit_buf + offset + sizeof(struct acpi_nfit_control_region) * 3;
1138         dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1139         dcr->header.length = sizeof(struct acpi_nfit_control_region);
1140         dcr->region_index = 3+1;
1141         dcr_common_init(dcr);
1142         dcr->serial_number = ~handle[3];
1143         dcr->code = NFIT_FIC_BLK;
1144         dcr->windows = 1;
1145         dcr->window_size = DCR_SIZE;
1146         dcr->command_offset = 0;
1147         dcr->command_size = 8;
1148         dcr->status_offset = 8;
1149         dcr->status_size = 4;
1150 
1151         offset = offset + sizeof(struct acpi_nfit_control_region) * 4;
1152         /* dcr-descriptor0: pmem */
1153         dcr = nfit_buf + offset;
1154         dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1155         dcr->header.length = offsetof(struct acpi_nfit_control_region,
1156                         window_size);
1157         dcr->region_index = 4+1;
1158         dcr_common_init(dcr);
1159         dcr->serial_number = ~handle[0];
1160         dcr->code = NFIT_FIC_BYTEN;
1161         dcr->windows = 0;
1162 
1163         /* dcr-descriptor1: pmem */
1164         dcr = nfit_buf + offset + offsetof(struct acpi_nfit_control_region,
1165                         window_size);
1166         dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1167         dcr->header.length = offsetof(struct acpi_nfit_control_region,
1168                         window_size);
1169         dcr->region_index = 5+1;
1170         dcr_common_init(dcr);
1171         dcr->serial_number = ~handle[1];
1172         dcr->code = NFIT_FIC_BYTEN;
1173         dcr->windows = 0;
1174 
1175         /* dcr-descriptor2: pmem */
1176         dcr = nfit_buf + offset + offsetof(struct acpi_nfit_control_region,
1177                         window_size) * 2;
1178         dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1179         dcr->header.length = offsetof(struct acpi_nfit_control_region,
1180                         window_size);
1181         dcr->region_index = 6+1;
1182         dcr_common_init(dcr);
1183         dcr->serial_number = ~handle[2];
1184         dcr->code = NFIT_FIC_BYTEN;
1185         dcr->windows = 0;
1186 
1187         /* dcr-descriptor3: pmem */
1188         dcr = nfit_buf + offset + offsetof(struct acpi_nfit_control_region,
1189                         window_size) * 3;
1190         dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1191         dcr->header.length = offsetof(struct acpi_nfit_control_region,
1192                         window_size);
1193         dcr->region_index = 7+1;
1194         dcr_common_init(dcr);
1195         dcr->serial_number = ~handle[3];
1196         dcr->code = NFIT_FIC_BYTEN;
1197         dcr->windows = 0;
1198 
1199         offset = offset + offsetof(struct acpi_nfit_control_region,
1200                         window_size) * 4;
1201         /* bdw0 (spa/dcr0, dimm0) */
1202         bdw = nfit_buf + offset;
1203         bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1204         bdw->header.length = sizeof(struct acpi_nfit_data_region);
1205         bdw->region_index = 0+1;
1206         bdw->windows = 1;
1207         bdw->offset = 0;
1208         bdw->size = BDW_SIZE;
1209         bdw->capacity = DIMM_SIZE;
1210         bdw->start_address = 0;
1211 
1212         /* bdw1 (spa/dcr1, dimm1) */
1213         bdw = nfit_buf + offset + sizeof(struct acpi_nfit_data_region);
1214         bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1215         bdw->header.length = sizeof(struct acpi_nfit_data_region);
1216         bdw->region_index = 1+1;
1217         bdw->windows = 1;
1218         bdw->offset = 0;
1219         bdw->size = BDW_SIZE;
1220         bdw->capacity = DIMM_SIZE;
1221         bdw->start_address = 0;
1222 
1223         /* bdw2 (spa/dcr2, dimm2) */
1224         bdw = nfit_buf + offset + sizeof(struct acpi_nfit_data_region) * 2;
1225         bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1226         bdw->header.length = sizeof(struct acpi_nfit_data_region);
1227         bdw->region_index = 2+1;
1228         bdw->windows = 1;
1229         bdw->offset = 0;
1230         bdw->size = BDW_SIZE;
1231         bdw->capacity = DIMM_SIZE;
1232         bdw->start_address = 0;
1233 
1234         /* bdw3 (spa/dcr3, dimm3) */
1235         bdw = nfit_buf + offset + sizeof(struct acpi_nfit_data_region) * 3;
1236         bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1237         bdw->header.length = sizeof(struct acpi_nfit_data_region);
1238         bdw->region_index = 3+1;
1239         bdw->windows = 1;
1240         bdw->offset = 0;
1241         bdw->size = BDW_SIZE;
1242         bdw->capacity = DIMM_SIZE;
1243         bdw->start_address = 0;
1244 
1245         offset = offset + sizeof(struct acpi_nfit_data_region) * 4;
1246         /* flush0 (dimm0) */
1247         flush = nfit_buf + offset;
1248         flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1249         flush->header.length = flush_hint_size;
1250         flush->device_handle = handle[0];
1251         flush->hint_count = NUM_HINTS;
1252         for (i = 0; i < NUM_HINTS; i++)
1253                 flush->hint_address[i] = t->flush_dma[0] + i * sizeof(u64);
1254 
1255         /* flush1 (dimm1) */
1256         flush = nfit_buf + offset + flush_hint_size * 1;
1257         flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1258         flush->header.length = flush_hint_size;
1259         flush->device_handle = handle[1];
1260         flush->hint_count = NUM_HINTS;
1261         for (i = 0; i < NUM_HINTS; i++)
1262                 flush->hint_address[i] = t->flush_dma[1] + i * sizeof(u64);
1263 
1264         /* flush2 (dimm2) */
1265         flush = nfit_buf + offset + flush_hint_size  * 2;
1266         flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1267         flush->header.length = flush_hint_size;
1268         flush->device_handle = handle[2];
1269         flush->hint_count = NUM_HINTS;
1270         for (i = 0; i < NUM_HINTS; i++)
1271                 flush->hint_address[i] = t->flush_dma[2] + i * sizeof(u64);
1272 
1273         /* flush3 (dimm3) */
1274         flush = nfit_buf + offset + flush_hint_size * 3;
1275         flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1276         flush->header.length = flush_hint_size;
1277         flush->device_handle = handle[3];
1278         flush->hint_count = NUM_HINTS;
1279         for (i = 0; i < NUM_HINTS; i++)
1280                 flush->hint_address[i] = t->flush_dma[3] + i * sizeof(u64);
1281 
1282         if (t->setup_hotplug) {
1283                 offset = offset + flush_hint_size * 4;
1284                 /* dcr-descriptor4: blk */
1285                 dcr = nfit_buf + offset;
1286                 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1287                 dcr->header.length = sizeof(struct acpi_nfit_control_region);
1288                 dcr->region_index = 8+1;
1289                 dcr_common_init(dcr);
1290                 dcr->serial_number = ~handle[4];
1291                 dcr->code = NFIT_FIC_BLK;
1292                 dcr->windows = 1;
1293                 dcr->window_size = DCR_SIZE;
1294                 dcr->command_offset = 0;
1295                 dcr->command_size = 8;
1296                 dcr->status_offset = 8;
1297                 dcr->status_size = 4;
1298 
1299                 offset = offset + sizeof(struct acpi_nfit_control_region);
1300                 /* dcr-descriptor4: pmem */
1301                 dcr = nfit_buf + offset;
1302                 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1303                 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1304                                 window_size);
1305                 dcr->region_index = 9+1;
1306                 dcr_common_init(dcr);
1307                 dcr->serial_number = ~handle[4];
1308                 dcr->code = NFIT_FIC_BYTEN;
1309                 dcr->windows = 0;
1310 
1311                 offset = offset + offsetof(struct acpi_nfit_control_region,
1312                                 window_size);
1313                 /* bdw4 (spa/dcr4, dimm4) */
1314                 bdw = nfit_buf + offset;
1315                 bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1316                 bdw->header.length = sizeof(struct acpi_nfit_data_region);
1317                 bdw->region_index = 8+1;
1318                 bdw->windows = 1;
1319                 bdw->offset = 0;
1320                 bdw->size = BDW_SIZE;
1321                 bdw->capacity = DIMM_SIZE;
1322                 bdw->start_address = 0;
1323 
1324                 offset = offset + sizeof(struct acpi_nfit_data_region);
1325                 /* spa10 (dcr4) dimm4 */
1326                 spa = nfit_buf + offset;
1327                 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1328                 spa->header.length = sizeof(*spa);
1329                 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
1330                 spa->range_index = 10+1;
1331                 spa->address = t->dcr_dma[4];
1332                 spa->length = DCR_SIZE;
1333 
1334                 /*
1335                  * spa11 (single-dimm interleave for hotplug, note storage
1336                  * does not actually alias the related block-data-window
1337                  * regions)
1338                  */
1339                 spa = nfit_buf + offset + sizeof(*spa);
1340                 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1341                 spa->header.length = sizeof(*spa);
1342                 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
1343                 spa->range_index = 11+1;
1344                 spa->address = t->spa_set_dma[2];
1345                 spa->length = SPA0_SIZE;
1346 
1347                 /* spa12 (bdw for dcr4) dimm4 */
1348                 spa = nfit_buf + offset + sizeof(*spa) * 2;
1349                 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1350                 spa->header.length = sizeof(*spa);
1351                 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
1352                 spa->range_index = 12+1;
1353                 spa->address = t->dimm_dma[4];
1354                 spa->length = DIMM_SIZE;
1355 
1356                 offset = offset + sizeof(*spa) * 3;
1357                 /* mem-region14 (spa/dcr4, dimm4) */
1358                 memdev = nfit_buf + offset;
1359                 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1360                 memdev->header.length = sizeof(*memdev);
1361                 memdev->device_handle = handle[4];
1362                 memdev->physical_id = 4;
1363                 memdev->region_id = 0;
1364                 memdev->range_index = 10+1;
1365                 memdev->region_index = 8+1;
1366                 memdev->region_size = 0;
1367                 memdev->region_offset = 0;
1368                 memdev->address = 0;
1369                 memdev->interleave_index = 0;
1370                 memdev->interleave_ways = 1;
1371 
1372                 /* mem-region15 (spa0, dimm4) */
1373                 memdev = nfit_buf + offset +
1374                                 sizeof(struct acpi_nfit_memory_map);
1375                 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1376                 memdev->header.length = sizeof(*memdev);
1377                 memdev->device_handle = handle[4];
1378                 memdev->physical_id = 4;
1379                 memdev->region_id = 0;
1380                 memdev->range_index = 11+1;
1381                 memdev->region_index = 9+1;
1382                 memdev->region_size = SPA0_SIZE;
1383                 memdev->region_offset = t->spa_set_dma[2];
1384                 memdev->address = 0;
1385                 memdev->interleave_index = 0;
1386                 memdev->interleave_ways = 1;
1387 
1388                 /* mem-region16 (spa/bdw4, dimm4) */
1389                 memdev = nfit_buf + offset +
1390                                 sizeof(struct acpi_nfit_memory_map) * 2;
1391                 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1392                 memdev->header.length = sizeof(*memdev);
1393                 memdev->device_handle = handle[4];
1394                 memdev->physical_id = 4;
1395                 memdev->region_id = 0;
1396                 memdev->range_index = 12+1;
1397                 memdev->region_index = 8+1;
1398                 memdev->region_size = 0;
1399                 memdev->region_offset = 0;
1400                 memdev->address = 0;
1401                 memdev->interleave_index = 0;
1402                 memdev->interleave_ways = 1;
1403 
1404                 offset = offset + sizeof(struct acpi_nfit_memory_map) * 3;
1405                 /* flush3 (dimm4) */
1406                 flush = nfit_buf + offset;
1407                 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1408                 flush->header.length = flush_hint_size;
1409                 flush->device_handle = handle[4];
1410                 flush->hint_count = NUM_HINTS;
1411                 for (i = 0; i < NUM_HINTS; i++)
1412                         flush->hint_address[i] = t->flush_dma[4]
1413                                 + i * sizeof(u64);
1414         }
1415 
1416         post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA0_SIZE);
1417 
1418         acpi_desc = &t->acpi_desc;
1419         set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_cmd_force_en);
1420         set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
1421         set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
1422         set_bit(ND_CMD_SMART, &acpi_desc->dimm_cmd_force_en);
1423         set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_cmd_force_en);
1424         set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en);
1425         set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
1426         set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
1427         set_bit(ND_CMD_SMART_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
1428 }
1429 
1430 static void nfit_test1_setup(struct nfit_test *t)
1431 {
1432         size_t offset;
1433         void *nfit_buf = t->nfit_buf;
1434         struct acpi_nfit_memory_map *memdev;
1435         struct acpi_nfit_control_region *dcr;
1436         struct acpi_nfit_system_address *spa;
1437         struct acpi_nfit_desc *acpi_desc;
1438 
1439         offset = 0;
1440         /* spa0 (flat range with no bdw aliasing) */
1441         spa = nfit_buf + offset;
1442         spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1443         spa->header.length = sizeof(*spa);
1444         memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
1445         spa->range_index = 0+1;
1446         spa->address = t->spa_set_dma[0];
1447         spa->length = SPA2_SIZE;
1448 
1449         /* virtual cd region */
1450         spa = nfit_buf + sizeof(*spa);
1451         spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1452         spa->header.length = sizeof(*spa);
1453         memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_VCD), 16);
1454         spa->range_index = 0;
1455         spa->address = t->spa_set_dma[1];
1456         spa->length = SPA_VCD_SIZE;
1457 
1458         offset += sizeof(*spa) * 2;
1459         /* mem-region0 (spa0, dimm0) */
1460         memdev = nfit_buf + offset;
1461         memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1462         memdev->header.length = sizeof(*memdev);
1463         memdev->device_handle = handle[5];
1464         memdev->physical_id = 0;
1465         memdev->region_id = 0;
1466         memdev->range_index = 0+1;
1467         memdev->region_index = 0+1;
1468         memdev->region_size = SPA2_SIZE;
1469         memdev->region_offset = 0;
1470         memdev->address = 0;
1471         memdev->interleave_index = 0;
1472         memdev->interleave_ways = 1;
1473         memdev->flags = ACPI_NFIT_MEM_SAVE_FAILED | ACPI_NFIT_MEM_RESTORE_FAILED
1474                 | ACPI_NFIT_MEM_FLUSH_FAILED | ACPI_NFIT_MEM_HEALTH_OBSERVED
1475                 | ACPI_NFIT_MEM_NOT_ARMED;
1476 
1477         offset += sizeof(*memdev);
1478         /* dcr-descriptor0 */
1479         dcr = nfit_buf + offset;
1480         dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1481         dcr->header.length = offsetof(struct acpi_nfit_control_region,
1482                         window_size);
1483         dcr->region_index = 0+1;
1484         dcr_common_init(dcr);
1485         dcr->serial_number = ~handle[5];
1486         dcr->code = NFIT_FIC_BYTE;
1487         dcr->windows = 0;
1488 
1489         post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA2_SIZE);
1490 
1491         acpi_desc = &t->acpi_desc;
1492         set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_cmd_force_en);
1493         set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en);
1494         set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
1495         set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
1496         set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_cmd_force_en);
1497         set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
1498         set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
1499 }
1500 
1501 static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,
1502                 void *iobuf, u64 len, int rw)
1503 {
1504         struct nfit_blk *nfit_blk = ndbr->blk_provider_data;
1505         struct nfit_blk_mmio *mmio = &nfit_blk->mmio[BDW];
1506         struct nd_region *nd_region = &ndbr->nd_region;
1507         unsigned int lane;
1508 
1509         lane = nd_region_acquire_lane(nd_region);
1510         if (rw)
1511                 memcpy(mmio->addr.base + dpa, iobuf, len);
1512         else {
1513                 memcpy(iobuf, mmio->addr.base + dpa, len);
1514 
1515                 /* give us some some coverage of the mmio_flush_range() API */
1516                 mmio_flush_range(mmio->addr.base + dpa, len);
1517         }
1518         nd_region_release_lane(nd_region, lane);
1519 
1520         return 0;
1521 }
1522 
1523 static unsigned long nfit_ctl_handle;
1524 
1525 union acpi_object *result;
1526 
1527 static union acpi_object *nfit_test_evaluate_dsm(acpi_handle handle,
1528                 const u8 *uuid, u64 rev, u64 func, union acpi_object *argv4)
1529 {
1530         if (handle != &nfit_ctl_handle)
1531                 return ERR_PTR(-ENXIO);
1532 
1533         return result;
1534 }
1535 
1536 static int setup_result(void *buf, size_t size)
1537 {
1538         result = kmalloc(sizeof(union acpi_object) + size, GFP_KERNEL);
1539         if (!result)
1540                 return -ENOMEM;
1541         result->package.type = ACPI_TYPE_BUFFER,
1542         result->buffer.pointer = (void *) (result + 1);
1543         result->buffer.length = size;
1544         memcpy(result->buffer.pointer, buf, size);
1545         memset(buf, 0, size);
1546         return 0;
1547 }
1548 
1549 static int nfit_ctl_test(struct device *dev)
1550 {
1551         int rc, cmd_rc;
1552         struct nvdimm *nvdimm;
1553         struct acpi_device *adev;
1554         struct nfit_mem *nfit_mem;
1555         struct nd_ars_record *record;
1556         struct acpi_nfit_desc *acpi_desc;
1557         const u64 test_val = 0x0123456789abcdefULL;
1558         unsigned long mask, cmd_size, offset;
1559         union {
1560                 struct nd_cmd_get_config_size cfg_size;
1561                 struct nd_cmd_ars_status ars_stat;
1562                 struct nd_cmd_ars_cap ars_cap;
1563                 char buf[sizeof(struct nd_cmd_ars_status)
1564                         + sizeof(struct nd_ars_record)];
1565         } cmds;
1566 
1567         adev = devm_kzalloc(dev, sizeof(*adev), GFP_KERNEL);
1568         if (!adev)
1569                 return -ENOMEM;
1570         *adev = (struct acpi_device) {
1571                 .handle = &nfit_ctl_handle,
1572                 .dev = {
1573                         .init_name = "test-adev",
1574                 },
1575         };
1576 
1577         acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
1578         if (!acpi_desc)
1579                 return -ENOMEM;
1580         *acpi_desc = (struct acpi_nfit_desc) {
1581                 .nd_desc = {
1582                         .cmd_mask = 1UL << ND_CMD_ARS_CAP
1583                                 | 1UL << ND_CMD_ARS_START
1584                                 | 1UL << ND_CMD_ARS_STATUS
1585                                 | 1UL << ND_CMD_CLEAR_ERROR,
1586                         .module = THIS_MODULE,
1587                         .provider_name = "ACPI.NFIT",
1588                         .ndctl = acpi_nfit_ctl,
1589                 },
1590                 .dev = &adev->dev,
1591         };
1592 
1593         nfit_mem = devm_kzalloc(dev, sizeof(*nfit_mem), GFP_KERNEL);
1594         if (!nfit_mem)
1595                 return -ENOMEM;
1596 
1597         mask = 1UL << ND_CMD_SMART | 1UL << ND_CMD_SMART_THRESHOLD
1598                 | 1UL << ND_CMD_DIMM_FLAGS | 1UL << ND_CMD_GET_CONFIG_SIZE
1599                 | 1UL << ND_CMD_GET_CONFIG_DATA | 1UL << ND_CMD_SET_CONFIG_DATA
1600                 | 1UL << ND_CMD_VENDOR;
1601         *nfit_mem = (struct nfit_mem) {
1602                 .adev = adev,
1603                 .family = NVDIMM_FAMILY_INTEL,
1604                 .dsm_mask = mask,
1605         };
1606 
1607         nvdimm = devm_kzalloc(dev, sizeof(*nvdimm), GFP_KERNEL);
1608         if (!nvdimm)
1609                 return -ENOMEM;
1610         *nvdimm = (struct nvdimm) {
1611                 .provider_data = nfit_mem,
1612                 .cmd_mask = mask,
1613                 .dev = {
1614                         .init_name = "test-dimm",
1615                 },
1616         };
1617 
1618 
1619         /* basic checkout of a typical 'get config size' command */
1620         cmd_size = sizeof(cmds.cfg_size);
1621         cmds.cfg_size = (struct nd_cmd_get_config_size) {
1622                 .status = 0,
1623                 .config_size = SZ_128K,
1624                 .max_xfer = SZ_4K,
1625         };
1626         rc = setup_result(cmds.buf, cmd_size);
1627         if (rc)
1628                 return rc;
1629         rc = acpi_nfit_ctl(&acpi_desc->nd_desc, nvdimm, ND_CMD_GET_CONFIG_SIZE,
1630                         cmds.buf, cmd_size, &cmd_rc);
1631 
1632         if (rc < 0 || cmd_rc || cmds.cfg_size.status != 0
1633                         || cmds.cfg_size.config_size != SZ_128K
1634                         || cmds.cfg_size.max_xfer != SZ_4K) {
1635                 dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
1636                                 __func__, __LINE__, rc, cmd_rc);
1637                 return -EIO;
1638         }
1639 
1640 
1641         /* test ars_status with zero output */
1642         cmd_size = offsetof(struct nd_cmd_ars_status, address);
1643         cmds.ars_stat = (struct nd_cmd_ars_status) {
1644                 .out_length = 0,
1645         };
1646         rc = setup_result(cmds.buf, cmd_size);
1647         if (rc)
1648                 return rc;
1649         rc = acpi_nfit_ctl(&acpi_desc->nd_desc, NULL, ND_CMD_ARS_STATUS,
1650                         cmds.buf, cmd_size, &cmd_rc);
1651 
1652         if (rc < 0 || cmd_rc) {
1653                 dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
1654                                 __func__, __LINE__, rc, cmd_rc);
1655                 return -EIO;
1656         }
1657 
1658 
1659         /* test ars_cap with benign extended status */
1660         cmd_size = sizeof(cmds.ars_cap);
1661         cmds.ars_cap = (struct nd_cmd_ars_cap) {
1662                 .status = ND_ARS_PERSISTENT << 16,
1663         };
1664         offset = offsetof(struct nd_cmd_ars_cap, status);
1665         rc = setup_result(cmds.buf + offset, cmd_size - offset);
1666         if (rc)
1667                 return rc;
1668         rc = acpi_nfit_ctl(&acpi_desc->nd_desc, NULL, ND_CMD_ARS_CAP,
1669                         cmds.buf, cmd_size, &cmd_rc);
1670 
1671         if (rc < 0 || cmd_rc) {
1672                 dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
1673                                 __func__, __LINE__, rc, cmd_rc);
1674                 return -EIO;
1675         }
1676 
1677 
1678         /* test ars_status with 'status' trimmed from 'out_length' */
1679         cmd_size = sizeof(cmds.ars_stat) + sizeof(struct nd_ars_record);
1680         cmds.ars_stat = (struct nd_cmd_ars_status) {
1681                 .out_length = cmd_size - 4,
1682         };
1683         record = &cmds.ars_stat.records[0];
1684         *record = (struct nd_ars_record) {
1685                 .length = test_val,
1686         };
1687         rc = setup_result(cmds.buf, cmd_size);
1688         if (rc)
1689                 return rc;
1690         rc = acpi_nfit_ctl(&acpi_desc->nd_desc, NULL, ND_CMD_ARS_STATUS,
1691                         cmds.buf, cmd_size, &cmd_rc);
1692 
1693         if (rc < 0 || cmd_rc || record->length != test_val) {
1694                 dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
1695                                 __func__, __LINE__, rc, cmd_rc);
1696                 return -EIO;
1697         }
1698 
1699 
1700         /* test ars_status with 'Output (Size)' including 'status' */
1701         cmd_size = sizeof(cmds.ars_stat) + sizeof(struct nd_ars_record);
1702         cmds.ars_stat = (struct nd_cmd_ars_status) {
1703                 .out_length = cmd_size,
1704         };
1705         record = &cmds.ars_stat.records[0];
1706         *record = (struct nd_ars_record) {
1707                 .length = test_val,
1708         };
1709         rc = setup_result(cmds.buf, cmd_size);
1710         if (rc)
1711                 return rc;
1712         rc = acpi_nfit_ctl(&acpi_desc->nd_desc, NULL, ND_CMD_ARS_STATUS,
1713                         cmds.buf, cmd_size, &cmd_rc);
1714 
1715         if (rc < 0 || cmd_rc || record->length != test_val) {
1716                 dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
1717                                 __func__, __LINE__, rc, cmd_rc);
1718                 return -EIO;
1719         }
1720 
1721 
1722         /* test extended status for get_config_size results in failure */
1723         cmd_size = sizeof(cmds.cfg_size);
1724         cmds.cfg_size = (struct nd_cmd_get_config_size) {
1725                 .status = 1 << 16,
1726         };
1727         rc = setup_result(cmds.buf, cmd_size);
1728         if (rc)
1729                 return rc;
1730         rc = acpi_nfit_ctl(&acpi_desc->nd_desc, nvdimm, ND_CMD_GET_CONFIG_SIZE,
1731                         cmds.buf, cmd_size, &cmd_rc);
1732 
1733         if (rc < 0 || cmd_rc >= 0) {
1734                 dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
1735                                 __func__, __LINE__, rc, cmd_rc);
1736                 return -EIO;
1737         }
1738 
1739         return 0;
1740 }
1741 
1742 static int nfit_test_probe(struct platform_device *pdev)
1743 {
1744         struct nvdimm_bus_descriptor *nd_desc;
1745         struct acpi_nfit_desc *acpi_desc;
1746         struct device *dev = &pdev->dev;
1747         struct nfit_test *nfit_test;
1748         struct nfit_mem *nfit_mem;
1749         union acpi_object *obj;
1750         int rc;
1751 
1752         if (strcmp(dev_name(&pdev->dev), "nfit_test.0") == 0) {
1753                 rc = nfit_ctl_test(&pdev->dev);
1754                 if (rc)
1755                         return rc;
1756         }
1757 
1758         nfit_test = to_nfit_test(&pdev->dev);
1759 
1760         /* common alloc */
1761         if (nfit_test->num_dcr) {
1762                 int num = nfit_test->num_dcr;
1763 
1764                 nfit_test->dimm = devm_kcalloc(dev, num, sizeof(void *),
1765                                 GFP_KERNEL);
1766                 nfit_test->dimm_dma = devm_kcalloc(dev, num, sizeof(dma_addr_t),
1767                                 GFP_KERNEL);
1768                 nfit_test->flush = devm_kcalloc(dev, num, sizeof(void *),
1769                                 GFP_KERNEL);
1770                 nfit_test->flush_dma = devm_kcalloc(dev, num, sizeof(dma_addr_t),
1771                                 GFP_KERNEL);
1772                 nfit_test->label = devm_kcalloc(dev, num, sizeof(void *),
1773                                 GFP_KERNEL);
1774                 nfit_test->label_dma = devm_kcalloc(dev, num,
1775                                 sizeof(dma_addr_t), GFP_KERNEL);
1776                 nfit_test->dcr = devm_kcalloc(dev, num,
1777                                 sizeof(struct nfit_test_dcr *), GFP_KERNEL);
1778                 nfit_test->dcr_dma = devm_kcalloc(dev, num,
1779                                 sizeof(dma_addr_t), GFP_KERNEL);
1780                 if (nfit_test->dimm && nfit_test->dimm_dma && nfit_test->label
1781                                 && nfit_test->label_dma && nfit_test->dcr
1782                                 && nfit_test->dcr_dma && nfit_test->flush
1783                                 && nfit_test->flush_dma)
1784                         /* pass */;
1785                 else
1786                         return -ENOMEM;
1787         }
1788 
1789         if (nfit_test->num_pm) {
1790                 int num = nfit_test->num_pm;
1791 
1792                 nfit_test->spa_set = devm_kcalloc(dev, num, sizeof(void *),
1793                                 GFP_KERNEL);
1794                 nfit_test->spa_set_dma = devm_kcalloc(dev, num,
1795                                 sizeof(dma_addr_t), GFP_KERNEL);
1796                 if (nfit_test->spa_set && nfit_test->spa_set_dma)
1797                         /* pass */;
1798                 else
1799                         return -ENOMEM;
1800         }
1801 
1802         /* per-nfit specific alloc */
1803         if (nfit_test->alloc(nfit_test))
1804                 return -ENOMEM;
1805 
1806         nfit_test->setup(nfit_test);
1807         acpi_desc = &nfit_test->acpi_desc;
1808         acpi_nfit_desc_init(acpi_desc, &pdev->dev);
1809         acpi_desc->blk_do_io = nfit_test_blk_do_io;
1810         nd_desc = &acpi_desc->nd_desc;
1811         nd_desc->provider_name = NULL;
1812         nd_desc->module = THIS_MODULE;
1813         nd_desc->ndctl = nfit_test_ctl;
1814 
1815         rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf,
1816                         nfit_test->nfit_size);
1817         if (rc)
1818                 return rc;
1819 
1820         if (nfit_test->setup != nfit_test0_setup)
1821                 return 0;
1822 
1823         nfit_test->setup_hotplug = 1;
1824         nfit_test->setup(nfit_test);
1825 
1826         obj = kzalloc(sizeof(*obj), GFP_KERNEL);
1827         if (!obj)
1828                 return -ENOMEM;
1829         obj->type = ACPI_TYPE_BUFFER;
1830         obj->buffer.length = nfit_test->nfit_size;
1831         obj->buffer.pointer = nfit_test->nfit_buf;
1832         *(nfit_test->_fit) = obj;
1833         __acpi_nfit_notify(&pdev->dev, nfit_test, 0x80);
1834 
1835         /* associate dimm devices with nfit_mem data for notification testing */
1836         mutex_lock(&acpi_desc->init_mutex);
1837         list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) {
1838                 u32 nfit_handle = __to_nfit_memdev(nfit_mem)->device_handle;
1839                 int i;
1840 
1841                 for (i = 0; i < NUM_DCR; i++)
1842                         if (nfit_handle == handle[i])
1843                                 dev_set_drvdata(nfit_test->dimm_dev[i],
1844                                                 nfit_mem);
1845         }
1846         mutex_unlock(&acpi_desc->init_mutex);
1847 
1848         return 0;
1849 }
1850 
1851 static int nfit_test_remove(struct platform_device *pdev)
1852 {
1853         return 0;
1854 }
1855 
1856 static void nfit_test_release(struct device *dev)
1857 {
1858         struct nfit_test *nfit_test = to_nfit_test(dev);
1859 
1860         kfree(nfit_test);
1861 }
1862 
1863 static const struct platform_device_id nfit_test_id[] = {
1864         { KBUILD_MODNAME },
1865         { },
1866 };
1867 
1868 static struct platform_driver nfit_test_driver = {
1869         .probe = nfit_test_probe,
1870         .remove = nfit_test_remove,
1871         .driver = {
1872                 .name = KBUILD_MODNAME,
1873         },
1874         .id_table = nfit_test_id,
1875 };
1876 
1877 static __init int nfit_test_init(void)
1878 {
1879         int rc, i;
1880 
1881         nfit_test_setup(nfit_test_lookup, nfit_test_evaluate_dsm);
1882 
1883         nfit_test_dimm = class_create(THIS_MODULE, "nfit_test_dimm");
1884         if (IS_ERR(nfit_test_dimm)) {
1885                 rc = PTR_ERR(nfit_test_dimm);
1886                 goto err_register;
1887         }
1888 
1889         for (i = 0; i < NUM_NFITS; i++) {
1890                 struct nfit_test *nfit_test;
1891                 struct platform_device *pdev;
1892 
1893                 nfit_test = kzalloc(sizeof(*nfit_test), GFP_KERNEL);
1894                 if (!nfit_test) {
1895                         rc = -ENOMEM;
1896                         goto err_register;
1897                 }
1898                 INIT_LIST_HEAD(&nfit_test->resources);
1899                 switch (i) {
1900                 case 0:
1901                         nfit_test->num_pm = NUM_PM;
1902                         nfit_test->dcr_idx = 0;
1903                         nfit_test->num_dcr = NUM_DCR;
1904                         nfit_test->alloc = nfit_test0_alloc;
1905                         nfit_test->setup = nfit_test0_setup;
1906                         break;
1907                 case 1:
1908                         nfit_test->num_pm = 1;
1909                         nfit_test->dcr_idx = NUM_DCR;
1910                         nfit_test->num_dcr = 1;
1911                         nfit_test->alloc = nfit_test1_alloc;
1912                         nfit_test->setup = nfit_test1_setup;
1913                         break;
1914                 default:
1915                         rc = -EINVAL;
1916                         goto err_register;
1917                 }
1918                 pdev = &nfit_test->pdev;
1919                 pdev->name = KBUILD_MODNAME;
1920                 pdev->id = i;
1921                 pdev->dev.release = nfit_test_release;
1922                 rc = platform_device_register(pdev);
1923                 if (rc) {
1924                         put_device(&pdev->dev);
1925                         goto err_register;
1926                 }
1927 
1928                 rc = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
1929                 if (rc)
1930                         goto err_register;
1931 
1932                 instances[i] = nfit_test;
1933         }
1934 
1935         rc = platform_driver_register(&nfit_test_driver);
1936         if (rc)
1937                 goto err_register;
1938         return 0;
1939 
1940  err_register:
1941         for (i = 0; i < NUM_NFITS; i++)
1942                 if (instances[i])
1943                         platform_device_unregister(&instances[i]->pdev);
1944         nfit_test_teardown();
1945         return rc;
1946 }
1947 
1948 static __exit void nfit_test_exit(void)
1949 {
1950         int i;
1951 
1952         platform_driver_unregister(&nfit_test_driver);
1953         for (i = 0; i < NUM_NFITS; i++)
1954                 platform_device_unregister(&instances[i]->pdev);
1955         nfit_test_teardown();
1956         class_destroy(nfit_test_dimm);
1957 }
1958 
1959 module_init(nfit_test_init);
1960 module_exit(nfit_test_exit);
1961 MODULE_LICENSE("GPL v2");
1962 MODULE_AUTHOR("Intel Corporation");
1963 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp