From 9951d585b6e7275de6f8b86967ea16527770c97c Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 24 Jul 2008 04:11:03 +0000 Subject: [PATCH] * We have to use get_memory_map_etc() instead of get_memory_map(), since the scheduler thread doing that has no direct access to the destination team's address space. * Improved some debug output. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26601 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/device_manager/dma_resources.cpp | 10 ++++--- .../kernel/device_manager/io_requests.cpp | 28 +++++++++++-------- .../kernel/device_manager/io_requests.h | 10 ++++--- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/system/kernel/device_manager/dma_resources.cpp b/src/system/kernel/device_manager/dma_resources.cpp index ef84eec97b..518bedb6d1 100644 --- a/src/system/kernel/device_manager/dma_resources.cpp +++ b/src/system/kernel/device_manager/dma_resources.cpp @@ -331,14 +331,14 @@ DMAResource::TranslateNext(IORequest* request, IOOperation* operation) uint32 segmentCount = 0; size_t partialBegin = offset & (fBlockSize - 1); - TRACE(" offset %Ld, block size %lu -> partial: %lu\n", offset, fBlockSize, - partialBegin); + TRACE(" offset %Ld, remaining size: %lu, block size %lu -> partial: %lu\n", + offset, request->RemainingBytes(), fBlockSize, partialBegin); if (buffer->IsVirtual()) { // Unless we need the bounce buffer anyway, we have to translate the // virtual addresses to physical addresses, so we can check the DMA // restrictions. - TRACE(" buffer is virtual\n"); + TRACE(" buffer is virtual %s\n", buffer->IsUser() ? "user" : "kernel"); // TODO: !partialOperation || totalLength >= fBlockSize // TODO: Maybe enforce fBounceBufferSize >= 2 * fBlockSize. if (true) { @@ -357,7 +357,9 @@ DMAResource::TranslateNext(IORequest* request, IOOperation* operation) while (size > 0 && segmentCount < fRestrictions.max_segment_count) { physical_entry entry; - get_memory_map((void*)base, size, &entry, 1); + uint32 count = 1; + get_memory_map_etc(request->Team(), (void*)base, size, + &entry, &count); vecs[segmentCount].iov_base = entry.address; vecs[segmentCount].iov_len = entry.size; diff --git a/src/system/kernel/device_manager/io_requests.cpp b/src/system/kernel/device_manager/io_requests.cpp index b7952f647c..299864c86b 100644 --- a/src/system/kernel/device_manager/io_requests.cpp +++ b/src/system/kernel/device_manager/io_requests.cpp @@ -681,7 +681,7 @@ IORequest::_CopyData(void* _buffer, off_t offset, size_t size, bool copyIn) // If we can, we directly copy from/to the virtual buffer. The memory is // locked in this case. - status_t (*copyFunction)(void*, void*, size_t, bool); + status_t (*copyFunction)(void*, void*, size_t, team_id, bool); if (fBuffer->IsPhysical()) { copyFunction = &IORequest::_CopyPhysical; } else { @@ -707,7 +707,7 @@ IORequest::_CopyData(void* _buffer, off_t offset, size_t size, bool copyIn) while (size > 0) { size_t toCopy = min_c(size, vecs[0].iov_len - vecOffset); status_t error = copyFunction(buffer, - (uint8*)vecs[0].iov_base + vecOffset, toCopy, copyIn); + (uint8*)vecs[0].iov_base + vecOffset, toCopy, fTeam, copyIn); if (error != B_OK) return error; @@ -723,7 +723,7 @@ IORequest::_CopyData(void* _buffer, off_t offset, size_t size, bool copyIn) /* static */ status_t IORequest::_CopySimple(void* bounceBuffer, void* external, size_t size, - bool copyIn) + team_id team, bool copyIn) { TRACE(" IORequest::_CopySimple(%p, %p, %lu, %d)\n", bounceBuffer, external, size, copyIn); @@ -737,7 +737,7 @@ IORequest::_CopySimple(void* bounceBuffer, void* external, size_t size, /* static */ status_t IORequest::_CopyPhysical(void* _bounceBuffer, void* _external, size_t size, - bool copyIn) + team_id team, bool copyIn) { uint8* bounceBuffer = (uint8*)_bounceBuffer; addr_t external = (addr_t)_external; @@ -749,7 +749,7 @@ IORequest::_CopyPhysical(void* _bounceBuffer, void* _external, size_t size, return error; size_t toCopy = min_c(size, B_PAGE_SIZE); - _CopySimple(bounceBuffer, (void*)virtualAddress, toCopy, copyIn); + _CopySimple(bounceBuffer, (void*)virtualAddress, toCopy, team, copyIn); vm_put_physical_page(virtualAddress); @@ -764,24 +764,28 @@ IORequest::_CopyPhysical(void* _bounceBuffer, void* _external, size_t size, /* static */ status_t IORequest::_CopyUser(void* _bounceBuffer, void* _external, size_t size, - bool copyIn) + team_id team, bool copyIn) { uint8* bounceBuffer = (uint8*)_bounceBuffer; uint8* external = (uint8*)_external; while (size > 0) { - physical_entry entries[8]; - int32 count = get_memory_map(external, size, entries, 8); - if (count <= 0) { + static const int32 kEntryCount = 8; + physical_entry entries[kEntryCount]; + + uint32 count = kEntryCount; + status_t error = get_memory_map_etc(team, external, size, entries, + &count); + if (error != B_OK && error != B_BUFFER_OVERFLOW) { panic("IORequest::_CopyUser(): Failed to get physical memory for " "user memory %p\n", external); return B_BAD_ADDRESS; } - for (int32 i = 0; i < count; i++) { + for (uint32 i = 0; i < count; i++) { const physical_entry& entry = entries[i]; - status_t error = _CopyPhysical(bounceBuffer, entry.address, - entry.size, copyIn); + error = _CopyPhysical(bounceBuffer, entry.address, + entry.size, team, copyIn); if (error != B_OK) return error; diff --git a/src/system/kernel/device_manager/io_requests.h b/src/system/kernel/device_manager/io_requests.h index fb46611844..b12968aee4 100644 --- a/src/system/kernel/device_manager/io_requests.h +++ b/src/system/kernel/device_manager/io_requests.h @@ -31,7 +31,7 @@ public: bool IsVirtual() const { return !fPhysical; } bool IsPhysical() const { return fPhysical; } - bool IsUser() const { return !fUser; } + bool IsUser() const { return fUser; } void SetVecs(const iovec* vecs, uint32 count, size_t length, uint32 flags); @@ -193,6 +193,7 @@ struct IORequest : IORequestChunk, DoublyLinkedListLinkImpl { bool IsWrite() const { return fIsWrite; } bool IsRead() const { return !fIsWrite; } + team_id Team() const { return fTeam; } IOBuffer* Buffer() const { return fBuffer; } off_t Offset() const { return fOffset; } @@ -215,11 +216,12 @@ private: status_t _CopyData(void* buffer, off_t offset, size_t size, bool copyIn); static status_t _CopySimple(void* bounceBuffer, void* external, - size_t size, bool copyIn); + size_t size, team_id team, bool copyIn); static status_t _CopyPhysical(void* bounceBuffer, - void* external, size_t size, bool copyIn); + void* external, size_t size, team_id team, + bool copyIn); static status_t _CopyUser(void* bounceBuffer, void* external, - size_t size, bool copyIn); + size_t size, team_id team, bool copyIn); mutex fLock; IOBuffer* fBuffer;