📄 mscp_tape.c
字号:
* Return * Values: */int tmscpwrite( dev, uio ) dev_t dev; struct uio *uio;{ register UNITB *up; /* If there is no known unit corresponding to the device * number, return an error. */ if(( up = Dev_to_Tunitb( dev )) == NULL ) { Dprint8("write: ENXIO return, unknown unit\n"); return( ENXIO ); } /* Invoke physio to fire off the strategy routine and return * the resulting status. */ return( physio( tmscpstrategy, &up->rawbuf, dev, B_WRITE, minphys, uio ));}/* * * Name: tmscpioctl - Process I/O Control Functions * * Abstract: * * Inputs: * * Outputs: * * * Return NONE * Values: */inttmscpioctl(dev, cmd, data, flag) dev_t dev; int cmd; caddr_t data; int flag;{ register UNITB *up; REQB *rp; struct uba_device *ui; /* ptr to the uba device structure */ CONNB *cp; struct mtop *mtop; /* mag tape cmd op to perform */ struct mtget *mtget; /* mag tape struct to get info in */ struct devget *devget; /* device struct for status info */ int unit; int retries; int s; Dprint6("tmscpioctl\n"); /* If there is no known unit corresponding to the device * number, return an error. */ if(( up = Dev_to_Tunitb( dev )) == NULL ) { Dprint8("ioctl: ENXIO return, unknown unit\n"); return( ENXIO ); } cp = up->connb; unit = up->unit; ui = up->ubdev; /* Set BOM if at position 0 for status ioctl's */ if(up->tms_position == 0) up->tms_flags |= DEV_BOM; else up->tms_flags &= ~DEV_BOM; /* tms_status is used to determine the status of the requested ioctl * except for the case of MTIOCGET. This means we need to init the field * in all cases except MTIOCGET. For MTIOCGET we want to return the status * of the last command issued. */ if (cmd != MTIOCGET) up->tms_status = ~(MSCP_ST_SUCC); switch( cmd ) { case MTIOCTOP: /* tape operation */ Dprint4("MTIOCTOP\n"); mtop = (struct mtop *)data; switch (mtop->mt_op) {/* The ERASE and ABORT ioctls work but at this time there are/* no user level functions which call them/*/* case MTERASE: /* Issue tape erase. It will erase from/* * current tape position to physical/* * end of tape. The rewinds to BOT./* * Would use timeout of RETRY_REPOS_COUNT./* *//* Dprint4("MTERASE\n");/* /* Check to make sure that the unit /* * is online./* *//* if( up->flags.online ) {/* (void) mscp_alloc_reqb( up, NULL, /* tmscp_era_states, (u_long) 0, (u_long) 0 );/* }/* break;/*/*/* case MTABORT: /* Issue abort command. It will abort the/* * last long running tape command issued./* * NOTE: The present abort scheme is /* * insuficient if more than one command is/* * outstanding or if the command intended to be/* * aborted was not the most recent command./* *//* Dprint4("MTABORT\n");/* /* Check to make sure that the unit /* * is online./* *//* if( up->flags.online ) {/*/*/*/* /* Allocate a request block and start the data transfer./* *//* (void) mscp_alloc_reqb( up, NULL, tmscp_abo_states, (u_long) 0, (u_long) 0 );/* }/* break;/* */ case MTWEOF: /* Write two EOF's and reposition back 1 * this has the effect of writing a EOT * but if a new file is put on the tape * (assume no rewind) the second EOF is * over written making it a real EOF and * not an EOT. * * Note: ts.c only writes one tape mark. This * makes behavior different if a reposition is * done after this command. If a close is done * after MTWEOF then there will really be 3 * tape marks on the media. This is a potential * violation of ansi specs. This routine never * looks at the count parameter from the user. */ Dprint4("MTWEOF\n"); /* Write the first tape mark */ up->Tflags.tms_wait = 1; rp = (REQB *) mscp_alloc_reqb( up, NULL, tmscp_wtm_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, "MTWEOF 1"); up->Tflags.tms_wait = 0; /* Check the status for the command that was issued and return fail code * if the status is not success. */ if ( up->tms_status != MSCP_ST_SUCC) return(EIO); /* Write the second tape mark * Initilize command status to prevent masking of error. */ up->Tflags.tms_wait = 1; up->tms_status = ~(MSCP_ST_SUCC); rp = (REQB *) mscp_alloc_reqb( up, NULL, tmscp_wtm_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, "MTWEOF 2"); up->Tflags.tms_wait = 0; /* Check the status for the command that was issued and return fail code * if the status is not success. */ if ( up->tms_status != MSCP_ST_SUCC) return(EIO); up->Tflags.tms_write=0; /* * Success of 2 consecutive wtm's will cause the * controller to flush it's cache. Clear tms_cach_write * to indicate that there are no write records pending * in the controller's write cache. */ up->Tflags.tms_cach_write = 0; /* Now reposition back over the last tape mark * Initilize command status to prevent masking of error. */ up->Tflags.tms_wait = 1; up->tms_status = ~(MSCP_ST_SUCC); rp = (REQB *) mscp_alloc_reqb( up, NULL, tmscp_rpo_states, (u_long) (MSCP_MD_OBJCT | MSCP_MD_REVRS), (u_long) 1 ); 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, "MTWEOF 3"); up->Tflags.tms_wait = 0; /* Check the status for the command that was issued and return fail code * if the status is not success. */ if ( up->tms_status != MSCP_ST_SUCC) return(EIO); else return(0); case MTFSF: /* Reposition command forward EOF count */ Dprint4("MTFSF\n"); /* Check to make sure that the unit * is online. */ if( up->flags.online ) { /* Allocate a request block and start the data transfer. */ up->Tflags.tms_wait = 1; rp = (REQB *) mscp_alloc_reqb( up, NULL, tmscp_rpo_states, (u_long) 0, (u_long) mtop->mt_count ); retries = RETRY_REPOS_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,"MTFSF"); up->Tflags.tms_wait = 0; } /* Check the status for the command that was issued and return fail code * if the status is not success. */ if ( up->tms_status != MSCP_ST_SUCC) return(EIO); else return(0); case MTBSF: /* Reposition command backward EOF count */ Dprint4("MTBSF\n"); /* Check to make sure that the unit * is online. */ if( up->flags.online ) { /* Allocate a request block and start the data transfer. */ up->Tflags.tms_wait = 1; rp = (REQB *) mscp_alloc_reqb( up, NULL, tmscp_rpo_states, (u_long) MSCP_MD_REVRS, (u_long) mtop->mt_count ); retries = RETRY_REPOS_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,"MTBSF"); up->Tflags.tms_wait = 0; } /* Check the status for the command that was issued and return fail code * if the status is not success. */ if ( up->tms_status != MSCP_ST_SUCC) return(EIO); else return(0); case MTFSR: /* Reposition command forward count */ Dprint4("MTFSR\n"); /* Check to make sure that the unit * is online. */ if( up->flags.online ) { /* Allocate a request block and start the data * transfer. * To setup the reposition command to move * RECORDS call the tmscp_rec_states instead * of the tmscp_rpo_states. This is the only * way to tell in the "cm" routine that records * and not tape OBJECTS or tape MARKS are to be * skipped. The previous driver moved tape * objects; not true records. */ up->Tflags.tms_wait = 1; rp = (REQB *) mscp_alloc_reqb( up, NULL, tmscp_rec_states, (u_long) 0, (u_long) mtop->mt_count ); retries = RETRY_REPOS_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,"MTFSR 1"); up->Tflags.tms_wait = 0; } /* Check the status for the command that was issued * and return fail code if the status is not success. * The status would not be success if a tape mark has * been encountered (as an example). Clear the * associated serious exception if it has been raised. * Serious exception will be set if the reposition * record command hit a tape mark. */ if ( up->tms_status != MSCP_ST_SUCC) { if (up->Tflags.tms_clserex) { /* Allocate a request block to * reposition nowhere to clear the * serious exception. */ 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,"MTFSR 2"); up->Tflags.tms_wait = 0; } return(EIO); } else return(0); case MTBSR: /* Reposition command backward count */ Dprint4("MTBSR\n"); /* Check to make sure that the unit * is online. */ if( up->flags.online ) { /* Allocate a request block and start the data * transfer. * To setup the reposition command to move * RECORDS call the tmscp_rec_states instead * of the tmscp_rpo_states. This is the only * way to tell in the "cm" routine that records * and not tape OBJECTS or tape MARKS are to be * skipped. The previous driver moved tape * object
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -