Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hpet_example.c
Go to the documentation of this file.
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 
18 extern void hpet_open_close(int, const char **);
19 extern void hpet_info(int, const char **);
20 extern void hpet_poll(int, const char **);
21 extern void hpet_fasync(int, const char **);
22 extern void hpet_read(int, const char **);
23 
24 #include <sys/poll.h>
25 #include <sys/ioctl.h>
26 
27 struct hpet_command {
28  char *command;
29  void (*func)(int argc, const char ** argv);
30 } hpet_command[] = {
31  {
32  "open-close",
34  },
35  {
36  "info",
37  hpet_info
38  },
39  {
40  "poll",
41  hpet_poll
42  },
43  {
44  "fasync",
46  },
47 };
48 
49 int
50 main(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 
78 void
79 hpet_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 
97 void
98 hpet_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 
124 out:
125  close(fd);
126  return;
127 }
128 
129 void
130 hpet_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 
207 out:
208  close(fd);
209  return;
210 }
211 
212 static int hpet_sigio_count;
213 
214 static void
215 hpet_sigio(int val)
216 {
217  fprintf(stderr, "hpet_sigio: called\n");
218  hpet_sigio_count++;
219 }
220 
221 void
222 hpet_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 
287 out:
288  signal(SIGIO, oldsig);
289 
290  if (fd >= 0)
291  close(fd);
292 
293  return;
294 }