scvesactl.c revision 149640
11553Srgrimes/*- 21553Srgrimes * Copyright (c) 1998 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 31553Srgrimes * All rights reserved. 41553Srgrimes * 51553Srgrimes * This code is derived from software contributed to The DragonFly Project 61553Srgrimes * by Sascha Wildner <saw@online.de> 71553Srgrimes * 81553Srgrimes * Redistribution and use in source and binary forms, with or without 91553Srgrimes * modification, are permitted provided that the following conditions 101553Srgrimes * are met: 111553Srgrimes * 1. Redistributions of source code must retain the above copyright 121553Srgrimes * notice, this list of conditions and the following disclaimer as 131553Srgrimes * the first lines of this file unmodified. 141553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 151553Srgrimes * notice, this list of conditions and the following disclaimer in the 161553Srgrimes * documentation and/or other materials provided with the distribution. 171553Srgrimes * 181553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 191553Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 201553Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 211553Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 221553Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 231553Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 241553Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 251553Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 261553Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 271553Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 281553Srgrimes * 291553Srgrimes */ 301553Srgrimes 311553Srgrimes#include <sys/cdefs.h> 321553Srgrimes__FBSDID("$FreeBSD: head/sys/dev/syscons/scvesactl.c 149640 2005-08-30 18:58:17Z rodrigc $"); 331553Srgrimes 341553Srgrimes#include "opt_vga.h" 351553Srgrimes 3629780Scharnier#ifndef VGA_NO_MODE_CHANGE 371553Srgrimes 381553Srgrimes#include <sys/param.h> 391553Srgrimes#include <sys/systm.h> 401553Srgrimes#include <sys/conf.h> 411553Srgrimes#include <sys/tty.h> 4229780Scharnier#include <sys/kernel.h> 4315637Sjoerg#include <sys/fbio.h> 4429780Scharnier#include <sys/consio.h> 4529780Scharnier 4650042Smdodd#include <machine/pc/vesa.h> 471553Srgrimes 481553Srgrimes#include <dev/fb/fbreg.h> 491553Srgrimes#include <dev/syscons/syscons.h> 501553Srgrimes 5129780Scharnierstatic d_ioctl_t *prev_user_ioctl; 521553Srgrimes 5331492Swollmanstatic int 5429780Scharniervesa_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) 5529780Scharnier{ 561553Srgrimes scr_stat *scp; 5729780Scharnier struct tty *tp; 5829780Scharnier int mode; 591553Srgrimes 6029780Scharnier tp = dev->si_tty; 611553Srgrimes if (!tp) 6250039Smdodd return ENXIO; 6331492Swollman scp = SC_STAT(tp->t_dev); 641553Srgrimes 651553Srgrimes switch (cmd) { 661553Srgrimes 671553Srgrimes /* generic text modes */ 6815637Sjoerg case SW_TEXT_132x25: case SW_TEXT_132x30: 6915637Sjoerg case SW_TEXT_132x43: case SW_TEXT_132x50: 7015637Sjoerg case SW_TEXT_132x60: 7115637Sjoerg if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) 721553Srgrimes return ENODEV; 731553Srgrimes return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0, 0); 741553Srgrimes 751553Srgrimes /* text modes */ 7627618Simp case SW_VESA_C80x60: 7727618Simp case SW_VESA_C132x25: 7839084Swollman case SW_VESA_C132x43: 791553Srgrimes case SW_VESA_C132x50: 8039084Swollman case SW_VESA_C132x60: 8139084Swollman if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) 8239084Swollman return ENODEV; 8339084Swollman mode = (cmd & 0xff) + M_VESA_BASE; 841553Srgrimes return sc_set_text_mode(scp, tp, mode, 0, 0, 0, 0); 8539084Swollman 8650039Smdodd /* graphics modes */ 871553Srgrimes case SW_VESA_32K_320: case SW_VESA_64K_320: 881553Srgrimes case SW_VESA_FULL_320: 891553Srgrimes 9015637Sjoerg case SW_VESA_CG640x400: 911553Srgrimes 921553Srgrimes case SW_VESA_CG640x480: 931553Srgrimes case SW_VESA_32K_640: case SW_VESA_64K_640: 941553Srgrimes case SW_VESA_FULL_640: 951553Srgrimes 961553Srgrimes case SW_VESA_800x600: case SW_VESA_CG800x600: 971553Srgrimes case SW_VESA_32K_800: case SW_VESA_64K_800: 981553Srgrimes case SW_VESA_FULL_800: 9927618Simp 10027618Simp case SW_VESA_1024x768: case SW_VESA_CG1024x768: 10127618Simp case SW_VESA_32K_1024: case SW_VESA_64K_1024: 1021553Srgrimes case SW_VESA_FULL_1024: 1031553Srgrimes 1041553Srgrimes case SW_VESA_1280x1024: case SW_VESA_CG1280x1024: 1051553Srgrimes case SW_VESA_32K_1280: case SW_VESA_64K_1280: 1061553Srgrimes case SW_VESA_FULL_1280: 1071553Srgrimes if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) 1081553Srgrimes return ENODEV; 1091553Srgrimes mode = (cmd & 0xff) + M_VESA_BASE; 1101553Srgrimes return sc_set_graphics_mode(scp, tp, mode); 1111553Srgrimes default: 1121553Srgrimes if (IOCGROUP(cmd) == 'V') { 1131553Srgrimes if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) 1141553Srgrimes return ENODEV; 11515637Sjoerg 1161553Srgrimes mode = (cmd & 0xff) + M_VESA_BASE; 1171553Srgrimes 1181553Srgrimes /* Only set graphics mode in non-pcvt case */ 11931492Swollman if (((cmd & IOC_DIRMASK) == IOC_VOID) && 12031492Swollman (mode > M_VESA_FULL_1280) && 12131492Swollman (mode < M_VESA_MODE_MAX)) 12231492Swollman return sc_set_graphics_mode(scp, tp, mode); 1231553Srgrimes } 1241553Srgrimes } 1251553Srgrimes 12650039Smdodd if (prev_user_ioctl) 1271553Srgrimes return (*prev_user_ioctl)(dev, cmd, data, flag, td); 1281553Srgrimes else 12950039Smdodd return ENOIOCTL; 1301553Srgrimes} 1311553Srgrimes 1321553Srgrimesint 1331553Srgrimesvesa_load_ioctl(void) 1341553Srgrimes{ 1351553Srgrimes if (prev_user_ioctl) 1361553Srgrimes return EBUSY; 13750039Smdodd prev_user_ioctl = sc_user_ioctl; 1381553Srgrimes sc_user_ioctl = vesa_ioctl; 1391553Srgrimes return 0; 14050039Smdodd} 14150039Smdodd 14250039Smdoddint 14350039Smdoddvesa_unload_ioctl(void) 14450039Smdodd{ 14550039Smdodd if (sc_user_ioctl != vesa_ioctl) 1461553Srgrimes return EBUSY; 1471553Srgrimes sc_user_ioctl = prev_user_ioctl; 1481553Srgrimes prev_user_ioctl = NULL; 1491553Srgrimes return 0; 15050039Smdodd} 1511553Srgrimes 1521553Srgrimes#endif /* SC_NO_MODE_CHANGE */ 15350039Smdodd