dasd_3990_erp.c

来自「linux-2.4.29操作系统的源码」· C语言 代码 · 共 1,977 行 · 第 1/5 页

C
1,977
字号
        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. */voiddasd_3990_erp_block_queue (ccw_req_t     *erp,                           unsigned long expires){	dasd_device_t *device = erp->device;        DEV_MESSAGE (KERN_INFO, device,                     "blocking request queue for %is",                     (int) expires);        device->stopped |= DASD_STOPPED_PENDING;        check_then_set (&erp->status,                        CQR_STATUS_ERROR,                        CQR_STATUS_QUEUED);        /* restart queue after some time */        if (!timer_pending(&device->blocking_timer)) {                init_timer(&device->blocking_timer);                device->blocking_timer.function = dasd_3990_erp_restart_queue;                 device->blocking_timer.data     = (unsigned long) device;                device->blocking_timer.expires  = jiffies + (expires * HZ);                add_timer(&device->blocking_timer);         } else {                mod_timer(&device->blocking_timer, jiffies + (expires * HZ));        }} /* end dasd_3990_erp_block_queue */ /* * DASD_3990_ERP_RESTART_QUEUE  * * DESCRIPTION *   Restarts request queue of current device. *   This has to be done if either an related interrupt was received, or  *   the timer has expired. */voiddasd_3990_erp_restart_queue (unsigned long device_ptr){	dasd_device_t *device = (dasd_device_t *) device_ptr;	unsigned long flags;                /* get the needed locks to modify the request queue */	s390irq_spin_lock_irqsave (device->devinfo.irq,                                    flags);        /* 'restart' the device queue */        DEV_MESSAGE (KERN_INFO, device, "%s",                     "request queue restarted by MIH");        device->stopped &= ~DASD_STOPPED_PENDING;        s390irq_spin_unlock_irqrestore (device->devinfo.irq,                                         flags);        dasd_schedule_bh (device);} /* end dasd_3990_erp_restart_queue *//* * DASD_3990_ERP_INT_REQ  * * DESCRIPTION *   Handles 'Intervention Required' error. *   This means either device offline or not installed. * * PARAMETER *   erp                current erp * RETURN VALUES *   erp                modified erp */ccw_req_t *dasd_3990_erp_int_req (ccw_req_t *erp){	dasd_device_t *device = erp->device;        /* first time set initial retry counter and erp_function */        /* and retry once without blocking queue                 */        /* (this enables easier enqueing of the cqr)             */        if (erp->function != dasd_3990_erp_int_req) {                erp->retries  = 256;                erp->function = dasd_3990_erp_int_req;        } else {                /* issue a message and wait for 'device ready' interrupt */                DEV_MESSAGE (KERN_ERR, device, "%s",                             "is offline or not installed - "                             "INTERVENTION REQUIRED!!");                                dasd_3990_erp_block_queue (erp,                                           60);        }	return erp;} /* end dasd_3990_erp_int_req *//* * DASD_3990_ERP_ALTERNATE_PATH  * * DESCRIPTION *   Repeat the operation on a different channel path. *   If all alternate paths have been tried, the request is posted with a *   permanent error. * *  PARAMETER *   erp                pointer to the current ERP * * RETURN VALUES *   erp                modified pointer to the ERP * */voiddasd_3990_erp_alternate_path (ccw_req_t *erp){	dasd_device_t *device = erp->device;        int irq = device->devinfo.irq;        /* try alternate valid path */        erp->lpm     &= ~(erp->dstat->lpum);        erp->options |= DOIO_VALID_LPM;		/* use LPM for DO_IO */	if ((erp->lpm & ioinfo[irq]->opm) != 0x00) {		DEV_MESSAGE (KERN_DEBUG, device,                             "try alternate lpm=%x (lpum=%x / opm=%x)",                             erp->lpm,                             erp->dstat->lpum,                             ioinfo[irq]->opm);		/* reset status to queued to handle the request again... */		if (erp->status > CQR_STATUS_QUEUED)                        erp->status = CQR_STATUS_QUEUED;                erp->retries = 1;                	} else {                         DEV_MESSAGE (KERN_ERR, device,                             "No alternate channel path left (lpum=%x / "                             "opm=%x) -> permanent error",                             erp->dstat->lpum,                             ioinfo[irq]->opm);                /* post request with permanent error */		if (erp->status > CQR_STATUS_QUEUED)                        erp->status = CQR_STATUS_FAILED;        }        } /* end dasd_3990_erp_alternate_path *//* * DASD_3990_ERP_DCTL * * DESCRIPTION *   Setup cqr to do the Diagnostic Control (DCTL) command with an  *   Inhibit Write subcommand (0x20) and the given modifier. * *  PARAMETER *   erp                pointer to the current (failed) ERP *   modifier           subcommand modifier *    * RETURN VALUES *   dctl_cqr           pointer to NEW dctl_cqr  * */ccw_req_t *dasd_3990_erp_DCTL (ccw_req_t *erp,                    char      modifier){	dasd_device_t *device = erp->device;	DCTL_data_t   *DCTL_data;        ccw1_t        *ccw;        ccw_req_t     *dctl_cqr = dasd_alloc_request ((char *) &erp->magic,                                                      1,                                                      sizeof(DCTL_data_t),                                                      erp->device);        	if (!dctl_cqr) {                DEV_MESSAGE (KERN_ERR, device, "%s",                             "Unable to allocate DCTL-CQR");                                check_then_set (&erp->status,                                CQR_STATUS_ERROR,                                CQR_STATUS_FAILED);		return erp;        }	DCTL_data = dctl_cqr->data;        DCTL_data->subcommand = 0x02; /* Inhibit Write */        DCTL_data->modifier   = modifier;	ccw = dctl_cqr->cpaddr;	memset (ccw, 0, sizeof (ccw1_t));        ccw->cmd_code = CCW_CMD_DCTL;        ccw->count    = 4;        if (dasd_set_normalized_cda(ccw,                                     __pa (DCTL_data), dctl_cqr, erp->device)) {                dasd_free_request (dctl_cqr, erp->device);                DEV_MESSAGE (KERN_ERR, device, "%s",                             "Unable to allocate DCTL-CQR");                check_then_set (&erp->status,                                CQR_STATUS_ERROR,                                CQR_STATUS_FAILED);		return erp;        }        dctl_cqr->function = dasd_3990_erp_DCTL;        dctl_cqr->refers   = erp;        dctl_cqr->device   = erp->device;        dctl_cqr->magic    = erp->magic;        dctl_cqr->lpm      = LPM_ANYPATH;        dctl_cqr->expires  = 5 * TOD_MIN;        dctl_cqr->retries  = 2;	dctl_cqr->buildclk = get_clock ();        dctl_cqr->status = CQR_STATUS_FILLED;	return dctl_cqr;} /* end dasd_3990_erp_DCTL *//* * DASD_3990_ERP_ACTION_1  * * 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). * *  PARAMETER *   erp                pointer to the current ERP * * RETURN VALUES *   erp                pointer to the ERP * */ccw_req_t *dasd_3990_erp_action_1 (ccw_req_t *erp){        erp->function = dasd_3990_erp_action_1;        dasd_3990_erp_alternate_path (erp);	return erp;} /* end dasd_3990_erp_action_1 *//* * DASD_3990_ERP_ACTION_4  * * DESCRIPTION *   Setup ERP to do the ERP action 4 (see Reference manual). *   Set the current request to PENDING to block the CQR queue for that device *   until the state change interrupt appears. *   Use a timer (20 seconds) to retry the cqr if the interrupt is still missing. * *  PARAMETER *   sense              sense data of the actual error *   erp                pointer to the current ERP * * RETURN VALUES *   erp                pointer to the ERP * */ccw_req_t *dasd_3990_erp_action_4 (ccw_req_t *erp,			char      *sense){	dasd_device_t *device = erp->device;        /* 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) {                erp->retries  = 256;                 erp->function = dasd_3990_erp_action_4;        } else {                if (sense[25] == 0x1D) {	/* state change pending */                                                DEV_MESSAGE (KERN_INFO, device,                                     "waiting for state change pending "                                     "interrupt, %d retries left",                                     erp->retries);                        dasd_3990_erp_block_queue (erp,                                                   30);                } else {			DEV_MESSAGE (KERN_INFO, device,                                      "redriving request immediately, "                                     "%d retries left",                                      erp->retries);                        /* no state change pending - retry */                        check_then_set (&erp->status,                                        CQR_STATUS_ERROR,                                        CQR_STATUS_QUEUED);                }        }	return erp;} /* end dasd_3990_erp_action_4 *//* *****************************************************************************  * 24 byte sense ERP functions (only) *****************************************************************************  *//* * DASD_3990_ERP_ACTION_5  * * DESCRIPTION *   Setup ERP to do the ERP action 5 (see Reference manual). *   NOTE: Further handling is done in xxx_further_erp after the retries. * *  PARAMETER *   erp                pointer to the current ERP * * RETURN VALUES *   erp                pointer to the ERP * */ccw_req_t *

⌨️ 快捷键说明

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