brintos

brintos / linux-shallow public Read only

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