summaryrefslogtreecommitdiff
path: root/spectro/usbio_lusb.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2014-09-07 13:29:54 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2014-09-07 13:29:54 +0200
commita879b4e708b3e46c9697ba6581687eeb5b02a320 (patch)
treef85acc5cb1a7c0b03a050c879c20cab3deb9f40e /spectro/usbio_lusb.c
parent556dffcdad42b938bc196819aa463247de709765 (diff)
parentc07d0c2d2f6f7b0eb6e92cc6204bf05037957e82 (diff)
state from 2014-09-07 13:30 MESZ
Diffstat (limited to 'spectro/usbio_lusb.c')
-rw-r--r--spectro/usbio_lusb.c897
1 files changed, 0 insertions, 897 deletions
diff --git a/spectro/usbio_lusb.c b/spectro/usbio_lusb.c
deleted file mode 100644
index f78bcca..0000000
--- a/spectro/usbio_lusb.c
+++ /dev/null
@@ -1,897 +0,0 @@
-
-/* General USB I/O support, legacy Libusb 0.1/1.0 implementation, no longer */
-/* used by default, but can be configured in the Jamfile. */
-/* The corresponding libusb code is not distributed with the current source */
-/* though, and would have to be copied from ArgyllCMS V1.4.0 */
-
-/* This file is conditionaly #included into usbio.c */
-
-/*
- * Argyll Color Correction System
- *
- * Author: Graeme W. Gill
- * Date: 2006/22/4
- *
- * Copyright 2006 - 2013 Graeme W. Gill
- * All rights reserved.
- *
- * This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :-
- * see the License2.txt file for licencing details.
- */
-
-/* To simplify error messages: */
-#ifdef USE_LIBUSB1
-# define USB_STRERROR(RV) libusb_strerror(RV)
-#else
-# define USB_STRERROR(RV) usb_strerror()
-#endif
-
-#ifdef USE_LIBUSB1
-# define usb_device libusb_device
-# define usb_device_descriptor libusb_device_descriptor
-# define usb_dev_handle libusb_device_handle
-# define usb_config_descriptor libusb_config_descriptor
-# define usb_strerror libusb_strerror
-#endif
-
-#if defined(__FreeBSD__) /* Shut spurious warnings up */
-# define CASTFIX (intptr_t)
-#else
-# define CASTFIX
-#endif
-
-/* Check a USB Vendor and product ID, and add the device */
-/* to the icoms path if it is supported. */
-/* (this is used to help implement usb_get_paths) */
-/* return icom error */
-static int usb_check_and_add(
-icompaths *p,
-struct usb_device *usbd
-) {
- instType itype;
- int nep; /* Number of end points */
-
- struct usb_device_descriptor descriptor;
-
-#ifdef USE_LIBUSB1
- enum libusb_error rv;
-
- if ((rv = libusb_get_device_descriptor(usbd, &descriptor)) != LIBUSB_SUCCESS) {
- a1loge(p->log, ICOM_SYS, "usb_check_and_add: failed with %d (%s)\n",
- rv,USB_STRERROR(rv));
- return ICOM_SYS;
- }
-#else
- descriptor = usbd->descriptor; /* Copy */
-#endif
- a1logd(p->log, 6, "usb_check_and_add: called with VID 0x%x, PID 0x%x\n",descriptor.idVendor, descriptor.idProduct);
-
-#ifdef USE_LIBUSB1
-#if defined(NT) || defined(__APPLE__)
- /* Ignore libusb1 HID driver capability */
- {
- struct libusb_config_descriptor *confdesc = NULL;
-
- /* If not obviously HID, we need to fetch the config descriptor */
- if (descriptor.bDeviceClass != LIBUSB_CLASS_HID
- && (rv = libusb_get_config_descriptor(usbd, 0, &confdesc)) != LIBUSB_SUCCESS) {
- /* This seems to happen for hubs etc., so ignore it */
- a1logd(p->log, 6 , "usb_check_and_add: get conf desc. failed - device not reconized\n");
- return ICOM_OK;
- }
-
- if (descriptor.bDeviceClass == LIBUSB_CLASS_HID
- || (confdesc->bNumInterfaces > 0
- && confdesc->interface[0]. num_altsetting > 0
- && confdesc->interface[0].altsetting[0].bInterfaceClass == LIBUSB_CLASS_HID)) {
- int i;
- /* See if this devices is already in the list via the HID interface */
- /* (This may not be 100% correct in the face of multiple instances
- of the same device, if Windows allows different drivers for different
- instances of the same device type.) */
- for (i = 0; i < p->npaths; i++) {
- if (p->paths[i]->vid == descriptor.idVendor
- && p->paths[i]->pid == descriptor.idProduct)
- break; /* Yes */
- }
- if (i < p->npaths) {
- a1logd(p->log, 6, "Is an HID device and already added\n");
- if (confdesc != NULL)
- libusb_free_config_descriptor(confdesc);
- return ICOM_OK;
- }
- }
- if (confdesc != NULL)
- libusb_free_config_descriptor(confdesc);
- }
-#endif
-#endif
-
- /* The i1pro2 is detected by checking the number of end points, */
- /* so set this value in icom now by looking at the descriptor */
- {
-#ifdef USE_LIBUSB1
- struct libusb_config_descriptor *confdesc;
- const struct libusb_interface_descriptor *ifd;
-
- if (libusb_get_config_descriptor(usbd, 0, &confdesc) != LIBUSB_SUCCESS) {
- /* This seems to happen for hubs etc., so ignore it */
- a1logd(p->log, 6 , "usb_check_and_add: get conf desc. failed - device not reconized\n");
- return ICOM_OK;
- }
-
- ifd = &confdesc->interface[0].altsetting[0];
- nep = ifd->bNumEndpoints;
- if (confdesc != NULL)
- libusb_free_config_descriptor(confdesc);
-#else
- struct usb_interface_descriptor *ifd;
- ifd = &usbd->config[0].interface[0].altsetting[0];
- nep = ifd->bNumEndpoints;
-#endif
- }
-
- if ((itype = inst_usb_match((unsigned int)descriptor.idVendor,
- (unsigned int)descriptor.idProduct, nep)) != instUnknown) {
- char pname[400];
-
- a1logd(p->log, 2, "usb_check_and_add: found known instrument VID 0x%x, PID 0x%x\n",
- descriptor.idVendor, descriptor.idProduct);
-
- /* Create a path/identification */
- /* (devnum doesn't seem valid ?) */
-#ifdef USE_LIBUSB1
- libusb_ref_device(usbd); /* Keep it */
- sprintf(pname,"usb:/bus%d/dev%d/ (%s)",libusb_get_bus_number(usbd),libusb_get_device_address(usbd), inst_name(itype));
-#else
-# if defined(UNIX)
- sprintf(pname,"usb:/bus%d/dev%d (%s)",usbd->bus->location >> 24, usbd->devnum, inst_name(itype));
-# else
- sprintf(pname,"usb:/bus%lu/dev%d (%s)",usbd->bus->location, usbd->devnum, inst_name(itype));
-# endif
-#endif
-
- /* Add the path to the list */
- p->add_usb(p, pname, descriptor.idVendor, descriptor.idProduct, nep, usbd, itype);
- return ICOM_OK;
- }
- a1logd(p->log, 6 , "usb_check_and_add: device not reconized\n");
-
- return ICOM_OK;
-}
-
-#ifdef USE_LIBUSB1
-
-/* Add paths of USB connected instruments */
-/* return icom error */
-int usb_get_paths(
-icompaths *p
-) {
- ssize_t i, nlist;
- struct libusb_device **list;
-
- /* Scan the USB busses for instruments we recognise */
- /* We're not expecting any of our instruments to be an interface on a device. */
-
- /* Use the default context to avoid worying about versions */
- /* of libusb1 that don't reference count them. (ie. would need */
- /* copies in both icompaths and icoms) */
-
- libusb_init(NULL); /* Use default context */
-
- /* Enable lower level debugging of device finding */
- if (p->log->debug >= 8)
- libusb_set_debug(NULL, p->log->debug);
-
- if ((nlist = libusb_get_device_list(NULL, &list)) < 0) {
- a1loge(p->log, ICOM_SYS, "usb_get_paths: get_device_list failed with %d (%s)\n",
- nlist,USB_STRERROR(nlist));
- return ICOM_SYS;
- }
-
- a1logd(p->log, 6, "usb_get_paths: about to look through devices:\n");
-
- for (i = 0; i < nlist; i++) {
- usb_check_and_add(p, list[i]);
- }
-
- libusb_free_device_list(list, 1);
-
- a1logd(p->log, 8, "usb_get_paths: returning %d paths and ICOM_OK\n",p->npaths);
- return ICOM_OK;
-}
-
-#else /* !USE_LIBUSB1 */
-
-/* Add paths of USB connected instruments */
-/* return icom error */
-int usb_get_paths(
-icompaths *p
-) {
- struct usb_bus *bus;
- int rv;
-
- /* Enable lower level debugging of device finding */
- if (p->log->debug >= 8)
- usb_set_debug(p->log->debug);
-
- /* Scan the USB busses for instruments we recognise */
- /* We're not expecting any of our instruments to be an interface on a device. */
-
- usb_init();
- if ((rv = usb_find_busses()) < 0) {
- a1loge(p->log, ICOM_SYS, "usb_get_paths: find_busses failed with %d (%s)\n",
- rv,USB_STRERROR(rv));
- return ICOM_SYS;
- }
- if ((rv = usb_find_devices()) < 0) {
- a1loge(p->log, ICOM_SYS, "usb_get_paths: usb_find_devices failed with %d (%s)\n",
- rv,USB_STRERROR(rv));
- return ICOM_SYS;
- }
-
- a1logd(p->log, 6, "usb_get_paths: about to look through busses:\n");
-
- for (bus = usb_get_busses(); bus != NULL; bus = bus->next) {
- struct usb_device *dev;
- a1logd(p->log, 6, "usb_get_paths: about to look through devices:\n");
- for (dev = bus->devices; dev != NULL; dev = dev->next) {
- if ((rv = usb_check_and_add(p, dev)) != ICOM_OK)
- return rv;
- }
- }
- a1logd(p->log, 8, "usb_get_paths: returning %d paths and ICOM_OK\n",p->npaths);
- return ICOM_OK;
-}
-#endif /* !USE_LIBUSB1 */
-
-/* Copy usb_idevice contents from icompaths to icom */
-/* return icom error */
-int usb_copy_usb_idevice(icoms *d, icompath *s) {
- if (s->usbd == NULL) {
- d->usbd = NULL;
- return ICOM_OK;
- }
-
- d->usbd = s->usbd; /* Copy pointer */
-#ifdef USE_LIBUSB1
- libusb_ref_device(d->usbd);
-#endif
- return ICOM_OK;
-}
-
-/* Cleanup and then free a usb dev entry */
-void usb_del_usb_idevice(struct usb_idevice *usbd) {
-
- if (usbd == NULL)
- return;
-
-#ifdef USE_LIBUSB1
- libusb_unref_device(usbd);
-#endif
-}
-
-/* Cleanup any USB specific icoms state */
-void usb_del_usb(icoms *p) {
-
-#ifdef USE_LIBUSB1
- usb_del_usb_idevice(p->usbd);
-#endif /* USE_LIBUSB1 */
-}
-
-/* Close an open USB port */
-/* If we don't do this, the port and/or the device may be left in an unusable state. */
-void usb_close_port(icoms *p) {
-
- a1logd(p->log, 8, "usb_close_port: called\n");
-
- if (p->is_open && p->usbh != NULL) {
- int iface;
-
- for (iface = 0; iface < p->nifce; iface++) {
-#ifdef USE_LIBUSB1
- libusb_release_interface(p->usbh, iface);
-#else
- usb_release_interface(p->usbh, iface);
-#endif
- }
-
- /* Workaround for some bugs */
- if (p->uflags & icomuf_reset_before_close) {
-#ifdef USE_LIBUSB1
- libusb_reset_device(p->usbh);
-#else
- usb_reset(p->usbh);
-#endif
- }
-
- /* Close as well, othewise we can't re-open */
- {
-#ifdef USE_LIBUSB1
- libusb_close(p->usbh);
-#else
- usb_close(p->usbh);
-#endif
- }
- p->usbh = NULL;
-
- a1logd(p->log, 8, "usb_close_port: port has been released and closed\n");
- }
- p->is_open = 0;
-
- /* Find it and delete it from our static cleanup list */
- usb_delete_from_cleanup_list(p);
-
-}
-
-/* Open a USB port for all our uses. */
-/* This always re-opens the port */
-/* return icom error */
-static int usb_open_port(
-icoms *p,
-int config, /* Configuration number */
-int wr_ep, /* Write end point */
-int rd_ep, /* Read end point */
-icomuflags usbflags,/* Any special handling flags */
-int retries, /* > 0 if we should retry set_configuration (100msec) */
-char **pnames /* List of process names to try and kill before opening */
-) {
- int tries = 0;
- a1logd(p->log, 8, "usb_open_port: Make sure USB port is open, tries %d\n",retries);
-
- if (p->is_open)
- p->close_port(p);
-
- /* Make sure the port is open */
- if (!p->is_open) {
- struct usb_device_descriptor descriptor;
-#ifdef USE_LIBUSB1
- const struct libusb_interface_descriptor *ifd;
- struct libusb_config_descriptor *confdesc;
-#else
- struct usb_interface_descriptor *ifd;
-#endif
- int rv, i, iface;
- kkill_nproc_ctx *kpc = NULL;
-
- /* Do open retries */
- for (tries = 0; retries >= 0; retries--, tries++) {
-
- a1logd(p->log, 8, "usb_open_port: About to open USB port '%s'\n",p->name);
-
- if (tries > 0) {
- //msec_sleep(i_rand(50,100));
- msec_sleep(77);
- }
- if (tries > 0 && pnames != NULL && kpc == NULL) {
-#if defined(__APPLE__) || defined(NT)
- if ((kpc = kkill_nprocess(pnames, p->log)) == NULL)
- a1logd(p->log, 1, "usb_open_port: kkill_nprocess returned error!\n");
-#endif /* __APPLE__ */
- }
-
-#ifdef USE_LIBUSB1
- if ((rv = libusb_open(p->usbd, &p->usbh)) != LIBUSB_SUCCESS)
-#else
- if ((p->usbh = usb_open(p->usbd)) == NULL)
-#endif
- {
- a1logd(p->log, 8, "usb_open_port: open '%s' config %d failed (%s) (Permissions ?)\n",p->name,config,USB_STRERROR(rv));
- if (retries <= 0) {
- if (kpc != NULL)
- kpc->del(kpc);
- a1loge(p->log, ICOM_SYS, "usb_open_port: open '%s' config %d failed (%s) (Permissions ?)\n",p->name,config,USB_STRERROR(rv));
- return ICOM_SYS;
- }
- continue;
- } else if (p->debug)
- a1logd(p->log, 2, "usb_open_port: open port '%s' succeeded\n",p->name);
-
- /* Get a copy of the device descriptor so we can see device params */
-#ifdef USE_LIBUSB1
- if (libusb_get_device_descriptor(p->usbd, &descriptor) != LIBUSB_SUCCESS) {
- a1loge(p->log, ICOM_SYS, "usb_open_port: get device descriptor on '%s' failed with %d (%s)\n",p->name,rv,USB_STRERROR(rv));
- return ICOM_SYS;
- }
-#else
- descriptor = p->usbd->descriptor; /* Copy */
-#endif
-
- p->uflags = usbflags;
-
- a1logd(p->log, 8, "usb_open_port: Number of configurations = %d\n",
- descriptor.bNumConfigurations);
- p->nconfig = descriptor.bNumConfigurations;
- p->config = config;
-
-#if defined(UNIX_X11)
- /* only call set_configuration on Linux if the device has more than one */
- /* possible configuration, because Linux does a set_configuration by default, */
- /* and two of them mess up instruments like the Spyder2 */
-
- if (descriptor.bNumConfigurations > 1) {
-#endif
-
- /* Can't skip this, as it is needed to setup the interface and end points on OS X */
-#ifdef USE_LIBUSB1
- if ((rv = libusb_set_configuration(p->usbh, config)) < 0)
-#else
- if ((rv = usb_set_configuration(p->usbh, config)) < 0)
-#endif
- {
- a1logd(p->log, 8, "usb_open_port: configuring '%s' to %d failed with %d (%s)\n",p->name,config,rv,USB_STRERROR(rv));
- if (retries <= 0) {
- if (kpc != NULL)
- kpc->del(kpc);
- a1loge(p->log, ICOM_SYS, "usb_open_port: configuring '%s' to %d failed with %d (%s)\n",p->name,config,rv,USB_STRERROR(rv));
- return ICOM_SYS;
- }
- /* reset the port and retry */
-#ifdef USE_LIBUSB1
- libusb_reset_device(p->usbh); // ~~999 ?????
- libusb_close(p->usbh);
-#else
- usb_reset(p->usbh);
- usb_close(p->usbh);
-#endif
- continue;
- }
-#if defined(UNIX_X11)
- } /* End of if bNumConfigurations > 1 */
-#endif
-
- /* We're done */
- break;
- }
-
- if (kpc != NULL)
- kpc->del(kpc);
-
- /* Claim all interfaces of this configuration */
-#ifdef USE_LIBUSB1
- if ((rv = libusb_get_active_config_descriptor(p->usbd, &confdesc)) != LIBUSB_SUCCESS) {
- a1loge(p->log, ICOM_SYS, "usb_open_port: get config desc. for '%s' failed with %d (%s)\n",p->name,rv,USB_STRERROR(rv));
- return ICOM_SYS;
- }
- p->nifce = confdesc->bNumInterfaces;
-#else
- p->nifce = p->usbd->config->bNumInterfaces;
-#endif
-
-// a1logv(p->log, 8, "usb_open_port: Number of interfaces = %d\n",p->nifce);
-
- /* Claim all the interfaces */
- for (iface = 0; iface < p->nifce; iface++) {
- /* (Second parameter is bInterfaceNumber) */
-
-#ifdef USE_LIBUSB1
- if ((rv = libusb_claim_interface(p->usbh, iface)) < 0) {
- /* Detatch the existing interface if kernel driver is active. */
- if (p->uflags & icomuf_detach
- && libusb_kernel_driver_active(p->usbh, iface) == 1) {
- libusb_detach_kernel_driver (p->usbh, iface);
- if ((rv = libusb_claim_interface(p->usbh, iface)) < 0) {
- a1loge(p->log, ICOM_SYS, "usb_open_port: Claiming USB port '%s' interface %d failed after detach with %d (%s)\n",p->name,iface,rv,USB_STRERROR(rv));
- return ICOM_SYS;
- }
- } else {
- a1loge(p->log, ICOM_SYS, "usb_open_port: Claiming USB port '%s' interface %d failed with %d (%s)\n",p->name,iface,rv,USB_STRERROR(rv));
- return ICOM_SYS;
- }
- }
-#else
- if ((rv = usb_claim_interface(p->usbh, iface)) < 0) {
-# if LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP == 1
- /* Detatch the existing interface. */
- if (p->uflags & icomuf_detach) {
- usb_detach_kernel_driver_np(p->usbh, iface);
- if ((rv = usb_claim_interface(p->usbh, iface)) < 0) {
- a1loge(p->log, ICOM_SYS, "usb_open_port: Claiming USB port '%s' interface %d failed after detach with %d (%s)\n",p->name,iface,rv,USB_STRERROR(rv));
- return ICOM_SYS;
- }
- }
-# else
- a1loge(p->log, ICOM_SYS, "usb_open_port: Claiming USB port '%s' interface %d failed with %d (%s)\n",p->name,iface,rv,USB_STRERROR(rv));
- return ICOM_SYS;
-# endif
- }
-#endif
-
- /* Fill in the end point details */
-#ifdef USE_LIBUSB1
- ifd = &confdesc->interface[iface].altsetting[0];
-#else
- ifd = &p->usbd->config[p->config-1].interface[iface].altsetting[0];
-#endif
-// a1logv(p->log, 8, "usb_open_port: Number of endpoints on iface %d = %d\n",iface, ifd->bNumEndpoints);
- p->nep = ifd->bNumEndpoints;
- for (i = 0; i < ifd->bNumEndpoints; i++) {
- int ad = ifd->endpoint[i].bEndpointAddress;
- p->EPINFO(ad).valid = 1;
- p->EPINFO(ad).addr = ad;
- p->EPINFO(ad).packetsize = ifd->endpoint[i].wMaxPacketSize;
- p->EPINFO(ad).type = ifd->endpoint[i].bmAttributes & IUSB_ENDPOINT_TYPE_MASK;
- /* Some I/F seem to hang if we do this, some seem to hang if we don't ! */
- if (!(p->uflags & icomuf_no_open_clear))
-#ifdef USE_LIBUSB1
- libusb_clear_halt(p->usbh, (unsigned char)ad);
-#else
- usb_clear_halt(p->usbh, ad);
-#endif
-// a1logv(p->log, 8, "usb_open_port: ep %d: endpoint addr %02x pktsze %d, type %d\n",i,ad,ifd->endpoint[i].wMaxPacketSize,p->EPINFO(ad).type);
- }
-
-#ifdef NEVER
- /* Get the serial number */
- {
- int rv;
- struct usb_device_descriptor descriptor;
-
- a1logd(p->log, 8, "usb_open_port: About to get device serial number\n");
-# ifdef USE_LIBUSB1
- if ((rv = libusb_get_device_descriptor(p->usbd, &descriptor)) != LIBUSB_SUCCESS) {
- a1loge(p->log, ICOM_SYS, "usb_open_port: get_device_descriptor failed with %d USB port '%s'\n",rv,p->name);
- return ICOM_SYS;
- }
-# else
- descriptor = dev->descriptor; /* Copy */
-# endif
- if ((rv = libusb_get_string_descriptor_ascii(p->usbh, descriptor.iSerialNumber, p->serialno, 32)) <= 0) {
- a1logd(p->log, 1, "usb_open_port: Failed to get device serial number %d (%s)\n",rv,USB_STRERROR(rv));
- p->serialno[0] = '\000';
- } else {
- a1logd(p->log, 1, "usb_open_port: Device serial number = '%s'\n",p->serialno);
- }
- }
-#endif /* NEVER */
- }
-
- /* Set "serial" coms values */
- p->wr_ep = wr_ep;
- p->rd_ep = rd_ep;
- p->rd_qa = p->EPINFO(rd_ep).packetsize;
- if (p->rd_qa == 0)
- p->rd_qa = 8;
- a1logd(p->log, 8, "usb_open_port: 'serial' read quanta = packet size = %d\n",p->rd_qa);
-
-#ifdef USE_LIBUSB1
- if (confdesc != NULL)
- libusb_free_config_descriptor(confdesc);
-#endif
-
- p->is_open = 1;
- a1logd(p->log, 8, "usb_open_port: USB port is now open\n");
- }
-
- /* Install the cleanup signal handlers, and add to our cleanup list */
- usb_install_signal_handlers(p);
-
- return ICOM_OK;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-/* Time out error return value */
-
-#ifdef USE_LIBUSB1
-#define USBIO_ERROR_TIMEOUT LIBUSB_ERROR_TIMEOUT
-#else
-# if defined(UNIX)
-#define USBIO_ERROR_TIMEOUT -ETIMEDOUT
-# else
-#define USBIO_ERROR_TIMEOUT -116 /* libusb-win32 code */
-# endif /* UNIX */
-#endif
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#ifdef USE_LIBUSB1
-
-/* Callback functions */
-static void bulk_transfer_cb(struct libusb_transfer *transfer)
-{
- int *completed = transfer->user_data;
- *completed = 1;
- /* caller interprets results and frees transfer */
-}
-
-/* Version of libusb1 sync to async code that returns the pointer */
-/* to the transfer structure so that the transfer can be cancelled */
-/* by another thread. */
-/* Return an icoms error code */
-static int do_sync_usb_transfer(
- icoms *p,
- struct libusb_device_handle *dev_handle,
- usb_cancelt *cancelt,
- int *transferred,
- icom_usb_trantype ttype,
- unsigned char endpoint,
- unsigned char *buffer,
- int length,
- unsigned int timeout
-) {
- enum libusb_transfer_type type;
- struct libusb_transfer *transfer = libusb_alloc_transfer(0);
- int completed = 0;
- int rv;
-
- if (!transfer) {
- a1logd(p->log, 1, "do_sync_usb_transfer: transfer is NULL!\n");
- return ICOM_SYS;
- }
-
- /* Translate icoms transfer type of libusb1 */
- switch (ttype) {
- case icom_usb_trantype_command:
- type = LIBUSB_TRANSFER_TYPE_CONTROL;
- break;
- case icom_usb_trantype_interrutpt:
- type = LIBUSB_TRANSFER_TYPE_INTERRUPT;
- break;
- case icom_usb_trantype_bulk:
- type = LIBUSB_TRANSFER_TYPE_BULK;
- break;
- }
-
- libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length,
- bulk_transfer_cb, &completed, timeout);
- transfer->type = type;
-
- if ((rv = libusb_submit_transfer(transfer)) < 0) {
- libusb_free_transfer(transfer);
- a1logd(p->log, 1, "do_sync_usb_transfer: Submitting transfer failed with %d (%s)\n",rv,USB_STRERROR(rv));
- if ((endpoint & IUSB_ENDPOINT_DIR_MASK) == IUSB_ENDPOINT_OUT)
- return ICOM_USBW;
- else
- return ICOM_USBR;
- }
-
- if (cancelt != NULL) {
- usb_lock_cancel(cancelt);
- cancelt->hcancel = (void *)transfer;
- usb_unlock_cancel(cancelt);
- }
-
- while (!completed) {
- if ((rv = libusb_handle_events_check(NULL, &completed)) < 0) {
- if (rv == LIBUSB_ERROR_INTERRUPTED)
- continue; /* Retry */
- /* Give up - cancel transfer and wait until complete */
- libusb_cancel_transfer(transfer);
- while (!completed) {
- if (libusb_handle_events_check(NULL, &completed) < 0)
- break;
- }
- if (cancelt != NULL) {
- usb_lock_cancel(cancelt);
- cancelt->hcancel = NULL;
- usb_unlock_cancel(cancelt);
- }
- libusb_free_transfer(transfer);
- a1loge(p->log, ICOM_SYS, "do_sync_usb_transfer: handle_events failed with %d (%s)\n",rv,USB_STRERROR(rv));
- return ICOM_SYS;
- }
- }
-
- *transferred = transfer->actual_length;
- switch (transfer->status) {
- case LIBUSB_TRANSFER_COMPLETED:
- rv = ICOM_OK;
- break;
- case LIBUSB_TRANSFER_TIMED_OUT:
- rv = ICOM_TO;
- break;
- case LIBUSB_TRANSFER_STALL:
- case LIBUSB_TRANSFER_OVERFLOW:
- case LIBUSB_TRANSFER_NO_DEVICE:
- if ((endpoint & IUSB_ENDPOINT_DIR_MASK) == IUSB_ENDPOINT_OUT)
- rv = ICOM_USBW;
- else
- rv = ICOM_USBR;
- break;
- case LIBUSB_TRANSFER_CANCELLED:
- rv = ICOM_CANC;
- break;
- default:
- a1loge(p->log, ICOM_SYS, "do_sync_usb_transfer: transfer faile with %d (%s)\n",rv,USB_STRERROR(rv));
- rv = ICOM_SYS;
- }
-
- if (cancelt != NULL) {
- usb_lock_cancel(cancelt);
- cancelt->hcancel = NULL;
- usb_unlock_cancel(cancelt);
- }
- libusb_free_transfer(transfer);
-
- /* requested size wasn't transferred */
- if (rv == ICOM_OK && *transferred != length)
- rv = ICOM_SHORT;
-
- return rv;
-}
-#endif /* USE_LIBUSB1 */
-
-/* Return icom error code */
-static int icoms_usb_control_msg(
-icoms *p,
-int *transferred,
-int requesttype, int request,
-int value, int index, unsigned char *bytes, int size,
-int timeout) {
- int rv;
-
- in_usb_rw++;
- a1logd(p->log, 8, "icoms_usb_control_msg: type 0x%x, req 0x%x, size %d\n",requesttype,request,size);
-
- if (transferred != NULL)
- *transferred = 0;
-#ifdef USE_LIBUSB1
- rv = libusb_control_transfer(p->usbh, (uint8_t)requesttype, (uint8_t)request,
- (uint16_t)value, (uint16_t)index, bytes, (uint16_t)size, timeout);
-#else
- rv = usb_control_msg(p->usbh, requesttype, request, value, index, (char *)bytes, size, timeout);
-#endif
- if (in_usb_rw < 0) /* interrupt recurssion */
- exit(0);
-
- in_usb_rw--;
-
- if (rv < 0) {
- if (rv == USBIO_ERROR_TIMEOUT) { /* Not a timeout */
- rv = ICOM_TO;
- } else {
- if (requesttype & IUSB_ENDPOINT_IN) /* Device to host */
- rv = ICOM_USBR; /* Read error */
- else
- rv = ICOM_USBW; /* Write error */
- }
- } else {
- if (transferred != NULL)
- *transferred = rv;
- if (rv != size) {
- rv = ICOM_SHORT;
- } else
- rv = ICOM_OK;
- }
- a1logd(p->log, 8, "icoms_usb_control_msg: returning err 0x%x and %d bytes\n",rv, *transferred);
- return rv;
-}
-
-/* Our versions of usblib read/write, that exit if a signal was caught */
-/* This is so that MSWindows works properly */
-/* return an icom error */
-static int icoms_usb_transaction(icoms *p, usb_cancelt *cancelt, int *xbytes,
- icom_usb_trantype type, int ep, unsigned char *bytes, int size, int timeout) {
- int rv;
-
- in_usb_rw++;
-
- a1logd(p->log, 8, "coms_usb_transaction: req type 0x%x ep 0x%x size %d\n",type,ep,size);
-#ifdef USE_LIBUSB1
- rv = do_sync_usb_transfer(p, p->usbh, cancelt, xbytes, type,
- (unsigned char)ep, bytes, size, timeout);
-#else
- if (xbytes != NULL)
- *xbytes = 0;
- if (cancelt != NULL) {
- usb_lock_cancel(cancelt);
- cancelt->hcancel = (void *) CASTFIX ep;
- usb_lock_cancel(cancelt);
- }
- if (type == icom_usb_trantype_interrutpt) {
- if ((ep & IUSB_ENDPOINT_DIR_MASK) == IUSB_ENDPOINT_OUT)
- rv = usb_interrupt_write(p->usbh, ep, (char *)bytes, size, timeout);
- else
- rv = usb_interrupt_read(p->usbh, ep, (char *)bytes, size, timeout);
- } else { /* bulk */
- if ((ep & IUSB_ENDPOINT_DIR_MASK) == IUSB_ENDPOINT_OUT)
- rv = usb_bulk_write(p->usbh, ep, (char *)bytes, size, timeout);
- else
- rv = usb_bulk_read(p->usbh, ep, (char *)bytes, size, timeout);
- }
- if (cancelt != NULL) {
- usb_lock_cancel(cancelt);
- cancelt->hcancel = (void *)-1;
- usb_lock_cancel(cancelt);
- }
- if (rv < 0) {
- if (rv == USBIO_ERROR_TIMEOUT)
- rv = ICOM_TO;
- else {
- if ((ep & IUSB_ENDPOINT_DIR_MASK) == IUSB_ENDPOINT_OUT)
- rv = ICOM_USBW;
- else
- rv = ICOM_USBR;
- }
- } else {
- if (xbytes != NULL)
- *xbytes = rv;
- if (rv != *xbytes)
- rv = ICOM_SHORT;
- else
- rv = ICOM_OK;
- }
-#endif
- if (in_usb_rw < 0) /* Signal handler recursion error */
- exit(0);
-
- in_usb_rw--;
-
- a1logd(p->log, 8, "coms_usb_transaction: returning err 0x%x and %d bytes\n",rv, *xbytes);
-
- return rv;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - */
-/* Cancel i/o in another thread */
-int icoms_usb_cancel_io(
- icoms *p,
- usb_cancelt *cancelt
-) {
- int rv = 0;
- usb_lock_cancel(cancelt);
-#ifdef USE_LIBUSB1
- if (cancelt->hcancel != NULL) {
- rv = libusb_cancel_transfer((struct libusb_transfer *)cancelt->hcancel);
- if (rv == LIBUSB_ERROR_NOT_FOUND)
- rv = 0;
- }
-#else
- if ((int) CASTFIX cancelt->hcancel >= 0) {
-// msec_sleep(1); /* Let device recover ? */
- rv = usb_resetep(p->usbh, (int) CASTFIX cancelt->hcancel); /* Not reliable ? */
-// msec_sleep(1); /* Let device recover ? */
- }
-#endif
- usb_unlock_cancel(cancelt);
-
- if (rv == 0)
- return ICOM_OK;
-
- a1logd(p->log, 1, "icoms_usb_cancel_io: failed with %d (%s)\n", rv,USB_STRERROR(rv));
- return ICOM_SYS;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - */
-/* Reset and end point data toggle to 0 */
-int icoms_usb_resetep(
- icoms *p,
- int ep /* End point address */
-) {
- int rv;
-#ifdef USE_LIBUSB1
- rv = libusb_resetep(p->usbh, (unsigned char)ep); /* Is this the same though ? */
-#else
- rv = usb_resetep(p->usbh, ep); /* Not reliable ? */
-#endif
-
- if (rv == 0)
- return ICOM_OK;
-
- a1logd(p->log, 1, "icoms_usb_resetep: failed with %d (%s)\n", rv,USB_STRERROR(rv));
- return ICOM_USBW;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - */
-/* Clear a halt on an end point */
-int icoms_usb_clearhalt(
- icoms *p,
- int ep /* End point address */
-) {
- int rv;
-#ifdef USE_LIBUSB1
- rv = libusb_clear_halt(p->usbh, (unsigned char)ep);
-#else
- rv = usb_clear_halt(p->usbh, ep);
-#endif
-
- if (rv == 0)
- return ICOM_OK;
-
- a1logd(p->log, 1, "icoms_usb_clearhalt: failed with %d (%s)\n", rv,USB_STRERROR(rv));
- return ICOM_USBW;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - */
-