Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e05dfa2 authored by Josh Gao's avatar Josh Gao
Browse files

adb: properly calculate packet size on Mac.

OS X reports maxPacketSize as wMaxPacketSize * (bMaxBurst + 1) in the
deprecated GetPipeProperties function. Use the also-deprecated
GetPipePropetiesV2 API to get bMaxBurst and figure out what
wMaxPacketSize is. (This file is going to go away eventually, so don't
bother with switching to the recommended GetPipePropertiesV3, since
it would be a substantially larger charge.)

libusb is unaffected.

Bug: http://b/77733422
Test: python test_device.py
Change-Id: I66517d699a4f39b93ba5eb7882bd8ee6c70f3672
(cherry picked from commit 2ea46521)
parent 8aafb0d7
Loading
Loading
Loading
Loading
+23 −12
Original line number Original line Diff line number Diff line
@@ -50,7 +50,7 @@ struct usb_handle
{
{
    UInt8 bulkIn;
    UInt8 bulkIn;
    UInt8 bulkOut;
    UInt8 bulkOut;
    IOUSBInterfaceInterface190** interface;
    IOUSBInterfaceInterface550** interface;
    unsigned int zero_mask;
    unsigned int zero_mask;
    size_t max_packet_size;
    size_t max_packet_size;


@@ -106,8 +106,8 @@ static void AddDevice(std::unique_ptr<usb_handle> handle) {
}
}


static void AndroidInterfaceAdded(io_iterator_t iterator);
static void AndroidInterfaceAdded(io_iterator_t iterator);
static std::unique_ptr<usb_handle> CheckInterface(IOUSBInterfaceInterface190 **iface,
static std::unique_ptr<usb_handle> CheckInterface(IOUSBInterfaceInterface550** iface, UInt16 vendor,
                                                  UInt16 vendor, UInt16 product);
                                                  UInt16 product);


static bool FindUSBDevices() {
static bool FindUSBDevices() {
    // Create the matching dictionary to find the Android device's adb interface.
    // Create the matching dictionary to find the Android device's adb interface.
@@ -295,8 +295,8 @@ AndroidInterfaceAdded(io_iterator_t iterator)
            continue;
            continue;
        }
        }


        std::unique_ptr<usb_handle> handle = CheckInterface((IOUSBInterfaceInterface190**)iface,
        std::unique_ptr<usb_handle> handle =
                                                            vendor, product);
            CheckInterface((IOUSBInterfaceInterface550**)iface, vendor, product);
        if (handle == nullptr) {
        if (handle == nullptr) {
            LOG(ERROR) << "Could not find device interface";
            LOG(ERROR) << "Could not find device interface";
            (*iface)->Release(iface);
            (*iface)->Release(iface);
@@ -315,7 +315,7 @@ AndroidInterfaceAdded(io_iterator_t iterator)
// Used to clear both the endpoints before starting.
// Used to clear both the endpoints before starting.
// When adb quits, we might clear the host endpoint but not the device.
// When adb quits, we might clear the host endpoint but not the device.
// So we make sure both sides are clear before starting up.
// 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);
    IOReturn rc = (*interface)->ClearPipeStallBothEnds(interface, bulkEp);
    if (rc != kIOReturnSuccess) {
    if (rc != kIOReturnSuccess) {
        LOG(ERROR) << "Could not clear pipe stall both ends: " << std::hex << rc;
        LOG(ERROR) << "Could not clear pipe stall both ends: " << std::hex << rc;
@@ -326,9 +326,8 @@ static bool ClearPipeStallBothEnds(IOUSBInterfaceInterface190** interface, UInt8


//* TODO: simplify this further since we only register to get ADB interface
//* TODO: simplify this further since we only register to get ADB interface
//* subclass+protocol events
//* subclass+protocol events
static std::unique_ptr<usb_handle>
static std::unique_ptr<usb_handle> CheckInterface(IOUSBInterfaceInterface550** interface,
CheckInterface(IOUSBInterfaceInterface190 **interface, UInt16 vendor, UInt16 product)
                                                  UInt16 vendor, UInt16 product) {
{
    std::unique_ptr<usb_handle> handle;
    std::unique_ptr<usb_handle> handle;
    IOReturn kr;
    IOReturn kr;
    UInt8 interfaceNumEndpoints, interfaceClass, interfaceSubClass, interfaceProtocol;
    UInt8 interfaceNumEndpoints, interfaceClass, interfaceSubClass, interfaceProtocol;
@@ -376,9 +375,14 @@ CheckInterface(IOUSBInterfaceInterface190 **interface, UInt16 vendor, UInt16 pro
        UInt8   interval;
        UInt8   interval;
        UInt8   number;
        UInt8   number;
        UInt8   direction;
        UInt8   direction;

        UInt8 maxBurst;
        kr = (*interface)->GetPipeProperties(interface, endpoint, &direction,
        UInt8 mult;
                &number, &transferType, &maxPacketSize, &interval);
        UInt16 bytesPerInterval;

        kr = (*interface)
                 ->GetPipePropertiesV2(interface, endpoint, &direction, &number, &transferType,
                                       &maxPacketSize, &interval, &maxBurst, &mult,
                                       &bytesPerInterval);
        if (kr != kIOReturnSuccess) {
        if (kr != kIOReturnSuccess) {
            LOG(ERROR) << "FindDeviceInterface - could not get pipe properties: "
            LOG(ERROR) << "FindDeviceInterface - could not get pipe properties: "
                       << std::hex << kr;
                       << std::hex << kr;
@@ -397,6 +401,13 @@ CheckInterface(IOUSBInterfaceInterface190 **interface, UInt16 vendor, UInt16 pro
            if (!ClearPipeStallBothEnds(interface, handle->bulkOut)) goto err_get_pipe_props;
            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->zero_mask = maxPacketSize - 1;
        handle->max_packet_size = maxPacketSize;
        handle->max_packet_size = maxPacketSize;
    }
    }
+12 −10
Original line number Original line Diff line number Diff line
@@ -1275,7 +1275,9 @@ class DeviceOfflineTest(DeviceTest):
        """
        """
        # The values that trigger things are 507 (512 - 5 bytes from shell protocol) + 1024*n
        # 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.
        # Probe some surrounding values as well, for the hell of it.
        for length in [506, 507, 508, 1018, 1019, 1020, 1530, 1531, 1532]:
        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;'
                cmd = ['dd', 'if=/dev/zero', 'bs={}'.format(length), 'count=1', '2>/dev/null;'
                       'echo', 'foo']
                       'echo', 'foo']
                rc, stdout, _ = self.device.shell_nocheck(cmd)
                rc, stdout, _ = self.device.shell_nocheck(cmd)