*
* For details on how to use the synchronous API, see the
* \ref syncio "synchronous I/O API documentation" pages.
- *
+ *
* \section async The asynchronous interface
*
* Asynchronous I/O is the most significant new feature in libusb-1.0.
* -# <b>Completion handling</b>: examine transfer results in the
* libusb_transfer structure
* -# <b>Deallocation</b>: clean up resources
- *
+ *
*
* \subsection asyncalloc Allocation
*
* request was not supported.
*
* \section asyncintr Considerations for interrupt transfers
- *
+ *
* All interrupt transfers are performed using the polling interval presented
* by the bInterval value of the endpoint descriptor.
*
* -# Repeatedly call libusb_handle_events() in blocking mode from a dedicated
* thread.
*
- * The first option is plainly not very nice, and will cause unnecessary
+ * The first option is plainly not very nice, and will cause unnecessary
* CPU wakeups leading to increased power usage and decreased battery life.
* The second option is not very nice either, but may be the nicest option
* available to you if the "proper" approach can not be applied to your
* application (read on...).
- *
+ *
* The recommended option is to integrate libusb with your application main
* event loop. libusb exposes a set of file descriptors which allow you to do
* this. Your main loop is probably already calling poll() or select() or a
* the loop, <em>up to 120 seconds later.</em> Clearly a two-minute delay is
* undesirable, and don't even think about using short timeouts to circumvent
* this issue!
- *
+ *
* The solution here is to ensure that no two threads are ever polling the
* file descriptors at the same time. A naive implementation of this would
* impact the capabilities of the library, so libusb offers the scheme
*
* Before we go any further, it is worth mentioning that all libusb-wrapped
* event handling procedures fully adhere to the scheme documented below.
- * This includes libusb_handle_events() and all the synchronous I/O functions -
+ * This includes libusb_handle_events() and all the synchronous I/O functions -
* libusb hides this headache from you. You do not need to worry about any
* of these issues if you stick to that level.
*
libusb_unlock_event_waiters(ctx);
goto retry;
}
-
+
libusb_wait_for_event(ctx);
}
libusb_unlock_event_waiters(ctx);
if (r)
return 1;
- ctx->event_handler_active = 1;
+ ctx->event_handler_active = 1;
return 0;
}
(cur_tv->tv_sec == systime.tv_sec &&
cur_tv->tv_usec > systime.tv_usec))
return 0;
-
+
/* otherwise, we've got an expired timeout to handle */
handle_timeout(transfer);
}
* need to use this function if you are calling poll() or select() or similar
* on libusb's file descriptors yourself - you do not need to use it if you
* are calling libusb_handle_events() or a variant directly.
- *
+ *
* You should call this function in your main loop in order to determine how
* long to wait for select() or poll() to return results. libusb needs to be
* called into at this timeout, so you should use it as an upper bound on
/* terminate all pending transfers with the LIBUSB_TRANSFER_NO_DEVICE
* status code.
- *
+ *
* this is a bit tricky because:
* 1. we can't do transfer completion while holding flying_transfers_lock
* 2. the transfers list can change underneath us - if we were to build a
/* No pipe found with the correct endpoint address */
usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
-
+
return -1;
}
(*plugInInterface)->Stop(plugInInterface);
IODestroyPlugInInterface (plugInInterface);
-
+
(*(device))->GetLocationID(device, locationp);
return device;
-static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
+static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
struct libusb_context *ctx = (struct libusb_context *)ptr;
struct libusb_device_handle *handle;
struct darwin_device_priv *dpriv;
IOServiceMatching(kIOUSBDeviceClassName),
(IOServiceMatchingCallback)darwin_devices_detached,
(void *)ctx, &libusb_rem_device_iterator);
-
+
if (kresult != kIOReturnSuccess) {
usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
static int process_new_device (struct libusb_context *ctx, usb_device_t **device, UInt32 locationID, struct discovered_devs **_discdevs) {
struct darwin_device_priv *priv;
- struct libusb_device *dev;
+ struct libusb_device *dev;
struct discovered_devs *discdevs;
UInt16 address, idVendor, idProduct;
UInt8 bDeviceClass, bDeviceSubClass;
req.wIndex = 0;
req.wLength = sizeof(IOUSBDeviceDescriptor);
req.pData = &(priv->dev_descriptor);
-
+
(*(device))->GetDeviceAddress (device, (USBDeviceAddress *)&address);
(*(device))->GetDeviceProduct (device, &idProduct);
(*(device))->GetDeviceVendor (device, &idVendor);
}
/**** end: retrieve device descriptors ****/
-
+
/* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
if (libusb_le16_to_cpu (priv->dev_descriptor.idProduct) != idProduct) {
/* not a valid device */
ret = LIBUSB_ERROR_NO_MEM;
break;
}
-
+
*_discdevs = discdevs;
-
+
usbi_info (ctx, "found device with address %d at %s", dev->device_address, priv->sys_path);
} while (0);
if (!libusb_darwin_mp)
return LIBUSB_ERROR_INVALID_PARAM;
-
+
kresult = usb_setup_device_iterator (&deviceIterator);
if (kresult != kIOReturnSuccess)
return darwin_to_libusb (kresult);
usbi_err (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
}
}
-
+
kresult = (*(dpriv->device))->Release(dpriv->device);
if (kresult) {
/* Log the fact that we had a problem closing the file, however failing a
io_iterator_t interface_iterator;
*usbInterfacep = IO_OBJECT_NULL;
-
+
/* Setup the Interface Request */
request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
for ( current_interface = 0 ; current_interface <= ifc ; current_interface++ )
*usbInterfacep = IOIteratorNext(interface_iterator);
-
+
/* done with the interface iterator */
IOObjectRelease(interface_iterator);
-
+
return 0;
}
int i;
usbi_info (HANDLE_CTX (dev_handle), "building table of endpoints.");
-
+
/* retrieve the total number of endpoints on this interface */
kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
if (kresult) {
}
cInterface->num_endpoints = numep;
-
+
return 0;
}
usbi_err (HANDLE_CTX (dev_handle), "GetNumberOfConfigurations: %s", darwin_error_str(kresult));
return darwin_to_libusb(kresult);
}
-
+
if (nConfig < 1) {
usbi_err (HANDLE_CTX (dev_handle), "GetNumberOfConfigurations: no configurations");
return LIBUSB_ERROR_OTHER;
usbi_err (HANDLE_CTX (dev_handle), "interface not found");
return LIBUSB_ERROR_NOT_FOUND;
}
-
+
/* get an interface to the device's interface */
kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
kIOCFPlugInInterfaceID, &plugInInterface, &score);
/* ignore release error */
(void)IOObjectRelease (usbInterface);
-
+
/* Do the actual claim */
kresult = (*plugInInterface)->QueryInterface(plugInInterface,
CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult));
return darwin_to_libusb (kresult);
}
-
+
/* We no longer need the intermediate plug-in */
(*plugInInterface)->Release(plugInInterface);
/* clean up endpoint data */
cInterface->num_endpoints = 0;
-
+
/* delete the interface's async event source */
if (cInterface->cfSource) {
CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
return darwin_to_libusb (kresult);
}
-
+
driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0);
IOObjectRelease (usbInterface);
/* are we reading or writing? */
is_read = transfer->endpoint & LIBUSB_ENDPOINT_IN;
-
+
if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
(*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
&transferType, &maxPacketSize, &interval);
-
+
/* submit the request */
/* timeouts are unavailable on interrupt endpoints */
if (transferType == kUSBInterrupt) {
/* are we reading or writing? */
is_read = transfer->endpoint & LIBUSB_ENDPOINT_IN;
-
+
/* construct an array of IOUSBIsocFrames */
tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc (transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
if (!tpriv->isoc_framelist)
/* schedule for a frame a little in the future */
frame += 2;
-
+
/* submit the request */
if (is_read)
kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
return darwin_to_libusb (kresult);
}
-static int submit_control_transfer(struct usbi_transfer *itransfer) {
+static int submit_control_transfer(struct usbi_transfer *itransfer) {
struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
struct darwin_device_priv *dpriv = (struct darwin_device_priv *)transfer->dev_handle->dev->os_priv;
if (kresult != kIOReturnSuccess)
usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
-
+
return darwin_to_libusb (kresult);
}
/* abort transactions */
(*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
-
+
usbi_info (ITRANSFER_CTX (itransfer), "calling clear pipe stall to clear the data toggle bit");
/* clear the data toggle bit */
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fds[0]);
usbi_handle_disconnect(handle);
-
+
/* done with this device */
continue;
case MESSAGE_ASYNC_IO_COMPLETE: