vfio_ccw_drv.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /*
  2. * VFIO based Physical Subchannel device driver
  3. *
  4. * Copyright IBM Corp. 2017
  5. *
  6. * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
  7. * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
  8. */
  9. #include <linux/module.h>
  10. #include <linux/init.h>
  11. #include <linux/device.h>
  12. #include <linux/slab.h>
  13. #include <linux/uuid.h>
  14. #include <linux/mdev.h>
  15. #include <asm/isc.h>
  16. #include "ioasm.h"
  17. #include "css.h"
  18. #include "vfio_ccw_private.h"
  19. struct workqueue_struct *vfio_ccw_work_q;
  20. /*
  21. * Helpers
  22. */
  23. int vfio_ccw_sch_quiesce(struct subchannel *sch)
  24. {
  25. struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
  26. DECLARE_COMPLETION_ONSTACK(completion);
  27. int iretry, ret = 0;
  28. spin_lock_irq(sch->lock);
  29. if (!sch->schib.pmcw.ena)
  30. goto out_unlock;
  31. ret = cio_disable_subchannel(sch);
  32. if (ret != -EBUSY)
  33. goto out_unlock;
  34. do {
  35. iretry = 255;
  36. ret = cio_cancel_halt_clear(sch, &iretry);
  37. while (ret == -EBUSY) {
  38. /*
  39. * Flush all I/O and wait for
  40. * cancel/halt/clear completion.
  41. */
  42. private->completion = &completion;
  43. spin_unlock_irq(sch->lock);
  44. wait_for_completion_timeout(&completion, 3*HZ);
  45. spin_lock_irq(sch->lock);
  46. private->completion = NULL;
  47. flush_workqueue(vfio_ccw_work_q);
  48. ret = cio_cancel_halt_clear(sch, &iretry);
  49. };
  50. ret = cio_disable_subchannel(sch);
  51. } while (ret == -EBUSY);
  52. out_unlock:
  53. private->state = VFIO_CCW_STATE_NOT_OPER;
  54. spin_unlock_irq(sch->lock);
  55. return ret;
  56. }
  57. static void vfio_ccw_sch_io_todo(struct work_struct *work)
  58. {
  59. struct vfio_ccw_private *private;
  60. struct subchannel *sch;
  61. struct irb *irb;
  62. private = container_of(work, struct vfio_ccw_private, io_work);
  63. irb = &private->irb;
  64. sch = private->sch;
  65. if (scsw_is_solicited(&irb->scsw)) {
  66. cp_update_scsw(&private->cp, &irb->scsw);
  67. cp_free(&private->cp);
  68. }
  69. memcpy(private->io_region.irb_area, irb, sizeof(*irb));
  70. if (private->io_trigger)
  71. eventfd_signal(private->io_trigger, 1);
  72. if (private->mdev)
  73. private->state = VFIO_CCW_STATE_IDLE;
  74. }
  75. /*
  76. * Sysfs interfaces
  77. */
  78. static ssize_t chpids_show(struct device *dev,
  79. struct device_attribute *attr,
  80. char *buf)
  81. {
  82. struct subchannel *sch = to_subchannel(dev);
  83. struct chsc_ssd_info *ssd = &sch->ssd_info;
  84. ssize_t ret = 0;
  85. int chp;
  86. int mask;
  87. for (chp = 0; chp < 8; chp++) {
  88. mask = 0x80 >> chp;
  89. if (ssd->path_mask & mask)
  90. ret += sprintf(buf + ret, "%02x ", ssd->chpid[chp].id);
  91. else
  92. ret += sprintf(buf + ret, "00 ");
  93. }
  94. ret += sprintf(buf+ret, "\n");
  95. return ret;
  96. }
  97. static ssize_t pimpampom_show(struct device *dev,
  98. struct device_attribute *attr,
  99. char *buf)
  100. {
  101. struct subchannel *sch = to_subchannel(dev);
  102. struct pmcw *pmcw = &sch->schib.pmcw;
  103. return sprintf(buf, "%02x %02x %02x\n",
  104. pmcw->pim, pmcw->pam, pmcw->pom);
  105. }
  106. static DEVICE_ATTR(chpids, 0444, chpids_show, NULL);
  107. static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL);
  108. static struct attribute *vfio_subchannel_attrs[] = {
  109. &dev_attr_chpids.attr,
  110. &dev_attr_pimpampom.attr,
  111. NULL,
  112. };
  113. static struct attribute_group vfio_subchannel_attr_group = {
  114. .attrs = vfio_subchannel_attrs,
  115. };
  116. /*
  117. * Css driver callbacks
  118. */
  119. static void vfio_ccw_sch_irq(struct subchannel *sch)
  120. {
  121. struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
  122. inc_irq_stat(IRQIO_CIO);
  123. vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
  124. }
  125. static int vfio_ccw_sch_probe(struct subchannel *sch)
  126. {
  127. struct pmcw *pmcw = &sch->schib.pmcw;
  128. struct vfio_ccw_private *private;
  129. int ret;
  130. if (pmcw->qf) {
  131. dev_warn(&sch->dev, "vfio: ccw: does not support QDIO: %s\n",
  132. dev_name(&sch->dev));
  133. return -ENODEV;
  134. }
  135. private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
  136. if (!private)
  137. return -ENOMEM;
  138. private->sch = sch;
  139. dev_set_drvdata(&sch->dev, private);
  140. spin_lock_irq(sch->lock);
  141. private->state = VFIO_CCW_STATE_NOT_OPER;
  142. sch->isc = VFIO_CCW_ISC;
  143. ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
  144. spin_unlock_irq(sch->lock);
  145. if (ret)
  146. goto out_free;
  147. ret = sysfs_create_group(&sch->dev.kobj, &vfio_subchannel_attr_group);
  148. if (ret)
  149. goto out_disable;
  150. ret = vfio_ccw_mdev_reg(sch);
  151. if (ret)
  152. goto out_rm_group;
  153. INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
  154. atomic_set(&private->avail, 1);
  155. private->state = VFIO_CCW_STATE_STANDBY;
  156. return 0;
  157. out_rm_group:
  158. sysfs_remove_group(&sch->dev.kobj, &vfio_subchannel_attr_group);
  159. out_disable:
  160. cio_disable_subchannel(sch);
  161. out_free:
  162. dev_set_drvdata(&sch->dev, NULL);
  163. kfree(private);
  164. return ret;
  165. }
  166. static int vfio_ccw_sch_remove(struct subchannel *sch)
  167. {
  168. struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
  169. vfio_ccw_sch_quiesce(sch);
  170. vfio_ccw_mdev_unreg(sch);
  171. sysfs_remove_group(&sch->dev.kobj, &vfio_subchannel_attr_group);
  172. dev_set_drvdata(&sch->dev, NULL);
  173. kfree(private);
  174. return 0;
  175. }
  176. static void vfio_ccw_sch_shutdown(struct subchannel *sch)
  177. {
  178. vfio_ccw_sch_quiesce(sch);
  179. }
  180. /**
  181. * vfio_ccw_sch_event - process subchannel event
  182. * @sch: subchannel
  183. * @process: non-zero if function is called in process context
  184. *
  185. * An unspecified event occurred for this subchannel. Adjust data according
  186. * to the current operational state of the subchannel. Return zero when the
  187. * event has been handled sufficiently or -EAGAIN when this function should
  188. * be called again in process context.
  189. */
  190. static int vfio_ccw_sch_event(struct subchannel *sch, int process)
  191. {
  192. struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
  193. unsigned long flags;
  194. spin_lock_irqsave(sch->lock, flags);
  195. if (!device_is_registered(&sch->dev))
  196. goto out_unlock;
  197. if (work_pending(&sch->todo_work))
  198. goto out_unlock;
  199. if (cio_update_schib(sch)) {
  200. vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER);
  201. goto out_unlock;
  202. }
  203. private = dev_get_drvdata(&sch->dev);
  204. if (private->state == VFIO_CCW_STATE_NOT_OPER) {
  205. private->state = private->mdev ? VFIO_CCW_STATE_IDLE :
  206. VFIO_CCW_STATE_STANDBY;
  207. }
  208. out_unlock:
  209. spin_unlock_irqrestore(sch->lock, flags);
  210. return 0;
  211. }
  212. static struct css_device_id vfio_ccw_sch_ids[] = {
  213. { .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, },
  214. { /* end of list */ },
  215. };
  216. MODULE_DEVICE_TABLE(css, vfio_ccw_sch_ids);
  217. static struct css_driver vfio_ccw_sch_driver = {
  218. .drv = {
  219. .name = "vfio_ccw",
  220. .owner = THIS_MODULE,
  221. },
  222. .subchannel_type = vfio_ccw_sch_ids,
  223. .irq = vfio_ccw_sch_irq,
  224. .probe = vfio_ccw_sch_probe,
  225. .remove = vfio_ccw_sch_remove,
  226. .shutdown = vfio_ccw_sch_shutdown,
  227. .sch_event = vfio_ccw_sch_event,
  228. };
  229. static int __init vfio_ccw_sch_init(void)
  230. {
  231. int ret;
  232. vfio_ccw_work_q = create_singlethread_workqueue("vfio-ccw");
  233. if (!vfio_ccw_work_q)
  234. return -ENOMEM;
  235. isc_register(VFIO_CCW_ISC);
  236. ret = css_driver_register(&vfio_ccw_sch_driver);
  237. if (ret) {
  238. isc_unregister(VFIO_CCW_ISC);
  239. destroy_workqueue(vfio_ccw_work_q);
  240. }
  241. return ret;
  242. }
  243. static void __exit vfio_ccw_sch_exit(void)
  244. {
  245. css_driver_unregister(&vfio_ccw_sch_driver);
  246. isc_unregister(VFIO_CCW_ISC);
  247. destroy_workqueue(vfio_ccw_work_q);
  248. }
  249. module_init(vfio_ccw_sch_init);
  250. module_exit(vfio_ccw_sch_exit);
  251. MODULE_LICENSE("GPL v2");