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> 42f41325dbSPeter Wemm #include <sys/linker_set.h> 43617b9080SKazutaka YOKOTA 446e8394b8SKazutaka YOKOTA #include <vm/vm.h> 456e8394b8SKazutaka YOKOTA #include <vm/pmap.h> 46617b9080SKazutaka YOKOTA 47617b9080SKazutaka YOKOTA #include <dev/fb/fbreg.h> 48617b9080SKazutaka YOKOTA 49f41325dbSPeter Wemm SET_DECLARE(videodriver_set, const video_driver_t); 50f41325dbSPeter Wemm 51617b9080SKazutaka YOKOTA /* local arrays */ 52617b9080SKazutaka YOKOTA 53617b9080SKazutaka YOKOTA /* 54617b9080SKazutaka YOKOTA * We need at least one entry each in order to initialize a video card 55617b9080SKazutaka YOKOTA * for the kernel console. The arrays will be increased dynamically 56617b9080SKazutaka YOKOTA * when necessary. 57617b9080SKazutaka YOKOTA */ 58617b9080SKazutaka YOKOTA 596e8394b8SKazutaka YOKOTA static int vid_malloc; 60617b9080SKazutaka YOKOTA static int adapters = 1; 6190500a9dSKazutaka YOKOTA static video_adapter_t *adp_ini; 6290500a9dSKazutaka YOKOTA static video_adapter_t **adapter = &adp_ini; 6390500a9dSKazutaka YOKOTA static video_switch_t *vidsw_ini; 64617b9080SKazutaka YOKOTA video_switch_t **vidsw = &vidsw_ini; 6590500a9dSKazutaka YOKOTA 6690500a9dSKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 676e8394b8SKazutaka YOKOTA static struct cdevsw *vidcdevsw_ini; 686e8394b8SKazutaka YOKOTA static struct cdevsw **vidcdevsw = &vidcdevsw_ini; 696e8394b8SKazutaka YOKOTA #endif 70617b9080SKazutaka YOKOTA 71617b9080SKazutaka YOKOTA #define ARRAY_DELTA 4 72617b9080SKazutaka YOKOTA 736e8394b8SKazutaka YOKOTA static int 74617b9080SKazutaka YOKOTA vid_realloc_array(void) 75617b9080SKazutaka YOKOTA { 76617b9080SKazutaka YOKOTA video_adapter_t **new_adp; 77617b9080SKazutaka YOKOTA video_switch_t **new_vidsw; 786e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 79617b9080SKazutaka YOKOTA struct cdevsw **new_cdevsw; 806e8394b8SKazutaka YOKOTA #endif 81617b9080SKazutaka YOKOTA int newsize; 82617b9080SKazutaka YOKOTA int s; 83617b9080SKazutaka YOKOTA 846e8394b8SKazutaka YOKOTA if (!vid_malloc) 856e8394b8SKazutaka YOKOTA return ENOMEM; 866e8394b8SKazutaka YOKOTA 87617b9080SKazutaka YOKOTA s = spltty(); 88617b9080SKazutaka YOKOTA newsize = ((adapters + ARRAY_DELTA)/ARRAY_DELTA)*ARRAY_DELTA; 89a163d034SWarner Losh new_adp = malloc(sizeof(*new_adp)*newsize, M_DEVBUF, M_WAITOK | M_ZERO); 907cc0979fSDavid Malone new_vidsw = malloc(sizeof(*new_vidsw)*newsize, M_DEVBUF, 91a163d034SWarner Losh M_WAITOK | M_ZERO); 926e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 937cc0979fSDavid Malone new_cdevsw = malloc(sizeof(*new_cdevsw)*newsize, M_DEVBUF, 94a163d034SWarner Losh M_WAITOK | M_ZERO); 956e8394b8SKazutaka YOKOTA #endif 96617b9080SKazutaka YOKOTA bcopy(adapter, new_adp, sizeof(*adapter)*adapters); 97617b9080SKazutaka YOKOTA bcopy(vidsw, new_vidsw, sizeof(*vidsw)*adapters); 986e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 99617b9080SKazutaka YOKOTA bcopy(vidcdevsw, new_cdevsw, sizeof(*vidcdevsw)*adapters); 1006e8394b8SKazutaka YOKOTA #endif 101617b9080SKazutaka YOKOTA if (adapters > 1) { 102617b9080SKazutaka YOKOTA free(adapter, M_DEVBUF); 103617b9080SKazutaka YOKOTA free(vidsw, M_DEVBUF); 1046e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 105617b9080SKazutaka YOKOTA free(vidcdevsw, M_DEVBUF); 1066e8394b8SKazutaka YOKOTA #endif 107617b9080SKazutaka YOKOTA } 108617b9080SKazutaka YOKOTA adapter = new_adp; 109617b9080SKazutaka YOKOTA vidsw = new_vidsw; 1106e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 111617b9080SKazutaka YOKOTA vidcdevsw = new_cdevsw; 1126e8394b8SKazutaka YOKOTA #endif 113617b9080SKazutaka YOKOTA adapters = newsize; 114617b9080SKazutaka YOKOTA splx(s); 115617b9080SKazutaka YOKOTA 116617b9080SKazutaka YOKOTA if (bootverbose) 117617b9080SKazutaka YOKOTA printf("fb: new array size %d\n", adapters); 1186e8394b8SKazutaka YOKOTA 1196e8394b8SKazutaka YOKOTA return 0; 120617b9080SKazutaka YOKOTA } 121617b9080SKazutaka YOKOTA 1226e8394b8SKazutaka YOKOTA static void 1236e8394b8SKazutaka YOKOTA vid_malloc_init(void *arg) 1246e8394b8SKazutaka YOKOTA { 1256e8394b8SKazutaka YOKOTA vid_malloc = TRUE; 1266e8394b8SKazutaka YOKOTA } 1276e8394b8SKazutaka YOKOTA 1286e8394b8SKazutaka YOKOTA SYSINIT(vid_mem, SI_SUB_KMEM, SI_ORDER_ANY, vid_malloc_init, NULL); 12990500a9dSKazutaka YOKOTA 130617b9080SKazutaka YOKOTA /* 131617b9080SKazutaka YOKOTA * Low-level frame buffer driver functions 132617b9080SKazutaka YOKOTA * frame buffer subdrivers, such as the VGA driver, call these functions 133617b9080SKazutaka YOKOTA * to initialize the video_adapter structure and register it to the virtual 134617b9080SKazutaka YOKOTA * frame buffer driver `fb'. 135617b9080SKazutaka YOKOTA */ 136617b9080SKazutaka YOKOTA 137617b9080SKazutaka YOKOTA /* initialize the video_adapter_t structure */ 138617b9080SKazutaka YOKOTA void 139617b9080SKazutaka YOKOTA vid_init_struct(video_adapter_t *adp, char *name, int type, int unit) 140617b9080SKazutaka YOKOTA { 141617b9080SKazutaka YOKOTA adp->va_flags = 0; 142617b9080SKazutaka YOKOTA adp->va_name = name; 143617b9080SKazutaka YOKOTA adp->va_type = type; 144617b9080SKazutaka YOKOTA adp->va_unit = unit; 145617b9080SKazutaka YOKOTA } 146617b9080SKazutaka YOKOTA 147617b9080SKazutaka YOKOTA /* Register a video adapter */ 148617b9080SKazutaka YOKOTA int 149617b9080SKazutaka YOKOTA vid_register(video_adapter_t *adp) 150617b9080SKazutaka YOKOTA { 1516e8394b8SKazutaka YOKOTA const video_driver_t **list; 1526e8394b8SKazutaka YOKOTA const video_driver_t *p; 153617b9080SKazutaka YOKOTA int index; 154617b9080SKazutaka YOKOTA 155617b9080SKazutaka YOKOTA for (index = 0; index < adapters; ++index) { 156617b9080SKazutaka YOKOTA if (adapter[index] == NULL) 157617b9080SKazutaka YOKOTA break; 158617b9080SKazutaka YOKOTA } 1596e8394b8SKazutaka YOKOTA if (index >= adapters) { 1606e8394b8SKazutaka YOKOTA if (vid_realloc_array()) 161617b9080SKazutaka YOKOTA return -1; 1626e8394b8SKazutaka YOKOTA } 163617b9080SKazutaka YOKOTA 164617b9080SKazutaka YOKOTA adp->va_index = index; 165617b9080SKazutaka YOKOTA adp->va_token = NULL; 166f41325dbSPeter Wemm SET_FOREACH(list, videodriver_set) { 167f41325dbSPeter Wemm p = *list; 168617b9080SKazutaka YOKOTA if (strcmp(p->name, adp->va_name) == 0) { 169617b9080SKazutaka YOKOTA adapter[index] = adp; 170617b9080SKazutaka YOKOTA vidsw[index] = p->vidsw; 171617b9080SKazutaka YOKOTA return index; 172617b9080SKazutaka YOKOTA } 173617b9080SKazutaka YOKOTA } 174617b9080SKazutaka YOKOTA 175617b9080SKazutaka YOKOTA return -1; 176617b9080SKazutaka YOKOTA } 177617b9080SKazutaka YOKOTA 178617b9080SKazutaka YOKOTA int 179617b9080SKazutaka YOKOTA vid_unregister(video_adapter_t *adp) 180617b9080SKazutaka YOKOTA { 181617b9080SKazutaka YOKOTA if ((adp->va_index < 0) || (adp->va_index >= adapters)) 182617b9080SKazutaka YOKOTA return ENOENT; 183617b9080SKazutaka YOKOTA if (adapter[adp->va_index] != adp) 184617b9080SKazutaka YOKOTA return ENOENT; 185617b9080SKazutaka YOKOTA 186617b9080SKazutaka YOKOTA adapter[adp->va_index] = NULL; 187617b9080SKazutaka YOKOTA vidsw[adp->va_index] = NULL; 188617b9080SKazutaka YOKOTA return 0; 189617b9080SKazutaka YOKOTA } 190617b9080SKazutaka YOKOTA 191617b9080SKazutaka YOKOTA /* Get video I/O function table */ 192617b9080SKazutaka YOKOTA video_switch_t 193617b9080SKazutaka YOKOTA *vid_get_switch(char *name) 194617b9080SKazutaka YOKOTA { 1956e8394b8SKazutaka YOKOTA const video_driver_t **list; 1966e8394b8SKazutaka YOKOTA const video_driver_t *p; 197617b9080SKazutaka YOKOTA 198f41325dbSPeter Wemm SET_FOREACH(list, videodriver_set) { 199f41325dbSPeter Wemm p = *list; 200617b9080SKazutaka YOKOTA if (strcmp(p->name, name) == 0) 201617b9080SKazutaka YOKOTA return p->vidsw; 202617b9080SKazutaka YOKOTA } 203617b9080SKazutaka YOKOTA 204617b9080SKazutaka YOKOTA return NULL; 205617b9080SKazutaka YOKOTA } 206617b9080SKazutaka YOKOTA 207617b9080SKazutaka YOKOTA /* 208617b9080SKazutaka YOKOTA * Video card client functions 209617b9080SKazutaka YOKOTA * Video card clients, such as the console driver `syscons' and the frame 210617b9080SKazutaka YOKOTA * buffer cdev driver, use these functions to claim and release a card for 211617b9080SKazutaka YOKOTA * exclusive use. 212617b9080SKazutaka YOKOTA */ 213617b9080SKazutaka YOKOTA 214617b9080SKazutaka YOKOTA /* find the video card specified by a driver name and a unit number */ 215617b9080SKazutaka YOKOTA int 216617b9080SKazutaka YOKOTA vid_find_adapter(char *driver, int unit) 217617b9080SKazutaka YOKOTA { 218617b9080SKazutaka YOKOTA int i; 219617b9080SKazutaka YOKOTA 220617b9080SKazutaka YOKOTA for (i = 0; i < adapters; ++i) { 221617b9080SKazutaka YOKOTA if (adapter[i] == NULL) 222617b9080SKazutaka YOKOTA continue; 223617b9080SKazutaka YOKOTA if (strcmp("*", driver) && strcmp(adapter[i]->va_name, driver)) 224617b9080SKazutaka YOKOTA continue; 225617b9080SKazutaka YOKOTA if ((unit != -1) && (adapter[i]->va_unit != unit)) 226617b9080SKazutaka YOKOTA continue; 227617b9080SKazutaka YOKOTA return i; 228617b9080SKazutaka YOKOTA } 229617b9080SKazutaka YOKOTA return -1; 230617b9080SKazutaka YOKOTA } 231617b9080SKazutaka YOKOTA 232617b9080SKazutaka YOKOTA /* allocate a video card */ 233617b9080SKazutaka YOKOTA int 234617b9080SKazutaka YOKOTA vid_allocate(char *driver, int unit, void *id) 235617b9080SKazutaka YOKOTA { 236617b9080SKazutaka YOKOTA int index; 237617b9080SKazutaka YOKOTA int s; 238617b9080SKazutaka YOKOTA 239617b9080SKazutaka YOKOTA s = spltty(); 240617b9080SKazutaka YOKOTA index = vid_find_adapter(driver, unit); 241617b9080SKazutaka YOKOTA if (index >= 0) { 242617b9080SKazutaka YOKOTA if (adapter[index]->va_token) { 243617b9080SKazutaka YOKOTA splx(s); 244617b9080SKazutaka YOKOTA return -1; 245617b9080SKazutaka YOKOTA } 246617b9080SKazutaka YOKOTA adapter[index]->va_token = id; 247617b9080SKazutaka YOKOTA } 248617b9080SKazutaka YOKOTA splx(s); 249617b9080SKazutaka YOKOTA return index; 250617b9080SKazutaka YOKOTA } 251617b9080SKazutaka YOKOTA 252617b9080SKazutaka YOKOTA int 253617b9080SKazutaka YOKOTA vid_release(video_adapter_t *adp, void *id) 254617b9080SKazutaka YOKOTA { 255617b9080SKazutaka YOKOTA int error; 256617b9080SKazutaka YOKOTA int s; 257617b9080SKazutaka YOKOTA 258617b9080SKazutaka YOKOTA s = spltty(); 259617b9080SKazutaka YOKOTA if (adp->va_token == NULL) { 260617b9080SKazutaka YOKOTA error = EINVAL; 261617b9080SKazutaka YOKOTA } else if (adp->va_token != id) { 262617b9080SKazutaka YOKOTA error = EPERM; 263617b9080SKazutaka YOKOTA } else { 264617b9080SKazutaka YOKOTA adp->va_token = NULL; 265617b9080SKazutaka YOKOTA error = 0; 266617b9080SKazutaka YOKOTA } 267617b9080SKazutaka YOKOTA splx(s); 268617b9080SKazutaka YOKOTA return error; 269617b9080SKazutaka YOKOTA } 270617b9080SKazutaka YOKOTA 271617b9080SKazutaka YOKOTA /* Get a video adapter structure */ 272617b9080SKazutaka YOKOTA video_adapter_t 273617b9080SKazutaka YOKOTA *vid_get_adapter(int index) 274617b9080SKazutaka YOKOTA { 275617b9080SKazutaka YOKOTA if ((index < 0) || (index >= adapters)) 276617b9080SKazutaka YOKOTA return NULL; 277617b9080SKazutaka YOKOTA return adapter[index]; 278617b9080SKazutaka YOKOTA } 279617b9080SKazutaka YOKOTA 280617b9080SKazutaka YOKOTA /* Configure drivers: this is a backdoor for the console driver XXX */ 281617b9080SKazutaka YOKOTA int 282617b9080SKazutaka YOKOTA vid_configure(int flags) 283617b9080SKazutaka YOKOTA { 2846e8394b8SKazutaka YOKOTA const video_driver_t **list; 2856e8394b8SKazutaka YOKOTA const video_driver_t *p; 286617b9080SKazutaka YOKOTA 287f41325dbSPeter Wemm SET_FOREACH(list, videodriver_set) { 288f41325dbSPeter Wemm p = *list; 289617b9080SKazutaka YOKOTA if (p->configure != NULL) 290617b9080SKazutaka YOKOTA (*p->configure)(flags); 291617b9080SKazutaka YOKOTA } 292617b9080SKazutaka YOKOTA 293617b9080SKazutaka YOKOTA return 0; 294617b9080SKazutaka YOKOTA } 295617b9080SKazutaka YOKOTA 296617b9080SKazutaka YOKOTA /* 297617b9080SKazutaka YOKOTA * Virtual frame buffer cdev driver functions 298617b9080SKazutaka YOKOTA * The virtual frame buffer driver dispatches driver functions to 299617b9080SKazutaka YOKOTA * appropriate subdrivers. 300617b9080SKazutaka YOKOTA */ 301617b9080SKazutaka YOKOTA 3026e8394b8SKazutaka YOKOTA #define FB_DRIVER_NAME "fb" 303617b9080SKazutaka YOKOTA 304617b9080SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 305617b9080SKazutaka YOKOTA 3066e8394b8SKazutaka YOKOTA #if experimental 3076e8394b8SKazutaka YOKOTA 3086e8394b8SKazutaka YOKOTA static devclass_t fb_devclass; 3096e8394b8SKazutaka YOKOTA 3106e8394b8SKazutaka YOKOTA static int fbprobe(device_t dev); 3116e8394b8SKazutaka YOKOTA static int fbattach(device_t dev); 3126e8394b8SKazutaka YOKOTA 3136e8394b8SKazutaka YOKOTA static device_method_t fb_methods[] = { 3146e8394b8SKazutaka YOKOTA DEVMETHOD(device_probe, fbprobe), 3156e8394b8SKazutaka YOKOTA DEVMETHOD(device_attach, fbattach), 3166e8394b8SKazutaka YOKOTA 3176e8394b8SKazutaka YOKOTA DEVMETHOD(bus_print_child, bus_generic_print_child), 3186e8394b8SKazutaka YOKOTA { 0, 0 } 3196e8394b8SKazutaka YOKOTA }; 3206e8394b8SKazutaka YOKOTA 3216e8394b8SKazutaka YOKOTA static driver_t fb_driver = { 3226e8394b8SKazutaka YOKOTA FB_DRIVER_NAME, 3236e8394b8SKazutaka YOKOTA fb_methods, 3246e8394b8SKazutaka YOKOTA 0, 3256e8394b8SKazutaka YOKOTA }; 3266e8394b8SKazutaka YOKOTA 3276e8394b8SKazutaka YOKOTA static int 3286e8394b8SKazutaka YOKOTA fbprobe(device_t dev) 3296e8394b8SKazutaka YOKOTA { 3306e8394b8SKazutaka YOKOTA int unit; 3316e8394b8SKazutaka YOKOTA 3326e8394b8SKazutaka YOKOTA unit = device_get_unit(dev); 3336e8394b8SKazutaka YOKOTA if (unit >= adapters) 3346e8394b8SKazutaka YOKOTA return ENXIO; 3356e8394b8SKazutaka YOKOTA if (adapter[unit] == NULL) 3366e8394b8SKazutaka YOKOTA return ENXIO; 3376e8394b8SKazutaka YOKOTA 3386e8394b8SKazutaka YOKOTA device_set_desc(dev, "generic frame buffer"); 3396e8394b8SKazutaka YOKOTA return 0; 3406e8394b8SKazutaka YOKOTA } 3416e8394b8SKazutaka YOKOTA 3426e8394b8SKazutaka YOKOTA static int 3436e8394b8SKazutaka YOKOTA fbattach(device_t dev) 3446e8394b8SKazutaka YOKOTA { 3456e8394b8SKazutaka YOKOTA printf("fbattach: about to attach children\n"); 3466e8394b8SKazutaka YOKOTA bus_generic_attach(dev); 3476e8394b8SKazutaka YOKOTA return 0; 3486e8394b8SKazutaka YOKOTA } 3496e8394b8SKazutaka YOKOTA 3506e8394b8SKazutaka YOKOTA #endif /* experimental */ 3516e8394b8SKazutaka YOKOTA 352617b9080SKazutaka YOKOTA #define FB_UNIT(dev) minor(dev) 353617b9080SKazutaka YOKOTA #define FB_MKMINOR(unit) (u) 354617b9080SKazutaka YOKOTA 3556d473442SPoul-Henning Kamp #if experimental 356617b9080SKazutaka YOKOTA static d_open_t fbopen; 357617b9080SKazutaka YOKOTA static d_close_t fbclose; 3586e8394b8SKazutaka YOKOTA static d_read_t fbread; 3596e8394b8SKazutaka YOKOTA static d_write_t fbwrite; 360617b9080SKazutaka YOKOTA static d_ioctl_t fbioctl; 361617b9080SKazutaka YOKOTA static d_mmap_t fbmmap; 362617b9080SKazutaka YOKOTA 3636e8394b8SKazutaka YOKOTA #define CDEV_MAJOR 123 /* XXX */ 364617b9080SKazutaka YOKOTA 365617b9080SKazutaka YOKOTA static struct cdevsw fb_cdevsw = { 3667ac40f5fSPoul-Henning Kamp .d_open = fbopen, 3677ac40f5fSPoul-Henning Kamp .d_close = fbclose, 3687ac40f5fSPoul-Henning Kamp .d_read = fbread, 3697ac40f5fSPoul-Henning Kamp .d_write = fbwrite, 3707ac40f5fSPoul-Henning Kamp .d_ioctl = fbioctl, 3717ac40f5fSPoul-Henning Kamp .d_mmap = fbmmap, 3727ac40f5fSPoul-Henning Kamp .d_name = FB_DRIVER_NAME, 3737ac40f5fSPoul-Henning Kamp .d_maj = CDEV_MAJOR, 374617b9080SKazutaka YOKOTA }; 3756d473442SPoul-Henning Kamp #endif 376617b9080SKazutaka YOKOTA 3772b120974SPeter Wemm 3782b120974SPeter Wemm static int 3792b120974SPeter Wemm fb_modevent(module_t mod, int type, void *data) 380617b9080SKazutaka YOKOTA { 381617b9080SKazutaka YOKOTA 3822b120974SPeter Wemm switch (type) { 3832b120974SPeter Wemm case MOD_LOAD: 3842b120974SPeter Wemm break; 3852b120974SPeter Wemm case MOD_UNLOAD: 3862b120974SPeter Wemm printf("fb module unload - not possible for this module type\n"); 3872b120974SPeter Wemm return EINVAL; 388617b9080SKazutaka YOKOTA } 3892b120974SPeter Wemm return 0; 390617b9080SKazutaka YOKOTA } 391617b9080SKazutaka YOKOTA 3922b120974SPeter Wemm static moduledata_t fb_mod = { 3932b120974SPeter Wemm "fb", 3942b120974SPeter Wemm fb_modevent, 3952b120974SPeter Wemm NULL 3962b120974SPeter Wemm }; 3972b120974SPeter Wemm 3982b120974SPeter Wemm DECLARE_MODULE(fb, fb_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 399617b9080SKazutaka YOKOTA 400617b9080SKazutaka YOKOTA int 4016e8394b8SKazutaka YOKOTA fb_attach(dev_t dev, video_adapter_t *adp, struct cdevsw *cdevsw) 402617b9080SKazutaka YOKOTA { 403617b9080SKazutaka YOKOTA int s; 404617b9080SKazutaka YOKOTA 405617b9080SKazutaka YOKOTA if (adp->va_index >= adapters) 406617b9080SKazutaka YOKOTA return EINVAL; 407617b9080SKazutaka YOKOTA if (adapter[adp->va_index] != adp) 408617b9080SKazutaka YOKOTA return EINVAL; 409617b9080SKazutaka YOKOTA 410617b9080SKazutaka YOKOTA s = spltty(); 411617b9080SKazutaka YOKOTA adp->va_minor = minor(dev); 412617b9080SKazutaka YOKOTA vidcdevsw[adp->va_index] = cdevsw; 413617b9080SKazutaka YOKOTA splx(s); 414617b9080SKazutaka YOKOTA 415617b9080SKazutaka YOKOTA printf("fb%d at %s%d\n", adp->va_index, adp->va_name, adp->va_unit); 416617b9080SKazutaka YOKOTA return 0; 417617b9080SKazutaka YOKOTA } 418617b9080SKazutaka YOKOTA 419617b9080SKazutaka YOKOTA int 4206e8394b8SKazutaka YOKOTA fb_detach(dev_t dev, video_adapter_t *adp, struct cdevsw *cdevsw) 421617b9080SKazutaka YOKOTA { 422617b9080SKazutaka YOKOTA int s; 423617b9080SKazutaka YOKOTA 424617b9080SKazutaka YOKOTA if (adp->va_index >= adapters) 425617b9080SKazutaka YOKOTA return EINVAL; 426617b9080SKazutaka YOKOTA if (adapter[adp->va_index] != adp) 427617b9080SKazutaka YOKOTA return EINVAL; 428617b9080SKazutaka YOKOTA if (vidcdevsw[adp->va_index] != cdevsw) 429617b9080SKazutaka YOKOTA return EINVAL; 430617b9080SKazutaka YOKOTA 431617b9080SKazutaka YOKOTA s = spltty(); 432617b9080SKazutaka YOKOTA vidcdevsw[adp->va_index] = NULL; 433617b9080SKazutaka YOKOTA splx(s); 434617b9080SKazutaka YOKOTA return 0; 435617b9080SKazutaka YOKOTA } 436617b9080SKazutaka YOKOTA 4376d473442SPoul-Henning Kamp #if experimental 4386e8394b8SKazutaka YOKOTA static int 439b40ce416SJulian Elischer fbopen(dev_t dev, int flag, int mode, struct thread *td) 4406e8394b8SKazutaka YOKOTA { 4416e8394b8SKazutaka YOKOTA int unit; 4426e8394b8SKazutaka YOKOTA 4436e8394b8SKazutaka YOKOTA unit = FB_UNIT(dev); 4446e8394b8SKazutaka YOKOTA if (unit >= adapters) 4456e8394b8SKazutaka YOKOTA return ENXIO; 4466e8394b8SKazutaka YOKOTA if (vidcdevsw[unit] == NULL) 4476e8394b8SKazutaka YOKOTA return ENXIO; 4486e8394b8SKazutaka YOKOTA return (*vidcdevsw[unit]->d_open)(makedev(0, adapter[unit]->va_minor), 449b40ce416SJulian Elischer flag, mode, td); 4506e8394b8SKazutaka YOKOTA } 4516e8394b8SKazutaka YOKOTA 4526e8394b8SKazutaka YOKOTA static int 453b40ce416SJulian Elischer fbclose(dev_t dev, int flag, int mode, struct thread *td) 4546e8394b8SKazutaka YOKOTA { 4556e8394b8SKazutaka YOKOTA int unit; 4566e8394b8SKazutaka YOKOTA 4576e8394b8SKazutaka YOKOTA unit = FB_UNIT(dev); 4586e8394b8SKazutaka YOKOTA if (vidcdevsw[unit] == NULL) 4596e8394b8SKazutaka YOKOTA return ENXIO; 4606e8394b8SKazutaka YOKOTA return (*vidcdevsw[unit]->d_close)(makedev(0, adapter[unit]->va_minor), 461b40ce416SJulian Elischer flag, mode, td); 4626e8394b8SKazutaka YOKOTA } 4636e8394b8SKazutaka YOKOTA 4646e8394b8SKazutaka YOKOTA static int 4656e8394b8SKazutaka YOKOTA fbread(dev_t dev, struct uio *uio, int flag) 4666e8394b8SKazutaka YOKOTA { 4676e8394b8SKazutaka YOKOTA int unit; 4686e8394b8SKazutaka YOKOTA 4696e8394b8SKazutaka YOKOTA unit = FB_UNIT(dev); 4706e8394b8SKazutaka YOKOTA if (vidcdevsw[unit] == NULL) 4716e8394b8SKazutaka YOKOTA return ENXIO; 4726e8394b8SKazutaka YOKOTA return (*vidcdevsw[unit]->d_read)(makedev(0, adapter[unit]->va_minor), 4736e8394b8SKazutaka YOKOTA uio, flag); 4746e8394b8SKazutaka YOKOTA } 4756e8394b8SKazutaka YOKOTA 4766e8394b8SKazutaka YOKOTA static int 4776e8394b8SKazutaka YOKOTA fbwrite(dev_t dev, struct uio *uio, int flag) 4786e8394b8SKazutaka YOKOTA { 4796e8394b8SKazutaka YOKOTA int unit; 4806e8394b8SKazutaka YOKOTA 4816e8394b8SKazutaka YOKOTA unit = FB_UNIT(dev); 4826e8394b8SKazutaka YOKOTA if (vidcdevsw[unit] == NULL) 4836e8394b8SKazutaka YOKOTA return ENXIO; 4846e8394b8SKazutaka YOKOTA return (*vidcdevsw[unit]->d_write)(makedev(0, adapter[unit]->va_minor), 4856e8394b8SKazutaka YOKOTA uio, flag); 4866e8394b8SKazutaka YOKOTA } 4876e8394b8SKazutaka YOKOTA 4886e8394b8SKazutaka YOKOTA static int 489b40ce416SJulian Elischer fbioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct thread *td) 4906e8394b8SKazutaka YOKOTA { 4916e8394b8SKazutaka YOKOTA int unit; 4926e8394b8SKazutaka YOKOTA 4936e8394b8SKazutaka YOKOTA unit = FB_UNIT(dev); 4946e8394b8SKazutaka YOKOTA if (vidcdevsw[unit] == NULL) 4956e8394b8SKazutaka YOKOTA return ENXIO; 4966e8394b8SKazutaka YOKOTA return (*vidcdevsw[unit]->d_ioctl)(makedev(0, adapter[unit]->va_minor), 497b40ce416SJulian Elischer cmd, arg, flag, td); 4986e8394b8SKazutaka YOKOTA } 4996e8394b8SKazutaka YOKOTA 5006e8394b8SKazutaka YOKOTA static int 50107159f9cSMaxime Henrion fbmmap(dev_t dev, vm_offset_t offset, vm_offset_t *paddr, int nprot) 5026e8394b8SKazutaka YOKOTA { 5036e8394b8SKazutaka YOKOTA int unit; 5046e8394b8SKazutaka YOKOTA 5056e8394b8SKazutaka YOKOTA unit = FB_UNIT(dev); 5066e8394b8SKazutaka YOKOTA if (vidcdevsw[unit] == NULL) 5076e8394b8SKazutaka YOKOTA return ENXIO; 5086e8394b8SKazutaka YOKOTA return (*vidcdevsw[unit]->d_mmap)(makedev(0, adapter[unit]->va_minor), 50907159f9cSMaxime Henrion offset, paddr, nprot); 5106e8394b8SKazutaka YOKOTA } 5116e8394b8SKazutaka YOKOTA 51203016f42SPoul-Henning Kamp DEV_DRIVER_MODULE(fb, ???, fb_driver, fb_devclass, fb_cdevsw, 0, 0); 5136e8394b8SKazutaka YOKOTA #endif 5146e8394b8SKazutaka YOKOTA 5156e8394b8SKazutaka YOKOTA /* 5166e8394b8SKazutaka YOKOTA * Generic frame buffer cdev driver functions 5176e8394b8SKazutaka YOKOTA * Frame buffer subdrivers may call these functions to implement common 5186e8394b8SKazutaka YOKOTA * driver functions. 5196e8394b8SKazutaka YOKOTA */ 5206e8394b8SKazutaka YOKOTA 5216e8394b8SKazutaka YOKOTA int genfbopen(genfb_softc_t *sc, video_adapter_t *adp, int flag, int mode, 522b40ce416SJulian Elischer struct thread *td) 5236e8394b8SKazutaka YOKOTA { 5246e8394b8SKazutaka YOKOTA int s; 5256e8394b8SKazutaka YOKOTA 5266e8394b8SKazutaka YOKOTA s = spltty(); 5276e8394b8SKazutaka YOKOTA if (!(sc->gfb_flags & FB_OPEN)) 5286e8394b8SKazutaka YOKOTA sc->gfb_flags |= FB_OPEN; 5296e8394b8SKazutaka YOKOTA splx(s); 5306e8394b8SKazutaka YOKOTA return 0; 5316e8394b8SKazutaka YOKOTA } 5326e8394b8SKazutaka YOKOTA 5336e8394b8SKazutaka YOKOTA int genfbclose(genfb_softc_t *sc, video_adapter_t *adp, int flag, int mode, 534b40ce416SJulian Elischer struct thread *td) 5356e8394b8SKazutaka YOKOTA { 5366e8394b8SKazutaka YOKOTA int s; 5376e8394b8SKazutaka YOKOTA 5386e8394b8SKazutaka YOKOTA s = spltty(); 5396e8394b8SKazutaka YOKOTA sc->gfb_flags &= ~FB_OPEN; 5406e8394b8SKazutaka YOKOTA splx(s); 5416e8394b8SKazutaka YOKOTA return 0; 5426e8394b8SKazutaka YOKOTA } 5436e8394b8SKazutaka YOKOTA 5446e8394b8SKazutaka YOKOTA int genfbread(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio, 5456e8394b8SKazutaka YOKOTA int flag) 5466e8394b8SKazutaka YOKOTA { 5476e8394b8SKazutaka YOKOTA int size; 5486e8394b8SKazutaka YOKOTA int offset; 5496e8394b8SKazutaka YOKOTA int error; 5506e8394b8SKazutaka YOKOTA int len; 5516e8394b8SKazutaka YOKOTA 5526e8394b8SKazutaka YOKOTA error = 0; 5536e8394b8SKazutaka YOKOTA size = adp->va_buffer_size/adp->va_info.vi_planes; 5546e8394b8SKazutaka YOKOTA while (uio->uio_resid > 0) { 5556e8394b8SKazutaka YOKOTA if (uio->uio_offset >= size) 5566e8394b8SKazutaka YOKOTA break; 5576e8394b8SKazutaka YOKOTA offset = uio->uio_offset%adp->va_window_size; 5586e8394b8SKazutaka YOKOTA len = imin(uio->uio_resid, size - uio->uio_offset); 5596e8394b8SKazutaka YOKOTA len = imin(len, adp->va_window_size - offset); 5606e8394b8SKazutaka YOKOTA if (len <= 0) 5616e8394b8SKazutaka YOKOTA break; 5626e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, uio->uio_offset); 5636e8394b8SKazutaka YOKOTA error = uiomove((caddr_t)(adp->va_window + offset), len, uio); 5646e8394b8SKazutaka YOKOTA if (error) 5656e8394b8SKazutaka YOKOTA break; 5666e8394b8SKazutaka YOKOTA } 5676e8394b8SKazutaka YOKOTA return error; 5686e8394b8SKazutaka YOKOTA } 5696e8394b8SKazutaka YOKOTA 5706e8394b8SKazutaka YOKOTA int genfbwrite(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio, 5716e8394b8SKazutaka YOKOTA int flag) 5726e8394b8SKazutaka YOKOTA { 5736e8394b8SKazutaka YOKOTA return ENODEV; 5746e8394b8SKazutaka YOKOTA } 5756e8394b8SKazutaka YOKOTA 5766e8394b8SKazutaka YOKOTA int genfbioctl(genfb_softc_t *sc, video_adapter_t *adp, u_long cmd, 577b40ce416SJulian Elischer caddr_t arg, int flag, struct thread *td) 5786e8394b8SKazutaka YOKOTA { 5796e8394b8SKazutaka YOKOTA int error; 5806e8394b8SKazutaka YOKOTA 5816e8394b8SKazutaka YOKOTA if (adp == NULL) /* XXX */ 5826e8394b8SKazutaka YOKOTA return ENXIO; 5836e8394b8SKazutaka YOKOTA error = (*vidsw[adp->va_index]->ioctl)(adp, cmd, arg); 5846e8394b8SKazutaka YOKOTA if (error == ENOIOCTL) 5856e8394b8SKazutaka YOKOTA error = ENODEV; 5866e8394b8SKazutaka YOKOTA return error; 5876e8394b8SKazutaka YOKOTA } 5886e8394b8SKazutaka YOKOTA 5896e8394b8SKazutaka YOKOTA int genfbmmap(genfb_softc_t *sc, video_adapter_t *adp, vm_offset_t offset, 59007159f9cSMaxime Henrion vm_offset_t *paddr, int prot) 5916e8394b8SKazutaka YOKOTA { 59207159f9cSMaxime Henrion return (*vidsw[adp->va_index]->mmap)(adp, offset, paddr, prot); 5936e8394b8SKazutaka YOKOTA } 5946e8394b8SKazutaka YOKOTA 595617b9080SKazutaka YOKOTA #endif /* FB_INSTALL_CDEV */ 596617b9080SKazutaka YOKOTA 597617b9080SKazutaka YOKOTA static char 598617b9080SKazutaka YOKOTA *adapter_name(int type) 599617b9080SKazutaka YOKOTA { 600617b9080SKazutaka YOKOTA static struct { 601617b9080SKazutaka YOKOTA int type; 602617b9080SKazutaka YOKOTA char *name; 603617b9080SKazutaka YOKOTA } names[] = { 604617b9080SKazutaka YOKOTA { KD_MONO, "MDA" }, 605617b9080SKazutaka YOKOTA { KD_HERCULES, "Hercules" }, 606617b9080SKazutaka YOKOTA { KD_CGA, "CGA" }, 607617b9080SKazutaka YOKOTA { KD_EGA, "EGA" }, 608617b9080SKazutaka YOKOTA { KD_VGA, "VGA" }, 609617b9080SKazutaka YOKOTA { KD_PC98, "PC-98x1" }, 6106e8394b8SKazutaka YOKOTA { KD_TGA, "TGA" }, 611617b9080SKazutaka YOKOTA { -1, "Unknown" }, 612617b9080SKazutaka YOKOTA }; 613617b9080SKazutaka YOKOTA int i; 614617b9080SKazutaka YOKOTA 615617b9080SKazutaka YOKOTA for (i = 0; names[i].type != -1; ++i) 616617b9080SKazutaka YOKOTA if (names[i].type == type) 617617b9080SKazutaka YOKOTA break; 618617b9080SKazutaka YOKOTA return names[i].name; 619617b9080SKazutaka YOKOTA } 620617b9080SKazutaka YOKOTA 6216e8394b8SKazutaka YOKOTA /* 6226e8394b8SKazutaka YOKOTA * Generic low-level frame buffer functions 6236e8394b8SKazutaka YOKOTA * The low-level functions in the frame buffer subdriver may use these 6246e8394b8SKazutaka YOKOTA * functions. 6256e8394b8SKazutaka YOKOTA */ 6266e8394b8SKazutaka YOKOTA 627617b9080SKazutaka YOKOTA void 628617b9080SKazutaka YOKOTA fb_dump_adp_info(char *driver, video_adapter_t *adp, int level) 629617b9080SKazutaka YOKOTA { 630617b9080SKazutaka YOKOTA if (level <= 0) 631617b9080SKazutaka YOKOTA return; 632617b9080SKazutaka YOKOTA 633617b9080SKazutaka YOKOTA printf("%s%d: %s%d, %s, type:%s (%d), flags:0x%x\n", 6346e8394b8SKazutaka YOKOTA FB_DRIVER_NAME, adp->va_index, driver, adp->va_unit, adp->va_name, 635617b9080SKazutaka YOKOTA adapter_name(adp->va_type), adp->va_type, adp->va_flags); 6360301e9c8SDavid E. O'Brien printf("%s%d: port:0x%lx-0x%lx, crtc:0x%lx, mem:0x%lx 0x%x\n", 6370301e9c8SDavid E. O'Brien FB_DRIVER_NAME, adp->va_index, (u_long)adp->va_io_base, 6380301e9c8SDavid E. O'Brien (u_long)adp->va_io_base + adp->va_io_size - 1, 6390301e9c8SDavid E. O'Brien (u_long)adp->va_crtc_addr, (u_long)adp->va_mem_base, 6400301e9c8SDavid E. O'Brien adp->va_mem_size); 641617b9080SKazutaka YOKOTA printf("%s%d: init mode:%d, bios mode:%d, current mode:%d\n", 6426e8394b8SKazutaka YOKOTA FB_DRIVER_NAME, adp->va_index, 643617b9080SKazutaka YOKOTA adp->va_initial_mode, adp->va_initial_bios_mode, adp->va_mode); 6446e8394b8SKazutaka YOKOTA printf("%s%d: window:%p size:%dk gran:%dk, buf:%p size:%dk\n", 6456e8394b8SKazutaka YOKOTA FB_DRIVER_NAME, adp->va_index, 6466e8394b8SKazutaka YOKOTA (void *)adp->va_window, (int)adp->va_window_size/1024, 6476e8394b8SKazutaka YOKOTA (int)adp->va_window_gran/1024, (void *)adp->va_buffer, 648f359876fSKazutaka YOKOTA (int)adp->va_buffer_size/1024); 649617b9080SKazutaka YOKOTA } 650617b9080SKazutaka YOKOTA 651617b9080SKazutaka YOKOTA void 652617b9080SKazutaka YOKOTA fb_dump_mode_info(char *driver, video_adapter_t *adp, video_info_t *info, 653617b9080SKazutaka YOKOTA int level) 654617b9080SKazutaka YOKOTA { 655617b9080SKazutaka YOKOTA if (level <= 0) 656617b9080SKazutaka YOKOTA return; 657617b9080SKazutaka YOKOTA 658617b9080SKazutaka YOKOTA printf("%s%d: %s, mode:%d, flags:0x%x ", 659617b9080SKazutaka YOKOTA driver, adp->va_unit, adp->va_name, info->vi_mode, info->vi_flags); 660617b9080SKazutaka YOKOTA if (info->vi_flags & V_INFO_GRAPHICS) 661617b9080SKazutaka YOKOTA printf("G %dx%dx%d, %d plane(s), font:%dx%d, ", 662617b9080SKazutaka YOKOTA info->vi_width, info->vi_height, 663617b9080SKazutaka YOKOTA info->vi_depth, info->vi_planes, 664617b9080SKazutaka YOKOTA info->vi_cwidth, info->vi_cheight); 665617b9080SKazutaka YOKOTA else 666617b9080SKazutaka YOKOTA printf("T %dx%d, font:%dx%d, ", 667617b9080SKazutaka YOKOTA info->vi_width, info->vi_height, 668617b9080SKazutaka YOKOTA info->vi_cwidth, info->vi_cheight); 6690301e9c8SDavid E. O'Brien printf("win:0x%lx\n", (u_long)info->vi_window); 670617b9080SKazutaka YOKOTA } 6716e8394b8SKazutaka YOKOTA 6726e8394b8SKazutaka YOKOTA int 6736e8394b8SKazutaka YOKOTA fb_type(int adp_type) 6746e8394b8SKazutaka YOKOTA { 6756e8394b8SKazutaka YOKOTA static struct { 6766e8394b8SKazutaka YOKOTA int fb_type; 6776e8394b8SKazutaka YOKOTA int va_type; 6786e8394b8SKazutaka YOKOTA } types[] = { 6796e8394b8SKazutaka YOKOTA { FBTYPE_MDA, KD_MONO }, 6806e8394b8SKazutaka YOKOTA { FBTYPE_HERCULES, KD_HERCULES }, 6816e8394b8SKazutaka YOKOTA { FBTYPE_CGA, KD_CGA }, 6826e8394b8SKazutaka YOKOTA { FBTYPE_EGA, KD_EGA }, 6836e8394b8SKazutaka YOKOTA { FBTYPE_VGA, KD_VGA }, 6846e8394b8SKazutaka YOKOTA { FBTYPE_PC98, KD_PC98 }, 6856e8394b8SKazutaka YOKOTA { FBTYPE_TGA, KD_TGA }, 6866e8394b8SKazutaka YOKOTA }; 6876e8394b8SKazutaka YOKOTA int i; 6886e8394b8SKazutaka YOKOTA 6896e8394b8SKazutaka YOKOTA for (i = 0; i < sizeof(types)/sizeof(types[0]); ++i) { 6906e8394b8SKazutaka YOKOTA if (types[i].va_type == adp_type) 6916e8394b8SKazutaka YOKOTA return types[i].fb_type; 6926e8394b8SKazutaka YOKOTA } 6936e8394b8SKazutaka YOKOTA return -1; 6946e8394b8SKazutaka YOKOTA } 6956e8394b8SKazutaka YOKOTA 6966e8394b8SKazutaka YOKOTA int 6976e8394b8SKazutaka YOKOTA fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) 6986e8394b8SKazutaka YOKOTA { 6996e8394b8SKazutaka YOKOTA int error; 7006e8394b8SKazutaka YOKOTA int s; 7016e8394b8SKazutaka YOKOTA 7026e8394b8SKazutaka YOKOTA /* assert(adp != NULL) */ 7036e8394b8SKazutaka YOKOTA 7046e8394b8SKazutaka YOKOTA error = 0; 7056e8394b8SKazutaka YOKOTA s = spltty(); 7066e8394b8SKazutaka YOKOTA 7076e8394b8SKazutaka YOKOTA switch (cmd) { 7086e8394b8SKazutaka YOKOTA 7096e8394b8SKazutaka YOKOTA case FBIO_ADAPTER: /* get video adapter index */ 7106e8394b8SKazutaka YOKOTA *(int *)arg = adp->va_index; 7116e8394b8SKazutaka YOKOTA break; 7126e8394b8SKazutaka YOKOTA 7136e8394b8SKazutaka YOKOTA case FBIO_ADPTYPE: /* get video adapter type */ 7146e8394b8SKazutaka YOKOTA *(int *)arg = adp->va_type; 7156e8394b8SKazutaka YOKOTA break; 7166e8394b8SKazutaka YOKOTA 7176e8394b8SKazutaka YOKOTA case FBIO_ADPINFO: /* get video adapter info */ 7186e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_index = adp->va_index; 7196e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_type = adp->va_type; 7206e8394b8SKazutaka YOKOTA bcopy(adp->va_name, ((video_adapter_info_t *)arg)->va_name, 7216e8394b8SKazutaka YOKOTA imin(strlen(adp->va_name) + 1, 7226e8394b8SKazutaka YOKOTA sizeof(((video_adapter_info_t *)arg)->va_name))); 7236e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_unit = adp->va_unit; 7246e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_flags = adp->va_flags; 7256e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_io_base = adp->va_io_base; 7266e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_io_size = adp->va_io_size; 7276e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_crtc_addr = adp->va_crtc_addr; 7286e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_mem_base = adp->va_mem_base; 7296e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_mem_size = adp->va_mem_size; 7306e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_window 7312727ed91SAndrew Gallatin #ifdef __i386__ 7326e8394b8SKazutaka YOKOTA = vtophys(adp->va_window); 7332727ed91SAndrew Gallatin #else 7342727ed91SAndrew Gallatin = adp->va_window; 7352727ed91SAndrew Gallatin #endif 7366e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_window_size 7376e8394b8SKazutaka YOKOTA = adp->va_window_size; 7386e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_window_gran 7396e8394b8SKazutaka YOKOTA = adp->va_window_gran; 7406e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_window_orig 7416e8394b8SKazutaka YOKOTA = adp->va_window_orig; 7426e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_unused0 7432727ed91SAndrew Gallatin #ifdef __i386__ 7446e8394b8SKazutaka YOKOTA = (adp->va_buffer) ? vtophys(adp->va_buffer) : 0; 7452727ed91SAndrew Gallatin #else 7462727ed91SAndrew Gallatin = adp->va_buffer; 7472727ed91SAndrew Gallatin #endif 7486e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_buffer_size 7496e8394b8SKazutaka YOKOTA = adp->va_buffer_size; 7506e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_mode = adp->va_mode; 7516e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_initial_mode 7526e8394b8SKazutaka YOKOTA = adp->va_initial_mode; 7536e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_initial_bios_mode 7546e8394b8SKazutaka YOKOTA = adp->va_initial_bios_mode; 7556e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_line_width 7566e8394b8SKazutaka YOKOTA = adp->va_line_width; 7576e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_disp_start.x 7586e8394b8SKazutaka YOKOTA = adp->va_disp_start.x; 7596e8394b8SKazutaka YOKOTA ((video_adapter_info_t *)arg)->va_disp_start.y 7606e8394b8SKazutaka YOKOTA = adp->va_disp_start.y; 7616e8394b8SKazutaka YOKOTA break; 7626e8394b8SKazutaka YOKOTA 7636e8394b8SKazutaka YOKOTA case FBIO_MODEINFO: /* get mode information */ 7646e8394b8SKazutaka YOKOTA error = (*vidsw[adp->va_index]->get_info)(adp, 7656e8394b8SKazutaka YOKOTA ((video_info_t *)arg)->vi_mode, 7666e8394b8SKazutaka YOKOTA (video_info_t *)arg); 7676e8394b8SKazutaka YOKOTA if (error) 7686e8394b8SKazutaka YOKOTA error = ENODEV; 7696e8394b8SKazutaka YOKOTA break; 7706e8394b8SKazutaka YOKOTA 7716e8394b8SKazutaka YOKOTA case FBIO_FINDMODE: /* find a matching video mode */ 7726e8394b8SKazutaka YOKOTA error = (*vidsw[adp->va_index]->query_mode)(adp, 7736e8394b8SKazutaka YOKOTA (video_info_t *)arg); 7746e8394b8SKazutaka YOKOTA break; 7756e8394b8SKazutaka YOKOTA 7766e8394b8SKazutaka YOKOTA case FBIO_GETMODE: /* get video mode */ 7776e8394b8SKazutaka YOKOTA *(int *)arg = adp->va_mode; 7786e8394b8SKazutaka YOKOTA break; 7796e8394b8SKazutaka YOKOTA 7806e8394b8SKazutaka YOKOTA case FBIO_SETMODE: /* set video mode */ 7816e8394b8SKazutaka YOKOTA error = (*vidsw[adp->va_index]->set_mode)(adp, *(int *)arg); 7826e8394b8SKazutaka YOKOTA if (error) 7836e8394b8SKazutaka YOKOTA error = ENODEV; /* EINVAL? */ 7846e8394b8SKazutaka YOKOTA break; 7856e8394b8SKazutaka YOKOTA 7866e8394b8SKazutaka YOKOTA case FBIO_GETWINORG: /* get frame buffer window origin */ 7876e8394b8SKazutaka YOKOTA *(u_int *)arg = adp->va_window_orig; 7886e8394b8SKazutaka YOKOTA break; 7896e8394b8SKazutaka YOKOTA 7906e8394b8SKazutaka YOKOTA case FBIO_GETDISPSTART: /* get display start address */ 7916e8394b8SKazutaka YOKOTA ((video_display_start_t *)arg)->x = adp->va_disp_start.x; 7926e8394b8SKazutaka YOKOTA ((video_display_start_t *)arg)->y = adp->va_disp_start.y; 7936e8394b8SKazutaka YOKOTA break; 7946e8394b8SKazutaka YOKOTA 7956e8394b8SKazutaka YOKOTA case FBIO_GETLINEWIDTH: /* get scan line width in bytes */ 7966e8394b8SKazutaka YOKOTA *(u_int *)arg = adp->va_line_width; 7976e8394b8SKazutaka YOKOTA break; 7986e8394b8SKazutaka YOKOTA 799eac47d67SKazutaka YOKOTA case FBIO_BLANK: /* blank display */ 800eac47d67SKazutaka YOKOTA error = (*vidsw[adp->va_index]->blank_display)(adp, *(int *)arg); 801eac47d67SKazutaka YOKOTA break; 802eac47d67SKazutaka YOKOTA 8036e8394b8SKazutaka YOKOTA case FBIO_GETPALETTE: /* get color palette */ 8046e8394b8SKazutaka YOKOTA case FBIO_SETPALETTE: /* set color palette */ 8056e8394b8SKazutaka YOKOTA /* XXX */ 8066e8394b8SKazutaka YOKOTA 8076e8394b8SKazutaka YOKOTA case FBIOPUTCMAP: 8086e8394b8SKazutaka YOKOTA case FBIOGETCMAP: 809eac47d67SKazutaka YOKOTA case FBIOPUTCMAPI: 810eac47d67SKazutaka YOKOTA case FBIOGETCMAPI: 8116e8394b8SKazutaka YOKOTA /* XXX */ 8126e8394b8SKazutaka YOKOTA 8136e8394b8SKazutaka YOKOTA case FBIO_SETWINORG: /* set frame buffer window origin */ 8146e8394b8SKazutaka YOKOTA case FBIO_SETDISPSTART: /* set display start address */ 8156e8394b8SKazutaka YOKOTA case FBIO_SETLINEWIDTH: /* set scan line width in pixel */ 8166e8394b8SKazutaka YOKOTA 8176e8394b8SKazutaka YOKOTA case FBIOGTYPE: 8186e8394b8SKazutaka YOKOTA case FBIOGATTR: 8196e8394b8SKazutaka YOKOTA case FBIOSVIDEO: 8206e8394b8SKazutaka YOKOTA case FBIOGVIDEO: 821eac47d67SKazutaka YOKOTA case FBIOVERTICAL: 8226e8394b8SKazutaka YOKOTA case FBIOSCURSOR: 8236e8394b8SKazutaka YOKOTA case FBIOGCURSOR: 8246e8394b8SKazutaka YOKOTA case FBIOSCURPOS: 8256e8394b8SKazutaka YOKOTA case FBIOGCURPOS: 8266e8394b8SKazutaka YOKOTA case FBIOGCURMAX: 827eac47d67SKazutaka YOKOTA case FBIOMONINFO: 828eac47d67SKazutaka YOKOTA case FBIOGXINFO: 8296e8394b8SKazutaka YOKOTA 8306e8394b8SKazutaka YOKOTA default: 8316e8394b8SKazutaka YOKOTA error = ENODEV; 8326e8394b8SKazutaka YOKOTA break; 8336e8394b8SKazutaka YOKOTA } 8346e8394b8SKazutaka YOKOTA 8356e8394b8SKazutaka YOKOTA splx(s); 8366e8394b8SKazutaka YOKOTA return error; 8376e8394b8SKazutaka YOKOTA } 838