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

📄 sdc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
	register struct nb1_regs *sdaddr = (struct nb1_regs *)qmem;	register struct buf *bp ,*dp;	register err = 0;	register struct uba_device *ui;	register struct vsdev *vd;	int xunit;	u_char status,udc_cstat,udc_dstat;#ifdef lint	star = star;#endif	vd = &vsdiskdev;	sdc_delay();	status = sdaddr->dkc_stat;	if( ((status & DKC_INTPEND) != DKC_INTPEND) ||	    ((status & DKC_DONE) != DKC_DONE) ) {/* TODO1: debug		mprintf("%s:%s: stray interrupt \n",DEV_ID,SOFT_ERR);*/		sd_stray++;		return;	}		if(!xbnflag) {		if( (bp = sd_st.sd_buf) == NULL) {			mprintf("%s:%s: No valid buffer\n",DEV_ID,SOFT_ERR); 			if(sddebug >=2) cprintf("sdintr:No valid buffer: cmd = %o, dkc_stat = %o\n",sd_st.sd_cmd,status);			return;		}		dp = &sdutab[dkunit(bp)];		xunit = minor(bp->b_dev) & 07;	}	switch(sd_st.sd_cmd) {			    case SD_STEP:	    case SD_DESEL:	    case SD_SELECT:	    case SD_SEEK:	    case SD_RESTOR:	    case SD_FMT:	    case SD_RDTR:		mprintf("%s%d:%s: Command not yet implemented thru interrupt, command = %c\n",DEV_ID,sd_st.sd_drno,SOFT_ERR,sd_st.sd_cmd);		return;		/* break; */	    case SD_RDPHY:	    case SD_RDLOG:	    case SD_WRPHY:	    case SD_WRLOG:		if(!xbnflag) {		    ui = sddinfo[dkunit(bp)];		    if(ui->ui_dk >= 0) 			    dk_busy &= ~(1 << ui->ui_dk);		}		sdaddr->dkc_cmd = (SD_SETREG | UDC_CSTAT);		sdc_delay();		udc_cstat = sdaddr->dkc_reg;  /* read UDC_CSTAT */		sdc_delay();		sdaddr->dkc_cmd = (SD_SETREG | UDC_DSTAT);		sdc_delay();		udc_dstat = sdaddr->dkc_reg;		if( (status & DKC_TERMCOD) != DKC_SUCCESS) {		    if( (sddebug) && (rtr_cnt == 0)) {			cprintf("sdintr: udc_cstat = %o ",udc_cstat);			cprintf("sdintr: drive = %d, block = %d, head = %o,cyln = %o,bleft = %d,bcount = %d\n",sd_st.sd_drno,sd_st.sd_blkno,sd_st.sd_hd,sd_st.sd_cyl.sd_word,sd_st.sd_bleft,sd_st.sd_bcount);			sdaddr->dkc_cmd = (SD_SETREG | UDC_DMA7);			cprintf("sdintr:DMA7 = %o ",sdaddr->dkc_reg); /* DMA7*/			cprintf("sdintr:DMA15 = %o ",sdaddr->dkc_reg); /* DMA15 */			cprintf("sdintr:DMA23 = %o\n",sdaddr->dkc_reg); /* DMA23 */			sd_st.ucb[sd_st.sd_drno].badsect = 0; 			cprintf("sdintr:DSECT = %o ",sdaddr->dkc_reg); /* DSECT */			cprintf("sdintr:CHEAD = %o ",sdaddr->dkc_reg); /* CHEAD */			cprintf("sdintr:CCYL = %o ",sdaddr->dkc_reg); /* CCYL */			sdaddr->dkc_cmd = (SD_SETREG | UDC_DSTAT);			cprintf("sdintr:DSTAT = %o\n",sdaddr->dkc_reg); /* DSTAT */		    } else {			sdc_delay();			sdaddr->dkc_cmd = (SD_SETREG | UDC_DSECT);			sd_st.ucb[sd_st.sd_drno].badsect = 0; 		    }		    if ( (udc_cstat & CST_ECCER)  ||			 (udc_cstat & CST_CMPER) ){			    if(rtr_cnt == 0)sd_st.sd_softcnt[sd_st.sd_drno]++;			    if(!xbnflag)				if(++rtr_cnt < RTRY_CNT){				    if(sd_st.sd_type[sd_st.sd_drno] == DT_RX50)					    sd_st.sd_blkno -= rx50nsect;				    else					    sd_st.sd_blkno -= sd_st.sd_nsect;				    if(!sdstart())					return;				} 			    rtr_cnt = 0;			    if( (sd_st.sd_drno == DRV_NUM2) || xbnflag ) 				 err++;			    else if(sd_retry(0)) 				err++;			    if(err) {				if(ddm_err) {				    printf("%s%d%c: hard error sn %d\n",DEV_ID,sd_st.sd_drno,'a'+xunit,BAD_SECT(sd_st.sd_drno,xunit));				    printf("%s%d: Forced Error Modifier set LBN %d\n",DEV_ID,sd_st.sd_drno,BAD_LBN(sd_st.sd_drno));				    ddm_err = 0;				    sd_st.sd_bleft -= (sd_st.ucb[sd_st.sd_drno].badsect + 1 ) * SD_SIZE;				}				else if(udc_cstat & CST_CMPER)					printf("%s%d:%s: compare error\n",DEV_ID,sd_st.sd_drno,HARD_ERR);				    else printf("%s%d:%s: eccerror\n",DEV_ID,sd_st.sd_drno,HARD_ERR);				    if(sdbbrdbug) {					cprintf("%s%d: block = %d, head = %o, cylinder = %o\n",DEV_ID,sd_st.sd_drno,sd_st.sd_blkno-sd_st.sd_nsect,sd_st.sd_hd,sd_st.sd_cyl.sd_word);					sdaddr->dkc_cmd = (SD_SETREG | UDC_DSECT);					cprintf("sdintr:DSECT = %o ",sdaddr->dkc_reg); /* DSECT */					cprintf("sdintr:CHEAD = %o ",sdaddr->dkc_reg); /* CHEAD */					cprintf("sdintr:CCYL = %o ",sdaddr->dkc_reg); /* CCYL */					cprintf("sdintr:CSTAT = %o ",udc_cstat);					sdaddr->dkc_cmd = (SD_SETREG | UDC_DSTAT);					cprintf("sdintr:DSTAT = %o\n",sdaddr->dkc_reg); /* DSTAT */				    }			    }		    }		    else if ((udc_cstat & CST_SYNER) ) {			if(rtr_cnt == 0)sd_st.sd_softcnt[sd_st.sd_drno]++;			if(!xbnflag)			    if(++rtr_cnt < RTRY_CNT){				if(sd_st.sd_type[sd_st.sd_drno] == DT_RX50) {				    sd_st.sd_blkno -= rx50nsect;				}				else				    sd_st.sd_blkno -= sd_st.sd_nsect;				if(!sdstart())				    return;			    } 			    rtr_cnt = 0;			    printf("%s%d:%s: syncerr\n",DEV_ID,sd_st.sd_drno,HARD_ERR);			    err++;		    }		    else if ( (status & DKC_OVRUN) == DKC_OVRUN) {			printf("%s%d:%s: overrun/underrun\n",DEV_ID,sd_st.sd_drno,HARD_ERR);			err++;			sd_reset();		    }		    else if( (udc_dstat & DST_WRFAULT) == DST_WRFAULT) {			if(rtr_cnt == 0)sd_st.sd_softcnt[sd_st.sd_drno]++;			if(!xbnflag)			    if(++rtr_cnt < RTRY_CNT){				if(!sd_deselect()) {				    DELAY(100);				    /* Select the drive and start all over again */			            if(sd_st.sd_type[sd_st.sd_drno] == DT_RX50)				       sd_st.sd_blkno -= rx50nsect;			            else				       sd_st.sd_blkno -= sd_st.sd_nsect;			            if(!sdstart())				       return;				}			    } 			printf("%s%d:%s: WRITE FAULT\n",DEV_ID,sd_st.sd_drno,HARD_ERR);			rtr_cnt = 0;			err++;		    }		    else if ( (udc_cstat & CST_DELDT) == CST_DELDT) {			DELAY(10);			sd_reset();		        if(rtr_cnt == 0)sd_st.sd_softcnt[sd_st.sd_drno]++;		        if(!xbnflag)			     if(++rtr_cnt < RTRY_CNT){			         if(sd_st.sd_type[sd_st.sd_drno] == DT_RX50)				       sd_st.sd_blkno -= rx50nsect;			         else				       sd_st.sd_blkno -= sd_st.sd_nsect;			         if(!sdstart())				       return;			     } 		        rtr_cnt = 0;		        if( (sd_st.sd_drno == DRV_NUM2) || xbnflag ) 				 err++;		        else if(sd_retry(1)) {			        if(ddm_err) {				        printf("%s%d%c: hard error sn %d\n",DEV_ID,sd_st.sd_drno,'a'+xunit,BAD_SECT(sd_st.sd_drno,xunit));					printf("%s%d: Forced Error Modifier set LBN %d\n",DEV_ID,sd_st.sd_drno,BAD_LBN(sd_st.sd_drno));					ddm_err = 0;					sd_st.sd_bleft -= (sd_st.ucb[sd_st.sd_drno].badsect + 1 ) * SD_SIZE; 			        }			        else 					printf("%s%d:%s:\n",DEV_ID,sd_st.sd_drno,HARD_ERR);				err++;			}		    }		    else if ( (status & DKC_BADSECT) == DKC_BADSECT) {			if( (sd_st.sd_drno == DRV_NUM2) || xbnflag ) {			     printf("%s%d:%s: bad sector\n",DEV_ID,sd_st.sd_drno,HARD_ERR);			     err++;			}			else if(sd_retry(0)) 			    err++;		    }		    else if( (udc_dstat & DST_WRPROT) == DST_WRPROT) {			cprintf("%s%d: WRITE PROTECTED\n",DEV_ID,sd_st.sd_drno);			sd_st.sd_flags[sd_st.sd_drno] |= DEV_WRTLCK;			err++;		    }		    else {			mprintf("%s%d:%s: Unknown error type, UDC_CSTAT = %o, UDC_DSTAT = %o,DKC_STAT = %o\n",DEV_ID,sd_st.sd_drno,SOFT_ERR,udc_cstat,udc_dstat,status);			err++;		    }		}		rtr_cnt = 0;		if(sd_st.sd_drno == DRV_NUM2) {  		     if( (udc_dstat & DST_WRPROT) == DST_WRPROT) {			sd_st.sd_flags[sd_st.sd_drno] |= DEV_WRTLCK;		     }		} 		if(err) {		    if(!xbnflag) {			bp->b_flags |= B_ERROR;			dp->b_actf = bp->av_forw;			bp->b_resid = sd_st.sd_bleft;			iodone(bp);			sd_st.sd_status |= (CNT_DONE | CNT_ERR);			/*sdustart() gets called from vs_bufctl*/			vd->vsd_action = VS_WANTBACK;			if ((cpu == C_VAXSTAR) && cvs_exmode_on)				sdustart();			else			        vs_bufctl(vd);		    }		    sd_st.sd_hardcnt[sd_st.sd_drno]++;		    sd_st.sd_status |= (CNT_DONE | CNT_ERR);		    return;		}		break;	    default:		mprintf("%s%d:%s: wrong command: %o\n",DEV_ID,sd_st.sd_drno,SOFT_ERR,sd_st.sd_cmd);		return;  	}	if(xbnflag) {		sdtransfer(xbnbuf,EMPTY);		sd_st.sd_status &= ~CNT_ERR;		sd_st.sd_status |= CNT_DONE;		return;	}	if(bp->b_flags & B_READ)		if((sd_st.sd_type[sd_st.sd_drno] == DT_RX50) && (rx50nsect > 1) )			rx50transfer(sd_st.sd_addr,EMPTY);		else			sdtransfer(sd_st.sd_addr,EMPTY);	if(sd_st.sd_bleft > sd_st.sd_bcount)		sd_st.sd_bleft -= sd_st.sd_bcount;	else		sd_st.sd_bleft = 0;	sd_st.sd_addr += sd_st.sd_bcount;	if(sd_st.sd_bleft > 0) {		if(!(bp->b_flags & B_READ)) {			/* Diskette drive requires some time to complete tunnel 			 * erasure of data just written */			if(sd_st.sd_type[sd_st.sd_drno] == DT_RX50)				DELAY(700);  			if(sd_st.sd_type[sd_st.sd_drno] == DT_RX33)				DELAY(400); 		}		if(sdstart()) {			/*sdustart() gets called from vs_bufctl*/			vd->vsd_action = VS_WANTBACK;			if ((cpu == C_VAXSTAR) && cvs_exmode_on)				sdustart();			else				vs_bufctl(vd);		}	}	else {		dp->b_actf = bp->av_forw;		bp->b_resid = sd_st.sd_bleft;		iodone(bp);		sd_st.sd_status |= CNT_DONE;		sd_st.sd_status &= ~(CNT_BSY | CNT_ERR);		vd->vsd_action = VS_WANTBACK;		if ((cpu == C_VAXSTAR) && cvs_exmode_on)			sdustart();		else		        vs_bufctl(vd); /*sdustart() gets called from vs_bufctl*/	}	return;}sdwait(){	register count = 0;	while(!(sd_st.sd_status & CNT_DONE ))   /* wait for status change */		if(++count >= LOOP_DELAY)			return(1);	sd_st.sd_status &= ~CNT_DONE;	return(0);}/* This routine transfers the data from/to the controller's buffer to/from the * user buffer ( for RDs and RX33 diskette) */sdtransfer(bpp,op)	char *bpp;	short op;{	register struct nb1_regs *sdaddr = (struct nb1_regs *)qmem;	register short  nbytes;	register char   *buf0, *buf1;	buf0  = bpp;	if (sd_st.sd_bleft >= sd_st.sd_bcount)		nbytes =  sd_st.sd_bcount;	else		nbytes=sd_st.sd_bleft;	if ((cpu == C_VAXSTAR) && cvs_exmode_on)		buf1 = (char *)cvseddbmem;	else		buf1 = (char *)sdaddr->nb_ddb;	if( op == FILL)		 bcopy (buf0, buf1, nbytes);	else		 bcopy (buf1, buf0, nbytes);}/* This routine transfers the data from/to the controller's buffer to/from the * user buffer ( for RX50 diskette) */rx50transfer(bpp,op)	char *bpp;	short op;{	register struct nb1_regs *sdaddr = (struct nb1_regs *)qmem;	register char *buf0, *buf1;	register i,sector;	int last,nbytes;	buf0 = bpp;	if(sd_st.sd_bleft >= sd_st.sd_bcount)		last = sd_st.sd_bcount % SD_SIZE;	else		last = sd_st.sd_bleft % SD_SIZE;	nbytes = SD_SIZE;	for(i=0; i< rx50nsect; i++) {		if( i== (rx50nsect-1)) 			if (last) {				nbytes = last;			}		sector = rx_table[rx50blk % 50];		if ((cpu == C_VAXSTAR) && cvs_exmode_on)		    buf1 = (char *)cvseddbmem + SD_SIZE*(sector - 1);		else		    buf1 = (char *)sdaddr->nb_ddb + SD_SIZE*(sector - 1);		if(op == FILL)			 bcopy (buf0, buf1, nbytes);		else			 bcopy (buf1, buf0, nbytes);		buf0 += nbytes;		rx50blk++;	}	return;}/* This routine reads the XBNs (first 3 blocks) to get all format information */sd_rdfmt(unit)	register int unit;{	register sector,i;	register struct sd_uib *uibptr;	register char *char_ptr, *buf_ptr;	short *data_ptr;	u_char sect,head,cylin,scnt,cmd;	short sd_sum;	sd_st.sd_hd = sd_st.sd_cyl.sd_word  = 0;	head = cylin = 0;	scnt =1;	cmd =  (SD_RDLOG | RD_XFER); 	sd_st.sd_drno = unit;	uibptr = &sd_uib[unit];	for( sector = 0; sector < 3; sector++ ) {		xbnflag = 1;		sect = sector & 0377;		sd_st.sd_cmd = SD_RDLOG;		sd_st.sd_bleft = sd_st.sd_bcount = SD_SIZE;		sd_st.sd_status = 0;		if(sd_rdwr(sect,head,cylin,scnt,cmd,0))			continue;		if(sdwait())			continue;;		xbnflag = 0;		if(sd_st.sd_status & CNT_ERR) {			sd_st.sd_status &= ~CNT_ERR;			cprintf("sd_rdfmt: reading XBN %d failed\n",sector);			continue;		}		for( i = 0; i < 9; i++ )			if( xbnbuf[i] != 0x00 ){				cprintf("sd_rdfmt:bytes 0-8 not zero in xbn %d\n",sector);				goto repeat;			}		if( xbnbuf[9] != 0x36 ) {			cprintf("sd_rdfmt: byte 9 not 0x36 in xbn %d\n",sector);			continue;		}		sd_sum = 0;		data_ptr = (short *)&xbnbuf[0];		for( i = 255; --i >= 0; )			sd_sum += *data_ptr++;		if( *data_ptr == sd_sum ) {			char_ptr = (char *)uibptr;			buf_ptr = &xbnbuf[0];			for(i=0; i<UIBSIZE; i++) {				/* This is done because the filler is only 10 bytes long *				   and the next element is int which should be word *				   aligned */				*char_ptr++ = *buf_ptr++;			}			sd_st.ucb[unit].xbn_un.xbn_short[0] = sd_uib[unit].xbnsize[0];			sd_st.ucb[unit].xbn_un.xbn_short[1] = sd_uib[unit].xbnsize[1];			sd_st.ucb[unit].dbn_un.dbn_short[0] = sd_uib[unit].dbnsize[0];			sd_st.ucb[unit].dbn_un.dbn_short[1] = sd_uib[unit].dbnsize[1];			sd_st.ucb[unit].lbn_un.lbn_short[0] = sd_uib[unit].lbnsize[0];			sd_st.ucb[unit].lbn_un.lbn_short[1] = sd_uib[unit].lbnsize[1];			sd_st.ucb[unit].rbn_un.rbn_short[0] = sd_uib[unit].rbnsize[0];			sd_st.ucb[unit].rbn_un.rbn_short[1] = sd_uib[unit].rbnsize[1];			sd_st.ucb[unit].med_un.med_short[0] = sd_uib[unit].media[0];			sd_st.ucb[unit].med_un.med_short[1] = sd_uib[unit].media[1];			sd_st.ucb[uni

⌨️ 快捷键说明

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