Merge "adb: properly calculate packet size on Mac."
am: ee63d74b6c
Change-Id: I2c4228a1d5bff33ca2db3249e261f98054eb342e
diff --git a/adb/client/usb_osx.cpp b/adb/client/usb_osx.cpp
index b15d28a..8a95a19 100644
--- a/adb/client/usb_osx.cpp
+++ b/adb/client/usb_osx.cpp
@@ -50,7 +50,7 @@
{
UInt8 bulkIn;
UInt8 bulkOut;
- IOUSBInterfaceInterface190** interface;
+ IOUSBInterfaceInterface550** interface;
unsigned int zero_mask;
size_t max_packet_size;
@@ -106,8 +106,8 @@
}
static void AndroidInterfaceAdded(io_iterator_t iterator);
-static std::unique_ptr<usb_handle> CheckInterface(IOUSBInterfaceInterface190 **iface,
- UInt16 vendor, UInt16 product);
+static std::unique_ptr<usb_handle> CheckInterface(IOUSBInterfaceInterface550** iface, UInt16 vendor,
+ UInt16 product);
static bool FindUSBDevices() {
// Create the matching dictionary to find the Android device's adb interface.
@@ -295,8 +295,8 @@
continue;
}
- std::unique_ptr<usb_handle> handle = CheckInterface((IOUSBInterfaceInterface190**)iface,
- vendor, product);
+ std::unique_ptr<usb_handle> handle =
+ CheckInterface((IOUSBInterfaceInterface550**)iface, vendor, product);
if (handle == nullptr) {
LOG(ERROR) << "Could not find device interface";
(*iface)->Release(iface);
@@ -315,7 +315,7 @@
// Used to clear both the endpoints before starting.
// When adb quits, we might clear the host endpoint but not the device.
// So we make sure both sides are clear before starting up.
-static bool ClearPipeStallBothEnds(IOUSBInterfaceInterface190** interface, UInt8 bulkEp) {
+static bool ClearPipeStallBothEnds(IOUSBInterfaceInterface550** interface, UInt8 bulkEp) {
IOReturn rc = (*interface)->ClearPipeStallBothEnds(interface, bulkEp);
if (rc != kIOReturnSuccess) {
LOG(ERROR) << "Could not clear pipe stall both ends: " << std::hex << rc;
@@ -326,9 +326,8 @@
//* TODO: simplify this further since we only register to get ADB interface
//* subclass+protocol events
-static std::unique_ptr<usb_handle>
-CheckInterface(IOUSBInterfaceInterface190 **interface, UInt16 vendor, UInt16 product)
-{
+static std::unique_ptr<usb_handle> CheckInterface(IOUSBInterfaceInterface550** interface,
+ UInt16 vendor, UInt16 product) {
std::unique_ptr<usb_handle> handle;
IOReturn kr;
UInt8 interfaceNumEndpoints, interfaceClass, interfaceSubClass, interfaceProtocol;
@@ -376,9 +375,14 @@
UInt8 interval;
UInt8 number;
UInt8 direction;
+ UInt8 maxBurst;
+ UInt8 mult;
+ UInt16 bytesPerInterval;
- kr = (*interface)->GetPipeProperties(interface, endpoint, &direction,
- &number, &transferType, &maxPacketSize, &interval);
+ kr = (*interface)
+ ->GetPipePropertiesV2(interface, endpoint, &direction, &number, &transferType,
+ &maxPacketSize, &interval, &maxBurst, &mult,
+ &bytesPerInterval);
if (kr != kIOReturnSuccess) {
LOG(ERROR) << "FindDeviceInterface - could not get pipe properties: "
<< std::hex << kr;
@@ -397,6 +401,13 @@
if (!ClearPipeStallBothEnds(interface, handle->bulkOut)) goto err_get_pipe_props;
}
+ if (maxBurst != 0)
+ // bMaxBurst is the number of additional packets in the burst.
+ maxPacketSize /= (maxBurst + 1);
+
+ // mult is only relevant for isochronous endpoints.
+ CHECK_EQ(0, mult);
+
handle->zero_mask = maxPacketSize - 1;
handle->max_packet_size = maxPacketSize;
}
diff --git a/adb/test_device.py b/adb/test_device.py
index d39eb14..b1ad043 100644
--- a/adb/test_device.py
+++ b/adb/test_device.py
@@ -1275,16 +1275,18 @@
"""
# The values that trigger things are 507 (512 - 5 bytes from shell protocol) + 1024*n
# Probe some surrounding values as well, for the hell of it.
- for length in [506, 507, 508, 1018, 1019, 1020, 1530, 1531, 1532]:
- cmd = ['dd', 'if=/dev/zero', 'bs={}'.format(length), 'count=1', '2>/dev/null;'
- 'echo', 'foo']
- rc, stdout, _ = self.device.shell_nocheck(cmd)
+ for base in [512] + range(1024, 1024 * 16, 1024):
+ for offset in [-6, -5, -4]:
+ length = base + offset
+ cmd = ['dd', 'if=/dev/zero', 'bs={}'.format(length), 'count=1', '2>/dev/null;'
+ 'echo', 'foo']
+ rc, stdout, _ = self.device.shell_nocheck(cmd)
- self.assertEqual(0, rc)
+ self.assertEqual(0, rc)
- # Output should be '\0' * length, followed by "foo\n"
- self.assertEqual(length, len(stdout) - 4)
- self.assertEqual(stdout, "\0" * length + "foo\n")
+ # Output should be '\0' * length, followed by "foo\n"
+ self.assertEqual(length, len(stdout) - 4)
+ self.assertEqual(stdout, "\0" * length + "foo\n")
def main():