/*
 * mmhold.c -- DF-4783: userland holder across mmcsd teardown (TEST ONLY).
 *
 * Opens /dev/mmcsd0 ONCE and issues pread() on the same fd forever,
 * never closing it: the fd pins the cdev via specfs exactly like a
 * mounted filesystem / busy raw device does.  Run this, then trigger
 * the card-removal teardown (sysctl hw.mmcrace.action=1) and watch
 * what the in-flight/next preads hit: EBADF (dead ops) or a crash
 * inside mmcsd_strategy (freed softc via si_drv1).
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int
main(int argc, char **argv)
{
	const char *path = argc > 1 ? argv[1] : "/dev/mmcsd0";
	char buf[512];
	int fd, n = 0;
	off_t off = 0;

	fd = open(path, O_RDONLY);
	if (fd < 0) {
		perror("open");
		return (1);
	}
	printf("mmhold: fd=%d on %s, hammering pread\n", fd, path);
	fflush(stdout);
	for (;;) {
		if (pread(fd, buf, sizeof(buf), off) < 0) {
			printf("mmhold: pread error errno=%d (%s) n=%d\n",
			    errno, strerror(errno), n);
			fflush(stdout);
		} else if (++n % 2000 == 0) {
			printf("mmhold: %d reads ok\n", n);
			fflush(stdout);
		}
		off += 512;
		if (off > 100 * 1024 * 1024)
			off = 0;
	}
}
