1 1.3 christos /* $NetBSD: unixcons.c,v 1.3 2014/03/26 08:02:38 christos Exp $ */ 2 1.1 nonaka 3 1.1 nonaka /* 4 1.1 nonaka * Copyright (c) 2009 NONAKA Kimihiro <nonaka (at) netbsd.org> 5 1.1 nonaka * All rights reserved. 6 1.1 nonaka * 7 1.1 nonaka * Redistribution and use in source and binary forms, with or without 8 1.1 nonaka * modification, are permitted provided that the following conditions 9 1.1 nonaka * are met: 10 1.1 nonaka * 1. Redistributions of source code must retain the above copyright 11 1.1 nonaka * notice, this list of conditions and the following disclaimer. 12 1.1 nonaka * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 nonaka * notice, this list of conditions and the following disclaimer in the 14 1.1 nonaka * documentation and/or other materials provided with the distribution. 15 1.1 nonaka * 16 1.1 nonaka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 nonaka * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 nonaka * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 nonaka * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 nonaka * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.1 nonaka * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.1 nonaka * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.1 nonaka * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.1 nonaka * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.1 nonaka * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 1.1 nonaka */ 27 1.1 nonaka 28 1.1 nonaka #include "boot.h" 29 1.1 nonaka #include "bootinfo.h" 30 1.1 nonaka #include "unixdev.h" 31 1.1 nonaka 32 1.1 nonaka #include "compat_linux.h" 33 1.1 nonaka #include "termios.h" 34 1.1 nonaka 35 1.1 nonaka struct btinfo_console bi_cons; 36 1.1 nonaka 37 1.1 nonaka static int iodev = CONSDEV_GLASS; 38 1.1 nonaka static int infd = 0; 39 1.1 nonaka static int outfd = 1; 40 1.1 nonaka 41 1.1 nonaka static const char *comdevname[] = { 42 1.1 nonaka "/dev/ttyS0", 43 1.1 nonaka }; 44 1.1 nonaka 45 1.1 nonaka static void common_putc(int fd, int c); 46 1.1 nonaka static int common_getc(int fd, int timo); 47 1.1 nonaka 48 1.1 nonaka void 49 1.1 nonaka consinit(int dev, int speed) 50 1.1 nonaka { 51 1.1 nonaka struct linux_termios termios; 52 1.1 nonaka int fd; 53 1.1 nonaka 54 1.1 nonaka switch (dev) { 55 1.1 nonaka case CONSDEV_COM0: 56 1.1 nonaka iodev = dev; 57 1.1 nonaka break; 58 1.1 nonaka 59 1.1 nonaka case CONSDEV_GLASS: 60 1.1 nonaka default: 61 1.1 nonaka glass_console: 62 1.1 nonaka iodev = CONSDEV_GLASS; 63 1.1 nonaka break; 64 1.1 nonaka } 65 1.1 nonaka 66 1.1 nonaka if (infd >= 0 && infd == outfd) { 67 1.1 nonaka uclose(infd); 68 1.1 nonaka infd = 0; 69 1.1 nonaka outfd = 1; 70 1.1 nonaka } 71 1.1 nonaka 72 1.1 nonaka if (iodev == CONSDEV_GLASS) { 73 1.1 nonaka infd = 0; 74 1.1 nonaka outfd = 1; 75 1.1 nonaka 76 1.1 nonaka strlcpy(bi_cons.devname, "glass", sizeof(bi_cons.devname)); 77 1.1 nonaka bi_cons.addr = -1; 78 1.1 nonaka bi_cons.speed = -1; 79 1.1 nonaka } else { 80 1.1 nonaka fd = uopen(comdevname[iodev - CONSDEV_COM0], LINUX_O_RDWR); 81 1.1 nonaka if (fd < 0) 82 1.1 nonaka goto glass_console; 83 1.1 nonaka infd = outfd = fd; 84 1.1 nonaka 85 1.1 nonaka /* set speed */ 86 1.1 nonaka linux_tcgetattr(fd, &termios); 87 1.1 nonaka if (linux_cfsetspeed(&termios, speed) < 0) { 88 1.1 nonaka speed = 9600; 89 1.1 nonaka if (linux_cfsetspeed(&termios, speed) < 0) 90 1.1 nonaka goto glass_console; 91 1.1 nonaka } 92 1.1 nonaka if (linux_tcsetattr(fd, LINUX_TCSETS, &termios) < 0) 93 1.1 nonaka goto glass_console; 94 1.1 nonaka 95 1.1 nonaka snprintf(bi_cons.devname, sizeof(bi_cons.devname), "com%d", 96 1.1 nonaka iodev - CONSDEV_COM0); 97 1.1 nonaka bi_cons.addr = -1; 98 1.1 nonaka bi_cons.speed = speed; 99 1.1 nonaka } 100 1.1 nonaka BI_ADD(&bi_cons, BTINFO_CONSDEV, sizeof(bi_cons)); 101 1.1 nonaka } 102 1.1 nonaka 103 1.1 nonaka void 104 1.1 nonaka putchar(int c) 105 1.1 nonaka { 106 1.1 nonaka 107 1.1 nonaka common_putc(outfd, c); 108 1.1 nonaka } 109 1.1 nonaka 110 1.1 nonaka int 111 1.1 nonaka getchar(void) 112 1.1 nonaka { 113 1.1 nonaka 114 1.1 nonaka return common_getc(infd, 1); 115 1.1 nonaka } 116 1.1 nonaka 117 1.1 nonaka static void 118 1.1 nonaka common_putc(int fd, int c) 119 1.1 nonaka { 120 1.1 nonaka 121 1.1 nonaka (void)uwrite(fd, &c, 1); 122 1.1 nonaka } 123 1.1 nonaka 124 1.1 nonaka static int 125 1.1 nonaka common_getc(int fd, int timo) 126 1.1 nonaka { 127 1.1 nonaka struct linux_timeval tv; 128 1.1 nonaka fd_set fdset; 129 1.1 nonaka int nfds, n; 130 1.1 nonaka char c; 131 1.1 nonaka 132 1.1 nonaka for (; timo < 0 || timo > 0; --timo) { 133 1.1 nonaka tv.tv_sec = 1; 134 1.1 nonaka tv.tv_usec = 0; 135 1.1 nonaka FD_ZERO(&fdset); 136 1.1 nonaka 137 1.1 nonaka nfds = 1; 138 1.1 nonaka FD_SET(fd, &fdset); 139 1.1 nonaka 140 1.1 nonaka n = uselect(nfds, &fdset, NULL, NULL, &tv); 141 1.1 nonaka if (n > 0) 142 1.1 nonaka break; 143 1.1 nonaka } 144 1.1 nonaka 145 1.1 nonaka if (timo > 0) { 146 1.1 nonaka for (fd = 0; fd < nfds; fd++) { 147 1.1 nonaka if (FD_ISSET(fd, &fdset)) { 148 1.1 nonaka return (uread(fd, &c, 1) < 1 ? -1 : c); 149 1.1 nonaka } 150 1.1 nonaka } 151 1.1 nonaka } 152 1.1 nonaka return -1; 153 1.1 nonaka } 154 1.1 nonaka 155 1.1 nonaka int 156 1.1 nonaka awaitkey(int timeout, int tell) 157 1.1 nonaka { 158 1.1 nonaka struct linux_termios orig_termios, raw_termios; 159 1.1 nonaka int c = 0; 160 1.1 nonaka int i; 161 1.1 nonaka 162 1.1 nonaka /* set raw mode */ 163 1.1 nonaka linux_tcgetattr(infd, &orig_termios); 164 1.1 nonaka raw_termios = orig_termios; 165 1.1 nonaka linux_cfmakeraw(&raw_termios); 166 1.1 nonaka linux_tcsetattr(infd, LINUX_TCSETS, &raw_termios); 167 1.1 nonaka 168 1.1 nonaka for (i = timeout; i > 0; i--) { 169 1.1 nonaka if (tell) { 170 1.1 nonaka char numbuf[20]; 171 1.1 nonaka int len, j; 172 1.1 nonaka 173 1.3 christos len = snprintf(numbuf, sizeof(numbuf), "%d ", i); 174 1.1 nonaka for (j = 0; j < len; j++) 175 1.1 nonaka numbuf[len + j] = '\b'; 176 1.1 nonaka numbuf[len + j] = '\0'; 177 1.2 joerg printf("%s", numbuf); 178 1.1 nonaka } 179 1.1 nonaka c = common_getc(infd, 1); 180 1.1 nonaka if (c == 0) 181 1.1 nonaka c = -1; 182 1.1 nonaka if (c >= 0) 183 1.1 nonaka break; 184 1.1 nonaka } 185 1.1 nonaka if (i == 0) 186 1.1 nonaka c = '\0'; 187 1.1 nonaka 188 1.1 nonaka /* set original mode */ 189 1.1 nonaka linux_tcsetattr(infd, LINUX_TCSETS, &orig_termios); 190 1.1 nonaka 191 1.1 nonaka if (tell) 192 1.1 nonaka printf("0 \n"); 193 1.1 nonaka 194 1.1 nonaka return c; 195 1.1 nonaka } 196 1.1 nonaka 197 1.1 nonaka void dummycall2(void); 198 1.1 nonaka void 199 1.1 nonaka dummycall2(void) 200 1.1 nonaka { 201 1.1 nonaka 202 1.1 nonaka (void)linux_termio_to_bsd_termios; 203 1.1 nonaka (void)bsd_termios_to_linux_termio; 204 1.1 nonaka (void)linux_termios_to_bsd_termios; 205 1.1 nonaka (void)bsd_termios_to_linux_termios; 206 1.1 nonaka } 207