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

📄 rx.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
		while ((rxaddr->rxcs&RX_TREQ) == 0)			;		rxaddr->rxdb = (u_short) bp->b_bcount >> 1;	}	while ((rxaddr->rxcs&RX_TREQ) == 0)		;	rxaddr->rxdb = (u_short) ubinfo;}rxintr(ctlr)	int ctlr;{	int unit, sector, track;	struct uba_ctlr *um = rxminfo[ctlr];	register struct rxdevice *rxaddr;	register struct buf *bp, *dp;	register struct rx_softc *sc;	struct uba_device *ui;	struct rxerr *er;	struct rx_ctlr *rxc;	if (!um->um_tab.b_active)		return;	dp = um->um_tab.b_actf;	if (!dp->b_active)		return;	bp = dp->b_actf;	unit = RXUNIT(bp->b_dev);	sc = &rx_softc[unit];	ui = rxdinfo[unit];	rxaddr = (struct rxdevice *)um->um_addr;	rxc = &rx_ctlr[um->um_ctlr];	rxc->rxc_tocnt = 0;	er = &rxerr[unit];#ifdef RXDEBUG	printf("rxint: dev=%x, st=%d, cs=0x%x, db=0x%x\n", 		bp->b_dev, rxc->rxc_state, rxaddr->rxcs, rxaddr->rxdb);#endif	if ((rxaddr->rxcs & RX_ERR) &&	    (rxc->rxc_state != RXS_RDSTAT) && (rxc->rxc_state != RXS_RDERR))		goto error;	switch (rxc->rxc_state) {	/*	 * Incomplete commands.  Perform next step	 * and return.  Note that b_active is set on	 * entrance and, therefore, also on exit.	 */	case RXS_READ:		if (rxaddr->rxdb & RXES_DDMARK)			sc->sc_flags |= RXF_DDMK;		else			sc->sc_flags &= ~RXF_DDMK;		rxc->rxc_state = RXS_EMPTY;		um->um_cmd = RX_EMPTY;		(void) ubago(ui);		return;	case RXS_FILL:		rxc->rxc_state = RXS_WRITE;		if (sc->sc_flags & RXF_USEWDDS) {			rxaddr->rxcs = RX_WDDS | sc->sc_csbits;			sc->sc_flags &= ~RXF_USEWDDS;		} else			rxaddr->rxcs = RX_WRITE | sc->sc_csbits;		rxmap(bp, &sector, &track);		while ((rxaddr->rxcs&RX_TREQ) == 0)			;		rxaddr->rxdb = sector;		while ((rxaddr->rxcs&RX_TREQ) == 0)			;		rxaddr->rxdb = track;		return;	/*	 * Possibly completed command.	 */	case RXS_RDSTAT:		if (bp->b_flags & B_RDSTAT) {			if ((rxaddr->rxdb&RXES_READY) == 0) {				bp->b_flags |= B_ERROR;				bp->b_error = ENODEV;			} else {				sc->sc_csbits |= rxaddr->rxdb&RXES_DBLDEN ?					RX_DDEN : RX_SDEN;			}			goto rdone;		}		if (rxaddr->rxdb&RXES_READY)			goto rderr;		bp->b_error = ENODEV;		bp->b_flags |= B_ERROR;		goto done;	/*	 * Command completed.	 */	case RXS_EMPTY:	case RXS_WRITE:			goto done;	case RXS_FORMAT:		goto rdone;	case RXS_RDERR:		bp = savebp;		rxmap(bp, &sector, &track);		printf("rx%d: hard error, trk %d psec %d ",			unit, track, sector);		printf("cs=%b, db=%b, err=", MASKREG(er->rxcs), 			RXCS_BITS, MASKREG(er->rxdb), RXES_BITS);		printf("%x, %x, %x, %x\n", MASKREG(er->rxxt[0]),			MASKREG(er->rxxt[1]), MASKREG(er->rxxt[2]), 			MASKREG(er->rxxt[3]));		goto done;	default:		printf("rx%d: state %d (reset)\n", unit, rxc->rxc_state);		rxreset(um->um_ubanum);		return;	}error:	/*	 * In case of an error:	 *  (a) Give up now if a format (ioctl) was in progress, if a	 *	  density error was detected, or if the drive went offline	 *  (b) Retry up to nine times if a CRC (data) error was detected,	 *	  then give up if the error persists.	 *  (c) In all other cases, reinitialize the drive and try the	 *	  operation once more before giving up.	 */	if (rxc->rxc_state == RXS_FORMAT || (rxaddr->rxdb&RXES_DENERR))		goto giveup;	if (rxaddr->rxdb & RXES_CRCERR) {		if (++um->um_tab.b_errcnt >= 10)			goto giveup;		goto retry;	}	um->um_tab.b_errcnt += 9;	if (um->um_tab.b_errcnt >= 10)		goto giveup;	rxaddr->rxcs = RX_INIT;	/* no way to get an interrupt for "init done", so just wait */	while ((rxaddr->rxcs&RX_DONE) == 0)		;	/* if someone opened the drive: give up */	if ((rxaddr->rxdb&RXES_READY) == 0)		goto giveup;retry:	/*	 * In case we already have UNIBUS resources, give	 * them back since we reallocate things in rxstart.	 */	if (um->um_ubinfo)		ubadone(um);	um->um_tab.b_active = 0;	rxstart(um);	return;giveup:	/*	 * Hard I/O error --	 * ALL errors are considered fatal and will abort the	 * transfer and purge the i/o request queue	 */	sc->sc_flags |= RXF_BAD;	sc->sc_resid = 0;	/* make sure the transfer is terminated */	rxc->rxc_state = RXS_RDSTAT;	rxaddr->rxcs = RX_RDSTAT | sc->sc_csbits;	return;rderr:	/*	 * A hard error (other than not ready) has occurred.	 * Read the extended error status information.	 * Before doing this, save the current CS and DB register values,	 * because the read error status operation may modify them.	 * Insert buffer with request at the head of the queue.	 */	bp->b_error = EIO;	bp->b_flags |= B_ERROR;	if (um->um_ubinfo)		ubadone(um);	savebp = bp;	er->rxcs = rxaddr->rxcs;	er->rxdb = rxaddr->rxdb;	bp = &erxbuf[unit];	bp->b_un.b_addr = (caddr_t)er->rxxt;	bp->b_bcount = sizeof (er->rxxt);	bp->b_flags &= ~(B_DIRTY|B_UAREA|B_PHYS|B_PAGET);	if (dp->b_actf == NULL)		dp->b_actl = bp;	bp->b_forw = dp->b_actf;	dp->b_actf = bp;	rxc->rxc_state = RXS_RDERR;	um->um_cmd = RX_RDERR;	(void) ubago(ui);	return;done:	ubadone(um);rdone:	um->um_tab.b_active = 0;	um->um_tab.b_errcnt = 0;	if ((sc->sc_resid -= NBPS) > 0) {		bp->b_un.b_addr += NBPS;		rxstart(um);		return;	}	bp->b_un.b_addr = sc->sc_uaddr;	bp->b_resid = 0;	bp->b_bcount = sc->sc_bcnt;	dp->b_actf = bp->av_forw;	iodone(bp);	sc->sc_offset = 0;	rxc->rxc_state = RXS_IDLE;	um->um_tab.b_actf = dp->b_forw;	dp->b_active = 0;	dp->b_errcnt = 0;#ifdef RXDEBUG	printf(".. bp=%x, new=%x\n", bp, dp->b_actf);#endif	/*	 * If this unit has more work to do,	 * start it up right away	 */	if (dp->b_actf)		rxustart(ui);	rxstart(um);}/*ARGSUSED*/rxwatch(){	register struct uba_device *ui;	register struct uba_ctlr *um;	register struct rx_softc *sc;	struct rx_ctlr *rxc;	int i, dopen = 0;	for (i=0; i<nNURX; i++) {		ui = rxdinfo[i];		if (ui == 0 || ui->ui_alive == 0)			continue;		sc = &rx_softc[i];		if ((sc->sc_open == 0) && (rxutab[i].b_active == 0)) {			sc->sc_csbits = 0;			continue;		}		dopen++;		um = ui->ui_mi;		rxc = &rx_ctlr[um->um_ctlr];		if (++rxc->rxc_tocnt >= RX_MAXTIMEOUT) {			rxc->rxc_tocnt = 0;			if (um->um_tab.b_active) {					printf("rx%d: timeout\n", i);/* for debugging */				rxintr(um->um_ctlr);			}		}	}	if (dopen)		timeout(rxwatch, (caddr_t)0, hz);	else		rxwstart = 0;}rxreset(uban)	int uban;{	register struct uba_ctlr *um;	register struct rxdevice *rxaddr;	register int ctlr;	for (ctlr = 0; ctlr < nNFX; ctlr++) {		if ((um = rxminfo[ctlr]) == 0 || um->um_ubanum != uban ||		    um->um_alive == 0)			continue;		if (um->um_ubinfo)			um->um_ubinfo = 0;		rx_ctlr[ctlr].rxc_state = RXS_IDLE;		rxaddr = (struct rxdevice *)um->um_addr;		rxaddr->rxcs = RX_INIT;		while ((rxaddr->rxcs&RX_DONE) == 0)			;		rxstart(um);	}}rxread(dev, uio)	dev_t dev;	struct uio *uio;{	int unit = RXUNIT(dev);	struct rx_softc *sc = &rx_softc[unit];	if (uio->uio_offset + uio->uio_resid > RXSIZE)		return (ENXIO);	if (uio->uio_offset < 0 || (uio->uio_offset & SECMASK) != 0)		return (ENXIO);	sc->sc_offset = uio->uio_offset % DEV_BSIZE;	return (physio(rxstrategy, &rrxbuf[unit], dev, B_READ, minphys, uio));}rxwrite(dev, uio)	dev_t dev;	struct uio *uio;{	int unit = RXUNIT(dev);	struct rx_softc *sc = &rx_softc[unit];	if (uio->uio_offset + uio->uio_resid > RXSIZE)		return (ENXIO);	if (uio->uio_offset < 0 || (uio->uio_offset & SECMASK) != 0)		return (ENXIO);	sc->sc_offset = uio->uio_offset % DEV_BSIZE;	return(physio(rxstrategy, &rrxbuf[unit], dev, B_WRITE, minphys, uio));}/* * Control routine: * processes four kinds of requests: * *	(1) Set density (i.e., format the diskette) according to  *		  that specified data parameter *	(2) Arrange for the next sector to be written with a deleted- *		  data mark. *	(3) Report whether the last sector read had a deleted-data mark *	(4) Report the density of the diskette in the indicated drive *	    (since the density it automatically determined by the driver, *	     this is the only way to let an application program know the *	     density) * * Requests relating to deleted-data marks can be handled right here. * A "set density" (format) request, however, must additionally be  * processed through "rxstart", just like a read or write request. *//*ARGSUSED3*/rxioctl(dev, cmd, data, flag)	dev_t dev;	caddr_t data;{   	int unit = RXUNIT(dev);	struct rx_softc *sc = &rx_softc[unit];	switch (cmd) {	case RXIOC_FORMAT:		if ((flag&FWRITE) == 0)			return (EBADF);		if (sc->sc_open > 1)			return (EBUSY);		if (*(int *)data)			sc->sc_csbits |= RX_DDEN;		else			sc->sc_csbits &= ~RX_DDEN;		return (rxformat(dev));	case RXIOC_WDDS:		sc->sc_flags |= RXF_USEWDDS;		return (0);	case RXIOC_RDDSMK:		*(int *)data = sc->sc_flags & RXF_DDMK;		return (0);	case RXIOC_GDENS:		*(int *)data = sc->sc_csbits & RX_DDEN;		return (0);	}	return (ENXIO);}/* * Initiate a format command. */rxformat(dev)	dev_t dev;{	int unit = RXUNIT(dev);	struct buf *bp;	struct rx_softc *sc = &rx_softc[unit];	int s, error = 0;	bp = &rrxbuf[unit];	bp->b_flags = B_BUSY | B_CTRL;	sc->sc_flags = RXF_FORMAT | RXF_LOCK;	bp->b_dev = dev;	bp->b_error = 0;	bp->b_blkno = 0;	rxstrategy(bp);	iowait(bp);	if (bp->b_flags & B_ERROR)		error = bp->b_error;	bp->b_flags &= ~B_BUSY;	sc->sc_flags &= ~RXF_LOCK;	return (error);}/* * A permanent hard error condition has occured, * purge the buffer queue */rxpurge(um)	register struct uba_ctlr *um;{	register struct buf *bp, *dp;	dp = um->um_tab.b_actf;	while (dp->b_actf) {		dp->b_errcnt++;		bp = dp->b_actf;		bp->b_error = EIO;		bp->b_flags |= B_ERROR;		iodone(bp);		dp->b_actf = bp->av_forw;	}}#endif

⌨️ 快捷键说明

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