/*
 * mmio.c -- DF-4783 raw I/O spammer (TEST ONLY).
 * N threads pread()ing /dev/mmcsd0 forever; used to keep the data path
 * (physio -> bio -> mmcsd_strategy) busy while the driver is torn down.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>

static const char *devpath = "/dev/mmcsd0";
static int nthreads = 16;
static volatile int stop;

static void *
spam(void *arg)
{
	int fd, n = (int)(long)arg;
	char *buf;
	off_t off = (off_t)n * 8192;

	buf = malloc(256 * 1024);
	while (!stop) {
		fd = open(devpath, O_RDONLY);
		if (fd < 0) {
			usleep(200);
			continue;
		}
		while (!stop) {
			if (pread(fd, buf, 256 * 1024, off) < 0)
				break;		/* device died (detach) */
			off += 262144;
			if (off > 200 * 1024 * 1024)
				off = 0;
		}
		close(fd);
	}
	free(buf);
	return (NULL);
}

int
main(int argc, char **argv)
{
	pthread_t th[64];
	int i;

	if (argc > 1)
		nthreads = atoi(argv[1]);
	if (argc > 2)
		devpath = argv[2];
	for (i = 0; i < nthreads; i++)
		pthread_create(&th[i], NULL, spam, (void *)(long)i);
	for (i = 0; i < nthreads; i++)
		pthread_join(th[i], NULL);
	return (0);
}
