summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--adb/usb_osx.cpp58
1 files changed, 36 insertions, 22 deletions
diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp
index 939f319ab..b3b3a2f2f 100644
--- a/adb/usb_osx.cpp
+++ b/adb/usb_osx.cpp
@@ -43,11 +43,11 @@ static io_iterator_t notificationIterator;
43 43
44struct usb_handle 44struct usb_handle
45{ 45{
46 UInt8 bulkIn; 46 UInt8 bulkIn;
47 UInt8 bulkOut; 47 UInt8 bulkOut;
48 IOUSBInterfaceInterface **interface; 48 IOUSBInterfaceInterface190** interface;
49 io_object_t usbNotification; 49 io_object_t usbNotification;
50 unsigned int zero_mask; 50 unsigned int zero_mask;
51}; 51};
52 52
53static CFRunLoopRef currentRunLoop = 0; 53static CFRunLoopRef currentRunLoop = 0;
@@ -59,7 +59,7 @@ static void AndroidInterfaceAdded(void *refCon, io_iterator_t iterator);
59static void AndroidInterfaceNotify(void *refCon, io_iterator_t iterator, 59static void AndroidInterfaceNotify(void *refCon, io_iterator_t iterator,
60 natural_t messageType, 60 natural_t messageType,
61 void *messageArgument); 61 void *messageArgument);
62static usb_handle* CheckInterface(IOUSBInterfaceInterface **iface, 62static usb_handle* CheckInterface(IOUSBInterfaceInterface190 **iface,
63 UInt16 vendor, UInt16 product); 63 UInt16 vendor, UInt16 product);
64 64
65static int 65static int
@@ -256,7 +256,7 @@ AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
256 DBG("INFO: Found vid=%04x pid=%04x serial=%s\n", vendor, product, 256 DBG("INFO: Found vid=%04x pid=%04x serial=%s\n", vendor, product,
257 serial); 257 serial);
258 258
259 usb_handle* handle = CheckInterface((IOUSBInterfaceInterface**)iface, 259 usb_handle* handle = CheckInterface((IOUSBInterfaceInterface190**)iface,
260 vendor, product); 260 vendor, product);
261 if (handle == NULL) { 261 if (handle == NULL) {
262 DBG("ERR: Could not find device interface: %08x\n", kr); 262 DBG("ERR: Could not find device interface: %08x\n", kr);
@@ -299,10 +299,22 @@ AndroidInterfaceNotify(void *refCon, io_service_t service, natural_t messageType
299 } 299 }
300} 300}
301 301
302// Used to clear both the endpoints before starting.
303// When adb quits, we might clear the host endpoint but not the device.
304// So we make sure both sides are clear before starting up.
305static bool ClearPipeStallBothEnds(IOUSBInterfaceInterface190** interface, UInt8 bulkEp) {
306 IOReturn rc = (*interface)->ClearPipeStallBothEnds(interface, bulkEp);
307 if (rc != kIOReturnSuccess) {
308 DBG("ERR: Could not clear pipe: (%08x)\n", rc);
309 return false;
310 }
311 return true;
312}
313
302//* TODO: simplify this further since we only register to get ADB interface 314//* TODO: simplify this further since we only register to get ADB interface
303//* subclass+protocol events 315//* subclass+protocol events
304static usb_handle* 316static usb_handle*
305CheckInterface(IOUSBInterfaceInterface **interface, UInt16 vendor, UInt16 product) 317CheckInterface(IOUSBInterfaceInterface190 **interface, UInt16 vendor, UInt16 product)
306{ 318{
307 usb_handle* handle = NULL; 319 usb_handle* handle = NULL;
308 IOReturn kr; 320 IOReturn kr;
@@ -335,9 +347,9 @@ CheckInterface(IOUSBInterfaceInterface **interface, UInt16 vendor, UInt16 produc
335 347
336 //* check to make sure interface class, subclass and protocol match ADB 348 //* check to make sure interface class, subclass and protocol match ADB
337 //* avoid opening mass storage endpoints 349 //* avoid opening mass storage endpoints
338 if (!is_adb_interface(vendor, product, interfaceClass, 350 if (!is_adb_interface(vendor, product, interfaceClass, interfaceSubClass, interfaceProtocol)) {
339 interfaceSubClass, interfaceProtocol))
340 goto err_bad_adb_interface; 351 goto err_bad_adb_interface;
352 }
341 353
342 handle = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle))); 354 handle = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
343 if (handle == nullptr) goto err_bad_adb_interface; 355 if (handle == nullptr) goto err_bad_adb_interface;
@@ -353,22 +365,24 @@ CheckInterface(IOUSBInterfaceInterface **interface, UInt16 vendor, UInt16 produc
353 365
354 kr = (*interface)->GetPipeProperties(interface, endpoint, &direction, 366 kr = (*interface)->GetPipeProperties(interface, endpoint, &direction,
355 &number, &transferType, &maxPacketSize, &interval); 367 &number, &transferType, &maxPacketSize, &interval);
368 if (kr != kIOReturnSuccess) {
369 DBG("ERR: FindDeviceInterface - could not get pipe properties (%08x)\n", kr);
370 goto err_get_pipe_props;
371 }
356 372
357 if (kIOReturnSuccess == kr) { 373 if (kUSBBulk != transferType) continue;
358 if (kUSBBulk != transferType)
359 continue;
360
361 if (kUSBIn == direction)
362 handle->bulkIn = endpoint;
363 374
364 if (kUSBOut == direction) 375 if (kUSBIn == direction) {
365 handle->bulkOut = endpoint; 376 handle->bulkIn = endpoint;
377 if (!ClearPipeStallBothEnds(interface, handle->bulkIn)) goto err_get_pipe_props;
378 }
366 379
367 handle->zero_mask = maxPacketSize - 1; 380 if (kUSBOut == direction) {
368 } else { 381 handle->bulkOut = endpoint;
369 DBG("ERR: FindDeviceInterface - could not get pipe properties (%08x)\n", kr); 382 if (!ClearPipeStallBothEnds(interface, handle->bulkOut)) goto err_get_pipe_props;
370 goto err_get_pipe_props;
371 } 383 }
384
385 handle->zero_mask = maxPacketSize - 1;
372 } 386 }
373 387
374 handle->interface = interface; 388 handle->interface = interface;