📄 mscp_tape.c
字号:
{ TAPE_DATAGRAM, tmscp_invevent }, /* */ { TAPE_DATAGRAM, tmscp_invevent }, /* */ { TAPE_DATAGRAM, tmscp_invevent }, /* */ { TAPE_DATAGRAM, tmscp_invevent }, /* */ { TAPE_DATAGRAM, tmscp_invevent }, /* */ { TAPE_DATAGRAM, tmscp_invevent }, /* */ { TAPE_DATAGRAM, tmscp_invevent }, /* */ { TAPE_DATAGRAM, tmscp_invevent }, /* */ { TAPE_DATAGRAM, tmscp_invevent }, /* */};/* Write tape mark command states. */STATE tmscp_wtm_states[] = { /* Wriet tape mark initial state. */ { ST_WTM_INITIAL, tmscp_invevent }, /* EV_NULL */ { ST_WTM_INITIAL, mscp_alloc_rspid }, /* EV_INITIAL */ { ST_WTM_INITIAL, mscp_alloc_msg }, /* EV_RSPID */ { ST_WTM_INITIAL, tmscp_writetmcm }, /* EV_MSGBUF */ { ST_WTM_INITIAL, tmscp_invevent }, /* EV_MAPPING */ { ST_WTM_INITIAL, tmscp_writetmem }, /* EV_ENDMSG */ { ST_WTM_INITIAL, tmscp_invevent}, /* EV_TIMEOUT */ { ST_WTM_INITIAL, tmscp_invevent }, /* */ { ST_WTM_INITIAL, tmscp_invevent }, /* */ { ST_WTM_INITIAL, tmscp_invevent }, /* */ { ST_WTM_INITIAL, tmscp_invevent }, /* */ { ST_WTM_INITIAL, tmscp_invevent }, /* */ { ST_WTM_INITIAL, tmscp_invevent }, /* */ { ST_WTM_INITIAL, tmscp_invevent }, /* */ { ST_WTM_INITIAL, tmscp_invevent }, /* */ { ST_WTM_INITIAL, tmscp_invevent }, /* */};/* Reposition tape command states. * Repositions files (tape marks), tape objects, nowhere. */STATE tmscp_rpo_states[] = { /* Reposition tape initial state. */ { ST_RPO_INITIAL, tmscp_invevent }, /* EV_NULL */ { ST_RPO_INITIAL, mscp_alloc_rspid }, /* EV_INITIAL */ { ST_RPO_INITIAL, mscp_alloc_msg }, /* EV_RSPID */ { ST_RPO_INITIAL, tmscp_reposcm }, /* EV_MSGBUF */ { ST_RPO_INITIAL, tmscp_invevent }, /* EV_MAPPING */ { ST_RPO_INITIAL, tmscp_reposem }, /* EV_ENDMSG */ { ST_RPO_INITIAL, tmscp_invevent}, /* EV_TIMEOUT */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */};/* Reposition tape records command states. * Reposition tape records only. */STATE tmscp_rec_states[] = { /* Reposition tape initial state. */ { ST_RPO_INITIAL, tmscp_invevent }, /* EV_NULL */ { ST_RPO_INITIAL, mscp_alloc_rspid }, /* EV_INITIAL */ { ST_RPO_INITIAL, mscp_alloc_msg }, /* EV_RSPID */ { ST_RPO_INITIAL, tmscp_repreccm }, /* EV_MSGBUF */ { ST_RPO_INITIAL, tmscp_invevent }, /* EV_MAPPING */ { ST_RPO_INITIAL, tmscp_reposem }, /* EV_ENDMSG */ { ST_RPO_INITIAL, tmscp_invevent}, /* EV_TIMEOUT */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */ { ST_RPO_INITIAL, tmscp_invevent }, /* */};/* Get unit status command states. */STATE tmscp_gtu_states[] = { /* Reposition tape initial state. */ { ST_GTU_INITIAL, tmscp_invevent }, /* EV_NULL */ { ST_GTU_INITIAL, mscp_alloc_rspid }, /* EV_INITIAL */ { ST_GTU_INITIAL, mscp_alloc_msg }, /* EV_RSPID */ { ST_GTU_INITIAL, tmscp_gtuntcm }, /* EV_MSGBUF */ { ST_GTU_INITIAL, tmscp_invevent }, /* EV_MAPPING */ { ST_GTU_INITIAL, tmscp_gtuntem }, /* EV_ENDMSG */ { ST_GTU_INITIAL, tmscp_invevent }, /* EV_TIMEOUT */ { ST_GTU_INITIAL, tmscp_invevent }, /* */ { ST_GTU_INITIAL, tmscp_invevent }, /* */ { ST_GTU_INITIAL, tmscp_invevent }, /* */ { ST_GTU_INITIAL, tmscp_invevent }, /* */ { ST_GTU_INITIAL, tmscp_invevent }, /* */ { ST_GTU_INITIAL, tmscp_invevent }, /* */ { ST_GTU_INITIAL, tmscp_invevent }, /* */ { ST_GTU_INITIAL, tmscp_invevent }, /* */ { ST_GTU_INITIAL, tmscp_invevent }, /* */};/* Set unit characteristics command states. */STATE tmscp_stu_states[] = { /* Set characteristics initial state. */ { ST_STU_INITIAL, tmscp_invevent }, /* EV_NULL */ { ST_STU_INITIAL, mscp_alloc_rspid }, /* EV_INITIAL */ { ST_STU_INITIAL, mscp_alloc_msg }, /* EV_RSPID */ { ST_STU_INITIAL, tmscp_setunitcm }, /* EV_MSGBUF */ { ST_STU_INITIAL, tmscp_invevent }, /* EV_MAPPING */ { ST_STU_INITIAL, tmscp_setunitem }, /* EV_ENDMSG */ { ST_STU_INITIAL, tmscp_invevent }, /* EV_TIMEOUT */ { ST_STU_INITIAL, tmscp_invevent }, /* */ { ST_STU_INITIAL, tmscp_invevent }, /* */ { ST_STU_INITIAL, tmscp_invevent }, /* */ { ST_STU_INITIAL, tmscp_invevent }, /* */ { ST_STU_INITIAL, tmscp_invevent }, /* */ { ST_STU_INITIAL, tmscp_invevent }, /* */ { ST_STU_INITIAL, tmscp_invevent }, /* */ { ST_STU_INITIAL, tmscp_invevent }, /* */ { ST_STU_INITIAL, tmscp_invevent }, /* */};/* Erase tape states. */STATE tmscp_era_states[] = { /* Erase tape initial state. */ { ST_ERA_INITIAL, tmscp_invevent }, /* EV_NULL */ { ST_ERA_INITIAL, mscp_alloc_rspid }, /* EV_INITIAL */ { ST_ERA_INITIAL, mscp_alloc_msg }, /* EV_RSPID */ { ST_ERA_INITIAL, tmscp_erasecm }, /* EV_MSGBUF */ { ST_ERA_INITIAL, tmscp_invevent }, /* EV_MAPPING */ { ST_ERA_INITIAL, tmscp_eraseem }, /* EV_ENDMSG */ { ST_ERA_INITIAL, tmscp_invevent}, /* EV_TIMEOUT */ { ST_ERA_INITIAL, tmscp_invevent }, /* */ { ST_ERA_INITIAL, tmscp_invevent }, /* */ { ST_ERA_INITIAL, tmscp_invevent }, /* */ { ST_ERA_INITIAL, tmscp_invevent }, /* */ { ST_ERA_INITIAL, tmscp_invevent }, /* */ { ST_ERA_INITIAL, tmscp_invevent }, /* */ { ST_ERA_INITIAL, tmscp_invevent }, /* */ { ST_ERA_INITIAL, tmscp_invevent }, /* */ { ST_ERA_INITIAL, tmscp_invevent }, /* */};/* Data transfer states. */STATE tmscp_xfr_states[] = { /* Unit online initial state. */ { ST_XF_INITIAL, tmscp_invevent }, /* EV_NULL */ { ST_XF_INITIAL, mscp_alloc_rspid }, /* EV_INITIAL */ { ST_XF_INITIAL, mscp_alloc_msg }, /* EV_RSPID */ { ST_XF_INITIAL, mscp_map_buffer }, /* EV_MSGBUF */ { ST_XF_INITIAL, tmscp_transfercm }, /* EV_MAPPING */ { ST_XF_INITIAL, tmscp_transferem }, /* EV_ENDMSG */ { ST_XF_INITIAL, tmscp_invevent }, /* EV_TIMEOUT */ { ST_XF_INITIAL, tmscp_invevent }, /* */ { ST_XF_INITIAL, tmscp_invevent }, /* */ { ST_XF_INITIAL, tmscp_invevent }, /* */ { ST_XF_INITIAL, tmscp_invevent }, /* */ { ST_XF_INITIAL, tmscp_invevent }, /* */ { ST_XF_INITIAL, tmscp_invevent }, /* */ { ST_XF_INITIAL, tmscp_invevent }, /* */ { ST_XF_INITIAL, tmscp_invevent }, /* */ { ST_XF_INITIAL, tmscp_invevent }, /* */};/* Flush controller's write-back cache command state. */STATE tmscp_flu_states[] = { /* flush command initial state. */ { ST_FLU_INITIAL, tmscp_invevent }, /* EV_NULL */ { ST_FLU_INITIAL, mscp_alloc_rspid }, /* EV_INITIAL */ { ST_FLU_INITIAL, mscp_alloc_msg }, /* EV_RSPID */ { ST_FLU_INITIAL, tmscp_flushcm }, /* EV_MSGBUF */ { ST_FLU_INITIAL, tmscp_invevent }, /* EV_MAPPING */ { ST_FLU_INITIAL, tmscp_flushem }, /* EV_ENDMSG */ { ST_FLU_INITIAL, tmscp_invevent}, /* EV_TIMEOUT */ { ST_FLU_INITIAL, tmscp_invevent }, /* */ { ST_FLU_INITIAL, tmscp_invevent }, /* */ { ST_FLU_INITIAL, tmscp_invevent }, /* */ { ST_FLU_INITIAL, tmscp_invevent }, /* */ { ST_FLU_INITIAL, tmscp_invevent }, /* */ { ST_FLU_INITIAL, tmscp_invevent }, /* */ { ST_FLU_INITIAL, tmscp_invevent }, /* */ { ST_FLU_INITIAL, tmscp_invevent }, /* */ { ST_FLU_INITIAL, tmscp_invevent }, /* */};/* * * Name: tmscpopen - Open Tape Unit * * Abstract: * * Inputs: * * Outputs: * * * Return NONE * Values: */int tmscpopen(dev, flag) dev_t dev; int flag;{ UNITB *up; REQB *rp; int retries; Dprint6("tmscpopen\n"); /* If there is no known unit corresponding to the device * number, return an error. */ if(( up = Dev_to_Tunitb( dev )) == NULL ) { Dprint8("open: return ENXIO unknown unit\n"); return( ENXIO ); } up->tms_category_flags &= ~DEV_RWDING; /* If the unit is in use fail as the drive is in use already. */ if(up->Tflags.tms_inuse){ Dprint8("open: return ENXIO unit in use\n"); return(ENXIO); } /* * Mark the unit in use so opens will fail for the next user * that wants the tape drive. */ up->Tflags.tms_inuse = 1; /* Set drive type. */ up->sel = SEL( dev ); /* Do a get unit status insure that the states have not changed. * Clear online so that it's status will be set by the get unit status. */ up->flags.online = 0; up->Tflags.tms_wait = 1; rp = (REQB *) mscp_alloc_reqb( up, NULL, tmscp_gtu_states,(u_long) 0, (u_long) 0 ); retries = RETRY_COUNT; while( up->Tflags.tms_wait && ( --retries >= 0 ) ) { timeout( wakeup, ( caddr_t )rp, hz ); ( void )sleep(( caddr_t )rp, PSWP+1 ); untimeout(wakeup,(caddr_t)rp); /* to be sure*/ } Time_Check(up->Tflags.tms_wait, retries, "gtu in open"); up->Tflags.tms_wait = 0; /* If the unit is already online. This would be the case for a * no-rewind device which is already out on the tape. * Issue a reposition to clear outstanding serious exceptions which * would be set by encountering a tape mark when a previous open to * the no-rewind device has read to the tape mark. This allows for * a transition into the next file. If the device isn't online the * serious exception would be explicitly cleared by the online states. * return success. * * The tmscp_rpo_states clears flags and sets up up->tms_position * to a known value. */ if( up->flags.online ) { Dprint8("OPEN unit already on line\n"); up->Tflags.tms_wait = 1; rp = (REQB *) mscp_alloc_reqb( up, NULL, tmscp_rpo_states, (u_long) MSCP_MD_OBJCT, (u_long) 0 ); retries = RETRY_COUNT; while( up->Tflags.tms_wait && ( --retries >= 0 ) ) { timeout( wakeup, ( caddr_t )rp, hz ); ( void )sleep(( caddr_t )rp, PSWP+1 ); untimeout(wakeup, ( caddr_t )rp, hz ); } Time_Check(up->Tflags.tms_wait, retries, "rpo in open"); up->Tflags.tms_wait = 0; /* There have been cases on the TU81 where an availcm failed * to bring the unit into an available state. As a result the * state is online which would prevent setting of the tape * density which was otherwise done by the onlineinit. * To work around this problem, check to see if we are at BOT. * If so then set the tape density to the value determined by * the previous get unit status. */ if (up->tms_position == 0) { Dprint8("OPEN, online at BOT, set attributes\n"); up->Tflags.tms_wait = 1; rp = (REQB *) mscp_alloc_reqb( up, NULL, tmscp_stu_states, (u_long) 0, (u_long) 0 ); retries = RETRY_COUNT; while( up->Tflags.tms_wait && ( --retries >= 0 ) ) { timeout( wakeup, ( caddr_t )rp, hz ); ( void )sleep(( caddr_t )rp, PSWP+1 ); untimeout(wakeup, ( caddr_t )rp, hz ); } Time_Check(up->Tflags.tms_wait, retries, "stu in open"); up->Tflags.tms_wait = 0; } /* * This is a check to see if the hardware went out from under * us. What could happen is that the initial get unit status * stated that the unit is online (not available). Since that * time the controller has changed its mind and became * available. If this happens then don't return. This will * cause an online sequence to be performed to try to recover. * This failure has been observed on the TU81+ and the TBK70. */ if ( up->tms_status != MSCP_ST_AVLBL) { return( 0 ); } Dprint8("tmscpopen: unit went available.\n"); } /* Zero saved cmd_ref used by ABORT process. */ up->cmd_ref = 0; /* Insure the tape flags are zero * clear_Sflags is used as quick way to zero out all the bitfields. * this introduces a small window (for SMP) where another open could * come in between these two instructions. */ up->clear_Sflags = 0; up->Tflags.tms_inuse = 1; up->tms_flags = 0; /* Start an online sequence */ rp = (REQB *) mscp_alloc_reqb( up,( struct buf * ) NULL, tmscp_onl_states, (u_long) 0, (u_long) 0 ); retries = RETRY_COUNT; while( !up->flags.online && up->flags.online_ip && --retries >= 0 ) { timeout( wakeup, ( caddr_t )rp, hz ); ( void )sleep(( caddr_t )rp, PSWP+1 ); untimeout(wakeup,(caddr_t)rp); /* to be sure*/ } /* * If the end message wasn't received before the time expired then * log this as a driver problem. */ if (!up->flags.online && up->flags.online_ip && (retries < 0)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -