📄 mscp_disk.c
字号:
* Otherwise, redispatch with the (preset) online complete event. */ if( !( up->unt_flgs & MSCP_UF_REPLC || up->flags.wrtp || up->flags.alonl )) new_event = mscp_bbr_online( rp ); /* The Get Unit Status failed. Recycle the RSPID and redispatch * to retry the ONLINE command. */ } else { mscp_recycle_rspid( rp ); new_event = EV_ONLERROR; } return( new_event );} /**//* * * Name: mscp_markonline - Mark unit online. * * Abstract: * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_long mscp_markonline( event, rp ) u_long event; register REQB *rp;{ register UNITB *up = rp->unitb; register u_long new_event = EV_NULL; up->flags.online = 1; up->flags.online_ip = 0; mscp_dealloc_reqb( rp ); return( new_event );}/**//* * * Name: mscp_availcm - Send an AVAIL command message * * Abstract: * * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_longmscp_availcm( event, rp ) u_long event; register REQB *rp;{ register UNITB *up = rp->unitb; register MSCP *mp = rp->msgptr; register u_long new_event; /* Format the message buffer as a AVAILABLE command. Queue the message * for transmission, then wait for the AVAILABLE end message. * If the unit is set to exclusive access mode then set the exclusive * modifier to hold onto the exclusive access operation. This implies that * the only way to clear exclusive access is to issue an ioctl to clear * the excl_acc flag and then do an avail. The other way exclusive access * is cleared is when the unit becomes inoperative, disabled or unknown. */ Init_msg( mp, rp->rspid, rp->unitb->unit ); mp->mscp_opcode = MSCP_OP_AVAIL; if ( up->flags.excl_acc ) { mp->mscp_modifier = MSCP_MD_EXCAC; } new_event = mscp_send_msg( rp ); return( new_event );} /**//* * * Name: mscp_markoffline - Mark a unit offline * * Abstract: * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_longmscp_markoffline( event, rp ) u_long event; register REQB *rp;{ register UNITB *up = rp->unitb; register CONNB *cp = rp->connb; register MSCP *mp = rp->msgptr; register u_long new_event = EV_NULL; u_short em_status = mp->mscp_status & MSCP_ST_MASK; u_short em_subcode = mp->mscp_status >> MSCP_ST_SBBIT; /* Reset the online-in-progress bit, deallocate the request block * and exit with an EV_NULL event. */ up->flags.online_ip = 0; up->flags.close_ip = 0; up->flags.online = 0; /* If unit recovery is in progress: this unit did not come back * online so document the failure (printf) and return EV_ONLERROR * to continue the unit recovery process. */ if(( cp->flags.restart) && (rp->flags.perm_reqb)) { printf("\nDisk unit #%d failed unit recovery.\n",up->unit); return (EV_ONLERROR); } mscp_dealloc_reqb( rp ); return( new_event );}/**//* * * Name: mscp_transfercm - Send a READ/WRITE command message * * Abstract: * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_longmscp_transfercm( event, rp ) u_long event; register REQB *rp;{ register MSCP *mp = rp->msgptr; register struct buf *bp = rp->bufptr; register UNITB *up = rp->unitb; register struct uba_device *ui = up->ubdev; /* set up stat data for iostat utilities. */ if(ui->ui_dk >= 0) { dk_xfer[ui->ui_dk]++; dk_wds[ui->ui_dk] += bp->b_bcount>>6; } /* Format the message buffer as a READ/WRITE command and fill in * the transfer byte count, local buffer handle, and logical * block number. Update the state and send the message, then * wait for the end message to come back. */ Init_msg( mp, rp->rspid, rp->unitb->unit ); mp->mscp_opcode = ( bp->b_flags & B_READ ) ? MSCP_OP_READ : MSCP_OP_WRITE; mp->mscp_byte_cnt = bp->b_bcount; Move_bhandle( rp->lbhandle, mp->mscp_buffer[ 0 ] ); mp->mscp_lbn = rp->p1; return( mscp_send_msg( rp )); }/**//* * * Name: mscp_transferem - process a data transfer end message. * * Abstract: * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_longmscp_transferem( event, rp ) u_long event; register REQB *rp;{ register MSCP *mp = rp->msgptr; register struct buf *bp = rp->bufptr; register u_long new_event = EV_NULL; UNITB *up = rp->unitb; struct uba_device *ui = up->ubdev; u_short em_status = mp->mscp_status & MSCP_ST_MASK; u_short em_subcode = mp->mscp_status >> MSCP_ST_SBBIT; if( mp->mscp_flags & MSCP_EF_BBLKR ) { new_event = mscp_bbr_replace( rp ); } else { /* If an error of any kind occurred during the data transfer, * mark the buf structure accordingly. */ if( em_status != MSCP_ST_SUCC ) { bp->b_flags |= B_ERROR; bp->b_error = EIO; /* temporary log force error here - pmk */ if (em_status == MSCP_ST_DATA && em_subcode == MSCP_SC_FRCER) { printf("ra%d%c: hard error sn %d\n", Ux( bp->b_dev ), 'a' + ( u_char )Px( bp->b_dev ), bp->b_blkno + (mp->mscp_byte_cnt / 512)); printf("ra%d%c: Force Error Modifer Set: LBN %d\n", Ux( bp->b_dev ), 'a' + ( u_char )Px( bp->b_dev ), rp->p1 + (mp->mscp_byte_cnt / 512)); } } /* Save the bytes not transferred in the request block. (It can't * be saved in b_resid, because mapping information is stuffed in * there by the port driver. I/O done is likewise deferred until * the buffer has been unmapped.) * Deallocate the request block with all the resources that it * holds and terminate the thread. */ rp->p1 = bp->b_bcount - mp->mscp_byte_cnt; mscp_dealloc_reqb( rp ); } return( new_event );}/**//* * * Name: mscp_accscancm - access command message * * Abstract: * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_longmscp_accscancm( event, rp ) u_long event; register REQB *rp;{ register MSCP *mp = rp->msgptr; register UNITB *up = rp->unitb; Init_msg( mp, rp->rspid, rp->unitb->unit ); mp->mscp_opcode = MSCP_OP_ACCESS; mp->mscp_byte_cnt = rp->p2; mp->mscp_lbn = rp->p1; return( mscp_send_msg( rp )); }/**//* * * Name: mscp_accscanem - process an access end message. * * Abstract: * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_longmscp_accscanem( event, rp ) u_long event; register REQB *rp;{ register MSCP *mp = rp->msgptr; register u_long new_event = EV_NULL; UNITB *up = rp->unitb; up->acc_status = mp->mscp_status; up->acc_flags = mp->mscp_flags; up->acc_badlbn = mp->mscp_lbn; up->acc_bytecnt = mp->mscp_byte_cnt; if( mp->mscp_flags & MSCP_EF_BBLKR ) { new_event = mscp_bbr_replace( rp ); } else { up->flags.force_scan_ip = 0; mscp_dealloc_reqb( rp ); } return( new_event );}/**//* * * Name: mscp_setunitcm - set unit command message * * Abstract: * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_longmscp_setunitcm( event, rp ) u_long event; register REQB *rp;{ register MSCP *mp = rp->msgptr; register UNITB *up = rp->unitb; Init_msg( mp, rp->rspid, rp->unitb->unit ); mp->mscp_opcode = MSCP_OP_STUNT; if ( up->flags.excl_acc ) mp->mscp_modifier = MSCP_MD_EXCAC; return( mscp_send_msg( rp ) ); }/**//* * * Name: mscp_setunitem - process a set unit end message. * * Abstract: * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_longmscp_setunitem( event, rp ) u_long event; register REQB *rp;{ register MSCP *mp = rp->msgptr; register u_long new_event = EV_NULL; UNITB *up = rp->unitb; u_short em_status = mp->mscp_status & MSCP_ST_MASK; u_short em_subcode = mp->mscp_status >> MSCP_ST_SBBIT; /* * Check to see that the command succeeded. A status of available with * a subcode of available implies success subcode normal when exclusive * access is granted while the unit was in the "Unit-Available" state. */ if (( em_status == MSCP_ST_SUCC ) || (( em_status == MSCP_ST_AVLBL ) && (em_subcode == MSCP_SC_AVAIL))) { /* Make sure the set of exclusive access succeeded. If it does fail * then clear the excl_acc flag so that the ioctl routine will know to * return a failure status. */ if ( up->flags.excl_acc ) { if (( mp->mscp_unt_flgs & MSCP_UF_EXACC ) == 0 ) { up->flags.excl_acc = 0; } } else { if ( mp->mscp_unt_flgs & MSCP_UF_EXACC ) { up->flags.excl_acc = 1; } } } else { if ( up->flags.excl_acc ) { up->flags.excl_acc = 0; } else { up->flags.excl_acc = 1; } } up->flags.mscp_wait = 0; return( new_event );}/**//* * * Name: mscp_recovinit - Initiate restoration of unit states. * * Abstract: * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_longmscp_recovinit( event, rp ) u_long event; register REQB *rp;{ register CONNB *cp = rp->connb; register UNITB *up; register u_long new_event = EV_NULL; /* Find the first unit that was online when the connection dropped. */ for( up = cp->unit.flink; up != ( UNITB * )&cp->unit.flink && !up->flags.online; up = up->flink ) {} /* If we found a previously online unit, mark it offline with * online in progress, store the unit block pointer in the request * block and allocate a RSPID to use in the online sequence. */ if( up != ( UNITB * )&cp->unit.flink ) { up->flags.online = 0; up->flags.online_ip = 1; rp->unitb = up; new_event = mscp_alloc_rspid( event, rp ); /* No unit was online when the connection dropped; however, there * may have been an online request enqueued, so attempt to restart * the next request in the restart queue. */ } else { mscp_restart_next( cp ); mscp_dealloc_all( rp ); } return( new_event );}/**//* * * Name: mscp_recovnext - Mark current unit online and process next * * Abstract: * * Inputs: rp Request block pointer. * * Outputs: NONE * * * Return NONE. * Values: */u_long
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -