xref: /original-bsd/sys/vax/uba/ik.c (revision 8af5b582)
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.7 (Berkeley) 12/16/90
7  */
8 
9 #include "ik.h"
10 #if NIK > 0
11 /*
12  * Ikonas Frame Buffer Interface -- Bill Reeves.
13  */
14 #include "../include/pte.h"
15 
16 #include "sys/param.h"
17 #include "sys/user.h"
18 #include "sys/buf.h"
19 #include "sys/systm.h"
20 #include "sys/map.h"
21 #include "sys/uio.h"
22 #include "sys/ioctl.h"
23 
24 #include "ubareg.h"
25 #include "ubavar.h"
26 #include "ikreg.h"
27 
28 #define IKBUSY 01
29 #define IKDMAPRI (PZERO-1)
30 #define IKWAITPRI (PZERO+1)
31 
32 int	ikprobe(), ikattach(), ikintr();
33 struct	uba_device *ikdinfo[NIK];
34 u_short	ikstd[] = { 0772460, 0000000, 0 };
35 struct	uba_driver ikdriver =
36 	{ ikprobe, 0, ikattach, 0, ikstd, "ik", ikdinfo, 0, 0 };
37 
38 struct ik_softc {
39 	char	ik_open;
40 	short	ik_uid;
41 	short	ik_state;
42 	int	ik_ubinfo;
43 	int	ik_count;
44 	struct	buf *ik_bp;
45 	int	ik_bufp;
46 	int	ik_icnt;
47 } ik_softc[NIK];
48 
49 int	ikstrategy();
50 u_int	ikminphys();
51 struct	buf rikbuf[NIK];
52 
53 #define IKUNIT(dev) (minor(dev))
54 
55 ikprobe(reg)
56 	caddr_t reg;
57 {
58 	register int br, cvec;		/* value-result */
59 	register struct ikdevice *ikaddr = (struct ikdevice *) reg;
60 
61 #ifdef lint
62 	br = 0; cvec = br; br = cvec;
63 	ikintr(0);
64 #endif
65 	ikaddr->ik_istat = 0;
66 	ikaddr->ik_xaddr = 0;
67 	ikaddr->ik_yaddr = 0;
68 	ikaddr->ik_ustat = IK_IENABLE | IK_GO;
69 	DELAY(10000);
70 	ikaddr->ik_ustat = 0;
71 	return (sizeof (struct ikdevice));
72 }
73 
74 /*ARGSUSED*/
75 ikattach(ui)
76 	struct uba_device *ui;
77 {
78 
79 }
80 
81 ikopen(dev)
82 	dev_t dev;
83 {
84 	register struct ik_softc *ikp;
85 	register struct uba_device *ui;
86 
87 	if (IKUNIT(dev) >= NIK || (ikp = &ik_softc[minor(dev)])->ik_open ||
88 	    (ui = ikdinfo[IKUNIT(dev)]) == 0 || ui->ui_alive == 0)
89 		return (ENXIO);
90 	ikp->ik_open = 1;
91 	ikp->ik_icnt = 0;
92 	ikp->ik_state = 0;
93 	ikp->ik_uid = u.u_uid;
94 	maptouser(ui->ui_addr);
95 	return (0);
96 }
97 
98 ikclose(dev)
99 	dev_t dev;
100 {
101 
102 	ik_softc[minor(dev)].ik_open = 0;
103 	ik_softc[minor(dev)].ik_state = 0;
104 	unmaptouser(ikdinfo[IKUNIT(dev)]->ui_addr);
105 	return (0);
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 		(void) tsleep((caddr_t)ikp, IKDMAPRI+1, devout, 0);
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 		(void) tsleep((caddr_t)ikp, IKDMAPRI, devout, 0);
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 	int error = 0;
197 
198 	switch (cmd) {
199 
200 	case IKIOGETADDR:
201 		*(caddr_t *)data = ui->ui_addr;
202 		break;
203 
204 	case IKIOWAITINT:
205 		ikp = &ik_softc[IKUNIT(dev)];
206 		ikp->ik_state |= IKBUSY;
207 		while (ikp->ik_state&IKBUSY && error == 0)
208 			error = tsleep((caddr_t)ikp, IKWAITPRI | PCATCH,
209 			    devwait, 0);
210 		break;
211 
212 	default:
213 		return (ENOTTY);
214 	}
215 	return (error);
216 }
217 
218 /*ARGSUSED*/
219 ikintr(dev)
220 	dev_t dev;
221 {
222 	register struct ikdevice *ikaddr =
223 			(struct ikdevice *) ikdinfo[IKUNIT(dev)]->ui_addr;
224 	register struct ik_softc *ikp = &ik_softc[IKUNIT(dev)];
225 
226 	ikp->ik_icnt++;
227 	if (ikp->ik_state&IKBUSY) {
228 		ikaddr->ik_ustat = 0;
229 		ikp->ik_state &= ~IKBUSY;
230 		wakeup((caddr_t)ikp);
231 	}
232 }
233 
234 ikreset(uban)
235 	int uban;
236 {
237 	register int i;
238 	register struct uba_device *ui;
239 	register struct ik_softc *ikp = ik_softc;
240 
241 	for (i = 0; i < NIK; i++, ikp++) {
242 		if ((ui = ikdinfo[i]) == 0 || ui->ui_alive == 0 ||
243 		    ui->ui_ubanum != uban || ikp->ik_open == 0)
244 			continue;
245 		printf(" ik%d", i);
246 		if ((ikp->ik_state&IKBUSY) == 0)
247 			continue;
248 		ikp->ik_ubinfo =
249 		    ubasetup(ui->ui_ubanum, ikp->ik_bp, UBA_NEEDBDP);
250 		ikp->ik_count = -(ikp->ik_bp->b_bcount/2);
251 		ikstart(ui);
252 	}
253 }
254 #endif
255