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

authored by Stefan Haberland and committed by Martin Schwidefsky 6c5f57c7 a3afe70b

+52 -27
+6 -11
drivers/s390/block/dasd.c
··· 1057 1057 if (device->features & DASD_FEATURE_ERPLOG) { 1058 1058 dasd_log_sense(cqr, irb); 1059 1059 } 1060 - /* If we have no sense data, or we just don't want complex ERP 1061 - * for this request, but if we have retries left, then just 1062 - * reset this request and retry it in the fastpath 1060 + /* 1061 + * If we don't want complex ERP for this request, then just 1062 + * reset this and retry it in the fastpath 1063 1063 */ 1064 - if (!(cqr->irb.esw.esw0.erw.cons && 1065 - test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags)) && 1064 + if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags) && 1066 1065 cqr->retries > 0) { 1067 1066 DEV_MESSAGE(KERN_DEBUG, device, 1068 1067 "default ERP in fastpath (%i retries left)", ··· 1741 1742 1742 1743 /* Process requests that may be recovered */ 1743 1744 if (cqr->status == DASD_CQR_NEED_ERP) { 1744 - if (cqr->irb.esw.esw0.erw.cons && 1745 - test_bit(DASD_CQR_FLAGS_USE_ERP, 1746 - &cqr->flags)) { 1747 - erp_fn = base->discipline->erp_action(cqr); 1748 - erp_fn(cqr); 1749 - } 1745 + erp_fn = base->discipline->erp_action(cqr); 1746 + erp_fn(cqr); 1750 1747 goto restart; 1751 1748 } 1752 1749
+46 -16
drivers/s390/block/dasd_3990_erp.c
··· 164 164 165 165 /* reset status to submit the request again... */ 166 166 erp->status = DASD_CQR_FILLED; 167 - erp->retries = 1; 167 + erp->retries = 10; 168 168 } else { 169 169 DEV_MESSAGE(KERN_ERR, device, 170 170 "No alternate channel path left (lpum=%x / " ··· 301 301 erp->function = dasd_3990_erp_action_4; 302 302 303 303 } else { 304 - 305 - if (sense[25] == 0x1D) { /* state change pending */ 304 + if (sense && (sense[25] == 0x1D)) { /* state change pending */ 306 305 307 306 DEV_MESSAGE(KERN_INFO, device, 308 307 "waiting for state change pending " ··· 310 311 311 312 dasd_3990_erp_block_queue(erp, 30*HZ); 312 313 313 - } else if (sense[25] == 0x1E) { /* busy */ 314 + } else if (sense && (sense[25] == 0x1E)) { /* busy */ 314 315 DEV_MESSAGE(KERN_INFO, device, 315 316 "busy - redriving request later, " 316 317 "%d retries left", ··· 2119 2120 */ 2120 2121 2121 2122 /* 2123 + * DASD_3990_ERP_CONTROL_CHECK 2124 + * 2125 + * DESCRIPTION 2126 + * Does a generic inspection if a control check occured and sets up 2127 + * the related error recovery procedure 2128 + * 2129 + * PARAMETER 2130 + * erp pointer to the currently created default ERP 2131 + * 2132 + * RETURN VALUES 2133 + * erp_filled pointer to the erp 2134 + */ 2135 + 2136 + static struct dasd_ccw_req * 2137 + dasd_3990_erp_control_check(struct dasd_ccw_req *erp) 2138 + { 2139 + struct dasd_device *device = erp->startdev; 2140 + 2141 + if (erp->refers->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK 2142 + | SCHN_STAT_CHN_CTRL_CHK)) { 2143 + DEV_MESSAGE(KERN_DEBUG, device, "%s", 2144 + "channel or interface control check"); 2145 + erp = dasd_3990_erp_action_4(erp, NULL); 2146 + } 2147 + return erp; 2148 + } 2149 + 2150 + /* 2122 2151 * DASD_3990_ERP_INSPECT 2123 2152 * 2124 2153 * DESCRIPTION ··· 2172 2145 if (erp_new) 2173 2146 return erp_new; 2174 2147 2148 + /* check if no concurrent sens is available */ 2149 + if (!erp->refers->irb.esw.esw0.erw.cons) 2150 + erp_new = dasd_3990_erp_control_check(erp); 2175 2151 /* distinguish between 24 and 32 byte sense data */ 2176 - if (sense[27] & DASD_SENSE_BIT_0) { 2152 + else if (sense[27] & DASD_SENSE_BIT_0) { 2177 2153 2178 2154 /* inspect the 24 byte sense data */ 2179 2155 erp_new = dasd_3990_erp_inspect_24(erp, sense); ··· 2315 2285 // return 0; /* CCW doesn't match */ 2316 2286 } 2317 2287 2288 + if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons) 2289 + return 0; 2290 + 2291 + if ((cqr1->irb.esw.esw0.erw.cons == 0) && 2292 + (cqr2->irb.esw.esw0.erw.cons == 0)) { 2293 + if ((cqr1->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK | 2294 + SCHN_STAT_CHN_CTRL_CHK)) == 2295 + (cqr2->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK | 2296 + SCHN_STAT_CHN_CTRL_CHK))) 2297 + return 1; /* match with ifcc*/ 2298 + } 2318 2299 /* check sense data; byte 0-2,25,27 */ 2319 2300 if (!((memcmp (cqr1->irb.ecw, cqr2->irb.ecw, 3) == 0) && 2320 2301 (cqr1->irb.ecw[27] == cqr2->irb.ecw[27]) && ··· 2600 2559 cqr->status = DASD_CQR_DONE; 2601 2560 2602 2561 return cqr; 2603 - } 2604 - /* check if sense data are available */ 2605 - if (!cqr->irb.ecw) { 2606 - DEV_MESSAGE(KERN_DEBUG, device, 2607 - "ERP called witout sense data avail ..." 2608 - "request %p - NO ERP possible", cqr); 2609 - 2610 - cqr->status = DASD_CQR_FAILED; 2611 - 2612 - return cqr; 2613 - 2614 2562 } 2615 2563 2616 2564 /* check if error happened before */