1230557Sjimharris/*- 2230557Sjimharris * SPDX-License-Identifier: BSD-2-Clause 3230557Sjimharris * 4230557Sjimharris * Copyright (c) 1998 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 5230557Sjimharris * All rights reserved. 6230557Sjimharris * 7230557Sjimharris * This code is derived from software contributed to The DragonFly Project 8230557Sjimharris * by Sascha Wildner <saw@online.de> 9230557Sjimharris * 10230557Sjimharris * Redistribution and use in source and binary forms, with or without 11230557Sjimharris * modification, are permitted provided that the following conditions 12230557Sjimharris * are met: 13230557Sjimharris * 1. Redistributions of source code must retain the above copyright 14230557Sjimharris * notice, this list of conditions and the following disclaimer as 15230557Sjimharris * the first lines of this file unmodified. 16230557Sjimharris * 2. Redistributions in binary form must reproduce the above copyright 17230557Sjimharris * notice, this list of conditions and the following disclaimer in the 18230557Sjimharris * documentation and/or other materials provided with the distribution. 19230557Sjimharris * 20230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21230557Sjimharris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22230557Sjimharris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23230557Sjimharris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24230557Sjimharris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25230557Sjimharris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29230557Sjimharris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30230557Sjimharris * 31230557Sjimharris */ 32230557Sjimharris 33230557Sjimharris#include <sys/cdefs.h> 34230557Sjimharris#include "opt_vga.h" 35230557Sjimharris 36230557Sjimharris#ifndef VGA_NO_MODE_CHANGE 37230557Sjimharris 38230557Sjimharris#include <sys/param.h> 39230557Sjimharris#include <sys/systm.h> 40230557Sjimharris#include <sys/conf.h> 41230557Sjimharris#include <sys/tty.h> 42230557Sjimharris#include <sys/kernel.h> 43230557Sjimharris#include <sys/fbio.h> 44230557Sjimharris#include <sys/consio.h> 45230557Sjimharris 46230557Sjimharris#include <dev/fb/vesa.h> 47230557Sjimharris 48230557Sjimharris#include <dev/fb/fbreg.h> 49230557Sjimharris#include <dev/syscons/syscons.h> 50230557Sjimharris 51230557Sjimharrisstatic tsw_ioctl_t *prev_user_ioctl; 52230557Sjimharris 53230557Sjimharrisstatic int 54230557Sjimharrisvesa_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) 55230557Sjimharris{ 56230557Sjimharris scr_stat *scp; 57230557Sjimharris int mode; 58230557Sjimharris 59230557Sjimharris scp = SC_STAT(tp); 60230557Sjimharris 61230557Sjimharris switch (cmd) { 62230557Sjimharris /* generic text modes */ 63230557Sjimharris case SW_TEXT_132x25: case SW_TEXT_132x30: 64230557Sjimharris case SW_TEXT_132x43: case SW_TEXT_132x50: 65230557Sjimharris case SW_TEXT_132x60: 66230557Sjimharris if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) 67230557Sjimharris return ENODEV; 68230557Sjimharris return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0, 0); 69230557Sjimharris 70230557Sjimharris /* text modes */ 71230557Sjimharris case SW_VESA_C80x60: 72230557Sjimharris case SW_VESA_C132x25: 73230557Sjimharris case SW_VESA_C132x43: 74230557Sjimharris case SW_VESA_C132x50: 75230557Sjimharris case SW_VESA_C132x60: 76230557Sjimharris if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) 77230557Sjimharris return ENODEV; 78230557Sjimharris mode = (cmd & 0xff) + M_VESA_BASE; 79230557Sjimharris return sc_set_text_mode(scp, tp, mode, 0, 0, 0, 0); 80230557Sjimharris 81230557Sjimharris /* graphics modes */ 82230557Sjimharris case SW_VESA_32K_320: case SW_VESA_64K_320: 83230557Sjimharris case SW_VESA_FULL_320: 84230557Sjimharris 85230557Sjimharris case SW_VESA_CG640x400: 86230557Sjimharris 87230557Sjimharris case SW_VESA_CG640x480: 88230557Sjimharris case SW_VESA_32K_640: case SW_VESA_64K_640: 89230557Sjimharris case SW_VESA_FULL_640: 90230557Sjimharris 91230557Sjimharris case SW_VESA_800x600: case SW_VESA_CG800x600: 92230557Sjimharris case SW_VESA_32K_800: case SW_VESA_64K_800: 93230557Sjimharris case SW_VESA_FULL_800: 94230557Sjimharris 95230557Sjimharris case SW_VESA_1024x768: case SW_VESA_CG1024x768: 96230557Sjimharris case SW_VESA_32K_1024: case SW_VESA_64K_1024: 97230557Sjimharris case SW_VESA_FULL_1024: 98230557Sjimharris 99230557Sjimharris case SW_VESA_1280x1024: case SW_VESA_CG1280x1024: 100230557Sjimharris case SW_VESA_32K_1280: case SW_VESA_64K_1280: 101230557Sjimharris case SW_VESA_FULL_1280: 102230557Sjimharris if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) 103230557Sjimharris return ENODEV; 104230557Sjimharris mode = (cmd & 0xff) + M_VESA_BASE; 105230557Sjimharris return sc_set_graphics_mode(scp, tp, mode); 106230557Sjimharris default: 107230557Sjimharris if (IOCGROUP(cmd) == 'V') { 108230557Sjimharris if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) 109230557Sjimharris return ENODEV; 110230557Sjimharris 111230557Sjimharris mode = (cmd & 0xff) + M_VESA_BASE; 112230557Sjimharris 113230557Sjimharris if (((cmd & IOC_DIRMASK) == IOC_VOID) && 114230557Sjimharris (mode > M_VESA_FULL_1280) && 115230557Sjimharris (mode < M_VESA_MODE_MAX)) 116230557Sjimharris return sc_set_graphics_mode(scp, tp, mode); 117230557Sjimharris } 118230557Sjimharris } 119230557Sjimharris 120230557Sjimharris if (prev_user_ioctl) 121230557Sjimharris return (*prev_user_ioctl)(tp, cmd, data, td); 122230557Sjimharris else 123230557Sjimharris return ENOIOCTL; 124230557Sjimharris} 125230557Sjimharris 126230557Sjimharrisint 127230557Sjimharrisvesa_load_ioctl(void) 128230557Sjimharris{ 129230557Sjimharris if (prev_user_ioctl) 130230557Sjimharris return EBUSY; 131230557Sjimharris prev_user_ioctl = sc_user_ioctl; 132230557Sjimharris sc_user_ioctl = vesa_ioctl; 133230557Sjimharris return 0; 134230557Sjimharris} 135230557Sjimharris 136230557Sjimharrisint 137230557Sjimharrisvesa_unload_ioctl(void) 138230557Sjimharris{ 139230557Sjimharris if (sc_user_ioctl != vesa_ioctl) 140230557Sjimharris return EBUSY; 141230557Sjimharris sc_user_ioctl = prev_user_ioctl; 142230557Sjimharris prev_user_ioctl = NULL; 143230557Sjimharris return 0; 144230557Sjimharris} 145230557Sjimharris 146230557Sjimharris#endif /* VGA_NO_MODE_CHANGE */ 147230557Sjimharris