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