diff options
author | Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> | 2017-03-17 04:17:40 +0100 |
---|---|---|
committer | Cornelia Huck <cornelia.huck@de.ibm.com> | 2017-03-31 12:55:11 +0200 |
commit | bbe37e4cb89702aa78e0f44618c5af7f9aaa33f6 (patch) | |
tree | 46269ef030a61c19f629701e53678e0311b2d2c7 /drivers/s390/cio/vfio_ccw_private.h | |
parent | e5f84dbaea59b4f712dac428c337528b70e1c533 (diff) |
vfio: ccw: introduce a finite state machine
The current implementation doesn't check if the subchannel is in a
proper device state when handling an event. Let's introduce
a finite state machine to manage the state/event change.
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
Message-Id: <20170317031743.40128-14-bjsdjshi@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/vfio_ccw_private.h')
-rw-r--r-- | drivers/s390/cio/vfio_ccw_private.h | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h index 2503797fb153..fc0f01c16ef9 100644 --- a/drivers/s390/cio/vfio_ccw_private.h +++ b/drivers/s390/cio/vfio_ccw_private.h @@ -21,6 +21,7 @@ /** * struct vfio_ccw_private * @sch: pointer to the subchannel + * @state: internal state of the device * @completion: synchronization helper of the I/O completion * @avail: available for creating a mediated device * @mdev: pointer to the mediated device @@ -34,6 +35,7 @@ */ struct vfio_ccw_private { struct subchannel *sch; + int state; struct completion *completion; atomic_t avail; struct mdev_device *mdev; @@ -52,6 +54,43 @@ 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); -extern int vfio_ccw_sch_cmd_request(struct vfio_ccw_private *private); + +/* + * States of the device statemachine. + */ +enum vfio_ccw_state { + VFIO_CCW_STATE_NOT_OPER, + VFIO_CCW_STATE_STANDBY, + VFIO_CCW_STATE_IDLE, + VFIO_CCW_STATE_BOXED, + VFIO_CCW_STATE_BUSY, + /* 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; #endif |