* 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
This commit is contained in:
Ingo Weinhold 2008-07-24 04:11:03 +00:00
parent 6e60a6ac03
commit 9951d585b6
3 changed files with 28 additions and 20 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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<IORequest> {
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;