1617b9080SKazutaka YOKOTA /*- 2617b9080SKazutaka YOKOTA * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 3617b9080SKazutaka YOKOTA * All rights reserved. 4617b9080SKazutaka YOKOTA * 5617b9080SKazutaka YOKOTA * Redistribution and use in source and binary forms, with or without 6617b9080SKazutaka YOKOTA * modification, are permitted provided that the following conditions 7617b9080SKazutaka YOKOTA * are met: 8617b9080SKazutaka YOKOTA * 1. Redistributions of source code must retain the above copyright 9617b9080SKazutaka YOKOTA * notice, this list of conditions and the following disclaimer as 10617b9080SKazutaka YOKOTA * the first lines of this file unmodified. 11617b9080SKazutaka YOKOTA * 2. Redistributions in binary form must reproduce the above copyright 12617b9080SKazutaka YOKOTA * notice, this list of conditions and the following disclaimer in the 13617b9080SKazutaka YOKOTA * documentation and/or other materials provided with the distribution. 14617b9080SKazutaka YOKOTA * 3. The name of the author may not be used to endorse or promote products 15617b9080SKazutaka YOKOTA * derived from this software without specific prior written permission. 16617b9080SKazutaka YOKOTA * 17617b9080SKazutaka YOKOTA * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 18617b9080SKazutaka YOKOTA * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19617b9080SKazutaka YOKOTA * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20617b9080SKazutaka YOKOTA * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21617b9080SKazutaka YOKOTA * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22617b9080SKazutaka YOKOTA * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23617b9080SKazutaka YOKOTA * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24617b9080SKazutaka YOKOTA * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25617b9080SKazutaka YOKOTA * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26617b9080SKazutaka YOKOTA * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27617b9080SKazutaka YOKOTA * 28c3aac50fSPeter Wemm * $FreeBSD$ 29617b9080SKazutaka YOKOTA */ 30617b9080SKazutaka YOKOTA 31617b9080SKazutaka YOKOTA #include "opt_fb.h" 32617b9080SKazutaka YOKOTA 33617b9080SKazutaka YOKOTA #include <sys/param.h> 34617b9080SKazutaka YOKOTA #include <sys/systm.h> 35617b9080SKazutaka YOKOTA #include <sys/conf.h> 366e8394b8SKazutaka YOKOTA #include <sys/bus.h> 37617b9080SKazutaka YOKOTA #include <sys/kernel.h> 38617b9080SKazutaka YOKOTA #include <sys/malloc.h> 392b120974SPeter Wemm #include <sys/module.h> 406e8394b8SKazutaka YOKOTA #include <sys/uio.h> 416e8394b8SKazutaka YOKOTA #include <sys/fbio.h> 42617b9080SKazutaka YOKOTA 436e8394b8SKazutaka YOKOTA #include <vm/vm.h> 446e8394b8SKazutaka YOKOTA #include <vm/pmap.h> 45617b9080SKazutaka YOKOTA 46617b9080SKazutaka YOKOTA #include <dev/fb/fbreg.h> 47617b9080SKazutaka YOKOTA 48617b9080SKazutaka YOKOTA /* local arrays */ 49617b9080SKazutaka YOKOTA 50617b9080SKazutaka YOKOTA /* 51617b9080SKazutaka YOKOTA * We need at least one entry each in order to initialize a video card 52617b9080SKazutaka YOKOTA * for the kernel console. The arrays will be increased dynamically 53617b9080SKazutaka YOKOTA * when necessary. 54617b9080SKazutaka YOKOTA */ 55617b9080SKazutaka YOKOTA 566e8394b8SKazutaka YOKOTA static int vid_malloc; 57617b9080SKazutaka YOKOTA static int adapters = 1; 5890500a9dSKazutaka YOKOTA static video_adapter_t *adp_ini; 5990500a9dSKazutaka YOKOTA static video_adapter_t **adapter = &adp_ini; 6090500a9dSKazutaka YOKOTA static video_switch_t *vidsw_ini; 61617b9080SKazutaka YOKOTA video_switch_t **vidsw = &vidsw_ini; 6290500a9dSKazutaka YOKOTA 6390500a9dSKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 646e8394b8SKazutaka YOKOTA static struct cdevsw *vidcdevsw_ini; 656e8394b8SKazutaka YOKOTA static struct cdevsw **vidcdevsw = &vidcdevsw_ini; 666e8394b8SKazutaka YOKOTA #endif 67617b9080SKazutaka YOKOTA 68617b9080SKazutaka YOKOTA #define ARRAY_DELTA 4 69617b9080SKazutaka YOKOTA 706e8394b8SKazutaka YOKOTA static int 71617b9080SKazutaka YOKOTA vid_realloc_array(void) 72617b9080SKazutaka YOKOTA { 73617b9080SKazutaka YOKOTA video_adapter_t **new_adp; 74617b9080SKazutaka YOKOTA video_switch_t **new_vidsw; 756e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 76617b9080SKazutaka YOKOTA struct cdevsw **new_cdevsw; 776e8394b8SKazutaka YOKOTA #endif 78617b9080SKazutaka YOKOTA int newsize; 79617b9080SKazutaka YOKOTA int s; 80617b9080SKazutaka YOKOTA 816e8394b8SKazutaka YOKOTA if (!vid_malloc) 826e8394b8SKazutaka YOKOTA return ENOMEM; 836e8394b8SKazutaka YOKOTA 84617b9080SKazutaka YOKOTA s = spltty(); 85617b9080SKazutaka YOKOTA newsize = ((adapters + ARRAY_DELTA)/ARRAY_DELTA)*ARRAY_DELTA; 867cc0979fSDavid Malone new_adp = malloc(sizeof(*new_adp)*newsize, M_DEVBUF, M_WAITOK | M_ZERO); 877cc0979fSDavid Malone new_vidsw = malloc(sizeof(*new_vidsw)*newsize, M_DEVBUF, 887cc0979fSDavid Malone M_WAITOK | M_ZERO); 896e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 907cc0979fSDavid Malone new_cdevsw = malloc(sizeof(*new_cdevsw)*newsize, M_DEVBUF, 917cc0979fSDavid Malone M_WAITOK | M_ZERO); 926e8394b8SKazutaka YOKOTA #endif 93617b9080SKazutaka YOKOTA bcopy(adapter, new_adp, sizeof(*adapter)*adapters); 94617b9080SKazutaka YOKOTA bcopy(vidsw, new_vidsw, sizeof(*vidsw)*adapters); 956e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 96617b9080SKazutaka YOKOTA bcopy(vidcdevsw, new_cdevsw, sizeof(*vidcdevsw)*adapters); 976e8394b8SKazutaka YOKOTA #endif 98617b9080SKazutaka YOKOTA if (adapters > 1) { 99617b9080SKazutaka YOKOTA free(adapter, M_DEVBUF); 100617b9080SKazutaka YOKOTA free(vidsw, M_DEVBUF); 1016e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 102617b9080SKazutaka YOKOTA free(vidcdevsw, M_DEVBUF); 1036e8394b8SKazutaka YOKOTA #endif 104617b9080SKazutaka YOKOTA } 105617b9080SKazutaka YOKOTA adapter = new_adp; 106617b9080SKazutaka YOKOTA vidsw = new_vidsw; 1076e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 108617b9080SKazutaka YOKOTA vidcdevsw = new_cdevsw; 1096e8394b8SKazutaka YOKOTA #endif 110617b9080SKazutaka YOKOTA adapters = newsize; 111617b9080SKazutaka YOKOTA splx(s); 112617b9080SKazutaka YOKOTA 113617b9080SKazutaka YOKOTA if (bootverbose) 114617b9080SKazutaka YOKOTA printf("fb: new array size %d\n", adapters); 1156e8394b8SKazutaka YOKOTA 1166e8394b8SKazutaka YOKOTA return 0; 117617b9080SKazutaka YOKOTA } 118617b9080SKazutaka YOKOTA 1196e8394b8SKazutaka YOKOTA static void 1206e8394b8SKazutaka YOKOTA vid_malloc_init(void *arg) 1216e8394b8SKazutaka YOKOTA { 1226e8394b8SKazutaka YOKOTA vid_malloc = TRUE; 1236e8394b8SKazutaka YOKOTA } 1246e8394b8SKazutaka YOKOTA 1256e8394b8SKazutaka YOKOTA SYSINIT(vid_mem, SI_SUB_KMEM, SI_ORDER_ANY, vid_malloc_init, NULL); 12690500a9dSKazutaka YOKOTA 127617b9080SKazutaka YOKOTA /* 128617b9080SKazutaka YOKOTA * Low-level frame buffer driver functions 129617b9080SKazutaka YOKOTA * frame buffer subdrivers, such as the VGA driver, call these functions 130617b9080SKazutaka YOKOTA * to initialize the video_adapter structure and register it to the virtual 131617b9080SKazutaka YOKOTA * frame buffer driver `fb'. 132617b9080SKazutaka YOKOTA */ 133617b9080SKazutaka YOKOTA 134617b9080SKazutaka YOKOTA /* initialize the video_adapter_t structure */ 135617b9080SKazutaka YOKOTA void 136617b9080SKazutaka YOKOTA vid_init_struct(video_adapter_t *adp, char *name, int type, int unit) 137617b9080SKazutaka YOKOTA { 138617b9080SKazutaka YOKOTA adp->va_flags = 0; 139617b9080SKazutaka YOKOTA adp->va_name = name; 140617b9080SKazutaka YOKOTA adp->va_type = type; 141617b9080SKazutaka YOKOTA adp->va_unit = unit; 142617b9080SKazutaka YOKOTA } 143617b9080SKazutaka YOKOTA 144617b9080SKazutaka YOKOTA /* Register a video adapter */ 145617b9080SKazutaka YOKOTA int 146617b9080SKazutaka YOKOTA vid_register(video_adapter_t *adp) 147617b9080SKazutaka YOKOTA { 1486e8394b8SKazutaka YOKOTA const video_driver_t **list; 1496e8394b8SKazutaka YOKOTA const video_driver_t *p; 150617b9080SKazutaka YOKOTA int index; 151617b9080SKazutaka YOKOTA 152617b9080SKazutaka YOKOTA for (index = 0; index < adapters; ++index) { 153617b9080SKazutaka YOKOTA if (adapter[index] == NULL) 154617b9080SKazutaka YOKOTA break; 155617b9080SKazutaka YOKOTA } 1566e8394b8SKazutaka YOKOTA if (index >= adapters) { 1576e8394b8SKazutaka YOKOTA if (vid_realloc_array()) 158617b9080SKazutaka YOKOTA return -1; 1596e8394b8SKazutaka YOKOTA } 160617b9080SKazutaka YOKOTA 161617b9080SKazutaka YOKOTA adp->va_index = index; 162617b9080SKazutaka YOKOTA adp->va_token = NULL; 1636e8394b8SKazutaka YOKOTA list = (const video_driver_t **)videodriver_set.ls_items; 164617b9080SKazutaka YOKOTA while ((p = *list++) != NULL) { 165617b9080SKazutaka YOKOTA if (strcmp(p->name, adp->va_name) == 0) { 166617b9080SKazutaka YOKOTA adapter[index] = adp; 167617b9080SKazutaka YOKOTA vidsw[index] = p->vidsw; 168617b9080SKazutaka YOKOTA return index; 169617b9080SKazutaka YOKOTA } 170617b9080SKazutaka YOKOTA } 171617b9080SKazutaka YOKOTA 172617b9080SKazutaka YOKOTA return -1; 173617b9080SKazutaka YOKOTA } 174617b9080SKazutaka YOKOTA 175617b9080SKazutaka YOKOTA int 176617b9080SKazutaka YOKOTA vid_unregister(video_adapter_t *adp) 177617b9080SKazutaka YOKOTA { 178617b9080SKazutaka YOKOTA if ((adp->va_index < 0) || (adp->va_index >= adapters)) 179617b9080SKazutaka YOKOTA return ENOENT; 180617b9080SKazutaka YOKOTA if (adapter[adp->va_index] != adp) 181617b9080SKazutaka YOKOTA return ENOENT; 182617b9080SKazutaka YOKOTA 183617b9080SKazutaka YOKOTA adapter[adp->va_index] = NULL; 184617b9080SKazutaka YOKOTA vidsw[adp->va_index] = NULL; 185617b9080SKazutaka YOKOTA return 0; 186617b9080SKazutaka YOKOTA } 187617b9080SKazutaka YOKOTA 188617b9080SKazutaka YOKOTA /* Get video I/O function table */ 189617b9080SKazutaka YOKOTA video_switch_t 190617b9080SKazutaka YOKOTA *vid_get_switch(char *name) 191617b9080SKazutaka YOKOTA { 1926e8394b8SKazutaka YOKOTA const video_driver_t **list; 1936e8394b8SKazutaka YOKOTA const video_driver_t *p; 194617b9080SKazutaka YOKOTA 1956e8394b8SKazutaka YOKOTA list = (const video_driver_t **)videodriver_set.ls_items; 196617b9080SKazutaka YOKOTA while ((p = *list++) != NULL) { 197617b9080SKazutaka YOKOTA if (strcmp(p->name, name) == 0) 198617b9080SKazutaka YOKOTA return p->vidsw; 199617b9080SKazutaka YOKOTA } 200617b9080SKazutaka YOKOTA 201617b9080SKazutaka YOKOTA return NULL; 202617b9080SKazutaka YOKOTA } 203617b9080SKazutaka YOKOTA 204617b9080SKazutaka YOKOTA /* 205617b9080SKazutaka YOKOTA * Video card client functions 206617b9080SKazutaka YOKOTA * Video card clients, such as the console driver `syscons' and the frame 207617b9080SKazutaka YOKOTA * buffer cdev driver, use these functions to claim and release a card for 208617b9080SKazutaka YOKOTA * exclusive use. 209617b9080SKazutaka YOKOTA */ 210617b9080SKazutaka YOKOTA 211617b9080SKazutaka YOKOTA /* find the video card specified by a driver name and a unit number */ 212617b9080SKazutaka YOKOTA int 213617b9080SKazutaka YOKOTA vid_find_adapter(char *driver, int unit) 214617b9080SKazutaka YOKOTA { 215617b9080SKazutaka YOKOTA int i; 216617b9080SKazutaka YOKOTA 217617b9080SKazutaka YOKOTA for (i = 0; i < adapters; ++i) { 218617b9080SKazutaka YOKOTA if (adapter[i] == NULL) 219617b9080SKazutaka YOKOTA continue; 220617b9080SKazutaka YOKOTA if (strcmp("*", driver) && strcmp(adapter[i]->va_name, driver)) 221617b9080SKazutaka YOKOTA continue; 222617b9080SKazutaka YOKOTA if ((unit != -1) && (adapter[i]->va_unit != unit)) 223617b9080SKazutaka YOKOTA continue; 224617b9080SKazutaka YOKOTA return i; 225617b9080SKazutaka YOKOTA } 226617b9080SKazutaka YOKOTA return -1; 227617b9080SKazutaka YOKOTA } 228617b9080SKazutaka YOKOTA 229617b9080SKazutaka YOKOTA /* allocate a video card */ 230617b9080SKazutaka YOKOTA int 231617b9080SKazutaka YOKOTA vid_allocate(char *driver, int unit, void *id) 232617b9080SKazutaka YOKOTA { 233617b9080SKazutaka YOKOTA int index; 234617b9080SKazutaka YOKOTA int s; 235617b9080SKazutaka YOKOTA 236617b9080SKazutaka YOKOTA s = spltty(); 237617b9080SKazutaka YOKOTA index = vid_find_adapter(driver, unit); 238617b9080SKazutaka YOKOTA if (index >= 0) { 239617b9080SKazutaka YOKOTA if (adapter[index]->va_token) { 240617b9080SKazutaka YOKOTA splx(s); 241617b9080SKazutaka YOKOTA return -1; 242617b9080SKazutaka YOKOTA } 243617b9080SKazutaka YOKOTA adapter[index]->va_token = id; 244617b9080SKazutaka YOKOTA } 245617b9080SKazutaka YOKOTA splx(s); 246617b9080SKazutaka YOKOTA return index; 247617b9080SKazutaka YOKOTA } 248617b9080SKazutaka YOKOTA 249617b9080SKazutaka YOKOTA int 250617b9080SKazutaka YOKOTA vid_release(video_adapter_t *adp, void *id) 251617b9080SKazutaka YOKOTA { 252617b9080SKazutaka YOKOTA int error; 253617b9080SKazutaka YOKOTA int s; 254617b9080SKazutaka YOKOTA 255617b9080SKazutaka YOKOTA s = spltty(); 256617b9080SKazutaka YOKOTA if (adp->va_token == NULL) { 257617b9080SKazutaka YOKOTA error = EINVAL; 258617b9080SKazutaka YOKOTA } else if (adp->va_token != id) { 259617b9080SKazutaka YOKOTA error = EPERM; 260617b9080SKazutaka YOKOTA } else { 261617b9080SKazutaka YOKOTA adp->va_token = NULL; 262617b9080SKazutaka YOKOTA error = 0; 263617b9080SKazutaka YOKOTA } 264617b9080SKazutaka YOKOTA splx(s); 265617b9080SKazutaka YOKOTA return error; 266617b9080SKazutaka YOKOTA } 267617b9080SKazutaka YOKOTA 268617b9080SKazutaka YOKOTA /* Get a video adapter structure */ 269617b9080SKazutaka YOKOTA video_adapter_t 270617b9080SKazutaka YOKOTA *vid_get_adapter(int index) 271617b9080SKazutaka YOKOTA { 272617b9080SKazutaka YOKOTA if ((index < 0) || (index >= adapters)) 273617b9080SKazutaka YOKOTA return NULL; 274617b9080SKazutaka YOKOTA return adapter[index]; 275617b9080SKazutaka YOKOTA } 276617b9080SKazutaka YOKOTA 277617b9080SKazutaka YOKOTA /* Configure drivers: this is a backdoor for the console driver XXX */ 278617b9080SKazutaka YOKOTA int 279617b9080SKazutaka YOKOTA vid_configure(int flags) 280617b9080SKazutaka YOKOTA { 2816e8394b8SKazutaka YOKOTA const video_driver_t **list; 2826e8394b8SKazutaka YOKOTA const video_driver_t *p; 283617b9080SKazutaka YOKOTA 2846e8394b8SKazutaka YOKOTA list = (const video_driver_t **)videodriver_set.ls_items; 285617b9080SKazutaka YOKOTA while ((p = *list++) != NULL) { 286617b9080SKazutaka YOKOTA if (p->configure != NULL) 287617b9080SKazutaka YOKOTA (*p->configure)(flags); 288617b9080SKazutaka YOKOTA } 289617b9080SKazutaka YOKOTA 290617b9080SKazutaka YOKOTA return 0; 291617b9080SKazutaka YOKOTA } 292617b9080SKazutaka YOKOTA 293617b9080SKazutaka YOKOTA /* 294617b9080SKazutaka YOKOTA * Virtual frame buffer cdev driver functions 295617b9080SKazutaka YOKOTA * The virtual frame buffer driver dispatches driver functions to 296617b9080SKazutaka YOKOTA * appropriate subdrivers. 297617b9080SKazutaka YOKOTA */ 298617b9080SKazutaka YOKOTA 2996e8394b8SKazutaka YOKOTA #define FB_DRIVER_NAME "fb" 300617b9080SKazutaka YOKOTA 301617b9080SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 302617b9080SKazutaka YOKOTA 3036e8394b8SKazutaka YOKOTA #if experimental 3046e8394b8SKazutaka YOKOTA 3056e8394b8SKazutaka YOKOTA static devclass_t fb_devclass; 3066e8394b8SKazutaka YOKOTA 3076e8394b8SKazutaka YOKOTA static int fbprobe(device_t dev); 3086e8394b8SKazutaka YOKOTA static int fbattach(device_t dev); 3096e8394b8SKazutaka YOKOTA 3106e8394b8SKazutaka YOKOTA static device_method_t fb_methods[] = { 3116e8394b8SKazutaka YOKOTA DEVMETHOD(device_probe, fbprobe), 3126e8394b8SKazutaka YOKOTA DEVMETHOD(device_attach, fbattach), 3136e8394b8SKazutaka YOKOTA 3146e8394b8SKazutaka YOKOTA DEVMETHOD(bus_print_child, bus_generic_print_child), 3156e8394b8SKazutaka YOKOTA { 0, 0 } 3166e8394b8SKazutaka YOKOTA }; 3176e8394b8SKazutaka YOKOTA 3186e8394b8SKazutaka YOKOTA static driver_t fb_driver = { 3196e8394b8SKazutaka YOKOTA FB_DRIVER_NAME, 3206e8394b8SKazutaka YOKOTA fb_methods, 3216e8394b8SKazutaka YOKOTA 0, 3226e8394b8SKazutaka YOKOTA }; 3236e8394b8SKazutaka YOKOTA 3246e8394b8SKazutaka YOKOTA static int 3256e8394b8SKazutaka YOKOTA fbprobe(device_t dev) 3266e8394b8SKazutaka YOKOTA { 3276e8394b8SKazutaka YOKOTA int unit; 3286e8394b8SKazutaka YOKOTA 3296e8394b8SKazutaka YOKOTA unit = device_get_unit(dev); 3306e8394b8SKazutaka YOKOTA if (unit >= adapters) 3316e8394b8SKazutaka YOKOTA return ENXIO; 3326e8394b8SKazutaka YOKOTA if (adapter[unit] == NULL) 3336e8394b8SKazutaka YOKOTA return ENXIO; 3346e8394b8SKazutaka YOKOTA 3356e8394b8SKazutaka YOKOTA device_set_desc(dev, "generic frame buffer"); 3366e8394b8SKazutaka YOKOTA return 0; 3376e8394b8SKazutaka YOKOTA } 3386e8394b8SKazutaka YOKOTA 3396e8394b8SKazutaka YOKOTA static int 3406e8394b8SKazutaka YOKOTA fbattach(device_t dev) 3416e8394b8SKazutaka YOKOTA { 3426e8394b8SKazutaka YOKOTA printf("fbattach: about to attach children\n"); 3436e8394b8SKazutaka YOKOTA bus_generic_attach(dev); 3446e8394b8SKazutaka YOKOTA return 0; 3456e8394b8SKazutaka YOKOTA } 3466e8394b8SKazutaka YOKOTA 3476e8394b8SKazutaka YOKOTA #endif /* experimental */ 3486e8394b8SKazutaka YOKOTA 349617b9080SKazutaka YOKOTA #define FB_UNIT(dev) minor(dev) 350617b9080SKazutaka YOKOTA #define FB_MKMINOR(unit) (u) 351617b9080SKazutaka YOKOTA 352617b9080SKazutaka YOKOTA static d_open_t fbopen; 353617b9080SKazutaka YOKOTA static d_close_t fbclose; 3546e8394b8SKazutaka YOKOTA static d_read_t fbread; 3556e8394b8SKazutaka YOKOTA static d_write_t fbwrite; 356617b9080SKazutaka YOKOTA static d_ioctl_t fbioctl; 357617b9080SKazutaka YOKOTA static d_mmap_t fbmmap; 358617b9080SKazutaka YOKOTA 3596e8394b8SKazutaka YOKOTA #define CDEV_MAJOR 123 /* XXX */ 360617b9080SKazutaka YOKOTA 361617b9080SKazutaka YOKOTA static struct cdevsw fb_cdevsw = { 3624e2f199eSPoul-Henning Kamp /* open */ fbopen, 3634e2f199eSPoul-Henning Kamp /* close */ fbclose, 3646e8394b8SKazutaka YOKOTA /* read */ fbread, 3656e8394b8SKazutaka YOKOTA /* write */ fbwrite, 3664e2f199eSPoul-Henning Kamp /* ioctl */ fbioctl, 3674e2f199eSPoul-Henning Kamp /* poll */ nopoll, 3684e2f199eSPoul-Henning Kamp /* mmap */ fbmmap, 3694e2f199eSPoul-Henning Kamp /* strategy */ nostrategy, 3706e8394b8SKazutaka YOKOTA /* name */ FB_DRIVER_NAME, 3714e2f199eSPoul-Henning Kamp /* maj */ CDEV_MAJOR, 3724e2f199eSPoul-Henning Kamp /* dump */ nodump, 3734e2f199eSPoul-Henning Kamp /* psize */ nopsize, 3744e2f199eSPoul-Henning Kamp /* flags */ 0, 3754e2f199eSPoul-Henning Kamp /* bmaj */ -1 376617b9080SKazutaka YOKOTA }; 377617b9080SKazutaka YOKOTA 3782b120974SPeter Wemm 3792b120974SPeter Wemm static int 3802b120974SPeter Wemm fb_modevent(module_t mod, int type, void *data) 381617b9080SKazutaka YOKOTA { 382617b9080SKazutaka YOKOTA 3832b120974SPeter Wemm switch (type) { 3842b120974SPeter Wemm case MOD_LOAD: 3852447bec8SPoul-Henning Kamp cdevsw_add(&fb_cdevsw); 3862b120974SPeter Wemm break; 3872b120974SPeter Wemm case MOD_UNLOAD: 3882b120974SPeter Wemm printf("fb module unload - not possible for this module type\n"); 3892b120974SPeter Wemm return EINVAL; 390617b9080SKazutaka YOKOTA } 3912b120974SPeter Wemm return 0; 392617b9080SKazutaka YOKOTA } 393617b9080SKazutaka YOKOTA 3942b120974SPeter Wemm static moduledata_t fb_mod = { 3952b120974SPeter Wemm "fb", 3962b120974SPeter Wemm fb_modevent, 3972b120974SPeter Wemm NULL 3982b120974SPeter Wemm }; 3992b120974SPeter Wemm 4002b120974SPeter Wemm DECLARE_MODULE(fb, fb_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 401617b9080SKazutaka YOKOTA 402617b9080SKazutaka YOKOTA int 4036e8394b8SKazutaka YOKOTA fb_attach(dev_t dev, video_adapter_t *adp, struct cdevsw *cdevsw) 404617b9080SKazutaka YOKOTA { 405617b9080SKazutaka YOKOTA int s; 406617b9080SKazutaka YOKOTA 407617b9080SKazutaka YOKOTA if (adp->va_index >= adapters) 408617b9080SKazutaka YOKOTA return EINVAL; 409617b9080SKazutaka YOKOTA if (adapter[adp->va_index] != adp) 410617b9080SKazutaka YOKOTA return EINVAL; 411617b9080SKazutaka YOKOTA 412617b9080SKazutaka YOKOTA s = spltty(); 413617b9080SKazutaka YOKOTA adp->va_minor = minor(dev); 414617b9080SKazutaka YOKOTA vidcdevsw[adp->va_index] = cdevsw; 415617b9080SKazutaka YOKOTA splx(s); 416617b9080SKazutaka YOKOTA 417617b9080SKazutaka YOKOTA printf("fb%d at %s%d\n", adp->va_index, adp->va_name, adp->va_unit); 418617b9080SKazutaka YOKOTA return 0; 419617b9080SKazutaka YOKOTA } 420617b9080SKazutaka YOKOTA 421617b9080SKazutaka YOKOTA int 4226e8394b8SKazutaka YOKOTA fb_detach(dev_t dev, video_adapter_t *adp, struct cdevsw *cdevsw) 423617b9080SKazutaka YOKOTA { 424617b9080SKazutaka YOKOTA int s; 425617b9080SKazutaka YOKOTA 426617b9080SKazutaka YOKOTA if (adp->va_index >= adapters) 427617b9080SKazutaka YOKOTA return EINVAL; 428617b9080SKazutaka YOKOTA if (adapter[adp->va_index] != adp) 429617b9080SKazutaka YOKOTA return EINVAL; 430617b9080SKazutaka YOKOTA if (vidcdevsw[adp->va_index] != cdevsw) 431617b9080SKazutaka YOKOTA return EINVAL; 432617b9080SKazutaka YOKOTA 433617b9080SKazutaka YOKOTA s = spltty(); 434617b9080SKazutaka YOKOTA vidcdevsw[adp->va_index] = NULL; 435617b9080SKazutaka YOKOTA splx(s); 436617b9080SKazutaka YOKOTA return 0; 437617b9080SKazutaka YOKOTA } 438617b9080SKazutaka YOKOTA 4396e8394b8SKazutaka YOKOTA static int 4406e8394b8SKazutaka YOKOTA fbopen(dev_t dev, int flag, int mode, struct proc *p) 4416e8394b8SKazutaka YOKOTA { 4426e8394b8SKazutaka YOKOTA int unit; 4436e8394b8SKazutaka YOKOTA 4446e8394b8SKazutaka YOKOTA unit = FB_UNIT(dev); 4456e8394b8SKazutaka YOKOTA if (unit >= adapters) 4466e8394b8SKazutaka YOKOTA return ENXIO; 4476e8394b8SKazutaka YOKOTA if (vidcdevsw[unit] == NULL) 4486e8394b8SKazutaka YOKOTA return ENXIO; 4496e8394b8SKazutaka YOKOTA return (*vidcdevsw[unit]->d_open)(makedev(0, adapter[unit]->va_minor), 4506e8394b8SKazutaka YOKOTA flag, mode, p); 4516e8394b8SKazutaka YOKOTA } 4526e8394b8SKazutaka YOKOTA 4536e8394b8SKazutaka YOKOTA static int 4546e8394b8SKazutaka YOKOTA fbclose(dev_t dev, int flag, int mode, struct proc *p) 4556e8394b8SKazutaka YOKOTA { 4566e8394b8SKazutaka YOKOTA int unit; 4576e8394b8SKazutaka YOKOTA 4586e8394b8SKazutaka YOKOTA unit = FB_UNIT(dev); 4596e8394b8SKazutaka YOKOTA if (vidcdevsw[unit] == NULL) 4606e8394b8SKazutaka YOKOTA return ENXIO; 4616e8394b8SKazutaka YOKOTA return (*vidcdevsw[unit]->d_close)(makedev(0, adapter[unit]->va_minor), 4626e8394b8SKazutaka YOKOTA flag, mode, p); 4636e8394b8SKazutaka YOKOTA } 4646e8394b8SKazutaka YOKOTA 4656e8394b8SKazutaka YOKOTA static int 4666e8394b8SKazutaka YOKOTA fbread(dev_t dev, struct uio *uio, int flag) 4676e8394b8SKazutaka YOKOTA { 4686e8394b8SKazutaka YOKOTA int unit; 4696e8394b8SKazutaka YOKOTA 4706e8394b8SKazutaka YOKOTA unit = FB_UNIT(dev); 4716e8394b8SKazutaka YOKOTA if (vidcdevsw[unit] == NULL) 4726e8394b8SKazutaka YOKOTA return ENXIO; 4736e8394b8SKazutaka YOKOTA return (*vidcdevsw[unit]->d_read)(makedev(0, adapter[unit]->va_minor), 4746e8394b8SKazutaka YOKOTA uio, flag); 4756e8394b8SKazutaka YOKOTA } 4766e8394b8SKazutaka YOKOTA 4776e8394b8SKazutaka YOKOTA static int 4786e8394b8SKazutaka YOKOTA fbwrite(dev_t dev, struct uio *uio, int flag) 4796e8394b8SKazutaka YOKOTA { 4806e8394b8SKazutaka YOKOTA int unit; 4816e8394b8SKazutaka YOKOTA 4826e8394b8SKazutaka YOKOTA unit = FB_UNIT(dev); 4836e8394b8SKazutaka YOKOTA if (vidcdevsw[unit] == NULL) 4846e8394b8SKazutaka YOKOTA return ENXIO; 4856e8394b8SKazutaka YOKOTA return (*vidcdevsw[unit]->d_write)(makedev(0, adapter[unit]->va_minor), 4866e8394b8SKazutaka YOKOTA uio, flag); 4876e8394b8SKazutaka YOKOTA } 4886e8394b8SKazutaka YOKOTA 4896e8394b8SKazutaka YOKOTA static int 4906e8394b8SKazutaka YOKOTA fbioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p) 4916e8394b8SKazutaka YOKOTA { 4926e8394b8SKazutaka YOKOTA int unit; 4936e8394b8SKazutaka YOKOTA 4946e8394b8SKazutaka YOKOTA unit = FB_UNIT(dev); 4956e8394b8SKazutaka YOKOTA if (vidcdevsw[unit] == NULL) 4966e8394b8SKazutaka YOKOTA return ENXIO; 4976e8394b8SKazutaka YOKOTA return (*vidcdevsw[unit]->d_ioctl)(makedev(0, adapter[unit]->va_minor), 4986e8394b8SKazutaka YOKOTA cmd, arg, flag, p); 4996e8394b8SKazutaka YOKOTA } 5006e8394b8SKazutaka YOKOTA 5016e8394b8SKazutaka YOKOTA static int 5026e8394b8SKazutaka YOKOTA fbmmap(dev_t dev, vm_offset_t offset, int nprot) 5036e8394b8SKazutaka YOKOTA { 5046e8394b8SKazutaka YOKOTA int unit; 5056e8394b8SKazutaka YOKOTA 5066e8394b8SKazutaka YOKOTA unit = FB_UNIT(dev); 5076e8394b8SKazutaka YOKOTA if (vidcdevsw[unit] == NULL) 5086e8394b8SKazutaka YOKOTA return ENXIO; 5096e8394b8SKazutaka YOKOTA return (*vidcdevsw[unit]->d_mmap)(makedev(0, adapter[unit]->va_minor), 5106e8394b8SKazutaka YOKOTA offset, nprot); 5116e8394b8SKazutaka YOKOTA } 5126e8394b8SKazutaka YOKOTA 5136e8394b8SKazutaka YOKOTA #if experimental 51403016f42SPoul-Henning Kamp DEV_DRIVER_MODULE(fb, ???, fb_driver, fb_devclass, fb_cdevsw, 0, 0); 5156e8394b8SKazutaka YOKOTA #endif 5166e8394b8SKazutaka YOKOTA 5176e8394b8SKazutaka YOKOTA /* 5186e8394b8SKazutaka YOKOTA * Generic frame buffer cdev driver functions 5196e8394b8SKazutaka YOKOTA * Frame buffer subdrivers may call these functions to implement common 5206e8394b8SKazutaka YOKOTA * driver functions. 5216e8394b8SKazutaka YOKOTA */ 5226e8394b8SKazutaka YOKOTA 5236e8394b8SKazutaka YOKOTA int genfbopen(genfb_softc_t *sc, video_adapter_t *adp, int flag, int mode, 5246e8394b8SKazutaka YOKOTA struct proc *p) 5256e8394b8SKazutaka YOKOTA { 5266e8394b8SKazutaka YOKOTA int s; 5276e8394b8SKazutaka YOKOTA 5286e8394b8SKazutaka YOKOTA s = spltty(); 5296e8394b8SKazutaka YOKOTA if (!(sc->gfb_flags & FB_OPEN)) 5306e8394b8SKazutaka YOKOTA sc->gfb_flags |= FB_OPEN; 5316e8394b8SKazutaka YOKOTA splx(s); 5326e8394b8SKazutaka YOKOTA return 0; 5336e8394b8SKazutaka YOKOTA } 5346e8394b8SKazutaka YOKOTA 5356e8394b8SKazutaka YOKOTA int genfbclose(genfb_softc_t *sc, video_adapter_t *adp, int flag, int mode, 5366e8394b8SKazutaka YOKOTA struct proc *p) 5376e8394b8SKazutaka YOKOTA { 5386e8394b8SKazutaka YOKOTA int s; 5396e8394b8SKazutaka YOKOTA 5406e8394b8SKazutaka YOKOTA s = spltty(); 5416e8394b8SKazutaka YOKOTA sc->gfb_flags &= ~FB_OPEN; 5426e8394b8SKazutaka YOKOTA splx(s); 5436e8394b8SKazutaka YOKOTA return 0; 5446e8394b8SKazutaka YOKOTA } 5456e8394b8SKazutaka YOKOTA 5466e8394b8SKazutaka YOKOTA int genfbread(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio, 5476e8394b8SKazutaka YOKOTA int flag) 5486e8394b8SKazutaka YOKOTA { 5496e8394b8SKazutaka YOKOTA int size; 5506e8394b8SKazutaka YOKOTA int offset; 5516e8394b8SKazutaka YOKOTA int error; 5526e8394b8SKazutaka YOKOTA int len; 5536e8394b8SKazutaka YOKOTA 5546e8394b8SKazutaka YOKOTA error = 0; 5556e8394b8SKazutaka YOKOTA size = adp->va_buffer_size/adp->va_info.vi_planes; 5566e8394b8SKazutaka YOKOTA while (uio->uio_resid > 0) { 5576e8394b8SKazutaka YOKOTA if (uio->uio_offset >= size) 5586e8394b8SKazutaka YOKOTA break; 5596e8394b8SKazutaka YOKOTA offset = uio->uio_offset%adp->va_window_size; 5606e8394b8SKazutaka YOKOTA len = imin(uio->uio_resid, size - uio->uio_offset); 5616e8394b8SKazutaka YOKOTA len = imin(len, adp->va_window_size - offset); 5626e8394b8SKazutaka YOKOTA if (len <= 0) 5636e8394b8SKazutaka YOKOTA break; 5646e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, uio->uio_offset); 5656e8394b8SKazutaka YOKOTA error = uiomove((caddr_t)(adp->va_window + offset), len, uio); 5666e8394b8SKazutaka YOKOTA if (error) 5676e8394b8SKazutaka YOKOTA break; 5686e8394b8SKazutaka YOKOTA } 5696e8394b8SKazutaka YOKOTA return error; 5706e8394b8SKazutaka YOKOTA } 5716e8394b8SKazutaka YOKOTA 5726e8394b8SKazutaka YOKOTA int genfbwrite(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio, 5736e8394b8SKazutaka YOKOTA int flag) 5746e8394b8SKazutaka YOKOTA { 5756e8394b8SKazutaka YOKOTA return ENODEV; 5766e8394b8SKazutaka YOKOTA } 5776e8394b8SKazutaka YOKOTA 5786e8394b8SKazutaka YOKOTA int genfbioctl(genfb_softc_t *sc, video_adapter_t *adp, u_long cmd, 5796e8394b8SKazutaka YOKOTA caddr_t arg, int flag, struct proc *p) 5806e8394b8SKazutaka YOKOTA { 5816e8394b8SKazutaka YOKOTA int error; 5826e8394b8SKazutaka YOKOTA 5836e8394b8SKazutaka YOKOTA if (adp == NULL) /* XXX */ 5846e8394b8SKazutaka YOKOTA return ENXIO; 5856e8394b8SKazutaka YOKOTA error = (*vidsw[adp->va_index]->ioctl)(adp, cmd, arg); 5866e8394b8SKazutaka YOKOTA if (error == ENOIOCTL) 5876e8394b8SKazutaka YOKOTA error = ENODEV; 5886e8394b8SKazutaka YOKOTA return error; 5896e8394b8SKazutaka YOKOTA } 5906e8394b8SKazutaka YOKOTA 5916e8394b8SKazutaka YOKOTA int genfbmmap(genfb_softc_t *sc, video_adapter_t *adp, vm_offset_t offset, 5926e8394b8SKazutaka YOKOTA int prot) 5936e8394b8SKazutaka YOKOTA { 5946e8394b8SKazutaka YOKOTA return (*vidsw[adp->va_index]->mmap)(adp, offset, prot); 5956e8394b8SKazutaka YOKOTA } 5966e8394b8SKazutaka YOKOTA 597617b9080SKazutaka YOKOTA #endif /* FB_INSTALL_CDEV */ 598617b9080SKazutaka YOKOTA 599617b9080SKazutaka YOKOTA static char 600617b9080SKazutaka YOKOTA *adapter_name(int type) 601617b9080SKazutaka YOKOTA { 602617b9080SKazutaka YOKOTA static struct { 603617b9080SKazutaka YOKOTA int type; 604617b9080SKazutaka YOKOTA char *name; 605617b9080SKazutaka YOKOTA } names[] = { 606617b9080SKazutaka YOKOTA { KD_MONO, "MDA" }, 607617b9080SKazutaka YOKOTA { KD_HERCULES, "Hercules" }, 608617b9080SKazutaka YOKOTA { KD_CGA, "CGA" }, 609617b9080SKazutaka YOKOTA { KD_EGA, "EGA" }, 610617b9080SKazutaka YOKOTA { KD_VGA, "VGA" }, 611617b9080SKazutaka YOKOTA { KD_PC98, "PC-98x1" }, 6126e8394b8SKazutaka YOKOTA { KD_TGA, "TGA" }, 613617b9080SKazutaka YOKOTA { -1, "Unknown" }, 614617b9080SKazutaka YOKOTA }; 615617b9080SKazutaka YOKOTA int i; 616617b9080SKazutaka YOKOTA 617617b9080SKazutaka YOKOTA for (i = 0; names[i].type != -1; ++i) 618617b9080SKazutaka YOKOTA if (names[i].type == type) 619617b9080SKazutaka YOKOTA break; 620617b9080SKazutaka YOKOTA return names[i].name; 621617b9080SKazutaka YOKOTA } 622617b9080SKazutaka YOKOTA 6236e8394b8SKazutaka YOKOTA /* 6246e8394b8SKazutaka YOKOTA * Generic low-level frame buffer functions 6256e8394b8SKazutaka YOKOTA * The low-level functions in the frame buffer subdriver may use these 6266e8394b8SKazutaka YOKOTA * functions. 6276e8394b8SKazutaka YOKOTA */ 6286e8394b8SKazutaka YOKOTA 629617b9080SKazutaka YOKOTA void 630617b9080SKazutaka YOKOTA fb_dump_adp_info(char *driver, video_adapter_t *adp, int level) 631617b9080SKazutaka YOKOTA { 632617b9080SKazutaka YOKOTA if (level <= 0) 633617b9080SKazutaka YOKOTA return; 634617b9080SKazutaka YOKOTA 635617b9080SKazutaka YOKOTA printf("%s%d: %s%d, %s, type:%s (%d), flags:0x%x\n", 6366e8394b8SKazutaka YOKOTA FB_DRIVER_NAME, adp->va_index, driver, adp->va_unit, adp->va_name, 637617b9080SKazutaka YOKOTA adapter_name(adp->va_type), adp->va_type, adp->va_flags); 638617b9080SKazutaka YOKOTA printf("%s%d: port:0x%x-0x%x, crtc:0x%x, mem:0x%x 0x%x\n", 6396e8394b8SKazutaka YOKOTA FB_DRIVER_NAME, adp->va_index, 640617b9080SKazutaka YOKOTA adp->va_io_base, adp->va_io_base + adp->va_io_size - 1, 641617b9080SKazutaka YOKOTA adp->va_crtc_addr, adp->va_mem_base, adp->va_mem_size); 642617b9080SKazutaka YOKOTA printf("%s%d: init mode:%d, bios mode:%d, current mode:%d\n", 6436e8394b8SKazutaka YOKOTA FB_DRIVER_NAME, adp->va_index, 644617b9080SKazutaka YOKOTA adp->va_initial_mode, adp->va_initial_bios_mode, adp->va_mode); 6456e8394b8SKazutaka YOKOTA printf("%s%d: window:%p size:%dk gran:%dk, buf:%p size:%dk\n", 6466e8394b8SKazutaka YOKOTA FB_DRIVER_NAME, adp->va_index, 6476e8394b8SKazutaka YOKOTA (void *)adp->va_window, (int)adp->va_window_size/1024, 6486e8394b8SKazutaka YOKOTA (int)adp->va_window_gran/1024, (void *)adp->va_buffer, 649f359876fSKazutaka YOKOTA (int)adp->va_buffer_size/1024); 650617b9080SKazutaka YOKOTA } 651617b9080SKazutaka YOKOTA 652617b9080SKazutaka YOKOTA void 653617b9080SKazutaka YOKOTA fb_dump_mode_info(char *driver, video_adapter_t *adp, video_info_t *info, 654617b9080SKazutaka YOKOTA int level) 655617b9080SKazutaka YOKOTA { 656617b9080SKazutaka YOKOTA if (level <= 0) 657617b9080SKazutaka YOKOTA return; 658617b9080SKazutaka YOKOTA 659617b9080SKazutaka YOKOTA printf("%s%d: %s, mode:%d, flags:0x%x ", 660617b9080SKazutaka YOKOTA driver, adp->va_unit, adp->va_name, info->vi_mode, info->vi_flags); 661617b9080SKazutaka YOKOTA if (info->vi_flags & V_INFO_GRAPHICS) 662617b9080SKazutaka YOKOTA printf("G %dx%dx%d, %d plane(s), font:%dx%d, ", 663617b9080SKazutaka YOKOTA info->vi_width, info->vi_height, 664617b9080SKazutaka YOKOTA info->vi_depth, info->vi_planes, 665617b9080SKazutaka YOKOTA info->vi_cwidth, info->vi_cheight); 666617b9080SKazutaka YOKOTA else 667617b9080SKazutaka YOKOTA printf("T %dx%d, font:%dx%d, ", 668617b9080SKazutaka YOKOTA info->vi_width, info->vi_height, 669617b9080SKazutaka YOKOTA info->vi_cwidth, info->vi_cheight); 670617b9080SKazutaka YOKOTA printf("win:0x%x\n", info->vi_window); 671617b9080SKazutaka YOKOTA } 6726e8394b8SKazutaka YOKOTA 6736e8394b8SKazutaka YOKOTA int 6746e8394b8SKazutaka YOKOTA fb_type(int adp_type) 6756e8394b8SKazutaka YOKOTA { 6766e8394b8SKazutaka YOKOTA static struct { 6776e8394b8SKazutaka YOKOTA int fb_type; 6786e8394b8SKazutaka YOKOTA int va_type; 6796e8394b8SKazutaka YOKOTA } types[] = { 6806e8394b8SKazutaka YOKOTA { FBTYPE_MDA, KD_MONO }, 6816e8394b8SKazutaka YOKOTA { FBTYPE_HERCULES, KD_HERCULES }, 6826e8394b8SKazutaka YOKOTA { FBTYPE_CGA, KD_CGA }, 6836e8394b8SKazutaka YOKOTA { FBTYPE_EGA, KD_EGA }, 6846e8394b8SKazutaka YOKOTA { FBTYPE_VGA, KD_VGA }, 6856e8394b8SKazutaka YOKOTA { FBTYPE_PC98, KD_PC98 }, 6866e8394b8SKazutaka YOKOTA { FBTYPE_TGA, KD_TGA }, 6876e8394b8SKazutaka YOKOTA }; 6886e8394b8SKazutaka YOKOTA int i; 6896e8394b8SKazutaka YOKOTA 6906e8394b8SKazutaka YOKOTA for (i = 0; i < sizeof(types)/sizeof(types[0]); ++i) { 6916e8394b8SKazutaka YOKOTA if (types[i].va_type == adp_type) 6926e8394b8SKazutaka YOKOTA return types[i].fb_type; 6936e8394b8SKazutaka YOKOTA } 6946e8394b8SKazutaka YOKOTA return -1; 6956e8394b8SKazutaka YOKOTA } 6966e8394b8SKazutaka YOKOTA 6976e8394b8SKazutaka YOKOTA int 6986e8394b8SKazutaka YOKOTA fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) 6996e8394b8SKazutaka YOKOTA { 7006e8394b8SKazutaka YOKOTA int error; 7016e8394b8SKazutaka YOKOTA int s; 7026e8394b8SKazutaka YOKOTA 7036e8394b8SKazutaka YOKOTA /* assert(adp != NULL) */ 7046e8394b8SKazutaka YOKOTA 7056e8394b8SKazutaka YOKOTA error = 0; 7066e8394b8SKazutaka YOKOTA s = spltty(); 7076e8394b8SKazutaka YOKOTA 7086e8394b8SKazutaka YOKOTA switch (cmd) { 7096e8394b8SKazutaka YOKOTA 7106e8394b8SKazutaka YOKOTA case FBIO_ADAPTER: /* get video adapter index */ 7116e8394b8SKazutaka YOKOTA *(int *)arg = adp->va_index; 7126e8394b8SKazutaka YOKOTA break; 7136e8394b8SKazutaka YOKOTA 7146e8394b8SKazutaka YOKOTA case FBIO_ADPTYPE: /* get video adapter type */ 7156e8394b8SKazutaka YOKOTA *(int *)arg = adp->va_type; 7166e8394b8SKazutaka YOKOTA break; 7176e8394b8SKazutaka YOKOTA 7186e8394b8SKazutaka YOKOTA case FBIO_ADPINFO: /* get video adapter info */ 7196e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_index = adp->va_index; 7206e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_type = adp->va_type; 7216e8394b8SKazutaka YOKOTA bcopy(adp->va_name, ((video_adapter_info_t *)arg)->va_name, 7226e8394b8SKazutaka YOKOTA imin(strlen(adp->va_name) + 1, 7236e8394b8SKazutaka YOKOTA sizeof(((video_adapter_info_t *)arg)->va_name))); 7246e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_unit = adp->va_unit; 7256e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_flags = adp->va_flags; 7266e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_io_base = adp->va_io_base; 7276e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_io_size = adp->va_io_size; 7286e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_crtc_addr = adp->va_crtc_addr; 7296e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_mem_base = adp->va_mem_base; 7306e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_mem_size = adp->va_mem_size; 7316e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_window 7322727ed91SAndrew Gallatin #ifdef __i386__ 7336e8394b8SKazutaka YOKOTA = vtophys(adp->va_window); 7342727ed91SAndrew Gallatin #else 7352727ed91SAndrew Gallatin = adp->va_window; 7362727ed91SAndrew Gallatin #endif 7376e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_window_size 7386e8394b8SKazutaka YOKOTA = adp->va_window_size; 7396e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_window_gran 7406e8394b8SKazutaka YOKOTA = adp->va_window_gran; 7416e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_window_orig 7426e8394b8SKazutaka YOKOTA = adp->va_window_orig; 7436e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_unused0 7442727ed91SAndrew Gallatin #ifdef __i386__ 7456e8394b8SKazutaka YOKOTA = (adp->va_buffer) ? vtophys(adp->va_buffer) : 0; 7462727ed91SAndrew Gallatin #else 7472727ed91SAndrew Gallatin = adp->va_buffer; 7482727ed91SAndrew Gallatin #endif 7496e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_buffer_size 7506e8394b8SKazutaka YOKOTA = adp->va_buffer_size; 7516e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_mode = adp->va_mode; 7526e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_initial_mode 7536e8394b8SKazutaka YOKOTA = adp->va_initial_mode; 7546e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_initial_bios_mode 7556e8394b8SKazutaka YOKOTA = adp->va_initial_bios_mode; 7566e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_line_width 7576e8394b8SKazutaka YOKOTA = adp->va_line_width; 7586e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_disp_start.x 7596e8394b8SKazutaka YOKOTA = adp->va_disp_start.x; 7606e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_disp_start.y 7616e8394b8SKazutaka YOKOTA = adp->va_disp_start.y; 7626e8394b8SKazutaka YOKOTA break; 7636e8394b8SKazutaka YOKOTA 7646e8394b8SKazutaka YOKOTA case FBIO_MODEINFO: /* get mode information */ 7656e8394b8SKazutaka YOKOTA error = (*vidsw[adp->va_index]->get_info)(adp, 7666e8394b8SKazutaka YOKOTA ((video_info_t *)arg)->vi_mode, 7676e8394b8SKazutaka YOKOTA (video_info_t *)arg); 7686e8394b8SKazutaka YOKOTA if (error) 7696e8394b8SKazutaka YOKOTA error = ENODEV; 7706e8394b8SKazutaka YOKOTA break; 7716e8394b8SKazutaka YOKOTA 7726e8394b8SKazutaka YOKOTA case FBIO_FINDMODE: /* find a matching video mode */ 7736e8394b8SKazutaka YOKOTA error = (*vidsw[adp->va_index]->query_mode)(adp, 7746e8394b8SKazutaka YOKOTA (video_info_t *)arg); 7756e8394b8SKazutaka YOKOTA break; 7766e8394b8SKazutaka YOKOTA 7776e8394b8SKazutaka YOKOTA case FBIO_GETMODE: /* get video mode */ 7786e8394b8SKazutaka YOKOTA *(int *)arg = adp->va_mode; 7796e8394b8SKazutaka YOKOTA break; 7806e8394b8SKazutaka YOKOTA 7816e8394b8SKazutaka YOKOTA case FBIO_SETMODE: /* set video mode */ 7826e8394b8SKazutaka YOKOTA error = (*vidsw[adp->va_index]->set_mode)(adp, *(int *)arg); 7836e8394b8SKazutaka YOKOTA if (error) 7846e8394b8SKazutaka YOKOTA error = ENODEV; /* EINVAL? */ 7856e8394b8SKazutaka YOKOTA break; 7866e8394b8SKazutaka YOKOTA 7876e8394b8SKazutaka YOKOTA case FBIO_GETWINORG: /* get frame buffer window origin */ 7886e8394b8SKazutaka YOKOTA *(u_int *)arg = adp->va_window_orig; 7896e8394b8SKazutaka YOKOTA break; 7906e8394b8SKazutaka YOKOTA 7916e8394b8SKazutaka YOKOTA case FBIO_GETDISPSTART: /* get display start address */ 7926e8394b8SKazutaka YOKOTA ((video_display_start_t *)arg)->x = adp->va_disp_start.x; 7936e8394b8SKazutaka YOKOTA ((video_display_start_t *)arg)->y = adp->va_disp_start.y; 7946e8394b8SKazutaka YOKOTA break; 7956e8394b8SKazutaka YOKOTA 7966e8394b8SKazutaka YOKOTA case FBIO_GETLINEWIDTH: /* get scan line width in bytes */ 7976e8394b8SKazutaka YOKOTA *(u_int *)arg = adp->va_line_width; 7986e8394b8SKazutaka YOKOTA break; 7996e8394b8SKazutaka YOKOTA 8006e8394b8SKazutaka YOKOTA case FBIO_GETPALETTE: /* get color palette */ 8016e8394b8SKazutaka YOKOTA case FBIO_SETPALETTE: /* set color palette */ 8026e8394b8SKazutaka YOKOTA /* XXX */ 8036e8394b8SKazutaka YOKOTA 8046e8394b8SKazutaka YOKOTA case FBIOPUTCMAP: 8056e8394b8SKazutaka YOKOTA case FBIOGETCMAP: 8066e8394b8SKazutaka YOKOTA /* XXX */ 8076e8394b8SKazutaka YOKOTA 8086e8394b8SKazutaka YOKOTA case FBIO_SETWINORG: /* set frame buffer window origin */ 8096e8394b8SKazutaka YOKOTA case FBIO_SETDISPSTART: /* set display start address */ 8106e8394b8SKazutaka YOKOTA case FBIO_SETLINEWIDTH: /* set scan line width in pixel */ 8116e8394b8SKazutaka YOKOTA 8126e8394b8SKazutaka YOKOTA case FBIOGTYPE: 8136e8394b8SKazutaka YOKOTA case FBIOGATTR: 8146e8394b8SKazutaka YOKOTA case FBIOSVIDEO: 8156e8394b8SKazutaka YOKOTA case FBIOGVIDEO: 8166e8394b8SKazutaka YOKOTA case FBIOSCURSOR: 8176e8394b8SKazutaka YOKOTA case FBIOGCURSOR: 8186e8394b8SKazutaka YOKOTA case FBIOSCURPOS: 8196e8394b8SKazutaka YOKOTA case FBIOGCURPOS: 8206e8394b8SKazutaka YOKOTA case FBIOGCURMAX: 8216e8394b8SKazutaka YOKOTA 8226e8394b8SKazutaka YOKOTA default: 8236e8394b8SKazutaka YOKOTA error = ENODEV; 8246e8394b8SKazutaka YOKOTA break; 8256e8394b8SKazutaka YOKOTA } 8266e8394b8SKazutaka YOKOTA 8276e8394b8SKazutaka YOKOTA splx(s); 8286e8394b8SKazutaka YOKOTA return error; 8296e8394b8SKazutaka YOKOTA } 830