xref: /netbsd-src/sys/arch/zaurus/stand/zboot/unixcons.c (revision dc14a659696da5e5f1946adfc0121396bac3f145)
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