FreeCalypso > hg > fc-usbser-tools
diff duart28/find_usb.c @ 27:2413a54a1bfc
fc-duart28-conf started
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 09 Sep 2023 17:53:21 +0000 |
parents | |
children | b9ecfa54fe2b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/duart28/find_usb.c Sat Sep 09 17:53:21 2023 +0000 @@ -0,0 +1,84 @@ +/* + * 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" + +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 void +report_found_dev(struct usb_device *dev, unsigned usb_pid, char string_letter) +{ + printf("Found FreeCalypso DUART28 adapter at bus %s device %s,\n", + dev->bus->dirname, dev->filename); + if (usb_pid == 0x7152 && string_letter == 'C') + printf("presenting as DUART28C\n"); + else if (usb_pid == 0x6010 && string_letter == 'S') + printf("presenting as DUART28S\n"); + else + printf("presenting with inconsistent ID!\n"); +} + +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); + report_found_dev(dev, desc->idProduct, strbuf[7]); + 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; +}