summaryrefslogtreecommitdiff
path: root/serial.c
diff options
context:
space:
mode:
authorhailfinger <hailfinger@2b7e53f0-3cfb-0310-b3e9-8179ed1497e1>2009-11-23 19:20:11 +0000
committerhailfinger <hailfinger@2b7e53f0-3cfb-0310-b3e9-8179ed1497e1>2009-11-23 19:20:11 +0000
commitc46274b04a255a059596a02cc45b583a0453d9e1 (patch)
treece82d190a42e73f31bf764e9f81e24f567cdca2d /serial.c
parentf15ccbbbb1cb05bf1533acd9e38f508144e15202 (diff)
downloadflashrom-c46274b04a255a059596a02cc45b583a0453d9e1.tar.gz
Move serial handling from serprog.c to serial.c.
This is the first step in enabling platform independent serprog and it also allows other drivers to use serial port functionality without requiring serprog. Pure code move, no code changed. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Uwe Hermann <uwe@hermann-uwe.de> git-svn-id: https://code.coreboot.org/svn/flashrom/trunk@771 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'serial.c')
-rw-r--r--serial.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/serial.c b/serial.c
new file mode 100644
index 0000000..e22a8fa
--- /dev/null
+++ b/serial.c
@@ -0,0 +1,142 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2009 Urja Rannikko <urjaman@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "flash.h"
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <termios.h>
+
+int sp_fd;
+
+void __attribute__((noreturn)) sp_die(char *msg)
+{
+ perror(msg);
+ exit(1);
+}
+
+struct baudentry {
+ int flag;
+ unsigned int baud;
+};
+
+/* I'd like if the C preprocessor could have directives in macros */
+#define BAUDENTRY(baud) { B##baud, baud },
+static const struct baudentry sp_baudtable[] = {
+ BAUDENTRY(9600)
+ BAUDENTRY(19200)
+ BAUDENTRY(38400)
+ BAUDENTRY(57600)
+ BAUDENTRY(115200)
+#ifdef B230400
+ BAUDENTRY(230400)
+#endif
+#ifdef B460800
+ BAUDENTRY(460800)
+#endif
+#ifdef B500000
+ BAUDENTRY(500000)
+#endif
+#ifdef B576000
+ BAUDENTRY(576000)
+#endif
+#ifdef B921600
+ BAUDENTRY(921600)
+#endif
+#ifdef B1000000
+ BAUDENTRY(1000000)
+#endif
+#ifdef B1152000
+ BAUDENTRY(1152000)
+#endif
+#ifdef B1500000
+ BAUDENTRY(1500000)
+#endif
+#ifdef B2000000
+ BAUDENTRY(2000000)
+#endif
+#ifdef B2500000
+ BAUDENTRY(2500000)
+#endif
+#ifdef B3000000
+ BAUDENTRY(3000000)
+#endif
+#ifdef B3500000
+ BAUDENTRY(3500000)
+#endif
+#ifdef B4000000
+ BAUDENTRY(4000000)
+#endif
+ {0, 0} /* Terminator */
+};
+
+int sp_openserport(char *dev, unsigned int baud)
+{
+ struct termios options;
+ int fd, i;
+ fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);
+ if (fd < 0)
+ sp_die("Error: cannot open serial port");
+ fcntl(fd, F_SETFL, 0);
+ tcgetattr(fd, &options);
+ for (i = 0;; i++) {
+ if (sp_baudtable[i].baud == 0) {
+ close(fd);
+ fprintf(stderr,
+ "Error: cannot configure for baudrate %d\n",
+ baud);
+ exit(1);
+ }
+ if (sp_baudtable[i].baud == baud) {
+ cfsetispeed(&options, sp_baudtable[i].flag);
+ cfsetospeed(&options, sp_baudtable[i].flag);
+ break;
+ }
+ }
+ options.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);
+ options.c_cflag |= (CS8 | CLOCAL | CREAD);
+ options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+ options.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL | IGNCR | INLCR);
+ options.c_oflag &= ~OPOST;
+ tcsetattr(fd, TCSANOW, &options);
+ return fd;
+}
+
+void sp_flush_incoming(void)
+{
+ int i;
+ for (i=0;i<100;i++) { /* In case the device doesnt do EAGAIN, just read 0 */
+ unsigned char flush[16];
+ ssize_t rv;
+ rv = read(sp_fd, flush, sizeof(flush));
+ if ((rv == -1) && (errno == EAGAIN))
+ break;
+ if (rv == -1)
+ sp_die("flush read");
+ }
+ return;
+}