zfcp_sysfs_port.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * zfcp device driver
  3. *
  4. * sysfs attributes for zfcp port.
  5. *
  6. * Copyright IBM Corporation 2002, 2008
  7. */
  8. #include "zfcp_ext.h"
  9. /**
  10. * zfcp_sysfs_port_release - gets called when a struct device port is released
  11. * @dev: pointer to belonging device
  12. */
  13. void
  14. zfcp_sysfs_port_release(struct device *dev)
  15. {
  16. kfree(dev);
  17. }
  18. /**
  19. * ZFCP_DEFINE_PORT_ATTR
  20. * @_name: name of show attribute
  21. * @_format: format string
  22. * @_value: value to print
  23. *
  24. * Generates attributes for a port.
  25. */
  26. #define ZFCP_DEFINE_PORT_ATTR(_name, _format, _value) \
  27. static ssize_t zfcp_sysfs_port_##_name##_show(struct device *dev, struct device_attribute *attr, \
  28. char *buf) \
  29. { \
  30. struct zfcp_port *port; \
  31. \
  32. port = dev_get_drvdata(dev); \
  33. return sprintf(buf, _format, _value); \
  34. } \
  35. \
  36. static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_port_##_name##_show, NULL);
  37. ZFCP_DEFINE_PORT_ATTR(status, "0x%08x\n", atomic_read(&port->status));
  38. ZFCP_DEFINE_PORT_ATTR(in_recovery, "%d\n", atomic_test_mask
  39. (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status));
  40. ZFCP_DEFINE_PORT_ATTR(access_denied, "%d\n", atomic_test_mask
  41. (ZFCP_STATUS_COMMON_ACCESS_DENIED, &port->status));
  42. /**
  43. * zfcp_sysfs_unit_add_store - add a unit to sysfs tree
  44. * @dev: pointer to belonging device
  45. * @buf: pointer to input buffer
  46. * @count: number of bytes in buffer
  47. *
  48. * Store function of the "unit_add" attribute of a port.
  49. */
  50. static ssize_t
  51. zfcp_sysfs_unit_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  52. {
  53. fcp_lun_t fcp_lun;
  54. char *endp;
  55. struct zfcp_port *port;
  56. struct zfcp_unit *unit;
  57. int retval = -EINVAL;
  58. down(&zfcp_data.config_sema);
  59. port = dev_get_drvdata(dev);
  60. if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status)) {
  61. retval = -EBUSY;
  62. goto out;
  63. }
  64. fcp_lun = simple_strtoull(buf, &endp, 0);
  65. if ((endp + 1) < (buf + count))
  66. goto out;
  67. unit = zfcp_unit_enqueue(port, fcp_lun);
  68. if (!unit)
  69. goto out;
  70. retval = 0;
  71. zfcp_erp_unit_reopen(unit, 0, 94, NULL);
  72. zfcp_erp_wait(unit->port->adapter);
  73. zfcp_unit_put(unit);
  74. out:
  75. up(&zfcp_data.config_sema);
  76. return retval ? retval : (ssize_t) count;
  77. }
  78. static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store);
  79. /**
  80. * zfcp_sysfs_unit_remove_store - remove a unit from sysfs tree
  81. * @dev: pointer to belonging device
  82. * @buf: pointer to input buffer
  83. * @count: number of bytes in buffer
  84. */
  85. static ssize_t
  86. zfcp_sysfs_unit_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  87. {
  88. struct zfcp_port *port;
  89. struct zfcp_unit *unit;
  90. fcp_lun_t fcp_lun;
  91. char *endp;
  92. int retval = 0;
  93. down(&zfcp_data.config_sema);
  94. port = dev_get_drvdata(dev);
  95. if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status)) {
  96. retval = -EBUSY;
  97. goto out;
  98. }
  99. fcp_lun = simple_strtoull(buf, &endp, 0);
  100. if ((endp + 1) < (buf + count)) {
  101. retval = -EINVAL;
  102. goto out;
  103. }
  104. write_lock_irq(&zfcp_data.config_lock);
  105. unit = zfcp_get_unit_by_lun(port, fcp_lun);
  106. if (unit && (atomic_read(&unit->refcount) == 0)) {
  107. zfcp_unit_get(unit);
  108. atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
  109. list_move(&unit->list, &port->unit_remove_lh);
  110. }
  111. else {
  112. unit = NULL;
  113. }
  114. write_unlock_irq(&zfcp_data.config_lock);
  115. if (!unit) {
  116. retval = -ENXIO;
  117. goto out;
  118. }
  119. zfcp_erp_unit_shutdown(unit, 0, 95, NULL);
  120. zfcp_erp_wait(unit->port->adapter);
  121. zfcp_unit_put(unit);
  122. zfcp_unit_dequeue(unit);
  123. out:
  124. up(&zfcp_data.config_sema);
  125. return retval ? retval : (ssize_t) count;
  126. }
  127. static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);
  128. /**
  129. * zfcp_sysfs_port_failed_store - failed state of port
  130. * @dev: pointer to belonging device
  131. * @buf: pointer to input buffer
  132. * @count: number of bytes in buffer
  133. *
  134. * Store function of the "failed" attribute of a port.
  135. * If a "0" gets written to "failed", error recovery will be
  136. * started for the belonging port.
  137. */
  138. static ssize_t
  139. zfcp_sysfs_port_failed_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  140. {
  141. struct zfcp_port *port;
  142. unsigned int val;
  143. char *endp;
  144. int retval = 0;
  145. down(&zfcp_data.config_sema);
  146. port = dev_get_drvdata(dev);
  147. if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status)) {
  148. retval = -EBUSY;
  149. goto out;
  150. }
  151. val = simple_strtoul(buf, &endp, 0);
  152. if (((endp + 1) < (buf + count)) || (val != 0)) {
  153. retval = -EINVAL;
  154. goto out;
  155. }
  156. zfcp_erp_modify_port_status(port, 45, NULL,
  157. ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
  158. zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, 96, NULL);
  159. zfcp_erp_wait(port->adapter);
  160. out:
  161. up(&zfcp_data.config_sema);
  162. return retval ? retval : (ssize_t) count;
  163. }
  164. /**
  165. * zfcp_sysfs_port_failed_show - failed state of port
  166. * @dev: pointer to belonging device
  167. * @buf: pointer to input buffer
  168. *
  169. * Show function of "failed" attribute of port. Will be
  170. * "0" if port is working, otherwise "1".
  171. */
  172. static ssize_t
  173. zfcp_sysfs_port_failed_show(struct device *dev, struct device_attribute *attr, char *buf)
  174. {
  175. struct zfcp_port *port;
  176. port = dev_get_drvdata(dev);
  177. if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status))
  178. return sprintf(buf, "1\n");
  179. else
  180. return sprintf(buf, "0\n");
  181. }
  182. static DEVICE_ATTR(failed, S_IWUSR | S_IRUGO, zfcp_sysfs_port_failed_show,
  183. zfcp_sysfs_port_failed_store);
  184. /**
  185. * zfcp_port_common_attrs
  186. * sysfs attributes that are common for all kind of fc ports.
  187. */
  188. static struct attribute *zfcp_port_common_attrs[] = {
  189. &dev_attr_failed.attr,
  190. &dev_attr_in_recovery.attr,
  191. &dev_attr_status.attr,
  192. &dev_attr_access_denied.attr,
  193. NULL
  194. };
  195. static struct attribute_group zfcp_port_common_attr_group = {
  196. .attrs = zfcp_port_common_attrs,
  197. };
  198. /**
  199. * zfcp_port_no_ns_attrs
  200. * sysfs attributes not to be used for nameserver ports.
  201. */
  202. static struct attribute *zfcp_port_no_ns_attrs[] = {
  203. &dev_attr_unit_add.attr,
  204. &dev_attr_unit_remove.attr,
  205. NULL
  206. };
  207. static struct attribute_group zfcp_port_no_ns_attr_group = {
  208. .attrs = zfcp_port_no_ns_attrs,
  209. };
  210. /**
  211. * zfcp_sysfs_port_create_files - create sysfs port files
  212. * @dev: pointer to belonging device
  213. *
  214. * Create all attributes of the sysfs representation of a port.
  215. */
  216. int
  217. zfcp_sysfs_port_create_files(struct device *dev, u32 flags)
  218. {
  219. int retval;
  220. retval = sysfs_create_group(&dev->kobj, &zfcp_port_common_attr_group);
  221. if ((flags & ZFCP_STATUS_PORT_WKA) || retval)
  222. return retval;
  223. retval = sysfs_create_group(&dev->kobj, &zfcp_port_no_ns_attr_group);
  224. if (retval)
  225. sysfs_remove_group(&dev->kobj, &zfcp_port_common_attr_group);
  226. return retval;
  227. }
  228. /**
  229. * zfcp_sysfs_port_remove_files - remove sysfs port files
  230. * @dev: pointer to belonging device
  231. *
  232. * Remove all attributes of the sysfs representation of a port.
  233. */
  234. void
  235. zfcp_sysfs_port_remove_files(struct device *dev, u32 flags)
  236. {
  237. sysfs_remove_group(&dev->kobj, &zfcp_port_common_attr_group);
  238. if (!(flags & ZFCP_STATUS_PORT_WKA))
  239. sysfs_remove_group(&dev->kobj, &zfcp_port_no_ns_attr_group);
  240. }