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 */ 28617b9080SKazutaka YOKOTA 29aad970f1SDavid E. O'Brien #include <sys/cdefs.h> 30aad970f1SDavid E. O'Brien __FBSDID("$FreeBSD$"); 31aad970f1SDavid E. O'Brien 32617b9080SKazutaka YOKOTA #include "opt_fb.h" 33617b9080SKazutaka YOKOTA 34617b9080SKazutaka YOKOTA #include <sys/param.h> 35617b9080SKazutaka YOKOTA #include <sys/systm.h> 36617b9080SKazutaka YOKOTA #include <sys/conf.h> 376e8394b8SKazutaka YOKOTA #include <sys/bus.h> 38617b9080SKazutaka YOKOTA #include <sys/kernel.h> 39617b9080SKazutaka YOKOTA #include <sys/malloc.h> 402b120974SPeter Wemm #include <sys/module.h> 416e8394b8SKazutaka YOKOTA #include <sys/uio.h> 426e8394b8SKazutaka YOKOTA #include <sys/fbio.h> 43f41325dbSPeter Wemm #include <sys/linker_set.h> 44617b9080SKazutaka YOKOTA 456e8394b8SKazutaka YOKOTA #include <vm/vm.h> 466e8394b8SKazutaka YOKOTA #include <vm/pmap.h> 47617b9080SKazutaka YOKOTA 48617b9080SKazutaka YOKOTA #include <dev/fb/fbreg.h> 49617b9080SKazutaka YOKOTA 50f41325dbSPeter Wemm SET_DECLARE(videodriver_set, const video_driver_t); 51f41325dbSPeter Wemm 52617b9080SKazutaka YOKOTA /* local arrays */ 53617b9080SKazutaka YOKOTA 54617b9080SKazutaka YOKOTA /* 55617b9080SKazutaka YOKOTA * We need at least one entry each in order to initialize a video card 56617b9080SKazutaka YOKOTA * for the kernel console. The arrays will be increased dynamically 57617b9080SKazutaka YOKOTA * when necessary. 58617b9080SKazutaka YOKOTA */ 59617b9080SKazutaka YOKOTA 606e8394b8SKazutaka YOKOTA static int vid_malloc; 61617b9080SKazutaka YOKOTA static int adapters = 1; 6290500a9dSKazutaka YOKOTA static video_adapter_t *adp_ini; 6390500a9dSKazutaka YOKOTA static video_adapter_t **adapter = &adp_ini; 6490500a9dSKazutaka YOKOTA static video_switch_t *vidsw_ini; 65617b9080SKazutaka YOKOTA video_switch_t **vidsw = &vidsw_ini; 6690500a9dSKazutaka YOKOTA 6790500a9dSKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 686e8394b8SKazutaka YOKOTA static struct cdevsw *vidcdevsw_ini; 696e8394b8SKazutaka YOKOTA static struct cdevsw **vidcdevsw = &vidcdevsw_ini; 706e8394b8SKazutaka YOKOTA #endif 71617b9080SKazutaka YOKOTA 72617b9080SKazutaka YOKOTA #define ARRAY_DELTA 4 73617b9080SKazutaka YOKOTA 746e8394b8SKazutaka YOKOTA static int 75617b9080SKazutaka YOKOTA vid_realloc_array(void) 76617b9080SKazutaka YOKOTA { 77617b9080SKazutaka YOKOTA video_adapter_t **new_adp; 78617b9080SKazutaka YOKOTA video_switch_t **new_vidsw; 796e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 80617b9080SKazutaka YOKOTA struct cdevsw **new_cdevsw; 816e8394b8SKazutaka YOKOTA #endif 82617b9080SKazutaka YOKOTA int newsize; 83617b9080SKazutaka YOKOTA int s; 84617b9080SKazutaka YOKOTA 856e8394b8SKazutaka YOKOTA if (!vid_malloc) 866e8394b8SKazutaka YOKOTA return ENOMEM; 876e8394b8SKazutaka YOKOTA 88617b9080SKazutaka YOKOTA s = spltty(); 89617b9080SKazutaka YOKOTA newsize = ((adapters + ARRAY_DELTA)/ARRAY_DELTA)*ARRAY_DELTA; 90a163d034SWarner Losh new_adp = malloc(sizeof(*new_adp)*newsize, M_DEVBUF, M_WAITOK | M_ZERO); 917cc0979fSDavid Malone new_vidsw = malloc(sizeof(*new_vidsw)*newsize, M_DEVBUF, 92a163d034SWarner Losh M_WAITOK | M_ZERO); 936e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 947cc0979fSDavid Malone new_cdevsw = malloc(sizeof(*new_cdevsw)*newsize, M_DEVBUF, 95a163d034SWarner Losh M_WAITOK | M_ZERO); 966e8394b8SKazutaka YOKOTA #endif 97617b9080SKazutaka YOKOTA bcopy(adapter, new_adp, sizeof(*adapter)*adapters); 98617b9080SKazutaka YOKOTA bcopy(vidsw, new_vidsw, sizeof(*vidsw)*adapters); 996e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 100617b9080SKazutaka YOKOTA bcopy(vidcdevsw, new_cdevsw, sizeof(*vidcdevsw)*adapters); 1016e8394b8SKazutaka YOKOTA #endif 102617b9080SKazutaka YOKOTA if (adapters > 1) { 103617b9080SKazutaka YOKOTA free(adapter, M_DEVBUF); 104617b9080SKazutaka YOKOTA free(vidsw, M_DEVBUF); 1056e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 106617b9080SKazutaka YOKOTA free(vidcdevsw, M_DEVBUF); 1076e8394b8SKazutaka YOKOTA #endif 108617b9080SKazutaka YOKOTA } 109617b9080SKazutaka YOKOTA adapter = new_adp; 110617b9080SKazutaka YOKOTA vidsw = new_vidsw; 1116e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 112617b9080SKazutaka YOKOTA vidcdevsw = new_cdevsw; 1136e8394b8SKazutaka YOKOTA #endif 114617b9080SKazutaka YOKOTA adapters = newsize; 115617b9080SKazutaka YOKOTA splx(s); 116617b9080SKazutaka YOKOTA 117617b9080SKazutaka YOKOTA if (bootverbose) 118617b9080SKazutaka YOKOTA printf("fb: new array size %d\n", adapters); 1196e8394b8SKazutaka YOKOTA 1206e8394b8SKazutaka YOKOTA return 0; 121617b9080SKazutaka YOKOTA } 122617b9080SKazutaka YOKOTA 1236e8394b8SKazutaka YOKOTA static void 1246e8394b8SKazutaka YOKOTA vid_malloc_init(void *arg) 1256e8394b8SKazutaka YOKOTA { 1266e8394b8SKazutaka YOKOTA vid_malloc = TRUE; 1276e8394b8SKazutaka YOKOTA } 1286e8394b8SKazutaka YOKOTA 1296e8394b8SKazutaka YOKOTA SYSINIT(vid_mem, SI_SUB_KMEM, SI_ORDER_ANY, vid_malloc_init, NULL); 13090500a9dSKazutaka YOKOTA 131617b9080SKazutaka YOKOTA /* 132617b9080SKazutaka YOKOTA * Low-level frame buffer driver functions 133617b9080SKazutaka YOKOTA * frame buffer subdrivers, such as the VGA driver, call these functions 134617b9080SKazutaka YOKOTA * to initialize the video_adapter structure and register it to the virtual 135617b9080SKazutaka YOKOTA * frame buffer driver `fb'. 136617b9080SKazutaka YOKOTA */ 137617b9080SKazutaka YOKOTA 138617b9080SKazutaka YOKOTA /* initialize the video_adapter_t structure */ 139617b9080SKazutaka YOKOTA void 140617b9080SKazutaka YOKOTA vid_init_struct(video_adapter_t *adp, char *name, int type, int unit) 141617b9080SKazutaka YOKOTA { 142617b9080SKazutaka YOKOTA adp->va_flags = 0; 143617b9080SKazutaka YOKOTA adp->va_name = name; 144617b9080SKazutaka YOKOTA adp->va_type = type; 145617b9080SKazutaka YOKOTA adp->va_unit = unit; 146617b9080SKazutaka YOKOTA } 147617b9080SKazutaka YOKOTA 148617b9080SKazutaka YOKOTA /* Register a video adapter */ 149617b9080SKazutaka YOKOTA int 150617b9080SKazutaka YOKOTA vid_register(video_adapter_t *adp) 151617b9080SKazutaka YOKOTA { 1526e8394b8SKazutaka YOKOTA const video_driver_t **list; 1536e8394b8SKazutaka YOKOTA const video_driver_t *p; 154617b9080SKazutaka YOKOTA int index; 155617b9080SKazutaka YOKOTA 156617b9080SKazutaka YOKOTA for (index = 0; index < adapters; ++index) { 157617b9080SKazutaka YOKOTA if (adapter[index] == NULL) 158617b9080SKazutaka YOKOTA break; 159617b9080SKazutaka YOKOTA } 1606e8394b8SKazutaka YOKOTA if (index >= adapters) { 1616e8394b8SKazutaka YOKOTA if (vid_realloc_array()) 162617b9080SKazutaka YOKOTA return -1; 1636e8394b8SKazutaka YOKOTA } 164617b9080SKazutaka YOKOTA 165617b9080SKazutaka YOKOTA adp->va_index = index; 166617b9080SKazutaka YOKOTA adp->va_token = NULL; 167f41325dbSPeter Wemm SET_FOREACH(list, videodriver_set) { 168f41325dbSPeter Wemm p = *list; 169617b9080SKazutaka YOKOTA if (strcmp(p->name, adp->va_name) == 0) { 170617b9080SKazutaka YOKOTA adapter[index] = adp; 171617b9080SKazutaka YOKOTA vidsw[index] = p->vidsw; 172617b9080SKazutaka YOKOTA return index; 173617b9080SKazutaka YOKOTA } 174617b9080SKazutaka YOKOTA } 175617b9080SKazutaka YOKOTA 176617b9080SKazutaka YOKOTA return -1; 177617b9080SKazutaka YOKOTA } 178617b9080SKazutaka YOKOTA 179617b9080SKazutaka YOKOTA int 180617b9080SKazutaka YOKOTA vid_unregister(video_adapter_t *adp) 181617b9080SKazutaka YOKOTA { 182617b9080SKazutaka YOKOTA if ((adp->va_index < 0) || (adp->va_index >= adapters)) 183617b9080SKazutaka YOKOTA return ENOENT; 184617b9080SKazutaka YOKOTA if (adapter[adp->va_index] != adp) 185617b9080SKazutaka YOKOTA return ENOENT; 186617b9080SKazutaka YOKOTA 187617b9080SKazutaka YOKOTA adapter[adp->va_index] = NULL; 188617b9080SKazutaka YOKOTA vidsw[adp->va_index] = NULL; 189617b9080SKazutaka YOKOTA return 0; 190617b9080SKazutaka YOKOTA } 191617b9080SKazutaka YOKOTA 192617b9080SKazutaka YOKOTA /* Get video I/O function table */ 193617b9080SKazutaka YOKOTA video_switch_t 194617b9080SKazutaka YOKOTA *vid_get_switch(char *name) 195617b9080SKazutaka YOKOTA { 1966e8394b8SKazutaka YOKOTA const video_driver_t **list; 1976e8394b8SKazutaka YOKOTA const video_driver_t *p; 198617b9080SKazutaka YOKOTA 199f41325dbSPeter Wemm SET_FOREACH(list, videodriver_set) { 200f41325dbSPeter Wemm p = *list; 201617b9080SKazutaka YOKOTA if (strcmp(p->name, name) == 0) 202617b9080SKazutaka YOKOTA return p->vidsw; 203617b9080SKazutaka YOKOTA } 204617b9080SKazutaka YOKOTA 205617b9080SKazutaka YOKOTA return NULL; 206617b9080SKazutaka YOKOTA } 207617b9080SKazutaka YOKOTA 208617b9080SKazutaka YOKOTA /* 209617b9080SKazutaka YOKOTA * Video card client functions 210617b9080SKazutaka YOKOTA * Video card clients, such as the console driver `syscons' and the frame 211617b9080SKazutaka YOKOTA * buffer cdev driver, use these functions to claim and release a card for 212617b9080SKazutaka YOKOTA * exclusive use. 213617b9080SKazutaka YOKOTA */ 214617b9080SKazutaka YOKOTA 215617b9080SKazutaka YOKOTA /* find the video card specified by a driver name and a unit number */ 216617b9080SKazutaka YOKOTA int 217617b9080SKazutaka YOKOTA vid_find_adapter(char *driver, int unit) 218617b9080SKazutaka YOKOTA { 219617b9080SKazutaka YOKOTA int i; 220617b9080SKazutaka YOKOTA 221617b9080SKazutaka YOKOTA for (i = 0; i < adapters; ++i) { 222617b9080SKazutaka YOKOTA if (adapter[i] == NULL) 223617b9080SKazutaka YOKOTA continue; 224617b9080SKazutaka YOKOTA if (strcmp("*", driver) && strcmp(adapter[i]->va_name, driver)) 225617b9080SKazutaka YOKOTA continue; 226617b9080SKazutaka YOKOTA if ((unit != -1) && (adapter[i]->va_unit != unit)) 227617b9080SKazutaka YOKOTA continue; 228617b9080SKazutaka YOKOTA return i; 229617b9080SKazutaka YOKOTA } 230617b9080SKazutaka YOKOTA return -1; 231617b9080SKazutaka YOKOTA } 232617b9080SKazutaka YOKOTA 233617b9080SKazutaka YOKOTA /* allocate a video card */ 234617b9080SKazutaka YOKOTA int 235617b9080SKazutaka YOKOTA vid_allocate(char *driver, int unit, void *id) 236617b9080SKazutaka YOKOTA { 237617b9080SKazutaka YOKOTA int index; 238617b9080SKazutaka YOKOTA int s; 239617b9080SKazutaka YOKOTA 240617b9080SKazutaka YOKOTA s = spltty(); 241617b9080SKazutaka YOKOTA index = vid_find_adapter(driver, unit); 242617b9080SKazutaka YOKOTA if (index >= 0) { 243617b9080SKazutaka YOKOTA if (adapter[index]->va_token) { 244617b9080SKazutaka YOKOTA splx(s); 245617b9080SKazutaka YOKOTA return -1; 246617b9080SKazutaka YOKOTA } 247617b9080SKazutaka YOKOTA adapter[index]->va_token = id; 248617b9080SKazutaka YOKOTA } 249617b9080SKazutaka YOKOTA splx(s); 250617b9080SKazutaka YOKOTA return index; 251617b9080SKazutaka YOKOTA } 252617b9080SKazutaka YOKOTA 253617b9080SKazutaka YOKOTA int 254617b9080SKazutaka YOKOTA vid_release(video_adapter_t *adp, void *id) 255617b9080SKazutaka YOKOTA { 256617b9080SKazutaka YOKOTA int error; 257617b9080SKazutaka YOKOTA int s; 258617b9080SKazutaka YOKOTA 259617b9080SKazutaka YOKOTA s = spltty(); 260617b9080SKazutaka YOKOTA if (adp->va_token == NULL) { 261617b9080SKazutaka YOKOTA error = EINVAL; 262617b9080SKazutaka YOKOTA } else if (adp->va_token != id) { 263617b9080SKazutaka YOKOTA error = EPERM; 264617b9080SKazutaka YOKOTA } else { 265617b9080SKazutaka YOKOTA adp->va_token = NULL; 266617b9080SKazutaka YOKOTA error = 0; 267617b9080SKazutaka YOKOTA } 268617b9080SKazutaka YOKOTA splx(s); 269617b9080SKazutaka YOKOTA return error; 270617b9080SKazutaka YOKOTA } 271617b9080SKazutaka YOKOTA 272617b9080SKazutaka YOKOTA /* Get a video adapter structure */ 273617b9080SKazutaka YOKOTA video_adapter_t 274617b9080SKazutaka YOKOTA *vid_get_adapter(int index) 275617b9080SKazutaka YOKOTA { 276617b9080SKazutaka YOKOTA if ((index < 0) || (index >= adapters)) 277617b9080SKazutaka YOKOTA return NULL; 278617b9080SKazutaka YOKOTA return adapter[index]; 279617b9080SKazutaka YOKOTA } 280617b9080SKazutaka YOKOTA 281617b9080SKazutaka YOKOTA /* Configure drivers: this is a backdoor for the console driver XXX */ 282617b9080SKazutaka YOKOTA int 283617b9080SKazutaka YOKOTA vid_configure(int flags) 284617b9080SKazutaka YOKOTA { 2856e8394b8SKazutaka YOKOTA const video_driver_t **list; 2866e8394b8SKazutaka YOKOTA const video_driver_t *p; 287617b9080SKazutaka YOKOTA 288f41325dbSPeter Wemm SET_FOREACH(list, videodriver_set) { 289f41325dbSPeter Wemm p = *list; 290617b9080SKazutaka YOKOTA if (p->configure != NULL) 291617b9080SKazutaka YOKOTA (*p->configure)(flags); 292617b9080SKazutaka YOKOTA } 293617b9080SKazutaka YOKOTA 294617b9080SKazutaka YOKOTA return 0; 295617b9080SKazutaka YOKOTA } 296617b9080SKazutaka YOKOTA 297617b9080SKazutaka YOKOTA /* 298617b9080SKazutaka YOKOTA * Virtual frame buffer cdev driver functions 299617b9080SKazutaka YOKOTA * The virtual frame buffer driver dispatches driver functions to 300617b9080SKazutaka YOKOTA * appropriate subdrivers. 301617b9080SKazutaka YOKOTA */ 302617b9080SKazutaka YOKOTA 3036e8394b8SKazutaka YOKOTA #define FB_DRIVER_NAME "fb" 304617b9080SKazutaka YOKOTA 305617b9080SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 306617b9080SKazutaka YOKOTA 3076e8394b8SKazutaka YOKOTA #if experimental 3086e8394b8SKazutaka YOKOTA 3096e8394b8SKazutaka YOKOTA static devclass_t fb_devclass; 3106e8394b8SKazutaka YOKOTA 3116e8394b8SKazutaka YOKOTA static int fbprobe(device_t dev); 3126e8394b8SKazutaka YOKOTA static int fbattach(device_t dev); 3136e8394b8SKazutaka YOKOTA 3146e8394b8SKazutaka YOKOTA static device_method_t fb_methods[] = { 3156e8394b8SKazutaka YOKOTA DEVMETHOD(device_probe, fbprobe), 3166e8394b8SKazutaka YOKOTA DEVMETHOD(device_attach, fbattach), 3176e8394b8SKazutaka YOKOTA 3186e8394b8SKazutaka YOKOTA DEVMETHOD(bus_print_child, bus_generic_print_child), 3196e8394b8SKazutaka YOKOTA { 0, 0 } 3206e8394b8SKazutaka YOKOTA }; 3216e8394b8SKazutaka YOKOTA 3226e8394b8SKazutaka YOKOTA static driver_t fb_driver = { 3236e8394b8SKazutaka YOKOTA FB_DRIVER_NAME, 3246e8394b8SKazutaka YOKOTA fb_methods, 3256e8394b8SKazutaka YOKOTA 0, 3266e8394b8SKazutaka YOKOTA }; 3276e8394b8SKazutaka YOKOTA 3286e8394b8SKazutaka YOKOTA static int 3296e8394b8SKazutaka YOKOTA fbprobe(device_t dev) 3306e8394b8SKazutaka YOKOTA { 3316e8394b8SKazutaka YOKOTA int unit; 3326e8394b8SKazutaka YOKOTA 3336e8394b8SKazutaka YOKOTA unit = device_get_unit(dev); 3346e8394b8SKazutaka YOKOTA if (unit >= adapters) 3356e8394b8SKazutaka YOKOTA return ENXIO; 3366e8394b8SKazutaka YOKOTA if (adapter[unit] == NULL) 3376e8394b8SKazutaka YOKOTA return ENXIO; 3386e8394b8SKazutaka YOKOTA 3396e8394b8SKazutaka YOKOTA device_set_desc(dev, "generic frame buffer"); 3406e8394b8SKazutaka YOKOTA return 0; 3416e8394b8SKazutaka YOKOTA } 3426e8394b8SKazutaka YOKOTA 3436e8394b8SKazutaka YOKOTA static int 3446e8394b8SKazutaka YOKOTA fbattach(device_t dev) 3456e8394b8SKazutaka YOKOTA { 3466e8394b8SKazutaka YOKOTA printf("fbattach: about to attach children\n"); 3476e8394b8SKazutaka YOKOTA bus_generic_attach(dev); 3486e8394b8SKazutaka YOKOTA return 0; 3496e8394b8SKazutaka YOKOTA } 3506e8394b8SKazutaka YOKOTA 3516e8394b8SKazutaka YOKOTA #endif /* experimental */ 3526e8394b8SKazutaka YOKOTA 353617b9080SKazutaka YOKOTA #define FB_UNIT(dev) minor(dev) 354617b9080SKazutaka YOKOTA #define FB_MKMINOR(unit) (u) 355617b9080SKazutaka YOKOTA 3566d473442SPoul-Henning Kamp #if experimental 357617b9080SKazutaka YOKOTA static d_open_t fbopen; 358617b9080SKazutaka YOKOTA static d_close_t fbclose; 3596e8394b8SKazutaka YOKOTA static d_read_t fbread; 3606e8394b8SKazutaka YOKOTA static d_write_t fbwrite; 361617b9080SKazutaka YOKOTA static d_ioctl_t fbioctl; 362617b9080SKazutaka YOKOTA static d_mmap_t fbmmap; 363617b9080SKazutaka YOKOTA 3646e8394b8SKazutaka YOKOTA #define CDEV_MAJOR 123 /* XXX */ 365617b9080SKazutaka YOKOTA 366617b9080SKazutaka YOKOTA static struct cdevsw fb_cdevsw = { 3677ac40f5fSPoul-Henning Kamp .d_open = fbopen, 3687ac40f5fSPoul-Henning Kamp .d_close = fbclose, 3697ac40f5fSPoul-Henning Kamp .d_read = fbread, 3707ac40f5fSPoul-Henning Kamp .d_write = fbwrite, 3717ac40f5fSPoul-Henning Kamp .d_ioctl = fbioctl, 3727ac40f5fSPoul-Henning Kamp .d_mmap = fbmmap, 3737ac40f5fSPoul-Henning Kamp .d_name = FB_DRIVER_NAME, 3747ac40f5fSPoul-Henning Kamp .d_maj = CDEV_MAJOR, 375617b9080SKazutaka YOKOTA }; 3766d473442SPoul-Henning Kamp #endif 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: 3852b120974SPeter Wemm break; 3862b120974SPeter Wemm case MOD_UNLOAD: 3872b120974SPeter Wemm printf("fb module unload - not possible for this module type\n"); 3882b120974SPeter Wemm return EINVAL; 389617b9080SKazutaka YOKOTA } 3902b120974SPeter Wemm return 0; 391617b9080SKazutaka YOKOTA } 392617b9080SKazutaka YOKOTA 3932b120974SPeter Wemm static moduledata_t fb_mod = { 3942b120974SPeter Wemm "fb", 3952b120974SPeter Wemm fb_modevent, 3962b120974SPeter Wemm NULL 3972b120974SPeter Wemm }; 3982b120974SPeter Wemm 3992b120974SPeter Wemm DECLARE_MODULE(fb, fb_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 400617b9080SKazutaka YOKOTA 401617b9080SKazutaka YOKOTA int 4026e8394b8SKazutaka YOKOTA fb_attach(dev_t dev, video_adapter_t *adp, struct cdevsw *cdevsw) 403617b9080SKazutaka YOKOTA { 404617b9080SKazutaka YOKOTA int s; 405617b9080SKazutaka YOKOTA 406617b9080SKazutaka YOKOTA if (adp->va_index >= adapters) 407617b9080SKazutaka YOKOTA return EINVAL; 408617b9080SKazutaka YOKOTA if (adapter[adp->va_index] != adp) 409617b9080SKazutaka YOKOTA return EINVAL; 410617b9080SKazutaka YOKOTA 411617b9080SKazutaka YOKOTA s = spltty(); 412617b9080SKazutaka YOKOTA adp->va_minor = minor(dev); 413617b9080SKazutaka YOKOTA vidcdevsw[adp->va_index] = cdevsw; 414617b9080SKazutaka YOKOTA splx(s); 415617b9080SKazutaka YOKOTA 416617b9080SKazutaka YOKOTA printf("fb%d at %s%d\n", adp->va_index, adp->va_name, adp->va_unit); 417617b9080SKazutaka YOKOTA return 0; 418617b9080SKazutaka YOKOTA } 419617b9080SKazutaka YOKOTA 420617b9080SKazutaka YOKOTA int 4216e8394b8SKazutaka YOKOTA fb_detach(dev_t dev, video_adapter_t *adp, struct cdevsw *cdevsw) 422617b9080SKazutaka YOKOTA { 423617b9080SKazutaka YOKOTA int s; 424617b9080SKazutaka YOKOTA 425617b9080SKazutaka YOKOTA if (adp->va_index >= adapters) 426617b9080SKazutaka YOKOTA return EINVAL; 427617b9080SKazutaka YOKOTA if (adapter[adp->va_index] != adp) 428617b9080SKazutaka YOKOTA return EINVAL; 429617b9080SKazutaka YOKOTA if (vidcdevsw[adp->va_index] != cdevsw) 430617b9080SKazutaka YOKOTA return EINVAL; 431617b9080SKazutaka YOKOTA 432617b9080SKazutaka YOKOTA s = spltty(); 433617b9080SKazutaka YOKOTA vidcdevsw[adp->va_index] = NULL; 434617b9080SKazutaka YOKOTA splx(s); 435617b9080SKazutaka YOKOTA return 0; 436617b9080SKazutaka YOKOTA } 437617b9080SKazutaka YOKOTA 4386d473442SPoul-Henning Kamp #if experimental 4396e8394b8SKazutaka YOKOTA static int 440b40ce416SJulian Elischer fbopen(dev_t dev, int flag, int mode, struct thread *td) 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), 450b40ce416SJulian Elischer flag, mode, td); 4516e8394b8SKazutaka YOKOTA } 4526e8394b8SKazutaka YOKOTA 4536e8394b8SKazutaka YOKOTA static int 454b40ce416SJulian Elischer fbclose(dev_t dev, int flag, int mode, struct thread *td) 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), 462b40ce416SJulian Elischer flag, mode, td); 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 490b40ce416SJulian Elischer fbioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct thread *td) 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), 498b40ce416SJulian Elischer cmd, arg, flag, td); 4996e8394b8SKazutaka YOKOTA } 5006e8394b8SKazutaka YOKOTA 5016e8394b8SKazutaka YOKOTA static int 502227f9a1cSJake Burkholder fbmmap(dev_t dev, vm_offset_t offset, vm_paddr_t *paddr, 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), 51007159f9cSMaxime Henrion offset, paddr, nprot); 5116e8394b8SKazutaka YOKOTA } 5126e8394b8SKazutaka YOKOTA 513dfc161b4SJake Burkholder DEV_DRIVER_MODULE(fb, foo, fb_driver, fb_devclass, fb_cdevsw, 0, 0); 5146e8394b8SKazutaka YOKOTA #endif 5156e8394b8SKazutaka YOKOTA 5166e8394b8SKazutaka YOKOTA /* 5176e8394b8SKazutaka YOKOTA * Generic frame buffer cdev driver functions 5186e8394b8SKazutaka YOKOTA * Frame buffer subdrivers may call these functions to implement common 5196e8394b8SKazutaka YOKOTA * driver functions. 5206e8394b8SKazutaka YOKOTA */ 5216e8394b8SKazutaka YOKOTA 5226e8394b8SKazutaka YOKOTA int genfbopen(genfb_softc_t *sc, video_adapter_t *adp, int flag, int mode, 523b40ce416SJulian Elischer struct thread *td) 5246e8394b8SKazutaka YOKOTA { 5256e8394b8SKazutaka YOKOTA int s; 5266e8394b8SKazutaka YOKOTA 5276e8394b8SKazutaka YOKOTA s = spltty(); 5286e8394b8SKazutaka YOKOTA if (!(sc->gfb_flags & FB_OPEN)) 5296e8394b8SKazutaka YOKOTA sc->gfb_flags |= FB_OPEN; 5306e8394b8SKazutaka YOKOTA splx(s); 5316e8394b8SKazutaka YOKOTA return 0; 5326e8394b8SKazutaka YOKOTA } 5336e8394b8SKazutaka YOKOTA 5346e8394b8SKazutaka YOKOTA int genfbclose(genfb_softc_t *sc, video_adapter_t *adp, int flag, int mode, 535b40ce416SJulian Elischer struct thread *td) 5366e8394b8SKazutaka YOKOTA { 5376e8394b8SKazutaka YOKOTA int s; 5386e8394b8SKazutaka YOKOTA 5396e8394b8SKazutaka YOKOTA s = spltty(); 5406e8394b8SKazutaka YOKOTA sc->gfb_flags &= ~FB_OPEN; 5416e8394b8SKazutaka YOKOTA splx(s); 5426e8394b8SKazutaka YOKOTA return 0; 5436e8394b8SKazutaka YOKOTA } 5446e8394b8SKazutaka YOKOTA 5456e8394b8SKazutaka YOKOTA int genfbread(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio, 5466e8394b8SKazutaka YOKOTA int flag) 5476e8394b8SKazutaka YOKOTA { 5486e8394b8SKazutaka YOKOTA int size; 5496e8394b8SKazutaka YOKOTA int offset; 5506e8394b8SKazutaka YOKOTA int error; 5516e8394b8SKazutaka YOKOTA int len; 5526e8394b8SKazutaka YOKOTA 5536e8394b8SKazutaka YOKOTA error = 0; 5546e8394b8SKazutaka YOKOTA size = adp->va_buffer_size/adp->va_info.vi_planes; 5556e8394b8SKazutaka YOKOTA while (uio->uio_resid > 0) { 5566e8394b8SKazutaka YOKOTA if (uio->uio_offset >= size) 5576e8394b8SKazutaka YOKOTA break; 5586e8394b8SKazutaka YOKOTA offset = uio->uio_offset%adp->va_window_size; 5596e8394b8SKazutaka YOKOTA len = imin(uio->uio_resid, size - uio->uio_offset); 5606e8394b8SKazutaka YOKOTA len = imin(len, adp->va_window_size - offset); 5616e8394b8SKazutaka YOKOTA if (len <= 0) 5626e8394b8SKazutaka YOKOTA break; 5636e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, uio->uio_offset); 5646e8394b8SKazutaka YOKOTA error = uiomove((caddr_t)(adp->va_window + offset), len, uio); 5656e8394b8SKazutaka YOKOTA if (error) 5666e8394b8SKazutaka YOKOTA break; 5676e8394b8SKazutaka YOKOTA } 5686e8394b8SKazutaka YOKOTA return error; 5696e8394b8SKazutaka YOKOTA } 5706e8394b8SKazutaka YOKOTA 5716e8394b8SKazutaka YOKOTA int genfbwrite(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio, 5726e8394b8SKazutaka YOKOTA int flag) 5736e8394b8SKazutaka YOKOTA { 5746e8394b8SKazutaka YOKOTA return ENODEV; 5756e8394b8SKazutaka YOKOTA } 5766e8394b8SKazutaka YOKOTA 5776e8394b8SKazutaka YOKOTA int genfbioctl(genfb_softc_t *sc, video_adapter_t *adp, u_long cmd, 578b40ce416SJulian Elischer caddr_t arg, int flag, struct thread *td) 5796e8394b8SKazutaka YOKOTA { 5806e8394b8SKazutaka YOKOTA int error; 5816e8394b8SKazutaka YOKOTA 5826e8394b8SKazutaka YOKOTA if (adp == NULL) /* XXX */ 5836e8394b8SKazutaka YOKOTA return ENXIO; 5846e8394b8SKazutaka YOKOTA error = (*vidsw[adp->va_index]->ioctl)(adp, cmd, arg); 5856e8394b8SKazutaka YOKOTA if (error == ENOIOCTL) 5866e8394b8SKazutaka YOKOTA error = ENODEV; 5876e8394b8SKazutaka YOKOTA return error; 5886e8394b8SKazutaka YOKOTA } 5896e8394b8SKazutaka YOKOTA 5906e8394b8SKazutaka YOKOTA int genfbmmap(genfb_softc_t *sc, video_adapter_t *adp, vm_offset_t offset, 59107159f9cSMaxime Henrion vm_offset_t *paddr, int prot) 5926e8394b8SKazutaka YOKOTA { 59307159f9cSMaxime Henrion return (*vidsw[adp->va_index]->mmap)(adp, offset, paddr, prot); 5946e8394b8SKazutaka YOKOTA } 5956e8394b8SKazutaka YOKOTA 596617b9080SKazutaka YOKOTA #endif /* FB_INSTALL_CDEV */ 597617b9080SKazutaka YOKOTA 598617b9080SKazutaka YOKOTA static char 599617b9080SKazutaka YOKOTA *adapter_name(int type) 600617b9080SKazutaka YOKOTA { 601617b9080SKazutaka YOKOTA static struct { 602617b9080SKazutaka YOKOTA int type; 603617b9080SKazutaka YOKOTA char *name; 604617b9080SKazutaka YOKOTA } names[] = { 605617b9080SKazutaka YOKOTA { KD_MONO, "MDA" }, 606617b9080SKazutaka YOKOTA { KD_HERCULES, "Hercules" }, 607617b9080SKazutaka YOKOTA { KD_CGA, "CGA" }, 608617b9080SKazutaka YOKOTA { KD_EGA, "EGA" }, 609617b9080SKazutaka YOKOTA { KD_VGA, "VGA" }, 610617b9080SKazutaka YOKOTA { KD_PC98, "PC-98x1" }, 6116e8394b8SKazutaka YOKOTA { KD_TGA, "TGA" }, 612617b9080SKazutaka YOKOTA { -1, "Unknown" }, 613617b9080SKazutaka YOKOTA }; 614617b9080SKazutaka YOKOTA int i; 615617b9080SKazutaka YOKOTA 616617b9080SKazutaka YOKOTA for (i = 0; names[i].type != -1; ++i) 617617b9080SKazutaka YOKOTA if (names[i].type == type) 618617b9080SKazutaka YOKOTA break; 619617b9080SKazutaka YOKOTA return names[i].name; 620617b9080SKazutaka YOKOTA } 621617b9080SKazutaka YOKOTA 6226e8394b8SKazutaka YOKOTA /* 6236e8394b8SKazutaka YOKOTA * Generic low-level frame buffer functions 6246e8394b8SKazutaka YOKOTA * The low-level functions in the frame buffer subdriver may use these 6256e8394b8SKazutaka YOKOTA * functions. 6266e8394b8SKazutaka YOKOTA */ 6276e8394b8SKazutaka YOKOTA 628617b9080SKazutaka YOKOTA void 629617b9080SKazutaka YOKOTA fb_dump_adp_info(char *driver, video_adapter_t *adp, int level) 630617b9080SKazutaka YOKOTA { 631617b9080SKazutaka YOKOTA if (level <= 0) 632617b9080SKazutaka YOKOTA return; 633617b9080SKazutaka YOKOTA 634617b9080SKazutaka YOKOTA printf("%s%d: %s%d, %s, type:%s (%d), flags:0x%x\n", 6356e8394b8SKazutaka YOKOTA FB_DRIVER_NAME, adp->va_index, driver, adp->va_unit, adp->va_name, 636617b9080SKazutaka YOKOTA adapter_name(adp->va_type), adp->va_type, adp->va_flags); 6370301e9c8SDavid E. O'Brien printf("%s%d: port:0x%lx-0x%lx, crtc:0x%lx, mem:0x%lx 0x%x\n", 6380301e9c8SDavid E. O'Brien FB_DRIVER_NAME, adp->va_index, (u_long)adp->va_io_base, 6390301e9c8SDavid E. O'Brien (u_long)adp->va_io_base + adp->va_io_size - 1, 6400301e9c8SDavid E. O'Brien (u_long)adp->va_crtc_addr, (u_long)adp->va_mem_base, 6410301e9c8SDavid E. O'Brien 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); 6700301e9c8SDavid E. O'Brien printf("win:0x%lx\n", (u_long)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 800eac47d67SKazutaka YOKOTA case FBIO_BLANK: /* blank display */ 801eac47d67SKazutaka YOKOTA error = (*vidsw[adp->va_index]->blank_display)(adp, *(int *)arg); 802eac47d67SKazutaka YOKOTA break; 803eac47d67SKazutaka YOKOTA 8046e8394b8SKazutaka YOKOTA case FBIO_GETPALETTE: /* get color palette */ 8056e8394b8SKazutaka YOKOTA case FBIO_SETPALETTE: /* set color palette */ 8066e8394b8SKazutaka YOKOTA /* XXX */ 8076e8394b8SKazutaka YOKOTA 8086e8394b8SKazutaka YOKOTA case FBIOPUTCMAP: 8096e8394b8SKazutaka YOKOTA case FBIOGETCMAP: 810eac47d67SKazutaka YOKOTA case FBIOPUTCMAPI: 811eac47d67SKazutaka YOKOTA case FBIOGETCMAPI: 8126e8394b8SKazutaka YOKOTA /* XXX */ 8136e8394b8SKazutaka YOKOTA 8146e8394b8SKazutaka YOKOTA case FBIO_SETWINORG: /* set frame buffer window origin */ 8156e8394b8SKazutaka YOKOTA case FBIO_SETDISPSTART: /* set display start address */ 8166e8394b8SKazutaka YOKOTA case FBIO_SETLINEWIDTH: /* set scan line width in pixel */ 8176e8394b8SKazutaka YOKOTA 8186e8394b8SKazutaka YOKOTA case FBIOGTYPE: 8196e8394b8SKazutaka YOKOTA case FBIOGATTR: 8206e8394b8SKazutaka YOKOTA case FBIOSVIDEO: 8216e8394b8SKazutaka YOKOTA case FBIOGVIDEO: 822eac47d67SKazutaka YOKOTA case FBIOVERTICAL: 8236e8394b8SKazutaka YOKOTA case FBIOSCURSOR: 8246e8394b8SKazutaka YOKOTA case FBIOGCURSOR: 8256e8394b8SKazutaka YOKOTA case FBIOSCURPOS: 8266e8394b8SKazutaka YOKOTA case FBIOGCURPOS: 8276e8394b8SKazutaka YOKOTA case FBIOGCURMAX: 828eac47d67SKazutaka YOKOTA case FBIOMONINFO: 829eac47d67SKazutaka YOKOTA case FBIOGXINFO: 8306e8394b8SKazutaka YOKOTA 8316e8394b8SKazutaka YOKOTA default: 8326e8394b8SKazutaka YOKOTA error = ENODEV; 8336e8394b8SKazutaka YOKOTA break; 8346e8394b8SKazutaka YOKOTA } 8356e8394b8SKazutaka YOKOTA 8366e8394b8SKazutaka YOKOTA splx(s); 8376e8394b8SKazutaka YOKOTA return error; 8386e8394b8SKazutaka YOKOTA } 839