tangled
alpha
login
or
join now
tjh.dev
/
kernel
1
fork
atom
Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1
fork
atom
overview
issues
pulls
pipelines
Merge branch 'for-4.7/libnvdimm' into libnvdimm-for-next
Dan Williams
10 years ago
2159669f
594d6d96
+158
-6
6 changed files
expand all
collapse all
unified
split
drivers
acpi
nfit.c
nfit.h
nvdimm
btt.c
bus.c
include
uapi
linux
ndctl.h
tools
testing
nvdimm
test
nfit.c
+70
-4
drivers/acpi/nfit.c
reviewed
···
658
658
if (!nfit_mem)
659
659
return -ENOMEM;
660
660
INIT_LIST_HEAD(&nfit_mem->list);
661
661
+
nfit_mem->acpi_desc = acpi_desc;
661
662
list_add(&nfit_mem->list, &acpi_desc->dimms);
662
663
}
663
664
···
842
841
}
843
842
static DEVICE_ATTR_RO(device);
844
843
844
844
+
static int num_nvdimm_formats(struct nvdimm *nvdimm)
845
845
+
{
846
846
+
struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
847
847
+
int formats = 0;
848
848
+
849
849
+
if (nfit_mem->memdev_pmem)
850
850
+
formats++;
851
851
+
if (nfit_mem->memdev_bdw)
852
852
+
formats++;
853
853
+
return formats;
854
854
+
}
855
855
+
845
856
static ssize_t format_show(struct device *dev,
846
857
struct device_attribute *attr, char *buf)
847
858
{
···
862
849
return sprintf(buf, "%#x\n", dcr->code);
863
850
}
864
851
static DEVICE_ATTR_RO(format);
852
852
+
853
853
+
static ssize_t format1_show(struct device *dev,
854
854
+
struct device_attribute *attr, char *buf)
855
855
+
{
856
856
+
u32 handle;
857
857
+
ssize_t rc = -ENXIO;
858
858
+
struct nfit_mem *nfit_mem;
859
859
+
struct nfit_memdev *nfit_memdev;
860
860
+
struct acpi_nfit_desc *acpi_desc;
861
861
+
struct nvdimm *nvdimm = to_nvdimm(dev);
862
862
+
struct acpi_nfit_control_region *dcr = to_nfit_dcr(dev);
863
863
+
864
864
+
nfit_mem = nvdimm_provider_data(nvdimm);
865
865
+
acpi_desc = nfit_mem->acpi_desc;
866
866
+
handle = to_nfit_memdev(dev)->device_handle;
867
867
+
868
868
+
/* assumes DIMMs have at most 2 published interface codes */
869
869
+
mutex_lock(&acpi_desc->init_mutex);
870
870
+
list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
871
871
+
struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev;
872
872
+
struct nfit_dcr *nfit_dcr;
873
873
+
874
874
+
if (memdev->device_handle != handle)
875
875
+
continue;
876
876
+
877
877
+
list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) {
878
878
+
if (nfit_dcr->dcr->region_index != memdev->region_index)
879
879
+
continue;
880
880
+
if (nfit_dcr->dcr->code == dcr->code)
881
881
+
continue;
882
882
+
rc = sprintf(buf, "%#x\n", nfit_dcr->dcr->code);
883
883
+
break;
884
884
+
}
885
885
+
if (rc != ENXIO)
886
886
+
break;
887
887
+
}
888
888
+
mutex_unlock(&acpi_desc->init_mutex);
889
889
+
return rc;
890
890
+
}
891
891
+
static DEVICE_ATTR_RO(format1);
892
892
+
893
893
+
static ssize_t formats_show(struct device *dev,
894
894
+
struct device_attribute *attr, char *buf)
895
895
+
{
896
896
+
struct nvdimm *nvdimm = to_nvdimm(dev);
897
897
+
898
898
+
return sprintf(buf, "%d\n", num_nvdimm_formats(nvdimm));
899
899
+
}
900
900
+
static DEVICE_ATTR_RO(formats);
865
901
866
902
static ssize_t serial_show(struct device *dev,
867
903
struct device_attribute *attr, char *buf)
···
941
879
&dev_attr_vendor.attr,
942
880
&dev_attr_device.attr,
943
881
&dev_attr_format.attr,
882
882
+
&dev_attr_formats.attr,
883
883
+
&dev_attr_format1.attr,
944
884
&dev_attr_serial.attr,
945
885
&dev_attr_rev_id.attr,
946
886
&dev_attr_flags.attr,
···
953
889
struct attribute *a, int n)
954
890
{
955
891
struct device *dev = container_of(kobj, struct device, kobj);
892
892
+
struct nvdimm *nvdimm = to_nvdimm(dev);
956
893
957
957
-
if (to_nfit_dcr(dev))
958
958
-
return a->mode;
959
959
-
else
894
894
+
if (!to_nfit_dcr(dev))
960
895
return 0;
896
896
+
if (a == &dev_attr_format1.attr && num_nvdimm_formats(nvdimm) <= 1)
897
897
+
return 0;
898
898
+
return a->mode;
961
899
}
962
900
963
901
static struct attribute_group acpi_nfit_dimm_attribute_group = {
···
2375
2309
acpi_size sz;
2376
2310
int rc;
2377
2311
2378
2378
-
status = acpi_get_table_with_size("NFIT", 0, &tbl, &sz);
2312
2312
+
status = acpi_get_table_with_size(ACPI_SIG_NFIT, 0, &tbl, &sz);
2379
2313
if (ACPI_FAILURE(status)) {
2380
2314
/* This is ok, we could have an nvdimm hotplugged later */
2381
2315
dev_dbg(dev, "failed to find NFIT at startup\n");
+1
drivers/acpi/nfit.h
reviewed
···
109
109
struct nfit_flush *nfit_flush;
110
110
struct list_head list;
111
111
struct acpi_device *adev;
112
112
+
struct acpi_nfit_desc *acpi_desc;
112
113
unsigned long dsm_mask;
113
114
};
114
115
+5
-1
drivers/nvdimm/btt.c
reviewed
···
1383
1383
struct btt *btt;
1384
1384
size_t rawsize;
1385
1385
1386
1386
-
if (!nd_btt->uuid || !nd_btt->ndns || !nd_btt->lbasize)
1386
1386
+
if (!nd_btt->uuid || !nd_btt->ndns || !nd_btt->lbasize) {
1387
1387
+
dev_dbg(&nd_btt->dev, "incomplete btt configuration\n");
1387
1388
return -ENODEV;
1389
1389
+
}
1388
1390
1389
1391
rawsize = nvdimm_namespace_capacity(ndns) - SZ_4K;
1390
1392
if (rawsize < ARENA_MIN_SIZE) {
1393
1393
+
dev_dbg(&nd_btt->dev, "%s must be at least %ld bytes\n",
1394
1394
+
dev_name(&ndns->dev), ARENA_MIN_SIZE + SZ_4K);
1391
1395
return -ENXIO;
1392
1396
}
1393
1397
nd_region = to_nd_region(nd_btt->dev.parent);
+3
drivers/nvdimm/bus.c
reviewed
···
787
787
{
788
788
int rc;
789
789
790
790
+
BUILD_BUG_ON(sizeof(struct nd_smart_payload) != 128);
791
791
+
BUILD_BUG_ON(sizeof(struct nd_smart_threshold_payload) != 8);
792
792
+
790
793
rc = bus_register(&nvdimm_bus_type);
791
794
if (rc)
792
795
return rc;
+35
-1
include/uapi/linux/ndctl.h
reviewed
···
1
1
/*
2
2
-
* Copyright (c) 2014-2015, Intel Corporation.
2
2
+
* Copyright (c) 2014-2016, Intel Corporation.
3
3
*
4
4
* This program is free software; you can redistribute it and/or modify it
5
5
* under the terms and conditions of the GNU Lesser General Public License,
···
20
20
__u8 data[128];
21
21
} __packed;
22
22
23
23
+
#define ND_SMART_HEALTH_VALID (1 << 0)
24
24
+
#define ND_SMART_TEMP_VALID (1 << 1)
25
25
+
#define ND_SMART_SPARES_VALID (1 << 2)
26
26
+
#define ND_SMART_ALARM_VALID (1 << 3)
27
27
+
#define ND_SMART_USED_VALID (1 << 4)
28
28
+
#define ND_SMART_SHUTDOWN_VALID (1 << 5)
29
29
+
#define ND_SMART_VENDOR_VALID (1 << 6)
30
30
+
#define ND_SMART_TEMP_TRIP (1 << 0)
31
31
+
#define ND_SMART_SPARE_TRIP (1 << 1)
32
32
+
#define ND_SMART_NON_CRITICAL_HEALTH (1 << 0)
33
33
+
#define ND_SMART_CRITICAL_HEALTH (1 << 1)
34
34
+
#define ND_SMART_FATAL_HEALTH (1 << 2)
35
35
+
36
36
+
struct nd_smart_payload {
37
37
+
__u32 flags;
38
38
+
__u8 reserved0[4];
39
39
+
__u8 health;
40
40
+
__u16 temperature;
41
41
+
__u8 spares;
42
42
+
__u8 alarm_flags;
43
43
+
__u8 life_used;
44
44
+
__u8 shutdown_state;
45
45
+
__u8 reserved1;
46
46
+
__u32 vendor_size;
47
47
+
__u8 vendor_data[108];
48
48
+
} __packed;
49
49
+
23
50
struct nd_cmd_smart_threshold {
24
51
__u32 status;
25
52
__u8 data[8];
53
53
+
} __packed;
54
54
+
55
55
+
struct nd_smart_threshold_payload {
56
56
+
__u16 alarm_control;
57
57
+
__u16 temperature;
58
58
+
__u8 spares;
59
59
+
__u8 reserved[3];
26
60
} __packed;
27
61
28
62
struct nd_cmd_dimm_flags {
+44
tools/testing/nvdimm/test/nfit.c
reviewed
···
330
330
return 0;
331
331
}
332
332
333
333
+
static int nfit_test_cmd_smart(struct nd_cmd_smart *smart, unsigned int buf_len)
334
334
+
{
335
335
+
static const struct nd_smart_payload smart_data = {
336
336
+
.flags = ND_SMART_HEALTH_VALID | ND_SMART_TEMP_VALID
337
337
+
| ND_SMART_SPARES_VALID | ND_SMART_ALARM_VALID
338
338
+
| ND_SMART_USED_VALID | ND_SMART_SHUTDOWN_VALID,
339
339
+
.health = ND_SMART_NON_CRITICAL_HEALTH,
340
340
+
.temperature = 23 * 16,
341
341
+
.spares = 75,
342
342
+
.alarm_flags = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
343
343
+
.life_used = 5,
344
344
+
.shutdown_state = 0,
345
345
+
.vendor_size = 0,
346
346
+
};
347
347
+
348
348
+
if (buf_len < sizeof(*smart))
349
349
+
return -EINVAL;
350
350
+
memcpy(smart->data, &smart_data, sizeof(smart_data));
351
351
+
return 0;
352
352
+
}
353
353
+
354
354
+
static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold *smart_t,
355
355
+
unsigned int buf_len)
356
356
+
{
357
357
+
static const struct nd_smart_threshold_payload smart_t_data = {
358
358
+
.alarm_control = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
359
359
+
.temperature = 40 * 16,
360
360
+
.spares = 5,
361
361
+
};
362
362
+
363
363
+
if (buf_len < sizeof(*smart_t))
364
364
+
return -EINVAL;
365
365
+
memcpy(smart_t->data, &smart_t_data, sizeof(smart_t_data));
366
366
+
return 0;
367
367
+
}
368
368
+
333
369
static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
334
370
struct nvdimm *nvdimm, unsigned int cmd, void *buf,
335
371
unsigned int buf_len, int *cmd_rc)
···
403
367
case ND_CMD_SET_CONFIG_DATA:
404
368
rc = nfit_test_cmd_set_config_data(buf, buf_len,
405
369
t->label[i]);
370
370
+
break;
371
371
+
case ND_CMD_SMART:
372
372
+
rc = nfit_test_cmd_smart(buf, buf_len);
373
373
+
break;
374
374
+
case ND_CMD_SMART_THRESHOLD:
375
375
+
rc = nfit_test_cmd_smart_threshold(buf, buf_len);
406
376
break;
407
377
default:
408
378
return -ENOTTY;
···
1296
1254
set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_dsm_force_en);
1297
1255
set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en);
1298
1256
set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en);
1257
1257
+
set_bit(ND_CMD_SMART, &acpi_desc->dimm_dsm_force_en);
1299
1258
set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en);
1300
1259
set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en);
1301
1260
set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en);
1302
1261
set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_dsm_force_en);
1262
1262
+
set_bit(ND_CMD_SMART_THRESHOLD, &acpi_desc->dimm_dsm_force_en);
1303
1263
}
1304
1264
1305
1265
static void nfit_test1_setup(struct nfit_test *t)