1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Watchdog Driver Test Program 4 */ 5 6 #include <errno.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <unistd.h> 11 #include <fcntl.h> 12 #include <signal.h> 13 #include <getopt.h> 14 #include <sys/ioctl.h> 15 #include <linux/types.h> 16 #include <linux/watchdog.h> 17 18 #define DEFAULT_PING_RATE 1 19 20 int fd; 21 const char v = 'V'; 22 static const char sopts[] = "bdehp:t:"; 23 static const struct option lopts[] = { 24 {"bootstatus", no_argument, NULL, 'b'}, 25 {"disable", no_argument, NULL, 'd'}, 26 {"enable", no_argument, NULL, 'e'}, 27 {"help", no_argument, NULL, 'h'}, 28 {"pingrate", required_argument, NULL, 'p'}, 29 {"timeout", required_argument, NULL, 't'}, 30 {NULL, no_argument, NULL, 0x0} 31 }; 32 33 /* 34 * This function simply sends an IOCTL to the driver, which in turn ticks 35 * the PC Watchdog card to reset its internal timer so it doesn't trigger 36 * a computer reset. 37 */ 38 static void keep_alive(void) 39 { 40 int dummy; 41 int ret; 42 43 ret = ioctl(fd, WDIOC_KEEPALIVE, &dummy); 44 if (!ret) 45 printf("."); 46 } 47 48 /* 49 * The main program. Run the program with "-d" to disable the card, 50 * or "-e" to enable the card. 51 */ 52 53 static void term(int sig) 54 { 55 int ret = write(fd, &v, 1); 56 57 close(fd); 58 if (ret < 0) 59 printf("\nStopping watchdog ticks failed (%d)...\n", errno); 60 else 61 printf("\nStopping watchdog ticks...\n"); 62 exit(0); 63 } 64 65 static void usage(char *progname) 66 { 67 printf("Usage: %s [options]\n", progname); 68 printf(" -b, --bootstatus Get last boot status (Watchdog/POR)\n"); 69 printf(" -d, --disable Turn off the watchdog timer\n"); 70 printf(" -e, --enable Turn on the watchdog timer\n"); 71 printf(" -h, --help Print the help message\n"); 72 printf(" -p, --pingrate=P Set ping rate to P seconds (default %d)\n", DEFAULT_PING_RATE); 73 printf(" -t, --timeout=T Set timeout to T seconds\n"); 74 printf("\n"); 75 printf("Parameters are parsed left-to-right in real-time.\n"); 76 printf("Example: %s -d -t 10 -p 5 -e\n", progname); 77 } 78 79 int main(int argc, char *argv[]) 80 { 81 int flags; 82 unsigned int ping_rate = DEFAULT_PING_RATE; 83 int ret; 84 int c; 85 int oneshot = 0; 86 87 setbuf(stdout, NULL); 88 89 fd = open("/dev/watchdog", O_WRONLY); 90 91 if (fd == -1) { 92 printf("Watchdog device not enabled.\n"); 93 exit(-1); 94 } 95 96 while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) { 97 switch (c) { 98 case 'b': 99 flags = 0; 100 oneshot = 1; 101 ret = ioctl(fd, WDIOC_GETBOOTSTATUS, &flags); 102 if (!ret) 103 printf("Last boot is caused by: %s.\n", (flags != 0) ? 104 "Watchdog" : "Power-On-Reset"); 105 else 106 printf("WDIOC_GETBOOTSTATUS errno '%s'\n", strerror(errno)); 107 break; 108 case 'd': 109 flags = WDIOS_DISABLECARD; 110 ret = ioctl(fd, WDIOC_SETOPTIONS, &flags); 111 if (!ret) 112 printf("Watchdog card disabled.\n"); 113 else 114 printf("WDIOS_DISABLECARD errno '%s'\n", strerror(errno)); 115 break; 116 case 'e': 117 flags = WDIOS_ENABLECARD; 118 ret = ioctl(fd, WDIOC_SETOPTIONS, &flags); 119 if (!ret) 120 printf("Watchdog card enabled.\n"); 121 else 122 printf("WDIOS_ENABLECARD errno '%s'\n", strerror(errno)); 123 break; 124 case 'p': 125 ping_rate = strtoul(optarg, NULL, 0); 126 if (!ping_rate) 127 ping_rate = DEFAULT_PING_RATE; 128 printf("Watchdog ping rate set to %u seconds.\n", ping_rate); 129 break; 130 case 't': 131 flags = strtoul(optarg, NULL, 0); 132 ret = ioctl(fd, WDIOC_SETTIMEOUT, &flags); 133 if (!ret) 134 printf("Watchdog timeout set to %u seconds.\n", flags); 135 else 136 printf("WDIOC_SETTIMEOUT errno '%s'\n", strerror(errno)); 137 break; 138 default: 139 usage(argv[0]); 140 goto end; 141 } 142 } 143 144 if (oneshot) 145 goto end; 146 147 printf("Watchdog Ticking Away!\n"); 148 149 signal(SIGINT, term); 150 151 while (1) { 152 keep_alive(); 153 sleep(ping_rate); 154 } 155 end: 156 ret = write(fd, &v, 1); 157 if (ret < 0) 158 printf("Stopping watchdog ticks failed (%d)...\n", errno); 159 close(fd); 160 return 0; 161 } 162