📄 mscp_bbr.c
字号:
bbrp->prev_desc.code = sp->code; bbrp->prev_desc.lbn = sp->lbn; sp->code = RCT_DS_UNUSABL; sp->lbn = 0; bbrp->multi_buf = bbrp->buf3; rp->p1 = ( bbrp->match_rbn / 128 ) + up->unt_size + 2; new_event = mscp_multi_write( rp ); return( new_event );}/**//* * * Name: mscp_bbr_step11c - * * Abstract: This function writes the original updated RCT descriptor * block to disk. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step11c( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register UNITB *up = rp->unitb; u_long new_event; Cprintf("mscp_bbr_step11c: entered\n"); /* Multi-write the descriptor block back into the RCT. */ bbrp->multi_buf = bbrp->buf2; rp->p1 = ( bbrp->rbn / 128 ) + up->unt_size + 2; new_event = mscp_multi_write( rp ); return( new_event );}/**//* * * Name: mscp_bbr_step12 - * * Abstract: This function issues the MSCP REPLACE command to actually * mark the block on disk as replaced. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step12( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register UNITB *up = rp->unitb; register MSCP *mp = rp->msgptr; u_long new_event; Cprintf("mscp_bbr_step12: entered\n"); /* Format and send a replace command to revector the logical block. */ Init_msg( mp, rp->rspid, rp->unitb->unit ); mp->mscp_opcode = MSCP_OP_REPLC; mp->mscp_modifier = MSCP_MD_PRIMR; if( bbrp->flags.bit.nonprim ) mp->mscp_modifier = 0; mp->mscp_rbn = bbrp->rbn; mp->mscp_lbn = bbrp->lbn; new_event = mscp_send_msg( rp ); return( new_event );}/**//* * * Name: mscp_bbr_step12a - * * Abstract: This function * * Replacement blocks are initially written with a test pattern and * marked with the forced error indicator. If this routine is * entered during a normal replacement operation, we can safely test * that the replacement block is still in that initial state. If the * replacement process was interrupted, however, we may have overwritten * the the replacement block data, so the test is not valid. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step12a( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register MSCP *mp = rp->msgptr; u_long code = mp->mscp_status & MSCP_ST_MASK; u_long subcode = mp->mscp_status >> MSCP_ST_SBBIT; register u_long new_event; Cprintf("mscp_bbr_step12a: entered\n"); /* If the REPLACE command succeeded and the BBR code has been * entered to complete a previously interrupted replacement, * redispatch. Otherwise, read the replacement block data. */ if(( code == MSCP_ST_SUCC ) && ( subcode == MSCP_SC_NORML )) { if( bbrp->flags.bit.p2recov ) new_event = EV_BBRSUCCESS; else { rp->p1 = bbrp->lbn; rp->p2 = 0; new_event = mscp_bbr_read( rp, bbrp->buf3 ); } /* Failure of a replacement command is a severe error. Redispatch * to process the command failure. */ } else { Cprintf("REPLACE failed: code = %x, subcode = %x\n", code, subcode); bbrp->flags.bit.repfail = 1; mscp_bbr_log(rp, MSLG_FM_DISK_TRN, code, subcode); new_event = EV_BBRERROR; } return( new_event );}/**//* * * Name: mscp_bbr_step12b - * * Abstract: This function verifies that the target RBN is unused by * checking that the read end status is a forced error. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step12b( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register MSCP *mp = rp->msgptr; register RCT_SECTOR_0 *sp = ( RCT_SECTOR_0 * )bbrp->buf0; u_long code = mp->mscp_status & MSCP_ST_MASK; u_long subcode = mp->mscp_status >> MSCP_ST_SBBIT; register u_long new_event; Cprintf("mscp_bbr_step12b: entered\n"); /* If the read completion status is forced error, the RBN is still * in its initial pristine state. If the status indicates some other * data error, the replacement block is bad and another will have to * be found. Redispatch to step 9. Any other status is treated as a * replace command failure. * severe error. */ if( code == MSCP_ST_DATA ) { if( subcode == MSCP_SC_FRCER ) new_event = EV_BBRSUCCESS; else { bbrp->match_rbn = bbrp->rbn; bbrp->flags.bit.match = 1; sp->badrbn = bbrp->rbn; sp->flags |= RCT_S0_BR; new_event = EV_BBRSUBSTEP; } } else { Cprintf("code = %x, subcode = %x\n", code, subcode); bbrp->flags.bit.repfail = 1; mscp_bbr_log(rp, MSLG_FM_DISK_TRN, code, subcode); new_event = EV_BBRERROR; } return( new_event );}/**//* * * Name: mscp_bbr_step12c - Write back saved data * * Abstract: Step 12c of the bad block replacement algorithm * writes the saved data back to the bad block, then * reads it back and compares it to the saved data. * If the write, read and compare all succeed, the * replacement has succeeded. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step12c( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register MSCP *mp = rp->msgptr; register u_long new_event = EV_NULL; RCT_SECTOR_0 *sp = ( RCT_SECTOR_0 * )bbrp->buf0; u_long code = mp->mscp_status & MSCP_ST_MASK; u_long subcode = mp->mscp_status >> MSCP_ST_SBBIT; Cprintf("mscp_bbr_step12c: entered, Event = %x\n", event); /* On initial entry into this substep, initialize the loop counter * and write the saved data into the block in question. If the FE * flag is set, write the data with the forced error modifier. */ if( event == EV_BBRSUCCESS ) { rp->p1 = bbrp->lbn; rp->p2 = 0; if( bbrp->flags.bit.fe ) /* TODO fix this name */ rp->p2 |= MSCP_MD_ERROR; new_event = mscp_bbr_write( rp, bbrp->buf1 ); /* Not the initial entry, so an end message arrived. If the message was * a write, and it succeeded, read back the data into another work * buffer. If the write failed set the status to EV_BBRERROR. */ } else if( mp->mscp_endcode == ( MSCP_OP_WRITE | MSCP_OP_END )) { if(( code != MSCP_ST_SUCC ) ) { bbrp->match_rbn = bbrp->rbn; bbrp->flags.bit.match = 1; sp->badrbn = bbrp->rbn; sp->flags |= RCT_S0_BR; new_event = EV_BBRERROR; } else new_event = mscp_bbr_read( rp, bbrp->buf3 ); /* The end message was a read. If the end message status is success * or the status is a forced error and the data was written with the * forced error modifier, the read succeeded. Compare the saved data * to the data read back. If the read and the compare both succeeded, * set the return status to EV_BBRSUCCESS. Otherwise set it to * EV_BBRERROR. */ } else if(( code == MSCP_ST_SUCC ) || (( code == MSCP_ST_DATA ) && ( subcode == MSCP_SC_FRCER ) && ( bbrp->flags.bit.fe )) && ( bcmp( bbrp->buf1, bbrp->buf3, 512 ) == 0 )) { new_event = EV_BBRSUCCESS; /* The read failed: set the error flag. */ } else { bbrp->match_rbn = bbrp->rbn; bbrp->flags.bit.match = 1; sp->badrbn = bbrp->rbn; sp->flags |= RCT_S0_BR; new_event = EV_BBRERROR; } return( new_event );}/**//* * * Name: mscp_bbr_step12d - * * Abstract: This function writes the saved data back to the original * lbn. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step12d( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register UNITB *up = rp->unitb; register CONNB *cp = rp->connb; register MSCP *mp = rp->msgptr; u_long new_event; Cprintf("mscp_bbr_step12d: entered\n"); printf("\t\tWARNING\n"); printf("REPLACE command failure at lbn %d\n", bbrp->lbn); printf("on controller %d unit %d. Notify Field Service \n", cp->cnt_number, up->unit); printf("or consult the System Managers Guide.\n"); rp->p1 = bbrp->lbn; rp->p2 = 0; if( bbrp->flags.bit.fe ) rp->p2 |= MSCP_MD_ERROR; new_event = mscp_bbr_write( rp, bbrp->buf1 ); return( new_event );}/**//* * * Name: mscp_bbr_step12e - * * Abstract: This function issues a MSCP SET UNIT CHARACTERISTICS command * to software write-protect the unit. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step12e( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register UNITB *up = rp->unitb; register MSCP *mp = rp->msgptr; u_long new_event; Cprintf("mscp_bbr_step12e: entered\n"); /* Format and send a set unit characteristics command to * write protect the unit. */ Init_msg( mp, rp->rspid, rp->unitb->unit ); mp->mscp_opcode = MSCP_OP_STUNT; mp->mscp_modifier = MSCP_MD_STWRP; mp->mscp_unt_flgs = MSCP_UF_WRTPS; new_event = mscp_send_msg( rp ); return( new_event );}/**//* * * Name: mscp_bbr_step13 - End of replacement update to RCT 0 * * Abstract: This function updates RCT sector 0 to reflect the * fact that replacement is no longer taking place. * The sector, read in step 6, is modified and rewritten * to the RCT. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step13( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register UNITB *up = rp->unitb; register RCT_SECTOR_0 *sp = ( RCT_SECTOR_0 * )bbrp->buf0; Cprintf("mscp_bbr_step13: entered\n"); /* Update RCT sector 0 by clearing the replacement flags, the lbn * being replaced, the replacement block number, and the bad * replacement block number. */ sp->flags = 0; sp->lbn = 0; sp->rbn = 0; sp->badrbn = 0; /* Set up the buffer address and RCT sector 0 logical block * number and start the multicopy write. */ bbrp->multi_buf = bbrp->buf0; rp->p1 = up->unt_size; return( mscp_multi_write( rp ));}/**//* * * Name: mscp_bbr_step14 - Clean up and release locks * * Abstract: This function logs the successful replacement attempt in * the system error log and calls bbr_unlock() to restart the * original I/O. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs: * * Outputs: * * * Return * Values: EV_NULL */u_longmscp_bbr_step14( event, rp ) u_long event; register REQB *rp;{ register BBRB *bbrp = rp->connb->bbrb; register UNITB *up = rp->unitb; register RCT_SECTOR_0 *sp = ( RCT_SECTOR_0 * )bbrp->buf0; register u_long flags, subcode; Cprintf("mscp_bbr_step14: entered\n"); flags = 0; subcode = 0; if(bbrp->flags.bit.fe) flags |= MSLG_LFR_FE; if(bbrp->flags.bit.nonprim) flags |= MSLG_LFR_TE; if(bbrp->flags.bit.match) flags |= MSLG_LFR_BR; if(bbrp->flags.bit.trans) subcode = MSCP_SC_NOTRP; else { subcode = MSCP_SC_BBROK; flags |= MSLG_LFR_RP; } mscp_bbr_log(rp, MSLG_FM_REPLACE, flags, subcode); mscp_bbr_unlock(rp); return( EV_NULL );}/**//* * * Name: mscp_bbr_step15 - * * Abstract: This function attempts to "undo" the failed replacement * by restoring the RCT entries to their previous state. * * Inputs: IPL_SCS * event Event code * rp Request block pointer * * Implicit * Inputs:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -