AppleUHCIqhMemoryBlock.cpp [plain text]
#include <IOKit/IOBufferMemoryDescriptor.h>
#include <IOKit/usb/IOUSBLog.h>
#include "AppleUSBUHCI.h"
#include "UHCI.h"
#include "AppleUHCIqhMemoryBlock.h"
#define super OSObject
OSDefineMetaClassAndStructors(AppleUHCIqhMemoryBlock, OSObject);
AppleUHCIqhMemoryBlock*
AppleUHCIqhMemoryBlock::NewMemoryBlock(void)
{
AppleUHCIqhMemoryBlock *me = new AppleUHCIqhMemoryBlock;
IOByteCount len;
IODMACommand *dmaCommand = NULL;
UInt64 offset = 0;
IODMACommand::Segment32 segments;
UInt32 numSegments = 1;
IOReturn status = kIOReturnSuccess;
if (me)
{
dmaCommand = IODMACommand::withSpecification(kIODMACommandOutputHost32, 32, PAGE_SIZE, (IODMACommand::MappingOptions)(IODMACommand::kMapped | IODMACommand::kIterateOnly));
if (!dmaCommand)
{
USBError(1, "AppleUHCIqhMemoryBlock::NewMemoryBlock - could not create IODMACommand");
return NULL;
}
USBLog(6, "AppleUHCIqhMemoryBlock::NewMemoryBlock - got IODMACommand %p", dmaCommand);
me->_buffer = IOBufferMemoryDescriptor::inTaskWithPhysicalMask(kernel_task, kIOMemoryUnshared | kIODirectionInOut, kUHCIPageSize, kUHCIStructureAllocationPhysicalMask);
if (me->_buffer)
{
status = me->_buffer->prepare();
if (status)
{
USBError(1, "AppleUHCIqhMemoryBlock::NewMemoryBlock - could not prepare buffer");
me->_buffer->release();
me->release();
dmaCommand->release();
return NULL;
}
me->_sharedLogical = (UHCIQueueHeadSharedPtr)me->_buffer->getBytesNoCopy();
bzero(me->_sharedLogical, kUHCIPageSize);
status = dmaCommand->setMemoryDescriptor(me->_buffer);
if (status)
{
USBError(1, "AppleUHCIqhMemoryBlock::NewMemoryBlock - could not set memory descriptor");
me->_buffer->complete();
me->_buffer->release();
me->release();
dmaCommand->release();
return NULL;
}
status = dmaCommand->gen32IOVMSegments(&offset, &segments, &numSegments);
dmaCommand->clearMemoryDescriptor();
dmaCommand->release();
if (status || (numSegments != 1) || (segments.fLength != kUHCIPageSize))
{
USBError(1, "AppleUHCIqhMemoryBlock::NewMemoryBlock - could not get physical segment");
me->_buffer->complete();
me->_buffer->release();
me->release();
return NULL;
}
me->_sharedPhysical = segments.fIOVMAddr;
}
else
{
USBError(1, "AppleUHCIqhMemoryBlock::NewMemoryBlock, could not allocate buffer!");
me->release();
me = NULL;
}
}
else
{
USBError(1, "AppleUHCIqhMemoryBlock::NewMemoryBlock, constructor failed!");
}
return me;
}
UInt32
AppleUHCIqhMemoryBlock::NumQHs(void)
{
return QHsPerBlock;
}
IOPhysicalAddress
AppleUHCIqhMemoryBlock::GetPhysicalPtr(UInt32 index)
{
IOPhysicalAddress ret = NULL;
if (index < QHsPerBlock)
ret = _sharedPhysical + (index * sizeof(UHCIQueueHeadShared));
return ret;
}
UHCIQueueHeadSharedPtr
AppleUHCIqhMemoryBlock::GetLogicalPtr(UInt32 index)
{
UHCIQueueHeadSharedPtr ret = NULL;
if (index < QHsPerBlock)
ret = &_sharedLogical[index];
return ret;
}
AppleUHCIqhMemoryBlock*
AppleUHCIqhMemoryBlock::GetNextBlock(void)
{
return _nextBlock;
}
void
AppleUHCIqhMemoryBlock::SetNextBlock(AppleUHCIqhMemoryBlock* next)
{
_nextBlock = next;
}