forked from Minki/linux
[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: Michael Ernst <mernst@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
c560d105a1
commit
094f2100d6
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user