⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
		case ST_RBL:		case ST_TUR:			break;		case ST_WFM:			sc->st_wfm.numoffmks2 = 0; /* max of 65536 file marks */			sc->st_wfm.numoffmks1 = LTOB(count,1);			sc->st_wfm.numoffmks0 = LTOB(count,0);			break;		case ST_P_BSPACEF:			count = -count;		case ST_P_FSPACEF:			cmd = ST_SPACE;			sc->st_space.code = 1;			sc->st_space.count2 = LTOB(count,2);			sc->st_space.count1 = LTOB(count,1);			sc->st_space.count0 = LTOB(count,0);			break;		case ST_P_BSPACER:			count = -count;		case ST_P_FSPACER:			cmd = ST_SPACE;			sc->st_space.code = 0;			sc->st_space.count2 = LTOB(count,2);			sc->st_space.count1 = LTOB(count,1);			sc->st_space.count0 = LTOB(count,0);			break;		case ST_VFY:			sc->st_vfy.fixed = 1;	/* only records */			sc->st_vfy.bytcmp = 0;	/* CRC verify only */			sc->st_vfy.verflen2 = LTOB(count,2);			sc->st_vfy.verflen1 = LTOB(count,1);			sc->st_vfy.verflen0 = LTOB(count,0);			break;		case ST_ERASE:			sc->st_erase.longbit = 0; /* don't erase to end							of tape */			break;		case ST_UNLOAD:			sc->st_load.load = 0;  /* unload only for now */			sc->st_load.reten = 0; /* not used on MAYA    */			break;		case ST_RECDIAG:			sc->st_recdiag.aloclen1 = 0;			sc->st_recdiag.aloclen0 = ST_RECDIAG_LEN;			break;		case ST_SNDDIAG:			return(ST_RET_ERR);			break;		case ST_MODSEL:		case ST_P_CACHE:			cmd = ST_MODSEL;			sc->st_modsel.pll = 0x0e;			sc->st_modsel.bufmode = 1;			sc->st_modsel.rdeclen = 0x08;			sc->st_modsel.vulen = 1;#ifdef STDEBUG			sc->st_modsel.vu7 = st_direct_track_mode;#endif STDEBUG			sc->st_modsel.notimo = 1;			sc->st_modsel.nof = st_max_numof_fills;			break;		case ST_P_NOCACHE:			cmd = ST_MODSEL;			sc->st_modsel.pll = 0x0e;			sc->st_modsel.bufmode = 0;			sc->st_modsel.rdeclen = 0x08;			sc->st_modsel.vulen = 1;			sc->st_modsel.nof = 0;			break;		case ST_TRKSEL:			return(ST_RET_ERR);			break;		case ST_RESUNIT:		case ST_RELUNIT:#ifdef STDEBUG 			printd("st_bldpkt: unimplemented command 0x%x\n", 				cmd);#endif STDEBUG			return (ST_RET_ERR);			break;						default:#ifdef STDEBUG			printd("st_bldpkt: unknown command = 0x%x\n",				cmd);#endif STDEBUG			return (ST_RET_ERR);			break;	}	/* The only unit on the VAXSTAR is logical unit zero.	 * 	 * st_read is used here to get to the fields in the 	 * structure for all commands.	 */	sc->st_read.lun = 0;	sc->st_read.link = 0;	sc->st_read.flag = 0;	sc->st_read.mbz = 0;	sc->st_opcode = cmd;	return(ST_SUCCESS);}/**/st_start(){    register struct nb1_regs *staddr = (struct nb1_regs *)qmem;    register struct nb_regs *stiaddr = (struct nb_regs *)nexus;    register struct buf *bp;    register struct buf *dp;    register struct st_softc *sc;    register struct vsdev *vd;    struct uba_ctlr *um;    struct uba_device *ui;    char *stv;			/* virtual address of st page tables	      */    struct pte *pte, *mpte;	/* used for mapping page table entries	      */    char *bufp;    unsigned v;    int o, npf;    struct proc *rp;    int fuz;			/* return value from a call to fuzzy()	      */    int ret;			/* return value from various routines	      */    int sp_ret;    int i, tmpstflags, tmpresid, tmpstat;    short count;    u_char *byteptr;	    vd = &vstapedev;    um = stdinfo[0]->ui_mi;    dp = &stutab[0];    sc =  &st_softc[0];    bp = dp->b_actf;    /*     * st_start is one big state machine.  The states are kept     * in the st_softc structure.  The state variables that      * are used in this state machine are:     *     *	sc->sc_xstate	used to dispatch to major states     *	sc->sc_xevent	used to dispatch to minor (sub)states     */    for (;;) {	/* forever */#ifdef STDEBUG	printd2("st_start: state = %s, event = %s\n",	    trace_xstate[sc->sc_xstate], trace_event[sc->sc_xevent]);#endif STDEBUG    switch(sc->sc_xstate) {/**/	case ST_NEXT:	    switch(sc->sc_xevent) {		case ST_CONT:		    /*		     * Remove the completed request from the queue,		     * return the buffer, return.  We will be called		     * back from vs_bufctl() when the vaxstar buffer		     * is allocated to us.		     */		    bp = dp->b_actf;		    dp->b_actf = bp->av_forw;		    bp->b_resid = sc->sc_resid;#ifdef STDEBUG		    printd1("resid = %d\n", bp->b_resid);#endif STDEBUG		    sc->sc_flags |= DEV_DONE;		    biodone(bp);		    sc->sc_xevent = ST_BEGIN;		    st_retries = 0;		    /*		     * The comand has ended, reset the timer to zero		     */		    sc->sc_ticks = 0;		    if(dp->b_actf == NULL) {			dp->b_active = 0;#ifdef STDEBUG	ST_TRACK('@');#endif STDEBUG			return(VS_DEALLOC);		    }		    else {#ifdef STDEBUG	ST_TRACK('#');#endif STDEBUG	    		vd->vsd_funcptr = st_start;			return(VS_WANTBACK);		    }		    break;		case ST_BEGIN:		    sc->sc_stflags &= ~ST_MAPPED;		    if ((bp = dp->b_actf) == NULL) {			dp->b_active = 0;#ifdef STDEBUG	ST_TRACK('$');#endif STDEBUG			return(VS_DEALLOC);		    }		    if((sc->sc_flags & DEV_EOM) && !((sc->sc_flags & DEV_CSE) ||			(dis_eot_st[0] & DISEOT))) {			bp->b_resid = bp->b_bcount;			bp->b_error = ENOSPC;			bp->b_flags |= B_ERROR;			sc->sc_xevent = ST_CONT;			break;		    }#ifdef	TM_NO_FIX		    if((sc->sc_category_flags & DEV_TPMARK) &&			(bp->b_flags & B_READ)) {			bp->b_resid = 0;			bp->b_error = EIO;			bp->b_flags |= B_ERROR;			sc->sc_xevent = ST_CONT;			break;		    }#endif	TM_NO_FIX		    if((bp->b_flags&B_READ) && (bp->b_flags&B_RAWASYNC) && 			((sc->sc_category_flags&DEV_TPMARK) ||			(sc->sc_flags&DEV_HARDERR))) {			bp->b_error = EIO;			bp->b_flags |= B_ERROR;			sc->sc_xevent = ST_CONT;			break;		    }		    /* log progress */		    sc->sc_progress = time;		    if (bp == &cstbuf[0]) {			/* 			 * execute control operation with the specified count			 */			if (bp->b_command == ST_REWIND) {			    um->um_tab.b_active = SREW;			    sc->sc_flags &= ~DEV_EOM;			}			else {			    um->um_tab.b_active = SCOM;			}	    	    	sc->sc_xstate = ST_SP_START;			sc->sc_xevent = ST_CONT;	    	    	break;		    }		    /*		     * If it's not a control operation, it must be		     * data.		     */		    sc->sc_xstate = ST_RW_START;		    sc->sc_xevent = ST_CONT;		    break;		default:			;#ifdef STDEBUG		    printd("st_start: ST_NEXT: state = %s, event = %s\n",			trace_xstate[sc->sc_xstate], trace_event[sc->sc_xevent]);#endif STDEBUG	    }	    break;/*  */	case ST_SP_START:	    if (sc->st_opcode != ST_RQSNS) {		sc->sc_flags &= ~DEV_WRITTEN;	    }	    /*	     * The write to b_resid has to follow the	     * read of b_command. This is because both	     * b_command and b_resid are the same field	     * (overloaded).  The write to b_resid destroys	     * the data in b_command.  This is a black	     * hole waiting to be fallen into!	     */	    sc->sc_curcmd = bp->b_command;	    bp->b_resid = 0;	    st_bldpkt(sc, sc->sc_curcmd, bp->b_bcount);	    switch (fuz = st_scsistart()) {		case ST_SUCCESS:		    sc->sc_xstate = ST_NEXT;		    sc->sc_xevent = ST_CONT;		    break;		case ST_RET_ERR:		/* 		 * If this command was issued from stopen, don't		 * do the ST_RQSNS if it fails		 */		if (!(st_from_open)) {		    st_bldpkt(sc, ST_RQSNS, 0);		    if(st_scsistart() == ST_SUCCESS) {#ifdef STDEBUG			if (stdebug > 1) {			    stprintsense();			}#endif STDEBUG			switch (sp_ret = sterror(sc)) {			    case ST_SUCCESS:				sc->sc_xstate = ST_NEXT;				sc->sc_xevent = ST_CONT;				break;			    case ST_RETRY:				sc->sc_xstate = ST_NEXT;				sc->sc_xevent = ST_CONT;				if ((st_retries < 3 ) && (sc->st_opcode != ST_TUR)) {				    sc->sc_xevent = ST_BEGIN;				    st_retries++;				}				else {				    bp->b_flags |= B_ERROR;				    sc->sc_xstate = ST_NEXT;				    sc->sc_xevent = ST_CONT;				}				break;			    case ST_FATAL:		    		if((sc->sc_flags & DEV_EOM) &&				    !((sc->sc_flags & DEV_CSE) ||				    (dis_eot_st[0] & DISEOT))) {				    bp->b_error = ENOSPC;				}				bp->b_flags |= B_ERROR;				sc->sc_xstate = ST_NEXT;				sc->sc_xevent = ST_CONT;				break;			    default:#ifdef STDEBUG				printd("st_start: ST_SP_CONT: unknown sp_ret = 0x%x\n",					sp_ret);#endif STDEBUG				bp->b_flags = B_ERROR;				sc->sc_xstate = ST_NEXT;				sc->sc_xevent = ST_CONT;				break;			}			if((sc->st_opcode == ST_RQSNS) || (sc->st_opcode == ST_SPACE)) {				sc->sc_xevent = ST_CONT;			}			break;		    }		    else {			sc->sc_xstate = ST_NEXT;			sc->sc_xevent = ST_CONT;			break;		    }		}		else {			sc->sc_xstate = ST_NEXT;			sc->sc_xevent = ST_CONT;			break;		}		break;		case ST_IP:		    sc->sc_xstate = ST_SP_CONT;#ifdef STDEBUG	ST_TRACK('%');#endif STDEBUG		    sc->sc_stflags |= ST_RETD_KEEP;		    return(VS_KEEP);		    break;		default:#ifdef STDEBUG		    printd("st_start: ST_SP_START: return value = 0x%x\n", fuz);#endif STDEBUG		    bp->b_flags = B_ERROR;		    sc->sc_xstate = ST_NEXT;		    sc->sc_xevent = ST_CONT;		    break;	    }	    break;		/*  */	case ST_SP_CONT:	    /*	     * If this command is a ST_RQSNS, look at the	     * status bytes and determine what to do next,	     * otherwise process as ususal.	     */	    if (sc->st_opcode != ST_RQSNS) {		if (sc->sc_stflags == ST_NORMAL) {		    sc->sc_xstate = ST_NEXT;		    sc->sc_xevent = ST_CONT;		    break;		}		if (sc->sc_stflags & ST_NEED_SENSE) {		    st_bldpkt(sc, ST_RQSNS, 0);		    if(st_scsistart() == ST_SUCCESS) {#ifdef STDEBUG			if (stdebug > 1) {			    stprintsense();			}#endif STDEBUG			switch (sp_ret = sterror(sc)) {			    case ST_SUCCESS:#ifndef	TM_NO_FIX				if ((sc->sc_category_flags & DEV_TPMARK) &&				    ((sc->sc_curcmd == ST_P_FSPACER) ||				     (sc->sc_curcmd == ST_P_BSPACER)))					bp->b_flags |= B_ERROR;#endif	TM_NO_FIX				sc->sc_xstate = ST_NEXT;				sc->sc_xevent = ST_CONT;				break;			    case ST_RETRY:				sc->sc_xstate = ST_NEXT;				sc->sc_xevent = ST_CONT;				if ((st_retries < 3 ) && (sc->st_opcode != ST_TUR)) {					sc->sc_xevent = ST_BEGIN;					st_retries++;				}				else {				    bp->b_flags |= B_ERROR;				    sc->sc_xstate = ST_NEXT;				    sc->sc_xevent = ST_CONT;				}				break;			    case ST_FATAL:				bp->b_flags |= B_ERROR;				sc->sc_xstate = ST_NEXT;				sc->sc_xevent = ST_CONT;				break;			    default:#ifdef STDEBUG				printd("st_start: ST_SP_CONT: unknown sp_ret = 0x%x\n",					sp_ret);#endif STDEBUG				bp->b_flags = B_ERROR;				sc->sc_xstate = ST_NEXT;				sc->sc_xevent = ST_CONT;				break;			}			if((sc->st_opcode == ST_RQSNS) || (sc->st_opcode == ST_SPACE)) {				sc->sc_xevent = ST_CONT;			}			break;		    }		    else {			sc->sc_xstate = ST_NEXT;			sc->sc_xevent = ST_CONT;			break;		    }		}		else {		    if ((sc->sc_stflags & ST_ENCR_ERR) == ST_ENCR_ERR) {			bp->b_flags |= B_ERROR;		    	sc->sc_xstate = ST_NEXT;		    	sc->sc_xevent = ST_CONT;			break;		    }		    else {			sc->sc_xstate = ST_NEXT;			sc->sc_xevent = ST_CONT;			break;		    }		}	    }#ifdef STDEBUG	    if (stdebug > 1) {		stprintsense();	    }#endif STDEBUG	    sc->sc_xstate = ST_NEXT;	    sc->sc_xevent = ST_CONT;	    break;/**/	case ST_RW_START:	    /*	     * If bytecount is too large, throw out the transfer	     */	    if (bp->b_bcount > 16384) {		mprintf("st0: buffer too large\n");		DEV_UGH(sc->sc_device,0,"buffer too large");		bp->b_flags |= B_ERROR;		sc->sc_xstate = ST_NEXT;		sc->sc_xevent = ST_CONT;		break;	    }	    if (bp->b_flags & B_READ) {		sc->sc_curcmd = ST_READ;		st_bldpkt(sc, sc->sc_curcmd, bp->b_bcount);		sc->sc_xstate = ST_R_STDMA;	    }	    else {		sc->sc_curcmd = ST_WRITE;		st_bldpkt(sc, sc->sc_curcmd, bp->b_bcount);		sc->sc_xstate = ST_W_STDMA;	    }	    break;/**/	case ST_R_COPY:	    /* Copy the data from the 16K buffer to memo

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -