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