Loading media/mtp/MtpFfsHandle.cpp +23 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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(); Loading @@ -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) { Loading media/mtp/MtpFfsHandle.h +4 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading
media/mtp/MtpFfsHandle.cpp +23 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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(); Loading @@ -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) { Loading
media/mtp/MtpFfsHandle.h +4 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading