Patrick Williams | b48b7b4 | 2016-08-17 15:04:38 -0500 | [diff] [blame] | 1 | From 059d5512e840fe68e2bb37add6c9208fa9c34d15 Mon Sep 17 00:00:00 2001 |
| 2 | From: Sekhar Nori <nsekhar@ti.com> |
| 3 | Date: Tue, 24 Feb 2015 22:16:37 +0530 |
| 4 | Subject: [PATCH 1/2] Add option to enable internal loopback |
| 5 | |
| 6 | Upstream-status: Pending |
| 7 | --- |
| 8 | serialcheck.c | 23 +++++++++++++++++++++++ |
| 9 | 1 file changed, 23 insertions(+) |
| 10 | |
| 11 | diff --git a/serialcheck.c b/serialcheck.c |
| 12 | index 4f5b747..4100c37 100644 |
| 13 | --- a/serialcheck.c |
| 14 | +++ b/serialcheck.c |
| 15 | @@ -12,6 +12,8 @@ |
| 16 | #include <sys/ioctl.h> |
| 17 | #include <linux/serial.h> |
| 18 | |
| 19 | +#define TIOCM_LOOP 0x8000 |
| 20 | + |
| 21 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) |
| 22 | #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) |
| 23 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) |
| 24 | @@ -40,6 +42,7 @@ struct g_opt { |
| 25 | unsigned char hflow; |
| 26 | unsigned char do_termios; |
| 27 | unsigned char *cmp_buff; |
| 28 | + unsigned char loopback; |
| 29 | }; |
| 30 | |
| 31 | /* name, key, arg, flags, doc, group */ |
| 32 | @@ -51,6 +54,7 @@ static struct argp_option options[] = { |
| 33 | {"mode", 'm', "M", 0, "transfer mode (d = duplex, t = send r = receive)", 0}, |
| 34 | {"loops", 'l', "NUM", 0, "loops to perform (0 => wait fot CTRL-C", 0}, |
| 35 | {"no-termios", 'n', NULL, 0, "No termios change (baud rate etc. remains unchanged)", 0}, |
| 36 | + {"loopback", 'k', NULL, 0, "loopback mode", 0}, |
| 37 | {NULL, 0, NULL, 0, NULL, 0} |
| 38 | }; |
| 39 | |
| 40 | @@ -67,6 +71,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) |
| 41 | go->baudrate = 115200; |
| 42 | go->loops = UINT_MAX; |
| 43 | go->do_termios = 1; |
| 44 | + go->loopback = 0; |
| 45 | break; |
| 46 | case ARGP_KEY_ARG: |
| 47 | ret = ARGP_ERR_UNKNOWN; |
| 48 | @@ -113,6 +118,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) |
| 49 | } else |
| 50 | go->loops = num; |
| 51 | break; |
| 52 | + case 'k': |
| 53 | + go->loopback = 1; |
| 54 | + break; |
| 55 | default: |
| 56 | ret = ARGP_ERR_UNKNOWN; |
| 57 | } |
| 58 | @@ -487,6 +495,21 @@ int main(int argc, char *argv[]) |
| 59 | die("tcflush failed: %m\n"); |
| 60 | } |
| 61 | |
| 62 | + if (opts.loopback) { |
| 63 | + unsigned int mcr; |
| 64 | + |
| 65 | + ret = ioctl(fd, TIOCMGET, &mcr); |
| 66 | + if (ret < 0) |
| 67 | + die("mcr get failed: %m\n"); |
| 68 | + |
| 69 | + mcr |= TIOCM_LOOP; |
| 70 | + |
| 71 | + ret = ioctl(fd, TIOCMSET, &mcr); |
| 72 | + if (ret < 0) |
| 73 | + die ("mcr set failed: %m\n"); |
| 74 | + |
| 75 | + } |
| 76 | + |
| 77 | ret = fcntl(fd, F_SETFL, 0); |
| 78 | if (ret) |
| 79 | printf("Failed to remove nonblock mode\n"); |
| 80 | -- |
| 81 | 1.9.1 |