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
ikprobe(reg)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
ikopen(dev)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
ikclose(dev)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
ikread(dev,uio)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
ikwrite(dev,uio)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
ikminphys(bp)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
ikstrategy(bp)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
ikstart(ui)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*/
ikioctl(dev,cmd,data,flag)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*/
ikintr(dev)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
ikreset(uban)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