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

📄 dasd_3990_erp.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  * File...........: linux/drivers/s390/block/dasd_3990_erp.c * Author(s)......: Horst  Hummel    <Horst.Hummel@de.ibm.com>  *                  Holger Smolinski <Holger.Smolinski@de.ibm.com> * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 * * History of changes: * 05/14/01 fixed PL030160GTO (BUG() in erp_action_5) */#include <asm/ccwcache.h>#include <asm/idals.h>#include <asm/s390io.h>#include <linux/timer.h>#include "dasd_int.h"#include "dasd_eckd.h"#include "dasd_3990_erp.h"#ifdef PRINTK_HEADER#undef PRINTK_HEADER#endif				/* PRINTK_HEADER */#define PRINTK_HEADER "dasd_erp(3990): "/* *****************************************************************************  * SECTION DEBUG ROUTINES *****************************************************************************  */voidlog_erp_chain (ccw_req_t *cqr,               int       caller,               __u32     cpa){        ccw_req_t     *loop_cqr = cqr;	dasd_device_t *device   = cqr->device;        int     i;        char    *nl,                 *end_cqr,                *begin,                 *end;                /* dump sense data */        if (device->discipline            &&             device->discipline->dump_sense  ) {                device->discipline->dump_sense (device,                                                 cqr);        }        /* log the channel program */        while (loop_cqr != NULL) {                                DASD_MESSAGE (KERN_ERR, device,                               "(%s) ERP chain report for req: %p",                              caller == 0 ? "EXAMINE" : "ACTION",                              loop_cqr);                                nl      = (char *) loop_cqr;                end_cqr = nl + sizeof (ccw_req_t);                                 while (nl < end_cqr) {                                                DASD_MESSAGE (KERN_ERR, device,                                       "%p: %02x%02x%02x%02x %02x%02x%02x%02x "                                      "%02x%02x%02x%02x %02x%02x%02x%02x",                                      nl,                                      nl[0], nl[1], nl[2], nl[3],                                      nl[4], nl[5], nl[6], nl[7],                                      nl[8], nl[9], nl[10], nl[11],                                      nl[12], nl[13], nl[14], nl[15]);                        nl +=16;                }                                        nl  = (char *) loop_cqr->cpaddr;                                if (loop_cqr->cplength > 40) { /* log only parts of the CP */                        DASD_MESSAGE (KERN_ERR, device, "%s",                                      "Start of channel program:");                                                for (i = 0; i < 20; i += 2) {                                                                 DASD_MESSAGE (KERN_ERR, device,                                               "%p: %02x%02x%02x%02x %02x%02x%02x%02x "                                              "%02x%02x%02x%02x %02x%02x%02x%02x",                                              nl,                                              nl[0], nl[1], nl[2], nl[3],                                              nl[4], nl[5], nl[6], nl[7],                                              nl[8], nl[9], nl[10], nl[11],                                              nl[12], nl[13], nl[14], nl[15]);                                                                nl += 16;                        }                                                DASD_MESSAGE (KERN_ERR, device, "%s",                                      "End of channel program:");                                                nl  = (char *) loop_cqr->cpaddr;                        nl  += ((loop_cqr->cplength - 10) * 8);                                                for (i = 0; i < 20; i += 2) {                                                                 DASD_MESSAGE (KERN_ERR, device,                                               "%p: %02x%02x%02x%02x %02x%02x%02x%02x "                                              "%02x%02x%02x%02x %02x%02x%02x%02x",                                              nl,                                              nl[0], nl[1], nl[2], nl[3],                                              nl[4], nl[5], nl[6], nl[7],                                              nl[8], nl[9], nl[10], nl[11],                                              nl[12], nl[13], nl[14], nl[15]);                                                                nl += 16;                        }                                        } else { /* log the whole CP */                                                DASD_MESSAGE (KERN_ERR, device, "%s",                                      "Channel program (complete):");                                                for (i = 0; i < (loop_cqr->cplength + 4); i += 2) {                                                                 DASD_MESSAGE (KERN_ERR, device,                                               "%p: %02x%02x%02x%02x %02x%02x%02x%02x "                                              "%02x%02x%02x%02x %02x%02x%02x%02x",                                              nl,                                              nl[0], nl[1], nl[2], nl[3],                                              nl[4], nl[5], nl[6], nl[7],                                              nl[8], nl[9], nl[10], nl[11],                                              nl[12], nl[13], nl[14], nl[15]);                                                                nl += 16;                        }                }                /* log bytes arround failed CCW if not already done */                 begin = (char *) loop_cqr->cpaddr;                end   = begin + ((loop_cqr->cplength+4) * 8);                nl = (void *)(long)cpa;                if (loop_cqr == cqr) {  /* log only once */                         /* if not whole CP logged OR CCW outside logged CP */                        if ((loop_cqr->cplength > 40) ||                               ((nl < begin        ) &&                             (nl > end          )   )   ) {                                                        nl -= 10*8;     /* start some bytes before */                                                                DASD_MESSAGE (KERN_ERR, device,                                                 "Failed CCW (%p) (area):",                                                (void *)(long)cpa);                                                                for (i = 0; i < 20; i += 2) {                                                                                 DASD_MESSAGE (KERN_ERR, device,                                                       "%p: %02x%02x%02x%02x %02x%02x%02x%02x "                                                      "%02x%02x%02x%02x %02x%02x%02x%02x",                                                      nl,                                                      nl[0], nl[1], nl[2], nl[3],                                                      nl[4], nl[5], nl[6], nl[7],                                                      nl[8], nl[9], nl[10], nl[11],                                                      nl[12], nl[13], nl[14], nl[15]);                                                                                nl += 16;                                }                                                        } else {                                                                DASD_MESSAGE (KERN_ERR, device,                                               "Failed CCW (%p) already logged",                                              (void *)(long)cpa);                        }                }                                loop_cqr = loop_cqr->refers;        }        } /* end log_erp_chain *//* *****************************************************************************  * 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磗. *  *   All other configurations are handled as recoverable errors. * * RETURN VALUES *   dasd_era_fatal     for all fatal (unrecoverable errors) *   dasd_era_recover   for all others. */dasd_era_tdasd_3990_erp_examine_24 (ccw_req_t *cqr,                          char      *sense){        dasd_device_t *device = cqr->device;        	/* check for 'Command Reject' */	if ((  sense[0] & SNS0_CMD_REJECT       ) &&	    (!(sense[2] & SNS2_ENV_DATA_PRESENT))   ) {                DASD_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))   ) {                DASD_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) {                                DASD_MESSAGE (KERN_ERR, device,                              "EXAMINE 24: No Record Found detected %s",                              cqr == device->init_cqr ? " " :                              "- 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. */dasd_era_tdasd_3990_erp_examine_32 (ccw_req_t *cqr,                          char      *sense){        dasd_device_t *device = cqr->device;	switch (sense[25]) {	case 0x00:		return dasd_era_none;	case 0x01:                DASD_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_tdasd_3990_erp_examine (ccw_req_t *cqr,                        devstat_t *stat){	char          *sense  = stat->ii.sense.data;        dasd_era_t     era    = dasd_era_recover;        dasd_device_t *device = cqr->device;	/* check for successful execution first */	if (stat->cstat == 0x00                                 &&	    stat->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  ) &&            (cqr != device->init_cqr)   ){                log_erp_chain (cqr,                                0,                                stat->cpa);        }                return era;} /* END dasd_3990_erp_examine *//* *****************************************************************************  * SECTION ERP HANDLING *****************************************************************************  *//* *****************************************************************************  * 24 and 32 byte sense ERP functions *****************************************************************************  *//* * DASD_3990_ERP_CLEANUP  * * DESCRIPTION *   Removes the already build but not neccessary ERP request and sets *   the status of the original cqr / erp to the given (final) status * *  PARAMETER *   erp                request to be blocked *   final_status       either CQR_STATUS_DONE or CQR_STATUS_FAILED  * * RETURN VALUES *   cqr                original cqr                */ccw_req_t *dasd_3990_erp_cleanup (ccw_req_t *erp,                       char      final_status){        ccw_req_t *cqr = erp->refers;                dasd_free_request (erp, erp->device);        check_then_set (&cqr->status,                        CQR_STATUS_ERROR,                        final_status);        return cqr;} /* end dasd_3990_erp_cleanup */ /* * DASD_3990_ERP_BLOCK_QUEUE  * * DESCRIPTION *   Block the given device request queue to prevent from further *   processing until the started timer has expired or an related *   interrupt was received. * *  PARAMETER *   erp                request to be blocked *   expires            time to wait until restart (in seconds)  *

⌨️ 快捷键说明

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