rpadlpar_sysfs.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * Interface for Dynamic Logical Partitioning of I/O Slots on
  3. * RPA-compliant PPC64 platform.
  4. *
  5. * John Rose <johnrose@austin.ibm.com>
  6. * October 2003
  7. *
  8. * Copyright (C) 2003 IBM.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License
  12. * as published by the Free Software Foundation; either version
  13. * 2 of the License, or (at your option) any later version.
  14. */
  15. #include <linux/kobject.h>
  16. #include <linux/string.h>
  17. #include "pci_hotplug.h"
  18. #include "rpadlpar.h"
  19. #define DLPAR_KOBJ_NAME "control"
  20. #define ADD_SLOT_ATTR_NAME "add_slot"
  21. #define REMOVE_SLOT_ATTR_NAME "remove_slot"
  22. #define MAX_DRC_NAME_LEN 64
  23. /* Store return code of dlpar operation in attribute struct */
  24. struct dlpar_io_attr {
  25. int rc;
  26. struct attribute attr;
  27. ssize_t (*store)(struct dlpar_io_attr *dlpar_attr, const char *buf,
  28. size_t nbytes);
  29. };
  30. /* Common show callback for all attrs, display the return code
  31. * of the dlpar op */
  32. static ssize_t
  33. dlpar_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
  34. {
  35. struct dlpar_io_attr *dlpar_attr = container_of(attr,
  36. struct dlpar_io_attr, attr);
  37. return sprintf(buf, "%d\n", dlpar_attr->rc);
  38. }
  39. static ssize_t
  40. dlpar_attr_store(struct kobject * kobj, struct attribute * attr,
  41. const char *buf, size_t nbytes)
  42. {
  43. struct dlpar_io_attr *dlpar_attr = container_of(attr,
  44. struct dlpar_io_attr, attr);
  45. return dlpar_attr->store ?
  46. dlpar_attr->store(dlpar_attr, buf, nbytes) : -EIO;
  47. }
  48. static struct sysfs_ops dlpar_attr_sysfs_ops = {
  49. .show = dlpar_attr_show,
  50. .store = dlpar_attr_store,
  51. };
  52. static ssize_t add_slot_store(struct dlpar_io_attr *dlpar_attr,
  53. const char *buf, size_t nbytes)
  54. {
  55. char drc_name[MAX_DRC_NAME_LEN];
  56. char *end;
  57. if (nbytes >= MAX_DRC_NAME_LEN)
  58. return 0;
  59. memcpy(drc_name, buf, nbytes);
  60. end = strchr(drc_name, '\n');
  61. if (!end)
  62. end = &drc_name[nbytes];
  63. *end = '\0';
  64. dlpar_attr->rc = dlpar_add_slot(drc_name);
  65. return nbytes;
  66. }
  67. static ssize_t remove_slot_store(struct dlpar_io_attr *dlpar_attr,
  68. const char *buf, size_t nbytes)
  69. {
  70. char drc_name[MAX_DRC_NAME_LEN];
  71. char *end;
  72. if (nbytes >= MAX_DRC_NAME_LEN)
  73. return 0;
  74. memcpy(drc_name, buf, nbytes);
  75. end = strchr(drc_name, '\n');
  76. if (!end)
  77. end = &drc_name[nbytes];
  78. *end = '\0';
  79. dlpar_attr->rc = dlpar_remove_slot(drc_name);
  80. return nbytes;
  81. }
  82. static struct dlpar_io_attr add_slot_attr = {
  83. .rc = 0,
  84. .attr = { .name = ADD_SLOT_ATTR_NAME, .mode = 0644, },
  85. .store = add_slot_store,
  86. };
  87. static struct dlpar_io_attr remove_slot_attr = {
  88. .rc = 0,
  89. .attr = { .name = REMOVE_SLOT_ATTR_NAME, .mode = 0644},
  90. .store = remove_slot_store,
  91. };
  92. static struct attribute *default_attrs[] = {
  93. &add_slot_attr.attr,
  94. &remove_slot_attr.attr,
  95. NULL,
  96. };
  97. static void dlpar_io_release(struct kobject *kobj)
  98. {
  99. /* noop */
  100. return;
  101. }
  102. struct kobj_type ktype_dlpar_io = {
  103. .release = dlpar_io_release,
  104. .sysfs_ops = &dlpar_attr_sysfs_ops,
  105. .default_attrs = default_attrs,
  106. };
  107. struct kset dlpar_io_kset = {
  108. .subsys = &pci_hotplug_slots_subsys,
  109. .kobj = {.name = DLPAR_KOBJ_NAME, .ktype=&ktype_dlpar_io,},
  110. .ktype = &ktype_dlpar_io,
  111. };
  112. int dlpar_sysfs_init(void)
  113. {
  114. if (kset_register(&dlpar_io_kset)) {
  115. printk(KERN_ERR "rpadlpar_io: cannot register kset for %s\n",
  116. dlpar_io_kset.kobj.name);
  117. return -EINVAL;
  118. }
  119. return 0;
  120. }
  121. void dlpar_sysfs_exit(void)
  122. {
  123. kset_unregister(&dlpar_io_kset);
  124. }