/* reset status to submit the request again... */
erp->status = DASD_CQR_FILLED;
- erp->retries = 1;
+ erp->retries = 10;
} else {
DEV_MESSAGE(KERN_ERR, device,
"No alternate channel path left (lpum=%x / "
erp->function = dasd_3990_erp_action_4;
} else {
-
- if (sense[25] == 0x1D) { /* state change pending */
+ if (sense && (sense[25] == 0x1D)) { /* state change pending */
DEV_MESSAGE(KERN_INFO, device,
"waiting for state change pending "
dasd_3990_erp_block_queue(erp, 30*HZ);
- } else if (sense[25] == 0x1E) { /* busy */
+ } else if (sense && (sense[25] == 0x1E)) { /* busy */
DEV_MESSAGE(KERN_INFO, device,
"busy - redriving request later, "
"%d retries left",
} /* end dasd_3990_erp_compound */
+/*
+ *DASD_3990_ERP_HANDLE_SIM
+ *
+ *DESCRIPTION
+ * inspects the SIM SENSE data and starts an appropriate action
+ *
+ * PARAMETER
+ * sense sense data of the actual error
+ *
+ * RETURN VALUES
+ * none
+ */
+void
+dasd_3990_erp_handle_sim(struct dasd_device *device, char *sense)
+{
+ /* print message according to log or message to operator mode */
+ if ((sense[24] & DASD_SIM_MSG_TO_OP) || (sense[1] & 0x10)) {
+
+ /* print SIM SRC from RefCode */
+ DEV_MESSAGE(KERN_ERR, device, "SIM - SRC: "
+ "%02x%02x%02x%02x", sense[22],
+ sense[23], sense[11], sense[12]);
+ } else if (sense[24] & DASD_SIM_LOG) {
+ /* print SIM SRC Refcode */
+ DEV_MESSAGE(KERN_WARNING, device, "SIM - SRC: "
+ "%02x%02x%02x%02x", sense[22],
+ sense[23], sense[11], sense[12]);
+ }
+}
+
/*
* DASD_3990_ERP_INSPECT_32
*
erp->function = dasd_3990_erp_inspect_32;
+ /* check for SIM sense data */
+ if ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)
+ dasd_3990_erp_handle_sim(device, sense);
+
if (sense[25] & DASD_SENSE_BIT_0) {
/* compound program action codes (byte25 bit 0 == '1') */
*****************************************************************************
*/
+/*
+ * DASD_3990_ERP_CONTROL_CHECK
+ *
+ * DESCRIPTION
+ * Does a generic inspection if a control check occured and sets up
+ * the related error recovery procedure
+ *
+ * PARAMETER
+ * erp pointer to the currently created default ERP
+ *
+ * RETURN VALUES
+ * erp_filled pointer to the erp
+ */
+
+static struct dasd_ccw_req *
+dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
+{
+ struct dasd_device *device = erp->startdev;
+
+ if (erp->refers->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK
+ | SCHN_STAT_CHN_CTRL_CHK)) {
+ DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ "channel or interface control check");
+ erp = dasd_3990_erp_action_4(erp, NULL);
+ }
+ return erp;
+}
+
/*
* DASD_3990_ERP_INSPECT
*
if (erp_new)
return erp_new;
+ /* check if no concurrent sens is available */
+ if (!erp->refers->irb.esw.esw0.erw.cons)
+ erp_new = dasd_3990_erp_control_check(erp);
/* distinguish between 24 and 32 byte sense data */
- if (sense[27] & DASD_SENSE_BIT_0) {
+ else if (sense[27] & DASD_SENSE_BIT_0) {
/* inspect the 24 byte sense data */
erp_new = dasd_3990_erp_inspect_24(erp, sense);
dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
{
- /* check failed CCW */
- if (cqr1->irb.scsw.cpa != cqr2->irb.scsw.cpa) {
- // return 0; /* CCW doesn't match */
- }
+ if (cqr1->startdev != cqr2->startdev)
+ return 0;
+
+ if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons)
+ return 0;
+ if ((cqr1->irb.esw.esw0.erw.cons == 0) &&
+ (cqr2->irb.esw.esw0.erw.cons == 0)) {
+ if ((cqr1->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK |
+ SCHN_STAT_CHN_CTRL_CHK)) ==
+ (cqr2->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK |
+ SCHN_STAT_CHN_CTRL_CHK)))
+ return 1; /* match with ifcc*/
+ }
/* check sense data; byte 0-2,25,27 */
if (!((memcmp (cqr1->irb.ecw, cqr2->irb.ecw, 3) == 0) &&
(cqr1->irb.ecw[27] == cqr2->irb.ecw[27]) &&
return cqr;
}
- /* check if sense data are available */
- if (!cqr->irb.ecw) {
- DEV_MESSAGE(KERN_DEBUG, device,
- "ERP called witout sense data avail ..."
- "request %p - NO ERP possible", cqr);
-
- cqr->status = DASD_CQR_FAILED;
-
- return cqr;
-
- }
/* check if error happened before */
erp = dasd_3990_erp_in_erp(cqr);