18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Private stuff for vfio_ccw driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2017 68c2ecf20Sopenharmony_ci * Copyright Red Hat, Inc. 2019 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> 98c2ecf20Sopenharmony_ci * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com> 108c2ecf20Sopenharmony_ci * Cornelia Huck <cohuck@redhat.com> 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#ifndef _VFIO_CCW_PRIVATE_H_ 148c2ecf20Sopenharmony_ci#define _VFIO_CCW_PRIVATE_H_ 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include <linux/completion.h> 178c2ecf20Sopenharmony_ci#include <linux/eventfd.h> 188c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 198c2ecf20Sopenharmony_ci#include <linux/vfio_ccw.h> 208c2ecf20Sopenharmony_ci#include <asm/crw.h> 218c2ecf20Sopenharmony_ci#include <asm/debug.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#include "css.h" 248c2ecf20Sopenharmony_ci#include "vfio_ccw_cp.h" 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define VFIO_CCW_OFFSET_SHIFT 10 278c2ecf20Sopenharmony_ci#define VFIO_CCW_OFFSET_TO_INDEX(off) (off >> VFIO_CCW_OFFSET_SHIFT) 288c2ecf20Sopenharmony_ci#define VFIO_CCW_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_CCW_OFFSET_SHIFT) 298c2ecf20Sopenharmony_ci#define VFIO_CCW_OFFSET_MASK (((u64)(1) << VFIO_CCW_OFFSET_SHIFT) - 1) 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* capability chain handling similar to vfio-pci */ 328c2ecf20Sopenharmony_cistruct vfio_ccw_private; 338c2ecf20Sopenharmony_cistruct vfio_ccw_region; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistruct vfio_ccw_regops { 368c2ecf20Sopenharmony_ci ssize_t (*read)(struct vfio_ccw_private *private, char __user *buf, 378c2ecf20Sopenharmony_ci size_t count, loff_t *ppos); 388c2ecf20Sopenharmony_ci ssize_t (*write)(struct vfio_ccw_private *private, 398c2ecf20Sopenharmony_ci const char __user *buf, size_t count, loff_t *ppos); 408c2ecf20Sopenharmony_ci void (*release)(struct vfio_ccw_private *private, 418c2ecf20Sopenharmony_ci struct vfio_ccw_region *region); 428c2ecf20Sopenharmony_ci}; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistruct vfio_ccw_region { 458c2ecf20Sopenharmony_ci u32 type; 468c2ecf20Sopenharmony_ci u32 subtype; 478c2ecf20Sopenharmony_ci const struct vfio_ccw_regops *ops; 488c2ecf20Sopenharmony_ci void *data; 498c2ecf20Sopenharmony_ci size_t size; 508c2ecf20Sopenharmony_ci u32 flags; 518c2ecf20Sopenharmony_ci}; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ciint vfio_ccw_register_dev_region(struct vfio_ccw_private *private, 548c2ecf20Sopenharmony_ci unsigned int subtype, 558c2ecf20Sopenharmony_ci const struct vfio_ccw_regops *ops, 568c2ecf20Sopenharmony_ci size_t size, u32 flags, void *data); 578c2ecf20Sopenharmony_civoid vfio_ccw_unregister_dev_regions(struct vfio_ccw_private *private); 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ciint vfio_ccw_register_async_dev_regions(struct vfio_ccw_private *private); 608c2ecf20Sopenharmony_ciint vfio_ccw_register_schib_dev_regions(struct vfio_ccw_private *private); 618c2ecf20Sopenharmony_ciint vfio_ccw_register_crw_dev_regions(struct vfio_ccw_private *private); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistruct vfio_ccw_crw { 648c2ecf20Sopenharmony_ci struct list_head next; 658c2ecf20Sopenharmony_ci struct crw crw; 668c2ecf20Sopenharmony_ci}; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/** 698c2ecf20Sopenharmony_ci * struct vfio_ccw_private 708c2ecf20Sopenharmony_ci * @sch: pointer to the subchannel 718c2ecf20Sopenharmony_ci * @state: internal state of the device 728c2ecf20Sopenharmony_ci * @completion: synchronization helper of the I/O completion 738c2ecf20Sopenharmony_ci * @avail: available for creating a mediated device 748c2ecf20Sopenharmony_ci * @mdev: pointer to the mediated device 758c2ecf20Sopenharmony_ci * @nb: notifier for vfio events 768c2ecf20Sopenharmony_ci * @io_region: MMIO region to input/output I/O arguments/results 778c2ecf20Sopenharmony_ci * @io_mutex: protect against concurrent update of I/O regions 788c2ecf20Sopenharmony_ci * @region: additional regions for other subchannel operations 798c2ecf20Sopenharmony_ci * @cmd_region: MMIO region for asynchronous I/O commands other than START 808c2ecf20Sopenharmony_ci * @schib_region: MMIO region for SCHIB information 818c2ecf20Sopenharmony_ci * @crw_region: MMIO region for getting channel report words 828c2ecf20Sopenharmony_ci * @num_regions: number of additional regions 838c2ecf20Sopenharmony_ci * @cp: channel program for the current I/O operation 848c2ecf20Sopenharmony_ci * @irb: irb info received from interrupt 858c2ecf20Sopenharmony_ci * @scsw: scsw info 868c2ecf20Sopenharmony_ci * @io_trigger: eventfd ctx for signaling userspace I/O results 878c2ecf20Sopenharmony_ci * @io_work: work for deferral process of I/O handling 888c2ecf20Sopenharmony_ci */ 898c2ecf20Sopenharmony_cistruct vfio_ccw_private { 908c2ecf20Sopenharmony_ci struct subchannel *sch; 918c2ecf20Sopenharmony_ci int state; 928c2ecf20Sopenharmony_ci struct completion *completion; 938c2ecf20Sopenharmony_ci atomic_t avail; 948c2ecf20Sopenharmony_ci struct mdev_device *mdev; 958c2ecf20Sopenharmony_ci struct notifier_block nb; 968c2ecf20Sopenharmony_ci struct ccw_io_region *io_region; 978c2ecf20Sopenharmony_ci struct mutex io_mutex; 988c2ecf20Sopenharmony_ci struct vfio_ccw_region *region; 998c2ecf20Sopenharmony_ci struct ccw_cmd_region *cmd_region; 1008c2ecf20Sopenharmony_ci struct ccw_schib_region *schib_region; 1018c2ecf20Sopenharmony_ci struct ccw_crw_region *crw_region; 1028c2ecf20Sopenharmony_ci int num_regions; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci struct channel_program cp; 1058c2ecf20Sopenharmony_ci struct irb irb; 1068c2ecf20Sopenharmony_ci union scsw scsw; 1078c2ecf20Sopenharmony_ci struct list_head crw; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci struct eventfd_ctx *io_trigger; 1108c2ecf20Sopenharmony_ci struct eventfd_ctx *crw_trigger; 1118c2ecf20Sopenharmony_ci struct work_struct io_work; 1128c2ecf20Sopenharmony_ci struct work_struct crw_work; 1138c2ecf20Sopenharmony_ci} __aligned(8); 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ciextern int vfio_ccw_mdev_reg(struct subchannel *sch); 1168c2ecf20Sopenharmony_ciextern void vfio_ccw_mdev_unreg(struct subchannel *sch); 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ciextern int vfio_ccw_sch_quiesce(struct subchannel *sch); 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci/* 1218c2ecf20Sopenharmony_ci * States of the device statemachine. 1228c2ecf20Sopenharmony_ci */ 1238c2ecf20Sopenharmony_cienum vfio_ccw_state { 1248c2ecf20Sopenharmony_ci VFIO_CCW_STATE_NOT_OPER, 1258c2ecf20Sopenharmony_ci VFIO_CCW_STATE_STANDBY, 1268c2ecf20Sopenharmony_ci VFIO_CCW_STATE_IDLE, 1278c2ecf20Sopenharmony_ci VFIO_CCW_STATE_CP_PROCESSING, 1288c2ecf20Sopenharmony_ci VFIO_CCW_STATE_CP_PENDING, 1298c2ecf20Sopenharmony_ci /* last element! */ 1308c2ecf20Sopenharmony_ci NR_VFIO_CCW_STATES 1318c2ecf20Sopenharmony_ci}; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci/* 1348c2ecf20Sopenharmony_ci * Asynchronous events of the device statemachine. 1358c2ecf20Sopenharmony_ci */ 1368c2ecf20Sopenharmony_cienum vfio_ccw_event { 1378c2ecf20Sopenharmony_ci VFIO_CCW_EVENT_NOT_OPER, 1388c2ecf20Sopenharmony_ci VFIO_CCW_EVENT_IO_REQ, 1398c2ecf20Sopenharmony_ci VFIO_CCW_EVENT_INTERRUPT, 1408c2ecf20Sopenharmony_ci VFIO_CCW_EVENT_ASYNC_REQ, 1418c2ecf20Sopenharmony_ci /* last element! */ 1428c2ecf20Sopenharmony_ci NR_VFIO_CCW_EVENTS 1438c2ecf20Sopenharmony_ci}; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci/* 1468c2ecf20Sopenharmony_ci * Action called through jumptable. 1478c2ecf20Sopenharmony_ci */ 1488c2ecf20Sopenharmony_citypedef void (fsm_func_t)(struct vfio_ccw_private *, enum vfio_ccw_event); 1498c2ecf20Sopenharmony_ciextern fsm_func_t *vfio_ccw_jumptable[NR_VFIO_CCW_STATES][NR_VFIO_CCW_EVENTS]; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_cistatic inline void vfio_ccw_fsm_event(struct vfio_ccw_private *private, 1528c2ecf20Sopenharmony_ci int event) 1538c2ecf20Sopenharmony_ci{ 1548c2ecf20Sopenharmony_ci trace_vfio_ccw_fsm_event(private->sch->schid, private->state, event); 1558c2ecf20Sopenharmony_ci vfio_ccw_jumptable[private->state][event](private, event); 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ciextern struct workqueue_struct *vfio_ccw_work_q; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci/* s390 debug feature, similar to base cio */ 1628c2ecf20Sopenharmony_ciextern debug_info_t *vfio_ccw_debug_msg_id; 1638c2ecf20Sopenharmony_ciextern debug_info_t *vfio_ccw_debug_trace_id; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci#define VFIO_CCW_TRACE_EVENT(imp, txt) \ 1668c2ecf20Sopenharmony_ci debug_text_event(vfio_ccw_debug_trace_id, imp, txt) 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci#define VFIO_CCW_MSG_EVENT(imp, args...) \ 1698c2ecf20Sopenharmony_ci debug_sprintf_event(vfio_ccw_debug_msg_id, imp, ##args) 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_cistatic inline void VFIO_CCW_HEX_EVENT(int level, void *data, int length) 1728c2ecf20Sopenharmony_ci{ 1738c2ecf20Sopenharmony_ci debug_event(vfio_ccw_debug_trace_id, level, data, length); 1748c2ecf20Sopenharmony_ci} 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci#endif 177