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

Commit 88845be6 authored by Mike Lockwood's avatar Mike Lockwood Committed by Android Git Automerger
Browse files

am 215b682b: MTP: changes to use new usb_request support in libusbhost

* commit '215b682b':
  MTP: changes to use new usb_request support in libusbhost
parents 744d4dd8 215b682b
Loading
Loading
Loading
Loading
+3 −14
Original line number Original line Diff line number Diff line
@@ -29,12 +29,8 @@
#include <errno.h>
#include <errno.h>


#include <usbhost/usbhost.h>
#include <usbhost/usbhost.h>
#include <linux/version.h>

#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20)
struct usb_device;
#include <linux/usb/ch9.h>
#else
#include <linux/usb_ch9.h>
#endif


namespace android {
namespace android {


@@ -194,20 +190,13 @@ bool MtpClient::usbDeviceAdded(const char *devname) {
                return mDone;
                return mDone;
            }
            }


            struct usb_endpoint *ep_in = usb_endpoint_open(device, ep_in_desc);
            struct usb_endpoint *ep_out = usb_endpoint_open(device, ep_out_desc);
            struct usb_endpoint *ep_intr = usb_endpoint_open(device, ep_intr_desc);

            if (usb_device_claim_interface(device, interface->bInterfaceNumber)) {
            if (usb_device_claim_interface(device, interface->bInterfaceNumber)) {
                LOGE("usb_device_claim_interface failed errno: %d\n", errno);
                LOGE("usb_device_claim_interface failed errno: %d\n", errno);
                usb_endpoint_close(ep_in);
                usb_endpoint_close(ep_out);
                usb_endpoint_close(ep_intr);
                return mDone;
                return mDone;
            }
            }


