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 #include <linux/list_sort.h>
14 #include <linux/libnvdimm.h>
15 #include <linux/module.h>
16 #include <linux/ndctl.h>
17 #include <linux/list.h>
18 #include <linux/acpi.h>
19 #include <linux/sort.h>
22 static bool force_enable_dimms
;
23 module_param(force_enable_dimms
, bool, S_IRUGO
|S_IWUSR
);
24 MODULE_PARM_DESC(force_enable_dimms
, "Ignore _STA (ACPI DIMM device) status");
26 static u8 nfit_uuid
[NFIT_UUID_MAX
][16];
28 static const u8
*to_nfit_uuid(enum nfit_uuids id
)
33 static struct acpi_nfit_desc
*to_acpi_nfit_desc(
34 struct nvdimm_bus_descriptor
*nd_desc
)
36 return container_of(nd_desc
, struct acpi_nfit_desc
, nd_desc
);
39 static struct acpi_device
*to_acpi_dev(struct acpi_nfit_desc
*acpi_desc
)
41 struct nvdimm_bus_descriptor
*nd_desc
= &acpi_desc
->nd_desc
;
44 * If provider == 'ACPI.NFIT' we can assume 'dev' is a struct
47 if (!nd_desc
->provider_name
48 || strcmp(nd_desc
->provider_name
, "ACPI.NFIT") != 0)
51 return to_acpi_device(acpi_desc
->dev
);
54 static int acpi_nfit_ctl(struct nvdimm_bus_descriptor
*nd_desc
,
55 struct nvdimm
*nvdimm
, unsigned int cmd
, void *buf
,
58 struct acpi_nfit_desc
*acpi_desc
= to_acpi_nfit_desc(nd_desc
);
59 const struct nd_cmd_desc
*desc
= NULL
;
60 union acpi_object in_obj
, in_buf
, *out_obj
;
61 struct device
*dev
= acpi_desc
->dev
;
62 const char *cmd_name
, *dimm_name
;
63 unsigned long dsm_mask
;
70 struct nfit_mem
*nfit_mem
= nvdimm_provider_data(nvdimm
);
71 struct acpi_device
*adev
= nfit_mem
->adev
;
75 dimm_name
= dev_name(&adev
->dev
);
76 cmd_name
= nvdimm_cmd_name(cmd
);
77 dsm_mask
= nfit_mem
->dsm_mask
;
78 desc
= nd_cmd_dimm_desc(cmd
);
79 uuid
= to_nfit_uuid(NFIT_DEV_DIMM
);
80 handle
= adev
->handle
;
82 struct acpi_device
*adev
= to_acpi_dev(acpi_desc
);
84 cmd_name
= nvdimm_bus_cmd_name(cmd
);
85 dsm_mask
= nd_desc
->dsm_mask
;
86 desc
= nd_cmd_bus_desc(cmd
);
87 uuid
= to_nfit_uuid(NFIT_DEV_BUS
);
88 handle
= adev
->handle
;
92 if (!desc
|| (cmd
&& (desc
->out_num
+ desc
->in_num
== 0)))
95 if (!test_bit(cmd
, &dsm_mask
))
98 in_obj
.type
= ACPI_TYPE_PACKAGE
;
99 in_obj
.package
.count
= 1;
100 in_obj
.package
.elements
= &in_buf
;
101 in_buf
.type
= ACPI_TYPE_BUFFER
;
102 in_buf
.buffer
.pointer
= buf
;
103 in_buf
.buffer
.length
= 0;
105 /* libnvdimm has already validated the input envelope */
106 for (i
= 0; i
< desc
->in_num
; i
++)
107 in_buf
.buffer
.length
+= nd_cmd_in_size(nvdimm
, cmd
, desc
,
110 if (IS_ENABLED(CONFIG_ACPI_NFIT_DEBUG
)) {
111 dev_dbg(dev
, "%s:%s cmd: %s input length: %d\n", __func__
,
112 dimm_name
, cmd_name
, in_buf
.buffer
.length
);
113 print_hex_dump_debug(cmd_name
, DUMP_PREFIX_OFFSET
, 4,
114 4, in_buf
.buffer
.pointer
, min_t(u32
, 128,
115 in_buf
.buffer
.length
), true);
118 out_obj
= acpi_evaluate_dsm(handle
, uuid
, 1, cmd
, &in_obj
);
120 dev_dbg(dev
, "%s:%s _DSM failed cmd: %s\n", __func__
, dimm_name
,
125 if (out_obj
->package
.type
!= ACPI_TYPE_BUFFER
) {
126 dev_dbg(dev
, "%s:%s unexpected output object type cmd: %s type: %d\n",
127 __func__
, dimm_name
, cmd_name
, out_obj
->type
);
132 if (IS_ENABLED(CONFIG_ACPI_NFIT_DEBUG
)) {
133 dev_dbg(dev
, "%s:%s cmd: %s output length: %d\n", __func__
,
134 dimm_name
, cmd_name
, out_obj
->buffer
.length
);
135 print_hex_dump_debug(cmd_name
, DUMP_PREFIX_OFFSET
, 4,
136 4, out_obj
->buffer
.pointer
, min_t(u32
, 128,
137 out_obj
->buffer
.length
), true);
140 for (i
= 0, offset
= 0; i
< desc
->out_num
; i
++) {
141 u32 out_size
= nd_cmd_out_size(nvdimm
, cmd
, desc
, i
, buf
,
142 (u32
*) out_obj
->buffer
.pointer
);
144 if (offset
+ out_size
> out_obj
->buffer
.length
) {
145 dev_dbg(dev
, "%s:%s output object underflow cmd: %s field: %d\n",
146 __func__
, dimm_name
, cmd_name
, i
);
150 if (in_buf
.buffer
.length
+ offset
+ out_size
> buf_len
) {
151 dev_dbg(dev
, "%s:%s output overrun cmd: %s field: %d\n",
152 __func__
, dimm_name
, cmd_name
, i
);
156 memcpy(buf
+ in_buf
.buffer
.length
+ offset
,
157 out_obj
->buffer
.pointer
+ offset
, out_size
);
160 if (offset
+ in_buf
.buffer
.length
< buf_len
) {
163 * status valid, return the number of bytes left
164 * unfilled in the output buffer
166 rc
= buf_len
- offset
- in_buf
.buffer
.length
;
168 dev_err(dev
, "%s:%s underrun cmd: %s buf_len: %d out_len: %d\n",
169 __func__
, dimm_name
, cmd_name
, buf_len
,
182 static const char *spa_type_name(u16 type
)
184 static const char *to_name
[] = {
185 [NFIT_SPA_VOLATILE
] = "volatile",
186 [NFIT_SPA_PM
] = "pmem",
187 [NFIT_SPA_DCR
] = "dimm-control-region",
188 [NFIT_SPA_BDW
] = "block-data-window",
189 [NFIT_SPA_VDISK
] = "volatile-disk",
190 [NFIT_SPA_VCD
] = "volatile-cd",
191 [NFIT_SPA_PDISK
] = "persistent-disk",
192 [NFIT_SPA_PCD
] = "persistent-cd",
196 if (type
> NFIT_SPA_PCD
)
199 return to_name
[type
];
202 static int nfit_spa_type(struct acpi_nfit_system_address
*spa
)
206 for (i
= 0; i
< NFIT_UUID_MAX
; i
++)
207 if (memcmp(to_nfit_uuid(i
), spa
->range_guid
, 16) == 0)
212 static bool add_spa(struct acpi_nfit_desc
*acpi_desc
,
213 struct acpi_nfit_system_address
*spa
)
215 struct device
*dev
= acpi_desc
->dev
;
216 struct nfit_spa
*nfit_spa
= devm_kzalloc(dev
, sizeof(*nfit_spa
),
221 INIT_LIST_HEAD(&nfit_spa
->list
);
223 list_add_tail(&nfit_spa
->list
, &acpi_desc
->spas
);
224 dev_dbg(dev
, "%s: spa index: %d type: %s\n", __func__
,
226 spa_type_name(nfit_spa_type(spa
)));
230 static bool add_memdev(struct acpi_nfit_desc
*acpi_desc
,
231 struct acpi_nfit_memory_map
*memdev
)
233 struct device
*dev
= acpi_desc
->dev
;
234 struct nfit_memdev
*nfit_memdev
= devm_kzalloc(dev
,
235 sizeof(*nfit_memdev
), GFP_KERNEL
);
239 INIT_LIST_HEAD(&nfit_memdev
->list
);
240 nfit_memdev
->memdev
= memdev
;
241 list_add_tail(&nfit_memdev
->list
, &acpi_desc
->memdevs
);
242 dev_dbg(dev
, "%s: memdev handle: %#x spa: %d dcr: %d\n",
243 __func__
, memdev
->device_handle
, memdev
->range_index
,
244 memdev
->region_index
);
248 static bool add_dcr(struct acpi_nfit_desc
*acpi_desc
,
249 struct acpi_nfit_control_region
*dcr
)
251 struct device
*dev
= acpi_desc
->dev
;
252 struct nfit_dcr
*nfit_dcr
= devm_kzalloc(dev
, sizeof(*nfit_dcr
),
257 INIT_LIST_HEAD(&nfit_dcr
->list
);
259 list_add_tail(&nfit_dcr
->list
, &acpi_desc
->dcrs
);
260 dev_dbg(dev
, "%s: dcr index: %d windows: %d\n", __func__
,
261 dcr
->region_index
, dcr
->windows
);
265 static bool add_bdw(struct acpi_nfit_desc
*acpi_desc
,
266 struct acpi_nfit_data_region
*bdw
)
268 struct device
*dev
= acpi_desc
->dev
;
269 struct nfit_bdw
*nfit_bdw
= devm_kzalloc(dev
, sizeof(*nfit_bdw
),
274 INIT_LIST_HEAD(&nfit_bdw
->list
);
276 list_add_tail(&nfit_bdw
->list
, &acpi_desc
->bdws
);
277 dev_dbg(dev
, "%s: bdw dcr: %d windows: %d\n", __func__
,
278 bdw
->region_index
, bdw
->windows
);
282 static void *add_table(struct acpi_nfit_desc
*acpi_desc
, void *table
,
285 struct device
*dev
= acpi_desc
->dev
;
286 struct acpi_nfit_header
*hdr
;
287 void *err
= ERR_PTR(-ENOMEM
);
294 case ACPI_NFIT_TYPE_SYSTEM_ADDRESS
:
295 if (!add_spa(acpi_desc
, table
))
298 case ACPI_NFIT_TYPE_MEMORY_MAP
:
299 if (!add_memdev(acpi_desc
, table
))
302 case ACPI_NFIT_TYPE_CONTROL_REGION
:
303 if (!add_dcr(acpi_desc
, table
))
306 case ACPI_NFIT_TYPE_DATA_REGION
:
307 if (!add_bdw(acpi_desc
, table
))
311 case ACPI_NFIT_TYPE_INTERLEAVE
:
312 dev_dbg(dev
, "%s: idt\n", __func__
);
314 case ACPI_NFIT_TYPE_FLUSH_ADDRESS
:
315 dev_dbg(dev
, "%s: flush\n", __func__
);
317 case ACPI_NFIT_TYPE_SMBIOS
:
318 dev_dbg(dev
, "%s: smbios\n", __func__
);
321 dev_err(dev
, "unknown table '%d' parsing nfit\n", hdr
->type
);
325 return table
+ hdr
->length
;
328 static void nfit_mem_find_spa_bdw(struct acpi_nfit_desc
*acpi_desc
,
329 struct nfit_mem
*nfit_mem
)
331 u32 device_handle
= __to_nfit_memdev(nfit_mem
)->device_handle
;
332 u16 dcr
= nfit_mem
->dcr
->region_index
;
333 struct nfit_spa
*nfit_spa
;
335 list_for_each_entry(nfit_spa
, &acpi_desc
->spas
, list
) {
336 u16 range_index
= nfit_spa
->spa
->range_index
;
337 int type
= nfit_spa_type(nfit_spa
->spa
);
338 struct nfit_memdev
*nfit_memdev
;
340 if (type
!= NFIT_SPA_BDW
)
343 list_for_each_entry(nfit_memdev
, &acpi_desc
->memdevs
, list
) {
344 if (nfit_memdev
->memdev
->range_index
!= range_index
)
346 if (nfit_memdev
->memdev
->device_handle
!= device_handle
)
348 if (nfit_memdev
->memdev
->region_index
!= dcr
)
351 nfit_mem
->spa_bdw
= nfit_spa
->spa
;
356 dev_dbg(acpi_desc
->dev
, "SPA-BDW not found for SPA-DCR %d\n",
357 nfit_mem
->spa_dcr
->range_index
);
358 nfit_mem
->bdw
= NULL
;
361 static int nfit_mem_add(struct acpi_nfit_desc
*acpi_desc
,
362 struct nfit_mem
*nfit_mem
, struct acpi_nfit_system_address
*spa
)
364 u16 dcr
= __to_nfit_memdev(nfit_mem
)->region_index
;
365 struct nfit_dcr
*nfit_dcr
;
366 struct nfit_bdw
*nfit_bdw
;
368 list_for_each_entry(nfit_dcr
, &acpi_desc
->dcrs
, list
) {
369 if (nfit_dcr
->dcr
->region_index
!= dcr
)
371 nfit_mem
->dcr
= nfit_dcr
->dcr
;
375 if (!nfit_mem
->dcr
) {
376 dev_dbg(acpi_desc
->dev
, "SPA %d missing:%s%s\n",
377 spa
->range_index
, __to_nfit_memdev(nfit_mem
)
378 ? "" : " MEMDEV", nfit_mem
->dcr
? "" : " DCR");
383 * We've found enough to create an nvdimm, optionally
384 * find an associated BDW
386 list_add(&nfit_mem
->list
, &acpi_desc
->dimms
);
388 list_for_each_entry(nfit_bdw
, &acpi_desc
->bdws
, list
) {
389 if (nfit_bdw
->bdw
->region_index
!= dcr
)
391 nfit_mem
->bdw
= nfit_bdw
->bdw
;
398 nfit_mem_find_spa_bdw(acpi_desc
, nfit_mem
);
402 static int nfit_mem_dcr_init(struct acpi_nfit_desc
*acpi_desc
,
403 struct acpi_nfit_system_address
*spa
)
405 struct nfit_mem
*nfit_mem
, *found
;
406 struct nfit_memdev
*nfit_memdev
;
407 int type
= nfit_spa_type(spa
);
418 list_for_each_entry(nfit_memdev
, &acpi_desc
->memdevs
, list
) {
421 if (nfit_memdev
->memdev
->range_index
!= spa
->range_index
)
424 dcr
= nfit_memdev
->memdev
->region_index
;
425 list_for_each_entry(nfit_mem
, &acpi_desc
->dimms
, list
)
426 if (__to_nfit_memdev(nfit_mem
)->region_index
== dcr
) {
434 nfit_mem
= devm_kzalloc(acpi_desc
->dev
,
435 sizeof(*nfit_mem
), GFP_KERNEL
);
438 INIT_LIST_HEAD(&nfit_mem
->list
);
441 if (type
== NFIT_SPA_DCR
) {
442 /* multiple dimms may share a SPA when interleaved */
443 nfit_mem
->spa_dcr
= spa
;
444 nfit_mem
->memdev_dcr
= nfit_memdev
->memdev
;
447 * A single dimm may belong to multiple SPA-PM
448 * ranges, record at least one in addition to
451 nfit_mem
->memdev_pmem
= nfit_memdev
->memdev
;
457 rc
= nfit_mem_add(acpi_desc
, nfit_mem
, spa
);
465 static int nfit_mem_cmp(void *priv
, struct list_head
*_a
, struct list_head
*_b
)
467 struct nfit_mem
*a
= container_of(_a
, typeof(*a
), list
);
468 struct nfit_mem
*b
= container_of(_b
, typeof(*b
), list
);
469 u32 handleA
, handleB
;
471 handleA
= __to_nfit_memdev(a
)->device_handle
;
472 handleB
= __to_nfit_memdev(b
)->device_handle
;
473 if (handleA
< handleB
)
475 else if (handleA
> handleB
)
480 static int nfit_mem_init(struct acpi_nfit_desc
*acpi_desc
)
482 struct nfit_spa
*nfit_spa
;
485 * For each SPA-DCR or SPA-PMEM address range find its
486 * corresponding MEMDEV(s). From each MEMDEV find the
487 * corresponding DCR. Then, if we're operating on a SPA-DCR,
488 * try to find a SPA-BDW and a corresponding BDW that references
489 * the DCR. Throw it all into an nfit_mem object. Note, that
492 list_for_each_entry(nfit_spa
, &acpi_desc
->spas
, list
) {
495 rc
= nfit_mem_dcr_init(acpi_desc
, nfit_spa
->spa
);
500 list_sort(NULL
, &acpi_desc
->dimms
, nfit_mem_cmp
);
505 static ssize_t
revision_show(struct device
*dev
,
506 struct device_attribute
*attr
, char *buf
)
508 struct nvdimm_bus
*nvdimm_bus
= to_nvdimm_bus(dev
);
509 struct nvdimm_bus_descriptor
*nd_desc
= to_nd_desc(nvdimm_bus
);
510 struct acpi_nfit_desc
*acpi_desc
= to_acpi_desc(nd_desc
);
512 return sprintf(buf
, "%d\n", acpi_desc
->nfit
->header
.revision
);
514 static DEVICE_ATTR_RO(revision
);
516 static struct attribute
*acpi_nfit_attributes
[] = {
517 &dev_attr_revision
.attr
,
521 static struct attribute_group acpi_nfit_attribute_group
= {
523 .attrs
= acpi_nfit_attributes
,
526 static const struct attribute_group
*acpi_nfit_attribute_groups
[] = {
527 &nvdimm_bus_attribute_group
,
528 &acpi_nfit_attribute_group
,
532 static struct acpi_nfit_memory_map
*to_nfit_memdev(struct device
*dev
)
534 struct nvdimm
*nvdimm
= to_nvdimm(dev
);
535 struct nfit_mem
*nfit_mem
= nvdimm_provider_data(nvdimm
);
537 return __to_nfit_memdev(nfit_mem
);
540 static struct acpi_nfit_control_region
*to_nfit_dcr(struct device
*dev
)
542 struct nvdimm
*nvdimm
= to_nvdimm(dev
);
543 struct nfit_mem
*nfit_mem
= nvdimm_provider_data(nvdimm
);
545 return nfit_mem
->dcr
;
548 static ssize_t
handle_show(struct device
*dev
,
549 struct device_attribute
*attr
, char *buf
)
551 struct acpi_nfit_memory_map
*memdev
= to_nfit_memdev(dev
);
553 return sprintf(buf
, "%#x\n", memdev
->device_handle
);
555 static DEVICE_ATTR_RO(handle
);
557 static ssize_t
phys_id_show(struct device
*dev
,
558 struct device_attribute
*attr
, char *buf
)
560 struct acpi_nfit_memory_map
*memdev
= to_nfit_memdev(dev
);
562 return sprintf(buf
, "%#x\n", memdev
->physical_id
);
564 static DEVICE_ATTR_RO(phys_id
);
566 static ssize_t
vendor_show(struct device
*dev
,
567 struct device_attribute
*attr
, char *buf
)
569 struct acpi_nfit_control_region
*dcr
= to_nfit_dcr(dev
);
571 return sprintf(buf
, "%#x\n", dcr
->vendor_id
);
573 static DEVICE_ATTR_RO(vendor
);
575 static ssize_t
rev_id_show(struct device
*dev
,
576 struct device_attribute
*attr
, char *buf
)
578 struct acpi_nfit_control_region
*dcr
= to_nfit_dcr(dev
);
580 return sprintf(buf
, "%#x\n", dcr
->revision_id
);
582 static DEVICE_ATTR_RO(rev_id
);
584 static ssize_t
device_show(struct device
*dev
,
585 struct device_attribute
*attr
, char *buf
)
587 struct acpi_nfit_control_region
*dcr
= to_nfit_dcr(dev
);
589 return sprintf(buf
, "%#x\n", dcr
->device_id
);
591 static DEVICE_ATTR_RO(device
);
593 static ssize_t
format_show(struct device
*dev
,
594 struct device_attribute
*attr
, char *buf
)
596 struct acpi_nfit_control_region
*dcr
= to_nfit_dcr(dev
);
598 return sprintf(buf
, "%#x\n", dcr
->code
);
600 static DEVICE_ATTR_RO(format
);
602 static ssize_t
serial_show(struct device
*dev
,
603 struct device_attribute
*attr
, char *buf
)
605 struct acpi_nfit_control_region
*dcr
= to_nfit_dcr(dev
);
607 return sprintf(buf
, "%#x\n", dcr
->serial_number
);
609 static DEVICE_ATTR_RO(serial
);
611 static struct attribute
*acpi_nfit_dimm_attributes
[] = {
612 &dev_attr_handle
.attr
,
613 &dev_attr_phys_id
.attr
,
614 &dev_attr_vendor
.attr
,
615 &dev_attr_device
.attr
,
616 &dev_attr_format
.attr
,
617 &dev_attr_serial
.attr
,
618 &dev_attr_rev_id
.attr
,
622 static umode_t
acpi_nfit_dimm_attr_visible(struct kobject
*kobj
,
623 struct attribute
*a
, int n
)
625 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
627 if (to_nfit_dcr(dev
))
633 static struct attribute_group acpi_nfit_dimm_attribute_group
= {
635 .attrs
= acpi_nfit_dimm_attributes
,
636 .is_visible
= acpi_nfit_dimm_attr_visible
,
639 static const struct attribute_group
*acpi_nfit_dimm_attribute_groups
[] = {
640 &nvdimm_attribute_group
,
641 &nd_device_attribute_group
,
642 &acpi_nfit_dimm_attribute_group
,
646 static struct nvdimm
*acpi_nfit_dimm_by_handle(struct acpi_nfit_desc
*acpi_desc
,
649 struct nfit_mem
*nfit_mem
;
651 list_for_each_entry(nfit_mem
, &acpi_desc
->dimms
, list
)
652 if (__to_nfit_memdev(nfit_mem
)->device_handle
== device_handle
)
653 return nfit_mem
->nvdimm
;
658 static int acpi_nfit_add_dimm(struct acpi_nfit_desc
*acpi_desc
,
659 struct nfit_mem
*nfit_mem
, u32 device_handle
)
661 struct acpi_device
*adev
, *adev_dimm
;
662 struct device
*dev
= acpi_desc
->dev
;
663 const u8
*uuid
= to_nfit_uuid(NFIT_DEV_DIMM
);
664 unsigned long long sta
;
668 nfit_mem
->dsm_mask
= acpi_desc
->dimm_dsm_force_en
;
669 adev
= to_acpi_dev(acpi_desc
);
673 adev_dimm
= acpi_find_child_device(adev
, device_handle
, false);
674 nfit_mem
->adev
= adev_dimm
;
676 dev_err(dev
, "no ACPI.NFIT device with _ADR %#x, disabling...\n",
678 return force_enable_dimms
? 0 : -ENODEV
;
681 status
= acpi_evaluate_integer(adev_dimm
->handle
, "_STA", NULL
, &sta
);
682 if (status
== AE_NOT_FOUND
) {
683 dev_dbg(dev
, "%s missing _STA, assuming enabled...\n",
684 dev_name(&adev_dimm
->dev
));
686 } else if (ACPI_FAILURE(status
))
687 dev_err(dev
, "%s failed to retrieve_STA, disabling...\n",
688 dev_name(&adev_dimm
->dev
));
689 else if ((sta
& ACPI_STA_DEVICE_ENABLED
) == 0)
690 dev_info(dev
, "%s disabled by firmware\n",
691 dev_name(&adev_dimm
->dev
));
695 for (i
= ND_CMD_SMART
; i
<= ND_CMD_VENDOR
; i
++)
696 if (acpi_check_dsm(adev_dimm
->handle
, uuid
, 1, 1ULL << i
))
697 set_bit(i
, &nfit_mem
->dsm_mask
);
699 return force_enable_dimms
? 0 : rc
;
702 static int acpi_nfit_register_dimms(struct acpi_nfit_desc
*acpi_desc
)
704 struct nfit_mem
*nfit_mem
;
707 list_for_each_entry(nfit_mem
, &acpi_desc
->dimms
, list
) {
708 struct nvdimm
*nvdimm
;
709 unsigned long flags
= 0;
713 device_handle
= __to_nfit_memdev(nfit_mem
)->device_handle
;
714 nvdimm
= acpi_nfit_dimm_by_handle(acpi_desc
, device_handle
);
717 * If for some reason we find multiple DCRs the
720 dev_err(acpi_desc
->dev
, "duplicate DCR detected: %s\n",
721 nvdimm_name(nvdimm
));
725 if (nfit_mem
->bdw
&& nfit_mem
->memdev_pmem
)
726 flags
|= NDD_ALIASING
;
728 rc
= acpi_nfit_add_dimm(acpi_desc
, nfit_mem
, device_handle
);
732 nvdimm
= nvdimm_create(acpi_desc
->nvdimm_bus
, nfit_mem
,
733 acpi_nfit_dimm_attribute_groups
,
734 flags
, &nfit_mem
->dsm_mask
);
738 nfit_mem
->nvdimm
= nvdimm
;
742 return nvdimm_bus_check_dimm_count(acpi_desc
->nvdimm_bus
, dimm_count
);
745 static void acpi_nfit_init_dsms(struct acpi_nfit_desc
*acpi_desc
)
747 struct nvdimm_bus_descriptor
*nd_desc
= &acpi_desc
->nd_desc
;
748 const u8
*uuid
= to_nfit_uuid(NFIT_DEV_BUS
);
749 struct acpi_device
*adev
;
752 adev
= to_acpi_dev(acpi_desc
);
756 for (i
= ND_CMD_ARS_CAP
; i
<= ND_CMD_ARS_STATUS
; i
++)
757 if (acpi_check_dsm(adev
->handle
, uuid
, 1, 1ULL << i
))
758 set_bit(i
, &nd_desc
->dsm_mask
);
761 static ssize_t
range_index_show(struct device
*dev
,
762 struct device_attribute
*attr
, char *buf
)
764 struct nd_region
*nd_region
= to_nd_region(dev
);
765 struct nfit_spa
*nfit_spa
= nd_region_provider_data(nd_region
);
767 return sprintf(buf
, "%d\n", nfit_spa
->spa
->range_index
);
769 static DEVICE_ATTR_RO(range_index
);
771 static struct attribute
*acpi_nfit_region_attributes
[] = {
772 &dev_attr_range_index
.attr
,
776 static struct attribute_group acpi_nfit_region_attribute_group
= {
778 .attrs
= acpi_nfit_region_attributes
,
781 static const struct attribute_group
*acpi_nfit_region_attribute_groups
[] = {
782 &nd_region_attribute_group
,
783 &nd_mapping_attribute_group
,
784 &nd_device_attribute_group
,
785 &acpi_nfit_region_attribute_group
,
789 /* enough info to uniquely specify an interleave set */
790 struct nfit_set_info
{
791 struct nfit_set_info_map
{
798 static size_t sizeof_nfit_set_info(int num_mappings
)
800 return sizeof(struct nfit_set_info
)
801 + num_mappings
* sizeof(struct nfit_set_info_map
);
804 static int cmp_map(const void *m0
, const void *m1
)
806 const struct nfit_set_info_map
*map0
= m0
;
807 const struct nfit_set_info_map
*map1
= m1
;
809 return memcmp(&map0
->region_offset
, &map1
->region_offset
,
813 /* Retrieve the nth entry referencing this spa */
814 static struct acpi_nfit_memory_map
*memdev_from_spa(
815 struct acpi_nfit_desc
*acpi_desc
, u16 range_index
, int n
)
817 struct nfit_memdev
*nfit_memdev
;
819 list_for_each_entry(nfit_memdev
, &acpi_desc
->memdevs
, list
)
820 if (nfit_memdev
->memdev
->range_index
== range_index
)
822 return nfit_memdev
->memdev
;
826 static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc
*acpi_desc
,
827 struct nd_region_desc
*ndr_desc
,
828 struct acpi_nfit_system_address
*spa
)
830 int i
, spa_type
= nfit_spa_type(spa
);
831 struct device
*dev
= acpi_desc
->dev
;
832 struct nd_interleave_set
*nd_set
;
833 u16 nr
= ndr_desc
->num_mappings
;
834 struct nfit_set_info
*info
;
836 if (spa_type
== NFIT_SPA_PM
|| spa_type
== NFIT_SPA_VOLATILE
)
841 nd_set
= devm_kzalloc(dev
, sizeof(*nd_set
), GFP_KERNEL
);
845 info
= devm_kzalloc(dev
, sizeof_nfit_set_info(nr
), GFP_KERNEL
);
848 for (i
= 0; i
< nr
; i
++) {
849 struct nd_mapping
*nd_mapping
= &ndr_desc
->nd_mapping
[i
];
850 struct nfit_set_info_map
*map
= &info
->mapping
[i
];
851 struct nvdimm
*nvdimm
= nd_mapping
->nvdimm
;
852 struct nfit_mem
*nfit_mem
= nvdimm_provider_data(nvdimm
);
853 struct acpi_nfit_memory_map
*memdev
= memdev_from_spa(acpi_desc
,
854 spa
->range_index
, i
);
856 if (!memdev
|| !nfit_mem
->dcr
) {
857 dev_err(dev
, "%s: failed to find DCR\n", __func__
);
861 map
->region_offset
= memdev
->region_offset
;
862 map
->serial_number
= nfit_mem
->dcr
->serial_number
;
865 sort(&info
->mapping
[0], nr
, sizeof(struct nfit_set_info_map
),
867 nd_set
->cookie
= nd_fletcher64(info
, sizeof_nfit_set_info(nr
), 0);
868 ndr_desc
->nd_set
= nd_set
;
869 devm_kfree(dev
, info
);
874 static int acpi_nfit_init_mapping(struct acpi_nfit_desc
*acpi_desc
,
875 struct nd_mapping
*nd_mapping
, struct nd_region_desc
*ndr_desc
,
876 struct acpi_nfit_memory_map
*memdev
,
877 struct acpi_nfit_system_address
*spa
)
879 struct nvdimm
*nvdimm
= acpi_nfit_dimm_by_handle(acpi_desc
,
880 memdev
->device_handle
);
881 struct nfit_mem
*nfit_mem
;
885 dev_err(acpi_desc
->dev
, "spa%d dimm: %#x not found\n",
886 spa
->range_index
, memdev
->device_handle
);
890 nd_mapping
->nvdimm
= nvdimm
;
891 switch (nfit_spa_type(spa
)) {
893 case NFIT_SPA_VOLATILE
:
894 nd_mapping
->start
= memdev
->address
;
895 nd_mapping
->size
= memdev
->region_size
;
898 nfit_mem
= nvdimm_provider_data(nvdimm
);
899 if (!nfit_mem
|| !nfit_mem
->bdw
) {
900 dev_dbg(acpi_desc
->dev
, "spa%d %s missing bdw\n",
901 spa
->range_index
, nvdimm_name(nvdimm
));
903 nd_mapping
->size
= nfit_mem
->bdw
->capacity
;
904 nd_mapping
->start
= nfit_mem
->bdw
->start_address
;
905 ndr_desc
->num_lanes
= nfit_mem
->bdw
->windows
;
909 ndr_desc
->nd_mapping
= nd_mapping
;
910 ndr_desc
->num_mappings
= blk_valid
;
911 if (!nvdimm_blk_region_create(acpi_desc
->nvdimm_bus
, ndr_desc
))
919 static int acpi_nfit_register_region(struct acpi_nfit_desc
*acpi_desc
,
920 struct nfit_spa
*nfit_spa
)
922 static struct nd_mapping nd_mappings
[ND_MAX_MAPPINGS
];
923 struct acpi_nfit_system_address
*spa
= nfit_spa
->spa
;
924 struct nfit_memdev
*nfit_memdev
;
925 struct nd_region_desc ndr_desc
;
926 struct nvdimm_bus
*nvdimm_bus
;
930 if (spa
->range_index
== 0) {
931 dev_dbg(acpi_desc
->dev
, "%s: detected invalid spa index\n",
936 memset(&res
, 0, sizeof(res
));
937 memset(&nd_mappings
, 0, sizeof(nd_mappings
));
938 memset(&ndr_desc
, 0, sizeof(ndr_desc
));
939 res
.start
= spa
->address
;
940 res
.end
= res
.start
+ spa
->length
- 1;
942 ndr_desc
.provider_data
= nfit_spa
;
943 ndr_desc
.attr_groups
= acpi_nfit_region_attribute_groups
;
944 list_for_each_entry(nfit_memdev
, &acpi_desc
->memdevs
, list
) {
945 struct acpi_nfit_memory_map
*memdev
= nfit_memdev
->memdev
;
946 struct nd_mapping
*nd_mapping
;
948 if (memdev
->range_index
!= spa
->range_index
)
950 if (count
>= ND_MAX_MAPPINGS
) {
951 dev_err(acpi_desc
->dev
, "spa%d exceeds max mappings %d\n",
952 spa
->range_index
, ND_MAX_MAPPINGS
);
955 nd_mapping
= &nd_mappings
[count
++];
956 rc
= acpi_nfit_init_mapping(acpi_desc
, nd_mapping
, &ndr_desc
,
962 ndr_desc
.nd_mapping
= nd_mappings
;
963 ndr_desc
.num_mappings
= count
;
964 rc
= acpi_nfit_init_interleave_set(acpi_desc
, &ndr_desc
, spa
);
968 nvdimm_bus
= acpi_desc
->nvdimm_bus
;
969 if (nfit_spa_type(spa
) == NFIT_SPA_PM
) {
970 if (!nvdimm_pmem_region_create(nvdimm_bus
, &ndr_desc
))
972 } else if (nfit_spa_type(spa
) == NFIT_SPA_VOLATILE
) {
973 if (!nvdimm_volatile_region_create(nvdimm_bus
, &ndr_desc
))
979 static int acpi_nfit_register_regions(struct acpi_nfit_desc
*acpi_desc
)
981 struct nfit_spa
*nfit_spa
;
983 list_for_each_entry(nfit_spa
, &acpi_desc
->spas
, list
) {
984 int rc
= acpi_nfit_register_region(acpi_desc
, nfit_spa
);
992 static int acpi_nfit_init(struct acpi_nfit_desc
*acpi_desc
, acpi_size sz
)
994 struct device
*dev
= acpi_desc
->dev
;
999 INIT_LIST_HEAD(&acpi_desc
->spas
);
1000 INIT_LIST_HEAD(&acpi_desc
->dcrs
);
1001 INIT_LIST_HEAD(&acpi_desc
->bdws
);
1002 INIT_LIST_HEAD(&acpi_desc
->memdevs
);
1003 INIT_LIST_HEAD(&acpi_desc
->dimms
);
1005 data
= (u8
*) acpi_desc
->nfit
;
1007 data
+= sizeof(struct acpi_table_nfit
);
1008 while (!IS_ERR_OR_NULL(data
))
1009 data
= add_table(acpi_desc
, data
, end
);
1012 dev_dbg(dev
, "%s: nfit table parsing error: %ld\n", __func__
,
1014 return PTR_ERR(data
);
1017 if (nfit_mem_init(acpi_desc
) != 0)
1020 acpi_nfit_init_dsms(acpi_desc
);
1022 rc
= acpi_nfit_register_dimms(acpi_desc
);
1026 return acpi_nfit_register_regions(acpi_desc
);
1029 static int acpi_nfit_add(struct acpi_device
*adev
)
1031 struct nvdimm_bus_descriptor
*nd_desc
;
1032 struct acpi_nfit_desc
*acpi_desc
;
1033 struct device
*dev
= &adev
->dev
;
1034 struct acpi_table_header
*tbl
;
1035 acpi_status status
= AE_OK
;
1039 status
= acpi_get_table_with_size("NFIT", 0, &tbl
, &sz
);
1040 if (ACPI_FAILURE(status
)) {
1041 dev_err(dev
, "failed to find NFIT\n");
1045 acpi_desc
= devm_kzalloc(dev
, sizeof(*acpi_desc
), GFP_KERNEL
);
1049 dev_set_drvdata(dev
, acpi_desc
);
1050 acpi_desc
->dev
= dev
;
1051 acpi_desc
->nfit
= (struct acpi_table_nfit
*) tbl
;
1052 nd_desc
= &acpi_desc
->nd_desc
;
1053 nd_desc
->provider_name
= "ACPI.NFIT";
1054 nd_desc
->ndctl
= acpi_nfit_ctl
;
1055 nd_desc
->attr_groups
= acpi_nfit_attribute_groups
;
1057 acpi_desc
->nvdimm_bus
= nvdimm_bus_register(dev
, nd_desc
);
1058 if (!acpi_desc
->nvdimm_bus
)
1061 rc
= acpi_nfit_init(acpi_desc
, sz
);
1063 nvdimm_bus_unregister(acpi_desc
->nvdimm_bus
);
1069 static int acpi_nfit_remove(struct acpi_device
*adev
)
1071 struct acpi_nfit_desc
*acpi_desc
= dev_get_drvdata(&adev
->dev
);
1073 nvdimm_bus_unregister(acpi_desc
->nvdimm_bus
);
1077 static const struct acpi_device_id acpi_nfit_ids
[] = {
1081 MODULE_DEVICE_TABLE(acpi
, acpi_nfit_ids
);
1083 static struct acpi_driver acpi_nfit_driver
= {
1084 .name
= KBUILD_MODNAME
,
1085 .ids
= acpi_nfit_ids
,
1087 .add
= acpi_nfit_add
,
1088 .remove
= acpi_nfit_remove
,
1092 static __init
int nfit_init(void)
1094 BUILD_BUG_ON(sizeof(struct acpi_table_nfit
) != 40);
1095 BUILD_BUG_ON(sizeof(struct acpi_nfit_system_address
) != 56);
1096 BUILD_BUG_ON(sizeof(struct acpi_nfit_memory_map
) != 48);
1097 BUILD_BUG_ON(sizeof(struct acpi_nfit_interleave
) != 20);
1098 BUILD_BUG_ON(sizeof(struct acpi_nfit_smbios
) != 9);
1099 BUILD_BUG_ON(sizeof(struct acpi_nfit_control_region
) != 80);
1100 BUILD_BUG_ON(sizeof(struct acpi_nfit_data_region
) != 40);
1102 acpi_str_to_uuid(UUID_VOLATILE_MEMORY
, nfit_uuid
[NFIT_SPA_VOLATILE
]);
1103 acpi_str_to_uuid(UUID_PERSISTENT_MEMORY
, nfit_uuid
[NFIT_SPA_PM
]);
1104 acpi_str_to_uuid(UUID_CONTROL_REGION
, nfit_uuid
[NFIT_SPA_DCR
]);
1105 acpi_str_to_uuid(UUID_DATA_REGION
, nfit_uuid
[NFIT_SPA_BDW
]);
1106 acpi_str_to_uuid(UUID_VOLATILE_VIRTUAL_DISK
, nfit_uuid
[NFIT_SPA_VDISK
]);
1107 acpi_str_to_uuid(UUID_VOLATILE_VIRTUAL_CD
, nfit_uuid
[NFIT_SPA_VCD
]);
1108 acpi_str_to_uuid(UUID_PERSISTENT_VIRTUAL_DISK
, nfit_uuid
[NFIT_SPA_PDISK
]);
1109 acpi_str_to_uuid(UUID_PERSISTENT_VIRTUAL_CD
, nfit_uuid
[NFIT_SPA_PCD
]);
1110 acpi_str_to_uuid(UUID_NFIT_BUS
, nfit_uuid
[NFIT_DEV_BUS
]);
1111 acpi_str_to_uuid(UUID_NFIT_DIMM
, nfit_uuid
[NFIT_DEV_DIMM
]);
1113 return acpi_bus_register_driver(&acpi_nfit_driver
);
1116 static __exit
void nfit_exit(void)
1118 acpi_bus_unregister_driver(&acpi_nfit_driver
);
1121 module_init(nfit_init
);
1122 module_exit(nfit_exit
);
1123 MODULE_LICENSE("GPL v2");
1124 MODULE_AUTHOR("Intel Corporation");