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