view duart28/find_usb.c @ 44:5160f6717903

libuwrap: implement function to claim/unbind all interfaces
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 11 Sep 2023 02:27:11 +0000
parents b9ecfa54fe2b
children
line wrap: on
line source

/*
 * This module implements the step of locating a connected FreeCalypso DUART28
 * device (either C or S) at the libusb level, without booting off the kernel
 * driver and claiming the interface yet.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <usb.h>
#include "../libuwrap/prelim_init.h"

unsigned usb_presenting_pid;

static void
get_string(usb_dev_handle *usbh, int index, char *buf, size_t buflen)
{
	int rc;

	rc = usb_get_string_simple(usbh, index, buf, buflen);
	if (rc <= 0) {
		fprintf(stderr, "error: USB string retrieval failed\n");
		exit(1);
	}
}

static int
is_match(struct usb_device *dev)
{
	struct usb_device_descriptor *desc = &dev->descriptor;
	usb_dev_handle *usbh;
	char strbuf[1024];

	if (desc->idVendor != 0x0403)
		return 0;
	if (desc->idProduct != 0x6010 && desc->idProduct != 0x7152)
		return 0;
	usbh = usb_open(dev);
	if (!usbh) {
		fprintf(stderr, "error: usb_open() failed\n");
		exit(1);
	}
	get_string(usbh, desc->iManufacturer, strbuf, sizeof strbuf);
	if (strcmp(strbuf, "FreeCalypso")) {
		usb_close(usbh);
		return 0;
	}
	get_string(usbh, desc->iProduct, strbuf, sizeof strbuf);
	if (strcmp(strbuf, "DUART28C") && strcmp(strbuf, "DUART28S")) {
		usb_close(usbh);
		return 0;
	}
	usb_close(usbh);
	printf("Found FreeCalypso DUART28 adapter at bus %s device %s\n",
		dev->bus->dirname, dev->filename);
	usb_presenting_pid = desc->idProduct;
	return 1;
}

struct usb_device *
find_duart28_usbdev()
{
	struct usb_bus *bus;
	struct usb_device *dev;

	libusb_prelim_init();
	for (bus = usb_get_busses(); bus; bus = bus->next) {
		for (dev = bus->devices; dev; dev = dev->next) {
			if (is_match(dev))
				return dev;
		}
	}
	return 0;
}