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

📄 lpa.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
/* @(#)lpa.c	4.1	(ULTRIX)	7/2/90	*/#include "lpa.h"#if NLPA > 0 || defined(BINARY)#include "../h/param.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/buf.h"#include "../h/proc.h"#include "../h/ioctl.h"#include "../h/uio.h"#include "../io/uba/ubavar.h"/* * LPA driver for -- Asa Romberger * *	open *	write microcode *	write dedicated mode dispatch table *	ioctl TIOCSETP to set parameters *		struct iocb { *			short *baddr;	buffer address *			short rate;	- 1,000,000 / frequency in Hz *			short wc;	15-13 = number of buffers - 1 *					12-0 = buffer size in words *		} iocb; *	read - 1 character indicating buffer index *		fill or empty buffer * minor device number = DDCCCCCC where: *	DD	= 00 for analog input *		= 01 for analog output *	CCCCCC	= channel number * 18-mar-86  -- jaw     br/cvec changed to NOT use registers. * */ *	define NOMCODE to eliminate the microcode download check *//* #define TRACELPA *//* #define NOMCODE */#ifdef TRACELPA#	define TRACER(x)	printf(x)#	define TRACERN(x, d)	printf(x, d)#else#	define TRACER(x)#	define TRACERN(x, d)#endif	/* PRIORITY AT WHICH PROGRAM SHOULD RUN */	/* THIS SHOULD EVENTUALLY  TELL UNIX THIS IS A REAL-TIME DEVICE */#define NICE	0#define inc(v)		(sc->v = ((sc->v + 1) % sc->sc_nbuf))#define LPAPRI		(PZERO + 0)#define LPAUNIT(dev)	0#define LPADEVICE(dev)	(((dev) >> 6) & 03)#define LPACHANNEL(dev)	((dev) & 077)#ifdef	BINARYextern	struct	uba_device *lpadinfo[];struct lpa_softc {	int	sc_flag;	/* flags, as defined below */	int	sc_device;	/* device: 0 = analog in, 1 = analog out */	int	sc_channel;	/* device channel number */	struct buf sc_ubuffer;	/* user buffer header */	int	sc_ubabuf;	/* uba allocation pointer for buffer */	int	sc_ubufn;	/* present buffer that user is accessing */	int	sc_lbufn;	/* present buffer that lpa is accessing */	int	sc_lbufnx;	/* next buffer for lpa (value in ustat) */	int	sc_nbuf;	/* number of buffers */	int	sc_count;	/* buffer size in words */	short	sc_ustat;	/* user status word */	struct buf sc_ustatbuf;	/* dummy user status word buffer for ubasetup */	int	sc_ubaustat;	/* uba allocation pointer for ustat */	struct buf *sc_buffer;	/* scratch buffer header */	int	sc_start;	/* 0 if lpa operation has been started */} lpa_softc[];extern	int	nNLPA;#elsestruct	uba_device *lpadinfo[NLPA];struct lpa_softc {	int	sc_flag;	/* flags, as defined below */	int	sc_device;	/* device: 0 = analog in, 1 = analog out */	int	sc_channel;	/* device channel number */	struct buf sc_ubuffer;	/* user buffer header */	int	sc_ubabuf;	/* uba allocation pointer for buffer */	int	sc_ubufn;	/* present buffer that user is accessing */	int	sc_lbufn;	/* present buffer that lpa is accessing */	int	sc_lbufnx;	/* next buffer for lpa (value in ustat) */	int	sc_nbuf;	/* number of buffers */	int	sc_count;	/* buffer size in words */	short	sc_ustat;	/* user status word */	struct buf sc_ustatbuf;	/* dummy user status word buffer for ubasetup */	int	sc_ubaustat;	/* uba allocation pointer for ustat */	struct buf *sc_buffer;	/* scratch buffer header */	int	sc_start;	/* 0 if lpa operation has been started */} lpa_softc[NLPA];int	nNLPA = NLPA;#endifint	lpaprobe(), lpaattach(), lpaiintr(), lpaointr();u_short	lpastd[] = {0170460, 0};struct uba_driver lpadriver =  {lpaprobe, 0, lpaattach, 0, lpastd, "lpa", lpadinfo, 0, 0, 0 };/* flags for sc_flag */#define OPEN	01		/* device is open */#define MCODE	02		/* microcode has been loaded */#define DMDT	04		/* dedicated mode dispatch table loaded */#define STTY	010		/* stty call and device initialized */#define SLEEP	020		/* sleeping *//* bits for ustat */#define DONE	0100000		/* done */#define STOP	0040000		/* stop data transfer */#define NBI	0003400		/* next buffer index */#define LBI	0000003		/* last buffer index */struct lpadevice {	short	lcim;		/* control in and maintenance */	short	lcos;		/* control and status out */	short	lrda;		/* request description array address word */	short	lms;		/* maintenance status */};/* control in and maintenance register bits */#define	READYI	0000200		/* ready in */#define IIE	0000100		/* in interrupt enable */#define RDAEXT	0000014		/* rda address extension */#define RDAEXTOFFSET	2	/* offset of RDAEXT from right side */#define GO	0000001		/* go */#define RUN	0100000		/* run */#define RESET	0040000		/* reset */#define CWRITE	0020000		/* cram write */#define EA	0004000		/* enable arbitration */#define ROMO	0002000		/* rom O */#define ROMI	0001000		/* rom I */#define SMICRO	0000400		/* step microprocessor *//* control and status out register bits */#define READYO	0200		/* ready out */#define OIE	0100		/* out interrupt enable */#define UINDEX	0007		/* user index */#define ERROR	0100000		/* error */#define ESTAT	0060000		/* error status */#define ESCODE	0017400		/* error sub code */#define ECODE	0077400		/* error status + error sub code */#define OVERRUN	0243		/* overrun error *//* LPA COMMAND DESCRIPTION AREA *//* INIT COMMAND */#define INIT	0		/* mode */#define MCVERS	4		/* microcode version */#define ACLOCKA	0170404		/* LPA bus addresses */#define ACLOCKB	0170432#define AAD1	0170400#define AAD2	1		/* 0170440 - DOES NOT EXIST */#define ADA	0170420#define ADIO1	1		/* 0167770 - DOES NOT EXIST */#define ADIO2	1		/* 0167760 - DOES NOT EXIST */#define ADIO3	1		/* 0167750 - DOES NOT EXIST */#define ADIO4	1		/* 0167740 - DOES NOT EXIST */#define ADIO5	1		/* 0167730 - DOES NOT EXIST *//* CLOCK START COMMAND */#define CLOCK	1		/* mode */#define CLOCKA	0<<4		/* clock A */	/* clock status word */#define ENACTR	1		/* enable counter */#define R1M	1<<1		/* 1 MHz rate */#define R100K	2<<1		/* 100 KHz rate */#define R10K	3<<1		/* 10 KHz rate */#define R1K	4<<1		/* 1 KHz rate */#define R100	5<<1		/* 100 Hz rate */#define REXT	6<<1		/* external rate (from st1 input) */#define R60	7<<1		/* line frequency rate */#define MFIE	0100		/* mode flag interrupt enable */#define MSI	0<<8		/* single interval mode */#define MRI	1<<8		/* repeat interval mode */#define MEET	2<<8		/* external event time mode */#define MEETZ	3<<8		/* external event time mode from zero base */#define ST1EC	020000		/* st1 enable counter */#define ST1IE	040000		/* st1 interrupt enable *//* DATA TRANSFER START COMMAND */#define DTS	2		/* mode */#define SCHAN	1<<8		/* single channel */lpaprobe(reg)	caddr_t reg;{	register struct lpadevice *lpaaddr = (struct lpadevice *)reg;	/* this should force an interrupt, stall, clear the lpa */	br = 0x15;	cvec = 0330;TRACER("PROBE\n");	return (sizeof (struct lpadevice));}lpaattach(ui)	register struct upa_device *ui;{}lpaopen(dev, flag)	dev_t dev;	int flag;{	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("OPEN\n");	if (unit >= nNLPA || sc->sc_flag & OPEN || ui == 0 ||	    ui->ui_alive == 0)		return (ENXIO);	(void) spl7();	lpaaddr->lcim = RESET;	lpaaddr->lcim = 0;	(void) spl0();	lpaaddr->lcos = 0;	/* clear the registers as a precaution */	lpaaddr->lrda = 0;	lpaaddr->lms = 0;	sc->sc_flag = OPEN;	sc->sc_device = LPADEVICE(dev);	sc->sc_channel = LPACHANNEL(dev);	sc->sc_buffer = geteblk();	sc->sc_buffer->b_error = 0;	sc->sc_buffer->b_proc = u.u_procp;	sc->sc_ubufn = -1;	/* THIS SHOULD EVENTUALLY SPECIFY "REAL-TIME" */	u.u_procp->p_nice = NICE;	return (0);}lpaclose(dev, flag)	dev_t dev;	int flag;{	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;	if (sc->sc_device && sc->sc_ubufn >= 0 && (sc->sc_flag & ERROR) == 0) {		if (sc->sc_start)			lpacmd(sc->sc_buffer, lpaaddr, sc, ui->ui_ubanum);		sc->sc_flag |= STOP;		(void) spl5();		while (sc->sc_flag & STOP) {TRACER("SLEEP\n");			sc->sc_flag |= SLEEP;			sleep((caddr_t)sc, LPAPRI);		}	}	(void) spl7();	lpaaddr->lcim = RESET;	lpaaddr->lcim = 0;	(void) spl0();	if (sc->sc_ubabuf) {		ubarelse(ui->ui_ubanum, &sc->sc_ubabuf);		sc->sc_ubabuf = 0;		(void) spl6();		vsunlock(sc->sc_ubuffer.b_un.b_addr, sc->sc_ubuffer.b_bcount,			(sc->sc_device)? B_READ : B_WRITE);		u.u_procp->p_flag &= ~SPHYSIO;		(void) spl0();	}	if (sc->sc_ubaustat) {		ubarelse(ui->ui_ubanum, &sc->sc_ubaustat);		sc->sc_ubaustat = 0;	}	if (sc->sc_buffer) {		brelse(sc->sc_buffer);		sc->sc_buffer = 0;	}	sc->sc_flag = 0;TRACER("CLOSE\n");}lpawrite(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;	register int f;TRACER("WRITE\n");	f = sc->sc_flag;	if ((f & OPEN) == 0)		return (ENXIO);	if ((f & MCODE) == 0)		/* first write is the microcode */		return (lpamcode(lpaaddr, sc, uio));	if ((f & DMDT) == 0)		/* second write is the dispatch table */		return (lpadmdt(lpaaddr, sc, ui->ui_ubanum, uio));	return (ENXIO);

⌨️ 快捷键说明

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