From 059d5512e840fe68e2bb37add6c9208fa9c34d15 Mon Sep 17 00:00:00 2001
From: Sekhar Nori <nsekhar@ti.com>
Date: Tue, 24 Feb 2015 22:16:37 +0530
Subject: [PATCH 1/2] Add option to enable internal loopback

Upstream-status: Pending
---
 serialcheck.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/serialcheck.c b/serialcheck.c
index 4f5b747..4100c37 100644
--- a/serialcheck.c
+++ b/serialcheck.c
@@ -12,6 +12,8 @@
 #include <sys/ioctl.h>
 #include <linux/serial.h>

+#define TIOCM_LOOP	0x8000
+
 #define __same_type(a, b)	__builtin_types_compatible_p(typeof(a), typeof(b))
 #define BUILD_BUG_ON_ZERO(e)	(sizeof(struct { int:-!!(e); }))
 #define __must_be_array(a)	BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
@@ -40,6 +42,7 @@ struct g_opt {
	unsigned char hflow;
	unsigned char do_termios;
	unsigned char *cmp_buff;
+	unsigned char loopback;
 };

 /* name, key, arg, flags, doc, group */
@@ -51,6 +54,7 @@ static struct argp_option options[] = {
	{"mode",	'm', "M",    0, "transfer mode (d = duplex, t = send r = receive)", 0},
	{"loops",	'l', "NUM",  0, "loops to perform (0 => wait fot CTRL-C", 0},
	{"no-termios",	'n', NULL,   0, "No termios change (baud rate etc. remains unchanged)", 0},
+	{"loopback",	'k', NULL,   0, "loopback mode", 0},
	{NULL, 0, NULL, 0, NULL, 0}
 };

@@ -67,6 +71,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
		go->baudrate = 115200;
		go->loops = UINT_MAX;
		go->do_termios = 1;
+		go->loopback = 0;
		break;
	case ARGP_KEY_ARG:
		ret =  ARGP_ERR_UNKNOWN;
@@ -113,6 +118,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
		} else
			go->loops = num;
		break;
+	case 'k':
+		go->loopback = 1;
+		break;
	default:
		ret = ARGP_ERR_UNKNOWN;
	}
@@ -487,6 +495,21 @@ int main(int argc, char *argv[])
			die("tcflush failed: %m\n");
	}

+	if (opts.loopback) {
+		unsigned int mcr;
+
+		ret = ioctl(fd, TIOCMGET, &mcr);
+		if (ret < 0)
+			die("mcr get failed: %m\n");
+
+		mcr |= TIOCM_LOOP;
+
+		ret = ioctl(fd, TIOCMSET, &mcr);
+		if (ret < 0)
+			die ("mcr set failed: %m\n");
+
+	}
+
	ret = fcntl(fd, F_SETFL, 0);
	if (ret)
		printf("Failed to remove nonblock mode\n");
--
1.9.1
