nfit.c (13a08259187c5cd3f63d98efa159ab42976d85a4) nfit.c (73606afd4603a2f6296cd44c4d2b385916565a58)
1/*
2 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but

--- 118 unchanged lines hidden (view full) ---

127static u32 handle[NUM_DCR] = {
128 [0] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 0),
129 [1] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 1),
130 [2] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 0),
131 [3] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 1),
132 [4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0),
133};
134
1/*
2 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but

--- 118 unchanged lines hidden (view full) ---

127static u32 handle[NUM_DCR] = {
128 [0] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 0),
129 [1] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 1),
130 [2] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 0),
131 [3] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 1),
132 [4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0),
133};
134
135static unsigned long dimm_fail_cmd_flags[NUM_DCR];
136
135struct nfit_test {
136 struct acpi_nfit_desc acpi_desc;
137 struct platform_device pdev;
138 struct list_head resources;
139 void *nfit_buf;
140 dma_addr_t nfit_dma;
141 size_t nfit_size;
142 int num_dcr;

--- 6 unchanged lines hidden (view full) ---

149 dma_addr_t *label_dma;
150 void **spa_set;
151 dma_addr_t *spa_set_dma;
152 struct nfit_test_dcr **dcr;
153 dma_addr_t *dcr_dma;
154 int (*alloc)(struct nfit_test *t);
155 void (*setup)(struct nfit_test *t);
156 int setup_hotplug;
137struct nfit_test {
138 struct acpi_nfit_desc acpi_desc;
139 struct platform_device pdev;
140 struct list_head resources;
141 void *nfit_buf;
142 dma_addr_t nfit_dma;
143 size_t nfit_size;
144 int num_dcr;

--- 6 unchanged lines hidden (view full) ---

151 dma_addr_t *label_dma;
152 void **spa_set;
153 dma_addr_t *spa_set_dma;
154 struct nfit_test_dcr **dcr;
155 dma_addr_t *dcr_dma;
156 int (*alloc)(struct nfit_test *t);
157 void (*setup)(struct nfit_test *t);
158 int setup_hotplug;
159 union acpi_object **_fit;
160 dma_addr_t _fit_dma;
157 struct ars_state {
158 struct nd_cmd_ars_status *ars_status;
159 unsigned long deadline;
160 spinlock_t lock;
161 } ars_state;
161 struct ars_state {
162 struct nd_cmd_ars_status *ars_status;
163 unsigned long deadline;
164 spinlock_t lock;
165 } ars_state;
166 struct device *dimm_dev[NUM_DCR];
162};
163
164static struct nfit_test *to_nfit_test(struct device *dev)
165{
166 struct platform_device *pdev = to_platform_device(dev);
167
168 return container_of(pdev, struct nfit_test, pdev);
169}

--- 236 unchanged lines hidden (view full) ---

406 /* lookup label space for the given dimm */
407 for (i = 0; i < ARRAY_SIZE(handle); i++)
408 if (__to_nfit_memdev(nfit_mem)->device_handle ==
409 handle[i])
410 break;
411 if (i >= ARRAY_SIZE(handle))
412 return -ENXIO;
413
167};
168
169static struct nfit_test *to_nfit_test(struct device *dev)
170{
171 struct platform_device *pdev = to_platform_device(dev);
172
173 return container_of(pdev, struct nfit_test, pdev);
174}

--- 236 unchanged lines hidden (view full) ---

