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"); |