            MtpDevice* mtpDevice = new MtpDevice(device, interface->bInterfaceNumber,
            MtpDevice* mtpDevice = new MtpDevice(device, interface->bInterfaceNumber,
                        ep_in, ep_out, ep_intr);
                        ep_in_desc, ep_out_desc, ep_intr_desc);
            mDeviceList.add(mtpDevice);
            mDeviceList.add(mtpDevice);
            mtpDevice->initialize();
            mtpDevice->initialize();
            deviceAdded(mtpDevice);
            deviceAdded(mtpDevice);
+37 −21
Original line number Original line Diff line number Diff line
@@ -391,15 +391,19 @@ int MtpDataPacket::writeDataHeader(int fd, uint32_t length) {
#endif // MTP_DEVICE
#endif // MTP_DEVICE


#ifdef MTP_HOST
#ifdef MTP_HOST
int MtpDataPacket::read(struct usb_endpoint *ep) {
int MtpDataPacket::read(struct usb_request *request) {
    // first read the header
    // first read the header
    int length = transfer(ep, mBuffer, mBufferSize);
    request->buffer = mBuffer;
    request->buffer_length = mBufferSize;
    int length = transfer(request);
    if (length >= MTP_CONTAINER_HEADER_SIZE) {
    if (length >= MTP_CONTAINER_HEADER_SIZE) {
        // look at the length field to see if the data spans multiple packets
        // look at the length field to see if the data spans multiple packets
        uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET);
        uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET);
        while (totalLength > length) {
        while (totalLength > length) {
            allocate(length + mAllocationIncrement);
            allocate(length + mAllocationIncrement);
            int ret = transfer(ep, mBuffer + length, mAllocationIncrement);
            request->buffer = mBuffer + length;
            request->buffer_length = mAllocationIncrement;
            int ret = transfer(request);
            if (ret >= 0)
            if (ret >= 0)
                length += ret;
                length += ret;
            else {
            else {
@@ -413,10 +417,12 @@ int MtpDataPacket::read(struct usb_endpoint *ep) {
    return length;
    return length;
}
}


int MtpDataPacket::readData(struct usb_endpoint *ep, void* buffer, int length) {
int MtpDataPacket::readData(struct usb_request *request, void* buffer, int length) {
    int read = 0;
    int read = 0;
    while (read < length) {
    while (read < length) {
        int ret = transfer(ep, (char *)buffer + read, length - read);
        request->buffer = (char *)buffer + read;
        request->buffer_length = length - read;
        int ret = transfer(request);
        if (ret < 0) {
        if (ret < 0) {
            return ret;
            return ret;
        }
        }
@@ -426,8 +432,8 @@ int MtpDataPacket::readData(struct usb_endpoint *ep, void* buffer, int length) {
}
}


// Queue a read request.  Call readDataWait to wait for result
// Queue a read request.  Call readDataWait to wait for result
int MtpDataPacket::readDataAsync(struct usb_endpoint *ep, void* buffer, int length) {
int MtpDataPacket::readDataAsync(struct usb_request *req) {
    if (usb_endpoint_queue(ep, buffer, length)) {
    if (usb_request_queue(req)) {
        LOGE("usb_endpoint_queue failed, errno: %d", errno);
        LOGE("usb_endpoint_queue failed, errno: %d", errno);
        return -1;
        return -1;
    }
    }
@@ -435,39 +441,49 @@ int MtpDataPacket::readDataAsync(struct usb_endpoint *ep, void* buffer, int leng
}
}


// Wait for result of readDataAsync
// Wait for result of readDataAsync
int MtpDataPacket::readDataWait(struct usb_endpoint *ep) {
int MtpDataPacket::readDataWait(struct usb_device *device) {
    int ep_num;
    struct usb_request *req = usb_request_wait(device);
    return usb_endpoint_wait(usb_endpoint_get_device(ep), &ep_num);
    return (req ? req->actual_length : -1);
}
}


int MtpDataPacket::readDataHeader(struct usb_endpoint *ep) {
int MtpDataPacket::readDataHeader(struct usb_request *request) {
    int length = transfer(ep, mBuffer, usb_endpoint_max_packet(ep));
    request->buffer = mBuffer;
    request->buffer_length = request->max_packet_size;
    int length = transfer(request);
    if (length >= 0)
    if (length >= 0)
        mPacketSize = length;
        mPacketSize = length;
    return length;
    return length;
}
}


int MtpDataPacket::writeDataHeader(struct usb_endpoint *ep, uint32_t length) {
int MtpDataPacket::writeDataHeader(struct usb_request *request, uint32_t length) {
    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
    int ret = transfer(ep, mBuffer, MTP_CONTAINER_HEADER_SIZE);
    request->buffer = mBuffer;
    request->buffer_length = MTP_CONTAINER_HEADER_SIZE;
    int ret = transfer(request);
    return (ret < 0 ? ret : 0);
    return (ret < 0 ? ret : 0);
}
}


int MtpDataPacket::write(struct usb_endpoint *ep) {
int MtpDataPacket::write(struct usb_request *request) {
    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);


    // send header separately from data
    // send header separately from data
    int ret = transfer(ep, mBuffer, MTP_CONTAINER_HEADER_SIZE);
    request->buffer = mBuffer;
    if (ret == MTP_CONTAINER_HEADER_SIZE)
    request->buffer_length = MTP_CONTAINER_HEADER_SIZE;
        ret = transfer(ep, mBuffer + MTP_CONTAINER_HEADER_SIZE,
    int ret = transfer(request);
                        mPacketSize - MTP_CONTAINER_HEADER_SIZE);
    if (ret == MTP_CONTAINER_HEADER_SIZE) {
        request->buffer = mBuffer + MTP_CONTAINER_HEADER_SIZE;
        request->buffer_length = mPacketSize - MTP_CONTAINER_HEADER_SIZE;
        ret = transfer(request);
    }
    return (ret < 0 ? ret : 0);
    return (ret < 0 ? ret : 0);
}
}


int MtpDataPacket::write(struct usb_endpoint *ep, void* buffer, uint32_t length) {
int MtpDataPacket::write(struct usb_request *request, void* buffer, uint32_t length) {
    int ret = transfer(ep, buffer, length);
    request->buffer = buffer;
    request->buffer_length = length;
    int ret = transfer(request);
    return (ret < 0 ? ret : 0);
    return (ret < 0 ? ret : 0);
}
}


+12 −9
Original line number Original line Diff line number Diff line
@@ -20,6 +20,9 @@
#include "MtpPacket.h"
#include "MtpPacket.h"
#include "mtp.h"
#include "mtp.h"


struct usb_device;
struct usb_request;

namespace android {
namespace android {


class MtpStringBuffer;
class MtpStringBuffer;
@@ -100,15 +103,15 @@ public:
#endif
#endif


#ifdef MTP_HOST
#ifdef MTP_HOST
    int                 read(struct usb_endpoint *ep);
    int                 read(struct usb_request *request);
    int                 readData(struct usb_endpoint *ep, void* buffer, int length);
    int                 readData(struct usb_request *request, void* buffer, int length);
    int                 readDataAsync(struct usb_endpoint *ep, void* buffer, int length);
    int                 readDataAsync(struct usb_request *req);
    int                 readDataWait(struct usb_endpoint *ep);
    int                 readDataWait(struct usb_device *device);
    int                 readDataHeader(struct usb_endpoint *ep);
    int                 readDataHeader(struct usb_request *ep);


    int                 writeDataHeader(struct usb_endpoint *ep, uint32_t length);
    int                 writeDataHeader(struct usb_request *ep, uint32_t length);
    int                 write(struct usb_endpoint *ep);
    int                 write(struct usb_request *ep);
    int                 write(struct usb_endpoint *ep, void* buffer, uint32_t length);
    int                 write(struct usb_request *ep, void* buffer, uint32_t length);
#endif
#endif


    inline bool         hasData() const { return mPacketSize > MTP_CONTAINER_HEADER_SIZE; }
    inline bool         hasData() const { return mPacketSize > MTP_CONTAINER_HEADER_SIZE; }
+35 −23
Original line number Original line Diff line number Diff line
@@ -39,25 +39,35 @@
namespace android {
namespace android {


MtpDevice::MtpDevice(struct usb_device* device, int interface,
MtpDevice::MtpDevice(struct usb_device* device, int interface,
            struct usb_endpoint *ep_in, struct usb_endpoint *ep_out,
            const struct usb_endpoint_descriptor *ep_in,
            struct usb_endpoint *ep_intr)
            const struct usb_endpoint_descriptor *ep_out,
            const struct usb_endpoint_descriptor *ep_intr)
    :   mDevice(device),
    :   mDevice(device),
        mInterface(interface),
        mInterface(interface),
        mEndpointIn(ep_in),
        mRequestIn1(NULL),
        mEndpointOut(ep_out),
        mRequestIn2(NULL),
        mEndpointIntr(ep_intr),
        mRequestOut(NULL),
        mRequestIntr(NULL),
        mDeviceInfo(NULL),
        mDeviceInfo(NULL),
        mID(usb_device_get_unique_id(device)),
        mID(usb_device_get_unique_id(device)),
        mSessionID(0),
        mSessionID(0),
        mTransactionID(0),
        mTransactionID(0),
        mReceivedResponse(false)
        mReceivedResponse(false)
{
{
    mRequestIn1 = usb_request_new(device, ep_in);
    mRequestIn2 = usb_request_new(device, ep_in);
    mRequestOut = usb_request_new(device, ep_out);
    mRequestIntr = usb_request_new(device, ep_intr);
}
}


MtpDevice::~MtpDevice() {
MtpDevice::~MtpDevice() {
    close();
    close();
    for (int i = 0; i < mDeviceProperties.size(); i++)
    for (int i = 0; i < mDeviceProperties.size(); i++)
        delete mDeviceProperties[i];
        delete mDeviceProperties[i];
    usb_request_free(mRequestIn1);
    usb_request_free(mRequestIn2);
    usb_request_free(mRequestOut);
    usb_request_free(mRequestIntr);
}
}


void MtpDevice::initialize() {
void MtpDevice::initialize() {
@@ -325,7 +335,7 @@ bool MtpDevice::sendObject(MtpObjectInfo* info, int srcFD) {
        while (remaining > 0) {
        while (remaining > 0) {
            int count = read(srcFD, buffer, sizeof(buffer));
            int count = read(srcFD, buffer, sizeof(buffer));
            if (count > 0) {
            if (count > 0) {
                int written = mData.write(mEndpointOut, buffer, count);
                int written = mData.write(mRequestOut, buffer, count);
                // FIXME check error
                // FIXME check error
                remaining -= count;
                remaining -= count;
            } else {
            } else {
@@ -441,7 +451,7 @@ bool MtpDevice::readObject(MtpObjectHandle handle, const char* destPath, int gro
    mRequest.reset();
    mRequest.reset();
    mRequest.setParameter(1, handle);
    mRequest.setParameter(1, handle);
    if (sendRequest(MTP_OPERATION_GET_OBJECT)
    if (sendRequest(MTP_OPERATION_GET_OBJECT)
            && mData.readDataHeader(mEndpointIn)) {
            && mData.readDataHeader(mRequestIn1)) {
        uint32_t length = mData.getContainerLength();
        uint32_t length = mData.getContainerLength();
        if (length < MTP_CONTAINER_HEADER_SIZE)
        if (length < MTP_CONTAINER_HEADER_SIZE)
            goto fail;
            goto fail;
@@ -461,20 +471,22 @@ bool MtpDevice::readObject(MtpObjectHandle handle, const char* destPath, int gro


        // USB reads greater than 16K don't work
        // USB reads greater than 16K don't work
        char buffer1[16384], buffer2[16384];
        char buffer1[16384], buffer2[16384];
        char* readBuffer = buffer1;
        mRequestIn1->buffer = buffer1;
        char* writeBuffer = NULL;
        mRequestIn2->buffer = buffer2;
        struct usb_request* req = mRequestIn1;
        void* writeBuffer = NULL;
        int writeLength = 0;
        int writeLength = 0;


        while (remaining > 0 || writeBuffer) {
        while (remaining > 0 || writeBuffer) {
            if (remaining > 0) {
            if (remaining > 0) {
                // queue up a read request
                // queue up a read request
                int readSize = (remaining > sizeof(buffer1) ? sizeof(buffer1) : remaining);
                req->buffer_length = (remaining > sizeof(buffer1) ? sizeof(buffer1) : remaining);
                if (mData.readDataAsync(mEndpointIn, readBuffer, readSize)) {
                if (mData.readDataAsync(req)) {
                    LOGE("readDataAsync failed");
                    LOGE("readDataAsync failed");
                    goto fail;
                    goto fail;
                }
                }
            } else {
            } else {
                readBuffer = NULL;
                req = NULL;
            }
            }


            if (writeBuffer) {
            if (writeBuffer) {
@@ -482,23 +494,23 @@ bool MtpDevice::readObject(MtpObjectHandle handle, const char* destPath, int gro
                if (write(fd, writeBuffer, writeLength) != writeLength) {
                if (write(fd, writeBuffer, writeLength) != writeLength) {
                    LOGE("write failed");
                    LOGE("write failed");
                    // wait for pending read before failing
                    // wait for pending read before failing
                    if (readBuffer)
                    if (req)
                        mData.readDataWait(mEndpointIn);
                        mData.readDataWait(mDevice);
                    goto fail;
                    goto fail;
                }
                }
                writeBuffer = NULL;
                writeBuffer = NULL;
            }
            }


            // wait for read to complete
            // wait for read to complete
            if (readBuffer) {
            if (req) {
                int read = mData.readDataWait(mEndpointIn);
                int read = mData.readDataWait(mDevice);
                if (read < 0)
                if (read < 0)
                    goto fail;
                    goto fail;


                writeBuffer = readBuffer;
                writeBuffer = req->buffer;
                writeLength = read;
                writeLength = read;
                remaining -= read;
                remaining -= read;
                readBuffer = (readBuffer == buffer1 ? buffer2 : buffer1);
                req = (req == mRequestIn1 ? mRequestIn2 : mRequestIn1);
            }
            }
        }
        }


@@ -518,7 +530,7 @@ bool MtpDevice::sendRequest(MtpOperationCode operation) {
    mRequest.setOperationCode(operation);
    mRequest.setOperationCode(operation);
    if (mTransactionID > 0)
    if (mTransactionID > 0)
        mRequest.setTransactionID(mTransactionID++);
        mRequest.setTransactionID(mTransactionID++);
    int ret = mRequest.write(mEndpointOut);
    int ret = mRequest.write(mRequestOut);
    mRequest.dump();
    mRequest.dump();
    return (ret > 0);
    return (ret > 0);
}
}
@@ -527,14 +539,14 @@ bool MtpDevice::sendData() {
    LOGV("sendData\n");
    LOGV("sendData\n");
    mData.setOperationCode(mRequest.getOperationCode());
    mData.setOperationCode(mRequest.getOperationCode());
    mData.setTransactionID(mRequest.getTransactionID());
    mData.setTransactionID(mRequest.getTransactionID());
    int ret = mData.write(mEndpointOut);
    int ret = mData.write(mRequestOut);
    mData.dump();
    mData.dump();
    return (ret > 0);
    return (ret > 0);
}
}


bool MtpDevice::readData() {
bool MtpDevice::readData() {
    mData.reset();
    mData.reset();
    int ret = mData.read(mEndpointIn);
    int ret = mData.read(mRequestIn1);
    LOGV("readData returned %d\n", ret);
    LOGV("readData returned %d\n", ret);
    if (ret >= MTP_CONTAINER_HEADER_SIZE) {
    if (ret >= MTP_CONTAINER_HEADER_SIZE) {
        if (mData.getContainerType() == MTP_CONTAINER_TYPE_RESPONSE) {
        if (mData.getContainerType() == MTP_CONTAINER_TYPE_RESPONSE) {
@@ -557,7 +569,7 @@ bool MtpDevice::readData() {
bool MtpDevice::writeDataHeader(MtpOperationCode operation, int dataLength) {
bool MtpDevice::writeDataHeader(MtpOperationCode operation, int dataLength) {
    mData.setOperationCode(operation);
    mData.setOperationCode(operation);
    mData.setTransactionID(mRequest.getTransactionID());
    mData.setTransactionID(mRequest.getTransactionID());
    return (!mData.writeDataHeader(mEndpointOut, dataLength));
    return (!mData.writeDataHeader(mRequestOut, dataLength));
}
}


MtpResponseCode MtpDevice::readResponse() {
MtpResponseCode MtpDevice::readResponse() {
@@ -566,7 +578,7 @@ MtpResponseCode MtpDevice::readResponse() {
        mReceivedResponse = false;
        mReceivedResponse = false;
        return mResponse.getResponseCode();
        return mResponse.getResponseCode();
    }
    }
    int ret = mResponse.read(mEndpointIn);
    int ret = mResponse.read(mRequestIn1);
    if (ret >= MTP_CONTAINER_HEADER_SIZE) {
    if (ret >= MTP_CONTAINER_HEADER_SIZE) {
        mResponse.dump();
        mResponse.dump();
        return mResponse.getResponseCode();
        return mResponse.getResponseCode();
+9 −5
Original line number Original line Diff line number Diff line
@@ -25,6 +25,8 @@
#include <utils/threads.h>
#include <utils/threads.h>


struct usb_device;
struct usb_device;
struct usb_request;
struct usb_endpoint_descriptor;


namespace android {
namespace android {


@@ -36,9 +38,10 @@ class MtpDevice {
private:
private:
    struct usb_device*      mDevice;
    struct usb_device*      mDevice;
    int                     mInterface;
    int                     mInterface;
    struct usb_endpoint*    mEndpointIn;
    struct usb_request*     mRequestIn1;
    struct usb_endpoint*    mEndpointOut;
    struct usb_request*     mRequestIn2;
    struct usb_endpoint*    mEndpointIntr;
    struct usb_request*     mRequestOut;
    struct usb_request*     mRequestIntr;
    MtpDeviceInfo*          mDeviceInfo;
    MtpDeviceInfo*          mDeviceInfo;
    MtpPropertyList         mDeviceProperties;
    MtpPropertyList         mDeviceProperties;


@@ -61,8 +64,9 @@ private:


public:
public:
                            MtpDevice(struct usb_device* device, int interface,
                            MtpDevice(struct usb_device* device, int interface,
                                    struct usb_endpoint *ep_in, struct usb_endpoint *ep_out,
                                    const struct usb_endpoint_descriptor *ep_in,
                                    struct usb_endpoint *ep_intr);
                                    const struct usb_endpoint_descriptor *ep_out,
                                    const struct usb_endpoint_descriptor *ep_intr);
    virtual                 ~MtpDevice();
    virtual                 ~MtpDevice();


    inline int              getID() const { return mID; }
    inline int              getID() const { return mID; }
Loading