aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Haberland <stefan.haberland@de.ibm.com>2008-02-05 10:50:46 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-02-05 10:50:59 -0500
commit6c5f57c7884a7e0806ae9af86de243321cab4953 (patch)
tree40794edbe388da6e9da03ce42ec13e520914a022
parenta3afe70b83fdbbd4d757d2911900d168bc798a31 (diff)
[S390] dasd: add ifcc handling
Adding interface control check (ifcc) handling in error recovery. First retry up to 255 times and if all retries fail try an alternate path if possible. Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/block/dasd.c17
-rw-r--r--drivers/s390/block/dasd_3990_erp.c62
2 files changed, 52 insertions, 27 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index d640427c74c8..ab4f64c49829 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1057,12 +1057,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1057 if (device->features & DASD_FEATURE_ERPLOG) { 1057 if (device->features & DASD_FEATURE_ERPLOG) {
1058 dasd_log_sense(cqr, irb); 1058 dasd_log_sense(cqr, irb);
1059 } 1059 }
1060 /* If we have no sense data, or we just don't want complex ERP 1060 /*
1061 * for this request, but if we have retries left, then just 1061 * If we don't want complex ERP for this request, then just
1062 * reset this request and retry it in the fastpath 1062 * reset this and retry it in the fastpath
1063 */ 1063 */
1064 if (!(cqr->irb.esw.esw0.erw.cons && 1064 if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags) &&
1065 test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags)) &&
1066 cqr->retries > 0) { 1065 cqr->retries > 0) {
1067 DEV_MESSAGE(KERN_DEBUG, device, 1066 DEV_MESSAGE(KERN_DEBUG, device,
1068 "default ERP in fastpath (%i retries left)", 1067 "default ERP in fastpath (%i retries left)",
@@ -1742,12 +1741,8 @@ restart:
1742 1741
1743 /* Process requests that may be recovered */ 1742 /* Process requests that may be recovered */
1744 if (cqr->status == DASD_CQR_NEED_ERP) { 1743 if (cqr->status == DASD_CQR_NEED_ERP) {
1745 if (cqr->irb.esw.esw0.erw.cons && 1744 erp_fn = base->discipline->erp_action(cqr);
1746 test_bit(DASD_CQR_FLAGS_USE_ERP, 1745 erp_fn(cqr);
1747 &cqr->flags)) {
1748 erp_fn = base->discipline->erp_action(cqr);
1749 erp_fn(cqr);
1750 }
1751 goto restart; 1746 goto restart;
1752 } 1747 }
1753 1748
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index c361ab69ec00..f69714a0e9e7 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -164,7 +164,7 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
164 164
165 /* reset status to submit the request again... */ 165 /* reset status to submit the request again... */
166 erp->status = DASD_CQR_FILLED; 166 erp->status = DASD_CQR_FILLED;
167 erp->retries = 1; 167 erp->retries = 10;
168 } else { 168 } else {
169 DEV_MESSAGE(KERN_ERR, device, 169 DEV_MESSAGE(KERN_ERR, device,
170 "No alternate channel path left (lpum=%x / " 170 "No alternate channel path left (lpum=%x / "
@@ -301,8 +301,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
301 erp->function = dasd_3990_erp_action_4; 301 erp->function = dasd_3990_erp_action_4;
302 302
303 } else { 303 } else {
304 304 if (sense && (sense[25] == 0x1D)) { /* state change pending */
305 if (sense[25] == 0x1D) { /* state change pending */
306 305
307 DEV_MESSAGE(KERN_INFO, device, 306 DEV_MESSAGE(KERN_INFO, device,
308 "waiting for state change pending " 307 "waiting for state change pending "
@@ -311,7 +310,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
311 310
312 dasd_3990_erp_block_queue(erp, 30*HZ); 311 dasd_3990_erp_block_queue(erp, 30*HZ);
313 312
314 } else if (sense[25] == 0x1E) { /* busy */ 313 } else if (sense && (sense[25] == 0x1E)) { /* busy */
315 DEV_MESSAGE(KERN_INFO, device, 314 DEV_MESSAGE(KERN_INFO, device,
316 "busy - redriving request later, " 315 "busy - redriving request later, "
317 "%d retries left", 316 "%d retries left",
@@ -2120,6 +2119,34 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
2120 */ 2119 */
2121 2120
2122/* 2121/*
2122 * DASD_3990_ERP_CONTROL_CHECK
2123 *
2124 * DESCRIPTION
2125 * Does a generic inspection if a control check occured and sets up
2126 * the related error recovery procedure
2127 *
2128 * PARAMETER
2129 * erp pointer to the currently created default ERP
2130 *
2131 * RETURN VALUES
2132 * erp_filled pointer to the erp
2133 */
2134
2135static struct dasd_ccw_req *
2136dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
2137{
2138 struct dasd_device *device = erp->startdev;
2139
2140 if (erp->refers->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK
2141 | SCHN_STAT_CHN_CTRL_CHK)) {
2142 DEV_MESSAGE(KERN_DEBUG, device, "%s",
2143 "channel or interface control check");
2144 erp = dasd_3990_erp_action_4(erp, NULL);
2145 }
2146 return erp;
2147}
2148
2149/*
2123 * DASD_3990_ERP_INSPECT 2150 * DASD_3990_ERP_INSPECT
2124 * 2151 *
2125 * DESCRIPTION 2152 * DESCRIPTION
@@ -2145,8 +2172,11 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
2145 if (erp_new) 2172 if (erp_new)
2146 return erp_new; 2173 return erp_new;
2147 2174
2175 /* check if no concurrent sens is available */
2176 if (!erp->refers->irb.esw.esw0.erw.cons)
2177 erp_new = dasd_3990_erp_control_check(erp);
2148 /* distinguish between 24 and 32 byte sense data */ 2178 /* distinguish between 24 and 32 byte sense data */
2149 if (sense[27] & DASD_SENSE_BIT_0) { 2179 else if (sense[27] & DASD_SENSE_BIT_0) {
2150 2180
2151 /* inspect the 24 byte sense data */ 2181 /* inspect the 24 byte sense data */
2152 erp_new = dasd_3990_erp_inspect_24(erp, sense); 2182 erp_new = dasd_3990_erp_inspect_24(erp, sense);
@@ -2285,6 +2315,17 @@ dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
2285 // return 0; /* CCW doesn't match */ 2315 // return 0; /* CCW doesn't match */
2286 } 2316 }
2287 2317
2318 if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons)
2319 return 0;
2320
2321 if ((cqr1->irb.esw.esw0.erw.cons == 0) &&
2322 (cqr2->irb.esw.esw0.erw.cons == 0)) {
2323 if ((cqr1->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK |
2324 SCHN_STAT_CHN_CTRL_CHK)) ==
2325 (cqr2->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK |
2326 SCHN_STAT_CHN_CTRL_CHK)))
2327 return 1; /* match with ifcc*/
2328 }
2288 /* check sense data; byte 0-2,25,27 */ 2329 /* check sense data; byte 0-2,25,27 */
2289 if (!((memcmp (cqr1->irb.ecw, cqr2->irb.ecw, 3) == 0) && 2330 if (!((memcmp (cqr1->irb.ecw, cqr2->irb.ecw, 3) == 0) &&
2290 (cqr1->irb.ecw[27] == cqr2->irb.ecw[27]) && 2331 (cqr1->irb.ecw[27] == cqr2->irb.ecw[27]) &&
@@ -2560,17 +2601,6 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
2560 2601
2561 return cqr; 2602 return cqr;
2562 } 2603 }
2563 /* check if sense data are available */
2564 if (!cqr->irb.ecw) {
2565 DEV_MESSAGE(KERN_DEBUG, device,
2566 "ERP called witout sense data avail ..."
2567 "request %p - NO ERP possible", cqr);
2568
2569 cqr->status = DASD_CQR_FAILED;
2570
2571 return cqr;
2572
2573 }
2574 2604
2575 /* check if error happened before */ 2605 /* check if error happened before */
2576 erp = dasd_3990_erp_in_erp(cqr); 2606 erp = dasd_3990_erp_in_erp(cqr);