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

Commit e4dbaeff authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I89610b96,I9986cd8c

* changes:
  Retry allocations in case of ENODEV
  Fix GetPartialObject on FFS
parents 3f6419d0 b4f54266
Loading
Loading
Loading
Loading
+23 −6
Original line number Diff line number Diff line
@@ -62,8 +62,13 @@ constexpr int MAX_FILE_CHUNK_SIZE = 3145728;
constexpr int USB_FFS_MAX_WRITE = MTP_BUFFER_SIZE;
constexpr int USB_FFS_MAX_READ = MTP_BUFFER_SIZE;

static_assert(USB_FFS_MAX_WRITE > 0, "Max r/w values must be > 0!");
static_assert(USB_FFS_MAX_READ > 0, "Max r/w values must be > 0!");

constexpr unsigned int MAX_MTP_FILE_SIZE = 0xFFFFFFFF;

constexpr size_t ENDPOINT_ALLOC_RETRIES = 10;

struct func_desc {
    struct usb_interface_descriptor intf;
    struct usb_endpoint_descriptor_no_audio sink;
@@ -459,19 +464,28 @@ int MtpFfsHandle::start() {
    mMaxWrite = android::base::GetIntProperty("sys.usb.ffs.max_write", USB_FFS_MAX_WRITE);
    mMaxRead = android::base::GetIntProperty("sys.usb.ffs.max_read", USB_FFS_MAX_READ);

    while (mMaxWrite > USB_FFS_MAX_WRITE && mMaxRead > USB_FFS_MAX_READ) {
    size_t attempts = 0;
    while (mMaxWrite >= USB_FFS_MAX_WRITE && mMaxRead >= USB_FFS_MAX_READ &&
            attempts < ENDPOINT_ALLOC_RETRIES) {
        // If larger contiguous chunks of memory aren't available, attempt to try
        // smaller allocations.
        if (ioctl(mBulkIn, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(mMaxWrite)) ||
            ioctl(mBulkOut, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(mMaxRead))) {
            if (errno == ENODEV) {
                // Driver hasn't enabled endpoints yet.
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
                attempts += 1;
                continue;
            }
            mMaxWrite /= 2;
            mMaxRead /=2;
        } else {
            return 0;
        }
    }
    // Try to start MtpServer anyway, with the smallest max r/w values
    PLOG(ERROR) << "Functionfs could not allocate any memory!";
    return -1;
    return 0;
}

int MtpFfsHandle::configure(bool usePtp) {
@@ -583,7 +597,7 @@ int MtpFfsHandle::sendFile(mtp_file_range mfr) {
    uint64_t file_length = mfr.length;
    uint32_t given_length = std::min(static_cast<uint64_t>(MAX_MTP_FILE_SIZE),
            file_length + sizeof(mtp_data_header));
    uint64_t offset = 0;
    uint64_t offset = mfr.offset;
    struct usb_endpoint_descriptor mBulkIn_desc;
    int packet_size;

@@ -594,7 +608,10 @@ int MtpFfsHandle::sendFile(mtp_file_range mfr) {
        packet_size = mBulkIn_desc.wMaxPacketSize;
    }

    int init_read_len = packet_size - sizeof(mtp_data_header);
    // If file_length is larger than a size_t, truncating would produce the wrong comparison.
    // Instead, promote the left side to 64 bits, then truncate the small result.
    int init_read_len = std::min(
            static_cast<uint64_t>(packet_size - sizeof(mtp_data_header)), file_length);

    char *data = mBuffer1.data();
    char *data2 = mBuffer2.data();
@@ -620,10 +637,10 @@ int MtpFfsHandle::sendFile(mtp_file_range mfr) {
    if (TEMP_FAILURE_RETRY(pread(mfr.fd, reinterpret_cast<char*>(data) +
                    sizeof(mtp_data_header), init_read_len, offset))
            != init_read_len) return -1;
    if (writeHandle(mBulkIn, data, sizeof(mtp_data_header) + init_read_len) == -1) return -1;
    if (file_length == static_cast<unsigned>(init_read_len)) return 0;
    file_length -= init_read_len;
    offset += init_read_len;
    if (writeHandle(mBulkIn, data, packet_size) == -1) return -1;
    if (file_length == 0) return 0;

    // Break down the file into pieces that fit in buffers
    while(file_length > 0) {
+4 −0
Original line number Diff line number Diff line
@@ -59,6 +59,10 @@ public:
    int sendFile(mtp_file_range mfr);
    int sendEvent(mtp_event me);

    /**
     * Open ffs endpoints and allocate necessary kernel and user memory.
     * Will sleep until endpoints are enabled, for up to 1 second.
     */
    int start();
    void close();