[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>

authored by Michael Ernst and committed by Martin Schwidefsky 094f2100 c560d105

+25
+10
arch/s390/include/asm/ccwdev.h
··· 91 91 void (*handler) (struct ccw_device *, unsigned long, struct irb *); 92 92 }; 93 93 94 + /* 95 + * Possible CIO actions triggered by the unit check handler. 96 + */ 97 + enum uc_todo { 98 + UC_TODO_RETRY, 99 + UC_TODO_RETRY_ON_NEW_PATH, 100 + UC_TODO_STOP 101 + }; 94 102 95 103 /** 96 104 * struct ccw driver - device driver for channel attached devices ··· 115 107 * @freeze: callback for freezing during hibernation snapshotting 116 108 * @thaw: undo work done in @freeze 117 109 * @restore: callback for restoring after hibernation 110 + * @uc_handler: callback for unit check handler 118 111 * @driver: embedded device driver structure 119 112 * @name: device driver name 120 113 */ ··· 133 124 int (*freeze)(struct ccw_device *); 134 125 int (*thaw) (struct ccw_device *); 135 126 int (*restore)(struct ccw_device *); 127 + enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *); 136 128 struct device_driver driver; 137 129 char *name; 138 130 };
+15
drivers/s390/cio/ccwreq.c
··· 159 159 { 160 160 struct irb *irb = &cdev->private->irb; 161 161 struct cmd_scsw *scsw = &irb->scsw.cmd; 162 + enum uc_todo todo; 162 163 163 164 /* Perform BASIC SENSE if needed. */ 164 165 if (ccw_device_accumulate_and_sense(cdev, lcirb)) ··· 179 178 /* Check for command reject. */ 180 179 if (irb->ecw[0] & SNS0_CMD_REJECT) 181 180 return IO_REJECTED; 181 + /* Ask the driver what to do */ 182 + if (cdev->drv && cdev->drv->uc_handler) { 183 + todo = cdev->drv->uc_handler(cdev, lcirb); 184 + switch (todo) { 185 + case UC_TODO_RETRY: 186 + return IO_STATUS_ERROR; 187 + case UC_TODO_RETRY_ON_NEW_PATH: 188 + return IO_PATH_ERROR; 189 + case UC_TODO_STOP: 190 + return IO_REJECTED; 191 + default: 192 + return IO_STATUS_ERROR; 193 + } 194 + } 182 195 /* Assume that unexpected SENSE data implies an error. */ 183 196 return IO_STATUS_ERROR; 184 197 }