xref: /netbsd-src/sys/arch/zaurus/stand/zboot/unixcons.c (revision dc14a659696da5e5f1946adfc0121396bac3f145)
1 /*	$NetBSD: unixcons.c,v 1.3 2014/03/26 08:02:38 christos Exp $	*/
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 
35 struct btinfo_console bi_cons;
36 
37 static int iodev = CONSDEV_GLASS;
38 static int infd = 0;
39 static int outfd = 1;
40 
41 static const char *comdevname[] = {
42 	"/dev/ttyS0",
43 };
44 
45 static void common_putc(int fd, int c);
46 static int common_getc(int fd, int timo);
47 
48 void
consinit(int dev,int speed)49 consinit(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 
103 void
putchar(int c)104 putchar(int c)
105 {
106 
107 	common_putc(outfd, c);
108 }
109 
110 int
getchar(void)111 getchar(void)
112 {
113 
114 	return common_getc(infd, 1);
115 }
116 
117 static void
common_putc(int fd,int c)118 common_putc(int fd, int c)
119 {
120 
121 	(void)uwrite(fd, &c, 1);
122 }
123 
124 static int
common_getc(int fd,int timo)125 common_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 
155 int
awaitkey(int timeout,int tell)156 awaitkey(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 			len = snprintf(numbuf, sizeof(numbuf), "%d ", i);
174 			for (j = 0; j < len; j++)
175 				numbuf[len + j] = '\b';
176 			numbuf[len + j] = '\0';
177 			printf("%s", numbuf);
178 		}
179 		c = common_getc(infd, 1);
180 		if (c == 0)
181 			c = -1;
182 		if (c >= 0)
183 			break;
184 	}
185 	if (i == 0)
186 		c = '\0';
187 
188 	/* set original mode */
189 	linux_tcsetattr(infd, LINUX_TCSETS, &orig_termios);
190 
191 	if (tell)
192 		printf("0 \n");
193 
194 	return c;
195 }
196 
197 void dummycall2(void);
198 void
dummycall2(void)199 dummycall2(void)
200 {
201 
202 	(void)linux_termio_to_bsd_termios;
203 	(void)bsd_termios_to_linux_termio;
204 	(void)linux_termios_to_bsd_termios;
205 	(void)bsd_termios_to_linux_termios;
206 }
207