AppleUSBXHCI_AsyncQueues.h [plain text]
#ifndef AppleUSBXHCI_AppleUSBXHCI_AsyncQueues_h
#define AppleUSBXHCI_AppleUSBXHCI_AsyncQueues_h
#include <libkern/c++/OSMetaClass.h>
#include <libkern/c++/OSObject.h>
#include <IOKit/usb/IOUSBCommand.h>
#include <IOKit/usb/IOUSBControllerListElement.h>
#include <IOKit/IODMACommand.h>
#include "XHCI.h"
#include "AppleUSBXHCIUIM.h"
class AppleXHCIAsyncEndpoint;
class AppleUSBXHCI;
#define kFreeTDs 1
#define kAsyncMaxFragmentSize PAGE_SIZE*32 // 4K * 32 = 128K this is > the max value for TRB length field
#define kMaxFreeSpaceInRing 2 // Space for 2 more TDs with multiple of maxTRBs from queued TDs.
#define kAccountForAlignment 2 // For Event DATA trb & unaligned buffer
#define kMinimumTDs 1
class AppleXHCIAsyncTransferDescriptor : public OSObject
{
OSDeclareDefaultStructors(AppleXHCIAsyncTransferDescriptor)
public:
virtual bool init();
virtual void free(void);
void print(int level);
void reinit();
IOUSBCommand *activeCommand; UInt32 transferSize; UInt32 remAfterThisTD; IOByteCount startOffset; UInt32 trbIndex; UInt32 trbCount; bool interruptThisTD; bool fragmentedTD; UInt16 totalTDs; UInt32 offCOverride;
UInt32 shortfall;
UInt16 maxTRBs; bool immediateTransfer;
bool last;
UInt8 immediateBuffer[kMaxImmediateTRBTransferSize];
UInt16 streamID;
SInt16 completionIndex;
bool flushed;
bool lastFlushedTD;
bool lastInRing;
AppleXHCIAsyncEndpoint *_endpoint;
AppleXHCIAsyncTransferDescriptor *_logicalNext;
static AppleXHCIAsyncTransferDescriptor *ForEndpoint(AppleXHCIAsyncEndpoint *endpoint);
};
class AppleXHCIAsyncEndpoint : public OSObject
{
friend class AppleUSBXHCI;
OSDeclareDefaultStructors(AppleXHCIAsyncEndpoint)
protected:
virtual bool init(AppleUSBXHCI *controller, struct ringStruct *ring, UInt16 maxPacketSize, UInt16 maxBurst, UInt16 mult);
public:
virtual bool init();
virtual void free(void);
void validateLists(int level);
void print(int level);
struct ringStruct *_ring;
AppleXHCIAsyncTransferDescriptor *readyQueue; AppleXHCIAsyncTransferDescriptor *readyEnd;
AppleXHCIAsyncTransferDescriptor *activeQueue; AppleXHCIAsyncTransferDescriptor *activeEnd;
AppleXHCIAsyncTransferDescriptor *doneQueue; AppleXHCIAsyncTransferDescriptor *doneEnd;
AppleXHCIAsyncTransferDescriptor *freeQueue; AppleXHCIAsyncTransferDescriptor *freeEnd;
UInt32 onReadyQueue;
UInt32 onActiveQueue;
UInt32 onDoneQueue;
UInt32 onFreeQueue;
bool _aborting;
UInt32 _maxPacketSize;
UInt32 _maxBurst;
UInt32 _mult;
UInt32 _actualFragmentSize;
AppleUSBXHCI *_xhciUIM;
void PutTDAtHead(AppleXHCIAsyncTransferDescriptor **qStart, AppleXHCIAsyncTransferDescriptor **qEnd, AppleXHCIAsyncTransferDescriptor *pTD, UInt32 *qCount);
void PutTD(AppleXHCIAsyncTransferDescriptor **qStart, AppleXHCIAsyncTransferDescriptor **qEnd, AppleXHCIAsyncTransferDescriptor *pTD, UInt32 *qCount);
AppleXHCIAsyncTransferDescriptor *GetTD(AppleXHCIAsyncTransferDescriptor **qStart, AppleXHCIAsyncTransferDescriptor **qEnd, UInt32 *qCount);
void PutTDonFreeQueue(AppleXHCIAsyncTransferDescriptor *pTD);
AppleXHCIAsyncTransferDescriptor *GetTDFromFreeQueue(bool allocate = true);
void PutTDonReadyQueueAtHead(AppleXHCIAsyncTransferDescriptor *pTD);
void PutTDonReadyQueue(AppleXHCIAsyncTransferDescriptor *pTD);
AppleXHCIAsyncTransferDescriptor *GetTDFromReadyQueue();
void PutTDonDoneQueue(AppleXHCIAsyncTransferDescriptor *pTD);
AppleXHCIAsyncTransferDescriptor *GetTDFromDoneQueue();
void PutTDonActiveQueue(AppleXHCIAsyncTransferDescriptor *pTD);
AppleXHCIAsyncTransferDescriptor *GetTDFromActiveQueue();
AppleXHCIAsyncTransferDescriptor *GetTDFromActiveQueueWithIndex(UInt16 trbIndex);
void MoveTDsFromReadyQToDoneQ(IOUSBCommand *pUSBCommand = NULL);
void MoveAllTDsFromReadyQToDoneQ();
void MoveAllTDsFromActiveQToDoneQ();
IOReturn CreateTDs(IOUSBCommand *pUSBCommand, UInt16 streamID = 0, UInt32 offsC = 0, UInt8 immediateTransferSize = kInvalidImmediateTRBTransferSize, UInt8 *immediateBuffer = NULL);
void ScheduleTDs();
void ScavengeTDs(AppleXHCIAsyncTransferDescriptor *pActiveTD, IOReturn status, bool complete, bool flush);
void FlushTDs(IOUSBCommand *pUSBCommand);
void FlushTDsWithStatus(IOUSBCommand *pUSBCommand, IOReturn status);
void Complete(IOReturn status);
IOReturn Abort();
void UpdateTimeouts(bool abortAll, UInt32 curFrame, bool stopped);
bool NeedTimeouts();
};
#endif