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

📄 dasd_3990_erp.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		dasd_3990_erp_compound_path(erp, sense);	}	if ((erp->function == dasd_3990_erp_compound_path) &&	    (erp->status == DASD_CQR_ERROR)) {		erp = dasd_3990_erp_compound_code(erp, sense);	}	if ((erp->function == dasd_3990_erp_compound_code) &&	    (erp->status == DASD_CQR_ERROR)) {		dasd_3990_erp_compound_config(erp, sense);	}	/* if no compound action ERP specified, the request failed */	if (erp->status == DASD_CQR_ERROR) {		erp->status = DASD_CQR_FAILED;	}	return erp;}				/* end dasd_3990_erp_compound *//* * DASD_3990_ERP_INSPECT_32  * * DESCRIPTION *   Does a detailed inspection of the 32 byte sense data *   and sets up a related error recovery action.   * * PARAMETER *   sense		sense data of the actual error *   erp		pointer to the currently created default ERP * * RETURN VALUES *   erp_filled		pointer to the ERP * */static struct dasd_ccw_req *dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense){	struct dasd_device *device = erp->device;	erp->function = dasd_3990_erp_inspect_32;	if (sense[25] & DASD_SENSE_BIT_0) {		/* compound program action codes (byte25 bit 0 == '1') */		dasd_3990_erp_compound_retry(erp, sense);	} else {		/* single program action codes (byte25 bit 0 == '0') */		switch (sense[25]) {		case 0x00:	/* success - use default ERP for retries */		        DEV_MESSAGE(KERN_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");			erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);			break;		case 0x02:	/* intervention required */		case 0x03:	/* intervention required during dual copy */			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");			erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);			break;		case 0x10:  /* logging required for other channel program */			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");			erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);			break;		case 0x1B:	/* unexpected condition during write */			erp = dasd_3990_erp_action_1B_32(erp, sense);			break;		case 0x1C:	/* invalid data */			DEV_MESSAGE(KERN_EMERG, device, "%s",				    "Data recovered during retry with PCI "				    "fetch mode active");			/* not possible to handle this situation in Linux */			panic			    ("Invalid data - No way to inform application "			     "about the possibly incorrect data");			break;		case 0x1D:	/* state-change pending */			DEV_MESSAGE(KERN_DEBUG, device, "%s",				    "A State change pending condition exists "				    "for the subsystem or device");			erp = dasd_3990_erp_action_4(erp, sense);			break;		case 0x1E:	/* busy */                        DEV_MESSAGE(KERN_DEBUG, device, "%s",				    "Busy condition exists "				    "for the subsystem or device");                        erp = dasd_3990_erp_action_4(erp, sense);			break;		default:	/* all others errors - default erp  */			break;		}	}	return erp;}				/* end dasd_3990_erp_inspect_32 *//* *****************************************************************************  * main ERP control fuctions (24 and 32 byte sense) *****************************************************************************  *//* * DASD_3990_ERP_INSPECT * * DESCRIPTION *   Does a detailed inspection for sense data by calling either *   the 24-byte or the 32-byte inspection routine. * * PARAMETER *   erp		pointer to the currently created default ERP * RETURN VALUES *   erp_new		contens was possibly modified  */static struct dasd_ccw_req *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;	/* distinguish between 24 and 32 byte sense data */	if (sense[27] & DASD_SENSE_BIT_0) {		/* inspect the 24 byte sense data */		erp_new = dasd_3990_erp_inspect_24(erp, sense);	} else {		/* inspect the 32 byte sense data */		erp_new = dasd_3990_erp_inspect_32(erp, sense);	}	/* end distinguish between 24 and 32 byte sense data */	return erp_new;}/* * DASD_3990_ERP_ADD_ERP *  * 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) * * PARAMETER *   cqr		head of the current ERP-chain (or single cqr if  *			first error) * RETURN VALUES *   erp		pointer to new ERP-chain head */static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr){	struct dasd_device *device = cqr->device;	struct ccw1 *ccw;	/* allocate additional request block */	struct dasd_ccw_req *erp;	erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, cqr->device);	if (IS_ERR(erp)) {                if (cqr->retries <= 0) {		        DEV_MESSAGE(KERN_ERR, device, "%s",				    "Unable to allocate ERP request");			cqr->status = DASD_CQR_FAILED;                        cqr->stopclk = get_clock ();		} else {                        DEV_MESSAGE (KERN_ERR, device,                                     "Unable to allocate ERP request "				     "(%i retries left)",                                     cqr->retries);			dasd_set_timer(device, (HZ << 3));                }		return cqr;	}	/* 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->magic    = cqr->magic;	erp->expires  = 0;	erp->retries  = 256;	erp->buildclk = get_clock();	erp->status = DASD_CQR_FILLED;	return erp;}/* * DASD_3990_ERP_ADDITIONAL_ERP  *  * DESCRIPTION *   An additional ERP is needed to handle the current error. *   Add ERP to the head of the ERP-chain containing the ERP processing *   determined based on the sense data. * * PARAMETER *   cqr		head of the current ERP-chain (or single cqr if  *			first error) * * RETURN VALUES *   erp		pointer to new ERP-chain head */static struct dasd_ccw_req *dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr){	struct dasd_ccw_req *erp = NULL;	/* add erp and initialize with default TIC */	erp = dasd_3990_erp_add_erp(cqr);	/* inspect sense, determine specific ERP if possible */	if (erp != cqr) {		erp = dasd_3990_erp_inspect(erp);	}	return erp;}				/* end dasd_3990_erp_additional_erp *//* * DASD_3990_ERP_ERROR_MATCH * * DESCRIPTION *   Check if the device status of the given cqr is the same. *   This means that the failed CCW and the relevant sense data *   must match. *   I don't distinguish between 24 and 32 byte sense because in case of *   24 byte sense byte 25 and 27 is set as well. * * PARAMETER *   cqr1		first cqr, which will be compared with the  *   cqr2		second cqr. * * RETURN VALUES *   match		'boolean' for match found *			returns 1 if match found, otherwise 0. */static intdasd_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 */	}	/* 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]))) {		return 0;	/* sense doesn't match */	}	return 1;		/* match */}				/* end dasd_3990_erp_error_match *//* * DASD_3990_ERP_IN_ERP * * DESCRIPTION *   check if the current error already happened before. *   quick exit if current cqr is not an ERP (cqr->refers=NULL) * * PARAMETER *   cqr		failed cqr (either original cqr or already an erp) * * RETURN VALUES *   erp		erp-pointer to the already defined error  *			recovery procedure OR *			NULL if a 'new' error occurred. */static struct dasd_ccw_req *dasd_3990_erp_in_erp(struct dasd_ccw_req *cqr){	struct dasd_ccw_req *erp_head = cqr,	/* save erp chain head */	*erp_match = NULL;	/* save erp chain head */	int match = 0;		/* 'boolean' for matching error found */	if (cqr->refers == NULL) {	/* return if not in erp */		return NULL;	}	/* check the erp/cqr chain for current error */	do {		match = dasd_3990_erp_error_match(erp_head, cqr->refers);		erp_match = cqr;	/* save possible matching erp  */		cqr = cqr->refers;	/* check next erp/cqr in queue */	} while ((cqr->refers != NULL) && (!match));	if (!match) {		return NULL;	/* no match was found */	}	return erp_match;	/* return address of matching erp */}				/* END dasd_3990_erp_in_erp *//* * DASD_3990_ERP_FURTHER_ERP (24 & 32 byte sense) * * DESCRIPTION *   No retry is left for the current ERP. Check what has to be done  *   with the ERP. *     - do further defined ERP action or *     - wait for interrupt or	 *     - exit with permanent error * * PARAMETER *   erp		ERP which is in progress with no retry left * * RETURN VALUES *   erp		modified/additional ERP */static struct dasd_ccw_req *dasd_3990_erp_further_erp(struct dasd_ccw_req *erp){	struct dasd_device *device = erp->device;	char *sense = erp->irb.ecw;	/* check for 24 byte sense ERP */	if ((erp->function == dasd_3990_erp_bus_out) ||	    (erp->function == dasd_3990_erp_action_1) ||	    (erp->function == dasd_3990_erp_action_4)) {		erp = dasd_3990_erp_action_1(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)) {			/* issue a Diagnostic Control command with an 			 * Inhibit Write subcommand */			switch (sense[25]) {			case 0x17:			case 0x57:{	/* controller */					erp = dasd_3990_erp_DCTL(erp, 0x20);					break;				}			case 0x18:			case 0x58:{	/* channel path */					erp = dasd_3990_erp_DCTL(erp, 0x40);					break;				}			case 0x19:			case 0x59:{	/* storage director */					erp = dasd_3990_erp_DCTL(erp, 0x80);					break;				}			default:				DEV_MESSAGE(KERN_DEBUG, 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)) {		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);		erp->status = DASD_CQR_FAILED;	}	return erp;}				/* end dasd_3990_erp_further_erp *//* * DASD_3990_ERP_HANDLE_MATCH_ERP  * * DESCRIPTION *   An error occurred again and an ERP has been detected which is already *   used to handle this error (e.g. retries).  *   All prior ERP's are asumed to be successful and therefore removed *   from queue. *   If retry counter of matching erp is already 0, it is checked if further  *   action is needed (besides retry) or if the ERP has failed. * * PARAMETER *   erp_head		first ERP in ERP-chain *   erp		ERP that handles the actual error. *			(matching erp) * * RETURN VALUES *   erp		modified/additional ERP */static struct dasd_ccw_req *dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head,			       struct dasd_ccw_req *erp){	struct dasd_device *device = erp_head->device;	struct dasd_ccw_req *erp_done = erp_head;	/* finished req */	struct dasd_ccw_req *erp_free = NULL;	/* req to be freed */	/* loop over successful ERPs and remove them from chanq */	while (erp_done != erp) {		if (erp_done == NULL)	/* end of chain reached */			panic(PRINTK_HEADER "Programming error in ERP! The "			      "original request was lost\n");		/* remove the request from the device queue */		list_del(&erp_done->list);		erp_free = erp_done;		erp_done = erp_done->refers;		/* free the finished erp request */		dasd_free_erp_request(erp_free, erp_free->device);	}			/* end while */	if (erp->retries > 0) {		char *sense = erp->refers->irb.ecw;		/* check for special retries */		if (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) {			erp = dasd_3990_update_1B(erp, sense);		} else if (erp->function == dasd_3990_erp_int_req) {			erp = dasd_3990_erp_int_req(erp);		} else {			/* simple retry	  */			DEV_MESSAGE(KERN_DEBUG, device,				    "%i retries left for erp %p",				    erp->retries, erp);			/* handle

⌨️ 快捷键说明

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