*
*/
+#define KMSG_COMPONENT "dasd-eckd"
+
#include <linux/timer.h>
-#include <linux/slab.h>
#include <asm/idals.h>
-#include <asm/todclk.h>
#define PRINTK_HEADER "dasd_erp(3990): "
/*
*****************************************************************************
- * SECTION ERP EXAMINATION
- *****************************************************************************
- */
-
-/*
- * DASD_3990_ERP_EXAMINE_24
- *
- * DESCRIPTION
- * Checks only for fatal (unrecoverable) error.
- * A detailed examination of the sense data is done later outside
- * the interrupt handler.
- *
- * Each bit configuration leading to an action code 2 (Exit with
- * programming error or unusual condition indication)
- * are handled as fatal errorĀ“s.
- *
- * All other configurations are handled as recoverable errors.
- *
- * RETURN VALUES
- * dasd_era_fatal for all fatal (unrecoverable errors)
- * dasd_era_recover for all others.
- */
-static dasd_era_t
-dasd_3990_erp_examine_24(struct dasd_ccw_req * cqr, char *sense)
-{
-
- struct dasd_device *device = cqr->device;
-
- /* check for 'Command Reject' */
- if ((sense[0] & SNS0_CMD_REJECT) &&
- (!(sense[2] & SNS2_ENV_DATA_PRESENT))) {
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "EXAMINE 24: Command Reject detected - "
- "fatal error");
-
- return dasd_era_fatal;
- }
-
- /* check for 'Invalid Track Format' */
- if ((sense[1] & SNS1_INV_TRACK_FORMAT) &&
- (!(sense[2] & SNS2_ENV_DATA_PRESENT))) {
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "EXAMINE 24: Invalid Track Format detected "
- "- fatal error");
-
- return dasd_era_fatal;
- }
-
- /* check for 'No Record Found' */
- if (sense[1] & SNS1_NO_REC_FOUND) {
-
- /* FIXME: fatal error ?!? */
- DEV_MESSAGE(KERN_ERR, device,
- "EXAMINE 24: No Record Found detected %s",
- device->state <= DASD_STATE_BASIC ?
- " " : "- fatal error");
-
- return dasd_era_fatal;
- }
-
- /* return recoverable for all others */
- return dasd_era_recover;
-} /* END dasd_3990_erp_examine_24 */
-
-/*
- * DASD_3990_ERP_EXAMINE_32
- *
- * DESCRIPTION
- * Checks only for fatal/no/recoverable error.
- * A detailed examination of the sense data is done later outside
- * the interrupt handler.
- *
- * RETURN VALUES
- * dasd_era_none no error
- * dasd_era_fatal for all fatal (unrecoverable errors)
- * dasd_era_recover for recoverable others.
- */
-static dasd_era_t
-dasd_3990_erp_examine_32(struct dasd_ccw_req * cqr, char *sense)
-{
-
- struct dasd_device *device = cqr->device;
-
- switch (sense[25]) {
- case 0x00:
- return dasd_era_none;
-
- case 0x01:
- DEV_MESSAGE(KERN_ERR, device, "%s", "EXAMINE 32: fatal error");
-
- return dasd_era_fatal;
-
- default:
-
- return dasd_era_recover;
- }
-
-} /* end dasd_3990_erp_examine_32 */
-
-/*
- * DASD_3990_ERP_EXAMINE
- *
- * DESCRIPTION
- * Checks only for fatal/no/recover error.
- * A detailed examination of the sense data is done later outside
- * the interrupt handler.
- *
- * The logic is based on the 'IBM 3990 Storage Control Reference' manual
- * 'Chapter 7. Error Recovery Procedures'.
- *
- * RETURN VALUES
- * dasd_era_none no error
- * dasd_era_fatal for all fatal (unrecoverable errors)
- * dasd_era_recover for all others.
- */
-dasd_era_t
-dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb)
-{
-
- char *sense = irb->ecw;
- dasd_era_t era = dasd_era_recover;
- struct dasd_device *device = cqr->device;
-
- /* check for successful execution first */
- if (irb->scsw.cstat == 0x00 &&
- irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
- return dasd_era_none;
-
- /* distinguish between 24 and 32 byte sense data */
- if (sense[27] & DASD_SENSE_BIT_0) {
-
- era = dasd_3990_erp_examine_24(cqr, sense);
-
- } else {
-
- era = dasd_3990_erp_examine_32(cqr, sense);
-
- }
-
- /* log the erp chain if fatal error occurred */
- if ((era == dasd_era_fatal) && (device->state >= DASD_STATE_READY)) {
- dasd_log_sense(cqr, irb);
- dasd_log_ccw(cqr, 0, irb->scsw.cpa);
- }
-
- return era;
-
-} /* END dasd_3990_erp_examine */
-
-/*
- *****************************************************************************
* SECTION ERP HANDLING
*****************************************************************************
*/
{
struct dasd_ccw_req *cqr = erp->refers;
- dasd_free_erp_request(erp, erp->device);
+ dasd_free_erp_request(erp, erp->memdev);
cqr->status = final_status;
return cqr;
* processing until the started timer has expired or an related
* interrupt was received.
*/
-static void
-dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires)
+static void dasd_3990_erp_block_queue(struct dasd_ccw_req *erp, int expires)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
+ unsigned long flags;
- DEV_MESSAGE(KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"blocking request queue for %is", expires/HZ);
- device->stopped |= DASD_STOPPED_PENDING;
- erp->status = DASD_CQR_QUEUED;
-
- dasd_set_timer(device, expires);
+ spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
+ dasd_device_set_stop_bits(device, DASD_STOPPED_PENDING);
+ spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
+ erp->status = DASD_CQR_FILLED;
+ if (erp->block)
+ dasd_block_set_timer(erp->block, expires);
+ else
+ dasd_device_set_timer(device, expires);
}
/*
dasd_3990_erp_int_req(struct dasd_ccw_req * erp)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
/* first time set initial retry counter and erp_function */
/* and retry once without blocking queue */
} else {
/* issue a message and wait for 'device ready' interrupt */
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ dev_err(&device->cdev->dev,
"is offline or not installed - "
- "INTERVENTION REQUIRED!!");
+ "INTERVENTION REQUIRED!!\n");
dasd_3990_erp_block_queue(erp, 60*HZ);
}
static void
dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
__u8 opm;
+ unsigned long flags;
/* try alternate valid path */
+ spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
opm = ccw_device_get_path_mask(device->cdev);
+ spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
//FIXME: start with get_opm ?
if (erp->lpm == 0)
erp->lpm = LPM_ANYPATH & ~(erp->irb.esw.esw0.sublog.lpum);
if ((erp->lpm & opm) != 0x00) {
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
"try alternate lpm=%x (lpum=%x / opm=%x)",
erp->lpm, erp->irb.esw.esw0.sublog.lpum, opm);
- /* reset status to queued to handle the request again... */
- if (erp->status > DASD_CQR_QUEUED)
- erp->status = DASD_CQR_QUEUED;
- erp->retries = 1;
+ /* reset status to submit the request again... */
+ erp->status = DASD_CQR_FILLED;
+ erp->retries = 10;
} else {
- DEV_MESSAGE(KERN_ERR, device,
- "No alternate channel path left (lpum=%x / "
- "opm=%x) -> permanent error",
- erp->irb.esw.esw0.sublog.lpum, opm);
+ dev_err(&device->cdev->dev,
+ "The DASD cannot be reached on any path (lpum=%x"
+ "/opm=%x)\n", erp->irb.esw.esw0.sublog.lpum, opm);
/* post request with permanent error */
- if (erp->status > DASD_CQR_QUEUED)
- erp->status = DASD_CQR_FAILED;
+ erp->status = DASD_CQR_FAILED;
}
} /* end dasd_3990_erp_alternate_path */
dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
struct DCTL_data *DCTL_data;
struct ccw1 *ccw;
struct dasd_ccw_req *dctl_cqr;
dctl_cqr = dasd_alloc_erp_request((char *) &erp->magic, 1,
- sizeof (struct DCTL_data),
- erp->device);
+ sizeof(struct DCTL_data),
+ device);
if (IS_ERR(dctl_cqr)) {
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Unable to allocate DCTL-CQR");
+ dev_err(&device->cdev->dev,
+ "Unable to allocate DCTL-CQR\n");
erp->status = DASD_CQR_FAILED;
return erp;
}
DCTL_data->modifier = modifier;
ccw = dctl_cqr->cpaddr;
- memset(ccw, 0, sizeof (struct ccw1));
+ memset(ccw, 0, sizeof(struct ccw1));
ccw->cmd_code = CCW_CMD_DCTL;
ccw->count = 4;
ccw->cda = (__u32)(addr_t) DCTL_data;
dctl_cqr->function = dasd_3990_erp_DCTL;
dctl_cqr->refers = erp;
- dctl_cqr->device = erp->device;
+ dctl_cqr->startdev = device;
+ dctl_cqr->memdev = device;
dctl_cqr->magic = erp->magic;
dctl_cqr->expires = 5 * 60 * HZ;
dctl_cqr->retries = 2;
* DESCRIPTION
* Setup ERP to do the ERP action 1 (see Reference manual).
* Repeat the operation on a different channel path.
- * If all alternate paths have been tried, the request is posted with a
- * permanent error.
- * Note: duplex handling is not implemented (yet).
+ * As deviation from the recommended recovery action, we reset the path mask
+ * after we have tried each path and go through all paths a second time.
+ * This will cover situations where only one path at a time is actually down,
+ * but all paths fail and recover just with the same sequence and timing as
+ * we try to use them (flapping links).
+ * If all alternate paths have been tried twice, the request is posted with
+ * a permanent error.
*
* PARAMETER
* erp pointer to the current ERP
* erp pointer to the ERP
*
*/
-static struct dasd_ccw_req *
-dasd_3990_erp_action_1(struct dasd_ccw_req * erp)
+static struct dasd_ccw_req *dasd_3990_erp_action_1_sec(struct dasd_ccw_req *erp)
{
+ erp->function = dasd_3990_erp_action_1_sec;
+ dasd_3990_erp_alternate_path(erp);
+ return erp;
+}
+static struct dasd_ccw_req *dasd_3990_erp_action_1(struct dasd_ccw_req *erp)
+{
erp->function = dasd_3990_erp_action_1;
-
dasd_3990_erp_alternate_path(erp);
-
+ if (erp->status == DASD_CQR_FAILED) {
+ erp->status = DASD_CQR_FILLED;
+ erp->retries = 10;
+ erp->lpm = LPM_ANYPATH;
+ erp->function = dasd_3990_erp_action_1_sec;
+ }
return erp;
-
-} /* end dasd_3990_erp_action_1 */
+} /* end dasd_3990_erp_action_1(b) */
/*
* DASD_3990_ERP_ACTION_4
dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
/* first time set initial retry counter and erp_function */
/* and retry once without waiting for state change pending */
/* interrupt (this enables easier enqueing of the cqr) */
if (erp->function != dasd_3990_erp_action_4) {
- DEV_MESSAGE(KERN_INFO, device, "%s",
+ DBF_DEV_EVENT(DBF_INFO, device, "%s",
"dasd_3990_erp_action_4: first time retry");
erp->retries = 256;
erp->function = dasd_3990_erp_action_4;
} else {
+ if (sense && (sense[25] == 0x1D)) { /* state change pending */
- if (sense[25] == 0x1D) { /* state change pending */
-
- DEV_MESSAGE(KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"waiting for state change pending "
"interrupt, %d retries left",
erp->retries);
dasd_3990_erp_block_queue(erp, 30*HZ);
- } else if (sense[25] == 0x1E) { /* busy */
- DEV_MESSAGE(KERN_INFO, device,
+ } else if (sense && (sense[25] == 0x1E)) { /* busy */
+ DBF_DEV_EVENT(DBF_INFO, device,
"busy - redriving request later, "
"%d retries left",
erp->retries);
dasd_3990_erp_block_queue(erp, HZ);
} else {
-
/* no state change pending - retry */
- DEV_MESSAGE (KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"redriving request immediately, "
"%d retries left",
erp->retries);
- erp->status = DASD_CQR_QUEUED;
+ erp->status = DASD_CQR_FILLED;
}
}
dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
char msg_format = (sense[7] & 0xF0);
char msg_no = (sense[7] & 0x0F);
+ char errorstring[ERRORLENGTH];
switch (msg_format) {
case 0x00: /* Format 0 - Program or System Checks */
case 0x00: /* No Message */
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Invalid Command");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Invalid Command\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Invalid Command "
- "Sequence");
+ "Sequence\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - CCW Count less than "
- "required");
+ "required\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Invalid Parameter");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Invalid Parameter\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Diagnostic of Sepecial"
- " Command Violates File Mask");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Diagnostic of Special"
+ " Command Violates File Mask\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Channel Returned with "
- "Incorrect retry CCW");
+ "Incorrect retry CCW\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reset Notification");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reset Notification\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Storage Path Restart");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Storage Path Restart\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device,
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Channel requested "
- "... %02x", sense[8]);
+ "... %02x\n", sense[8]);
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Invalid Defective/"
- "Alternate Track Pointer");
+ "Alternate Track Pointer\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - DPS Installation "
- "Check");
+ "Check\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Command Invalid on "
- "Secondary Address");
+ "Secondary Address\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device,
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Status Not As "
- "Required: reason %02x", sense[8]);
+ "Required: reason %02x\n",
+ sense[8]);
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reseved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reserved\n");
}
} else {
switch (msg_no) {
case 0x00: /* No Message */
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Device Error Source");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Device Error "
+ "Source\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reserved\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device,
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Device Fenced - "
- "device = %02x", sense[4]);
+ "device = %02x\n", sense[4]);
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Data Pinned for "
- "Device");
+ "Device\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reserved\n");
}
}
break;
case 0x00: /* No Message */
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Device Status 1 not as "
- "expected");
+ "expected\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Index missing");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Index missing\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Interruption cannot be reset");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Interruption cannot be "
+ "reset\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Device did not respond to "
- "selection");
+ "selection\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Device check-2 error or Set "
- "Sector is not complete");
+ "Sector is not complete\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Head address does not "
- "compare");
+ "compare\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Device status 1 not valid");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Device status 1 not valid\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Device not ready");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Device not ready\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Track physical address did "
- "not compare");
+ "not compare\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Missing device address bit");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Missing device address bit\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Drive motor switch is off");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Drive motor switch is off\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Seek incomplete");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Seek incomplete\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Cylinder address did not "
- "compare");
+ "compare\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Offset active cannot be "
- "reset");
+ "reset\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Reserved\n");
}
break;
case 0x20: /* Format 2 - 3990 Equipment Checks */
switch (msg_no) {
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 2 - 3990 check-2 error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - 3990 check-2 error\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 2 - Support facility errors");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - Support facility errors\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device,
- "FORMAT 2 - Microcode detected error %02x",
- sense[8]);
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - Microcode detected error "
+ "%02x\n",
+ sense[8]);
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 2 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - Reserved\n");
}
break;
case 0x30: /* Format 3 - 3990 Control Checks */
switch (msg_no) {
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 3 - Allegiance terminated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 3 - Allegiance terminated\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 3 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 3 - Reserved\n");
}
break;
case 0x40: /* Format 4 - Data Checks */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Home address area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Home address area error\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Count area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Count area error\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Key area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Key area error\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Data area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Data area error\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in home address "
- "area");
+ "area\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in count address "
- "area");
+ "area\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - No sync byte in key area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - No sync byte in key area\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - No sync byte in data area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - No sync byte in data area\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Home address area error; "
- "offset active");
+ "offset active\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Count area error; offset "
- "active");
+ "active\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Key area error; offset "
- "active");
+ "active\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Data area error; "
- "offset active");
+ "offset active\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in home "
- "address area; offset active");
+ "address area; offset active\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No syn byte in count "
- "address area; offset active");
+ "address area; offset active\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in key area; "
- "offset active");
+ "offset active\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No syn byte in data area; "
- "offset active");
+ "offset active\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Reserved\n");
}
break;
case 0x50: /* Format 5 - Data Check with displacement information */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the "
- "home address area");
+ "home address area\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Data Check in the count area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Data Check in the count "
+ "area\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Data Check in the key area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Data Check in the key area\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Data Check in the data area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Data Check in the data "
+ "area\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the "
- "home address area; offset active");
+ "home address area; offset active\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the count area; "
- "offset active");
+ "offset active\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the key area; "
- "offset active");
+ "offset active\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the data area; "
- "offset active");
+ "offset active\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Reserved\n");
}
break;
case 0x60: /* Format 6 - Usage Statistics/Overrun Errors */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel A");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel A\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel B");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel B\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel C");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel C\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel D");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel D\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel E");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel E\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel F");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel F\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel G");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel G\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel H");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel H\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Reserved\n");
}
break;
case 0x70: /* Format 7 - Device Connection Control Checks */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - RCC initiated by a connection "
- "check alert");
+ "check alert\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - RCC 1 sequence not "
- "successful");
+ "successful\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - RCC 1 and RCC 2 sequences not "
- "successful");
+ "successful\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid tag-in during "
- "selection sequence");
+ "selection sequence\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 7 - extra RCC required");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 7 - extra RCC required\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid DCC selection "
- "response or timeout");
+ "response or timeout\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Missing end operation; device "
- "transfer complete");
+ "transfer complete\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Missing end operation; device "
- "transfer incomplete");
+ "transfer incomplete\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid tag-in for an "
- "immediate command sequence");
+ "immediate command sequence\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid tag-in for an "
- "extended command sequence");
+ "extended command sequence\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - 3990 microcode time out when "
- "stopping selection");
+ "stopping selection\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - No response to selection "
- "after a poll interruption");
+ "after a poll interruption\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Permanent path error (DASD "
- "controller not available)");
+ "controller not available)\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - DASD controller not available"
- " on disconnected command chain");
+ " on disconnected command chain\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 7 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 7 - Reserved\n");
}
break;
switch (msg_no) {
case 0x00: /* No Message */
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - Error correction code "
- "hardware fault");
+ "hardware fault\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - Unexpected end operation "
- "response code");
+ "response code\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - End operation with transfer "
- "count not zero");
+ "count not zero\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - End operation with transfer "
- "count zero");
+ "count zero\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - DPS checks after a system "
- "reset or selective reset");
+ "reset or selective reset\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 8 - DPS cannot be filled");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 8 - DPS cannot be filled\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - Short busy time-out during "
- "device selection");
+ "device selection\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - DASD controller failed to "
- "set or reset the long busy latch");
+ "set or reset the long busy latch\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - No interruption from device "
- "during a command chain");
+ "during a command chain\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 8 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 8 - Reserved\n");
}
break;
case 0x00:
break; /* No Message */
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 9 - Device check-2 error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 9 - Device check-2 error\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 9 - Head address did not compare");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 9 - Head address did not "
+ "compare\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 9 - Track physical address did "
- "not compare while oriented");
+ "not compare while oriented\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 9 - Cylinder address did not "
- "compare");
+ "compare\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 9 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 9 - Reserved\n");
}
break;
case 0xF0: /* Format F - Cache Storage Checks */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Operation Terminated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Operation Terminated\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Subsystem Processing Error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Subsystem Processing Error\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Cache or nonvolatile storage "
- "equipment failure");
+ "equipment failure\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Caching terminated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Caching terminated\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Cache fast write access not "
- "authorized");
+ "authorized\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Track format incorrect");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Track format incorrect\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Caching reinitiated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Caching reinitiated\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Nonvolatile storage "
- "terminated");
+ "terminated\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Volume is suspended duplex");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Volume is suspended duplex\n");
/* call extended error reporting (EER) */
dasd_eer_write(device, erp->refers,
DASD_EER_PPRCSUSPEND);
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Subsystem status connot be "
- "determined");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Subsystem status cannot be "
+ "determined\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Caching status reset to "
- "default");
+ "default\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - DASD Fast Write inhibited");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - DASD Fast Write inhibited\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT D - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT D - Reserved\n");
}
break;
- default: /* unknown message format - should not happen */
- DEV_MESSAGE (KERN_WARNING, device,
- "unknown message format %02x",
- msg_format);
+ default: /* unknown message format - should not happen
+ internal error 03 - unknown message format */
+ snprintf(errorstring, ERRORLENGTH, "03 %x02", msg_format);
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", errorstring);
break;
} /* end switch message format */
dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
erp->function = dasd_3990_erp_com_rej;
/* env data present (ACTION 10 - retry should work) */
if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Command Reject - environmental data present");
dasd_3990_handle_env_data(erp, sense);
erp->retries = 5;
+ } else if (sense[1] & SNS1_WRITE_INHIBITED) {
+ dev_err(&device->cdev->dev, "An I/O request was rejected"
+ " because writing is inhibited\n");
+ erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
} else {
- /* fatal error - set status to FAILED */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Command Reject - Fatal error");
+ /* fatal error - set status to FAILED
+ internal error 09 - Command Reject */
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "09");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
}
dasd_3990_erp_bus_out(struct dasd_ccw_req * erp)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
/* first time set initial retry counter and erp_function */
/* and retry once without blocking queue */
} else {
/* issue a message and wait for 'device ready' interrupt */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"bus out parity error or BOPC requested by "
"channel");
dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
erp->function = dasd_3990_erp_equip_check;
if (sense[1] & SNS1_WRITE_INHIBITED) {
+ dev_info(&device->cdev->dev,
+ "Write inhibited path encountered\n");
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
- "Write inhibited path encountered");
-
- /* vary path offline */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Path should be varied off-line. "
- "This is not implemented yet \n - please report "
- "to linux390@de.ibm.com");
+ /* vary path offline
+ internal error 04 - Path should be varied off-line.*/
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "04");
erp = dasd_3990_erp_action_1(erp);
} else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Equipment Check - " "environmental data present");
dasd_3990_handle_env_data(erp, sense);
} else if (sense[1] & SNS1_PERM_ERR) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Equipment Check - retry exhausted or "
"undesirable");
} else {
/* all other equipment checks - Action 5 */
/* rest is done when retries == 0 */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Equipment check or processing error");
erp = dasd_3990_erp_action_5(erp);
}
-
return erp;
} /* end dasd_3990_erp_equip_check */
dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
erp->function = dasd_3990_erp_data_check;
if (sense[2] & SNS2_CORRECTABLE) { /* correctable data check */
/* issue message that the data has been corrected */
- DEV_MESSAGE(KERN_EMERG, device, "%s",
+ dev_emerg(&device->cdev->dev,
"Data recovered during retry with PCI "
- "fetch mode active");
+ "fetch mode active\n");
/* not possible to handle this situation in Linux */
panic("No way to inform application about the possibly "
} else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Uncorrectable data check recovered secondary "
"addr of duplex pair");
} else if (sense[1] & SNS1_PERM_ERR) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Uncorrectable data check with internal "
"retry exhausted");
} else {
/* all other data checks */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Uncorrectable data check with retry count "
"exhausted...");
dasd_3990_erp_overrun(struct dasd_ccw_req * erp, char *sense)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
erp->function = dasd_3990_erp_overrun;
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Overrun - service overrun or overrun"
" error requested by channel");
dasd_3990_erp_inv_format(struct dasd_ccw_req * erp, char *sense)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
erp->function = dasd_3990_erp_inv_format;
if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Track format error when destaging or "
"staging data");
erp = dasd_3990_erp_action_4(erp, sense);
} else {
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Invalid Track Format - Fatal error should have "
- "been handled within the interrupt handler");
+ /* internal error 06 - The track format is not valid*/
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "06");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
}
dasd_3990_erp_EOC(struct dasd_ccw_req * default_erp, char *sense)
{
- struct dasd_device *device = default_erp->device;
+ struct dasd_device *device = default_erp->startdev;
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "End-of-Cylinder - must never happen");
+ dev_err(&device->cdev->dev,
+ "The cylinder data for accessing the DASD is inconsistent\n");
/* implement action 7 - BUG */
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
erp->function = dasd_3990_erp_env_data;
- DEV_MESSAGE(KERN_DEBUG, device, "%s", "Environmental data present");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Environmental data present");
dasd_3990_handle_env_data(erp, sense);
/* don't retry on disabled interface */
if (sense[7] != 0x0F) {
-
erp = dasd_3990_erp_action_4(erp, sense);
} else {
-
- erp = dasd_3990_erp_cleanup(erp, DASD_CQR_IN_IO);
+ erp->status = DASD_CQR_FILLED;
}
return erp;
dasd_3990_erp_no_rec(struct dasd_ccw_req * default_erp, char *sense)
{
- struct dasd_device *device = default_erp->device;
+ struct dasd_device *device = default_erp->startdev;
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "No Record Found - Fatal error should "
- "have been handled within the interrupt handler");
+ dev_err(&device->cdev->dev,
+ "The specified record was not found\n");
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
dasd_3990_erp_file_prot(struct dasd_ccw_req * erp)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
- DEV_MESSAGE(KERN_ERR, device, "%s", "File Protected");
+ dev_err(&device->cdev->dev, "Accessing the DASD failed because of "
+ "a hardware error\n");
return dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
} /* end dasd_3990_erp_file_prot */
/*
+ * DASD_3990_ERP_INSPECT_ALIAS
+ *
+ * DESCRIPTION
+ * Checks if the original request was started on an alias device.
+ * If yes, it modifies the original and the erp request so that
+ * the erp request can be started on a base device.
+ *
+ * PARAMETER
+ * erp pointer to the currently created default ERP
+ *
+ * RETURN VALUES
+ * erp pointer to the modified ERP, or NULL
+ */
+
+static struct dasd_ccw_req *dasd_3990_erp_inspect_alias(
+ struct dasd_ccw_req *erp)
+{
+ struct dasd_ccw_req *cqr = erp->refers;
+
+ if (cqr->block &&
+ (cqr->block->base != cqr->startdev)) {
+ if (cqr->startdev->features & DASD_FEATURE_ERPLOG) {
+ DBF_DEV_EVENT(DBF_ERR, cqr->startdev,
+ "ERP on alias device for request %p,"
+ " recover on base device %s", cqr,
+ dev_name(&cqr->block->base->cdev->dev));
+ }
+ dasd_eckd_reset_ccw_to_base_io(cqr);
+ erp->startdev = cqr->block->base;
+ erp->function = dasd_3990_erp_inspect_alias;
+ return erp;
+ } else
+ return NULL;
+}
+
+
+/*
* DASD_3990_ERP_INSPECT_24
*
* DESCRIPTION
dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
erp->retries = 256;
erp->function = dasd_3990_erp_action_10_32;
- DEV_MESSAGE(KERN_DEBUG, device, "%s", "Perform logging requested");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Perform logging requested");
return erp;
dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
{
- struct dasd_device *device = default_erp->device;
+ struct dasd_device *device = default_erp->startdev;
__u32 cpa = 0;
struct dasd_ccw_req *cqr;
struct dasd_ccw_req *erp;
struct DE_eckd_data *DE_data;
+ struct PFX_eckd_data *PFX_data;
char *LO_data; /* LO_eckd_data_t */
- struct ccw1 *ccw;
+ struct ccw1 *ccw, *oldccw;
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Write not finished because of unexpected condition");
default_erp->function = dasd_3990_erp_action_1B_32;
cqr = cqr->refers;
}
+ if (scsw_is_tm(&cqr->irb.scsw)) {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "32 bit sense, action 1B is not defined"
+ " in transport mode - just retry");
+ return default_erp;
+ }
+
/* for imprecise ending just do default erp */
if (sense[1] & 0x01) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Imprecise ending is set - just retry");
return default_erp;
/* determine the address of the CCW to be restarted */
/* Imprecise ending is not set -> addr from IRB-SCSW */
- cpa = default_erp->refers->irb.scsw.cpa;
+ cpa = default_erp->refers->irb.scsw.cmd.cpa;
if (cpa == 0) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Unable to determine address of the CCW "
"to be restarted");
/* Build new ERP request including DE/LO */
erp = dasd_alloc_erp_request((char *) &cqr->magic,
2 + 1,/* DE/LO + TIC */
- sizeof (struct DE_eckd_data) +
- sizeof (struct LO_eckd_data), device);
+ sizeof(struct DE_eckd_data) +
+ sizeof(struct LO_eckd_data), device);
if (IS_ERR(erp)) {
- DEV_MESSAGE(KERN_ERR, device, "%s", "Unable to allocate ERP");
+ /* internal error 01 - Unable to allocate ERP */
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "01");
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
}
/* use original DE */
DE_data = erp->data;
- memcpy(DE_data, cqr->data, sizeof (struct DE_eckd_data));
+ oldccw = cqr->cpaddr;
+ if (oldccw->cmd_code == DASD_ECKD_CCW_PFX) {
+ PFX_data = cqr->data;
+ memcpy(DE_data, &PFX_data->define_extent,
+ sizeof(struct DE_eckd_data));
+ } else
+ memcpy(DE_data, cqr->data, sizeof(struct DE_eckd_data));
/* create LO */
- LO_data = erp->data + sizeof (struct DE_eckd_data);
+ LO_data = erp->data + sizeof(struct DE_eckd_data);
if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "BUG - this should not happen");
-
+ /* should not */
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
}
/* create DE ccw */
ccw = erp->cpaddr;
- memset(ccw, 0, sizeof (struct ccw1));
+ memset(ccw, 0, sizeof(struct ccw1));
ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT;
ccw->flags = CCW_FLAG_CC;
ccw->count = 16;
/* create LO ccw */
ccw++;
- memset(ccw, 0, sizeof (struct ccw1));
+ memset(ccw, 0, sizeof(struct ccw1));
ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;
ccw->flags = CCW_FLAG_CC;
ccw->count = 16;
/* fill erp related fields */
erp->function = dasd_3990_erp_action_1B_32;
erp->refers = default_erp->refers;
- erp->device = device;
+ erp->startdev = device;
+ erp->memdev = device;
erp->magic = default_erp->magic;
erp->expires = 0;
erp->retries = 256;
dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
{
- struct dasd_device *device = previous_erp->device;
+ struct dasd_device *device = previous_erp->startdev;
__u32 cpa = 0;
struct dasd_ccw_req *cqr;
struct dasd_ccw_req *erp;
char *LO_data; /* struct LO_eckd_data */
struct ccw1 *ccw;
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Write not finished because of unexpected condition"
" - follow on");
cqr = cqr->refers;
}
+ if (scsw_is_tm(&cqr->irb.scsw)) {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "32 bit sense, action 1B, update,"
+ " in transport mode - just retry");
+ return previous_erp;
+ }
+
/* for imprecise ending just do default erp */
if (sense[1] & 0x01) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Imprecise ending is set - just retry");
- previous_erp->status = DASD_CQR_QUEUED;
+ previous_erp->status = DASD_CQR_FILLED;
return previous_erp;
}
/* determine the address of the CCW to be restarted */
/* Imprecise ending is not set -> addr from IRB-SCSW */
- cpa = previous_erp->irb.scsw.cpa;
+ cpa = previous_erp->irb.scsw.cmd.cpa;
if (cpa == 0) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
- "Unable to determine address of the CCW "
- "to be restarted");
+ /* internal error 02 -
+ Unable to determine address of the CCW to be restarted */
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "02");
previous_erp->status = DASD_CQR_FAILED;
erp = previous_erp;
/* update the LO with the new returned sense data */
- LO_data = erp->data + sizeof (struct DE_eckd_data);
+ LO_data = erp->data + sizeof(struct DE_eckd_data);
if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "BUG - this should not happen");
-
+ /* should not happen */
previous_erp->status = DASD_CQR_FAILED;
return previous_erp;
ccw++; /* addr of TIC ccw */
ccw->cda = cpa;
- erp->status = DASD_CQR_QUEUED;
+ erp->status = DASD_CQR_FILLED;
return erp;
* try further actions. */
erp->lpm = 0;
-
- erp->status = DASD_CQR_ERROR;
-
+ erp->status = DASD_CQR_NEED_ERP;
}
}
switch (sense[28]) {
case 0x17:
/* issue a Diagnostic Control command with an
- * Inhibit Write subcommand and controler modifier */
+ * Inhibit Write subcommand and controller modifier */
erp = dasd_3990_erp_DCTL(erp, 0x20);
break;
if ((sense[25] & DASD_SENSE_BIT_1) && (sense[26] & DASD_SENSE_BIT_2)) {
- /* set to suspended duplex state then restart */
- struct dasd_device *device = erp->device;
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Set device to suspended duplex state should be "
- "done!\n"
- "This is not implemented yet (for compound ERP)"
- " - please report to linux390@de.ibm.com");
+ /* set to suspended duplex state then restart
+ internal error 05 - Set device to suspended duplex state
+ should be done */
+ struct dasd_device *device = erp->startdev;
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "05");
}
{
if ((erp->function == dasd_3990_erp_compound_retry) &&
- (erp->status == DASD_CQR_ERROR)) {
+ (erp->status == DASD_CQR_NEED_ERP)) {
dasd_3990_erp_compound_path(erp, sense);
}
if ((erp->function == dasd_3990_erp_compound_path) &&
- (erp->status == DASD_CQR_ERROR)) {
+ (erp->status == DASD_CQR_NEED_ERP)) {
erp = dasd_3990_erp_compound_code(erp, sense);
}
if ((erp->function == dasd_3990_erp_compound_code) &&
- (erp->status == DASD_CQR_ERROR)) {
+ (erp->status == DASD_CQR_NEED_ERP)) {
dasd_3990_erp_compound_config(erp, sense);
}
/* if no compound action ERP specified, the request failed */
- if (erp->status == DASD_CQR_ERROR) {
-
+ if (erp->status == DASD_CQR_NEED_ERP)
erp->status = DASD_CQR_FAILED;
- }
return erp;
} /* 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_err(&device->cdev->dev, "SIM - SRC: "
+ "%02x%02x%02x%02x\n", sense[22],
+ sense[23], sense[11], sense[12]);
+ } else if (sense[24] & DASD_SIM_LOG) {
+ /* print SIM SRC Refcode */
+ dev_warn(&device->cdev->dev, "log SIM - SRC: "
+ "%02x%02x%02x%02x\n", sense[22],
+ sense[23], sense[11], sense[12]);
+ }
+}
+
+/*
* DASD_3990_ERP_INSPECT_32
*
* DESCRIPTION
dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
{
- struct dasd_device *device = erp->device;
+ struct dasd_device *device = erp->startdev;
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') */
switch (sense[25]) {
case 0x00: /* success - use default ERP for retries */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"ERP called for successful request"
" - just retry");
break;
case 0x01: /* fatal error */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Fatal error should have been "
- "handled within the interrupt handler");
+ dev_err(&device->cdev->dev,
+ "ERP failed for the DASD\n");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
break;
erp = dasd_3990_erp_int_req(erp);
break;
- case 0x0F: /* length mismatch during update write command */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "update write command error - should not "
- "happen;\n"
- "Please send this message together with "
- "the above sense data to linux390@de."
- "ibm.com");
+ case 0x0F: /* length mismatch during update write command
+ internal error 08 - update write command error*/
+ dev_err(&device->cdev->dev, "An error occurred in the "
+ "DASD device driver, reason=%s\n", "08");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
break;
erp = dasd_3990_erp_action_10_32(erp, sense);
break;
- case 0x15: /* next track outside defined extend */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "next track outside defined extend - "
- "should not happen;\n"
- "Please send this message together with "
- "the above sense data to linux390@de."
- "ibm.com");
+ case 0x15: /* next track outside defined extend
+ internal error 07 - The next track is not
+ within the defined storage extent */
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "07");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
break;
break;
case 0x1C: /* invalid data */
- DEV_MESSAGE(KERN_EMERG, device, "%s",
+ dev_emerg(&device->cdev->dev,
"Data recovered during retry with PCI "
- "fetch mode active");
+ "fetch mode active\n");
/* not possible to handle this situation in Linux */
panic
break;
case 0x1D: /* state-change pending */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"A State change pending condition exists "
"for the subsystem or device");
break;
case 0x1E: /* busy */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Busy condition exists "
"for the subsystem or device");
erp = dasd_3990_erp_action_4(erp, sense);
*/
/*
+ * 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 (scsw_cstat(&erp->refers->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK
+ | SCHN_STAT_CHN_CTRL_CHK)) {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "channel or interface control check");
+ erp = dasd_3990_erp_action_4(erp, NULL);
+ }
+ return erp;
+}
+
+/*
* DASD_3990_ERP_INSPECT
*
* DESCRIPTION
* erp_new contens was possibly modified
*/
static struct dasd_ccw_req *
-dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
+dasd_3990_erp_inspect(struct dasd_ccw_req *erp)
{
struct dasd_ccw_req *erp_new = NULL;
- /* sense data are located in the refers record of the */
- /* already set up new ERP ! */
- char *sense = erp->refers->irb.ecw;
-
+ char *sense;
+
+ /* if this problem occured on an alias retry on base */
+ erp_new = dasd_3990_erp_inspect_alias(erp);
+ if (erp_new)
+ return erp_new;
+
+ /* sense data are located in the refers record of the
+ * already set up new ERP !
+ * check if concurrent sens is available
+ */
+ sense = dasd_get_sense(&erp->refers->irb);
+ if (!sense)
+ 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);
* DESCRIPTION
* This funtion adds an additional request block (ERP) to the head of
* the given cqr (or erp).
- * This erp is initialized as an default erp (retry TIC)
+ * For a command mode cqr the erp is initialized as an default erp
+ * (retry TIC).
+ * For transport mode we make a copy of the original TCW (points to
+ * the original TCCB, TIDALs, etc.) but give it a fresh
+ * TSB so the original sense data will not be changed.
*
* PARAMETER
* cqr head of the current ERP-chain (or single cqr if
* RETURN VALUES
* erp pointer to new ERP-chain head
*/
-static struct dasd_ccw_req *
-dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
+static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
{
- struct dasd_device *device = cqr->device;
+ struct dasd_device *device = cqr->startdev;
struct ccw1 *ccw;
-
- /* allocate additional request block */
struct dasd_ccw_req *erp;
+ int cplength, datasize;
+ struct tcw *tcw;
+ struct tsb *tsb;
+
+ if (cqr->cpmode == 1) {
+ cplength = 0;
+ /* TCW needs to be 64 byte aligned, so leave enough room */
+ datasize = 64 + sizeof(struct tcw) + sizeof(struct tsb);
+ } else {
+ cplength = 2;
+ datasize = 0;
+ }
- erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, cqr->device);
+ /* allocate additional request block */
+ erp = dasd_alloc_erp_request((char *) &cqr->magic,
+ cplength, datasize, device);
if (IS_ERR(erp)) {
if (cqr->retries <= 0) {
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_ERR, device, "%s",
"Unable to allocate ERP request");
cqr->status = DASD_CQR_FAILED;
cqr->stopclk = get_clock ();
} else {
- DEV_MESSAGE (KERN_ERR, device,
+ DBF_DEV_EVENT(DBF_ERR, device,
"Unable to allocate ERP request "
"(%i retries left)",
cqr->retries);
- dasd_set_timer(device, (HZ << 3));
+ dasd_block_set_timer(device->block, (HZ << 3));
}
- return cqr;
+ return erp;
+ }
+
+ ccw = cqr->cpaddr;
+ if (cqr->cpmode == 1) {
+ /* make a shallow copy of the original tcw but set new tsb */
+ erp->cpmode = 1;
+ erp->cpaddr = PTR_ALIGN(erp->data, 64);
+ tcw = erp->cpaddr;
+ tsb = (struct tsb *) &tcw[1];
+ *tcw = *((struct tcw *)cqr->cpaddr);
+ tcw->tsb = (long)tsb;
+ } else if (ccw->cmd_code == DASD_ECKD_CCW_PSF) {
+ /* PSF cannot be chained from NOOP/TIC */
+ erp->cpaddr = cqr->cpaddr;
+ } else {
+ /* initialize request with default TIC to current ERP/CQR */
+ ccw = erp->cpaddr;
+ ccw->cmd_code = CCW_CMD_NOOP;
+ ccw->flags = CCW_FLAG_CC;
+ ccw++;
+ ccw->cmd_code = CCW_CMD_TIC;
+ ccw->cda = (long)(cqr->cpaddr);
}
- /* initialize request with default TIC to current ERP/CQR */
- ccw = erp->cpaddr;
- ccw->cmd_code = CCW_CMD_NOOP;
- ccw->flags = CCW_FLAG_CC;
- ccw++;
- ccw->cmd_code = CCW_CMD_TIC;
- ccw->cda = (long)(cqr->cpaddr);
erp->function = dasd_3990_erp_add_erp;
erp->refers = cqr;
- erp->device = cqr->device;
+ erp->startdev = device;
+ erp->memdev = device;
+ erp->block = cqr->block;
erp->magic = cqr->magic;
erp->expires = 0;
erp->retries = 256;
erp->buildclk = get_clock();
-
erp->status = DASD_CQR_FILLED;
return erp;
/* add erp and initialize with default TIC */
erp = dasd_3990_erp_add_erp(cqr);
+ if (IS_ERR(erp))
+ return erp;
+
/* inspect sense, determine specific ERP if possible */
if (erp != cqr) {
* match 'boolean' for match found
* returns 1 if match found, otherwise 0.
*/
-static int
-dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
+static int 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 */
+ char *sense1, *sense2;
+
+ if (cqr1->startdev != cqr2->startdev)
+ return 0;
+
+ sense1 = dasd_get_sense(&cqr1->irb);
+ sense2 = dasd_get_sense(&cqr2->irb);
+
+ /* one request has sense data, the other not -> no match, return 0 */
+ if (!sense1 != !sense2)
+ return 0;
+ /* no sense data in both cases -> check cstat for IFCC */
+ if (!sense1 && !sense2) {
+ if ((scsw_cstat(&cqr1->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
+ SCHN_STAT_CHN_CTRL_CHK)) ==
+ (scsw_cstat(&cqr2->irb.scsw) & (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]) &&
- (cqr1->irb.ecw[25] == cqr2->irb.ecw[25]))) {
+ if (!(sense1 && sense2 &&
+ (memcmp(sense1, sense2, 3) == 0) &&
+ (sense1[27] == sense2[27]) &&
+ (sense1[25] == sense2[25]))) {
return 0; /* sense doesn't match */
}
dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
{
- struct dasd_device *device = erp->device;
- char *sense = erp->irb.ecw;
+ struct dasd_device *device = erp->startdev;
+ char *sense = dasd_get_sense(&erp->irb);
/* check for 24 byte sense ERP */
if ((erp->function == dasd_3990_erp_bus_out) ||
erp = dasd_3990_erp_action_1(erp);
+ } else if (erp->function == dasd_3990_erp_action_1_sec) {
+ erp = dasd_3990_erp_action_1_sec(erp);
} else if (erp->function == dasd_3990_erp_action_5) {
/* retries have not been successful */
/* prepare erp for retry on different channel path */
erp = dasd_3990_erp_action_1(erp);
- if (!(sense[2] & DASD_SENSE_BIT_0)) {
+ if (sense && !(sense[2] & DASD_SENSE_BIT_0)) {
/* issue a Diagnostic Control command with an
* Inhibit Write subcommand */
break;
}
default:
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
"invalid subcommand modifier 0x%x "
"for Diagnostic Control Command",
sense[25]);
}
/* check for 32 byte sense ERP */
- } else if ((erp->function == dasd_3990_erp_compound_retry) ||
- (erp->function == dasd_3990_erp_compound_path) ||
- (erp->function == dasd_3990_erp_compound_code) ||
- (erp->function == dasd_3990_erp_compound_config)) {
+ } else if (sense &&
+ ((erp->function == dasd_3990_erp_compound_retry) ||
+ (erp->function == dasd_3990_erp_compound_path) ||
+ (erp->function == dasd_3990_erp_compound_code) ||
+ (erp->function == dasd_3990_erp_compound_config))) {
erp = dasd_3990_erp_compound(erp, sense);
} else {
- /* No retry left and no additional special handling */
- /*necessary */
- DEV_MESSAGE(KERN_ERR, device,
- "no retries left for erp %p - "
- "set status to FAILED", erp);
+ /*
+ * No retry left and no additional special handling
+ * necessary
+ */
+ dev_err(&device->cdev->dev,
+ "ERP %p has run out of retries and failed\n", erp);
erp->status = DASD_CQR_FAILED;
}
struct dasd_ccw_req *erp)
{
- struct dasd_device *device = erp_head->device;
+ struct dasd_device *device = erp_head->startdev;
struct dasd_ccw_req *erp_done = erp_head; /* finished req */
struct dasd_ccw_req *erp_free = NULL; /* req to be freed */
"original request was lost\n");
/* remove the request from the device queue */
- list_del(&erp_done->list);
+ list_del(&erp_done->blocklist);
erp_free = erp_done;
erp_done = erp_done->refers;
/* free the finished erp request */
- dasd_free_erp_request(erp_free, erp_free->device);
+ dasd_free_erp_request(erp_free, erp_free->memdev);
} /* end while */
if (erp->retries > 0) {
- char *sense = erp->refers->irb.ecw;
+ char *sense = dasd_get_sense(&erp->refers->irb);
/* check for special retries */
- if (erp->function == dasd_3990_erp_action_4) {
+ if (sense && erp->function == dasd_3990_erp_action_4) {
erp = dasd_3990_erp_action_4(erp, sense);
- } else if (erp->function == dasd_3990_erp_action_1B_32) {
+ } else if (sense &&
+ erp->function == dasd_3990_erp_action_1B_32) {
erp = dasd_3990_update_1B(erp, sense);
- } else if (erp->function == dasd_3990_erp_int_req) {
+ } else if (sense && erp->function == dasd_3990_erp_int_req) {
erp = dasd_3990_erp_int_req(erp);
} else {
/* simple retry */
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_DEBUG, device,
"%i retries left for erp %p",
erp->retries, erp);
/* handle the request again... */
- erp->status = DASD_CQR_QUEUED;
+ erp->status = DASD_CQR_FILLED;
}
} else {
* DASD_3990_ERP_ACTION
*
* DESCRIPTION
- * controll routine for 3990 erp actions.
+ * control routine for 3990 erp actions.
* Has to be called with the queue lock (namely the s390_irq_lock) acquired.
*
* PARAMETER
struct dasd_ccw_req *
dasd_3990_erp_action(struct dasd_ccw_req * cqr)
{
-
struct dasd_ccw_req *erp = NULL;
- struct dasd_device *device = cqr->device;
- __u32 cpa = cqr->irb.scsw.cpa;
+ struct dasd_device *device = cqr->startdev;
struct dasd_ccw_req *temp_erp = NULL;
if (device->features & DASD_FEATURE_ERPLOG) {
/* print current erp_chain */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "ERP chain at BEGINNING of ERP-ACTION");
+ dev_err(&device->cdev->dev,
+ "ERP chain at BEGINNING of ERP-ACTION\n");
for (temp_erp = cqr;
temp_erp != NULL; temp_erp = temp_erp->refers) {
- DEV_MESSAGE(KERN_ERR, device,
- " erp %p (%02x) refers to %p",
+ dev_err(&device->cdev->dev,
+ "ERP %p (%02x) refers to %p\n",
temp_erp, temp_erp->status,
temp_erp->refers);
}
}
- /* double-check if current erp/cqr was successfull */
- if ((cqr->irb.scsw.cstat == 0x00) &&
- (cqr->irb.scsw.dstat == (DEV_STAT_CHN_END|DEV_STAT_DEV_END))) {
+ /* double-check if current erp/cqr was successful */
+ if ((scsw_cstat(&cqr->irb.scsw) == 0x00) &&
+ (scsw_dstat(&cqr->irb.scsw) ==
+ (DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_DEBUG, device,
"ERP called for successful request %p"
" - NO ERP necessary", cqr);
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);
if (erp == NULL) {
/* no matching erp found - set up erp */
erp = dasd_3990_erp_additional_erp(cqr);
+ if (IS_ERR(erp))
+ return erp;
} else {
/* matching erp found - set all leading erp's to DONE */
erp = dasd_3990_erp_handle_match_erp(cqr, erp);
if (device->features & DASD_FEATURE_ERPLOG) {
/* print current erp_chain */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "ERP chain at END of ERP-ACTION");
+ dev_err(&device->cdev->dev,
+ "ERP chain at END of ERP-ACTION\n");
for (temp_erp = erp;
temp_erp != NULL; temp_erp = temp_erp->refers) {
- DEV_MESSAGE(KERN_ERR, device,
- " erp %p (%02x) refers to %p",
+ dev_err(&device->cdev->dev,
+ "ERP %p (%02x) refers to %p\n",
temp_erp, temp_erp->status,
temp_erp->refers);
}
}
- if (erp->status == DASD_CQR_FAILED)
- dasd_log_ccw(erp, 1, cpa);
-
- /* enqueue added ERP request */
- if (erp->status == DASD_CQR_FILLED) {
- erp->status = DASD_CQR_QUEUED;
- list_add(&erp->list, &device->ccw_queue);
+ /* enqueue ERP request if it's a new one */
+ if (list_empty(&erp->blocklist)) {
+ cqr->status = DASD_CQR_IN_ERP;
+ /* add erp request before the cqr */
+ list_add_tail(&erp->blocklist, &cqr->blocklist);
}
+
+
return erp;
} /* end dasd_3990_erp_action */