xref: /original-bsd/sys/vax/uba/ik.c (revision 1364b7d2)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)ik.c	7.3 (Berkeley) 04/25/89
7  */
8 
9 #include "ik.h"
10 #if NIK > 0
11 /*
12  * Ikonas Frame Buffer Interface -- Bill Reeves.
13  */
14 #include "machine/pte.h"
15 
16 #include "param.h"
17 #include "dir.h"
18 #include "user.h"
19 #include "buf.h"
20 #include "systm.h"
21 #include "map.h"
22 #include "uio.h"
23 #include "ioctl.h"
24 
25 #include "ubareg.h"
26 #include "ubavar.h"
27 #include "ikreg.h"
28 
29 #define IKBUSY 01
30 #define IKDMAPRI (PZERO-1)
31 #define IKWAITPRI (PZERO+1)
32 
33 int	ikprobe(), ikattach(), ikintr();
34 struct	uba_device *ikdinfo[NIK];
35 u_short	ikstd[] = { 0772460, 0000000, 0 };
36 struct	uba_driver ikdriver =
37 	{ ikprobe, 0, ikattach, 0, ikstd, "ik", ikdinfo, 0, 0 };
38 
39 struct ik_softc {
40 	char	ik_open;
41 	short	ik_uid;
42 	short	ik_state;
43 	int	ik_ubinfo;
44 	int	ik_count;
45 	struct	buf *ik_bp;
46 	int	ik_bufp;
47 	int	ik_icnt;
48 } ik_softc[NIK];
49 
50 int	ikstrategy();
51 u_int	ikminphys();
52 struct	buf rikbuf[NIK];
53 
54 #define IKUNIT(dev) (minor(dev))
55 
56 ikprobe(reg)
57 	caddr_t reg;
58 {
59 	register int br, cvec;		/* value-result */
60 	register struct ikdevice *ikaddr = (struct ikdevice *) reg;
61 
62 #ifdef lint
63 	br = 0; cvec = br; br = cvec;
64 	ikintr(0);
65 #endif
66 	ikaddr->ik_istat = 0;
67 	ikaddr->ik_xaddr = 0;
68 	ikaddr->ik_yaddr = 0;
69 	ikaddr->ik_ustat = IK_IENABLE | IK_GO;
70 	DELAY(10000);
71 	ikaddr->ik_ustat = 0;
72 	return (sizeof (struct ikdevice));
73 }
74 
75 /*ARGSUSED*/
76 ikattach(ui)
77 	struct uba_device *ui;
78 {
79 
80 }
81 
82 ikopen(dev)
83 	dev_t dev;
84 {
85 	register struct ik_softc *ikp;
86 	register struct uba_device *ui;
87 
88 	if (IKUNIT(dev) >= NIK || (ikp = &ik_softc[minor(dev)])->ik_open ||
89 	    (ui = ikdinfo[IKUNIT(dev)]) == 0 || ui->ui_alive == 0)
90 		return (ENXIO);
91 	ikp->ik_open = 1;
92 	ikp->ik_icnt = 0;
93 	ikp->ik_state = 0;
94 	ikp->ik_uid = u.u_uid;
95 	maptouser(ui->ui_addr);
96 	return (0);
97 }
98 
99 ikclose(dev)
100 	dev_t dev;
101 {
102 
103 	ik_softc[minor(dev)].ik_open = 0;
104 	ik_softc[minor(dev)].ik_state = 0;
105 	unmaptouser(ikdinfo[IKUNIT(dev)]->ui_addr);
106 }
107 
108 ikread(dev, uio)
109 	dev_t dev;
110 	struct uio *uio;
111 {
112 	register int unit = IKUNIT(dev);
113 
114 	if (unit >= NIK)
115 		return (ENXIO);
116 	return (physio(ikstrategy, &rikbuf[unit], dev, B_READ, ikminphys, uio));
117 }
118 
119 ikwrite(dev, uio)
120 	dev_t dev;
121 	struct uio *uio;
122 {
123 	register int unit = IKUNIT(dev);
124 
125 	if (unit >= NIK)
126 		return (ENXIO);
127 	return (physio(ikstrategy, &rikbuf[unit], dev, B_WRITE, ikminphys, uio));
128 }
129 
130 u_int
131 ikminphys(bp)
132 	register struct buf *bp;
133 {
134 
135 	if (bp->b_bcount > 65536)	/* may be able to do twice as much */
136 		bp->b_bcount = 65536;
137 }
138 
139 ikstrategy(bp)
140 	register struct buf *bp;
141 {
142 	register struct ik_softc *ikp = &ik_softc[IKUNIT(bp->b_dev)];
143 	register struct uba_device *ui;
144 
145 	if (IKUNIT(bp->b_dev) >= NIK || (ui = ikdinfo[IKUNIT(bp->b_dev)]) == 0
146 				|| ui->ui_alive == 0)
147 		goto bad;
148 	(void) spl5();
149 	while (ikp->ik_state & IKBUSY)
150 		sleep((caddr_t)ikp, IKDMAPRI+1);
151 	ikp->ik_state |= IKBUSY;
152 	ikp->ik_bp = bp;
153 	ikp->ik_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP);
154 	ikp->ik_bufp = UBAI_ADDR(ikp->ik_ubinfo);
155 	ikp->ik_count = -(bp->b_bcount>>1);	/* its a word count */
156 	ikstart(ui);
157 	while (ikp->ik_state&IKBUSY)
158 		sleep((caddr_t)ikp, IKDMAPRI);
159 	ikp->ik_count = 0;
160 	ikp->ik_bufp = 0;
161 	(void) spl0();
162 	ubarelse(ui->ui_ubanum, &ikp->ik_ubinfo);
163 	ikp->ik_bp = 0;
164 	iodone(bp);
165 	wakeup((caddr_t)ikp);
166 	return;
167 bad:
168 	bp->b_flags |= B_ERROR;
169 	iodone(bp);
170 	return;
171 }
172 
173 ikstart(ui)
174 	register struct uba_device *ui;
175 {
176 	register int istat;
177 	register struct ikdevice *ikaddr = (struct ikdevice *) ui->ui_addr;
178 	register struct ik_softc *ikp = &ik_softc[IKUNIT(ui->ui_unit)];
179 
180 	istat = ikaddr->ik_istat|DMAENABLE;
181 	ikaddr->ik_istat = istat;
182 	ikaddr->ik_wc =  ikp->ik_count;
183 	ikaddr->ik_ubaddr = ikp->ik_bufp;
184 	ikaddr->ik_ustat = IK_GO|IK_IENABLE|((ikp->ik_bufp>>12)&060);
185 }
186 
187 /*ARGSUSED*/
188 ikioctl(dev, cmd, data, flag)
189 	dev_t dev;
190 	int cmd;
191 	register caddr_t data;
192 	int flag;
193 {
194 	register struct uba_device *ui = ikdinfo[IKUNIT(dev)];
195 	register struct ik_softc *ikp;
196 
197 	switch (cmd) {
198 
199 	case IKIOGETADDR:
200 		*(caddr_t *)data = ui->ui_addr;
201 		break;
202 
203 	case IKIOWAITINT:
204 		ikp = &ik_softc[IKUNIT(dev)];
205 		ikp->ik_state |= IKBUSY;
206 		while (ikp->ik_state&IKBUSY)
207 			sleep((caddr_t)ikp, IKWAITPRI);
208 		break;
209 
210 	default:
211 		return (ENOTTY);
212 	}
213 	return (0);
214 }
215 
216 /*ARGSUSED*/
217 ikintr(dev)
218 	dev_t dev;
219 {
220 	register struct ikdevice *ikaddr =
221 			(struct ikdevice *) ikdinfo[IKUNIT(dev)]->ui_addr;
222 	register struct ik_softc *ikp = &ik_softc[IKUNIT(dev)];
223 
224 	ikp->ik_icnt++;
225 	if (ikp->ik_state&IKBUSY) {
226 		ikaddr->ik_ustat = 0;
227 		ikp->ik_state &= ~IKBUSY;
228 		wakeup((caddr_t)ikp);
229 	}
230 }
231 
232 ikreset(uban)
233 	int uban;
234 {
235 	register int i;
236 	register struct uba_device *ui;
237 	register struct ik_softc *ikp = ik_softc;
238 
239 	for (i = 0; i < NIK; i++, ikp++) {
240 		if ((ui = ikdinfo[i]) == 0 || ui->ui_alive == 0 ||
241 		    ui->ui_ubanum != uban || ikp->ik_open == 0)
242 			continue;
243 		printf(" ik%d", i);
244 		if ((ikp->ik_state&IKBUSY) == 0)
245 			continue;
246 		ikp->ik_ubinfo =
247 		    ubasetup(ui->ui_ubanum, ikp->ik_bp, UBA_NEEDBDP);
248 		ikp->ik_count = -(ikp->ik_bp->b_bcount/2);
249 		ikstart(ui);
250 	}
251 }
252 #endif
253