File:
[DragonFly] /
src /
sys /
dev /
video /
fb /
fb.c
Revision
1.8:
download - view:
text,
annotated -
select for diffs
Thu May 13 23:49:22 2004 UTC (9 years ago) by
dillon
Branches:
MAIN
CVS tags:
HEAD
device switch 1/many: Remove d_autoq, add d_clone (where d_autoq was).
d_autoq was used to allow the device port dispatch to mix old-style synchronous
calls with new style messaging calls within a particular device. It was never
used for that purpose.
d_clone will be more fully implemented as work continues. We are going to
install d_port in the dev_t (struct specinfo) structure itself and d_clone
will be needed to allow devices to 'revector' the port on a minor-number
by minor-number basis, in particular allowing minor numbers to be directly
dispatched to distinct threads. This is something we will be needing later
on.
1: /*-
2: * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer as
10: * the first lines of this file unmodified.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: * 3. The name of the author may not be used to endorse or promote products
15: * derived from this software without specific prior written permission.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20: * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27: *
28: * $FreeBSD: src/sys/dev/fb/fb.c,v 1.11.2.2 2000/08/02 22:35:22 peter Exp $
29: * $DragonFly: src/sys/dev/video/fb/fb.c,v 1.8 2004/05/13 23:49:22 dillon Exp $
30: */
31:
32: #include "opt_fb.h"
33:
34: #include <sys/param.h>
35: #include <sys/systm.h>
36: #include <sys/conf.h>
37: #include <sys/bus.h>
38: #include <sys/kernel.h>
39: #include <sys/malloc.h>
40: #include <sys/uio.h>
41: #include <sys/fbio.h>
42: #include <sys/linker_set.h>
43: #include <sys/device.h>
44:
45: #include <vm/vm.h>
46: #include <vm/pmap.h>
47:
48: #include "fbreg.h"
49:
50: SET_DECLARE(videodriver_set, const video_driver_t);
51:
52: /* local arrays */
53:
54: /*
55: * We need at least one entry each in order to initialize a video card
56: * for the kernel console. The arrays will be increased dynamically
57: * when necessary.
58: */
59:
60: static int vid_malloc;
61: static int adapters = 1;
62: static video_adapter_t *adp_ini;
63: static video_adapter_t **adapter = &adp_ini;
64: static video_switch_t *vidsw_ini;
65: video_switch_t **vidsw = &vidsw_ini;
66:
67: #ifdef FB_INSTALL_CDEV
68: static struct lwkt_port *vidcdevsw_ini;
69: static struct lwkt_port **vidcdevsw = &vidcdevsw_ini;
70: #endif
71:
72: #define ARRAY_DELTA 4
73:
74: static int
75: vid_realloc_array(void)
76: {
77: video_adapter_t **new_adp;
78: video_switch_t **new_vidsw;
79: #ifdef FB_INSTALL_CDEV
80: struct lwkt_port **new_cdevsw;
81: #endif
82: int newsize;
83: int s;
84:
85: if (!vid_malloc)
86: return ENOMEM;
87:
88: s = spltty();
89: newsize = ((adapters + ARRAY_DELTA)/ARRAY_DELTA)*ARRAY_DELTA;
90: new_adp = malloc(sizeof(*new_adp)*newsize, M_DEVBUF, M_WAITOK);
91: new_vidsw = malloc(sizeof(*new_vidsw)*newsize, M_DEVBUF, M_WAITOK);
92: #ifdef FB_INSTALL_CDEV
93: new_cdevsw = malloc(sizeof(*new_cdevsw)*newsize, M_DEVBUF, M_WAITOK);
94: #endif
95: bzero(new_adp, sizeof(*new_adp)*newsize);
96: bzero(new_vidsw, sizeof(*new_vidsw)*newsize);
97: bcopy(adapter, new_adp, sizeof(*adapter)*adapters);
98: bcopy(vidsw, new_vidsw, sizeof(*vidsw)*adapters);
99: #ifdef FB_INSTALL_CDEV
100: bzero(new_cdevsw, sizeof(*new_cdevsw)*newsize);
101: bcopy(vidcdevsw, new_cdevsw, sizeof(*vidcdevsw)*adapters);
102: #endif
103: if (adapters > 1) {
104: free(adapter, M_DEVBUF);
105: free(vidsw, M_DEVBUF);
106: #ifdef FB_INSTALL_CDEV
107: free(vidcdevsw, M_DEVBUF);
108: #endif
109: }
110: adapter = new_adp;
111: vidsw = new_vidsw;
112: #ifdef FB_INSTALL_CDEV
113: vidcdevsw = new_cdevsw;
114: #endif
115: adapters = newsize;
116: splx(s);
117:
118: if (bootverbose)
119: printf("fb: new array size %d\n", adapters);
120:
121: return 0;
122: }
123:
124: static void
125: vid_malloc_init(void *arg)
126: {
127: vid_malloc = TRUE;
128: }
129:
130: SYSINIT(vid_mem, SI_SUB_KMEM, SI_ORDER_ANY, vid_malloc_init, NULL);
131:
132: /*
133: * Low-level frame buffer driver functions
134: * frame buffer subdrivers, such as the VGA driver, call these functions
135: * to initialize the video_adapter structure and register it to the virtual
136: * frame buffer driver `fb'.
137: */
138:
139: /* initialize the video_adapter_t structure */
140: void
141: vid_init_struct(video_adapter_t *adp, char *name, int type, int unit)
142: {
143: adp->va_flags = 0;
144: adp->va_name = name;
145: adp->va_type = type;
146: adp->va_unit = unit;
147: }
148:
149: /* Register a video adapter */
150: int
151: vid_register(video_adapter_t *adp)
152: {
153: const video_driver_t **list;
154: const video_driver_t *p;
155: int index;
156:
157: for (index = 0; index < adapters; ++index) {
158: if (adapter[index] == NULL)
159: break;
160: }
161: if (index >= adapters) {
162: if (vid_realloc_array())
163: return -1;
164: }
165:
166: adp->va_index = index;
167: adp->va_token = NULL;
168: SET_FOREACH(list, videodriver_set) {
169: p = *list;
170: if (strcmp(p->name, adp->va_name) == 0) {
171: adapter[index] = adp;
172: vidsw[index] = p->vidsw;
173: return index;
174: }
175: }
176:
177: return -1;
178: }
179:
180: int
181: vid_unregister(video_adapter_t *adp)
182: {
183: if ((adp->va_index < 0) || (adp->va_index >= adapters))
184: return ENOENT;
185: if (adapter[adp->va_index] != adp)
186: return ENOENT;
187:
188: adapter[adp->va_index] = NULL;
189: vidsw[adp->va_index] = NULL;
190: return 0;
191: }
192:
193: /* Get video I/O function table */
194: video_switch_t
195: *vid_get_switch(char *name)
196: {
197: const video_driver_t **list;
198: const video_driver_t *p;
199:
200: SET_FOREACH(list, videodriver_set) {
201: p = *list;
202: if (strcmp(p->name, name) == 0)
203: return p->vidsw;
204: }
205:
206: return NULL;
207: }
208:
209: /*
210: * Video card client functions
211: * Video card clients, such as the console driver `syscons' and the frame
212: * buffer cdev driver, use these functions to claim and release a card for
213: * exclusive use.
214: */
215:
216: /* find the video card specified by a driver name and a unit number */
217: int
218: vid_find_adapter(char *driver, int unit)
219: {
220: int i;
221:
222: for (i = 0; i < adapters; ++i) {
223: if (adapter[i] == NULL)
224: continue;
225: if (strcmp("*", driver) && strcmp(adapter[i]->va_name, driver))
226: continue;
227: if ((unit != -1) && (adapter[i]->va_unit != unit))
228: continue;
229: return i;
230: }
231: return -1;
232: }
233:
234: /* allocate a video card */
235: int
236: vid_allocate(char *driver, int unit, void *id)
237: {
238: int index;
239: int s;
240:
241: s = spltty();
242: index = vid_find_adapter(driver, unit);
243: if (index >= 0) {
244: if (adapter[index]->va_token) {
245: splx(s);
246: return -1;
247: }
248: adapter[index]->va_token = id;
249: }
250: splx(s);
251: return index;
252: }
253:
254: int
255: vid_release(video_adapter_t *adp, void *id)
256: {
257: int error;
258: int s;
259:
260: s = spltty();
261: if (adp->va_token == NULL) {
262: error = EINVAL;
263: } else if (adp->va_token != id) {
264: error = EPERM;
265: } else {
266: adp->va_token = NULL;
267: error = 0;
268: }
269: splx(s);
270: return error;
271: }
272:
273: /* Get a video adapter structure */
274: video_adapter_t
275: *vid_get_adapter(int index)
276: {
277: if ((index < 0) || (index >= adapters))
278: return NULL;
279: return adapter[index];
280: }
281:
282: /* Configure drivers: this is a backdoor for the console driver XXX */
283: int
284: vid_configure(int flags)
285: {
286: const video_driver_t **list;
287: const video_driver_t *p;
288:
289: SET_FOREACH(list, videodriver_set) {
290: p = *list;
291: if (p->configure != NULL)
292: (*p->configure)(flags);
293: }
294:
295: return 0;
296: }
297:
298: /*
299: * Virtual frame buffer cdev driver functions
300: * The virtual frame buffer driver dispatches driver functions to
301: * appropriate subdrivers.
302: */
303:
304: #define FB_DRIVER_NAME "fb"
305:
306: #ifdef FB_INSTALL_CDEV
307:
308: #if experimental
309:
310: static devclass_t fb_devclass;
311:
312: static int fbprobe(device_t dev);
313: static int fbattach(device_t dev);
314:
315: static device_method_t fb_methods[] = {
316: DEVMETHOD(device_probe, fbprobe),
317: DEVMETHOD(device_attach, fbattach),
318:
319: DEVMETHOD(bus_print_child, bus_generic_print_child),
320: { 0, 0 }
321: };
322:
323: static driver_t fb_driver = {
324: FB_DRIVER_NAME,
325: fb_methods,
326: 0,
327: };
328:
329: static int
330: fbprobe(device_t dev)
331: {
332: int unit;
333:
334: unit = device_get_unit(dev);
335: if (unit >= adapters)
336: return ENXIO;
337: if (adapter[unit] == NULL)
338: return ENXIO;
339:
340: device_set_desc(dev, "generic frame buffer");
341: return 0;
342: }
343:
344: static int
345: fbattach(device_t dev)
346: {
347: printf("fbattach: about to attach children\n");
348: bus_generic_attach(dev);
349: return 0;
350: }
351:
352: #endif /* experimental */
353:
354: #define FB_UNIT(dev) minor(dev)
355: #define FB_MKMINOR(unit) (u)
356:
357: static d_open_t fbopen;
358: static d_close_t fbclose;
359: static d_read_t fbread;
360: static d_write_t fbwrite;
361: static d_ioctl_t fbioctl;
362: static d_mmap_t fbmmap;
363:
364: #define CDEV_MAJOR 123 /* XXX */
365:
366: static struct cdevsw fb_cdevsw = {
367: /* name */ FB_DRIVER_NAME,
368: /* maj */ CDEV_MAJOR,
369: /* flags */ 0,
370: /* port */ NULL,
371: /* clone */ NULL,
372:
373: /* open */ fbopen,
374: /* close */ fbclose,
375: /* read */ fbread,
376: /* write */ fbwrite,
377: /* ioctl */ fbioctl,
378: /* poll */ nopoll,
379: /* mmap */ fbmmap,
380: /* strategy */ nostrategy,
381: /* dump */ nodump,
382: /* psize */ nopsize
383: };
384:
385: static void
386: vfbattach(void *arg)
387: {
388: static int fb_devsw_installed = FALSE;
389:
390: if (!fb_devsw_installed) {
391: cdevsw_add(&fb_cdevsw);
392: fb_devsw_installed = TRUE;
393: }
394: }
395:
396: PSEUDO_SET(vfbattach, fb);
397:
398: /*
399: * Note: dev represents the actual video device, not the frame buffer
400: */
401: int
402: fb_attach(dev_t dev, video_adapter_t *adp)
403: {
404: int s;
405:
406: if (adp->va_index >= adapters)
407: return EINVAL;
408: if (adapter[adp->va_index] != adp)
409: return EINVAL;
410:
411: s = spltty();
412: adp->va_minor = minor(dev);
413: vidcdevsw[adp->va_index] = dev_dport(dev);
414: splx(s);
415:
416: printf("fb%d at %s%d\n", adp->va_index, adp->va_name, adp->va_unit);
417: return 0;
418: }
419:
420: #if 0 /* never seems to be called */
421: /*
422: * Note: dev represents the actual video device, not the frame buffer
423: */
424: int
425: fb_detach(dev_t dev, video_adapter_t *adp)
426: {
427: int s;
428:
429: if (adp->va_index >= adapters)
430: return EINVAL;
431: if (adapter[adp->va_index] != adp)
432: return EINVAL;
433: if (vidcdevsw[adp->va_index] != port)
434: return EINVAL;
435:
436: s = spltty();
437: vidcdevsw[adp->va_index] = NULL;
438: splx(s);
439: return 0;
440: }
441: #endif
442:
443: static int
444: fbopen(dev_t dev, int flag, int mode, struct thread *td)
445: {
446: int unit;
447:
448: unit = FB_UNIT(dev);
449: if (unit >= adapters)
450: return ENXIO;
451: if (vidcdevsw[unit] == NULL)
452: return ENXIO;
453: return dev_port_dopen(vidcdevsw[unit],
454: makedev(0, adapter[unit]->va_minor),
455: flag, mode, td);
456: }
457:
458: static int
459: fbclose(dev_t dev, int flag, int mode, struct thread *td)
460: {
461: int unit;
462:
463: unit = FB_UNIT(dev);
464: if (vidcdevsw[unit] == NULL)
465: return ENXIO;
466: return dev_port_dclose(vidcdevsw[unit],
467: makedev(0, adapter[unit]->va_minor),
468: flag, mode, td);
469: }
470:
471: static int
472: fbread(dev_t dev, struct uio *uio, int flag)
473: {
474: int unit;
475:
476: unit = FB_UNIT(dev);
477: if (vidcdevsw[unit] == NULL)
478: return ENXIO;
479: return dev_port_dread(vidcdevsw[unit],
480: makedev(0, adapter[unit]->va_minor),
481: uio, flag);
482: }
483:
484: static int
485: fbwrite(dev_t dev, struct uio *uio, int flag)
486: {
487: int unit;
488:
489: unit = FB_UNIT(dev);
490: if (vidcdevsw[unit] == NULL)
491: return ENXIO;
492: return dev_port_dwrite(vidcdevsw[unit],
493: makedev(0, adapter[unit]->va_minor),
494: uio, flag);
495: }
496:
497: static int
498: fbioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
499: {
500: int unit;
501:
502: unit = FB_UNIT(dev);
503: if (vidcdevsw[unit] == NULL)
504: return ENXIO;
505: return dev_port_dioctl(vidcdevsw[unit],
506: makedev(0, adapter[unit]->va_minor),
507: cmd, arg, flag, td);
508: }
509:
510: static int
511: fbmmap(dev_t dev, vm_offset_t offset, int nprot)
512: {
513: int unit;
514:
515: unit = FB_UNIT(dev);
516: if (vidcdevsw[unit] == NULL)
517: return ENXIO;
518: return (dev_port_dmmap(vidcdevsw[unit],
519: makedev(0, adapter[unit]->va_minor),
520: offset, nprot));
521: }
522:
523: #if experimental
524: DEV_DRIVER_MODULE(fb, ???, fb_driver, fb_devclass, fb_cdevsw, 0, 0);
525: #endif
526:
527: /*
528: * Generic frame buffer cdev driver functions
529: * Frame buffer subdrivers may call these functions to implement common
530: * driver functions.
531: */
532:
533: int genfbopen(genfb_softc_t *sc, video_adapter_t *adp, int flag, int mode,
534: struct thread *td)
535: {
536: int s;
537:
538: s = spltty();
539: if (!(sc->gfb_flags & FB_OPEN))
540: sc->gfb_flags |= FB_OPEN;
541: splx(s);
542: return 0;
543: }
544:
545: int genfbclose(genfb_softc_t *sc, video_adapter_t *adp, int flag, int mode,
546: struct thread *td)
547: {
548: int s;
549:
550: s = spltty();
551: sc->gfb_flags &= ~FB_OPEN;
552: splx(s);
553: return 0;
554: }
555:
556: int genfbread(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio,
557: int flag)
558: {
559: int size;
560: int offset;
561: int error;
562: int len;
563:
564: error = 0;
565: size = adp->va_buffer_size/adp->va_info.vi_planes;
566: while (uio->uio_resid > 0) {
567: if (uio->uio_offset >= size)
568: break;
569: offset = uio->uio_offset%adp->va_window_size;
570: len = imin(uio->uio_resid, size - uio->uio_offset);
571: len = imin(len, adp->va_window_size - offset);
572: if (len <= 0)
573: break;
574: (*vidsw[adp->va_index]->set_win_org)(adp, uio->uio_offset);
575: error = uiomove((caddr_t)(adp->va_window + offset), len, uio);
576: if (error)
577: break;
578: }
579: return error;
580: }
581:
582: int genfbwrite(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio,
583: int flag)
584: {
585: return ENODEV;
586: }
587:
588: int genfbioctl(genfb_softc_t *sc, video_adapter_t *adp, u_long cmd,
589: caddr_t arg, int flag, struct thread *td)
590: {
591: int error;
592:
593: if (adp == NULL) /* XXX */
594: return ENXIO;
595: error = (*vidsw[adp->va_index]->ioctl)(adp, cmd, arg);
596: if (error == ENOIOCTL)
597: error = ENODEV;
598: return error;
599: }
600:
601: int genfbmmap(genfb_softc_t *sc, video_adapter_t *adp, vm_offset_t offset,
602: int prot)
603: {
604: return (*vidsw[adp->va_index]->mmap)(adp, offset, prot);
605: }
606:
607: #endif /* FB_INSTALL_CDEV */
608:
609: static char
610: *adapter_name(int type)
611: {
612: static struct {
613: int type;
614: char *name;
615: } names[] = {
616: { KD_MONO, "MDA" },
617: { KD_HERCULES, "Hercules" },
618: { KD_CGA, "CGA" },
619: { KD_EGA, "EGA" },
620: { KD_VGA, "VGA" },
621: { KD_PC98, "PC-98x1" },
622: { KD_TGA, "TGA" },
623: { -1, "Unknown" },
624: };
625: int i;
626:
627: for (i = 0; names[i].type != -1; ++i)
628: if (names[i].type == type)
629: break;
630: return names[i].name;
631: }
632:
633: /*
634: * Generic low-level frame buffer functions
635: * The low-level functions in the frame buffer subdriver may use these
636: * functions.
637: */
638:
639: void
640: fb_dump_adp_info(char *driver, video_adapter_t *adp, int level)
641: {
642: if (level <= 0)
643: return;
644:
645: printf("%s%d: %s%d, %s, type:%s (%d), flags:0x%x\n",
646: FB_DRIVER_NAME, adp->va_index, driver, adp->va_unit, adp->va_name,
647: adapter_name(adp->va_type), adp->va_type, adp->va_flags);
648: printf("%s%d: port:0x%x-0x%x, crtc:0x%x, mem:0x%x 0x%x\n",
649: FB_DRIVER_NAME, adp->va_index,
650: adp->va_io_base, adp->va_io_base + adp->va_io_size - 1,
651: adp->va_crtc_addr, adp->va_mem_base, adp->va_mem_size);
652: printf("%s%d: init mode:%d, bios mode:%d, current mode:%d\n",
653: FB_DRIVER_NAME, adp->va_index,
654: adp->va_initial_mode, adp->va_initial_bios_mode, adp->va_mode);
655: printf("%s%d: window:%p size:%dk gran:%dk, buf:%p size:%dk\n",
656: FB_DRIVER_NAME, adp->va_index,
657: (void *)adp->va_window, (int)adp->va_window_size/1024,
658: (int)adp->va_window_gran/1024, (void *)adp->va_buffer,
659: (int)adp->va_buffer_size/1024);
660: }
661:
662: void
663: fb_dump_mode_info(char *driver, video_adapter_t *adp, video_info_t *info,
664: int level)
665: {
666: if (level <= 0)
667: return;
668:
669: printf("%s%d: %s, mode:%d, flags:0x%x ",
670: driver, adp->va_unit, adp->va_name, info->vi_mode, info->vi_flags);
671: if (info->vi_flags & V_INFO_GRAPHICS)
672: printf("G %dx%dx%d, %d plane(s), font:%dx%d, ",
673: info->vi_width, info->vi_height,
674: info->vi_depth, info->vi_planes,
675: info->vi_cwidth, info->vi_cheight);
676: else
677: printf("T %dx%d, font:%dx%d, ",
678: info->vi_width, info->vi_height,
679: info->vi_cwidth, info->vi_cheight);
680: printf("win:0x%x\n", info->vi_window);
681: }
682:
683: int
684: fb_type(int adp_type)
685: {
686: static struct {
687: int fb_type;
688: int va_type;
689: } types[] = {
690: { FBTYPE_MDA, KD_MONO },
691: { FBTYPE_HERCULES, KD_HERCULES },
692: { FBTYPE_CGA, KD_CGA },
693: { FBTYPE_EGA, KD_EGA },
694: { FBTYPE_VGA, KD_VGA },
695: { FBTYPE_PC98, KD_PC98 },
696: { FBTYPE_TGA, KD_TGA },
697: };
698: int i;
699:
700: for (i = 0; i < sizeof(types)/sizeof(types[0]); ++i) {
701: if (types[i].va_type == adp_type)
702: return types[i].fb_type;
703: }
704: return -1;
705: }
706:
707: int
708: fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
709: {
710: int error;
711: int s;
712:
713: /* assert(adp != NULL) */
714:
715: error = 0;
716: s = spltty();
717:
718: switch (cmd) {
719:
720: case FBIO_ADAPTER: /* get video adapter index */
721: *(int *)arg = adp->va_index;
722: break;
723:
724: case FBIO_ADPTYPE: /* get video adapter type */
725: *(int *)arg = adp->va_type;
726: break;
727:
728: case FBIO_ADPINFO: /* get video adapter info */
729: ((video_adapter_info_t *)arg)->va_index = adp->va_index;
730: ((video_adapter_info_t *)arg)->va_type = adp->va_type;
731: bcopy(adp->va_name, ((video_adapter_info_t *)arg)->va_name,
732: imin(strlen(adp->va_name) + 1,
733: sizeof(((video_adapter_info_t *)arg)->va_name)));
734: ((video_adapter_info_t *)arg)->va_unit = adp->va_unit;
735: ((video_adapter_info_t *)arg)->va_flags = adp->va_flags;
736: ((video_adapter_info_t *)arg)->va_io_base = adp->va_io_base;
737: ((video_adapter_info_t *)arg)->va_io_size = adp->va_io_size;
738: ((video_adapter_info_t *)arg)->va_crtc_addr = adp->va_crtc_addr;
739: ((video_adapter_info_t *)arg)->va_mem_base = adp->va_mem_base;
740: ((video_adapter_info_t *)arg)->va_mem_size = adp->va_mem_size;
741: ((video_adapter_info_t *)arg)->va_window
742: #ifdef __i386__
743: = vtophys(adp->va_window);
744: #else
745: = adp->va_window;
746: #endif
747: ((video_adapter_info_t *)arg)->va_window_size
748: = adp->va_window_size;
749: ((video_adapter_info_t *)arg)->va_window_gran
750: = adp->va_window_gran;
751: ((video_adapter_info_t *)arg)->va_window_orig
752: = adp->va_window_orig;
753: ((video_adapter_info_t *)arg)->va_unused0
754: #ifdef __i386__
755: = (adp->va_buffer) ? vtophys(adp->va_buffer) : 0;
756: #else
757: = adp->va_buffer;
758: #endif
759: ((video_adapter_info_t *)arg)->va_buffer_size
760: = adp->va_buffer_size;
761: ((video_adapter_info_t *)arg)->va_mode = adp->va_mode;
762: ((video_adapter_info_t *)arg)->va_initial_mode
763: = adp->va_initial_mode;
764: ((video_adapter_info_t *)arg)->va_initial_bios_mode
765: = adp->va_initial_bios_mode;
766: ((video_adapter_info_t *)arg)->va_line_width
767: = adp->va_line_width;
768: ((video_adapter_info_t *)arg)->va_disp_start.x
769: = adp->va_disp_start.x;
770: ((video_adapter_info_t *)arg)->va_disp_start.y
771: = adp->va_disp_start.y;
772: break;
773:
774: case FBIO_MODEINFO: /* get mode information */
775: error = (*vidsw[adp->va_index]->get_info)(adp,
776: ((video_info_t *)arg)->vi_mode,
777: (video_info_t *)arg);
778: if (error)
779: error = ENODEV;
780: break;
781:
782: case FBIO_FINDMODE: /* find a matching video mode */
783: error = (*vidsw[adp->va_index]->query_mode)(adp,
784: (video_info_t *)arg);
785: break;
786:
787: case FBIO_GETMODE: /* get video mode */
788: *(int *)arg = adp->va_mode;
789: break;
790:
791: case FBIO_SETMODE: /* set video mode */
792: error = (*vidsw[adp->va_index]->set_mode)(adp, *(int *)arg);
793: if (error)
794: error = ENODEV; /* EINVAL? */
795: break;
796:
797: case FBIO_GETWINORG: /* get frame buffer window origin */
798: *(u_int *)arg = adp->va_window_orig;
799: break;
800:
801: case FBIO_GETDISPSTART: /* get display start address */
802: ((video_display_start_t *)arg)->x = adp->va_disp_start.x;
803: ((video_display_start_t *)arg)->y = adp->va_disp_start.y;
804: break;
805:
806: case FBIO_GETLINEWIDTH: /* get scan line width in bytes */
807: *(u_int *)arg = adp->va_line_width;
808: break;
809:
810: case FBIO_GETPALETTE: /* get color palette */
811: case FBIO_SETPALETTE: /* set color palette */
812: /* XXX */
813:
814: case FBIOPUTCMAP:
815: case FBIOGETCMAP:
816: /* XXX */
817:
818: case FBIO_SETWINORG: /* set frame buffer window origin */
819: case FBIO_SETDISPSTART: /* set display start address */
820: case FBIO_SETLINEWIDTH: /* set scan line width in pixel */
821:
822: case FBIOGTYPE:
823: case FBIOGATTR:
824: case FBIOSVIDEO:
825: case FBIOGVIDEO:
826: case FBIOSCURSOR:
827: case FBIOGCURSOR:
828: case FBIOSCURPOS:
829: case FBIOGCURPOS:
830: case FBIOGCURMAX:
831:
832: default:
833: error = ENODEV;
834: break;
835: }
836:
837: splx(s);
838: return error;
839: }