drivers/s390/cio/device_status.c

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

File Facts

System
Linux kernel
Corpus path
drivers/s390/cio/device_status.c
Extension
.c
Size
12656 bytes
Lines
401
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 (cdev_irb->esw.esw0.erw.fsavf) {
			/* ... and copy the failing storage address. */
			memcpy(cdev_irb->esw.esw0.faddr, irb->esw.esw0.faddr,
			       sizeof (irb->esw.esw0.faddr));
			/* ... and copy the failing storage address format. */
			cdev_irb->esw.esw0.erw.fsaf = irb->esw.esw0.erw.fsaf;
		}
		/* Copy secondary ccw address validity bit. */
		cdev_irb->esw.esw0.erw.scavf = irb->esw.esw0.erw.scavf;
		if (irb->esw.esw0.erw.scavf)
			/* ... and copy the secondary ccw address. */
			cdev_irb->esw.esw0.saddr = irb->esw.esw0.saddr;
		
	}
	/* FIXME: DCTI for format 2? */

	/* Copy authorization bit. */
	cdev_irb->esw.esw0.erw.auth = irb->esw.esw0.erw.auth;
	/* Copy path verification required flag. */
	cdev_irb->esw.esw0.erw.pvrf = irb->esw.esw0.erw.pvrf;
	if (irb->esw.esw0.erw.pvrf)
		cdev->private->flags.doverify = 1;
	/* Copy concurrent sense bit. */
	cdev_irb->esw.esw0.erw.cons = irb->esw.esw0.erw.cons;
	if (irb->esw.esw0.erw.cons)
		cdev_irb->esw.esw0.erw.scnt = irb->esw.esw0.erw.scnt;
}

/*
 * Accumulate status from irb to devstat.
 */
void
ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb)
{
	struct irb *cdev_irb;

	/*
	 * Check if the status pending bit is set in stctl.
	 * If not, the remaining bit have no meaning and we must ignore them.
	 * The esw is not meaningful as well...
	 */
	if (!(scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))
		return;

	/* Check for channel checks and interface control checks. */
	ccw_device_msg_control_check(cdev, irb);

	/* Check for path not operational. */
	if (scsw_is_valid_pno(&irb->scsw) && scsw_pno(&irb->scsw))
		ccw_device_path_notoper(cdev);
	/* No irb accumulation for transport mode irbs. */
	if (scsw_is_tm(&irb->scsw)) {
		memcpy(&cdev->private->dma_area->irb, irb, sizeof(struct irb));
		return;
	}
	/*
	 * Don't accumulate unsolicited interrupts.
	 */
	if (!scsw_is_solicited(&irb->scsw))
		return;

	cdev_irb = &cdev->private->dma_area->irb;

	/*
	 * If the clear function had been performed, all formerly pending
	 * status at the subchannel has been cleared and we must not pass
	 * intermediate accumulated status to the device driver.
	 */
	if (irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC)
		memset(&cdev->private->dma_area->irb, 0, sizeof(struct irb));

	/* Copy bits which are valid only for the start function. */
	if (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) {
		/* Copy key. */
		cdev_irb->scsw.cmd.key = irb->scsw.cmd.key;
		/* Copy suspend control bit. */
		cdev_irb->scsw.cmd.sctl = irb->scsw.cmd.sctl;
		/* Accumulate deferred condition code. */
		cdev_irb->scsw.cmd.cc |= irb->scsw.cmd.cc;
		/* Copy ccw format bit. */
		cdev_irb->scsw.cmd.fmt = irb->scsw.cmd.fmt;
		/* Copy prefetch bit. */
		cdev_irb->scsw.cmd.pfch = irb->scsw.cmd.pfch;
		/* Copy initial-status-interruption-control. */
		cdev_irb->scsw.cmd.isic = irb->scsw.cmd.isic;
		/* Copy address limit checking control. */
		cdev_irb->scsw.cmd.alcc = irb->scsw.cmd.alcc;
		/* Copy suppress suspend bit. */
		cdev_irb->scsw.cmd.ssi = irb->scsw.cmd.ssi;
	}

Annotation

Implementation Notes