summaryrefslogtreecommitdiffstats
path: root/usbmuxd/usb-linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'usbmuxd/usb-linux.c')
-rw-r--r--usbmuxd/usb-linux.c41
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
50static struct collection device_list; 51static 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);