#include <libkern/OSDebug.h>
#include <IOKit/IOLib.h>
#include <IOKit/usb/IOUSBCommand.h>
#include <IOKit/usb/IOUSBLog.h>
OSDefineMetaClassAndStructors(IOUSBCommand, IOCommand)
OSDefineMetaClassAndStructors(IOUSBIsocCommand, IOCommand)
#define super IOCommand // same for both
IOUSBCommand*
IOUSBCommand::NewCommand()
{
IOUSBCommand *me = new IOUSBCommand;
if (me && !me->init())
{
me->release();
me = NULL;
}
return me;
}
bool
IOUSBCommand::init()
{
if (!super::init())
return false;
if (!_expansionData)
{
_expansionData = (ExpansionData *)IOMalloc(sizeof(ExpansionData));
if (!_expansionData)
return false;
bzero(_expansionData, sizeof(ExpansionData));
}
return true;
}
void
IOUSBCommand::free()
{
if (_expansionData)
{
IOFree(_expansionData, sizeof(ExpansionData));
_expansionData = NULL;
}
super::free();
}
void
IOUSBCommand::SetSelector(usbCommand sel)
{
_selector = sel;
}
void
IOUSBCommand::SetRequest(IOUSBDeviceRequestPtr req)
{
_request = req;
}
void
IOUSBCommand::SetAddress(USBDeviceAddress addr)
{
_address = addr;
}
void
IOUSBCommand::SetEndpoint(UInt8 ep)
{
_endpoint = ep;
}
void
IOUSBCommand::SetDirection(UInt8 dir)
{
_direction = dir;
}
void
IOUSBCommand::SetType(UInt8 type)
{
_type = type;
}
void
IOUSBCommand::SetBufferRounding(bool br)
{
_bufferRounding = br;
}
void
IOUSBCommand::SetBuffer(IOMemoryDescriptor *buf)
{
_buffer = buf;
}
void
IOUSBCommand::SetUSLCompletion(IOUSBCompletion completion)
{
_uslCompletion = completion;
}
void
IOUSBCommand::SetClientCompletion(IOUSBCompletion completion)
{
_clientCompletion = completion;
}
void
IOUSBCommand::SetDataRemaining(UInt32 dr)
{
if (_expansionData->_masterUSBCommand)
_expansionData->_masterUSBCommand->_dataRemaining = dr;
else
_dataRemaining = dr;
}
void
IOUSBCommand::SetStage(UInt8 stage)
{
if (_expansionData->_masterUSBCommand)
_expansionData->_masterUSBCommand->_stage = stage;
else
_stage = stage;
}
void
IOUSBCommand::SetStatus(IOReturn stat)
{
if (_expansionData->_masterUSBCommand)
_expansionData->_masterUSBCommand->_status = stat;
else
_status = stat;
}
void
IOUSBCommand::SetOrigBuffer(IOMemoryDescriptor *buf)
{
_origBuffer = buf;
}
void
IOUSBCommand::SetDisjointCompletion(IOUSBCompletion completion)
{
_disjointCompletion = completion;
}
void
IOUSBCommand::SetDblBufLength(IOByteCount len)
{
_dblBufLength = len;
}
void
IOUSBCommand::SetNoDataTimeout(UInt32 to)
{
_noDataTimeout = to;
}
void
IOUSBCommand::SetCompletionTimeout(UInt32 to)
{
_completionTimeout = to;
}
void
IOUSBCommand::SetUIMScratch(UInt32 index, UInt32 value)
{
if (index < 10)
if (_expansionData->_masterUSBCommand)
_expansionData->_masterUSBCommand->_UIMScratch[index] = value;
else
_UIMScratch[index] = value;
}
void
IOUSBCommand::SetReqCount(IOByteCount reqCount)
{
_expansionData->_reqCount = reqCount;
}
void
IOUSBCommand::SetRequestMemoryDescriptor(IOMemoryDescriptor *requestMemoryDescriptor)
{
_expansionData->_requestMemoryDescriptor = requestMemoryDescriptor;
}
void
IOUSBCommand::SetBufferMemoryDescriptor(IOMemoryDescriptor *bufferMemoryDescriptor)
{
_expansionData->_bufferMemoryDescriptor = bufferMemoryDescriptor;
}
void
IOUSBCommand::SetMultiTransferTransaction(bool multiTDTransaction)
{
_expansionData->_multiTransferTransaction = multiTDTransaction;
}
void
IOUSBCommand::SetFinalTransferInTransaction(bool finalTDinTransaction)
{
_expansionData->_finalTransferInTransaction = finalTDinTransaction;
}
void
IOUSBCommand::SetUseTimeStamp(bool useTimeStamp)
{
_expansionData->_useTimeStamp = useTimeStamp;
}
void
IOUSBCommand::SetTimeStamp(AbsoluteTime timeStamp)
{
_expansionData->_timeStamp = timeStamp;
}
void
IOUSBCommand::SetIsSyncTransfer(bool isSync)
{
_expansionData->_isSyncTransfer = isSync;
}
void
IOUSBCommand::SetBufferUSBCommand(IOUSBCommand *bufferUSBCommand)
{
if (!bufferUSBCommand && (_expansionData->_bufferUSBCommand))
_expansionData->_bufferUSBCommand->_expansionData->_masterUSBCommand = NULL;
_expansionData->_bufferUSBCommand = bufferUSBCommand;
if (bufferUSBCommand)
bufferUSBCommand->_expansionData->_masterUSBCommand = this;
}
usbCommand
IOUSBCommand::GetSelector(void)
{
return _selector;
}
IOUSBDeviceRequestPtr
IOUSBCommand::GetRequest(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_request : _request;
}
USBDeviceAddress
IOUSBCommand::GetAddress(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_address : _address;
}
UInt8
IOUSBCommand::GetEndpoint(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_endpoint : _endpoint;
}
UInt8
IOUSBCommand::GetDirection(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_direction : _direction;
}
UInt8
IOUSBCommand::GetType(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_type : _type;
}
bool
IOUSBCommand::GetBufferRounding(void)
{
return _bufferRounding;
}
IOMemoryDescriptor*
IOUSBCommand::GetBuffer(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_buffer : _buffer;
}
IOUSBCompletion
IOUSBCommand::GetUSLCompletion(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_uslCompletion : _uslCompletion;
}
IOUSBCompletion
IOUSBCommand::GetClientCompletion(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_clientCompletion : _clientCompletion;
}
UInt32
IOUSBCommand::GetDataRemaining(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_dataRemaining : _dataRemaining;
}
UInt8
IOUSBCommand::GetStage(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_stage : _stage;
}
IOReturn
IOUSBCommand::GetStatus(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_status : _status;
}
IOMemoryDescriptor *
IOUSBCommand::GetOrigBuffer(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_origBuffer : _origBuffer;
}
IOUSBCompletion
IOUSBCommand::GetDisjointCompletion(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_disjointCompletion : _disjointCompletion;
}
IOByteCount
IOUSBCommand::GetDblBufLength(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_dblBufLength : _dblBufLength;
}
UInt32
IOUSBCommand::GetNoDataTimeout(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_noDataTimeout : _noDataTimeout;
}
UInt32
IOUSBCommand::GetCompletionTimeout(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_completionTimeout : _completionTimeout;
}
UInt32 IOUSBCommand::GetUIMScratch(UInt32 index)
{
if (index < 10)
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_UIMScratch[index] : _UIMScratch[index];
else
return 0;
}
IOByteCount
IOUSBCommand::GetReqCount(void)
{
return _expansionData->_reqCount;
}
IOMemoryDescriptor*
IOUSBCommand::GetRequestMemoryDescriptor(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_expansionData->_requestMemoryDescriptor : _expansionData->_requestMemoryDescriptor;
}
IOMemoryDescriptor*
IOUSBCommand::GetBufferMemoryDescriptor(void)
{
return _expansionData->_bufferMemoryDescriptor;
}
bool
IOUSBCommand::GetMultiTransferTransaction(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_expansionData->_multiTransferTransaction : _expansionData->_multiTransferTransaction;
}
bool
IOUSBCommand::GetFinalTransferInTransaction(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_expansionData->_finalTransferInTransaction : _expansionData->_finalTransferInTransaction;
}
bool
IOUSBCommand::GetUseTimeStamp(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_expansionData->_useTimeStamp : _expansionData->_useTimeStamp;
}
AbsoluteTime
IOUSBCommand::GetTimeStamp(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_expansionData->_timeStamp : _expansionData->_timeStamp;
}
bool
IOUSBCommand::GetIsSyncTransfer(void)
{
return _expansionData->_masterUSBCommand ? _expansionData->_masterUSBCommand->_expansionData->_isSyncTransfer : _expansionData->_isSyncTransfer;
}
IOUSBIsocCommand*
IOUSBIsocCommand::NewCommand()
{
IOUSBIsocCommand *me = new IOUSBIsocCommand;
if (me && !me->init())
{
me->release();
me = NULL;
}
return me;
}
bool
IOUSBIsocCommand::init()
{
if (!super::init())
return false;
if (!_expansionData)
{
_expansionData = (ExpansionData *)IOMalloc(sizeof(ExpansionData));
if (!_expansionData)
return false;
bzero(_expansionData, sizeof(ExpansionData));
}
return true;
}
void
IOUSBIsocCommand::free()
{
if (_expansionData)
{
IOFree(_expansionData, sizeof(ExpansionData));
_expansionData = NULL;
}
super::free();
}
OSDefineMetaClassAndStructors(IOUSBCommandPool, IOCommandPool);
IOCommandPool *
IOUSBCommandPool::withWorkLoop(IOWorkLoop * inWorkLoop)
{
IOCommandPool * me = new IOUSBCommandPool;
if (me && !me->initWithWorkLoop(inWorkLoop)) {
me->release();
return 0;
}
return me;
}
IOReturn
IOUSBCommandPool::gatedGetCommand(IOCommand ** command, bool blockForCommand)
{
IOReturn ret;
ret = IOCommandPool::gatedGetCommand(command, blockForCommand);
return ret;
}
IOReturn
IOUSBCommandPool::gatedReturnCommand(IOCommand * command)
{
USBLog(7,"IOUSBCommandPool[%p]::gatedReturnCommand %p", this, command);
if (!command)
{
#if DEBUG_LEVEL != DEBUG_LEVEL_PRODUCTION
panic("IOUSBCommandPool::gatedReturnCommand( NULL )");
#else
return kIOReturnBadArgument;
#endif
}
if (command->fCommandChain.next &&
(&command->fCommandChain != command->fCommandChain.next ||
&command->fCommandChain != command->fCommandChain.prev))
{
#if DEBUG_LEVEL != DEBUG_LEVEL_PRODUCTION
kprintf("WARNING: gatedReturnCommand(%p) already on queue [next=%p prev=%p]\n",
command, command->fCommandChain.next, command->fCommandChain.prev);
panic("IOUSBCommandPool::gatedReturnCommand already on queue");
#else
char* bt[8];
OSBacktrace((void**)bt, 8);
USBError(1,"IOUSBCommandPool[%p]::gatedReturnCommand command already in queue, not putting it back into the queue, bt: [%p][%p][%p][%p][%p][%p][%p][%p]", this, bt[0], bt[1], bt[2], bt[3], bt[4], bt[5], bt[6], bt[7]);
return kIOReturnBadArgument;
#endif
}
return IOCommandPool::gatedReturnCommand(command);
}