Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <stdio.h>
0003 #include <stdlib.h>
0004 #include <unistd.h>
0005 #include <fcntl.h>
0006 #include <string.h>
0007 #include <memory.h>
0008 #include <malloc.h>
0009 #include <time.h>
0010 #include <ctype.h>
0011 #include <sys/types.h>
0012 #include <sys/wait.h>
0013 #include <signal.h>
0014 #include <errno.h>
0015 #include <sys/time.h>
0016 #include <linux/hpet.h>
0017 
0018 
0019 extern void hpet_open_close(int, const char **);
0020 extern void hpet_info(int, const char **);
0021 extern void hpet_poll(int, const char **);
0022 extern void hpet_fasync(int, const char **);
0023 extern void hpet_read(int, const char **);
0024 
0025 #include <sys/poll.h>
0026 #include <sys/ioctl.h>
0027 
0028 struct hpet_command {
0029     char        *command;
0030     void        (*func)(int argc, const char ** argv);
0031 } hpet_command[] = {
0032     {
0033         "open-close",
0034         hpet_open_close
0035     },
0036     {
0037         "info",
0038         hpet_info
0039     },
0040     {
0041         "poll",
0042         hpet_poll
0043     },
0044     {
0045         "fasync",
0046         hpet_fasync
0047     },
0048 };
0049 
0050 int
0051 main(int argc, const char ** argv)
0052 {
0053     unsigned int    i;
0054 
0055     argc--;
0056     argv++;
0057 
0058     if (!argc) {
0059         fprintf(stderr, "-hpet: requires command\n");
0060         return -1;
0061     }
0062 
0063 
0064     for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
0065         if (!strcmp(argv[0], hpet_command[i].command)) {
0066             argc--;
0067             argv++;
0068             fprintf(stderr, "-hpet: executing %s\n",
0069                 hpet_command[i].command);
0070             hpet_command[i].func(argc, argv);
0071             return 0;
0072         }
0073 
0074     fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
0075 
0076     return -1;
0077 }
0078 
0079 void
0080 hpet_open_close(int argc, const char **argv)
0081 {
0082     int fd;
0083 
0084     if (argc != 1) {
0085         fprintf(stderr, "hpet_open_close: device-name\n");
0086         return;
0087     }
0088 
0089     fd = open(argv[0], O_RDONLY);
0090     if (fd < 0)
0091         fprintf(stderr, "hpet_open_close: open failed\n");
0092     else
0093         close(fd);
0094 
0095     return;
0096 }
0097 
0098 void
0099 hpet_info(int argc, const char **argv)
0100 {
0101     struct hpet_info    info;
0102     int         fd;
0103 
0104     if (argc != 1) {
0105         fprintf(stderr, "hpet_info: device-name\n");
0106         return;
0107     }
0108 
0109     fd = open(argv[0], O_RDONLY);
0110     if (fd < 0) {
0111         fprintf(stderr, "hpet_info: open of %s failed\n", argv[0]);
0112         return;
0113     }
0114 
0115     if (ioctl(fd, HPET_INFO, &info) < 0) {
0116         fprintf(stderr, "hpet_info: failed to get info\n");
0117         goto out;
0118     }
0119 
0120     fprintf(stderr, "hpet_info: hi_irqfreq 0x%lx hi_flags 0x%lx ",
0121         info.hi_ireqfreq, info.hi_flags);
0122     fprintf(stderr, "hi_hpet %d hi_timer %d\n",
0123         info.hi_hpet, info.hi_timer);
0124 
0125 out:
0126     close(fd);
0127     return;
0128 }
0129 
0130 void
0131 hpet_poll(int argc, const char **argv)
0132 {
0133     unsigned long       freq;
0134     int         iterations, i, fd;
0135     struct pollfd       pfd;
0136     struct hpet_info    info;
0137     struct timeval      stv, etv;
0138     struct timezone     tz;
0139     long            usec;
0140 
0141     if (argc != 3) {
0142         fprintf(stderr, "hpet_poll: device-name freq iterations\n");
0143         return;
0144     }
0145 
0146     freq = atoi(argv[1]);
0147     iterations = atoi(argv[2]);
0148 
0149     fd = open(argv[0], O_RDONLY);
0150 
0151     if (fd < 0) {
0152         fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
0153         return;
0154     }
0155 
0156     if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
0157         fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
0158         goto out;
0159     }
0160 
0161     if (ioctl(fd, HPET_INFO, &info) < 0) {
0162         fprintf(stderr, "hpet_poll: failed to get info\n");
0163         goto out;
0164     }
0165 
0166     fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
0167 
0168     if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
0169         fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
0170         goto out;
0171     }
0172 
0173     if (ioctl(fd, HPET_IE_ON, 0) < 0) {
0174         fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
0175         goto out;
0176     }
0177 
0178     pfd.fd = fd;
0179     pfd.events = POLLIN;
0180 
0181     for (i = 0; i < iterations; i++) {
0182         pfd.revents = 0;
0183         gettimeofday(&stv, &tz);
0184         if (poll(&pfd, 1, -1) < 0)
0185             fprintf(stderr, "hpet_poll: poll failed\n");
0186         else {
0187             long    data;
0188 
0189             gettimeofday(&etv, &tz);
0190             usec = stv.tv_sec * 1000000 + stv.tv_usec;
0191             usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
0192 
0193             fprintf(stderr,
0194                 "hpet_poll: expired time = 0x%lx\n", usec);
0195 
0196             fprintf(stderr, "hpet_poll: revents = 0x%x\n",
0197                 pfd.revents);
0198 
0199             if (read(fd, &data, sizeof(data)) != sizeof(data)) {
0200                 fprintf(stderr, "hpet_poll: read failed\n");
0201             }
0202             else
0203                 fprintf(stderr, "hpet_poll: data 0x%lx\n",
0204                     data);
0205         }
0206     }
0207 
0208 out:
0209     close(fd);
0210     return;
0211 }
0212 
0213 static int hpet_sigio_count;
0214 
0215 static void
0216 hpet_sigio(int val)
0217 {
0218     fprintf(stderr, "hpet_sigio: called\n");
0219     hpet_sigio_count++;
0220 }
0221 
0222 void
0223 hpet_fasync(int argc, const char **argv)
0224 {
0225     unsigned long       freq;
0226     int         iterations, i, fd, value;
0227     sig_t           oldsig;
0228     struct hpet_info    info;
0229 
0230     hpet_sigio_count = 0;
0231     fd = -1;
0232 
0233     if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
0234         fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
0235         return;
0236     }
0237 
0238     if (argc != 3) {
0239         fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
0240         goto out;
0241     }
0242 
0243     fd = open(argv[0], O_RDONLY);
0244 
0245     if (fd < 0) {
0246         fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
0247         return;
0248     }
0249 
0250 
0251     if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
0252         ((value = fcntl(fd, F_GETFL)) == 1) ||
0253         (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
0254         fprintf(stderr, "hpet_fasync: fcntl failed\n");
0255         goto out;
0256     }
0257 
0258     freq = atoi(argv[1]);
0259     iterations = atoi(argv[2]);
0260 
0261     if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
0262         fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
0263         goto out;
0264     }
0265 
0266     if (ioctl(fd, HPET_INFO, &info) < 0) {
0267         fprintf(stderr, "hpet_fasync: failed to get info\n");
0268         goto out;
0269     }
0270 
0271     fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
0272 
0273     if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
0274         fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
0275         goto out;
0276     }
0277 
0278     if (ioctl(fd, HPET_IE_ON, 0) < 0) {
0279         fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
0280         goto out;
0281     }
0282 
0283     for (i = 0; i < iterations; i++) {
0284         (void) pause();
0285         fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
0286     }
0287 
0288 out:
0289     signal(SIGIO, oldsig);
0290 
0291     if (fd >= 0)
0292         close(fd);
0293 
0294     return;
0295 }