Loading media/mtp/MtpFfsHandle.cpp +51 −75 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ #include "AsyncIO.h" #include "MtpFfsHandle.h" #include "mtp.h" #define cpu_to_le16(x) htole16(x) #define cpu_to_le32(x) htole32(x) Loading @@ -58,8 +59,8 @@ constexpr int MAX_FILE_CHUNK_SIZE = 3145728; // To get good performance, override these with // higher values per device using the properties // sys.usb.ffs.max_read and sys.usb.ffs.max_write constexpr int USB_FFS_MAX_WRITE = 32768; constexpr int USB_FFS_MAX_READ = 32768; constexpr int USB_FFS_MAX_WRITE = MTP_BUFFER_SIZE; constexpr int USB_FFS_MAX_READ = MTP_BUFFER_SIZE; constexpr unsigned int MAX_MTP_FILE_SIZE = 0xFFFFFFFF; Loading Loading @@ -344,28 +345,9 @@ bool MtpFfsHandle::initFunctionfs() { if (mBulkIn > -1 || mBulkOut > -1 || mIntr > -1) LOG(WARNING) << "Endpoints were not closed before configure!"; mBulkIn.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_IN, O_RDWR))); if (mBulkIn < 0) { PLOG(ERROR) << FFS_MTP_EP_IN << ": cannot open bulk in ep"; goto err; } mBulkOut.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_OUT, O_RDWR))); if (mBulkOut < 0) { PLOG(ERROR) << FFS_MTP_EP_OUT << ": cannot open bulk out ep"; goto err; } mIntr.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_INTR, O_RDWR))); if (mIntr < 0) { PLOG(ERROR) << FFS_MTP_EP0 << ": cannot open intr ep"; goto err; } return true; err: closeEndpoints(); closeConfig(); return false; } Loading Loading @@ -447,8 +429,50 @@ int MtpFfsHandle::write(const void* data, int len) { int MtpFfsHandle::start() { mLock.lock(); mBulkIn.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_IN, O_RDWR))); if (mBulkIn < 0) { PLOG(ERROR) << FFS_MTP_EP_IN << ": cannot open bulk in ep"; return -1; } mBulkOut.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_OUT, O_RDWR))); if (mBulkOut < 0) { PLOG(ERROR) << FFS_MTP_EP_OUT << ": cannot open bulk out ep"; return -1; } mIntr.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_INTR, O_RDWR))); if (mIntr < 0) { PLOG(ERROR) << FFS_MTP_EP0 << ": cannot open intr ep"; return -1; } mBuffer1.resize(MAX_FILE_CHUNK_SIZE); mBuffer2.resize(MAX_FILE_CHUNK_SIZE); posix_madvise(mBuffer1.data(), MAX_FILE_CHUNK_SIZE, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED); posix_madvise(mBuffer2.data(), MAX_FILE_CHUNK_SIZE, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED); // Get device specific r/w size 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) { // 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))) { mMaxWrite /= 2; mMaxRead /=2; } else { return 0; } } PLOG(ERROR) << "Functionfs could not allocate any memory!"; return -1; } int MtpFfsHandle::configure(bool usePtp) { // Wait till previous server invocation has closed Loading @@ -465,13 +489,6 @@ int MtpFfsHandle::configure(bool usePtp) { return -1; } // Get device specific r/w size mMaxWrite = android::base::GetIntProperty("sys.usb.ffs.max_write", 0); mMaxRead = android::base::GetIntProperty("sys.usb.ffs.max_read", 0); if (!mMaxWrite) mMaxWrite = USB_FFS_MAX_WRITE; if (!mMaxRead) mMaxRead = USB_FFS_MAX_READ; return 0; } Loading @@ -480,26 +497,6 @@ void MtpFfsHandle::close() { mLock.unlock(); } class ScopedEndpointBufferAlloc { private: const int mFd; const unsigned int mAllocSize; public: ScopedEndpointBufferAlloc(int fd, unsigned alloc_size) : mFd(fd), mAllocSize(alloc_size) { if (ioctl(mFd, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(mAllocSize))) PLOG(ERROR) << "FFS endpoint alloc failed!"; } ~ScopedEndpointBufferAlloc() { if (ioctl(mFd, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(0))) PLOG(ERROR) << "FFS endpoint alloc reset failed!"; } DISALLOW_COPY_AND_ASSIGN(ScopedEndpointBufferAlloc); }; /* Read from USB and write to a local file. */ int MtpFfsHandle::receiveFile(mtp_file_range mfr) { // When receiving files, the incoming length is given in 32 bits. Loading @@ -507,15 +504,8 @@ int MtpFfsHandle::receiveFile(mtp_file_range mfr) { uint32_t file_length = mfr.length; uint64_t offset = lseek(mfr.fd, 0, SEEK_CUR); int buf1_len = std::min(static_cast<uint32_t>(MAX_FILE_CHUNK_SIZE), file_length); std::vector<char> buf1(buf1_len); char* data = buf1.data(); // If necessary, allocate a second buffer for background r/w int buf2_len = std::min(static_cast<uint32_t>(MAX_FILE_CHUNK_SIZE), file_length - MAX_FILE_CHUNK_SIZE); std::vector<char> buf2(std::max(0, buf2_len)); char *data2 = buf2.data(); char *data = mBuffer1.data(); char *data2 = mBuffer2.data(); struct aiocb aio; aio.aio_fildes = mfr.fd; Loading @@ -527,9 +517,6 @@ int MtpFfsHandle::receiveFile(mtp_file_range mfr) { bool write = false; posix_fadvise(mfr.fd, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE); posix_madvise(data, buf1_len, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED); posix_madvise(data2, buf2_len, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED); ScopedEndpointBufferAlloc scoped_alloc(mBulkOut, mMaxRead); // Break down the file into pieces that fit in buffers while (file_length > 0 || write) { Loading Loading @@ -608,20 +595,11 @@ int MtpFfsHandle::sendFile(mtp_file_range mfr) { } int init_read_len = packet_size - sizeof(mtp_data_header); int buf1_len = std::max(static_cast<uint64_t>(packet_size), std::min( static_cast<uint64_t>(MAX_FILE_CHUNK_SIZE), file_length - init_read_len)); std::vector<char> buf1(buf1_len); char *data = buf1.data(); // If necessary, allocate a second buffer for background r/w int buf2_len = std::min(static_cast<uint64_t>(MAX_FILE_CHUNK_SIZE), file_length - MAX_FILE_CHUNK_SIZE - init_read_len); std::vector<char> buf2(std::max(0, buf2_len)); char *data2 = buf2.data(); char *data = mBuffer1.data(); char *data2 = mBuffer2.data(); posix_fadvise(mfr.fd, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE); posix_madvise(data, buf1_len, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED); posix_madvise(data2, buf2_len, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED); struct aiocb aio; aio.aio_fildes = mfr.fd; Loading @@ -647,8 +625,6 @@ int MtpFfsHandle::sendFile(mtp_file_range mfr) { if (writeHandle(mBulkIn, data, packet_size) == -1) return -1; if (file_length == 0) return 0; ScopedEndpointBufferAlloc scoped_alloc(mBulkIn, mMaxWrite); // Break down the file into pieces that fit in buffers while(file_length > 0) { if (read) { Loading @@ -672,7 +648,7 @@ int MtpFfsHandle::sendFile(mtp_file_range mfr) { } if (file_length > 0) { length = std::min((uint64_t) MAX_FILE_CHUNK_SIZE, file_length); length = std::min(static_cast<uint64_t>(MAX_FILE_CHUNK_SIZE), file_length); // Queue up another read aio.aio_buf = data; aio.aio_offset = offset; Loading media/mtp/MtpFfsHandle.h +3 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,9 @@ private: int mMaxWrite; int mMaxRead; std::vector<char> mBuffer1; std::vector<char> mBuffer2; public: int read(void *data, int len); int write(const void *data, int len); Loading media/mtp/MtpServer.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -179,6 +179,7 @@ void MtpServer::run() { if (sHandle->start()) { ALOGE("Failed to start usb driver!"); sHandle->close(); return; } Loading Loading
media/mtp/MtpFfsHandle.cpp +51 −75 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ #include "AsyncIO.h" #include "MtpFfsHandle.h" #include "mtp.h" #define cpu_to_le16(x) htole16(x) #define cpu_to_le32(x) htole32(x) Loading @@ -58,8 +59,8 @@ constexpr int MAX_FILE_CHUNK_SIZE = 3145728; // To get good performance, override these with // higher values per device using the properties // sys.usb.ffs.max_read and sys.usb.ffs.max_write constexpr int USB_FFS_MAX_WRITE = 32768; constexpr int USB_FFS_MAX_READ = 32768; constexpr int USB_FFS_MAX_WRITE = MTP_BUFFER_SIZE; constexpr int USB_FFS_MAX_READ = MTP_BUFFER_SIZE; constexpr unsigned int MAX_MTP_FILE_SIZE = 0xFFFFFFFF; Loading Loading @@ -344,28 +345,9 @@ bool MtpFfsHandle::initFunctionfs() { if (mBulkIn > -1 || mBulkOut > -1 || mIntr > -1) LOG(WARNING) << "Endpoints were not closed before configure!"; mBulkIn.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_IN, O_RDWR))); if (mBulkIn < 0) { PLOG(ERROR) << FFS_MTP_EP_IN << ": cannot open bulk in ep"; goto err; } mBulkOut.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_OUT, O_RDWR))); if (mBulkOut < 0) { PLOG(ERROR) << FFS_MTP_EP_OUT << ": cannot open bulk out ep"; goto err; } mIntr.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_INTR, O_RDWR))); if (mIntr < 0) { PLOG(ERROR) << FFS_MTP_EP0 << ": cannot open intr ep"; goto err; } return true; err: closeEndpoints(); closeConfig(); return false; } Loading Loading @@ -447,8 +429,50 @@ int MtpFfsHandle::write(const void* data, int len) { int MtpFfsHandle::start() { mLock.lock(); mBulkIn.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_IN, O_RDWR))); if (mBulkIn < 0) { PLOG(ERROR) << FFS_MTP_EP_IN << ": cannot open bulk in ep"; return -1; } mBulkOut.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_OUT, O_RDWR))); if (mBulkOut < 0) { PLOG(ERROR) << FFS_MTP_EP_OUT << ": cannot open bulk out ep"; return -1; } mIntr.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_INTR, O_RDWR))); if (mIntr < 0) { PLOG(ERROR) << FFS_MTP_EP0 << ": cannot open intr ep"; return -1; } mBuffer1.resize(MAX_FILE_CHUNK_SIZE); mBuffer2.resize(MAX_FILE_CHUNK_SIZE); posix_madvise(mBuffer1.data(), MAX_FILE_CHUNK_SIZE, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED); posix_madvise(mBuffer2.data(), MAX_FILE_CHUNK_SIZE, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED); // Get device specific r/w size 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) { // 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))) { mMaxWrite /= 2; mMaxRead /=2; } else { return 0; } } PLOG(ERROR) << "Functionfs could not allocate any memory!"; return -1; } int MtpFfsHandle::configure(bool usePtp) { // Wait till previous server invocation has closed Loading @@ -465,13 +489,6 @@ int MtpFfsHandle::configure(bool usePtp) { return -1; } // Get device specific r/w size mMaxWrite = android::base::GetIntProperty("sys.usb.ffs.max_write", 0); mMaxRead = android::base::GetIntProperty("sys.usb.ffs.max_read", 0); if (!mMaxWrite) mMaxWrite = USB_FFS_MAX_WRITE; if (!mMaxRead) mMaxRead = USB_FFS_MAX_READ; return 0; } Loading @@ -480,26 +497,6 @@ void MtpFfsHandle::close() { mLock.unlock(); } class ScopedEndpointBufferAlloc { private: const int mFd; const unsigned int mAllocSize; public: ScopedEndpointBufferAlloc(int fd, unsigned alloc_size) : mFd(fd), mAllocSize(alloc_size) { if (ioctl(mFd, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(mAllocSize))) PLOG(ERROR) << "FFS endpoint alloc failed!"; } ~ScopedEndpointBufferAlloc() { if (ioctl(mFd, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(0))) PLOG(ERROR) << "FFS endpoint alloc reset failed!"; } DISALLOW_COPY_AND_ASSIGN(ScopedEndpointBufferAlloc); }; /* Read from USB and write to a local file. */ int MtpFfsHandle::receiveFile(mtp_file_range mfr) { // When receiving files, the incoming length is given in 32 bits. Loading @@ -507,15 +504,8 @@ int MtpFfsHandle::receiveFile(mtp_file_range mfr) { uint32_t file_length = mfr.length; uint64_t offset = lseek(mfr.fd, 0, SEEK_CUR); int buf1_len = std::min(static_cast<uint32_t>(MAX_FILE_CHUNK_SIZE), file_length); std::vector<char> buf1(buf1_len); char* data = buf1.data(); // If necessary, allocate a second buffer for background r/w int buf2_len = std::min(static_cast<uint32_t>(MAX_FILE_CHUNK_SIZE), file_length - MAX_FILE_CHUNK_SIZE); std::vector<char> buf2(std::max(0, buf2_len)); char *data2 = buf2.data(); char *data = mBuffer1.data(); char *data2 = mBuffer2.data(); struct aiocb aio; aio.aio_fildes = mfr.fd; Loading @@ -527,9 +517,6 @@ int MtpFfsHandle::receiveFile(mtp_file_range mfr) { bool write = false; posix_fadvise(mfr.fd, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE); posix_madvise(data, buf1_len, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED); posix_madvise(data2, buf2_len, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED); ScopedEndpointBufferAlloc scoped_alloc(mBulkOut, mMaxRead); // Break down the file into pieces that fit in buffers while (file_length > 0 || write) { Loading Loading @@ -608,20 +595,11 @@ int MtpFfsHandle::sendFile(mtp_file_range mfr) { } int init_read_len = packet_size - sizeof(mtp_data_header); int buf1_len = std::max(static_cast<uint64_t>(packet_size), std::min( static_cast<uint64_t>(MAX_FILE_CHUNK_SIZE), file_length - init_read_len)); std::vector<char> buf1(buf1_len); char *data = buf1.data(); // If necessary, allocate a second buffer for background r/w int buf2_len = std::min(static_cast<uint64_t>(MAX_FILE_CHUNK_SIZE), file_length - MAX_FILE_CHUNK_SIZE - init_read_len); std::vector<char> buf2(std::max(0, buf2_len)); char *data2 = buf2.data(); char *data = mBuffer1.data(); char *data2 = mBuffer2.data(); posix_fadvise(mfr.fd, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE); posix_madvise(data, buf1_len, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED); posix_madvise(data2, buf2_len, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED); struct aiocb aio; aio.aio_fildes = mfr.fd; Loading @@ -647,8 +625,6 @@ int MtpFfsHandle::sendFile(mtp_file_range mfr) { if (writeHandle(mBulkIn, data, packet_size) == -1) return -1; if (file_length == 0) return 0; ScopedEndpointBufferAlloc scoped_alloc(mBulkIn, mMaxWrite); // Break down the file into pieces that fit in buffers while(file_length > 0) { if (read) { Loading @@ -672,7 +648,7 @@ int MtpFfsHandle::sendFile(mtp_file_range mfr) { } if (file_length > 0) { length = std::min((uint64_t) MAX_FILE_CHUNK_SIZE, file_length); length = std::min(static_cast<uint64_t>(MAX_FILE_CHUNK_SIZE), file_length); // Queue up another read aio.aio_buf = data; aio.aio_offset = offset; Loading
media/mtp/MtpFfsHandle.h +3 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,9 @@ private: int mMaxWrite; int mMaxRead; std::vector<char> mBuffer1; std::vector<char> mBuffer2; public: int read(void *data, int len); int write(const void *data, int len); Loading
media/mtp/MtpServer.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -179,6 +179,7 @@ void MtpServer::run() { if (sHandle->start()) { ALOGE("Failed to start usb driver!"); sHandle->close(); return; } Loading