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 struct hpet_info info; 101 int fd; 102 103 if (argc != 1) { 104 fprintf(stderr, "hpet_info: device-name\n"); 105 return; 106 } 107 108 fd = open(argv[0], O_RDONLY); 109 if (fd < 0) { 110 fprintf(stderr, "hpet_info: open of %s failed\n", argv[0]); 111 return; 112 } 113 114 if (ioctl(fd, HPET_INFO, &info) < 0) { 115 fprintf(stderr, "hpet_info: failed to get info\n"); 116 goto out; 117 } 118 119 fprintf(stderr, "hpet_info: hi_irqfreq 0x%lx hi_flags 0x%lx ", 120 info.hi_ireqfreq, info.hi_flags); 121 fprintf(stderr, "hi_hpet %d hi_timer %d\n", 122 info.hi_hpet, info.hi_timer); 123 124out: 125 close(fd); 126 return; 127} 128 129void 130hpet_poll(int argc, const char **argv) 131{ 132 unsigned long freq; 133 int iterations, i, fd; 134 struct pollfd pfd; 135 struct hpet_info info; 136 struct timeval stv, etv; 137 struct timezone tz; 138 long usec; 139 140 if (argc != 3) { 141 fprintf(stderr, "hpet_poll: device-name freq iterations\n"); 142 return; 143 } 144 145 freq = atoi(argv[1]); 146 iterations = atoi(argv[2]); 147 148 fd = open(argv[0], O_RDONLY); 149 150 if (fd < 0) { 151 fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]); 152 return; 153 } 154 155 if (ioctl(fd, HPET_IRQFREQ, freq) < 0) { 156 fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n"); 157 goto out; 158 } 159 160 if (ioctl(fd, HPET_INFO, &info) < 0) { 161 fprintf(stderr, "hpet_poll: failed to get info\n"); 162 goto out; 163 } 164 165 fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags); 166 167 if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) { 168 fprintf(stderr, "hpet_poll: HPET_EPI failed\n"); 169 goto out; 170 } 171 172 if (ioctl(fd, HPET_IE_ON, 0) < 0) { 173 fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n"); 174 goto out; 175 } 176 177 pfd.fd = fd; 178 pfd.events = POLLIN; 179 180 for (i = 0; i < iterations; i++) { 181 pfd.revents = 0; 182 gettimeofday(&stv, &tz); 183 if (poll(&pfd, 1, -1) < 0) 184 fprintf(stderr, "hpet_poll: poll failed\n"); 185 else { 186 long data; 187 188 gettimeofday(&etv, &tz); 189 usec = stv.tv_sec * 1000000 + stv.tv_usec; 190 usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec; 191 192 fprintf(stderr, 193 "hpet_poll: expired time = 0x%lx\n", usec); 194 195 fprintf(stderr, "hpet_poll: revents = 0x%x\n", 196 pfd.revents); 197 198 if (read(fd, &data, sizeof(data)) != sizeof(data)) { 199 fprintf(stderr, "hpet_poll: read failed\n"); 200 } 201 else 202 fprintf(stderr, "hpet_poll: data 0x%lx\n", 203 data); 204 } 205 } 206 207out: 208 close(fd); 209 return; 210} 211 212static int hpet_sigio_count; 213 214static void 215hpet_sigio(int val) 216{ 217 fprintf(stderr, "hpet_sigio: called\n"); 218 hpet_sigio_count++; 219} 220 221void 222hpet_fasync(int argc, const char **argv) 223{ 224 unsigned long freq; 225 int iterations, i, fd, value; 226 sig_t oldsig; 227 struct hpet_info info; 228 229 hpet_sigio_count = 0; 230 fd = -1; 231 232 if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) { 233 fprintf(stderr, "hpet_fasync: failed to set signal handler\n"); 234 return; 235 } 236 237 if (argc != 3) { 238 fprintf(stderr, "hpet_fasync: device-name freq iterations\n"); 239 goto out; 240 } 241 242 fd = open(argv[0], O_RDONLY); 243 244 if (fd < 0) { 245 fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]); 246 return; 247 } 248 249 250 if ((fcntl(fd, F_SETOWN, getpid()) == 1) || 251 ((value = fcntl(fd, F_GETFL)) == 1) || 252 (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) { 253 fprintf(stderr, "hpet_fasync: fcntl failed\n"); 254 goto out; 255 } 256 257 freq = atoi(argv[1]); 258 iterations = atoi(argv[2]); 259 260 if (ioctl(fd, HPET_IRQFREQ, freq) < 0) { 261 fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n"); 262 goto out; 263 } 264 265 if (ioctl(fd, HPET_INFO, &info) < 0) { 266 fprintf(stderr, "hpet_fasync: failed to get info\n"); 267 goto out; 268 } 269 270 fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags); 271 272 if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) { 273 fprintf(stderr, "hpet_fasync: HPET_EPI failed\n"); 274 goto out; 275 } 276 277 if (ioctl(fd, HPET_IE_ON, 0) < 0) { 278 fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n"); 279 goto out; 280 } 281 282 for (i = 0; i < iterations; i++) { 283 (void) pause(); 284 fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count); 285 } 286 287out: 288 signal(SIGIO, oldsig); 289 290 if (fd >= 0) 291 close(fd); 292 293 return; 294} 295