linux/drivers/s390/cio/vfio_ccw_fsm.c
/*
 * Deal with the ccw command request from the userspace.
 */
Deal with the ccw command request from the userspace.
Deal with the ccw command request from the userspace .
static void fsm_io_request(struct vfio_ccw_private *private,
			   enum vfio_ccw_event event)
{
	union orb *orb;
	union scsw *scsw = &private->scsw;
	struct ccw_io_region *io_region = private->io_region;
	struct mdev_device *mdev = private->mdev;
	char *errstr = "request";
	private->state = VFIO_CCW_STATE_BOXED;
	memcpy(scsw, io_region->scsw_area, sizeof(*scsw));
	if (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) {
		orb = (union orb *)io_region->orb_area;
		if (orb->tm.b) {
			io_region->ret_code = -EOPNOTSUPP;
			errstr = "transport mode";
			goto err_out;
		}
		io_region->ret_code = cp_init(&private->cp, mdev_dev(mdev),
					      orb);
		if (io_region->ret_code) {
			errstr = "cp init";
			goto err_out;
		}
		io_region->ret_code = cp_prefetch(&private->cp);
		if (io_region->ret_code) {
			errstr = "cp prefetch";
			cp_free(&private->cp);
			goto err_out;
		}
		io_region->ret_code = fsm_io_helper(private);
		if (io_region->ret_code) {
			errstr = "cp fsm_io_helper";
			cp_free(&private->cp);
			goto err_out;
		}
		return;
	} else if (scsw->cmd.fctl & SCSW_FCTL_HALT_FUNC) {
		io_region->ret_code = -EOPNOTSUPP;
		goto err_out;
	} else if (scsw->cmd.fctl & SCSW_FCTL_CLEAR_FUNC) {
		io_region->ret_code = -EOPNOTSUPP;
		goto err_out;
	}
err_out:
	private->state = VFIO_CCW_STATE_IDLE;
	trace_vfio_ccw_io_fctl(scsw->cmd.fctl, get_schid(private),
			       io_region->ret_code, errstr);
}
static void fsm_io_request ( struct vfio_ccw_private * private , enum vfio_ccw_event event ) { union orb * orb ; union scsw * scsw = & private -> scsw ; struct ccw_io_region * io_region = private -> io_region ; struct mdev_device * mdev = private -> mdev ; char * errstr = " " ; private -> state = VFIO_CCW_STATE_BOXED ; memcpy ( scsw , io_region -> scsw_area , sizeof ( * scsw ) ) ; if ( scsw -> cmd . fctl & SCSW_FCTL_START_FUNC ) { orb = ( union orb * ) io_region -> orb_area ; if ( orb -> tm . b ) { io_region -> ret_code = - EOPNOTSUPP ; errstr = " " ; goto err_out ; } io_region -> ret_code = cp_init ( & private -> cp , mdev_dev ( mdev ) , orb ) ; if ( io_region -> ret_code ) { errstr = " " ; goto err_out ; } io_region -> ret_code = cp_prefetch ( & private -> cp ) ; if ( io_region -> ret_code ) { errstr = " " ; cp_free ( & private -> cp ) ; goto err_out ; } io_region -> ret_code = fsm_io_helper ( private ) ; if ( io_region -> ret_code ) { errstr = " " ; cp_free ( & private -> cp ) ; goto err_out ; } return ; } else if ( scsw -> cmd . fctl & SCSW_FCTL_HALT_FUNC ) { io_region -> ret_code = - EOPNOTSUPP ; goto err_out ; } else if ( scsw -> cmd . fctl & SCSW_FCTL_CLEAR_FUNC ) { io_region -> ret_code = - EOPNOTSUPP ; goto err_out ; } err_out : private -> state = VFIO_CCW_STATE_IDLE ; trace_vfio_ccw_io_fctl ( scsw -> cmd . fctl , get_schid ( private ) , io_region -> ret_code , errstr ) ; }
Deal with the ccw command request from the userspace.
Deal with the ccw command request from the userspace .
/* Don't try to build a cp if transport mode is specified. */ /* Start channel program and wait for I/O interrupt. */ /* XXX: Handle halt. */ /* XXX: Handle clear. */