411 /* lookup label space for the given dimm */
412 for (i = 0; i < ARRAY_SIZE(handle); i++)
413 if (__to_nfit_memdev(nfit_mem)->device_handle ==
414 handle[i])
415 break;
416 if (i >= ARRAY_SIZE(handle))
417 return -ENXIO;
418
419 if ((1 << func) & dimm_fail_cmd_flags[i])
420 return -EIO;
421
414 switch (func) {
415 case ND_CMD_GET_CONFIG_SIZE:
416 rc = nfit_test_cmd_get_config_size(buf, buf_len);
417 break;
418 case ND_CMD_GET_CONFIG_DATA:
419 rc = nfit_test_cmd_get_config_data(buf, buf_len,
420 t->label[i]);
421 break;
422 case ND_CMD_SET_CONFIG_DATA:
423 rc = nfit_test_cmd_set_config_data(buf, buf_len,
424 t->label[i]);
425 break;
426 case ND_CMD_SMART:
427 rc = nfit_test_cmd_smart(buf, buf_len);
428 break;
429 case ND_CMD_SMART_THRESHOLD:
430 rc = nfit_test_cmd_smart_threshold(buf, buf_len);
422 switch (func) {
423 case ND_CMD_GET_CONFIG_SIZE:
424 rc = nfit_test_cmd_get_config_size(buf, buf_len);
425 break;
426 case ND_CMD_GET_CONFIG_DATA:
427 rc = nfit_test_cmd_get_config_data(buf, buf_len,
428 t->label[i]);
429 break;
430 case ND_CMD_SET_CONFIG_DATA:
431 rc = nfit_test_cmd_set_config_data(buf, buf_len,
432 t->label[i]);
433 break;
434 case ND_CMD_SMART:
435 rc = nfit_test_cmd_smart(buf, buf_len);
436 break;
437 case ND_CMD_SMART_THRESHOLD:
438 rc = nfit_test_cmd_smart_threshold(buf, buf_len);
439 device_lock(&t->pdev.dev);
440 __acpi_nvdimm_notify(t->dimm_dev[i], 0x81);
441 device_unlock(&t->pdev.dev);
431 break;
432 default:
433 return -ENOTTY;
434 }
435 } else {
436 struct ars_state *ars_state = &t->ars_state;
437
438 if (!nd_desc || !test_bit(cmd, &nd_desc->cmd_mask))

--- 120 unchanged lines hidden (view full) ---

559 + sizeof(struct nd_ars_record) * NFIT_TEST_ARS_RECORDS,
560 GFP_KERNEL);
561 if (!ars_state->ars_status)
562 return -ENOMEM;
563 spin_lock_init(&ars_state->lock);
564 return 0;
565}
566
442 break;
443 default:
444 return -ENOTTY;
445 }
446 } else {
447 struct ars_state *ars_state = &t->ars_state;
448
449 if (!nd_desc || !test_bit(cmd, &nd_desc->cmd_mask))

--- 120 unchanged lines hidden (view full) ---

570 + sizeof(struct nd_ars_record) * NFIT_TEST_ARS_RECORDS,
571 GFP_KERNEL);
572 if (!ars_state->ars_status)
573 return -ENOMEM;
574 spin_lock_init(&ars_state->lock);
575 return 0;
576}
577
578static void put_dimms(void *data)
579{
580 struct device **dimm_dev = data;
581 int i;
582
583 for (i = 0; i < NUM_DCR; i++)
584 if (dimm_dev[i])
585 device_unregister(dimm_dev[i]);
586}
587
588static struct class *nfit_test_dimm;
589
590static int dimm_name_to_id(struct device *dev)
591{
592 int dimm;
593
594 if (sscanf(dev_name(dev), "test_dimm%d", &dimm) != 1
595 || dimm >= NUM_DCR || dimm < 0)
596 return -ENXIO;
597 return dimm;
598}
599
600
601static ssize_t handle_show(struct device *dev, struct device_attribute *attr,
602 char *buf)
603{
604 int dimm = dimm_name_to_id(dev);
605
606 if (dimm < 0)
607 return dimm;
608
609 return sprintf(buf, "%#x", handle[dimm]);
610}
611DEVICE_ATTR_RO(handle);
612
613static ssize_t fail_cmd_show(struct device *dev, struct device_attribute *attr,
614 char *buf)
615{
616 int dimm = dimm_name_to_id(dev);
617
618 if (dimm < 0)
619 return dimm;
620
621 return sprintf(buf, "%#lx\n", dimm_fail_cmd_flags[dimm]);
622}
623
624static ssize_t fail_cmd_store(struct device *dev, struct device_attribute *attr,
625 const char *buf, size_t size)
626{
627 int dimm = dimm_name_to_id(dev);
628 unsigned long val;
629 ssize_t rc;
630
631 if (dimm < 0)
632 return dimm;
633
634 rc = kstrtol(buf, 0, &val);
635 if (rc)
636 return rc;
637
638 dimm_fail_cmd_flags[dimm] = val;
639 return size;
640}
641static DEVICE_ATTR_RW(fail_cmd);
642
643static struct attribute *nfit_test_dimm_attributes[] = {
644 &dev_attr_fail_cmd.attr,
645 &dev_attr_handle.attr,
646 NULL,
647};
648
649static struct attribute_group nfit_test_dimm_attribute_group = {
650 .attrs = nfit_test_dimm_attributes,
651};
652
653static const struct attribute_group *nfit_test_dimm_attribute_groups[] = {
654 &nfit_test_dimm_attribute_group,
655 NULL,
656};
657
567static int nfit_test0_alloc(struct nfit_test *t)
568{
569 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA
570 + sizeof(struct acpi_nfit_memory_map) * NUM_MEM
571 + sizeof(struct acpi_nfit_control_region) * NUM_DCR
572 + offsetof(struct acpi_nfit_control_region,
573 window_size) * NUM_DCR
574 + sizeof(struct acpi_nfit_data_region) * NUM_BDW

--- 35 unchanged lines hidden (view full) ---

610 }
611
612 for (i = 0; i < NUM_DCR; i++) {
613 t->dcr[i] = test_alloc(t, LABEL_SIZE, &t->dcr_dma[i]);
614 if (!t->dcr[i])
615 return -ENOMEM;
616 }
617
658static int nfit_test0_alloc(struct nfit_test *t)
659{
660 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA
661 + sizeof(struct acpi_nfit_memory_map) * NUM_MEM
662 + sizeof(struct acpi_nfit_control_region) * NUM_DCR
663 + offsetof(struct acpi_nfit_control_region,
664 window_size) * NUM_DCR
665 + sizeof(struct acpi_nfit_data_region) * NUM_BDW

--- 35 unchanged lines hidden (view full) ---

701 }
702
703 for (i = 0; i < NUM_DCR; i++) {
704 t->dcr[i] = test_alloc(t, LABEL_SIZE, &t->dcr_dma[i]);
705 if (!t->dcr[i])
706 return -ENOMEM;
707 }
708
709 t->_fit = test_alloc(t, sizeof(union acpi_object **), &t->_fit_dma);
710 if (!t->_fit)
711 return -ENOMEM;
712
713 if (devm_add_action_or_reset(&t->pdev.dev, put_dimms, t->dimm_dev))
714 return -ENOMEM;
715 for (i = 0; i < NUM_DCR; i++) {
716 t->dimm_dev[i] = device_create_with_groups(nfit_test_dimm,
717 &t->pdev.dev, 0, NULL,
718 nfit_test_dimm_attribute_groups,
719 "test_dimm%d", i);
720 if (!t->dimm_dev[i])
721 return -ENOMEM;
722 }
723
618 return ars_state_init(&t->pdev.dev, &t->ars_state);
619}
620
621static int nfit_test1_alloc(struct nfit_test *t)
622{
623 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * 2
624 + sizeof(struct acpi_nfit_memory_map)
625 + offsetof(struct acpi_nfit_control_region, window_size);

--- 777 unchanged lines hidden (view full) ---

1403}
1404
1405static int nfit_test_probe(struct platform_device *pdev)
1406{
1407 struct nvdimm_bus_descriptor *nd_desc;
1408 struct acpi_nfit_desc *acpi_desc;
1409 struct device *dev = &pdev->dev;
1410 struct nfit_test *nfit_test;
724 return ars_state_init(&t->pdev.dev, &t->ars_state);
725}
726
727static int nfit_test1_alloc(struct nfit_test *t)
728{
729 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * 2
730 + sizeof(struct acpi_nfit_memory_map)
731 + offsetof(struct acpi_nfit_control_region, window_size);

--- 777 unchanged lines hidden (view full) ---

1509}
1510
1511static int nfit_test_probe(struct platform_device *pdev)
1512{
1513 struct nvdimm_bus_descriptor *nd_desc;
1514 struct acpi_nfit_desc *acpi_desc;
1515 struct device *dev = &pdev->dev;
1516 struct nfit_test *nfit_test;
1517 struct nfit_mem *nfit_mem;
1518 union acpi_object *obj;
1411 int rc;
1412
1413 nfit_test = to_nfit_test(&pdev->dev);
1414
1415 /* common alloc */
1416 if (nfit_test->num_dcr) {
1417 int num = nfit_test->num_dcr;
1418

--- 51 unchanged lines hidden (view full) ---

1470 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf,
1471 nfit_test->nfit_size);
1472 if (rc)
1473 return rc;
1474
1475 if (nfit_test->setup != nfit_test0_setup)
1476 return 0;
1477
1519 int rc;
1520
1521 nfit_test = to_nfit_test(&pdev->dev);
1522
1523 /* common alloc */
1524 if (nfit_test->num_dcr) {
1525 int num = nfit_test->num_dcr;
1526

--- 51 unchanged lines hidden (view full) ---

1578 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf,
1579 nfit_test->nfit_size);
1580 if (rc)
1581 return rc;
1582
1583 if (nfit_test->setup != nfit_test0_setup)
1584 return 0;
1585
1478 flush_work(&acpi_desc->work);
1479 nfit_test->setup_hotplug = 1;
1480 nfit_test->setup(nfit_test);
1481
1586 nfit_test->setup_hotplug = 1;
1587 nfit_test->setup(nfit_test);
1588
1482 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf,
1483 nfit_test->nfit_size);
1484 if (rc)
1485 return rc;
1589 obj = kzalloc(sizeof(*obj), GFP_KERNEL);
1590 if (!obj)
1591 return -ENOMEM;
1592 obj->type = ACPI_TYPE_BUFFER;
1593 obj->buffer.length = nfit_test->nfit_size;
1594 obj->buffer.pointer = nfit_test->nfit_buf;
1595 *(nfit_test->_fit) = obj;
1596 __acpi_nfit_notify(&pdev->dev, nfit_test, 0x80);
1486
1597
1598 /* associate dimm devices with nfit_mem data for notification testing */
1599 mutex_lock(&acpi_desc->init_mutex);
1600 list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) {
1601 u32 nfit_handle = __to_nfit_memdev(nfit_mem)->device_handle;
1602 int i;
1603
1604 for (i = 0; i < NUM_DCR; i++)
1605 if (nfit_handle == handle[i])
1606 dev_set_drvdata(nfit_test->dimm_dev[i],
1607 nfit_mem);
1608 }
1609 mutex_unlock(&acpi_desc->init_mutex);
1610
1487 return 0;
1488}
1489
1490static int nfit_test_remove(struct platform_device *pdev)
1491{
1492 return 0;
1493}
1494

