1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Private stuff for vfio_ccw driver 4 * 5 * Copyright IBM Corp. 2017 6 * Copyright Red Hat, Inc. 2019 7 * 8 * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> 9 * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com> 10 * Cornelia Huck <cohuck@redhat.com> 11 */ 12 13 #ifndef _VFIO_CCW_PRIVATE_H_ 14 #define _VFIO_CCW_PRIVATE_H_ 15 16 #include <linux/completion.h> 17 #include <linux/eventfd.h> 18 #include <linux/workqueue.h> 19 #include <linux/vfio_ccw.h> 20 21 #include "css.h" 22 #include "vfio_ccw_cp.h" 23 24 #define VFIO_CCW_OFFSET_SHIFT 10 25 #define VFIO_CCW_OFFSET_TO_INDEX(off) (off >> VFIO_CCW_OFFSET_SHIFT) 26 #define VFIO_CCW_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_CCW_OFFSET_SHIFT) 27 #define VFIO_CCW_OFFSET_MASK (((u64)(1) << VFIO_CCW_OFFSET_SHIFT) - 1) 28 29 /* capability chain handling similar to vfio-pci */ 30 struct vfio_ccw_private; 31 struct vfio_ccw_region; 32 33 struct vfio_ccw_regops { 34 ssize_t (*read)(struct vfio_ccw_private *private, char __user *buf, 35 size_t count, loff_t *ppos); 36 ssize_t (*write)(struct vfio_ccw_private *private, 37 const char __user *buf, size_t count, loff_t *ppos); 38 void (*release)(struct vfio_ccw_private *private, 39 struct vfio_ccw_region *region); 40 }; 41 42 struct vfio_ccw_region { 43 u32 type; 44 u32 subtype; 45 const struct vfio_ccw_regops *ops; 46 void *data; 47 size_t size; 48 u32 flags; 49 }; 50 51 int vfio_ccw_register_dev_region(struct vfio_ccw_private *private, 52 unsigned int subtype, 53 const struct vfio_ccw_regops *ops, 54 size_t size, u32 flags, void *data); 55 56 int vfio_ccw_register_async_dev_regions(struct vfio_ccw_private *private); 57 58 /** 59 * struct vfio_ccw_private 60 * @sch: pointer to the subchannel 61 * @state: internal state of the device 62 * @completion: synchronization helper of the I/O completion 63 * @avail: available for creating a mediated device 64 * @mdev: pointer to the mediated device 65 * @nb: notifier for vfio events 66 * @io_region: MMIO region to input/output I/O arguments/results 67 * @io_mutex: protect against concurrent update of I/O regions 68 * @region: additional regions for other subchannel operations 69 * @cmd_region: MMIO region for asynchronous I/O commands other than START 70 * @num_regions: number of additional regions 71 * @cp: channel program for the current I/O operation 72 * @irb: irb info received from interrupt 73 * @scsw: scsw info 74 * @io_trigger: eventfd ctx for signaling userspace I/O results 75 * @io_work: work for deferral process of I/O handling 76 */ 77 struct vfio_ccw_private { 78 struct subchannel *sch; 79 int state; 80 struct completion *completion; 81 atomic_t avail; 82 struct mdev_device *mdev; 83 struct notifier_block nb; 84 struct ccw_io_region *io_region; 85 struct mutex io_mutex; 86 struct vfio_ccw_region *region; 87 struct ccw_cmd_region *cmd_region; 88 int num_regions; 89 90 struct channel_program cp; 91 struct irb irb; 92 union scsw scsw; 93 94 struct eventfd_ctx *io_trigger; 95 struct work_struct io_work; 96 } __aligned(8); 97 98 extern int vfio_ccw_mdev_reg(struct subchannel *sch); 99 extern void vfio_ccw_mdev_unreg(struct subchannel *sch); 100 101 extern int vfio_ccw_sch_quiesce(struct subchannel *sch); 102 103 /* 104 * States of the device statemachine. 105 */ 106 enum vfio_ccw_state { 107 VFIO_CCW_STATE_NOT_OPER, 108 VFIO_CCW_STATE_STANDBY, 109 VFIO_CCW_STATE_IDLE, 110 VFIO_CCW_STATE_CP_PROCESSING, 111 VFIO_CCW_STATE_CP_PENDING, 112 /* last element! */ 113 NR_VFIO_CCW_STATES 114 }; 115 116 /* 117 * Asynchronous events of the device statemachine. 118 */ 119 enum vfio_ccw_event { 120 VFIO_CCW_EVENT_NOT_OPER, 121 VFIO_CCW_EVENT_IO_REQ, 122 VFIO_CCW_EVENT_INTERRUPT, 123 VFIO_CCW_EVENT_ASYNC_REQ, 124 /* last element! */ 125 NR_VFIO_CCW_EVENTS 126 }; 127 128 /* 129 * Action called through jumptable. 130 */ 131 typedef void (fsm_func_t)(struct vfio_ccw_private *, enum vfio_ccw_event); 132 extern fsm_func_t *vfio_ccw_jumptable[NR_VFIO_CCW_STATES][NR_VFIO_CCW_EVENTS]; 133 134 static inline void vfio_ccw_fsm_event(struct vfio_ccw_private *private, 135 int event) 136 { 137 vfio_ccw_jumptable[private->state][event](private, event); 138 } 139 140 extern struct workqueue_struct *vfio_ccw_work_q; 141 142 #endif 143