zfcp_ccw.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * zfcp device driver
  3. *
  4. * Registration and callback for the s390 common I/O layer.
  5. *
  6. * Copyright IBM Corporation 2002, 2010
  7. */
  8. #define KMSG_COMPONENT "zfcp"
  9. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  10. #include "zfcp_ext.h"
  11. #include "zfcp_reqlist.h"
  12. #define ZFCP_MODEL_PRIV 0x4
  13. static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock);
  14. struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *cdev)
  15. {
  16. struct zfcp_adapter *adapter;
  17. unsigned long flags;
  18. spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
  19. adapter = dev_get_drvdata(&cdev->dev);
  20. if (adapter)
  21. kref_get(&adapter->ref);
  22. spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
  23. return adapter;
  24. }
  25. void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
  26. {
  27. unsigned long flags;
  28. spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
  29. kref_put(&adapter->ref, zfcp_adapter_release);
  30. spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
  31. }
  32. static int zfcp_ccw_activate(struct ccw_device *cdev)
  33. {
  34. struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
  35. if (!adapter)
  36. return 0;
  37. zfcp_erp_modify_adapter_status(adapter, "ccresu1", NULL,
  38. ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
  39. zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
  40. "ccresu2", NULL);
  41. zfcp_erp_wait(adapter);
  42. flush_work(&adapter->scan_work);
  43. zfcp_ccw_adapter_put(adapter);
  44. return 0;
  45. }
  46. static struct ccw_device_id zfcp_ccw_device_id[] = {
  47. { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) },
  48. { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, ZFCP_MODEL_PRIV) },
  49. {},
  50. };
  51. MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id);
  52. /**
  53. * zfcp_ccw_priv_sch - check if subchannel is privileged
  54. * @adapter: Adapter/Subchannel to check
  55. */
  56. int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter)
  57. {
  58. return adapter->ccw_device->id.dev_model == ZFCP_MODEL_PRIV;
  59. }
  60. /**
  61. * zfcp_ccw_probe - probe function of zfcp driver
  62. * @cdev: pointer to belonging ccw device
  63. *
  64. * This function gets called by the common i/o layer for each FCP
  65. * device found on the current system. This is only a stub to make cio
  66. * work: To only allocate adapter resources for devices actually used,
  67. * the allocation is deferred to the first call to ccw_set_online.
  68. */
  69. static int zfcp_ccw_probe(struct ccw_device *cdev)
  70. {
  71. return 0;
  72. }
  73. /**
  74. * zfcp_ccw_remove - remove function of zfcp driver
  75. * @cdev: pointer to belonging ccw device
  76. *
  77. * This function gets called by the common i/o layer and removes an adapter
  78. * from the system. Task of this function is to get rid of all units and
  79. * ports that belong to this adapter. And in addition all resources of this
  80. * adapter will be freed too.
  81. */
  82. static void zfcp_ccw_remove(struct ccw_device *cdev)
  83. {
  84. struct zfcp_adapter *adapter;
  85. struct zfcp_port *port, *p;
  86. struct zfcp_unit *unit, *u;
  87. LIST_HEAD(unit_remove_lh);
  88. LIST_HEAD(port_remove_lh);
  89. ccw_device_set_offline(cdev);
  90. adapter = zfcp_ccw_adapter_by_cdev(cdev);
  91. if (!adapter)
  92. return;
  93. write_lock_irq(&adapter->port_list_lock);
  94. list_for_each_entry_safe(port, p, &adapter->port_list, list) {
  95. write_lock(&port->unit_list_lock);
  96. list_for_each_entry_safe(unit, u, &port->unit_list, list)
  97. list_move(&unit->list, &unit_remove_lh);
  98. write_unlock(&port->unit_list_lock);
  99. list_move(&port->list, &port_remove_lh);
  100. }
  101. write_unlock_irq(&adapter->port_list_lock);
  102. zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
  103. list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
  104. zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs);
  105. list_for_each_entry_safe(port, p, &port_remove_lh, list)
  106. zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs);
  107. zfcp_adapter_unregister(adapter);
  108. }
  109. /**
  110. * zfcp_ccw_set_online - set_online function of zfcp driver
  111. * @cdev: pointer to belonging ccw device
  112. *
  113. * This function gets called by the common i/o layer and sets an
  114. * adapter into state online. The first call will allocate all
  115. * adapter resources that will be retained until the device is removed
  116. * via zfcp_ccw_remove.
  117. *
  118. * Setting an fcp device online means that it will be registered with
  119. * the SCSI stack, that the QDIO queues will be set up and that the
  120. * adapter will be opened.
  121. */
  122. static int zfcp_ccw_set_online(struct ccw_device *cdev)
  123. {
  124. struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
  125. if (!adapter) {
  126. adapter = zfcp_adapter_enqueue(cdev);
  127. if (IS_ERR(adapter)) {
  128. dev_err(&cdev->dev,
  129. "Setting up data structures for the "
  130. "FCP adapter failed\n");
  131. return PTR_ERR(adapter);
  132. }
  133. kref_get(&adapter->ref);
  134. }
  135. /* initialize request counter */
  136. BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
  137. adapter->req_no = 0;
  138. zfcp_erp_modify_adapter_status(adapter, "ccsonl1", NULL,
  139. ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
  140. zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
  141. "ccsonl2", NULL);
  142. zfcp_erp_wait(adapter);
  143. flush_work(&adapter->scan_work);
  144. zfcp_ccw_adapter_put(adapter);
  145. return 0;
  146. }
  147. /**
  148. * zfcp_ccw_set_offline - set_offline function of zfcp driver
  149. * @cdev: pointer to belonging ccw device
  150. *
  151. * This function gets called by the common i/o layer and sets an adapter
  152. * into state offline.
  153. */
  154. static int zfcp_ccw_set_offline(struct ccw_device *cdev)
  155. {
  156. struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
  157. if (!adapter)
  158. return 0;
  159. zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL);
  160. zfcp_erp_wait(adapter);
  161. zfcp_ccw_adapter_put(adapter);
  162. return 0;
  163. }
  164. /**
  165. * zfcp_ccw_notify - ccw notify function
  166. * @cdev: pointer to belonging ccw device
  167. * @event: indicates if adapter was detached or attached
  168. *
  169. * This function gets called by the common i/o layer if an adapter has gone
  170. * or reappeared.
  171. */
  172. static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
  173. {
  174. struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
  175. if (!adapter)
  176. return 1;
  177. switch (event) {
  178. case CIO_GONE:
  179. dev_warn(&cdev->dev, "The FCP device has been detached\n");
  180. zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL);
  181. break;
  182. case CIO_NO_PATH:
  183. dev_warn(&cdev->dev,
  184. "The CHPID for the FCP device is offline\n");
  185. zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL);
  186. break;
  187. case CIO_OPER:
  188. dev_info(&cdev->dev, "The FCP device is operational again\n");
  189. zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL,
  190. ZFCP_STATUS_COMMON_RUNNING,
  191. ZFCP_SET);
  192. zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
  193. "ccnoti4", NULL);
  194. break;
  195. case CIO_BOXED:
  196. dev_warn(&cdev->dev, "The FCP device did not respond within "
  197. "the specified time\n");
  198. zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL);
  199. break;
  200. }
  201. zfcp_ccw_adapter_put(adapter);
  202. return 1;
  203. }
  204. /**
  205. * zfcp_ccw_shutdown - handle shutdown from cio
  206. * @cdev: device for adapter to shutdown.
  207. */
  208. static void zfcp_ccw_shutdown(struct ccw_device *cdev)
  209. {
  210. struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
  211. if (!adapter)
  212. return;
  213. zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL);
  214. zfcp_erp_wait(adapter);
  215. zfcp_erp_thread_kill(adapter);
  216. zfcp_ccw_adapter_put(adapter);
  217. }
  218. struct ccw_driver zfcp_ccw_driver = {
  219. .owner = THIS_MODULE,
  220. .name = "zfcp",
  221. .ids = zfcp_ccw_device_id,
  222. .probe = zfcp_ccw_probe,
  223. .remove = zfcp_ccw_remove,
  224. .set_online = zfcp_ccw_set_online,
  225. .set_offline = zfcp_ccw_set_offline,
  226. .notify = zfcp_ccw_notify,
  227. .shutdown = zfcp_ccw_shutdown,
  228. .freeze = zfcp_ccw_set_offline,
  229. .thaw = zfcp_ccw_activate,
  230. .restore = zfcp_ccw_activate,
  231. };