Commit 62ec0d49 authored by Eric Farman's avatar Eric Farman Committed by Alex Williamson
Browse files

vfio/ccw: Create an OPEN FSM Event



Move the process of enabling a subchannel for use by vfio-ccw
into the FSM, such that it can manage the sequence of lifecycle
events for the device.

That is, if the FSM state is NOT_OPER(erational), then do the work
that would enable the subchannel and move the FSM to STANDBY state.
An attempt to perform this event again from any of the other operating
states (IDLE, CP_PROCESSING, CP_PENDING) will convert the device back
to NOT_OPER so the configuration process can be started again.

Signed-off-by: default avatarEric Farman <farman@linux.ibm.com>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarMatthew Rosato <mjrosato@linux.ibm.com>
Link: https://lore.kernel.org/r/20220707135737.720765-9-farman@linux.ibm.com


Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent 4cc2c051
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -231,15 +231,10 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)

	dev_set_drvdata(&sch->dev, private);

	spin_lock_irq(sch->lock);
	sch->isc = VFIO_CCW_ISC;
	ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
	spin_unlock_irq(sch->lock);
	if (ret)
	vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_OPEN);
	if (private->state == VFIO_CCW_STATE_NOT_OPER)
		goto out_free;

	private->state = VFIO_CCW_STATE_STANDBY;

	ret = mdev_register_device(&sch->dev, &vfio_ccw_mdev_driver);
	if (ret)
		goto out_disable;
+21 −0
Original line number Diff line number Diff line
@@ -11,6 +11,8 @@

#include <linux/vfio.h>

#include <asm/isc.h>

#include "ioasm.h"
#include "vfio_ccw_private.h"

@@ -368,6 +370,20 @@ static void fsm_irq(struct vfio_ccw_private *private,
		complete(private->completion);
}

static void fsm_open(struct vfio_ccw_private *private,
		     enum vfio_ccw_event event)
{
	struct subchannel *sch = private->sch;
	int ret;

	spin_lock_irq(sch->lock);
	sch->isc = VFIO_CCW_ISC;
	ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
	if (!ret)
		private->state = VFIO_CCW_STATE_STANDBY;
	spin_unlock_irq(sch->lock);
}

/*
 * Device statemachine
 */
@@ -377,29 +393,34 @@ fsm_func_t *vfio_ccw_jumptable[NR_VFIO_CCW_STATES][NR_VFIO_CCW_EVENTS] = {
		[VFIO_CCW_EVENT_IO_REQ]		= fsm_io_error,
		[VFIO_CCW_EVENT_ASYNC_REQ]	= fsm_async_error,
		[VFIO_CCW_EVENT_INTERRUPT]	= fsm_disabled_irq,
		[VFIO_CCW_EVENT_OPEN]		= fsm_open,
	},
	[VFIO_CCW_STATE_STANDBY] = {
		[VFIO_CCW_EVENT_NOT_OPER]	= fsm_notoper,
		[VFIO_CCW_EVENT_IO_REQ]		= fsm_io_error,
		[VFIO_CCW_EVENT_ASYNC_REQ]	= fsm_async_error,
		[VFIO_CCW_EVENT_INTERRUPT]	= fsm_irq,
		[VFIO_CCW_EVENT_OPEN]		= fsm_notoper,
	},
	[VFIO_CCW_STATE_IDLE] = {
		[VFIO_CCW_EVENT_NOT_OPER]	= fsm_notoper,
		[VFIO_CCW_EVENT_IO_REQ]		= fsm_io_request,
		[VFIO_CCW_EVENT_ASYNC_REQ]	= fsm_async_request,
		[VFIO_CCW_EVENT_INTERRUPT]	= fsm_irq,
		[VFIO_CCW_EVENT_OPEN]		= fsm_notoper,
	},
	[VFIO_CCW_STATE_CP_PROCESSING] = {
		[VFIO_CCW_EVENT_NOT_OPER]	= fsm_notoper,
		[VFIO_CCW_EVENT_IO_REQ]		= fsm_io_retry,
		[VFIO_CCW_EVENT_ASYNC_REQ]	= fsm_async_retry,
		[VFIO_CCW_EVENT_INTERRUPT]	= fsm_irq,
		[VFIO_CCW_EVENT_OPEN]		= fsm_notoper,
	},
	[VFIO_CCW_STATE_CP_PENDING] = {
		[VFIO_CCW_EVENT_NOT_OPER]	= fsm_notoper,
		[VFIO_CCW_EVENT_IO_REQ]		= fsm_io_busy,
		[VFIO_CCW_EVENT_ASYNC_REQ]	= fsm_async_request,
		[VFIO_CCW_EVENT_INTERRUPT]	= fsm_irq,
		[VFIO_CCW_EVENT_OPEN]		= fsm_notoper,
	},
};
+1 −0
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ enum vfio_ccw_event {
	VFIO_CCW_EVENT_IO_REQ,
	VFIO_CCW_EVENT_INTERRUPT,
	VFIO_CCW_EVENT_ASYNC_REQ,
	VFIO_CCW_EVENT_OPEN,
	/* last element! */
	NR_VFIO_CCW_EVENTS
};