vfio_ccw_private.h 3.7 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0 */
2 3 4 5
/*
 * Private stuff for vfio_ccw driver
 *
 * Copyright IBM Corp. 2017
C
Cornelia Huck 已提交
6
 * Copyright Red Hat, Inc. 2019
7 8 9
 *
 * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
 *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
C
Cornelia Huck 已提交
10
 *            Cornelia Huck <cohuck@redhat.com>
11 12 13 14 15
 */

#ifndef _VFIO_CCW_PRIVATE_H_
#define _VFIO_CCW_PRIVATE_H_

16
#include <linux/completion.h>
17
#include <linux/eventfd.h>
18
#include <linux/workqueue.h>
19 20
#include <linux/vfio_ccw.h>

21
#include "css.h"
22
#include "vfio_ccw_cp.h"
23

C
Cornelia Huck 已提交
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#define VFIO_CCW_OFFSET_SHIFT   10
#define VFIO_CCW_OFFSET_TO_INDEX(off)	(off >> VFIO_CCW_OFFSET_SHIFT)
#define VFIO_CCW_INDEX_TO_OFFSET(index)	((u64)(index) << VFIO_CCW_OFFSET_SHIFT)
#define VFIO_CCW_OFFSET_MASK	(((u64)(1) << VFIO_CCW_OFFSET_SHIFT) - 1)

/* capability chain handling similar to vfio-pci */
struct vfio_ccw_private;
struct vfio_ccw_region;

struct vfio_ccw_regops {
	ssize_t	(*read)(struct vfio_ccw_private *private, char __user *buf,
			size_t count, loff_t *ppos);
	ssize_t	(*write)(struct vfio_ccw_private *private,
			 const char __user *buf, size_t count, loff_t *ppos);
	void	(*release)(struct vfio_ccw_private *private,
			   struct vfio_ccw_region *region);
};

struct vfio_ccw_region {
	u32				type;
	u32				subtype;
	const struct vfio_ccw_regops	*ops;
	void				*data;
	size_t				size;
	u32				flags;
};

int vfio_ccw_register_dev_region(struct vfio_ccw_private *private,
				 unsigned int subtype,
				 const struct vfio_ccw_regops *ops,
				 size_t size, u32 flags, void *data);

56 57 58
/**
 * struct vfio_ccw_private
 * @sch: pointer to the subchannel
59
 * @state: internal state of the device
60
 * @completion: synchronization helper of the I/O completion
61 62 63
 * @avail: available for creating a mediated device
 * @mdev: pointer to the mediated device
 * @nb: notifier for vfio events
64
 * @io_region: MMIO region to input/output I/O arguments/results
C
Cornelia Huck 已提交
65
 * @io_mutex: protect against concurrent update of I/O regions
C
Cornelia Huck 已提交
66 67
 * @region: additional regions for other subchannel operations
 * @num_regions: number of additional regions
68 69 70
 * @cp: channel program for the current I/O operation
 * @irb: irb info received from interrupt
 * @scsw: scsw info
71
 * @io_trigger: eventfd ctx for signaling userspace I/O results
72
 * @io_work: work for deferral process of I/O handling
73 74 75
 */
struct vfio_ccw_private {
	struct subchannel	*sch;
76
	int			state;
77
	struct completion	*completion;
78 79 80
	atomic_t		avail;
	struct mdev_device	*mdev;
	struct notifier_block	nb;
81
	struct ccw_io_region	*io_region;
C
Cornelia Huck 已提交
82
	struct mutex		io_mutex;
C
Cornelia Huck 已提交
83 84
	struct vfio_ccw_region *region;
	int num_regions;
85 86 87 88

	struct channel_program	cp;
	struct irb		irb;
	union scsw		scsw;
89 90

	struct eventfd_ctx	*io_trigger;
91
	struct work_struct	io_work;
92 93
} __aligned(8);

94 95 96 97
extern int vfio_ccw_mdev_reg(struct subchannel *sch);
extern void vfio_ccw_mdev_unreg(struct subchannel *sch);

extern int vfio_ccw_sch_quiesce(struct subchannel *sch);
98 99 100 101 102 103 104 105

/*
 * States of the device statemachine.
 */
enum vfio_ccw_state {
	VFIO_CCW_STATE_NOT_OPER,
	VFIO_CCW_STATE_STANDBY,
	VFIO_CCW_STATE_IDLE,
106 107
	VFIO_CCW_STATE_CP_PROCESSING,
	VFIO_CCW_STATE_CP_PENDING,
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
	/* last element! */
	NR_VFIO_CCW_STATES
};

/*
 * Asynchronous events of the device statemachine.
 */
enum vfio_ccw_event {
	VFIO_CCW_EVENT_NOT_OPER,
	VFIO_CCW_EVENT_IO_REQ,
	VFIO_CCW_EVENT_INTERRUPT,
	/* last element! */
	NR_VFIO_CCW_EVENTS
};

/*
 * Action called through jumptable.
 */
typedef void (fsm_func_t)(struct vfio_ccw_private *, enum vfio_ccw_event);
extern fsm_func_t *vfio_ccw_jumptable[NR_VFIO_CCW_STATES][NR_VFIO_CCW_EVENTS];

static inline void vfio_ccw_fsm_event(struct vfio_ccw_private *private,
				     int event)
{
	vfio_ccw_jumptable[private->state][event](private, event);
}

extern struct workqueue_struct *vfio_ccw_work_q;
136

137
#endif