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 + -
显示快捷键?