diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2014-09-07 13:29:54 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2014-09-07 13:29:54 +0200 |
commit | a879b4e708b3e46c9697ba6581687eeb5b02a320 (patch) | |
tree | f85acc5cb1a7c0b03a050c879c20cab3deb9f40e /spectro/usbio_lusb.c | |
parent | 556dffcdad42b938bc196819aa463247de709765 (diff) | |
parent | c07d0c2d2f6f7b0eb6e92cc6204bf05037957e82 (diff) |
state from 2014-09-07 13:30 MESZ
Diffstat (limited to 'spectro/usbio_lusb.c')
-rw-r--r-- | spectro/usbio_lusb.c | 897 |
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; -} - -/* - - - - - - - - - - - - - - - - - - - - - - - - - */ - |