Subject: Re: USB connect/removal events
To: Christian Groessler <cpg@aladdin.de>
From: Lennart Augustsson <lennart@mail.augustsson.net>
List: current-users
Date: 09/20/2000 21:03:37
This is a multi-part message in MIME format.
--------------E3691B1E0808B61D975E2720
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Christian Groessler wrote:

> Hi,
>
> I'm trying to track USB device removals and connects.
> usb(4) states to do this you can poll /dev/usbx.

The man page is incomplete.  You should create a device node with minor 255
and use that for select().

I'll include a program that shows how it's used.

    -- Lennart


--------------E3691B1E0808B61D975E2720
Content-Type: text/plain; charset=us-ascii;
 name="event.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="event.c"

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <err.h>
#include <signal.h>
#include <sys/types.h>
#include <dev/usb/usb.h>

char *logfile = "/var/log/usbevents";
FILE *log;

void
prevent(struct usb_event *ev)
{
	fprintf(log, "At %9lu.%09lu: ",
		(u_long)ev->ue_time.tv_sec,
		ev->ue_time.tv_nsec);
	switch (ev->ue_type) {
	case USB_EVENT_DEVICE_ATTACH:
	case USB_EVENT_DEVICE_DETACH:
		fprintf(log, "%s(%u) device addr %d, %s, %s",
			ev->ue_type == USB_EVENT_DEVICE_ATTACH ? 
			"ATTACH" : "DETACH",
			ev->u.ue_device.cookie.cookie,
			ev->u.ue_device.addr,
			ev->u.ue_device.vendor,
			ev->u.ue_device.product);
		if (ev->u.ue_device.nports != 0)
			fprintf(log, ", %d ports", ev->u.ue_device.nports);
		break;
	case USB_EVENT_CTRLR_ATTACH:
	case USB_EVENT_CTRLR_DETACH:
		fprintf(log, "%s host controller usb%d", 
			ev->ue_type == USB_EVENT_CTRLR_ATTACH ? 
			"ATTACH" : "DETACH",
			ev->u.ue_ctrlr.ue_bus);
		break;
	case USB_EVENT_DRIVER_ATTACH:
	case USB_EVENT_DRIVER_DETACH:
		fprintf(log, "%s(%u) driver %s",
			ev->ue_type == USB_EVENT_DRIVER_ATTACH ? 
			"ATTACH" : "DETACH",
			ev->u.ue_driver.ue_cookie.cookie,
			ev->u.ue_driver.ue_devname);
		break;
	}
	fprintf(log, "\n");
	fflush(log);
}

void
hup()
{
	fclose(log);
	log = fopen(logfile, "a");
	if (log == NULL)
		err(1, "open %s", logfile);
}

int
main(int argc, char **argv)
{
	char *dev = "/dev/usb";
	char *pidfile = "/var/run/usbd";
	int fd;
	int n;
	struct usb_event ev;
	fd_set fds;
	FILE *pidf;

	pidf = fopen(pidfile, "w");
	if (pidf != NULL) {
		fprintf(pidf, "%d", getpid());
		fclose(pidf);
	}
	signal(SIGHUP, hup);

	log = fopen(logfile, "a");
	if (log == NULL)
		err(1, "open %s", logfile);

	fd = open(dev, O_RDONLY);
	if (fd < 0)
		err(1, "open %s", dev);

	FD_ZERO(&fds);
	for (;;) {
		FD_SET(fd, &fds);
		n = select(fd+1, &fds, 0, 0, 0);
		if (n < 0)
			err(1, "select");
		/*printf("select n=%d\n", n);*/
		if (n == 0)
			continue;

		n = read(fd, &ev, sizeof ev);
		if (n < 0)
			err(1, "read");
		prevent(&ev);
	}
	exit(0);
}

--------------E3691B1E0808B61D975E2720--