/* $NetBSD: unixcons.c,v 1.3 2014/03/26 08:02:38 christos Exp $ */ /* * Copyright (c) 2009 NONAKA Kimihiro * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "boot.h" #include "bootinfo.h" #include "unixdev.h" #include "compat_linux.h" #include "termios.h" struct btinfo_console bi_cons; static int iodev = CONSDEV_GLASS; static int infd = 0; static int outfd = 1; static const char *comdevname[] = { "/dev/ttyS0", }; static void common_putc(int fd, int c); static int common_getc(int fd, int timo); void consinit(int dev, int speed) { struct linux_termios termios; int fd; switch (dev) { case CONSDEV_COM0: iodev = dev; break; case CONSDEV_GLASS: default: glass_console: iodev = CONSDEV_GLASS; break; } if (infd >= 0 && infd == outfd) { uclose(infd); infd = 0; outfd = 1; } if (iodev == CONSDEV_GLASS) { infd = 0; outfd = 1; strlcpy(bi_cons.devname, "glass", sizeof(bi_cons.devname)); bi_cons.addr = -1; bi_cons.speed = -1; } else { fd = uopen(comdevname[iodev - CONSDEV_COM0], LINUX_O_RDWR); if (fd < 0) goto glass_console; infd = outfd = fd; /* set speed */ linux_tcgetattr(fd, &termios); if (linux_cfsetspeed(&termios, speed) < 0) { speed = 9600; if (linux_cfsetspeed(&termios, speed) < 0) goto glass_console; } if (linux_tcsetattr(fd, LINUX_TCSETS, &termios) < 0) goto glass_console; snprintf(bi_cons.devname, sizeof(bi_cons.devname), "com%d", iodev - CONSDEV_COM0); bi_cons.addr = -1; bi_cons.speed = speed; } BI_ADD(&bi_cons, BTINFO_CONSDEV, sizeof(bi_cons)); } void putchar(int c) { common_putc(outfd, c); } int getchar(void) { return common_getc(infd, 1); } static void common_putc(int fd, int c) { (void)uwrite(fd, &c, 1); } static int common_getc(int fd, int timo) { struct linux_timeval tv; fd_set fdset; int nfds, n; char c; for (; timo < 0 || timo > 0; --timo) { tv.tv_sec = 1; tv.tv_usec = 0; FD_ZERO(&fdset); nfds = 1; FD_SET(fd, &fdset); n = uselect(nfds, &fdset, NULL, NULL, &tv); if (n > 0) break; } if (timo > 0) { for (fd = 0; fd < nfds; fd++) { if (FD_ISSET(fd, &fdset)) { return (uread(fd, &c, 1) < 1 ? -1 : c); } } } return -1; } int awaitkey(int timeout, int tell) { struct linux_termios orig_termios, raw_termios; int c = 0; int i; /* set raw mode */ linux_tcgetattr(infd, &orig_termios); raw_termios = orig_termios; linux_cfmakeraw(&raw_termios); linux_tcsetattr(infd, LINUX_TCSETS, &raw_termios); for (i = timeout; i > 0; i--) { if (tell) { char numbuf[20]; int len, j; len = snprintf(numbuf, sizeof(numbuf), "%d ", i); for (j = 0; j < len; j++) numbuf[len + j] = '\b'; numbuf[len + j] = '\0'; printf("%s", numbuf); } c = common_getc(infd, 1); if (c == 0) c = -1; if (c >= 0) break; } if (i == 0) c = '\0'; /* set original mode */ linux_tcsetattr(infd, LINUX_TCSETS, &orig_termios); if (tell) printf("0 \n"); return c; } void dummycall2(void); void dummycall2(void) { (void)linux_termio_to_bsd_termios; (void)bsd_termios_to_linux_termio; (void)linux_termios_to_bsd_termios; (void)bsd_termios_to_linux_termios; }