diff options
Diffstat (limited to 'usbmuxd')
| -rw-r--r-- | usbmuxd/usb-linux.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/usbmuxd/usb-linux.c b/usbmuxd/usb-linux.c index 9634d14..fb22d03 100644 --- a/usbmuxd/usb-linux.c +++ b/usbmuxd/usb-linux.c | |||
| @@ -45,6 +45,7 @@ struct usb_device { | |||
| 45 | int alive; | 45 | int alive; |
| 46 | struct libusb_transfer *rx_xfer; | 46 | struct libusb_transfer *rx_xfer; |
| 47 | struct collection tx_xfers; | 47 | struct collection tx_xfers; |
| 48 | int wMaxPacketSize; | ||
| 48 | }; | 49 | }; |
| 49 | 50 | ||
| 50 | static struct collection device_list; | 51 | static struct collection device_list; |
| @@ -133,26 +134,15 @@ int usb_send(struct usb_device *dev, const unsigned char *buf, int length) | |||
| 133 | struct libusb_transfer *xfer = libusb_alloc_transfer(0); | 134 | struct libusb_transfer *xfer = libusb_alloc_transfer(0); |
| 134 | libusb_fill_bulk_transfer(xfer, dev->dev, BULK_OUT, (void*)buf, length, tx_callback, dev, 0); | 135 | libusb_fill_bulk_transfer(xfer, dev->dev, BULK_OUT, (void*)buf, length, tx_callback, dev, 0); |
| 135 | xfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK; | 136 | xfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK; |
| 137 | if (length % dev->wMaxPacketSize == 0) { | ||
| 138 | xfer->flags |= LIBUSB_TRANSFER_ZERO_PACKET; | ||
| 139 | } | ||
| 136 | if((res = libusb_submit_transfer(xfer)) < 0) { | 140 | if((res = libusb_submit_transfer(xfer)) < 0) { |
| 137 | usbmuxd_log(LL_ERROR, "Failed to submit TX transfer %p len %d to device %d-%d: %d", buf, length, dev->bus, dev->address, res); | 141 | usbmuxd_log(LL_ERROR, "Failed to submit TX transfer %p len %d to device %d-%d: %d", buf, length, dev->bus, dev->address, res); |
| 138 | libusb_free_transfer(xfer); | 142 | libusb_free_transfer(xfer); |
| 139 | return res; | 143 | return res; |
| 140 | } | 144 | } |
| 141 | collection_add(&dev->tx_xfers, xfer); | 145 | collection_add(&dev->tx_xfers, xfer); |
| 142 | if((length % 512) == 0) { | ||
| 143 | usbmuxd_log(LL_DEBUG, "Send ZLP"); | ||
| 144 | // Send Zero Length Packet | ||
| 145 | xfer = libusb_alloc_transfer(0); | ||
| 146 | void *buffer = malloc(1); | ||
| 147 | libusb_fill_bulk_transfer(xfer, dev->dev, BULK_OUT, buffer, 0, tx_callback, dev, 0); | ||
| 148 | xfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK; | ||
| 149 | if((res = libusb_submit_transfer(xfer)) < 0) { | ||
| 150 | usbmuxd_log(LL_ERROR, "Failed to submit TX ZLP transfer to device %d-%d: %d", dev->bus, dev->address, res); | ||
| 151 | libusb_free_transfer(xfer); | ||
| 152 | return res; | ||
| 153 | } | ||
| 154 | collection_add(&dev->tx_xfers, xfer); | ||
| 155 | } | ||
| 156 | return 0; | 146 | return 0; |
| 157 | } | 147 | } |
| 158 | 148 | ||
| @@ -314,6 +304,29 @@ static int usb_discover(void) | |||
| 314 | usbdev->pid = devdesc.idProduct; | 304 | usbdev->pid = devdesc.idProduct; |
| 315 | usbdev->dev = handle; | 305 | usbdev->dev = handle; |
| 316 | usbdev->alive = 1; | 306 | usbdev->alive = 1; |
| 307 | usbdev->wMaxPacketSize = 0; | ||
| 308 | struct libusb_config_descriptor *cfg; | ||
| 309 | if (libusb_get_active_config_descriptor(dev, &cfg) == 0 | ||
| 310 | && cfg && cfg->bNumInterfaces >= (USB_INTERFACE+1)) { | ||
| 311 | const struct libusb_interface *ifp = &cfg->interface[USB_INTERFACE]; | ||
| 312 | if (ifp && ifp->num_altsetting >= 1) { | ||
| 313 | const struct libusb_interface_descriptor *as = &ifp->altsetting[0]; | ||
| 314 | int i; | ||
| 315 | for (i = 0; i < as->bNumEndpoints; i++) { | ||
| 316 | const struct libusb_endpoint_descriptor *ep = &as->endpoint[i]; | ||
| 317 | if (ep->bEndpointAddress == BULK_OUT) { | ||
| 318 | usbdev->wMaxPacketSize = ep->wMaxPacketSize; | ||
| 319 | } | ||
| 320 | } | ||
| 321 | } | ||
| 322 | } | ||
| 323 | if (usbdev->wMaxPacketSize == 0) { | ||
| 324 | usbmuxd_log(LL_ERROR, "Could not determine wMaxPacketSize for device %d-%d, setting to 64", usbdev->bus, usbdev->address); | ||
| 325 | usbdev->wMaxPacketSize = 64; | ||
| 326 | } else { | ||
| 327 | usbmuxd_log(LL_INFO, "Using wMaxPacketSize=%d for device %d-%d", usbdev->wMaxPacketSize, usbdev->bus, usbdev->address); | ||
| 328 | } | ||
| 329 | |||
| 317 | collection_init(&usbdev->tx_xfers); | 330 | collection_init(&usbdev->tx_xfers); |
| 318 | 331 | ||
| 319 | collection_add(&device_list, usbdev); | 332 | collection_add(&device_list, usbdev); |
