drivers/s390/cio/vfio_ccw_fsm.c

Source file repositories/reference/linux-study-clean/drivers/s390/cio/vfio_ccw_fsm.c

File Facts

System
Linux kernel
Corpus path
drivers/s390/cio/vfio_ccw_fsm.c
Extension
.c
Size
11505 bytes
Lines
466
Domain
Driver Families
Bucket
drivers/s390
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (orb->tm.b) {
			io_region->ret_code = -EOPNOTSUPP;
			VFIO_CCW_MSG_EVENT(2,
					   "sch %x.%x.%04x: transport mode\n",
					   schid.cssid,
					   schid.ssid, schid.sch_no);
			errstr = "transport mode";
			goto err_out;
		}
		io_region->ret_code = cp_init(&private->cp, orb);
		if (io_region->ret_code) {
			VFIO_CCW_MSG_EVENT(2,
					   "sch %x.%x.%04x: cp_init=%d\n",
					   schid.cssid,
					   schid.ssid, schid.sch_no,
					   io_region->ret_code);
			errstr = "cp init";
			goto err_out;
		}

		io_region->ret_code = cp_prefetch(&private->cp);
		if (io_region->ret_code) {
			VFIO_CCW_MSG_EVENT(2,
					   "sch %x.%x.%04x: cp_prefetch=%d\n",
					   schid.cssid,
					   schid.ssid, schid.sch_no,
					   io_region->ret_code);
			errstr = "cp prefetch";
			cp_free(&private->cp);
			goto err_out;
		}

		/* Start channel program and wait for I/O interrupt. */
		io_region->ret_code = fsm_io_helper(private);
		if (io_region->ret_code) {
			VFIO_CCW_MSG_EVENT(2,
					   "sch %x.%x.%04x: fsm_io_helper=%d\n",
					   schid.cssid,
					   schid.ssid, schid.sch_no,
					   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) {
		VFIO_CCW_MSG_EVENT(2,
				   "sch %x.%x.%04x: halt on io_region\n",
				   schid.cssid,
				   schid.ssid, schid.sch_no);
		/* halt is handled via the async cmd region */
		io_region->ret_code = -EOPNOTSUPP;
		goto err_out;
	} else if (scsw->cmd.fctl & SCSW_FCTL_CLEAR_FUNC) {
		VFIO_CCW_MSG_EVENT(2,
				   "sch %x.%x.%04x: clear on io_region\n",
				   schid.cssid,
				   schid.ssid, schid.sch_no);
		/* clear is handled via the async cmd region */
		io_region->ret_code = -EOPNOTSUPP;
		goto err_out;
	}

err_out:
	private->state = VFIO_CCW_STATE_IDLE;
	trace_vfio_ccw_fsm_io_request(scsw->cmd.fctl, schid,
				      io_region->ret_code, errstr);
}

/*
 * Deal with an async request from userspace.
 */
static void fsm_async_request(struct vfio_ccw_private *private,
			      enum vfio_ccw_event event)
{
	struct ccw_cmd_region *cmd_region = private->cmd_region;

	switch (cmd_region->command) {
	case VFIO_CCW_ASYNC_CMD_HSCH:
		cmd_region->ret_code = fsm_do_halt(private);
		break;
	case VFIO_CCW_ASYNC_CMD_CSCH:
		cmd_region->ret_code = fsm_do_clear(private);
		break;
	default:
		/* should not happen? */
		cmd_region->ret_code = -EINVAL;
	}

	trace_vfio_ccw_fsm_async_request(get_schid(private),

Annotation

Implementation Notes