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

📄 lpa.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
}lpamcode(lpaaddr, sc, uio)	register struct lpadevice *lpaaddr;	register struct lpa_softc *sc;	struct uio *uio;{	short v, r;	register int mcaddr;	int error;	mcaddr = 0;	while (uio->uio_resid) {		error = uiomove(&v, 2, UIO_WRITE, uio);		if (error)			break;		lpaaddr->lcim = 0;		/* load microcode word */		lpaaddr->lrda = mcaddr;		lpaaddr->lms = v;		lpaaddr->lcim = ROMO;		lpaaddr->lcim |= CWRITE;		lpaaddr->lcim = 0;		/* verify microcode word */		lpaaddr->lrda = mcaddr;		lpaaddr->lcim = ROMO;		if ((r = lpaaddr->lms) != v) {			/* download failure */			printf("LPA MICROCODE FAIL: exp:%o got:%o\n", v, r);			return (ENXIO);		}		mcaddr++;	}	lpaaddr->lcim = RUN | EA;	/* turn it on */	sc->sc_flag |= MCODE;	lpaaddr->lcim |= IIE;	lpaaddr->lcos |= OIE;	return (error);TRACER("MCODE\n");}lpadmdt(lpaaddr, sc, ubanum, uio)	register struct lpadevice *lpaaddr;	register struct lpa_softc *sc;	register short ubanum;	struct uio *uio;{	register short *p;	register int n;	int error;	p = (short *) sc->sc_buffer->b_un.b_addr;		/* INIT */	*p++ = (MCVERS << 8) | INIT;	/* mode */	*p++ = ACLOCKA;		/* LPA bus device addresses */	*p++ = ACLOCKB;	*p++ = AAD1;	*p++ = AAD2;	*p++ = ADA;	*p++ = ADIO1;	*p++ = ADIO2;	*p++ = ADIO3;	*p++ = ADIO4;	*p++ = ADIO5;	n = min(uio->uio_resid, 256);	/* dedicated mode dispatch table */	error = uiomove((char *)p, n, UIO_WRITE, uio);	if (error)		return (error);	n >>= 1;	p += n;	while (n++ < 128)		*p++ = 0;	lpacmd(sc->sc_buffer, lpaaddr, sc, ubanum);	sc->sc_flag |= DMDT;	return (0);TRACER("DMDT\n");}lpaioctl(dev, cmd, data, flag)	dev_t dev;	caddr_t data;{	register int unit = LPAUNIT(dev);	register struct lpa_softc *sc = &lpa_softc[unit];	register struct uba_device *ui = lpadinfo[unit];	register struct lpadevice *lpaaddr = (struct lpadevice *) ui->ui_addr;	register short *p;	register int i;	register int v;	struct iocb {		short *baddr;		short rate;		short wc;	} *iocb;TRACER("IOCTL IN\n");	if (cmd != TIOCSETP || (sc->sc_flag & DMDT) == 0)		return (ENXIO);	iocb = (struct iocb *)data;	p = (short *) sc->sc_buffer->b_un.b_addr;	/* CLOCK START */	*p++ = CLOCK | CLOCKA;			/* mode */	*p++ = ENACTR | R1M | MFIE | MRI;	/* clock status */	*p = iocb->rate;			/* clock preset */	lpacmd(sc->sc_buffer, lpaaddr, sc, ui->ui_ubanum);TRACER("CLOCK STARTED\n");	p = (short *) sc->sc_buffer->b_un.b_addr;	/* DATA TRANSFER START*/	*p++ = (sc->sc_device << 7) | DTS | SCHAN;	/* mode */	sc->sc_count = iocb->wc & 017777;	/* word count per buffer */	*p++ = sc->sc_count;							/* user status word */	sc->sc_ustatbuf.b_un.b_addr = (caddr_t) &sc->sc_ustat;	sc->sc_ustatbuf.b_flags = 0;	sc->sc_ustatbuf.b_bcount = 2;	sc->sc_ustatbuf.b_proc = u.u_procp;	sc->sc_ubaustat = ubasetup(ui->ui_ubanum, &sc->sc_ustatbuf, 0);	v = sc->sc_ubaustat;	*p++ = v;	*p = (v >> 16) & 03;		/* into low portion of word */	sc->sc_nbuf = (iocb->wc >> 13) & 07;	/* number of buffers */	*p++ |= sc->sc_nbuf++ << 8;		/* into high portion of word */					/* buffer addresses */	if (useracc(sc->sc_ubuffer.b_un.b_addr = (caddr_t) iocb->baddr,	    sc->sc_ubuffer.b_bcount = sc->sc_count * sc->sc_nbuf * 2,	    (i = (sc->sc_device)? B_READ : B_WRITE) ) == NULL) {TRACER("USER BUFFER FAULT\n");		return (EFAULT);	}	sc->sc_ubuffer.b_flags = B_PHYS | B_BUSY | i;	sc->sc_ubuffer.b_proc = u.u_procp;	u.u_procp->p_flag |= SPHYSIO;	vslock(sc->sc_ubuffer.b_un.b_addr, sc->sc_ubuffer.b_bcount);	sc->sc_ubabuf = ubasetup(ui->ui_ubanum, &sc->sc_ubuffer, 0);	v = sc->sc_ubabuf;	for (i = 0; i < sc->sc_nbuf; i++) {		*p++ = v;		*p++ = (v >> 16) & 03;		v += sc->sc_count * 2;	}	for ( ; i <= 7; i++) {		*p++ = 0;		*p++ = 0;	}	*p++ = 0; *p++ = 0;		/* random channel list address */	*p++ = 0;			/* delay */	*p++ = sc->sc_channel;		/* start channel, channel inc */	*p++ = 1;			/* number of samples in a sequence */	*p++ = 0;			/* dwell */	*p++ = 0;			/* start word no., event mark word */	*p++ = 0;			/* start word mask */	*p = 0;				/* event mark mask */	sc->sc_ustat = 0;	sc->sc_start = (sc->sc_device)? sc->sc_nbuf+1 : 1;	sc->sc_lbufn = 0;	sc->sc_lbufnx = 0;	sc->sc_flag |= STTY;TRACER("IOCTL OUT\n");	return (0);}lparead(dev, uio)	dev_t dev;	struct uio *uio;{	register int unit = LPAUNIT(dev);	register struct lpa_softc *sc = &lpa_softc[unit];	register struct uba_device *ui = lpadinfo[unit];	register struct lpadevice *lpaaddr = (struct lpadevice *) ui->ui_addr;TRACER("READ\n");	if ((sc->sc_flag & STTY) == 0)		return (ENXIO);	if (sc->sc_flag & ERROR)		return (ENXIO);	if (sc->sc_start)		if (--sc->sc_start == 0) {			lpacmd(sc->sc_buffer, lpaaddr, sc, ui->ui_ubanum);TRACER("START\n");		}	inc(sc_ubufn);	if (sc->sc_start == 0) {		(void) spl5();		while (sc->sc_ubufn == sc->sc_lbufn) {			if (sc->sc_flag & ERROR)				return (ENXIO);TRACER("SLEEP\n");			sc->sc_flag |= SLEEP;			sleep(sc, LPAPRI);		}		(void) spl0();	}TRACERN("READ %d\n", sc->sc_ubufn);	return (uiomove(&sc->sc_ubufn, 1, UIO_READ, uio));}lpacmd(bp, lpaaddr, sc, ubanum)	register struct buf *bp;	register struct lpadevice *lpaaddr;	register struct lpa_softc *sc;	register short ubanum;{	int ubareg;TRACER("CMD\n");	ubareg = ubasetup(ubanum, bp, UBA_NEEDBDP);	lpawait(lpaaddr, sc);	lpaaddr->lrda = ubareg;	lpaaddr->lcim &= ~RDAEXT;	lpaaddr->lcim |= ((ubareg >> (16-RDAEXTOFFSET)) & RDAEXT) | GO;	lpawait(lpaaddr, sc);	ubarelse(ubanum, &ubareg);}lpawait(lpaaddr, sc)	register struct lpadevice *lpaaddr;	register struct lpa_softc *sc;{	(void) spl5();	while ((lpaaddr->lcim & READYI) == 0) {TRACER("SLEEP\n");		sc->sc_flag |= SLEEP;		sleep((caddr_t)sc, LPAPRI);	}	(void) spl0();}lpaiintr(unit)	int unit;{	register struct lpa_softc *sc = &lpa_softc[unit];TRACER("{I");	if (sc->sc_flag & SLEEP) {TRACER("<WAKEUP>");		wakeup((caddr_t)sc);		sc->sc_flag &= ~SLEEP;	}TRACER("}");}lpaointr(unit)	int unit;{	register int c, m;	register struct lpa_softc *sc = &lpa_softc[unit];	register struct uba_device *ui = lpadinfo[unit];	register struct lpadevice *lpaaddr = (struct lpadevice *) ui->ui_addr;	int spx;TRACER("{O");	if (sc->sc_flag & SLEEP) {TRACER("<WAKEUP>");		wakeup(sc);		sc->sc_flag &= ~SLEEP;	}	c = lpaaddr->lcos;	m = lpaaddr->lms;	lpaaddr->lcos &= ~READYO;	if (c & ERROR) {TRACER("<ERROR>");		c = (c >> 8) & 0377;		if ((sc->sc_flag & STOP) == 0 || (c != OVERRUN)) {			printf("LPA ERROR %o %o\n", c, m&0177777);			sc->sc_flag |= ERROR;		}		sc->sc_flag &= ~STOP;TRACER("}\n");		return;	}TRACERN("<LPA %d>", sc->sc_lbufnx);	sc->sc_lbufn = sc->sc_lbufnx;	if (sc->sc_ubufn == sc->sc_lbufnx && c & ECODE) {TRACER("<STOP?>");		if (sc->sc_flag & STOP)			return;		printf("LPA OVERRUN\n");		sc->sc_flag |= ERROR;	}	inc(sc_lbufnx);TRACERN("<USTAT %o>", sc->sc_ustat);	spx = spl7();	sc->sc_ustat &= ~NBI;	sc->sc_ustat |= sc->sc_lbufnx << 8;	sc->sc_ustat &= ~DONE;	(void) splx(spx);TRACERN("<LPAN %d>}", sc->sc_lbufnx);}lpareset(uban)	int uban;{	register struct uba_device *ui;	register struct lpadevice *lpaaddr;	register struct lpa_softc *sc;	register int unit;TRACER("LPA RESET\n");	for (unit = 0; unit < nNLPA; unit++) {		if ((ui = lpadinfo[unit]) == 0 ||		    ui->ui_ubanum != uban || ui->ui_alive == 0)			continue;		printf(" lpa%d", unit);		lpaaddr = (struct lpadevice *)ui->ui_addr;		sc = &lpa_softc[unit];		sc->sc_flag |= ERROR;		(void) spl7();		lpaaddr->lcim = RESET;		lpaaddr->lcim = 0;		(void) spl0();		if (sc->sc_flag & SLEEP) {			wakeup((caddr_t)sc);			sc->sc_flag &= ~SLEEP;		}	}}#endif NLPA

⌨️ 快捷键说明

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