drivers/s390/cio/device_ops.c

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

File Facts

System
Linux kernel
Corpus path
drivers/s390/cio/device_ops.c
Extension
.c
Size
27659 bytes
Lines
871
Domain
Driver Families
Bucket
drivers/s390
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (!cdev->private->flags.fake_irb) {
			cdev->private->flags.fake_irb = FAKE_CMD_IRB;
			cdev->private->intparm = intparm;
			CIO_MSG_EVENT(2, "fakeirb: queue device 0.%x.%04x intparm %lx type=%d\n",
				      cdev->private->dev_id.ssid,
				      cdev->private->dev_id.devno, intparm,
				      cdev->private->flags.fake_irb);
			return 0;
		} else
			/* There's already a fake I/O around. */
			return -EBUSY;
	}
	if (cdev->private->state != DEV_STATE_ONLINE ||
	    ((sch->schib.scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) &&
	     !(sch->schib.scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS)))
		return -EBUSY;
	ret = cio_set_options (sch, flags);
	if (ret)
		return ret;
	/* Adjust requested path mask to exclude unusable paths. */
	if (lpm) {
		lpm &= sch->lpm;
		if (lpm == 0)
			return -EACCES;
	}
	ret = cio_start_key (sch, cpa, lpm, key);
	switch (ret) {
	case 0:
		cdev->private->intparm = intparm;
		if (expires)
			ccw_device_set_timeout(cdev, expires);
		break;
	case -EACCES:
	case -ENODEV:
		dev_fsm_event(cdev, DEV_EVENT_VERIFY);
		break;
	}
	return ret;
}

/**
 * ccw_device_start_key() - start a s390 channel program with key
 * @cdev: target ccw device
 * @cpa: logical start address of channel program
 * @intparm: user specific interruption parameter; will be presented back to
 *	     @cdev's interrupt handler. Allows a device driver to associate
 *	     the interrupt with a particular I/O request.
 * @lpm: defines the channel path to be used for a specific I/O request. A
 *	 value of 0 will make cio use the opm.
 * @key: storage key to be used for the I/O
 * @flags: additional flags; defines the action to be performed for I/O
 *	   processing.
 *
 * Start a S/390 channel program. When the interrupt arrives, the
 * IRQ handler is called, either immediately, delayed (dev-end missing,
 * or sense required) or never (no IRQ handler registered).
 * The interruption handler will echo back the @intparm specified here, unless
 * another interruption parameter is specified by a subsequent invocation of
 * ccw_device_halt() or ccw_device_clear().
 * Returns:
 *  %0, if the operation was successful;
 *  -%EBUSY, if the device is busy, or status pending;
 *  -%EACCES, if no path specified in @lpm is operational;
 *  -%ENODEV, if the device is not operational.
 * Context:
 *  Interrupts disabled, ccw device lock held
 */
int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
			 unsigned long intparm, __u8 lpm, __u8 key,
			 unsigned long flags)
{
	return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm, key,
					    flags, 0);
}

/**
 * ccw_device_start() - start a s390 channel program
 * @cdev: target ccw device
 * @cpa: logical start address of channel program
 * @intparm: user specific interruption parameter; will be presented back to
 *	     @cdev's interrupt handler. Allows a device driver to associate
 *	     the interrupt with a particular I/O request.
 * @lpm: defines the channel path to be used for a specific I/O request. A
 *	 value of 0 will make cio use the opm.
 * @flags: additional flags; defines the action to be performed for I/O
 *	   processing.
 *
 * Start a S/390 channel program. When the interrupt arrives, the
 * IRQ handler is called, either immediately, delayed (dev-end missing,
 * or sense required) or never (no IRQ handler registered).

Annotation

Implementation Notes