Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 094f2100 authored by Michael Ernst's avatar Michael Ernst Committed by Martin Schwidefsky
Browse files

[S390] cio: unit check handling during internal I/O



Send unit checks that occur during internal I/O to the device driver
and react according to its return code.

Signed-off-by: default avatarMichael Ernst <mernst@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent c560d105
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -91,6 +91,14 @@ struct ccw_device {
	void (*handler) (struct ccw_device *, unsigned long, struct irb *);
};

/*
 * Possible CIO actions triggered by the unit check handler.
 */
enum uc_todo {
	UC_TODO_RETRY,
	UC_TODO_RETRY_ON_NEW_PATH,
	UC_TODO_STOP
};

/**
 * struct ccw driver - device driver for channel attached devices
@@ -107,6 +115,7 @@ struct ccw_device {
 * @freeze: callback for freezing during hibernation snapshotting
 * @thaw: undo work done in @freeze
 * @restore: callback for restoring after hibernation
 * @uc_handler: callback for unit check handler
 * @driver: embedded device driver structure
 * @name: device driver name
 */
@@ -124,6 +133,7 @@ struct ccw_driver {
	int (*freeze)(struct ccw_device *);
	int (*thaw) (struct ccw_device *);
	int (*restore)(struct ccw_device *);
	enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *);
	struct device_driver driver;
	char *name;
};
+15 −0
Original line number Diff line number Diff line
@@ -159,6 +159,7 @@ static enum io_status ccwreq_status(struct ccw_device *cdev, struct irb *lcirb)
{
	struct irb *irb = &cdev->private->irb;
	struct cmd_scsw *scsw = &irb->scsw.cmd;
	enum uc_todo todo;

	/* Perform BASIC SENSE if needed. */
	if (ccw_device_accumulate_and_sense(cdev, lcirb))
@@ -178,6 +179,20 @@ static enum io_status ccwreq_status(struct ccw_device *cdev, struct irb *lcirb)
		/* Check for command reject. */
		if (irb->ecw[0] & SNS0_CMD_REJECT)
			return IO_REJECTED;
		/* Ask the driver what to do */
		if (cdev->drv && cdev->drv->uc_handler) {
			todo = cdev->drv->uc_handler(cdev, lcirb);
			switch (todo) {
			case UC_TODO_RETRY:
				return IO_STATUS_ERROR;
			case UC_TODO_RETRY_ON_NEW_PATH:
				return IO_PATH_ERROR;
			case UC_TODO_STOP:
				return IO_REJECTED;
			default:
				return IO_STATUS_ERROR;
			}
		}
		/* Assume that unexpected SENSE data implies an error. */
		return IO_STATUS_ERROR;
	}