xref: /csrg-svn/sys/vax/uba/ik.c (revision 45804)
134103Sbostic /*
234103Sbostic  * Copyright (c) 1982, 1986 Regents of the University of California.
334103Sbostic  * All rights reserved.  The Berkeley software License Agreement
434103Sbostic  * specifies the terms and conditions for redistribution.
534103Sbostic  *
6*45804Sbostic  *	@(#)ik.c	7.7 (Berkeley) 12/16/90
734103Sbostic  */
834103Sbostic 
934103Sbostic #include "ik.h"
1034103Sbostic #if NIK > 0
1134103Sbostic /*
1234103Sbostic  * Ikonas Frame Buffer Interface -- Bill Reeves.
1334103Sbostic  */
14*45804Sbostic #include "../include/pte.h"
1534103Sbostic 
16*45804Sbostic #include "sys/param.h"
17*45804Sbostic #include "sys/user.h"
18*45804Sbostic #include "sys/buf.h"
19*45804Sbostic #include "sys/systm.h"
20*45804Sbostic #include "sys/map.h"
21*45804Sbostic #include "sys/uio.h"
22*45804Sbostic #include "sys/ioctl.h"
2334103Sbostic 
2434103Sbostic #include "ubareg.h"
2534103Sbostic #include "ubavar.h"
2634103Sbostic #include "ikreg.h"
2734103Sbostic 
2834103Sbostic #define IKBUSY 01
2934103Sbostic #define IKDMAPRI (PZERO-1)
3034103Sbostic #define IKWAITPRI (PZERO+1)
3134103Sbostic 
3234103Sbostic int	ikprobe(), ikattach(), ikintr();
3334103Sbostic struct	uba_device *ikdinfo[NIK];
3434103Sbostic u_short	ikstd[] = { 0772460, 0000000, 0 };
3534103Sbostic struct	uba_driver ikdriver =
3634103Sbostic 	{ ikprobe, 0, ikattach, 0, ikstd, "ik", ikdinfo, 0, 0 };
3734103Sbostic 
3834103Sbostic struct ik_softc {
3934103Sbostic 	char	ik_open;
4034103Sbostic 	short	ik_uid;
4134103Sbostic 	short	ik_state;
4234103Sbostic 	int	ik_ubinfo;
4334103Sbostic 	int	ik_count;
4434103Sbostic 	struct	buf *ik_bp;
4534103Sbostic 	int	ik_bufp;
4634103Sbostic 	int	ik_icnt;
4734103Sbostic } ik_softc[NIK];
4834103Sbostic 
4934103Sbostic int	ikstrategy();
5034103Sbostic u_int	ikminphys();
5134103Sbostic struct	buf rikbuf[NIK];
5234103Sbostic 
5334103Sbostic #define IKUNIT(dev) (minor(dev))
5434103Sbostic 
ikprobe(reg)5534103Sbostic ikprobe(reg)
5634103Sbostic 	caddr_t reg;
5734103Sbostic {
5834103Sbostic 	register int br, cvec;		/* value-result */
5934103Sbostic 	register struct ikdevice *ikaddr = (struct ikdevice *) reg;
6034103Sbostic 
6134103Sbostic #ifdef lint
6234103Sbostic 	br = 0; cvec = br; br = cvec;
6334103Sbostic 	ikintr(0);
6434103Sbostic #endif
6534103Sbostic 	ikaddr->ik_istat = 0;
6634103Sbostic 	ikaddr->ik_xaddr = 0;
6734103Sbostic 	ikaddr->ik_yaddr = 0;
6834103Sbostic 	ikaddr->ik_ustat = IK_IENABLE | IK_GO;
6934103Sbostic 	DELAY(10000);
7034103Sbostic 	ikaddr->ik_ustat = 0;
7134103Sbostic 	return (sizeof (struct ikdevice));
7234103Sbostic }
7334103Sbostic 
7434103Sbostic /*ARGSUSED*/
7534103Sbostic ikattach(ui)
7634103Sbostic 	struct uba_device *ui;
7734103Sbostic {
7834103Sbostic 
7934103Sbostic }
8034103Sbostic 
ikopen(dev)8134103Sbostic ikopen(dev)
8234103Sbostic 	dev_t dev;
8334103Sbostic {
8434103Sbostic 	register struct ik_softc *ikp;
8534103Sbostic 	register struct uba_device *ui;
8634103Sbostic 
8734103Sbostic 	if (IKUNIT(dev) >= NIK || (ikp = &ik_softc[minor(dev)])->ik_open ||
8834103Sbostic 	    (ui = ikdinfo[IKUNIT(dev)]) == 0 || ui->ui_alive == 0)
8934103Sbostic 		return (ENXIO);
9034103Sbostic 	ikp->ik_open = 1;
9134103Sbostic 	ikp->ik_icnt = 0;
9234103Sbostic 	ikp->ik_state = 0;
9334103Sbostic 	ikp->ik_uid = u.u_uid;
9434103Sbostic 	maptouser(ui->ui_addr);
9534103Sbostic 	return (0);
9634103Sbostic }
9734103Sbostic 
ikclose(dev)9834103Sbostic ikclose(dev)
9934103Sbostic 	dev_t dev;
10034103Sbostic {
10134103Sbostic 
10234103Sbostic 	ik_softc[minor(dev)].ik_open = 0;
10334103Sbostic 	ik_softc[minor(dev)].ik_state = 0;
10434103Sbostic 	unmaptouser(ikdinfo[IKUNIT(dev)]->ui_addr);
10540729Skarels 	return (0);
10634103Sbostic }
10734103Sbostic 
ikread(dev,uio)10834103Sbostic ikread(dev, uio)
10934103Sbostic 	dev_t dev;
11034103Sbostic 	struct uio *uio;
11134103Sbostic {
11234103Sbostic 	register int unit = IKUNIT(dev);
11334103Sbostic 
11434103Sbostic 	if (unit >= NIK)
11534103Sbostic 		return (ENXIO);
11634103Sbostic 	return (physio(ikstrategy, &rikbuf[unit], dev, B_READ, ikminphys, uio));
11734103Sbostic }
11834103Sbostic 
ikwrite(dev,uio)11934103Sbostic ikwrite(dev, uio)
12034103Sbostic 	dev_t dev;
12134103Sbostic 	struct uio *uio;
12234103Sbostic {
12334103Sbostic 	register int unit = IKUNIT(dev);
12434103Sbostic 
12534103Sbostic 	if (unit >= NIK)
12634103Sbostic 		return (ENXIO);
12734103Sbostic 	return (physio(ikstrategy, &rikbuf[unit], dev, B_WRITE, ikminphys, uio));
12834103Sbostic }
12934103Sbostic 
13034103Sbostic u_int
ikminphys(bp)13134103Sbostic ikminphys(bp)
13234103Sbostic 	register struct buf *bp;
13334103Sbostic {
13434103Sbostic 
13534103Sbostic 	if (bp->b_bcount > 65536)	/* may be able to do twice as much */
13634103Sbostic 		bp->b_bcount = 65536;
13734103Sbostic }
13834103Sbostic 
ikstrategy(bp)13934103Sbostic ikstrategy(bp)
14034103Sbostic 	register struct buf *bp;
14134103Sbostic {
14234103Sbostic 	register struct ik_softc *ikp = &ik_softc[IKUNIT(bp->b_dev)];
14334103Sbostic 	register struct uba_device *ui;
14434103Sbostic 
14534103Sbostic 	if (IKUNIT(bp->b_dev) >= NIK || (ui = ikdinfo[IKUNIT(bp->b_dev)]) == 0
14634103Sbostic 				|| ui->ui_alive == 0)
14734103Sbostic 		goto bad;
14834103Sbostic 	(void) spl5();
14934103Sbostic 	while (ikp->ik_state & IKBUSY)
15040729Skarels 		(void) tsleep((caddr_t)ikp, IKDMAPRI+1, devout, 0);
15134103Sbostic 	ikp->ik_state |= IKBUSY;
15234103Sbostic 	ikp->ik_bp = bp;
15334103Sbostic 	ikp->ik_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP);
15436035Skarels 	ikp->ik_bufp = UBAI_ADDR(ikp->ik_ubinfo);
15534103Sbostic 	ikp->ik_count = -(bp->b_bcount>>1);	/* its a word count */
15634103Sbostic 	ikstart(ui);
15734103Sbostic 	while (ikp->ik_state&IKBUSY)
15840729Skarels 		(void) tsleep((caddr_t)ikp, IKDMAPRI, devout, 0);
15934103Sbostic 	ikp->ik_count = 0;
16034103Sbostic 	ikp->ik_bufp = 0;
16134103Sbostic 	(void) spl0();
16234103Sbostic 	ubarelse(ui->ui_ubanum, &ikp->ik_ubinfo);
16334103Sbostic 	ikp->ik_bp = 0;
16434103Sbostic 	iodone(bp);
16534103Sbostic 	wakeup((caddr_t)ikp);
16634103Sbostic 	return;
16734103Sbostic bad:
16834103Sbostic 	bp->b_flags |= B_ERROR;
16934103Sbostic 	iodone(bp);
17034103Sbostic 	return;
17134103Sbostic }
17234103Sbostic 
ikstart(ui)17334103Sbostic ikstart(ui)
17434103Sbostic 	register struct uba_device *ui;
17534103Sbostic {
17634103Sbostic 	register int istat;
17734103Sbostic 	register struct ikdevice *ikaddr = (struct ikdevice *) ui->ui_addr;
17834103Sbostic 	register struct ik_softc *ikp = &ik_softc[IKUNIT(ui->ui_unit)];
17934103Sbostic 
18034103Sbostic 	istat = ikaddr->ik_istat|DMAENABLE;
18134103Sbostic 	ikaddr->ik_istat = istat;
18234103Sbostic 	ikaddr->ik_wc =  ikp->ik_count;
18334103Sbostic 	ikaddr->ik_ubaddr = ikp->ik_bufp;
18434103Sbostic 	ikaddr->ik_ustat = IK_GO|IK_IENABLE|((ikp->ik_bufp>>12)&060);
18534103Sbostic }
18634103Sbostic 
18734103Sbostic /*ARGSUSED*/
ikioctl(dev,cmd,data,flag)18834103Sbostic ikioctl(dev, cmd, data, flag)
18934103Sbostic 	dev_t dev;
19034103Sbostic 	int cmd;
19134103Sbostic 	register caddr_t data;
19234103Sbostic 	int flag;
19334103Sbostic {
19434103Sbostic 	register struct uba_device *ui = ikdinfo[IKUNIT(dev)];
19534103Sbostic 	register struct ik_softc *ikp;
19640729Skarels 	int error = 0;
19734103Sbostic 
19834103Sbostic 	switch (cmd) {
19934103Sbostic 
20034103Sbostic 	case IKIOGETADDR:
20134103Sbostic 		*(caddr_t *)data = ui->ui_addr;
20234103Sbostic 		break;
20334103Sbostic 
20434103Sbostic 	case IKIOWAITINT:
20534103Sbostic 		ikp = &ik_softc[IKUNIT(dev)];
20634103Sbostic 		ikp->ik_state |= IKBUSY;
20740729Skarels 		while (ikp->ik_state&IKBUSY && error == 0)
20840729Skarels 			error = tsleep((caddr_t)ikp, IKWAITPRI | PCATCH,
20940729Skarels 			    devwait, 0);
21034103Sbostic 		break;
21134103Sbostic 
21234103Sbostic 	default:
21334103Sbostic 		return (ENOTTY);
21434103Sbostic 	}
21540729Skarels 	return (error);
21634103Sbostic }
21734103Sbostic 
21834103Sbostic /*ARGSUSED*/
ikintr(dev)21934103Sbostic ikintr(dev)
22034103Sbostic 	dev_t dev;
22134103Sbostic {
22234103Sbostic 	register struct ikdevice *ikaddr =
22334103Sbostic 			(struct ikdevice *) ikdinfo[IKUNIT(dev)]->ui_addr;
22434103Sbostic 	register struct ik_softc *ikp = &ik_softc[IKUNIT(dev)];
22534103Sbostic 
22634103Sbostic 	ikp->ik_icnt++;
22734103Sbostic 	if (ikp->ik_state&IKBUSY) {
22834103Sbostic 		ikaddr->ik_ustat = 0;
22934103Sbostic 		ikp->ik_state &= ~IKBUSY;
23034103Sbostic 		wakeup((caddr_t)ikp);
23134103Sbostic 	}
23234103Sbostic }
23334103Sbostic 
ikreset(uban)23434103Sbostic ikreset(uban)
23534103Sbostic 	int uban;
23634103Sbostic {
23734103Sbostic 	register int i;
23834103Sbostic 	register struct uba_device *ui;
23934103Sbostic 	register struct ik_softc *ikp = ik_softc;
24034103Sbostic 
24134103Sbostic 	for (i = 0; i < NIK; i++, ikp++) {
24234103Sbostic 		if ((ui = ikdinfo[i]) == 0 || ui->ui_alive == 0 ||
24334103Sbostic 		    ui->ui_ubanum != uban || ikp->ik_open == 0)
24434103Sbostic 			continue;
24534103Sbostic 		printf(" ik%d", i);
24634103Sbostic 		if ((ikp->ik_state&IKBUSY) == 0)
24734103Sbostic 			continue;
24834103Sbostic 		ikp->ik_ubinfo =
24934103Sbostic 		    ubasetup(ui->ui_ubanum, ikp->ik_bp, UBA_NEEDBDP);
25034103Sbostic 		ikp->ik_count = -(ikp->ik_bp->b_bcount/2);
25134103Sbostic 		ikstart(ui);
25234103Sbostic 	}
25334103Sbostic }
25434103Sbostic #endif
255