zfcp_ccw.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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 <linux/module.h>
  11. #include "zfcp_ext.h"
  12. #include "zfcp_reqlist.h"
  13. #define ZFCP_MODEL_PRIV 0x4
  14. static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock);
  15. struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *cdev)
  16. {
  17. struct zfcp_adapter *adapter;
  18. unsigned long flags;
  19. spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
  20. adapter = dev_get_drvdata(&cdev->dev);
  21. if (adapter)
  22. kref_get(&adapter->ref);
  23. spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
  24. return adapter;
  25. }
  26. void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
  27. {
  28. unsigned long flags;
  29. spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
  30. kref_put(&adapter->ref, zfcp_adapter_release);
  31. spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
  32. }
  33. static int zfcp_ccw_activate(struct ccw_device *cdev)
  34. {
  35. struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
  36. if (!adapter)
  37. return 0;
  38. zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
  39. zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
  40. "ccresu2");
  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_ccw_activate(cdev);
  139. zfcp_ccw_adapter_put(adapter);
  140. return 0;
  141. }
  142. /**
  143. * zfcp_ccw_set_offline - set_offline function of zfcp driver
  144. * @cdev: pointer to belonging ccw device
  145. *
  146. * This function gets called by the common i/o layer and sets an adapter
  147. * into state offline.
  148. */
  149. static int zfcp_ccw_set_offline(struct ccw_device *cdev)
  150. {
  151. struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
  152. if (!adapter)
  153. return 0;
  154. zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1");
  155. zfcp_erp_wait(adapter);
  156. zfcp_ccw_adapter_put(adapter);
  157. return 0;
  158. }
  159. /**
  160. * zfcp_ccw_notify - ccw notify function
  161. * @cdev: pointer to belonging ccw device
  162. * @event: indicates if adapter was detached or attached
  163. *
  164. * This function gets called by the common i/o layer if an adapter has gone
  165. * or reappeared.
  166. */
  167. static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
  168. {
  169. struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
  170. if (!adapter)
  171. return 1;
  172. switch (event) {
  173. case CIO_GONE:
  174. dev_warn(&cdev->dev, "The FCP device has been detached\n");
  175. zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
  176. break;
  177. case CIO_NO_PATH:
  178. dev_warn(&cdev->dev,
  179. "The CHPID for the FCP device is offline\n");
  180. zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
  181. break;
  182. case CIO_OPER:
  183. dev_info(&cdev->dev, "The FCP device is operational again\n");
  184. zfcp_erp_set_adapter_status(adapter,
  185. ZFCP_STATUS_COMMON_RUNNING);
  186. zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
  187. "ccnoti4");
  188. break;
  189. case CIO_BOXED:
  190. dev_warn(&cdev->dev, "The FCP device did not respond within "
  191. "the specified time\n");
  192. zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5");
  193. break;
  194. }
  195. zfcp_ccw_adapter_put(adapter);
  196. return 1;
  197. }
  198. /**
  199. * zfcp_ccw_shutdown - handle shutdown from cio
  200. * @cdev: device for adapter to shutdown.
  201. */
  202. static void zfcp_ccw_shutdown(struct ccw_device *cdev)
  203. {
  204. struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
  205. if (!adapter)
  206. return;
  207. zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1");
  208. zfcp_erp_wait(adapter);
  209. zfcp_erp_thread_kill(adapter);
  210. zfcp_ccw_adapter_put(adapter);
  211. }
  212. struct ccw_driver zfcp_ccw_driver = {
  213. .driver = {
  214. .owner = THIS_MODULE,
  215. .name = "zfcp",
  216. },
  217. .ids = zfcp_ccw_device_id,
  218. .probe = zfcp_ccw_probe,
  219. .remove = zfcp_ccw_remove,
  220. .set_online = zfcp_ccw_set_online,
  221. .set_offline = zfcp_ccw_set_offline,
  222. .notify = zfcp_ccw_notify,
  223. .shutdown = zfcp_ccw_shutdown,
  224. .freeze = zfcp_ccw_set_offline,
  225. .thaw = zfcp_ccw_activate,
  226. .restore = zfcp_ccw_activate,
  227. };