⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dasd_3990_erp.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* 'Data Check'		   */	if ((erp_filled == NULL) && (sense[0] & SNS0_DATA_CHECK)) {		erp_filled = dasd_3990_erp_data_check(erp, sense);	}	/* 'Overrun'		   */	if ((erp_filled == NULL) && (sense[0] & SNS0_OVERRUN)) {		erp_filled = dasd_3990_erp_overrun(erp, sense);	}	/* 'Invalid Track Format'  */	if ((erp_filled == NULL) && (sense[1] & SNS1_INV_TRACK_FORMAT)) {		erp_filled = dasd_3990_erp_inv_format(erp, sense);	}	/* 'End-of-Cylinder'	   */	if ((erp_filled == NULL) && (sense[1] & SNS1_EOC)) {		erp_filled = dasd_3990_erp_EOC(erp, sense);	}	/* 'Environmental Data'	   */	if ((erp_filled == NULL) && (sense[2] & SNS2_ENV_DATA_PRESENT)) {		erp_filled = dasd_3990_erp_env_data(erp, sense);	}	/* 'No Record Found'	   */	if ((erp_filled == NULL) && (sense[1] & SNS1_NO_REC_FOUND)) {		erp_filled = dasd_3990_erp_no_rec(erp, sense);	}	/* 'File Protected'	   */	if ((erp_filled == NULL) && (sense[1] & SNS1_FILE_PROTECTED)) {		erp_filled = dasd_3990_erp_file_prot(erp);	}	/* other (unknown) error - do default ERP */	if (erp_filled == NULL) {		erp_filled = erp;	}	return erp_filled;}				/* END dasd_3990_erp_inspect_24 *//* *****************************************************************************  * 32 byte sense ERP functions (only) *****************************************************************************  *//* * DASD_3990_ERPACTION_10_32  * * DESCRIPTION *   Handles 32 byte 'Action 10' of Single Program Action Codes. *   Just retry and if retry doesn't work, return with error. * * PARAMETER *   erp		current erp_head *   sense		current sense data  * RETURN VALUES *   erp		modified erp_head */static struct dasd_ccw_req *dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense){	struct dasd_device *device = erp->device;	erp->retries = 256;	erp->function = dasd_3990_erp_action_10_32;	DEV_MESSAGE(KERN_DEBUG, device, "%s", "Perform logging requested");	return erp;}				/* end dasd_3990_erp_action_10_32 *//* * DASD_3990_ERP_ACTION_1B_32 * * DESCRIPTION *   Handles 32 byte 'Action 1B' of Single Program Action Codes. *   A write operation could not be finished because of an unexpected  *   condition. *   The already created 'default erp' is used to get the link to  *   the erp chain, but it can not be used for this recovery  *   action because it contains no DE/LO data space. * * PARAMETER *   default_erp	already added default erp. *   sense		current sense data  * * RETURN VALUES *   erp		new erp or  *			default_erp in case of imprecise ending or error */static struct dasd_ccw_req *dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense){	struct dasd_device *device = default_erp->device;	__u32 cpa = 0;	struct dasd_ccw_req *cqr;	struct dasd_ccw_req *erp;	struct DE_eckd_data *DE_data;	char *LO_data;		/* LO_eckd_data_t */	struct ccw1 *ccw;	DEV_MESSAGE(KERN_DEBUG, device, "%s",		    "Write not finished because of unexpected condition");	default_erp->function = dasd_3990_erp_action_1B_32;	/* determine the original cqr */	cqr = default_erp;	while (cqr->refers != NULL) {		cqr = cqr->refers;	}	/* for imprecise ending just do default erp */	if (sense[1] & 0x01) {		DEV_MESSAGE(KERN_DEBUG, 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;	if (cpa == 0) {		DEV_MESSAGE(KERN_DEBUG, device, "%s",			    "Unable to determine address of the CCW "			    "to be restarted");		return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);	}	/* 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);	if (IS_ERR(erp)) {		DEV_MESSAGE(KERN_ERR, device, "%s", "Unable to allocate ERP");		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));	/* create LO */	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");		return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);	}	if ((sense[7] & 0x3F) == 0x01) {		/* operation code is WRITE DATA -> data area orientation */		LO_data[0] = 0x81;	} else if ((sense[7] & 0x3F) == 0x03) {		/* operation code is FORMAT WRITE -> index orientation */		LO_data[0] = 0xC3;	} else {		LO_data[0] = sense[7];	/* operation */	}	LO_data[1] = sense[8];	/* auxiliary */	LO_data[2] = sense[9];	LO_data[3] = sense[3];	/* count */	LO_data[4] = sense[29];	/* seek_addr.cyl */	LO_data[5] = sense[30];	/* seek_addr.cyl 2nd byte */	LO_data[7] = sense[31];	/* seek_addr.head 2nd byte */	memcpy(&(LO_data[8]), &(sense[11]), 8);	/* create DE ccw */	ccw = erp->cpaddr;	memset(ccw, 0, sizeof (struct ccw1));	ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT;	ccw->flags = CCW_FLAG_CC;	ccw->count = 16;	ccw->cda = (__u32)(addr_t) DE_data;	/* create LO ccw */	ccw++;	memset(ccw, 0, sizeof (struct ccw1));	ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;	ccw->flags = CCW_FLAG_CC;	ccw->count = 16;	ccw->cda = (__u32)(addr_t) LO_data;	/* TIC to the failed ccw */	ccw++;	ccw->cmd_code = CCW_CMD_TIC;	ccw->cda = cpa;	/* fill erp related fields */	erp->function = dasd_3990_erp_action_1B_32;	erp->refers = default_erp->refers;	erp->device = device;	erp->magic = default_erp->magic;	erp->expires = 0;	erp->retries = 256;	erp->buildclk = get_clock();	erp->status = DASD_CQR_FILLED;	/* remove the default erp */	dasd_free_erp_request(default_erp, device);	return erp;}				/* end dasd_3990_erp_action_1B_32 *//* * DASD_3990_UPDATE_1B * * DESCRIPTION *   Handles the update to the 32 byte 'Action 1B' of Single Program  *   Action Codes in case the first action was not successful. *   The already created 'previous_erp' is the currently not successful *   ERP.  * * PARAMETER *   previous_erp	already created previous erp. *   sense		current sense data  * RETURN VALUES *   erp		modified erp  */static struct dasd_ccw_req *dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense){	struct dasd_device *device = previous_erp->device;	__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",		    "Write not finished because of unexpected condition"		    " - follow on");	/* determine the original cqr */	cqr = previous_erp;	while (cqr->refers != NULL) {		cqr = cqr->refers;	}	/* for imprecise ending just do default erp */	if (sense[1] & 0x01) {		DEV_MESSAGE(KERN_DEBUG, device, "%s",			    "Imprecise ending is set - just retry");		previous_erp->status = DASD_CQR_QUEUED;		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;	if (cpa == 0) {		DEV_MESSAGE(KERN_DEBUG, device, "%s",			    "Unable to determine address of the CCW "			    "to be restarted");		previous_erp->status = DASD_CQR_FAILED;		return previous_erp;	}	erp = previous_erp;	/* update the LO with the new returned sense 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");		previous_erp->status = DASD_CQR_FAILED;		return previous_erp;	}	if ((sense[7] & 0x3F) == 0x01) {		/* operation code is WRITE DATA -> data area orientation */		LO_data[0] = 0x81;	} else if ((sense[7] & 0x3F) == 0x03) {		/* operation code is FORMAT WRITE -> index orientation */		LO_data[0] = 0xC3;	} else {		LO_data[0] = sense[7];	/* operation */	}	LO_data[1] = sense[8];	/* auxiliary */	LO_data[2] = sense[9];	LO_data[3] = sense[3];	/* count */	LO_data[4] = sense[29];	/* seek_addr.cyl */	LO_data[5] = sense[30];	/* seek_addr.cyl 2nd byte */	LO_data[7] = sense[31];	/* seek_addr.head 2nd byte */	memcpy(&(LO_data[8]), &(sense[11]), 8);	/* TIC to the failed ccw */	ccw = erp->cpaddr;	/* addr of DE ccw */	ccw++;			/* addr of LE ccw */	ccw++;			/* addr of TIC ccw */	ccw->cda = cpa;	erp->status = DASD_CQR_QUEUED;	return erp;}				/* end dasd_3990_update_1B *//* * DASD_3990_ERP_COMPOUND_RETRY  * * DESCRIPTION *   Handles the compound ERP action retry code. *   NOTE: At least one retry is done even if zero is specified *	   by the sense data. This makes enqueueing of the request *	   easier. * * PARAMETER *   sense		sense data of the actual error *   erp		pointer to the currently created ERP * * RETURN VALUES *   erp		modified ERP pointer * */static voiddasd_3990_erp_compound_retry(struct dasd_ccw_req * erp, char *sense){	switch (sense[25] & 0x03) {	case 0x00:		/* no not retry */		erp->retries = 1;		break;	case 0x01:		/* retry 2 times */		erp->retries = 2;		break;	case 0x02:		/* retry 10 times */		erp->retries = 10;		break;	case 0x03:		/* retry 256 times */		erp->retries = 256;		break;	default:		BUG();	}	erp->function = dasd_3990_erp_compound_retry;}				/* end dasd_3990_erp_compound_retry *//* * DASD_3990_ERP_COMPOUND_PATH  * * DESCRIPTION *   Handles the compound ERP action for retry on alternate *   channel path. * * PARAMETER *   sense		sense data of the actual error *   erp		pointer to the currently created ERP * * RETURN VALUES *   erp		modified ERP pointer * */static voiddasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense){	if (sense[25] & DASD_SENSE_BIT_3) {		dasd_3990_erp_alternate_path(erp);		if (erp->status == DASD_CQR_FAILED) {			/* reset the lpm and the status to be able to 			 * try further actions. */			erp->lpm = 0;			erp->status = DASD_CQR_ERROR;		}	}	erp->function = dasd_3990_erp_compound_path;}				/* end dasd_3990_erp_compound_path *//* * DASD_3990_ERP_COMPOUND_CODE  * * DESCRIPTION *   Handles the compound ERP action for retry code. * * PARAMETER *   sense		sense data of the actual error *   erp		pointer to the currently created ERP * * RETURN VALUES *   erp		NEW ERP pointer * */static struct dasd_ccw_req *dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense){	if (sense[25] & DASD_SENSE_BIT_2) {		switch (sense[28]) {		case 0x17:			/* issue a Diagnostic Control command with an 			 * Inhibit Write subcommand and controler modifier */			erp = dasd_3990_erp_DCTL(erp, 0x20);			break;					case 0x25:			/* wait for 5 seconds and retry again */			erp->retries = 1;						dasd_3990_erp_block_queue (erp, 5*HZ);			break;					default:			/* should not happen - continue */			break;		}	}	erp->function = dasd_3990_erp_compound_code;	return erp;}				/* end dasd_3990_erp_compound_code *//* * DASD_3990_ERP_COMPOUND_CONFIG  * * DESCRIPTION *   Handles the compound ERP action for configruation *   dependent error. *   Note: duplex handling is not implemented (yet). * * PARAMETER *   sense		sense data of the actual error *   erp		pointer to the currently created ERP * * RETURN VALUES *   erp		modified ERP pointer * */static voiddasd_3990_erp_compound_config(struct dasd_ccw_req * erp, char *sense){	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");	}	erp->function = dasd_3990_erp_compound_config;}				/* end dasd_3990_erp_compound_config *//* * DASD_3990_ERP_COMPOUND  * * DESCRIPTION *   Does the further compound program action if  *   compound retry was not successful. * * PARAMETER *   sense		sense data of the actual error *   erp		pointer to the current (failed) ERP * * RETURN VALUES *   erp		(additional) ERP pointer * */static struct dasd_ccw_req *dasd_3990_erp_compound(struct dasd_ccw_req * erp, char *sense){	if ((erp->function == dasd_3990_erp_compound_retry) &&	    (erp->status == DASD_CQR_ERROR)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -