view duart28/find_usb.c @ 68:5cbde3c80c24

fteeprom-{erase,prog}: detach logic: change to detach by default As it turns out, detaching all ttyUSB interfaces of a multichannel device does not require outside knowledge of how many channels there are, as in our previous -d option design that is being removed here - instead we can read the bNumInterfaces constant from the USB device's config descriptor and thus know how many interfaces there are in total. Based on this discovery, change the design of fteeprom-{erase,prog} as follows: * remove -d option; * flip the default to where we detach all interfaces by default; * add -n option to NOT detach any interfaces.
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 13 Sep 2023 06:37:03 +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;
}