--- 17 unchanged lines hidden (view full) ---

1512 },
1513 .id_table = nfit_test_id,
1514};
1515
1516static __init int nfit_test_init(void)
1517{
1518 int rc, i;
1519
1611 return 0;
1612}
1613
1614static int nfit_test_remove(struct platform_device *pdev)
1615{
1616 return 0;
1617}
1618

--- 17 unchanged lines hidden (view full) ---

1636 },
1637 .id_table = nfit_test_id,
1638};
1639
1640static __init int nfit_test_init(void)
1641{
1642 int rc, i;
1643
1644 nfit_test_dimm = class_create(THIS_MODULE, "nfit_test_dimm");
1645 if (IS_ERR(nfit_test_dimm))
1646 return PTR_ERR(nfit_test_dimm);
1647
1520 nfit_test_setup(nfit_test_lookup);
1521
1522 for (i = 0; i < NUM_NFITS; i++) {
1523 struct nfit_test *nfit_test;
1524 struct platform_device *pdev;
1525
1526 nfit_test = kzalloc(sizeof(*nfit_test), GFP_KERNEL);
1527 if (!nfit_test) {

--- 50 unchanged lines hidden (view full) ---

1578static __exit void nfit_test_exit(void)
1579{
1580 int i;
1581
1582 platform_driver_unregister(&nfit_test_driver);
1583 for (i = 0; i < NUM_NFITS; i++)
1584 platform_device_unregister(&instances[i]->pdev);
1585 nfit_test_teardown();
1648 nfit_test_setup(nfit_test_lookup);
1649
1650 for (i = 0; i < NUM_NFITS; i++) {
1651 struct nfit_test *nfit_test;
1652 struct platform_device *pdev;
1653
1654 nfit_test = kzalloc(sizeof(*nfit_test), GFP_KERNEL);
1655 if (!nfit_test) {

--- 50 unchanged lines hidden (view full) ---

1706static __exit void nfit_test_exit(void)
1707{
1708 int i;
1709
1710 platform_driver_unregister(&nfit_test_driver);
1711 for (i = 0; i < NUM_NFITS; i++)
1712 platform_device_unregister(&instances[i]->pdev);
1713 nfit_test_teardown();
1714 class_destroy(nfit_test_dimm);
1586}
1587
1588module_init(nfit_test_init);
1589module_exit(nfit_test_exit);
1590MODULE_LICENSE("GPL v2");
1591MODULE_AUTHOR("Intel Corporation");
1715}
1716
1717module_init(nfit_test_init);
1718module_exit(nfit_test_exit);
1719MODULE_LICENSE("GPL v2");
1720MODULE_AUTHOR("Intel Corporation");