2 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
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.
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.
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>
29 #include "nfit_test.h"
32 * Generate an NFIT table to describe the following topology:
34 * BUS0: Interleaved PMEM regions, and aliasing with BLK regions
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
45 * | +-------------------------^----------^ ^
46 * +--+---+ | blk4.0 | pm1.0 | 2 region4
47 * | imc1 +--+-------------------------+----------+ +
48 * +------+ | blk5.0 | pm1.0 | 3 region5
49 * +-------------------------+----------+-+-------+
53 * +--+---+ (Hotplug DIMM)
54 * | +----------------------------------------------+
55 * +--+---+ | blk6.0/pm7.0 | 4 region6/7
56 * | imc0 +--+----------------------------------------------+
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.
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.
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
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.
87 * BUS1: Legacy NVDIMM (single contiguous range)
90 * +---------------------+
91 * |---------------------|
93 * |---------------------|
94 * +---------------------+
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.
105 NUM_SPA
= NUM_PM
+ NUM_DCR
+ NUM_BDW
,
106 NUM_MEM
= NUM_DCR
+ NUM_BDW
+ 2 /* spa0 iset */ + 4 /* spa1 iset */,
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
,
115 NUM_NFITS
= 2, /* permit testing multiple NFITs per system */
118 struct nfit_test_dcr
{
121 __u8 aperature
[BDW_SIZE
];
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))
128 static u32 handle
[NUM_DCR
] = {
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),
136 static unsigned long dimm_fail_cmd_flags
[NUM_DCR
];
139 struct acpi_nfit_desc acpi_desc
;
140 struct platform_device pdev
;
141 struct list_head resources
;
148 dma_addr_t
*dimm_dma
;
150 dma_addr_t
*flush_dma
;
152 dma_addr_t
*label_dma
;
154 dma_addr_t
*spa_set_dma
;
155 struct nfit_test_dcr
**dcr
;
157 int (*alloc
)(struct nfit_test
*t
);
158 void (*setup
)(struct nfit_test
*t
);
160 union acpi_object
**_fit
;
163 struct nd_cmd_ars_status
*ars_status
;
164 unsigned long deadline
;
167 struct device
*dimm_dev
[NUM_DCR
];
170 static struct nfit_test
*to_nfit_test(struct device
*dev
)
172 struct platform_device
*pdev
= to_platform_device(dev
);
174 return container_of(pdev
, struct nfit_test
, pdev
);
177 static int nfit_test_cmd_get_config_size(struct nd_cmd_get_config_size
*nd_cmd
,
178 unsigned int buf_len
)
180 if (buf_len
< sizeof(*nd_cmd
))
184 nd_cmd
->config_size
= LABEL_SIZE
;
185 nd_cmd
->max_xfer
= SZ_4K
;
190 static int nfit_test_cmd_get_config_data(struct nd_cmd_get_config_data_hdr
191 *nd_cmd
, unsigned int buf_len
, void *label
)
193 unsigned int len
, offset
= nd_cmd
->in_offset
;
196 if (buf_len
< sizeof(*nd_cmd
))
198 if (offset
>= LABEL_SIZE
)
200 if (nd_cmd
->in_length
+ sizeof(*nd_cmd
) > buf_len
)
204 len
= min(nd_cmd
->in_length
, LABEL_SIZE
- offset
);
205 memcpy(nd_cmd
->out_buf
, label
+ offset
, len
);
206 rc
= buf_len
- sizeof(*nd_cmd
) - len
;
211 static int nfit_test_cmd_set_config_data(struct nd_cmd_set_config_hdr
*nd_cmd
,
212 unsigned int buf_len
, void *label
)
214 unsigned int len
, offset
= nd_cmd
->in_offset
;
218 if (buf_len
< sizeof(*nd_cmd
))
220 if (offset
>= LABEL_SIZE
)
222 if (nd_cmd
->in_length
+ sizeof(*nd_cmd
) + 4 > buf_len
)
225 status
= (void *)nd_cmd
+ nd_cmd
->in_length
+ sizeof(*nd_cmd
);
227 len
= min(nd_cmd
->in_length
, LABEL_SIZE
- offset
);
228 memcpy(label
+ offset
, nd_cmd
->in_buf
, len
);
229 rc
= buf_len
- sizeof(*nd_cmd
) - (len
+ 4);
234 #define NFIT_TEST_ARS_RECORDS 4
235 #define NFIT_TEST_CLEAR_ERR_UNIT 256
237 static int nfit_test_cmd_ars_cap(struct nd_cmd_ars_cap
*nd_cmd
,
238 unsigned int buf_len
)
240 if (buf_len
< sizeof(*nd_cmd
))
243 nd_cmd
->max_ars_out
= sizeof(struct nd_cmd_ars_status
)
244 + NFIT_TEST_ARS_RECORDS
* sizeof(struct nd_ars_record
);
245 nd_cmd
->status
= (ND_ARS_PERSISTENT
| ND_ARS_VOLATILE
) << 16;
246 nd_cmd
->clear_err_unit
= NFIT_TEST_CLEAR_ERR_UNIT
;
252 * Initialize the ars_state to return an ars_result 1 second in the future with
253 * a 4K error range in the middle of the requested address range.
255 static void post_ars_status(struct ars_state
*ars_state
, u64 addr
, u64 len
)
257 struct nd_cmd_ars_status
*ars_status
;
258 struct nd_ars_record
*ars_record
;
260 ars_state
->deadline
= jiffies
+ 1*HZ
;
261 ars_status
= ars_state
->ars_status
;
262 ars_status
->status
= 0;
263 ars_status
->out_length
= sizeof(struct nd_cmd_ars_status
)
264 + sizeof(struct nd_ars_record
);
265 ars_status
->address
= addr
;
266 ars_status
->length
= len
;
267 ars_status
->type
= ND_ARS_PERSISTENT
;
268 ars_status
->num_records
= 1;
269 ars_record
= &ars_status
->records
[0];
270 ars_record
->handle
= 0;
271 ars_record
->err_address
= addr
+ len
/ 2;
272 ars_record
->length
= SZ_4K
;
275 static int nfit_test_cmd_ars_start(struct ars_state
*ars_state
,
276 struct nd_cmd_ars_start
*ars_start
, unsigned int buf_len
,
279 if (buf_len
< sizeof(*ars_start
))
282 spin_lock(&ars_state
->lock
);
283 if (time_before(jiffies
, ars_state
->deadline
)) {
284 ars_start
->status
= NFIT_ARS_START_BUSY
;
287 ars_start
->status
= 0;
288 ars_start
->scrub_time
= 1;
289 post_ars_status(ars_state
, ars_start
->address
,
293 spin_unlock(&ars_state
->lock
);
298 static int nfit_test_cmd_ars_status(struct ars_state
*ars_state
,
299 struct nd_cmd_ars_status
*ars_status
, unsigned int buf_len
,
302 if (buf_len
< ars_state
->ars_status
->out_length
)
305 spin_lock(&ars_state
->lock
);
306 if (time_before(jiffies
, ars_state
->deadline
)) {
307 memset(ars_status
, 0, buf_len
);
308 ars_status
->status
= NFIT_ARS_STATUS_BUSY
;
309 ars_status
->out_length
= sizeof(*ars_status
);
312 memcpy(ars_status
, ars_state
->ars_status
,
313 ars_state
->ars_status
->out_length
);
316 spin_unlock(&ars_state
->lock
);
320 static int nfit_test_cmd_clear_error(struct nd_cmd_clear_error
*clear_err
,
321 unsigned int buf_len
, int *cmd_rc
)
323 const u64 mask
= NFIT_TEST_CLEAR_ERR_UNIT
- 1;
324 if (buf_len
< sizeof(*clear_err
))
327 if ((clear_err
->address
& mask
) || (clear_err
->length
& mask
))
331 * Report 'all clear' success for all commands even though a new
332 * scrub will find errors again. This is enough to have the
333 * error removed from the 'badblocks' tracking in the pmem
336 clear_err
->status
= 0;
337 clear_err
->cleared
= clear_err
->length
;
342 static int nfit_test_cmd_smart(struct nd_cmd_smart
*smart
, unsigned int buf_len
)
344 static const struct nd_smart_payload smart_data
= {
345 .flags
= ND_SMART_HEALTH_VALID
| ND_SMART_TEMP_VALID
346 | ND_SMART_SPARES_VALID
| ND_SMART_ALARM_VALID
347 | ND_SMART_USED_VALID
| ND_SMART_SHUTDOWN_VALID
,
348 .health
= ND_SMART_NON_CRITICAL_HEALTH
,
349 .temperature
= 23 * 16,
351 .alarm_flags
= ND_SMART_SPARE_TRIP
| ND_SMART_TEMP_TRIP
,
357 if (buf_len
< sizeof(*smart
))
359 memcpy(smart
->data
, &smart_data
, sizeof(smart_data
));
363 static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold
*smart_t
,
364 unsigned int buf_len
)
366 static const struct nd_smart_threshold_payload smart_t_data
= {
367 .alarm_control
= ND_SMART_SPARE_TRIP
| ND_SMART_TEMP_TRIP
,
368 .temperature
= 40 * 16,
372 if (buf_len
< sizeof(*smart_t
))
374 memcpy(smart_t
->data
, &smart_t_data
, sizeof(smart_t_data
));
378 static int nfit_test_ctl(struct nvdimm_bus_descriptor
*nd_desc
,
379 struct nvdimm
*nvdimm
, unsigned int cmd
, void *buf
,
380 unsigned int buf_len
, int *cmd_rc
)
382 struct acpi_nfit_desc
*acpi_desc
= to_acpi_desc(nd_desc
);
383 struct nfit_test
*t
= container_of(acpi_desc
, typeof(*t
), acpi_desc
);
384 unsigned int func
= cmd
;
385 int i
, rc
= 0, __cmd_rc
;
392 struct nfit_mem
*nfit_mem
= nvdimm_provider_data(nvdimm
);
393 unsigned long cmd_mask
= nvdimm_cmd_mask(nvdimm
);
398 if (cmd
== ND_CMD_CALL
) {
399 struct nd_cmd_pkg
*call_pkg
= buf
;
401 buf_len
= call_pkg
->nd_size_in
+ call_pkg
->nd_size_out
;
402 buf
= (void *) call_pkg
->nd_payload
;
403 func
= call_pkg
->nd_command
;
404 if (call_pkg
->nd_family
!= nfit_mem
->family
)
408 if (!test_bit(cmd
, &cmd_mask
)
409 || !test_bit(func
, &nfit_mem
->dsm_mask
))
412 /* lookup label space for the given dimm */
413 for (i
= 0; i
< ARRAY_SIZE(handle
); i
++)
414 if (__to_nfit_memdev(nfit_mem
)->device_handle
==
417 if (i
>= ARRAY_SIZE(handle
))
420 if ((1 << func
) & dimm_fail_cmd_flags
[i
])
424 case ND_CMD_GET_CONFIG_SIZE
:
425 rc
= nfit_test_cmd_get_config_size(buf
, buf_len
);
427 case ND_CMD_GET_CONFIG_DATA
:
428 rc
= nfit_test_cmd_get_config_data(buf
, buf_len
,
431 case ND_CMD_SET_CONFIG_DATA
:
432 rc
= nfit_test_cmd_set_config_data(buf
, buf_len
,
436 rc
= nfit_test_cmd_smart(buf
, buf_len
);
438 case ND_CMD_SMART_THRESHOLD
:
439 rc
= nfit_test_cmd_smart_threshold(buf
, buf_len
);
440 device_lock(&t
->pdev
.dev
);
441 __acpi_nvdimm_notify(t
->dimm_dev
[i
], 0x81);
442 device_unlock(&t
->pdev
.dev
);
448 struct ars_state
*ars_state
= &t
->ars_state
;
450 if (!nd_desc
|| !test_bit(cmd
, &nd_desc
->cmd_mask
))
455 rc
= nfit_test_cmd_ars_cap(buf
, buf_len
);
457 case ND_CMD_ARS_START
:
458 rc
= nfit_test_cmd_ars_start(ars_state
, buf
, buf_len
,
461 case ND_CMD_ARS_STATUS
:
462 rc
= nfit_test_cmd_ars_status(ars_state
, buf
, buf_len
,
465 case ND_CMD_CLEAR_ERROR
:
466 rc
= nfit_test_cmd_clear_error(buf
, buf_len
, cmd_rc
);
476 static DEFINE_SPINLOCK(nfit_test_lock
);
477 static struct nfit_test
*instances
[NUM_NFITS
];
479 static void release_nfit_res(void *data
)
481 struct nfit_test_resource
*nfit_res
= data
;
483 spin_lock(&nfit_test_lock
);
484 list_del(&nfit_res
->list
);
485 spin_unlock(&nfit_test_lock
);
487 vfree(nfit_res
->buf
);
491 static void *__test_alloc(struct nfit_test
*t
, size_t size
, dma_addr_t
*dma
,
494 struct device
*dev
= &t
->pdev
.dev
;
495 struct nfit_test_resource
*nfit_res
= kzalloc(sizeof(*nfit_res
),
499 if (!buf
|| !nfit_res
)
501 rc
= devm_add_action(dev
, release_nfit_res
, nfit_res
);
504 INIT_LIST_HEAD(&nfit_res
->list
);
505 memset(buf
, 0, size
);
508 nfit_res
->res
.start
= *dma
;
509 nfit_res
->res
.end
= *dma
+ size
- 1;
510 nfit_res
->res
.name
= "NFIT";
511 spin_lock_init(&nfit_res
->lock
);
512 INIT_LIST_HEAD(&nfit_res
->requests
);
513 spin_lock(&nfit_test_lock
);
514 list_add(&nfit_res
->list
, &t
->resources
);
515 spin_unlock(&nfit_test_lock
);
517 return nfit_res
->buf
;
525 static void *test_alloc(struct nfit_test
*t
, size_t size
, dma_addr_t
*dma
)
527 void *buf
= vmalloc(size
);
529 *dma
= (unsigned long) buf
;
530 return __test_alloc(t
, size
, dma
, buf
);
533 static struct nfit_test_resource
*nfit_test_lookup(resource_size_t addr
)
537 for (i
= 0; i
< ARRAY_SIZE(instances
); i
++) {
538 struct nfit_test_resource
*n
, *nfit_res
= NULL
;
539 struct nfit_test
*t
= instances
[i
];
543 spin_lock(&nfit_test_lock
);
544 list_for_each_entry(n
, &t
->resources
, list
) {
545 if (addr
>= n
->res
.start
&& (addr
< n
->res
.start
546 + resource_size(&n
->res
))) {
549 } else if (addr
>= (unsigned long) n
->buf
550 && (addr
< (unsigned long) n
->buf
551 + resource_size(&n
->res
))) {
556 spin_unlock(&nfit_test_lock
);
564 static int ars_state_init(struct device
*dev
, struct ars_state
*ars_state
)
566 ars_state
->ars_status
= devm_kzalloc(dev
,
567 sizeof(struct nd_cmd_ars_status
)
568 + sizeof(struct nd_ars_record
) * NFIT_TEST_ARS_RECORDS
,
570 if (!ars_state
->ars_status
)
572 spin_lock_init(&ars_state
->lock
);
576 static void put_dimms(void *data
)
578 struct device
**dimm_dev
= data
;
581 for (i
= 0; i
< NUM_DCR
; i
++)
583 device_unregister(dimm_dev
[i
]);
586 static struct class *nfit_test_dimm
;
588 static int dimm_name_to_id(struct device
*dev
)
592 if (sscanf(dev_name(dev
), "test_dimm%d", &dimm
) != 1
593 || dimm
>= NUM_DCR
|| dimm
< 0)
599 static ssize_t
handle_show(struct device
*dev
, struct device_attribute
*attr
,
602 int dimm
= dimm_name_to_id(dev
);
607 return sprintf(buf
, "%#x", handle
[dimm
]);
609 DEVICE_ATTR_RO(handle
);
611 static ssize_t
fail_cmd_show(struct device
*dev
, struct device_attribute
*attr
,
614 int dimm
= dimm_name_to_id(dev
);
619 return sprintf(buf
, "%#lx\n", dimm_fail_cmd_flags
[dimm
]);
622 static ssize_t
fail_cmd_store(struct device
*dev
, struct device_attribute
*attr
,
623 const char *buf
, size_t size
)
625 int dimm
= dimm_name_to_id(dev
);
632 rc
= kstrtol(buf
, 0, &val
);
636 dimm_fail_cmd_flags
[dimm
] = val
;
639 static DEVICE_ATTR_RW(fail_cmd
);
641 static struct attribute
*nfit_test_dimm_attributes
[] = {
642 &dev_attr_fail_cmd
.attr
,
643 &dev_attr_handle
.attr
,
647 static struct attribute_group nfit_test_dimm_attribute_group
= {
648 .attrs
= nfit_test_dimm_attributes
,
651 static const struct attribute_group
*nfit_test_dimm_attribute_groups
[] = {
652 &nfit_test_dimm_attribute_group
,
656 static int nfit_test0_alloc(struct nfit_test
*t
)
658 size_t nfit_size
= sizeof(struct acpi_nfit_system_address
) * NUM_SPA
659 + sizeof(struct acpi_nfit_memory_map
) * NUM_MEM
660 + sizeof(struct acpi_nfit_control_region
) * NUM_DCR
661 + offsetof(struct acpi_nfit_control_region
,
662 window_size
) * NUM_DCR
663 + sizeof(struct acpi_nfit_data_region
) * NUM_BDW
664 + (sizeof(struct acpi_nfit_flush_address
)
665 + sizeof(u64
) * NUM_HINTS
) * NUM_DCR
;
668 t
->nfit_buf
= test_alloc(t
, nfit_size
, &t
->nfit_dma
);
671 t
->nfit_size
= nfit_size
;
673 t
->spa_set
[0] = test_alloc(t
, SPA0_SIZE
, &t
->spa_set_dma
[0]);
677 t
->spa_set
[1] = test_alloc(t
, SPA1_SIZE
, &t
->spa_set_dma
[1]);
681 t
->spa_set
[2] = test_alloc(t
, SPA0_SIZE
, &t
->spa_set_dma
[2]);
685 for (i
= 0; i
< NUM_DCR
; i
++) {
686 t
->dimm
[i
] = test_alloc(t
, DIMM_SIZE
, &t
->dimm_dma
[i
]);
690 t
->label
[i
] = test_alloc(t
, LABEL_SIZE
, &t
->label_dma
[i
]);
693 sprintf(t
->label
[i
], "label%d", i
);
695 t
->flush
[i
] = test_alloc(t
, max(PAGE_SIZE
,
696 sizeof(u64
) * NUM_HINTS
),
702 for (i
= 0; i
< NUM_DCR
; i
++) {
703 t
->dcr
[i
] = test_alloc(t
, LABEL_SIZE
, &t
->dcr_dma
[i
]);
708 t
->_fit
= test_alloc(t
, sizeof(union acpi_object
**), &t
->_fit_dma
);
712 if (devm_add_action_or_reset(&t
->pdev
.dev
, put_dimms
, t
->dimm_dev
))
714 for (i
= 0; i
< NUM_DCR
; i
++) {
715 t
->dimm_dev
[i
] = device_create_with_groups(nfit_test_dimm
,
716 &t
->pdev
.dev
, 0, NULL
,
717 nfit_test_dimm_attribute_groups
,
723 return ars_state_init(&t
->pdev
.dev
, &t
->ars_state
);
726 static int nfit_test1_alloc(struct nfit_test
*t
)
728 size_t nfit_size
= sizeof(struct acpi_nfit_system_address
) * 2
729 + sizeof(struct acpi_nfit_memory_map
)
730 + offsetof(struct acpi_nfit_control_region
, window_size
);
732 t
->nfit_buf
= test_alloc(t
, nfit_size
, &t
->nfit_dma
);
735 t
->nfit_size
= nfit_size
;
737 t
->spa_set
[0] = test_alloc(t
, SPA2_SIZE
, &t
->spa_set_dma
[0]);
741 t
->spa_set
[1] = test_alloc(t
, SPA_VCD_SIZE
, &t
->spa_set_dma
[1]);
745 return ars_state_init(&t
->pdev
.dev
, &t
->ars_state
);
748 static void dcr_common_init(struct acpi_nfit_control_region
*dcr
)
750 dcr
->vendor_id
= 0xabcd;
752 dcr
->revision_id
= 1;
753 dcr
->valid_fields
= 1;
754 dcr
->manufacturing_location
= 0xa;
755 dcr
->manufacturing_date
= cpu_to_be16(2016);
758 static void nfit_test0_setup(struct nfit_test
*t
)
760 const int flush_hint_size
= sizeof(struct acpi_nfit_flush_address
)
761 + (sizeof(u64
) * NUM_HINTS
);
762 struct acpi_nfit_desc
*acpi_desc
;
763 struct acpi_nfit_memory_map
*memdev
;
764 void *nfit_buf
= t
->nfit_buf
;
765 struct acpi_nfit_system_address
*spa
;
766 struct acpi_nfit_control_region
*dcr
;
767 struct acpi_nfit_data_region
*bdw
;
768 struct acpi_nfit_flush_address
*flush
;
769 unsigned int offset
, i
;
772 * spa0 (interleave first half of dimm0 and dimm1, note storage
773 * does not actually alias the related block-data-window
777 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
778 spa
->header
.length
= sizeof(*spa
);
779 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
780 spa
->range_index
= 0+1;
781 spa
->address
= t
->spa_set_dma
[0];
782 spa
->length
= SPA0_SIZE
;
785 * spa1 (interleave last half of the 4 DIMMS, note storage
786 * does not actually alias the related block-data-window
789 spa
= nfit_buf
+ sizeof(*spa
);
790 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
791 spa
->header
.length
= sizeof(*spa
);
792 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
793 spa
->range_index
= 1+1;
794 spa
->address
= t
->spa_set_dma
[1];
795 spa
->length
= SPA1_SIZE
;
797 /* spa2 (dcr0) dimm0 */
798 spa
= nfit_buf
+ sizeof(*spa
) * 2;
799 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
800 spa
->header
.length
= sizeof(*spa
);
801 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
802 spa
->range_index
= 2+1;
803 spa
->address
= t
->dcr_dma
[0];
804 spa
->length
= DCR_SIZE
;
806 /* spa3 (dcr1) dimm1 */
807 spa
= nfit_buf
+ sizeof(*spa
) * 3;
808 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
809 spa
->header
.length
= sizeof(*spa
);
810 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
811 spa
->range_index
= 3+1;
812 spa
->address
= t
->dcr_dma
[1];
813 spa
->length
= DCR_SIZE
;
815 /* spa4 (dcr2) dimm2 */
816 spa
= nfit_buf
+ sizeof(*spa
) * 4;
817 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
818 spa
->header
.length
= sizeof(*spa
);
819 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
820 spa
->range_index
= 4+1;
821 spa
->address
= t
->dcr_dma
[2];
822 spa
->length
= DCR_SIZE
;
824 /* spa5 (dcr3) dimm3 */
825 spa
= nfit_buf
+ sizeof(*spa
) * 5;
826 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
827 spa
->header
.length
= sizeof(*spa
);
828 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
829 spa
->range_index
= 5+1;
830 spa
->address
= t
->dcr_dma
[3];
831 spa
->length
= DCR_SIZE
;
833 /* spa6 (bdw for dcr0) dimm0 */
834 spa
= nfit_buf
+ sizeof(*spa
) * 6;
835 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
836 spa
->header
.length
= sizeof(*spa
);
837 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
838 spa
->range_index
= 6+1;
839 spa
->address
= t
->dimm_dma
[0];
840 spa
->length
= DIMM_SIZE
;
842 /* spa7 (bdw for dcr1) dimm1 */
843 spa
= nfit_buf
+ sizeof(*spa
) * 7;
844 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
845 spa
->header
.length
= sizeof(*spa
);
846 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
847 spa
->range_index
= 7+1;
848 spa
->address
= t
->dimm_dma
[1];
849 spa
->length
= DIMM_SIZE
;
851 /* spa8 (bdw for dcr2) dimm2 */
852 spa
= nfit_buf
+ sizeof(*spa
) * 8;
853 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
854 spa
->header
.length
= sizeof(*spa
);
855 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
856 spa
->range_index
= 8+1;
857 spa
->address
= t
->dimm_dma
[2];
858 spa
->length
= DIMM_SIZE
;
860 /* spa9 (bdw for dcr3) dimm3 */
861 spa
= nfit_buf
+ sizeof(*spa
) * 9;
862 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
863 spa
->header
.length
= sizeof(*spa
);
864 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
865 spa
->range_index
= 9+1;
866 spa
->address
= t
->dimm_dma
[3];
867 spa
->length
= DIMM_SIZE
;
869 offset
= sizeof(*spa
) * 10;
870 /* mem-region0 (spa0, dimm0) */
871 memdev
= nfit_buf
+ offset
;
872 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
873 memdev
->header
.length
= sizeof(*memdev
);
874 memdev
->device_handle
= handle
[0];
875 memdev
->physical_id
= 0;
876 memdev
->region_id
= 0;
877 memdev
->range_index
= 0+1;
878 memdev
->region_index
= 4+1;
879 memdev
->region_size
= SPA0_SIZE
/2;
880 memdev
->region_offset
= t
->spa_set_dma
[0];
882 memdev
->interleave_index
= 0;
883 memdev
->interleave_ways
= 2;
885 /* mem-region1 (spa0, dimm1) */
886 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
);
887 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
888 memdev
->header
.length
= sizeof(*memdev
);
889 memdev
->device_handle
= handle
[1];
890 memdev
->physical_id
= 1;
891 memdev
->region_id
= 0;
892 memdev
->range_index
= 0+1;
893 memdev
->region_index
= 5+1;
894 memdev
->region_size
= SPA0_SIZE
/2;
895 memdev
->region_offset
= t
->spa_set_dma
[0] + SPA0_SIZE
/2;
897 memdev
->interleave_index
= 0;
898 memdev
->interleave_ways
= 2;
900 /* mem-region2 (spa1, dimm0) */
901 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 2;
902 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
903 memdev
->header
.length
= sizeof(*memdev
);
904 memdev
->device_handle
= handle
[0];
905 memdev
->physical_id
= 0;
906 memdev
->region_id
= 1;
907 memdev
->range_index
= 1+1;
908 memdev
->region_index
= 4+1;
909 memdev
->region_size
= SPA1_SIZE
/4;
910 memdev
->region_offset
= t
->spa_set_dma
[1];
911 memdev
->address
= SPA0_SIZE
/2;
912 memdev
->interleave_index
= 0;
913 memdev
->interleave_ways
= 4;
915 /* mem-region3 (spa1, dimm1) */
916 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 3;
917 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
918 memdev
->header
.length
= sizeof(*memdev
);
919 memdev
->device_handle
= handle
[1];
920 memdev
->physical_id
= 1;
921 memdev
->region_id
= 1;
922 memdev
->range_index
= 1+1;
923 memdev
->region_index
= 5+1;
924 memdev
->region_size
= SPA1_SIZE
/4;
925 memdev
->region_offset
= t
->spa_set_dma
[1] + SPA1_SIZE
/4;
926 memdev
->address
= SPA0_SIZE
/2;
927 memdev
->interleave_index
= 0;
928 memdev
->interleave_ways
= 4;
930 /* mem-region4 (spa1, dimm2) */
931 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 4;
932 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
933 memdev
->header
.length
= sizeof(*memdev
);
934 memdev
->device_handle
= handle
[2];
935 memdev
->physical_id
= 2;
936 memdev
->region_id
= 0;
937 memdev
->range_index
= 1+1;
938 memdev
->region_index
= 6+1;
939 memdev
->region_size
= SPA1_SIZE
/4;
940 memdev
->region_offset
= t
->spa_set_dma
[1] + 2*SPA1_SIZE
/4;
941 memdev
->address
= SPA0_SIZE
/2;
942 memdev
->interleave_index
= 0;
943 memdev
->interleave_ways
= 4;
945 /* mem-region5 (spa1, dimm3) */
946 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 5;
947 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
948 memdev
->header
.length
= sizeof(*memdev
);
949 memdev
->device_handle
= handle
[3];
950 memdev
->physical_id
= 3;
951 memdev
->region_id
= 0;
952 memdev
->range_index
= 1+1;
953 memdev
->region_index
= 7+1;
954 memdev
->region_size
= SPA1_SIZE
/4;
955 memdev
->region_offset
= t
->spa_set_dma
[1] + 3*SPA1_SIZE
/4;
956 memdev
->address
= SPA0_SIZE
/2;
957 memdev
->interleave_index
= 0;
958 memdev
->interleave_ways
= 4;
960 /* mem-region6 (spa/dcr0, dimm0) */
961 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 6;
962 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
963 memdev
->header
.length
= sizeof(*memdev
);
964 memdev
->device_handle
= handle
[0];
965 memdev
->physical_id
= 0;
966 memdev
->region_id
= 0;
967 memdev
->range_index
= 2+1;
968 memdev
->region_index
= 0+1;
969 memdev
->region_size
= 0;
970 memdev
->region_offset
= 0;
972 memdev
->interleave_index
= 0;
973 memdev
->interleave_ways
= 1;
975 /* mem-region7 (spa/dcr1, dimm1) */
976 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 7;
977 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
978 memdev
->header
.length
= sizeof(*memdev
);
979 memdev
->device_handle
= handle
[1];
980 memdev
->physical_id
= 1;
981 memdev
->region_id
= 0;
982 memdev
->range_index
= 3+1;
983 memdev
->region_index
= 1+1;
984 memdev
->region_size
= 0;
985 memdev
->region_offset
= 0;
987 memdev
->interleave_index
= 0;
988 memdev
->interleave_ways
= 1;
990 /* mem-region8 (spa/dcr2, dimm2) */
991 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 8;
992 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
993 memdev
->header
.length
= sizeof(*memdev
);
994 memdev
->device_handle
= handle
[2];
995 memdev
->physical_id
= 2;
996 memdev
->region_id
= 0;
997 memdev
->range_index
= 4+1;
998 memdev
->region_index
= 2+1;
999 memdev
->region_size
= 0;
1000 memdev
->region_offset
= 0;
1001 memdev
->address
= 0;
1002 memdev
->interleave_index
= 0;
1003 memdev
->interleave_ways
= 1;
1005 /* mem-region9 (spa/dcr3, dimm3) */
1006 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 9;
1007 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1008 memdev
->header
.length
= sizeof(*memdev
);
1009 memdev
->device_handle
= handle
[3];
1010 memdev
->physical_id
= 3;
1011 memdev
->region_id
= 0;
1012 memdev
->range_index
= 5+1;
1013 memdev
->region_index
= 3+1;
1014 memdev
->region_size
= 0;
1015 memdev
->region_offset
= 0;
1016 memdev
->address
= 0;
1017 memdev
->interleave_index
= 0;
1018 memdev
->interleave_ways
= 1;
1020 /* mem-region10 (spa/bdw0, dimm0) */
1021 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 10;
1022 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1023 memdev
->header
.length
= sizeof(*memdev
);
1024 memdev
->device_handle
= handle
[0];
1025 memdev
->physical_id
= 0;
1026 memdev
->region_id
= 0;
1027 memdev
->range_index
= 6+1;
1028 memdev
->region_index
= 0+1;
1029 memdev
->region_size
= 0;
1030 memdev
->region_offset
= 0;
1031 memdev
->address
= 0;
1032 memdev
->interleave_index
= 0;
1033 memdev
->interleave_ways
= 1;
1035 /* mem-region11 (spa/bdw1, dimm1) */
1036 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 11;
1037 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1038 memdev
->header
.length
= sizeof(*memdev
);
1039 memdev
->device_handle
= handle
[1];
1040 memdev
->physical_id
= 1;
1041 memdev
->region_id
= 0;
1042 memdev
->range_index
= 7+1;
1043 memdev
->region_index
= 1+1;
1044 memdev
->region_size
= 0;
1045 memdev
->region_offset
= 0;
1046 memdev
->address
= 0;
1047 memdev
->interleave_index
= 0;
1048 memdev
->interleave_ways
= 1;
1050 /* mem-region12 (spa/bdw2, dimm2) */
1051 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 12;
1052 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1053 memdev
->header
.length
= sizeof(*memdev
);
1054 memdev
->device_handle
= handle
[2];
1055 memdev
->physical_id
= 2;
1056 memdev
->region_id
= 0;
1057 memdev
->range_index
= 8+1;
1058 memdev
->region_index
= 2+1;
1059 memdev
->region_size
= 0;
1060 memdev
->region_offset
= 0;
1061 memdev
->address
= 0;
1062 memdev
->interleave_index
= 0;
1063 memdev
->interleave_ways
= 1;
1065 /* mem-region13 (spa/dcr3, dimm3) */
1066 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 13;
1067 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1068 memdev
->header
.length
= sizeof(*memdev
);
1069 memdev
->device_handle
= handle
[3];
1070 memdev
->physical_id
= 3;
1071 memdev
->region_id
= 0;
1072 memdev
->range_index
= 9+1;
1073 memdev
->region_index
= 3+1;
1074 memdev
->region_size
= 0;
1075 memdev
->region_offset
= 0;
1076 memdev
->address
= 0;
1077 memdev
->interleave_index
= 0;
1078 memdev
->interleave_ways
= 1;
1080 offset
= offset
+ sizeof(struct acpi_nfit_memory_map
) * 14;
1081 /* dcr-descriptor0: blk */
1082 dcr
= nfit_buf
+ offset
;
1083 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1084 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1085 dcr
->region_index
= 0+1;
1086 dcr_common_init(dcr
);
1087 dcr
->serial_number
= ~handle
[0];
1088 dcr
->code
= NFIT_FIC_BLK
;
1090 dcr
->window_size
= DCR_SIZE
;
1091 dcr
->command_offset
= 0;
1092 dcr
->command_size
= 8;
1093 dcr
->status_offset
= 8;
1094 dcr
->status_size
= 4;
1096 /* dcr-descriptor1: blk */
1097 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
);
1098 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1099 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1100 dcr
->region_index
= 1+1;
1101 dcr_common_init(dcr
);
1102 dcr
->serial_number
= ~handle
[1];
1103 dcr
->code
= NFIT_FIC_BLK
;
1105 dcr
->window_size
= DCR_SIZE
;
1106 dcr
->command_offset
= 0;
1107 dcr
->command_size
= 8;
1108 dcr
->status_offset
= 8;
1109 dcr
->status_size
= 4;
1111 /* dcr-descriptor2: blk */
1112 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
) * 2;
1113 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1114 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1115 dcr
->region_index
= 2+1;
1116 dcr_common_init(dcr
);
1117 dcr
->serial_number
= ~handle
[2];
1118 dcr
->code
= NFIT_FIC_BLK
;
1120 dcr
->window_size
= DCR_SIZE
;
1121 dcr
->command_offset
= 0;
1122 dcr
->command_size
= 8;
1123 dcr
->status_offset
= 8;
1124 dcr
->status_size
= 4;
1126 /* dcr-descriptor3: blk */
1127 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
) * 3;
1128 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1129 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1130 dcr
->region_index
= 3+1;
1131 dcr_common_init(dcr
);
1132 dcr
->serial_number
= ~handle
[3];
1133 dcr
->code
= NFIT_FIC_BLK
;
1135 dcr
->window_size
= DCR_SIZE
;
1136 dcr
->command_offset
= 0;
1137 dcr
->command_size
= 8;
1138 dcr
->status_offset
= 8;
1139 dcr
->status_size
= 4;
1141 offset
= offset
+ sizeof(struct acpi_nfit_control_region
) * 4;
1142 /* dcr-descriptor0: pmem */
1143 dcr
= nfit_buf
+ offset
;
1144 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1145 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1147 dcr
->region_index
= 4+1;
1148 dcr_common_init(dcr
);
1149 dcr
->serial_number
= ~handle
[0];
1150 dcr
->code
= NFIT_FIC_BYTEN
;
1153 /* dcr-descriptor1: pmem */
1154 dcr
= nfit_buf
+ offset
+ offsetof(struct acpi_nfit_control_region
,
1156 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1157 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1159 dcr
->region_index
= 5+1;
1160 dcr_common_init(dcr
);
1161 dcr
->serial_number
= ~handle
[1];
1162 dcr
->code
= NFIT_FIC_BYTEN
;
1165 /* dcr-descriptor2: pmem */
1166 dcr
= nfit_buf
+ offset
+ offsetof(struct acpi_nfit_control_region
,
1168 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1169 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1171 dcr
->region_index
= 6+1;
1172 dcr_common_init(dcr
);
1173 dcr
->serial_number
= ~handle
[2];
1174 dcr
->code
= NFIT_FIC_BYTEN
;
1177 /* dcr-descriptor3: pmem */
1178 dcr
= nfit_buf
+ offset
+ offsetof(struct acpi_nfit_control_region
,
1180 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1181 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1183 dcr
->region_index
= 7+1;
1184 dcr_common_init(dcr
);
1185 dcr
->serial_number
= ~handle
[3];
1186 dcr
->code
= NFIT_FIC_BYTEN
;
1189 offset
= offset
+ offsetof(struct acpi_nfit_control_region
,
1191 /* bdw0 (spa/dcr0, dimm0) */
1192 bdw
= nfit_buf
+ offset
;
1193 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1194 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1195 bdw
->region_index
= 0+1;
1198 bdw
->size
= BDW_SIZE
;
1199 bdw
->capacity
= DIMM_SIZE
;
1200 bdw
->start_address
= 0;
1202 /* bdw1 (spa/dcr1, dimm1) */
1203 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
);
1204 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1205 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1206 bdw
->region_index
= 1+1;
1209 bdw
->size
= BDW_SIZE
;
1210 bdw
->capacity
= DIMM_SIZE
;
1211 bdw
->start_address
= 0;
1213 /* bdw2 (spa/dcr2, dimm2) */
1214 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
) * 2;
1215 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1216 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1217 bdw
->region_index
= 2+1;
1220 bdw
->size
= BDW_SIZE
;
1221 bdw
->capacity
= DIMM_SIZE
;
1222 bdw
->start_address
= 0;
1224 /* bdw3 (spa/dcr3, dimm3) */
1225 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
) * 3;
1226 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1227 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1228 bdw
->region_index
= 3+1;
1231 bdw
->size
= BDW_SIZE
;
1232 bdw
->capacity
= DIMM_SIZE
;
1233 bdw
->start_address
= 0;
1235 offset
= offset
+ sizeof(struct acpi_nfit_data_region
) * 4;
1236 /* flush0 (dimm0) */
1237 flush
= nfit_buf
+ offset
;
1238 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1239 flush
->header
.length
= flush_hint_size
;
1240 flush
->device_handle
= handle
[0];
1241 flush
->hint_count
= NUM_HINTS
;
1242 for (i
= 0; i
< NUM_HINTS
; i
++)
1243 flush
->hint_address
[i
] = t
->flush_dma
[0] + i
* sizeof(u64
);
1245 /* flush1 (dimm1) */
1246 flush
= nfit_buf
+ offset
+ flush_hint_size
* 1;
1247 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1248 flush
->header
.length
= flush_hint_size
;
1249 flush
->device_handle
= handle
[1];
1250 flush
->hint_count
= NUM_HINTS
;
1251 for (i
= 0; i
< NUM_HINTS
; i
++)
1252 flush
->hint_address
[i
] = t
->flush_dma
[1] + i
* sizeof(u64
);
1254 /* flush2 (dimm2) */
1255 flush
= nfit_buf
+ offset
+ flush_hint_size
* 2;
1256 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1257 flush
->header
.length
= flush_hint_size
;
1258 flush
->device_handle
= handle
[2];
1259 flush
->hint_count
= NUM_HINTS
;
1260 for (i
= 0; i
< NUM_HINTS
; i
++)
1261 flush
->hint_address
[i
] = t
->flush_dma
[2] + i
* sizeof(u64
);
1263 /* flush3 (dimm3) */
1264 flush
= nfit_buf
+ offset
+ flush_hint_size
* 3;
1265 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1266 flush
->header
.length
= flush_hint_size
;
1267 flush
->device_handle
= handle
[3];
1268 flush
->hint_count
= NUM_HINTS
;
1269 for (i
= 0; i
< NUM_HINTS
; i
++)
1270 flush
->hint_address
[i
] = t
->flush_dma
[3] + i
* sizeof(u64
);
1272 if (t
->setup_hotplug
) {
1273 offset
= offset
+ flush_hint_size
* 4;
1274 /* dcr-descriptor4: blk */
1275 dcr
= nfit_buf
+ offset
;
1276 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1277 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1278 dcr
->region_index
= 8+1;
1279 dcr_common_init(dcr
);
1280 dcr
->serial_number
= ~handle
[4];
1281 dcr
->code
= NFIT_FIC_BLK
;
1283 dcr
->window_size
= DCR_SIZE
;
1284 dcr
->command_offset
= 0;
1285 dcr
->command_size
= 8;
1286 dcr
->status_offset
= 8;
1287 dcr
->status_size
= 4;
1289 offset
= offset
+ sizeof(struct acpi_nfit_control_region
);
1290 /* dcr-descriptor4: pmem */
1291 dcr
= nfit_buf
+ offset
;
1292 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1293 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1295 dcr
->region_index
= 9+1;
1296 dcr_common_init(dcr
);
1297 dcr
->serial_number
= ~handle
[4];
1298 dcr
->code
= NFIT_FIC_BYTEN
;
1301 offset
= offset
+ offsetof(struct acpi_nfit_control_region
,
1303 /* bdw4 (spa/dcr4, dimm4) */
1304 bdw
= nfit_buf
+ offset
;
1305 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1306 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1307 bdw
->region_index
= 8+1;
1310 bdw
->size
= BDW_SIZE
;
1311 bdw
->capacity
= DIMM_SIZE
;
1312 bdw
->start_address
= 0;
1314 offset
= offset
+ sizeof(struct acpi_nfit_data_region
);
1315 /* spa10 (dcr4) dimm4 */
1316 spa
= nfit_buf
+ offset
;
1317 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1318 spa
->header
.length
= sizeof(*spa
);
1319 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
1320 spa
->range_index
= 10+1;
1321 spa
->address
= t
->dcr_dma
[4];
1322 spa
->length
= DCR_SIZE
;
1325 * spa11 (single-dimm interleave for hotplug, note storage
1326 * does not actually alias the related block-data-window
1329 spa
= nfit_buf
+ offset
+ sizeof(*spa
);
1330 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1331 spa
->header
.length
= sizeof(*spa
);
1332 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
1333 spa
->range_index
= 11+1;
1334 spa
->address
= t
->spa_set_dma
[2];
1335 spa
->length
= SPA0_SIZE
;
1337 /* spa12 (bdw for dcr4) dimm4 */
1338 spa
= nfit_buf
+ offset
+ sizeof(*spa
) * 2;
1339 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1340 spa
->header
.length
= sizeof(*spa
);
1341 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
1342 spa
->range_index
= 12+1;
1343 spa
->address
= t
->dimm_dma
[4];
1344 spa
->length
= DIMM_SIZE
;
1346 offset
= offset
+ sizeof(*spa
) * 3;
1347 /* mem-region14 (spa/dcr4, dimm4) */
1348 memdev
= nfit_buf
+ offset
;
1349 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1350 memdev
->header
.length
= sizeof(*memdev
);
1351 memdev
->device_handle
= handle
[4];
1352 memdev
->physical_id
= 4;
1353 memdev
->region_id
= 0;
1354 memdev
->range_index
= 10+1;
1355 memdev
->region_index
= 8+1;
1356 memdev
->region_size
= 0;
1357 memdev
->region_offset
= 0;
1358 memdev
->address
= 0;
1359 memdev
->interleave_index
= 0;
1360 memdev
->interleave_ways
= 1;
1362 /* mem-region15 (spa0, dimm4) */
1363 memdev
= nfit_buf
+ offset
+
1364 sizeof(struct acpi_nfit_memory_map
);
1365 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1366 memdev
->header
.length
= sizeof(*memdev
);
1367 memdev
->device_handle
= handle
[4];
1368 memdev
->physical_id
= 4;
1369 memdev
->region_id
= 0;
1370 memdev
->range_index
= 11+1;
1371 memdev
->region_index
= 9+1;
1372 memdev
->region_size
= SPA0_SIZE
;
1373 memdev
->region_offset
= t
->spa_set_dma
[2];
1374 memdev
->address
= 0;
1375 memdev
->interleave_index
= 0;
1376 memdev
->interleave_ways
= 1;
1378 /* mem-region16 (spa/bdw4, dimm4) */
1379 memdev
= nfit_buf
+ offset
+
1380 sizeof(struct acpi_nfit_memory_map
) * 2;
1381 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1382 memdev
->header
.length
= sizeof(*memdev
);
1383 memdev
->device_handle
= handle
[4];
1384 memdev
->physical_id
= 4;
1385 memdev
->region_id
= 0;
1386 memdev
->range_index
= 12+1;
1387 memdev
->region_index
= 8+1;
1388 memdev
->region_size
= 0;
1389 memdev
->region_offset
= 0;
1390 memdev
->address
= 0;
1391 memdev
->interleave_index
= 0;
1392 memdev
->interleave_ways
= 1;
1394 offset
= offset
+ sizeof(struct acpi_nfit_memory_map
) * 3;
1395 /* flush3 (dimm4) */
1396 flush
= nfit_buf
+ offset
;
1397 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1398 flush
->header
.length
= flush_hint_size
;
1399 flush
->device_handle
= handle
[4];
1400 flush
->hint_count
= NUM_HINTS
;
1401 for (i
= 0; i
< NUM_HINTS
; i
++)
1402 flush
->hint_address
[i
] = t
->flush_dma
[4]
1406 post_ars_status(&t
->ars_state
, t
->spa_set_dma
[0], SPA0_SIZE
);
1408 acpi_desc
= &t
->acpi_desc
;
1409 set_bit(ND_CMD_GET_CONFIG_SIZE
, &acpi_desc
->dimm_cmd_force_en
);
1410 set_bit(ND_CMD_GET_CONFIG_DATA
, &acpi_desc
->dimm_cmd_force_en
);
1411 set_bit(ND_CMD_SET_CONFIG_DATA
, &acpi_desc
->dimm_cmd_force_en
);
1412 set_bit(ND_CMD_SMART
, &acpi_desc
->dimm_cmd_force_en
);
1413 set_bit(ND_CMD_ARS_CAP
, &acpi_desc
->bus_cmd_force_en
);
1414 set_bit(ND_CMD_ARS_START
, &acpi_desc
->bus_cmd_force_en
);
1415 set_bit(ND_CMD_ARS_STATUS
, &acpi_desc
->bus_cmd_force_en
);
1416 set_bit(ND_CMD_CLEAR_ERROR
, &acpi_desc
->bus_cmd_force_en
);
1417 set_bit(ND_CMD_SMART_THRESHOLD
, &acpi_desc
->dimm_cmd_force_en
);
1420 static void nfit_test1_setup(struct nfit_test
*t
)
1423 void *nfit_buf
= t
->nfit_buf
;
1424 struct acpi_nfit_memory_map
*memdev
;
1425 struct acpi_nfit_control_region
*dcr
;
1426 struct acpi_nfit_system_address
*spa
;
1427 struct acpi_nfit_desc
*acpi_desc
;
1430 /* spa0 (flat range with no bdw aliasing) */
1431 spa
= nfit_buf
+ offset
;
1432 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1433 spa
->header
.length
= sizeof(*spa
);
1434 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
1435 spa
->range_index
= 0+1;
1436 spa
->address
= t
->spa_set_dma
[0];
1437 spa
->length
= SPA2_SIZE
;
1439 /* virtual cd region */
1440 spa
= nfit_buf
+ sizeof(*spa
);
1441 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1442 spa
->header
.length
= sizeof(*spa
);
1443 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_VCD
), 16);
1444 spa
->range_index
= 0;
1445 spa
->address
= t
->spa_set_dma
[1];
1446 spa
->length
= SPA_VCD_SIZE
;
1448 offset
+= sizeof(*spa
) * 2;
1449 /* mem-region0 (spa0, dimm0) */
1450 memdev
= nfit_buf
+ offset
;
1451 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1452 memdev
->header
.length
= sizeof(*memdev
);
1453 memdev
->device_handle
= 0;
1454 memdev
->physical_id
= 0;
1455 memdev
->region_id
= 0;
1456 memdev
->range_index
= 0+1;
1457 memdev
->region_index
= 0+1;
1458 memdev
->region_size
= SPA2_SIZE
;
1459 memdev
->region_offset
= 0;
1460 memdev
->address
= 0;
1461 memdev
->interleave_index
= 0;
1462 memdev
->interleave_ways
= 1;
1463 memdev
->flags
= ACPI_NFIT_MEM_SAVE_FAILED
| ACPI_NFIT_MEM_RESTORE_FAILED
1464 | ACPI_NFIT_MEM_FLUSH_FAILED
| ACPI_NFIT_MEM_HEALTH_OBSERVED
1465 | ACPI_NFIT_MEM_NOT_ARMED
;
1467 offset
+= sizeof(*memdev
);
1468 /* dcr-descriptor0 */
1469 dcr
= nfit_buf
+ offset
;
1470 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1471 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1473 dcr
->region_index
= 0+1;
1474 dcr_common_init(dcr
);
1475 dcr
->serial_number
= ~0;
1476 dcr
->code
= NFIT_FIC_BYTE
;
1479 post_ars_status(&t
->ars_state
, t
->spa_set_dma
[0], SPA2_SIZE
);
1481 acpi_desc
= &t
->acpi_desc
;
1482 set_bit(ND_CMD_ARS_CAP
, &acpi_desc
->bus_cmd_force_en
);
1483 set_bit(ND_CMD_ARS_START
, &acpi_desc
->bus_cmd_force_en
);
1484 set_bit(ND_CMD_ARS_STATUS
, &acpi_desc
->bus_cmd_force_en
);
1485 set_bit(ND_CMD_CLEAR_ERROR
, &acpi_desc
->bus_cmd_force_en
);
1488 static int nfit_test_blk_do_io(struct nd_blk_region
*ndbr
, resource_size_t dpa
,
1489 void *iobuf
, u64 len
, int rw
)
1491 struct nfit_blk
*nfit_blk
= ndbr
->blk_provider_data
;
1492 struct nfit_blk_mmio
*mmio
= &nfit_blk
->mmio
[BDW
];
1493 struct nd_region
*nd_region
= &ndbr
->nd_region
;
1496 lane
= nd_region_acquire_lane(nd_region
);
1498 memcpy(mmio
->addr
.base
+ dpa
, iobuf
, len
);
1500 memcpy(iobuf
, mmio
->addr
.base
+ dpa
, len
);
1502 /* give us some some coverage of the mmio_flush_range() API */
1503 mmio_flush_range(mmio
->addr
.base
+ dpa
, len
);
1505 nd_region_release_lane(nd_region
, lane
);
1510 static unsigned long nfit_ctl_handle
;
1512 union acpi_object
*result
;
1514 static union acpi_object
*nfit_test_evaluate_dsm(acpi_handle handle
,
1515 const u8
*uuid
, u64 rev
, u64 func
, union acpi_object
*argv4
)
1517 if (handle
!= &nfit_ctl_handle
)
1518 return ERR_PTR(-ENXIO
);
1523 static int setup_result(void *buf
, size_t size
)
1525 result
= kmalloc(sizeof(union acpi_object
) + size
, GFP_KERNEL
);
1528 result
->package
.type
= ACPI_TYPE_BUFFER
,
1529 result
->buffer
.pointer
= (void *) (result
+ 1);
1530 result
->buffer
.length
= size
;
1531 memcpy(result
->buffer
.pointer
, buf
, size
);
1532 memset(buf
, 0, size
);
1536 static int nfit_ctl_test(struct device
*dev
)
1539 struct nvdimm
*nvdimm
;
1540 struct acpi_device
*adev
;
1541 struct nfit_mem
*nfit_mem
;
1542 struct nd_ars_record
*record
;
1543 struct acpi_nfit_desc
*acpi_desc
;
1544 const u64 test_val
= 0x0123456789abcdefULL
;
1545 unsigned long mask
, cmd_size
, offset
;
1547 struct nd_cmd_get_config_size cfg_size
;
1548 struct nd_cmd_ars_status ars_stat
;
1549 struct nd_cmd_ars_cap ars_cap
;
1550 char buf
[sizeof(struct nd_cmd_ars_status
)
1551 + sizeof(struct nd_ars_record
)];
1554 adev
= devm_kzalloc(dev
, sizeof(*adev
), GFP_KERNEL
);
1557 *adev
= (struct acpi_device
) {
1558 .handle
= &nfit_ctl_handle
,
1560 .init_name
= "test-adev",
1564 acpi_desc
= devm_kzalloc(dev
, sizeof(*acpi_desc
), GFP_KERNEL
);
1567 *acpi_desc
= (struct acpi_nfit_desc
) {
1569 .cmd_mask
= 1UL << ND_CMD_ARS_CAP
1570 | 1UL << ND_CMD_ARS_START
1571 | 1UL << ND_CMD_ARS_STATUS
1572 | 1UL << ND_CMD_CLEAR_ERROR
,
1573 .module
= THIS_MODULE
,
1574 .provider_name
= "ACPI.NFIT",
1575 .ndctl
= acpi_nfit_ctl
,
1580 nfit_mem
= devm_kzalloc(dev
, sizeof(*nfit_mem
), GFP_KERNEL
);
1584 mask
= 1UL << ND_CMD_SMART
| 1UL << ND_CMD_SMART_THRESHOLD
1585 | 1UL << ND_CMD_DIMM_FLAGS
| 1UL << ND_CMD_GET_CONFIG_SIZE
1586 | 1UL << ND_CMD_GET_CONFIG_DATA
| 1UL << ND_CMD_SET_CONFIG_DATA
1587 | 1UL << ND_CMD_VENDOR
;
1588 *nfit_mem
= (struct nfit_mem
) {
1590 .family
= NVDIMM_FAMILY_INTEL
,
1594 nvdimm
= devm_kzalloc(dev
, sizeof(*nvdimm
), GFP_KERNEL
);
1597 *nvdimm
= (struct nvdimm
) {
1598 .provider_data
= nfit_mem
,
1601 .init_name
= "test-dimm",
1606 /* basic checkout of a typical 'get config size' command */
1607 cmd_size
= sizeof(cmds
.cfg_size
);
1608 cmds
.cfg_size
= (struct nd_cmd_get_config_size
) {
1610 .config_size
= SZ_128K
,
1613 rc
= setup_result(cmds
.buf
, cmd_size
);
1616 rc
= acpi_nfit_ctl(&acpi_desc
->nd_desc
, nvdimm
, ND_CMD_GET_CONFIG_SIZE
,
1617 cmds
.buf
, cmd_size
, &cmd_rc
);
1619 if (rc
< 0 || cmd_rc
|| cmds
.cfg_size
.status
!= 0
1620 || cmds
.cfg_size
.config_size
!= SZ_128K
1621 || cmds
.cfg_size
.max_xfer
!= SZ_4K
) {
1622 dev_dbg(dev
, "%s: failed at: %d rc: %d cmd_rc: %d\n",
1623 __func__
, __LINE__
, rc
, cmd_rc
);
1628 /* test ars_status with zero output */
1629 cmd_size
= offsetof(struct nd_cmd_ars_status
, address
);
1630 cmds
.ars_stat
= (struct nd_cmd_ars_status
) {
1633 rc
= setup_result(cmds
.buf
, cmd_size
);
1636 rc
= acpi_nfit_ctl(&acpi_desc
->nd_desc
, NULL
, ND_CMD_ARS_STATUS
,
1637 cmds
.buf
, cmd_size
, &cmd_rc
);
1639 if (rc
< 0 || cmd_rc
) {
1640 dev_dbg(dev
, "%s: failed at: %d rc: %d cmd_rc: %d\n",
1641 __func__
, __LINE__
, rc
, cmd_rc
);
1646 /* test ars_cap with benign extended status */
1647 cmd_size
= sizeof(cmds
.ars_cap
);
1648 cmds
.ars_cap
= (struct nd_cmd_ars_cap
) {
1649 .status
= ND_ARS_PERSISTENT
<< 16,
1651 offset
= offsetof(struct nd_cmd_ars_cap
, status
);
1652 rc
= setup_result(cmds
.buf
+ offset
, cmd_size
- offset
);
1655 rc
= acpi_nfit_ctl(&acpi_desc
->nd_desc
, NULL
, ND_CMD_ARS_CAP
,
1656 cmds
.buf
, cmd_size
, &cmd_rc
);
1658 if (rc
< 0 || cmd_rc
) {
1659 dev_dbg(dev
, "%s: failed at: %d rc: %d cmd_rc: %d\n",
1660 __func__
, __LINE__
, rc
, cmd_rc
);
1665 /* test ars_status with 'status' trimmed from 'out_length' */
1666 cmd_size
= sizeof(cmds
.ars_stat
) + sizeof(struct nd_ars_record
);
1667 cmds
.ars_stat
= (struct nd_cmd_ars_status
) {
1668 .out_length
= cmd_size
- 4,
1670 record
= &cmds
.ars_stat
.records
[0];
1671 *record
= (struct nd_ars_record
) {
1674 rc
= setup_result(cmds
.buf
, cmd_size
);
1677 rc
= acpi_nfit_ctl(&acpi_desc
->nd_desc
, NULL
, ND_CMD_ARS_STATUS
,
1678 cmds
.buf
, cmd_size
, &cmd_rc
);
1680 if (rc
< 0 || cmd_rc
|| record
->length
!= test_val
) {
1681 dev_dbg(dev
, "%s: failed at: %d rc: %d cmd_rc: %d\n",
1682 __func__
, __LINE__
, rc
, cmd_rc
);
1687 /* test ars_status with 'Output (Size)' including 'status' */
1688 cmd_size
= sizeof(cmds
.ars_stat
) + sizeof(struct nd_ars_record
);
1689 cmds
.ars_stat
= (struct nd_cmd_ars_status
) {
1690 .out_length
= cmd_size
,
1692 record
= &cmds
.ars_stat
.records
[0];
1693 *record
= (struct nd_ars_record
) {
1696 rc
= setup_result(cmds
.buf
, cmd_size
);
1699 rc
= acpi_nfit_ctl(&acpi_desc
->nd_desc
, NULL
, ND_CMD_ARS_STATUS
,
1700 cmds
.buf
, cmd_size
, &cmd_rc
);
1702 if (rc
< 0 || cmd_rc
|| record
->length
!= test_val
) {
1703 dev_dbg(dev
, "%s: failed at: %d rc: %d cmd_rc: %d\n",
1704 __func__
, __LINE__
, rc
, cmd_rc
);
1709 /* test extended status for get_config_size results in failure */
1710 cmd_size
= sizeof(cmds
.cfg_size
);
1711 cmds
.cfg_size
= (struct nd_cmd_get_config_size
) {
1714 rc
= setup_result(cmds
.buf
, cmd_size
);
1717 rc
= acpi_nfit_ctl(&acpi_desc
->nd_desc
, nvdimm
, ND_CMD_GET_CONFIG_SIZE
,
1718 cmds
.buf
, cmd_size
, &cmd_rc
);
1720 if (rc
< 0 || cmd_rc
>= 0) {
1721 dev_dbg(dev
, "%s: failed at: %d rc: %d cmd_rc: %d\n",
1722 __func__
, __LINE__
, rc
, cmd_rc
);
1729 static int nfit_test_probe(struct platform_device
*pdev
)
1731 struct nvdimm_bus_descriptor
*nd_desc
;
1732 struct acpi_nfit_desc
*acpi_desc
;
1733 struct device
*dev
= &pdev
->dev
;
1734 struct nfit_test
*nfit_test
;
1735 struct nfit_mem
*nfit_mem
;
1736 union acpi_object
*obj
;
1739 if (strcmp(dev_name(&pdev
->dev
), "nfit_test.0") == 0) {
1740 rc
= nfit_ctl_test(&pdev
->dev
);
1745 nfit_test
= to_nfit_test(&pdev
->dev
);
1748 if (nfit_test
->num_dcr
) {
1749 int num
= nfit_test
->num_dcr
;
1751 nfit_test
->dimm
= devm_kcalloc(dev
, num
, sizeof(void *),
1753 nfit_test
->dimm_dma
= devm_kcalloc(dev
, num
, sizeof(dma_addr_t
),
1755 nfit_test
->flush
= devm_kcalloc(dev
, num
, sizeof(void *),
1757 nfit_test
->flush_dma
= devm_kcalloc(dev
, num
, sizeof(dma_addr_t
),
1759 nfit_test
->label
= devm_kcalloc(dev
, num
, sizeof(void *),
1761 nfit_test
->label_dma
= devm_kcalloc(dev
, num
,
1762 sizeof(dma_addr_t
), GFP_KERNEL
);
1763 nfit_test
->dcr
= devm_kcalloc(dev
, num
,
1764 sizeof(struct nfit_test_dcr
*), GFP_KERNEL
);
1765 nfit_test
->dcr_dma
= devm_kcalloc(dev
, num
,
1766 sizeof(dma_addr_t
), GFP_KERNEL
);
1767 if (nfit_test
->dimm
&& nfit_test
->dimm_dma
&& nfit_test
->label
1768 && nfit_test
->label_dma
&& nfit_test
->dcr
1769 && nfit_test
->dcr_dma
&& nfit_test
->flush
1770 && nfit_test
->flush_dma
)
1776 if (nfit_test
->num_pm
) {
1777 int num
= nfit_test
->num_pm
;
1779 nfit_test
->spa_set
= devm_kcalloc(dev
, num
, sizeof(void *),
1781 nfit_test
->spa_set_dma
= devm_kcalloc(dev
, num
,
1782 sizeof(dma_addr_t
), GFP_KERNEL
);
1783 if (nfit_test
->spa_set
&& nfit_test
->spa_set_dma
)
1789 /* per-nfit specific alloc */
1790 if (nfit_test
->alloc(nfit_test
))
1793 nfit_test
->setup(nfit_test
);
1794 acpi_desc
= &nfit_test
->acpi_desc
;
1795 acpi_nfit_desc_init(acpi_desc
, &pdev
->dev
);
1796 acpi_desc
->blk_do_io
= nfit_test_blk_do_io
;
1797 nd_desc
= &acpi_desc
->nd_desc
;
1798 nd_desc
->provider_name
= NULL
;
1799 nd_desc
->module
= THIS_MODULE
;
1800 nd_desc
->ndctl
= nfit_test_ctl
;
1802 rc
= acpi_nfit_init(acpi_desc
, nfit_test
->nfit_buf
,
1803 nfit_test
->nfit_size
);
1807 if (nfit_test
->setup
!= nfit_test0_setup
)
1810 nfit_test
->setup_hotplug
= 1;
1811 nfit_test
->setup(nfit_test
);
1813 obj
= kzalloc(sizeof(*obj
), GFP_KERNEL
);
1816 obj
->type
= ACPI_TYPE_BUFFER
;
1817 obj
->buffer
.length
= nfit_test
->nfit_size
;
1818 obj
->buffer
.pointer
= nfit_test
->nfit_buf
;
1819 *(nfit_test
->_fit
) = obj
;
1820 __acpi_nfit_notify(&pdev
->dev
, nfit_test
, 0x80);
1822 /* associate dimm devices with nfit_mem data for notification testing */
1823 mutex_lock(&acpi_desc
->init_mutex
);
1824 list_for_each_entry(nfit_mem
, &acpi_desc
->dimms
, list
) {
1825 u32 nfit_handle
= __to_nfit_memdev(nfit_mem
)->device_handle
;
1828 for (i
= 0; i
< NUM_DCR
; i
++)
1829 if (nfit_handle
== handle
[i
])
1830 dev_set_drvdata(nfit_test
->dimm_dev
[i
],
1833 mutex_unlock(&acpi_desc
->init_mutex
);
1838 static int nfit_test_remove(struct platform_device
*pdev
)
1843 static void nfit_test_release(struct device
*dev
)
1845 struct nfit_test
*nfit_test
= to_nfit_test(dev
);
1850 static const struct platform_device_id nfit_test_id
[] = {
1855 static struct platform_driver nfit_test_driver
= {
1856 .probe
= nfit_test_probe
,
1857 .remove
= nfit_test_remove
,
1859 .name
= KBUILD_MODNAME
,
1861 .id_table
= nfit_test_id
,
1864 static __init
int nfit_test_init(void)
1868 nfit_test_setup(nfit_test_lookup
, nfit_test_evaluate_dsm
);
1870 nfit_test_dimm
= class_create(THIS_MODULE
, "nfit_test_dimm");
1871 if (IS_ERR(nfit_test_dimm
)) {
1872 rc
= PTR_ERR(nfit_test_dimm
);
1876 for (i
= 0; i
< NUM_NFITS
; i
++) {
1877 struct nfit_test
*nfit_test
;
1878 struct platform_device
*pdev
;
1880 nfit_test
= kzalloc(sizeof(*nfit_test
), GFP_KERNEL
);
1885 INIT_LIST_HEAD(&nfit_test
->resources
);
1888 nfit_test
->num_pm
= NUM_PM
;
1889 nfit_test
->num_dcr
= NUM_DCR
;
1890 nfit_test
->alloc
= nfit_test0_alloc
;
1891 nfit_test
->setup
= nfit_test0_setup
;
1894 nfit_test
->num_pm
= 1;
1895 nfit_test
->alloc
= nfit_test1_alloc
;
1896 nfit_test
->setup
= nfit_test1_setup
;
1902 pdev
= &nfit_test
->pdev
;
1903 pdev
->name
= KBUILD_MODNAME
;
1905 pdev
->dev
.release
= nfit_test_release
;
1906 rc
= platform_device_register(pdev
);
1908 put_device(&pdev
->dev
);
1911 get_device(&pdev
->dev
);
1913 rc
= dma_coerce_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(64));
1917 instances
[i
] = nfit_test
;
1920 rc
= platform_driver_register(&nfit_test_driver
);
1926 for (i
= 0; i
< NUM_NFITS
; i
++)
1928 platform_device_unregister(&instances
[i
]->pdev
);
1929 nfit_test_teardown();
1930 for (i
= 0; i
< NUM_NFITS
; i
++)
1932 put_device(&instances
[i
]->pdev
.dev
);
1937 static __exit
void nfit_test_exit(void)
1941 for (i
= 0; i
< NUM_NFITS
; i
++)
1942 platform_device_unregister(&instances
[i
]->pdev
);
1943 platform_driver_unregister(&nfit_test_driver
);
1944 nfit_test_teardown();
1946 for (i
= 0; i
< NUM_NFITS
; i
++)
1947 put_device(&instances
[i
]->pdev
.dev
);
1948 class_destroy(nfit_test_dimm
);
1951 module_init(nfit_test_init
);
1952 module_exit(nfit_test_exit
);
1953 MODULE_LICENSE("GPL v2");
1954 MODULE_AUTHOR("Intel Corporation");