fb.c revision 1.4 1 1.4 simonb /* $NetBSD: fb.c,v 1.4 2000/06/26 04:55:51 simonb Exp $ */
2 1.1 tsubai /*
3 1.1 tsubai * Copyright (c) 1992, 1993
4 1.1 tsubai * The Regents of the University of California. All rights reserved.
5 1.1 tsubai *
6 1.1 tsubai * This code is derived from software contributed to Berkeley by
7 1.1 tsubai * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
8 1.1 tsubai *
9 1.1 tsubai * Redistribution and use in source and binary forms, with or without
10 1.1 tsubai * modification, are permitted provided that the following conditions
11 1.1 tsubai * are met:
12 1.1 tsubai * 1. Redistributions of source code must retain the above copyright
13 1.1 tsubai * notice, this list of conditions and the following disclaimer.
14 1.1 tsubai * 2. Redistributions in binary form must reproduce the above copyright
15 1.1 tsubai * notice, this list of conditions and the following disclaimer in the
16 1.1 tsubai * documentation and/or other materials provided with the distribution.
17 1.1 tsubai * 3. All advertising materials mentioning features or use of this software
18 1.1 tsubai * must display the following acknowledgement:
19 1.1 tsubai * This product includes software developed by the University of
20 1.1 tsubai * California, Berkeley and its contributors.
21 1.1 tsubai * 4. Neither the name of the University nor the names of its contributors
22 1.1 tsubai * may be used to endorse or promote products derived from this software
23 1.1 tsubai * without specific prior written permission.
24 1.1 tsubai *
25 1.1 tsubai * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 1.1 tsubai * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 1.1 tsubai * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 1.1 tsubai * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 1.1 tsubai * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 1.1 tsubai * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 1.1 tsubai * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 1.1 tsubai * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 1.1 tsubai * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 1.1 tsubai * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 1.1 tsubai * SUCH DAMAGE.
36 1.1 tsubai *
37 1.1 tsubai * from: $Hdr: fb.c,v 4.300 91/06/27 20:43:06 root Rel41 $ SONY
38 1.1 tsubai *
39 1.1 tsubai * @(#)fb.c 8.1 (Berkeley) 6/11/93
40 1.1 tsubai */
41 1.1 tsubai
42 1.1 tsubai #include "fb.h"
43 1.1 tsubai #if NFB > 0
44 1.1 tsubai /*
45 1.1 tsubai * Frame buffer driver
46 1.1 tsubai */
47 1.1 tsubai
48 1.1 tsubai #include <sys/param.h>
49 1.1 tsubai #include <sys/types.h>
50 1.1 tsubai #include <sys/device.h>
51 1.1 tsubai #include <sys/systm.h>
52 1.1 tsubai #include <sys/proc.h>
53 1.1 tsubai
54 1.1 tsubai #include <machine/cpu.h>
55 1.1 tsubai #include <machine/autoconf.h>
56 1.1 tsubai #include <machine/framebuf.h>
57 1.1 tsubai
58 1.2 thorpej #include <newsmips/dev/fbreg.h>
59 1.1 tsubai
60 1.1 tsubai #define FB_USED 1
61 1.1 tsubai #define VIDEO_USED 2
62 1.1 tsubai
63 1.1 tsubai struct fb_softc {
64 1.1 tsubai struct device sc_dev;
65 1.1 tsubai int fbs_state;
66 1.1 tsubai int fbs_device;
67 1.1 tsubai lScrType fbs_type;
68 1.1 tsubai int fbs_flag;
69 1.1 tsubai struct fbreg fbreg;
70 1.1 tsubai };
71 1.1 tsubai
72 1.1 tsubai static int fbmatch __P((struct device *, struct cfdata *, void *));
73 1.1 tsubai static void fbattach __P((struct device *, struct device *, void *));
74 1.1 tsubai static void fblock __P((void));
75 1.1 tsubai static void fbunlock __P((int));
76 1.1 tsubai static int fbinit __P((struct fbreg *));
77 1.1 tsubai static void fbreset __P((struct fbreg *));
78 1.1 tsubai
79 1.1 tsubai struct cfattach fb_ca = {
80 1.1 tsubai sizeof(struct fb_softc), fbmatch, fbattach
81 1.1 tsubai };
82 1.1 tsubai
83 1.1 tsubai extern struct cfdriver fb_cd;
84 1.1 tsubai
85 1.1 tsubai static char *devname[] = {
86 1.1 tsubai /* 0*/ "",
87 1.1 tsubai /* 1*/ "NWB-512",
88 1.1 tsubai /* 2*/ "NWB-225",
89 1.1 tsubai /* 3*/ "POP-MONO",
90 1.1 tsubai /* 4*/ "POP-COLOR",
91 1.1 tsubai /* 5*/ "NWB-514",
92 1.1 tsubai /* 6*/ "NWB-251",
93 1.1 tsubai /* 7*/ "LCD-MONO",
94 1.1 tsubai /* 8*/ "LDC-COLOR",
95 1.1 tsubai /* 9*/ "NWB-518",
96 1.1 tsubai /*10*/ "NWB-252",
97 1.1 tsubai /*11*/ "NWB-253",
98 1.1 tsubai /*12*/ "NWB-254",
99 1.1 tsubai /*13*/ "NWB-255",
100 1.1 tsubai /*14*/ "SLB-101",
101 1.1 tsubai /*15*/ "NWB-256",
102 1.1 tsubai /*16*/ "NWB-257",
103 1.1 tsubai };
104 1.1 tsubai
105 1.1 tsubai static int fbstate = 0;
106 1.1 tsubai
107 1.1 tsubai extern int fb253_probe();
108 1.1 tsubai extern void bmcnattach();
109 1.1 tsubai extern int fbstart __P((struct fbreg *, int));
110 1.1 tsubai extern int search_fbdev __P((int, int));
111 1.1 tsubai extern int fbgetscrtype();
112 1.1 tsubai extern int fbsetpalette();
113 1.1 tsubai extern int fbgetpalette();
114 1.1 tsubai extern int fbsetcursor();
115 1.1 tsubai extern int fbnsetcursor();
116 1.1 tsubai extern int fbsetxy();
117 1.1 tsubai
118 1.1 tsubai static int
119 1.1 tsubai fbmatch(parent, cf, aux)
120 1.1 tsubai struct device *parent;
121 1.1 tsubai struct cfdata *cf;
122 1.1 tsubai void *aux;
123 1.1 tsubai {
124 1.1 tsubai struct confargs *ca = aux;
125 1.1 tsubai struct fbreg fbreg;
126 1.1 tsubai struct fbreg *fbp = &fbreg;
127 1.1 tsubai int unit = cf->cf_unit;
128 1.1 tsubai
129 1.1 tsubai if (strcmp(ca->ca_name, "fb"))
130 1.1 tsubai return 0;
131 1.1 tsubai
132 1.1 tsubai fbp->fb_command = FB_CPROBE;
133 1.1 tsubai fbp->fb_device = 0;
134 1.1 tsubai fbp->fb_unit = unit;
135 1.1 tsubai fbp->fb_data = -1;
136 1.1 tsubai fbstart(fbp, 1);
137 1.1 tsubai
138 1.1 tsubai if (fbp->fb_result != FB_ROK)
139 1.1 tsubai return 0;
140 1.1 tsubai
141 1.1 tsubai return 1;
142 1.1 tsubai }
143 1.1 tsubai
144 1.1 tsubai static void
145 1.1 tsubai fbattach(parent, self, aux)
146 1.1 tsubai struct device *parent;
147 1.1 tsubai struct device *self;
148 1.1 tsubai void *aux;
149 1.1 tsubai {
150 1.1 tsubai struct fb_softc *fb = (struct fb_softc *)self;
151 1.1 tsubai struct fbreg *fbp = &fb->fbreg;
152 1.1 tsubai int unit = fb->sc_dev.dv_cfdata->cf_unit;
153 1.1 tsubai extern int tty00_is_console;
154 1.1 tsubai
155 1.1 tsubai fb->fbs_device = unit;
156 1.1 tsubai
157 1.1 tsubai fbp->fb_command = FB_CATTACH;
158 1.1 tsubai fbp->fb_device = fb->fbs_device;
159 1.1 tsubai fbstart(fbp, 1);
160 1.1 tsubai fb->fbs_type = fbp->fb_scrtype;
161 1.1 tsubai
162 1.1 tsubai if (fb->fbs_type.type) {
163 1.1 tsubai fb->fbs_state = 0;
164 1.1 tsubai fb->fbs_flag = 0;
165 1.1 tsubai printf(": %s",
166 1.1 tsubai (fb->fbs_type.type < sizeof(devname)/sizeof(*devname))
167 1.1 tsubai ? devname[(int)fb->fbs_type.type] : "UNKNOWN");
168 1.1 tsubai printf(" (%d x %d %d plane)",
169 1.1 tsubai fb->fbs_type.visiblerect.extent.x,
170 1.1 tsubai fb->fbs_type.visiblerect.extent.y,
171 1.1 tsubai fb->fbs_type.plane);
172 1.1 tsubai }
173 1.1 tsubai
174 1.1 tsubai if (! tty00_is_console) { /* XXX */
175 1.1 tsubai printf(" (console)");
176 1.1 tsubai bmcnattach();
177 1.1 tsubai }
178 1.1 tsubai printf("\n");
179 1.1 tsubai }
180 1.1 tsubai
181 1.1 tsubai int
182 1.1 tsubai fbopen(dev, flags, mode, p)
183 1.1 tsubai dev_t dev;
184 1.1 tsubai int flags, mode;
185 1.1 tsubai struct proc *p;
186 1.1 tsubai {
187 1.1 tsubai register int unit = FBUNIT(dev);
188 1.1 tsubai register struct fb_softc *fb = fb_cd.cd_devs[unit];
189 1.1 tsubai register struct fbreg *fbp = &fb->fbreg;
190 1.1 tsubai
191 1.1 tsubai if (unit >= NFB)
192 1.1 tsubai return ENXIO;
193 1.1 tsubai if (fb->fbs_flag && !FBVIDEO(dev))
194 1.1 tsubai return EBUSY;
195 1.1 tsubai
196 1.1 tsubai if (fb->fbs_state == 0) {
197 1.1 tsubai fbp->fb_device = fb->fbs_device;
198 1.1 tsubai if (fbinit(fbp))
199 1.1 tsubai return EBUSY;
200 1.1 tsubai }
201 1.1 tsubai
202 1.1 tsubai fb->fbs_state |= FBVIDEO(dev) ? VIDEO_USED : FB_USED;
203 1.1 tsubai
204 1.1 tsubai return 0;
205 1.1 tsubai }
206 1.1 tsubai
207 1.1 tsubai int
208 1.1 tsubai fbclose(dev, flags, mode, p)
209 1.1 tsubai dev_t dev;
210 1.1 tsubai int flags, mode;
211 1.1 tsubai struct proc *p;
212 1.1 tsubai {
213 1.1 tsubai register int unit = FBUNIT(dev);
214 1.1 tsubai register struct fb_softc *fb = fb_cd.cd_devs[unit];
215 1.1 tsubai register struct fbreg *fbp = &fb->fbreg;
216 1.1 tsubai
217 1.1 tsubai if (unit >= NFB)
218 1.1 tsubai return ENXIO;
219 1.1 tsubai
220 1.1 tsubai if (fb->fbs_state == 0)
221 1.1 tsubai return 0;
222 1.1 tsubai
223 1.1 tsubai if (!FBVIDEO(dev))
224 1.1 tsubai fb->fbs_flag = 0;
225 1.1 tsubai
226 1.1 tsubai fb->fbs_state &= ~(FBVIDEO(dev) ? VIDEO_USED : FB_USED);
227 1.1 tsubai
228 1.1 tsubai if (fb->fbs_state == 0) {
229 1.1 tsubai fbp->fb_device = fb->fbs_device;
230 1.1 tsubai fbreset(fbp);
231 1.1 tsubai }
232 1.1 tsubai
233 1.1 tsubai return 0;
234 1.1 tsubai }
235 1.1 tsubai
236 1.1 tsubai int
237 1.1 tsubai fbioctl(dev, cmd, data, flags, p)
238 1.1 tsubai dev_t dev;
239 1.1 tsubai u_long cmd;
240 1.1 tsubai caddr_t data;
241 1.1 tsubai int flags;
242 1.1 tsubai struct proc *p;
243 1.1 tsubai {
244 1.1 tsubai register int unit = FBUNIT(dev);
245 1.1 tsubai register struct fb_softc *fb = fb_cd.cd_devs[unit];
246 1.1 tsubai register struct fbreg *fbp = &fb->fbreg;
247 1.1 tsubai register int error = 0;
248 1.1 tsubai
249 1.1 tsubai if (unit >= NFB)
250 1.1 tsubai return ENXIO;
251 1.1 tsubai
252 1.1 tsubai fblock();
253 1.1 tsubai
254 1.1 tsubai fbp->fb_device = fb->fbs_device;
255 1.1 tsubai
256 1.1 tsubai switch (cmd) {
257 1.1 tsubai case FBIOCENABLE:
258 1.1 tsubai fb->fbs_flag = 0;
259 1.1 tsubai break;
260 1.1 tsubai case FBIOCDISABLE:
261 1.1 tsubai fb->fbs_flag = 1;
262 1.1 tsubai break;
263 1.1 tsubai case FBIOCAUTODIM:
264 1.1 tsubai fbp->fb_command = FB_CAUTODIM;
265 1.1 tsubai fbp->fb_data = *((int *)data);
266 1.1 tsubai fbstart(fbp, 0);
267 1.1 tsubai break;
268 1.1 tsubai case FBIOCSETDIM:
269 1.1 tsubai fbp->fb_command = FB_CSETDIM;
270 1.1 tsubai fbp->fb_data = *((int*)data);
271 1.1 tsubai fbstart(fbp, 0);
272 1.1 tsubai break;
273 1.1 tsubai case FBIOCGETDIM:
274 1.1 tsubai fbp->fb_command = FB_CGETDIM;
275 1.1 tsubai fbstart(fbp, 1);
276 1.1 tsubai *((int*)data) = fbp->fb_data;
277 1.1 tsubai break;
278 1.1 tsubai #ifdef notyet
279 1.1 tsubai case FBIOCBITBLT:
280 1.1 tsubai error = fbbitblt(fbp, (sBitblt *)data);
281 1.1 tsubai break;
282 1.1 tsubai case FBIOCNBITBLT:
283 1.1 tsubai error = fbnbitblt(fbp, (lBitblt *)data, UIO_USERSPACE);
284 1.1 tsubai break;
285 1.1 tsubai case FBIOCBATCHBITBLT:
286 1.1 tsubai error = fbbatchbitblt(fbp, (sBatchBitblt*)data, UIO_USERSPACE);
287 1.1 tsubai break;
288 1.1 tsubai case FBIOCNBATCHBITBLT:
289 1.1 tsubai error = fbnbatchbitblt(fbp, (lBatchBitblt*)data, UIO_USERSPACE);
290 1.1 tsubai break;
291 1.1 tsubai case FBIOCTILEBITBLT:
292 1.1 tsubai error = fbtilebitblt(fbp, (sTileBitblt *)data);
293 1.1 tsubai break;
294 1.1 tsubai case FBIOCNTILEBITBLT:
295 1.1 tsubai error = fbntilebitblt(fbp, (lTileBitblt *)data);
296 1.1 tsubai break;
297 1.1 tsubai case FBIOCBITBLT3:
298 1.1 tsubai error = fbbitblt3(fbp, (sBitblt3 *)data);
299 1.1 tsubai break;
300 1.1 tsubai case FBIOCNBITBLT3:
301 1.1 tsubai error = fbnbitblt3(fbp, (lBitblt3 *)data);
302 1.1 tsubai break;
303 1.1 tsubai case FBIOCPOLYLINE:
304 1.1 tsubai error = fbpolyline(fbp, (sPrimLine *)data, 0);
305 1.1 tsubai break;
306 1.1 tsubai case FBIOCNPOLYLINE:
307 1.1 tsubai error = fbnpolyline(fbp, (lPrimLine *)data, 0, UIO_USERSPACE);
308 1.1 tsubai break;
309 1.1 tsubai case FBIOCDJPOLYLINE:
310 1.1 tsubai error = fbpolyline(fbp, (sPrimLine *)data, 1);
311 1.1 tsubai break;
312 1.1 tsubai case FBIOCNDJPOLYLINE:
313 1.1 tsubai error = fbnpolyline(fbp, (lPrimLine *)data, 1, UIO_USERSPACE);
314 1.1 tsubai break;
315 1.1 tsubai case FBIOCPOLYMARKER:
316 1.1 tsubai error = fbpolymarker(fbp, (sPrimMarker *)data);
317 1.1 tsubai break;
318 1.1 tsubai case FBIOCNPOLYMARKER:
319 1.1 tsubai error = fbnpolymarker(fbp, (lPrimMarker *)data, UIO_USERSPACE);
320 1.1 tsubai break;
321 1.1 tsubai case FBIOCRECTANGLE:
322 1.1 tsubai error = fbrectangle(fbp, (sPrimRect *)data);
323 1.1 tsubai break;
324 1.1 tsubai case FBIOCNRECTANGLE:
325 1.1 tsubai error = fbnrectangle(fbp, (lPrimRect *)data);
326 1.1 tsubai break;
327 1.1 tsubai case FBIOCFILLSCAN:
328 1.1 tsubai error = fbfillscan(fbp, (sPrimFill *)data);
329 1.1 tsubai break;
330 1.1 tsubai case FBIOCNFILLSCAN:
331 1.1 tsubai error = fbnfillscan(fbp, (lPrimFill *)data, UIO_USERSPACE);
332 1.1 tsubai break;
333 1.1 tsubai case FBIOCTEXT:
334 1.1 tsubai error = fbtext(fbp, (sPrimText *)data);
335 1.1 tsubai break;
336 1.1 tsubai case FBIOCNTEXT:
337 1.1 tsubai error = fbntext(fbp, (lPrimText *)data);
338 1.1 tsubai break;
339 1.1 tsubai case FBIOCPOLYDOT:
340 1.1 tsubai error = fbpolydot(fbp, (sPrimDot *)data);
341 1.1 tsubai break;
342 1.1 tsubai case FBIOCNPOLYDOT:
343 1.1 tsubai error = fbnpolydot(fbp, (lPrimDot *)data, UIO_USERSPACE);
344 1.1 tsubai break;
345 1.1 tsubai #endif
346 1.1 tsubai
347 1.1 tsubai case FBIOCGETSCRTYPE:
348 1.1 tsubai fbgetscrtype(fbp, (sScrType *)data);
349 1.1 tsubai break;
350 1.1 tsubai case FBIOCNGETSCRTYPE:
351 1.1 tsubai fbp->fb_command = FB_CGETSCRTYPE;
352 1.1 tsubai fbstart(fbp, 1);
353 1.1 tsubai *((lScrType*)data) = fbp->fb_scrtype;
354 1.1 tsubai break;
355 1.1 tsubai case FBIOCSETPALETTE:
356 1.1 tsubai fbsetpalette(fbp, (sPalette *)data);
357 1.1 tsubai break;
358 1.1 tsubai #ifdef notyet
359 1.1 tsubai case FBIOCNSETPALETTE:
360 1.1 tsubai error = fbnsetpalette(fbp, (lPalette *)data);
361 1.1 tsubai break;
362 1.1 tsubai #endif
363 1.1 tsubai case FBIOCGETPALETTE:
364 1.1 tsubai fbgetpalette(fbp, (sPalette *)data);
365 1.1 tsubai break;
366 1.1 tsubai #ifdef notyet
367 1.1 tsubai case FBIOCNGETPALETTE:
368 1.1 tsubai error = fbngetpalette(fbp, (lPalette *)data);
369 1.1 tsubai break;
370 1.1 tsubai #endif
371 1.1 tsubai case FBIOCSETCURSOR:
372 1.1 tsubai fbsetcursor(fbp, (sCursor *)data);
373 1.1 tsubai break;
374 1.1 tsubai case FBIOCNSETCURSOR:
375 1.1 tsubai fbnsetcursor(fbp, (lCursor *)data);
376 1.1 tsubai break;
377 1.1 tsubai case FBIOCNSETCURSOR2:
378 1.1 tsubai fbp->fb_command = FB_CSETCURSOR;
379 1.1 tsubai fbp->fb_cursor = *((lCursor2 *)data);
380 1.1 tsubai fbstart(fbp, 0);
381 1.1 tsubai break;
382 1.1 tsubai case FBIOCUNSETCURSOR:
383 1.1 tsubai fbp->fb_command = FB_CUNSETCURSOR;
384 1.1 tsubai fbstart(fbp, 0);
385 1.1 tsubai break;
386 1.1 tsubai case FBIOCNUNSETCURSOR:
387 1.1 tsubai fbp->fb_command = FB_CUNSETCURSOR;
388 1.1 tsubai fbstart(fbp, 0);
389 1.1 tsubai break;
390 1.1 tsubai case FBIOCSHOWCURSOR:
391 1.1 tsubai fbp->fb_command = FB_CSHOWCURSOR;
392 1.1 tsubai fbstart(fbp, 0);
393 1.1 tsubai break;
394 1.1 tsubai case FBIOCNSHOWCURSOR:
395 1.1 tsubai fbp->fb_command = FB_CSHOWCURSOR;
396 1.1 tsubai fbstart(fbp, 0);
397 1.1 tsubai break;
398 1.1 tsubai case FBIOCHIDECURSOR:
399 1.1 tsubai fbp->fb_command = FB_CHIDECURSOR;
400 1.1 tsubai fbstart(fbp, 0);
401 1.1 tsubai break;
402 1.1 tsubai case FBIOCNHIDECURSOR:
403 1.1 tsubai fbp->fb_command = FB_CHIDECURSOR;
404 1.1 tsubai fbstart(fbp, 0);
405 1.1 tsubai break;
406 1.1 tsubai case FBIOCSETXY:
407 1.1 tsubai fbsetxy(fbp, (sPoint *)data);
408 1.1 tsubai break;
409 1.1 tsubai case FBIOCNSETXY:
410 1.1 tsubai fbp->fb_command = FB_CSETXY;
411 1.1 tsubai fbp->fb_point = *((lPoint *)data);
412 1.1 tsubai fbstart(fbp, 0);
413 1.1 tsubai break;
414 1.1 tsubai case FBIOCNSETPALETTEMODE:
415 1.1 tsubai fbp->fb_command = FB_CSETPMODE;
416 1.1 tsubai fbp->fb_data = *((int*)data);
417 1.1 tsubai fbstart(fbp, 0);
418 1.1 tsubai break;
419 1.1 tsubai case FBIOCNGETPALETTEMODE:
420 1.1 tsubai fbp->fb_command = FB_CGETPMODE;
421 1.1 tsubai fbstart(fbp, 1);
422 1.1 tsubai *((int*)data) = fbp->fb_data;
423 1.1 tsubai break;
424 1.1 tsubai case FBIOCNSETVIDEO:
425 1.1 tsubai fbp->fb_command = FB_CSETVIDEO;
426 1.1 tsubai fbp->fb_videoctl = *((lVideoCtl*)data);
427 1.1 tsubai fbstart(fbp, 0);
428 1.1 tsubai break;
429 1.1 tsubai case FBIOCNGETVIDEO:
430 1.1 tsubai fbp->fb_command = FB_CGETVIDEO;
431 1.1 tsubai fbp->fb_videostatus.request = VIDEO_STATUS;
432 1.1 tsubai fbstart(fbp, 1);
433 1.1 tsubai *((lVideoStatus*)data) = fbp->fb_videostatus;
434 1.1 tsubai error = fbp->fb_result;
435 1.1 tsubai break;
436 1.1 tsubai case FBIOCNIOCTL:
437 1.1 tsubai fbp->fb_command = FB_CIOCTL;
438 1.1 tsubai fbp->fb_fbioctl = *((lFbIoctl*)data);
439 1.1 tsubai fbstart(fbp, 1);
440 1.1 tsubai *((lFbIoctl*)data) = fbp->fb_fbioctl;
441 1.1 tsubai if (fbp->fb_result == FB_RERROR)
442 1.1 tsubai error = EINVAL;
443 1.1 tsubai break;
444 1.1 tsubai
445 1.1 tsubai default:
446 1.1 tsubai error = ENXIO;
447 1.1 tsubai break;
448 1.1 tsubai }
449 1.1 tsubai
450 1.1 tsubai fbunlock(error);
451 1.1 tsubai
452 1.1 tsubai return error;
453 1.1 tsubai }
454 1.1 tsubai
455 1.4 simonb paddr_t
456 1.1 tsubai fbmmap(dev, off, prot)
457 1.1 tsubai dev_t dev;
458 1.4 simonb off_t off;
459 1.4 simonb int prot;
460 1.1 tsubai {
461 1.4 simonb int unit = FBUNIT(dev);
462 1.4 simonb struct fb_softc *fb = fb_cd.cd_devs[unit];
463 1.4 simonb struct fbreg *fbp = &fb->fbreg;
464 1.4 simonb paddr_t page;
465 1.1 tsubai
466 1.1 tsubai if (unit >= NFB)
467 1.1 tsubai return -1;
468 1.1 tsubai
469 1.1 tsubai if (off & PGOFSET)
470 1.1 tsubai return -1;
471 1.1 tsubai
472 1.1 tsubai if (off < 0)
473 1.1 tsubai return -1;
474 1.1 tsubai
475 1.1 tsubai fblock();
476 1.1 tsubai fbp->fb_device = fb->fbs_device;
477 1.1 tsubai fbp->fb_command = FB_CGETPAGE;
478 1.1 tsubai fbp->fb_data = off;
479 1.1 tsubai fbstart(fbp, 1);
480 1.1 tsubai page = fbp->fb_data;
481 1.1 tsubai if (fbp->fb_result == FB_RERROR)
482 1.1 tsubai page = -1;
483 1.1 tsubai else
484 1.1 tsubai fb->fbs_flag = 1;
485 1.1 tsubai fbunlock(fbp->fb_result);
486 1.1 tsubai
487 1.1 tsubai return page;
488 1.1 tsubai }
489 1.1 tsubai
490 1.1 tsubai #if 0 /* not needed? */
491 1.1 tsubai int
492 1.1 tsubai fbpoll(dev, events, p)
493 1.1 tsubai dev_t dev;
494 1.1 tsubai int events;
495 1.1 tsubai struct proc *p;
496 1.1 tsubai {
497 1.1 tsubai return -1;
498 1.1 tsubai }
499 1.1 tsubai #endif
500 1.1 tsubai
501 1.1 tsubai static void
502 1.1 tsubai fblock()
503 1.1 tsubai {
504 1.1 tsubai int s;
505 1.1 tsubai
506 1.1 tsubai #ifdef USE_RAW_INTR
507 1.1 tsubai fbwait();
508 1.1 tsubai #endif
509 1.1 tsubai s = splfb();
510 1.1 tsubai while (fbstate & FB_BUSY) {
511 1.1 tsubai fbstate |= FB_WANTED;
512 1.1 tsubai tsleep(&fbstate, FBPRI | PCATCH, "fblock", 0);
513 1.1 tsubai }
514 1.1 tsubai fbstate |= FB_BUSY;
515 1.1 tsubai splx(s);
516 1.1 tsubai }
517 1.1 tsubai
518 1.1 tsubai static void
519 1.1 tsubai fbunlock(error)
520 1.1 tsubai int error;
521 1.1 tsubai {
522 1.1 tsubai int s = splfb();
523 1.1 tsubai
524 1.1 tsubai #ifdef CPU_SINGLE
525 1.1 tsubai fbstate &= ~FB_BUSY;
526 1.1 tsubai if (fbstate & FB_WANTED) {
527 1.1 tsubai fbstate &= ~FB_WANTED;
528 1.1 tsubai wakeup(&fbstate);
529 1.1 tsubai }
530 1.1 tsubai #else
531 1.1 tsubai #ifdef USE_RAW_INTR
532 1.1 tsubai fbstate &= ~FB_BUSY;
533 1.1 tsubai if (fbstate & FB_WANTED) {
534 1.1 tsubai fbstate &= ~FB_WANTED;
535 1.1 tsubai wakeup(&fbstate);
536 1.1 tsubai }
537 1.1 tsubai #else
538 1.1 tsubai if (error || (fbstate & FB_DELAY) == 0) {
539 1.1 tsubai fbstate &= ~(FB_BUSY | FB_WAIT | FB_DELAY);
540 1.1 tsubai if (fbstate & FB_WANTED) {
541 1.1 tsubai fbstate &= ~FB_WANTED;
542 1.1 tsubai wakeup(&fbstate);
543 1.1 tsubai }
544 1.1 tsubai }
545 1.1 tsubai if (fbstate & FB_DELAY) {
546 1.1 tsubai fbstate &= ~FB_DELAY;
547 1.1 tsubai fbstate |= FB_DELAY2;
548 1.1 tsubai }
549 1.1 tsubai #endif
550 1.1 tsubai #endif /* CPU_SINGLE */
551 1.1 tsubai splx(s);
552 1.1 tsubai }
553 1.1 tsubai
554 1.1 tsubai static int
555 1.1 tsubai fbinit(fbp)
556 1.1 tsubai struct fbreg *fbp;
557 1.1 tsubai {
558 1.1 tsubai fblock();
559 1.1 tsubai
560 1.1 tsubai fbp->fb_command = FB_COPEN;
561 1.1 tsubai fbstart(fbp, 1);
562 1.1 tsubai if (fbp->fb_result != FB_ROK) {
563 1.1 tsubai fbunlock(0);
564 1.1 tsubai return FB_RERROR;
565 1.1 tsubai }
566 1.1 tsubai
567 1.1 tsubai fbp->fb_command = FB_CUNSETCURSOR;
568 1.1 tsubai fbstart(fbp, 0);
569 1.1 tsubai
570 1.1 tsubai fbunlock(0);
571 1.1 tsubai
572 1.1 tsubai return FB_ROK;
573 1.1 tsubai }
574 1.1 tsubai
575 1.1 tsubai static void
576 1.1 tsubai fbreset(fbp)
577 1.1 tsubai struct fbreg *fbp;
578 1.1 tsubai {
579 1.1 tsubai fblock();
580 1.1 tsubai
581 1.1 tsubai fbp->fb_command = FB_CUNSETCURSOR;
582 1.1 tsubai fbstart(fbp, 1);
583 1.1 tsubai
584 1.1 tsubai fbp->fb_command = FB_CCLOSE;
585 1.1 tsubai fbstart(fbp, 0);
586 1.1 tsubai
587 1.1 tsubai fbunlock(0);
588 1.1 tsubai }
589 1.1 tsubai #endif /* NFB > 0 */
590