blob: e22a8fa1425f1dff631514fbe7b5fbf4b8eebaf3 [file] [log] [blame]
Carl-Daniel Hailfingere51ea102009-11-23 19:20:11 +00001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2009 Urja Rannikko <urjaman@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <unistd.h>
24#include "flash.h"
25#include <string.h>
26#include <ctype.h>
27#include <fcntl.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <errno.h>
31#include <inttypes.h>
32#include <termios.h>
33
34int sp_fd;
35
36void __attribute__((noreturn)) sp_die(char *msg)
37{
38 perror(msg);
39 exit(1);
40}
41
42struct baudentry {
43 int flag;
44 unsigned int baud;
45};
46
47/* I'd like if the C preprocessor could have directives in macros */
48#define BAUDENTRY(baud) { B##baud, baud },
49static const struct baudentry sp_baudtable[] = {
50 BAUDENTRY(9600)
51 BAUDENTRY(19200)
52 BAUDENTRY(38400)
53 BAUDENTRY(57600)
54 BAUDENTRY(115200)
55#ifdef B230400
56 BAUDENTRY(230400)
57#endif
58#ifdef B460800
59 BAUDENTRY(460800)
60#endif
61#ifdef B500000
62 BAUDENTRY(500000)
63#endif
64#ifdef B576000
65 BAUDENTRY(576000)
66#endif
67#ifdef B921600
68 BAUDENTRY(921600)
69#endif
70#ifdef B1000000
71 BAUDENTRY(1000000)
72#endif
73#ifdef B1152000
74 BAUDENTRY(1152000)
75#endif
76#ifdef B1500000
77 BAUDENTRY(1500000)
78#endif
79#ifdef B2000000
80 BAUDENTRY(2000000)
81#endif
82#ifdef B2500000
83 BAUDENTRY(2500000)
84#endif
85#ifdef B3000000
86 BAUDENTRY(3000000)
87#endif
88#ifdef B3500000
89 BAUDENTRY(3500000)
90#endif
91#ifdef B4000000
92 BAUDENTRY(4000000)
93#endif
94 {0, 0} /* Terminator */
95};
96
97int sp_openserport(char *dev, unsigned int baud)
98{
99 struct termios options;
100 int fd, i;
101 fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);
102 if (fd < 0)
103 sp_die("Error: cannot open serial port");
104 fcntl(fd, F_SETFL, 0);
105 tcgetattr(fd, &options);
106 for (i = 0;; i++) {
107 if (sp_baudtable[i].baud == 0) {
108 close(fd);
109 fprintf(stderr,
110 "Error: cannot configure for baudrate %d\n",
111 baud);
112 exit(1);
113 }
114 if (sp_baudtable[i].baud == baud) {
115 cfsetispeed(&options, sp_baudtable[i].flag);
116 cfsetospeed(&options, sp_baudtable[i].flag);
117 break;
118 }
119 }
120 options.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);
121 options.c_cflag |= (CS8 | CLOCAL | CREAD);
122 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
123 options.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL | IGNCR | INLCR);
124 options.c_oflag &= ~OPOST;
125 tcsetattr(fd, TCSANOW, &options);
126 return fd;
127}
128
129void sp_flush_incoming(void)
130{
131 int i;
132 for (i=0;i<100;i++) { /* In case the device doesnt do EAGAIN, just read 0 */
133 unsigned char flush[16];
134 ssize_t rv;
135 rv = read(sp_fd, flush, sizeof(flush));
136 if ((rv == -1) && (errno == EAGAIN))
137 break;
138 if (rv == -1)
139 sp_die("flush read");
140 }
141 return;
142}