* 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:
parent
6e60a6ac03
commit
9951d585b6
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user