OS X: Don't assume an interval of 1
authorNathan Hjelm <hjelmn@cs.unm.edu>
Wed, 3 Apr 2013 10:12:47 +0000 (04:12 -0600)
committerPete Batard <pete@akeo.ie>
Wed, 3 Apr 2013 18:46:17 +0000 (19:46 +0100)
libusb/os/darwin_usb.c
libusb/version_nano.h

index 30ee3ff..e90c1cc 100644 (file)
@@ -1385,11 +1385,12 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
   struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
 
-  IOReturn                kresult;
-  uint8_t                 pipeRef, iface;
-  UInt64                  frame;
-  AbsoluteTime            atTime;
-  int                     i;
+  IOReturn kresult;
+  uint8_t direction, number, interval, pipeRef, iface, transferType;
+  uint16_t maxPacketSize;
+  UInt64 frame;
+  AbsoluteTime atTime;
+  int i;
 
   struct darwin_interface *cInterface;
 
@@ -1429,6 +1430,14 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
     return darwin_to_libusb (kresult);
   }
 
+  (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
+                                                 &transferType, &maxPacketSize, &interval);
+
+  /* work around buggy devices */
+  if (0 == interval) {
+    interval = 9;
+  }
+
   /* schedule for a frame a little in the future */
   frame += 4;
 
@@ -1445,10 +1454,9 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
                                                               transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
                                                               itransfer);
 
-  if (transfer->dev_handle->dev->speed == LIBUSB_SPEED_FULL)
-    cInterface->frames[transfer->endpoint] = frame + transfer->num_iso_packets;
-  else
-    cInterface->frames[transfer->endpoint] = frame + transfer->num_iso_packets / 8;
+  cInterface->frames[transfer->endpoint] = frame + transfer->num_iso_packets * (1 << (interval - 1));
+  if (transfer->dev_handle->dev->speed >= LIBUSB_SPEED_HIGH)
+    cInterface->frames[transfer->endpoint] /= 8;
 
   if (kresult != kIOReturnSuccess) {
     usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
index 19e505f..9aec26e 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 10636
+#define LIBUSB_NANO 10637