1#include <stdio.h> 2#include <stdlib.h> 3#include <unistd.h> 4#include <fcntl.h> 5#include <string.h> 6#include <memory.h> 7#include <malloc.h> 8#include <time.h> 9#include <ctype.h> 10#include <sys/types.h> 11#include <sys/wait.h> 12#include <signal.h> 13#include <errno.h> 14#include <sys/time.h> 15#include <linux/hpet.h> 16 17 18extern void hpet_open_close(int, const char **); 19extern void hpet_info(int, const char **); 20extern void hpet_poll(int, const char **); 21extern void hpet_fasync(int, const char **); 22extern void hpet_read(int, const char **); 23 24#include <sys/poll.h> 25#include <sys/ioctl.h> 26 27struct hpet_command { 28 char *command; 29 void (*func)(int argc, const char ** argv); 30} hpet_command[] = { 31 { 32 "open-close", 33 hpet_open_close 34 }, 35 { 36 "info", 37 hpet_info 38 }, 39 { 40 "poll", 41 hpet_poll 42 }, 43 { 44 "fasync", 45 hpet_fasync 46 }, 47}; 48 49int 50main(int argc, const char ** argv) 51{ 52 int i; 53 54 argc--; 55 argv++; 56 57 if (!argc) { 58 fprintf(stderr, "-hpet: requires command\n"); 59 return -1; 60 } 61 62 63 for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++) 64 if (!strcmp(argv[0], hpet_command[i].command)) { 65 argc--; 66 argv++; 67 fprintf(stderr, "-hpet: executing %s\n", 68 hpet_command[i].command); 69 hpet_command[i].func(argc, argv); 70 return 0; 71 } 72 73 fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]); 74 75 return -1; 76} 77 78void 79hpet_open_close(int argc, const char **argv) 80{ 81 int fd; 82 83 if (argc != 1) { 84 fprintf(stderr, "hpet_open_close: device-name\n"); 85 return; 86 } 87 88 fd = open(argv[0], O_RDONLY); 89 if (fd < 0) 90 fprintf(stderr, "hpet_open_close: open failed\n"); 91 else 92 close(fd); 93 94 return; 95} 96 97void 98hpet_info(int argc, const char **argv) 99{ 100} 101 102void 103hpet_poll(int argc, const char **argv) 104{ 105 unsigned long freq; 106 int iterations, i, fd; 107 struct pollfd pfd; 108 struct hpet_info info; 109 struct timeval stv, etv; 110 struct timezone tz; 111 long usec; 112 113 if (argc != 3) { 114 fprintf(stderr, "hpet_poll: device-name freq iterations\n"); 115 return; 116 } 117 118 freq = atoi(argv[1]); 119 iterations = atoi(argv[2]); 120 121 fd = open(argv[0], O_RDONLY); 122 123 if (fd < 0) { 124 fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]); 125 return; 126 } 127 128 if (ioctl(fd, HPET_IRQFREQ, freq) < 0) { 129 fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n"); 130 goto out; 131 } 132 133 if (ioctl(fd, HPET_INFO, &info) < 0) { 134 fprintf(stderr, "hpet_poll: failed to get info\n"); 135 goto out; 136 } 137 138 fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags); 139 140 if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) { 141 fprintf(stderr, "hpet_poll: HPET_EPI failed\n"); 142 goto out; 143 } 144 145 if (ioctl(fd, HPET_IE_ON, 0) < 0) { 146 fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n"); 147 goto out; 148 } 149 150 pfd.fd = fd; 151 pfd.events = POLLIN; 152 153 for (i = 0; i < iterations; i++) { 154 pfd.revents = 0; 155 gettimeofday(&stv, &tz); 156 if (poll(&pfd, 1, -1) < 0) 157 fprintf(stderr, "hpet_poll: poll failed\n"); 158 else { 159 long data; 160 161 gettimeofday(&etv, &tz); 162 usec = stv.tv_sec * 1000000 + stv.tv_usec; 163 usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec; 164 165 fprintf(stderr, 166 "hpet_poll: expired time = 0x%lx\n", usec); 167 168 fprintf(stderr, "hpet_poll: revents = 0x%x\n", 169 pfd.revents); 170 171 if (read(fd, &data, sizeof(data)) != sizeof(data)) { 172 fprintf(stderr, "hpet_poll: read failed\n"); 173 } 174 else 175 fprintf(stderr, "hpet_poll: data 0x%lx\n", 176 data); 177 } 178 } 179 180out: 181 close(fd); 182 return; 183} 184 185static int hpet_sigio_count; 186 187static void 188hpet_sigio(int val) 189{ 190 fprintf(stderr, "hpet_sigio: called\n"); 191 hpet_sigio_count++; 192} 193 194void 195hpet_fasync(int argc, const char **argv) 196{ 197 unsigned long freq; 198 int iterations, i, fd, value; 199 sig_t oldsig; 200 struct hpet_info info; 201 202 hpet_sigio_count = 0; 203 fd = -1; 204 205 if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) { 206 fprintf(stderr, "hpet_fasync: failed to set signal handler\n"); 207 return; 208 } 209 210 if (argc != 3) { 211 fprintf(stderr, "hpet_fasync: device-name freq iterations\n"); 212 goto out; 213 } 214 215 fd = open(argv[0], O_RDONLY); 216 217 if (fd < 0) { 218 fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]); 219 return; 220 } 221 222 223 if ((fcntl(fd, F_SETOWN, getpid()) == 1) || 224 ((value = fcntl(fd, F_GETFL)) == 1) || 225 (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) { 226 fprintf(stderr, "hpet_fasync: fcntl failed\n"); 227 goto out; 228 } 229 230 freq = atoi(argv[1]); 231 iterations = atoi(argv[2]); 232 233 if (ioctl(fd, HPET_IRQFREQ, freq) < 0) { 234 fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n"); 235 goto out; 236 } 237 238 if (ioctl(fd, HPET_INFO, &info) < 0) { 239 fprintf(stderr, "hpet_fasync: failed to get info\n"); 240 goto out; 241 } 242 243 fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags); 244 245 if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) { 246 fprintf(stderr, "hpet_fasync: HPET_EPI failed\n"); 247 goto out; 248 } 249 250 if (ioctl(fd, HPET_IE_ON, 0) < 0) { 251 fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n"); 252 goto out; 253 } 254 255 for (i = 0; i < iterations; i++) { 256 (void) pause(); 257 fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count); 258 } 259 260out: 261 signal(SIGIO, oldsig); 262 263 if (fd >= 0) 264 close(fd); 265 266 return; 267} 268