/* * Copyright (c) 1998-2002 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include #include #include enum { kSizeToIncrementLowLatencyCommandPool = 10 }; struct AsyncPB { OSAsyncReference fAsyncRef; UInt32 fMax; IOMemoryDescriptor *fMem; IOUSBDevRequestDesc req; }; struct IsoAsyncPB { OSAsyncReference fAsyncRef; int frameLen; // In bytes void * frameBase; // In user task IOMemoryDescriptor *dataMem; IOMemoryDescriptor *countMem; IOUSBIsocFrame frames[0]; }; typedef struct LowLatencyUserClientBufferInfo LowLatencyUserClientBufferInfo; struct LowLatencyUserClientBufferInfo { UInt32 cookie; UInt32 bufferType; void * bufferAddress; UInt32 bufferSize; IOMemoryDescriptor * bufferDescriptor; IOMemoryDescriptor * frameListDescriptor; IOMemoryMap * frameListMap; IOVirtualAddress frameListKernelAddress; LowLatencyUserClientBufferInfo * nextBuffer; }; class IOUSBLowLatencyCommand : public IOCommand { OSDeclareAbstractStructors(IOUSBLowLatencyCommand) private: OSAsyncReference fAsyncRef; IOByteCount fFrameLength; // In bytes void * fFrameBase; // In user task IOMemoryDescriptor * fDataBufferDescriptor; public: // static constructor static IOUSBLowLatencyCommand * NewCommand(void); // accessor methods // void SetAsyncReference(OSAsyncReference ref); void SetFrameLength(IOByteCount frameLength) { fFrameLength = frameLength; } void SetFrameBase(void * frameBase) { fFrameBase = frameBase; } void SetDataBuffer(IOMemoryDescriptor * dataMem) {fDataBufferDescriptor = dataMem; } void GetAsyncReference(OSAsyncReference *ref) { *ref = fAsyncRef; } IOByteCount GetFrameLength(void) { return fFrameLength; } void * GetFrameBase(void){ return fFrameBase; } IOMemoryDescriptor * GetDataBuffer(void){ return fDataBufferDescriptor; } }; class IOUSBInterfaceUserClient : public IOUserClient { OSDeclareDefaultStructors(IOUSBInterfaceUserClient) private: IOUSBInterface * fOwner; task_t fTask; const IOExternalMethod *fMethods; const IOExternalAsyncMethod *fAsyncMethods; IOCommandGate *fGate; UInt32 fNumMethods; UInt32 fNumAsyncMethods; UInt32 fOutstandingIO; mach_port_t fWakePort; bool fDead; bool fNeedToClose; IOCommandPool * fFreeUSBLowLatencyCommandPool; UInt32 fCurrentSizeOfCommandPool; IOWorkLoop * fWorkLoop; LowLatencyUserClientBufferInfo * fUserClientBufferInfoListHead; static const IOExternalMethod sMethods[kNumUSBInterfaceMethods]; static const IOExternalAsyncMethod sAsyncMethods[kNumUSBInterfaceAsyncMethods]; // my protected methods virtual void SetExternalMethodVectors(void); void IncreaseCommandPool(); // IOKit methods virtual void stop(IOService * provider); virtual bool start( IOService * provider ); virtual bool finalize(IOOptionBits options); virtual void free(); // "new" IOService methods virtual bool willTerminate( IOService * provider, IOOptionBits options ); virtual bool didTerminate( IOService * provider, IOOptionBits options, bool * defer ); // pseudo IOKit methods - these methods are NOT the IOService:: methods, since both IOService::open // and IOService::close require an IOService* as the first parameter virtual IOReturn open(bool seize); virtual IOReturn close(void); // IOUserClient methods virtual bool initWithTask(task_t owningTask, void *security_id, UInt32 type); virtual IOExternalMethod* getTargetAndMethodForIndex(IOService **target, UInt32 index); virtual IOExternalAsyncMethod* getAsyncTargetAndMethodForIndex(IOService **target, UInt32 index); virtual IOReturn clientClose( void ); virtual IOReturn clientDied( void ); // misc methods virtual IOUSBPipe* GetPipeObj(UInt8 pipeNo); // worker method for Isoch stuff virtual IOReturn DoIsochPipeAsync(OSAsyncReference asyncRef, IOUSBIsocStruct *stuff, IODirection direction); virtual IOReturn DoLowLatencyIsochPipeAsync(OSAsyncReference asyncRef, IOUSBLowLatencyIsocStruct *stuff, IODirection direction); // IOUSBInterface methods virtual IOReturn GetDevice(io_service_t *device); virtual IOReturn SetAlternateInterface(UInt8 altInterface); virtual IOReturn GetFrameNumber(IOUSBGetFrameStruct *data, UInt32 *size); virtual IOReturn GetMicroFrameNumber(IOUSBGetFrameStruct *data, UInt32 *size); virtual IOReturn GetBandwidthAvailable(UInt32 *bandwidth); virtual IOReturn GetFrameListTime(UInt32 *microsecondsInFrame); virtual IOReturn GetEndpointProperties(UInt8 alternateSetting, UInt8 endpointNumber, UInt8 direction, UInt32 *transferType, UInt32 *maxPacketSize, UInt32 *interval); // working with pipes virtual IOReturn GetPipeProperties(UInt8 pipeRef, UInt32 *direction, UInt32 *number, UInt32 *transferType, UInt32 *maxPacketSize, UInt32 *interval); virtual IOReturn ReadPipe(UInt8 pipeRef, UInt32 noDataTimeout, UInt32 completionTimeout, void *buf, UInt32 *size); virtual IOReturn ReadPipeOOL(IOUSBBulkPipeReq *reqIn, UInt32 *sizeOut, IOByteCount inCount, IOByteCount *outCount); virtual IOReturn WritePipe(UInt8 pipeRef, UInt32 noDataTimeout, UInt32 completionTimeout, void *buf, UInt32 size); virtual IOReturn WritePipeOOL(IOUSBBulkPipeReq *req, IOByteCount inCount); virtual IOReturn GetPipeStatus(UInt8 pipeRef); virtual IOReturn AbortPipe(UInt8 pipeRef); virtual IOReturn ResetPipe(UInt8 pipeRef); virtual IOReturn SetPipeIdle(UInt8 pipeRef); virtual IOReturn SetPipeActive(UInt8 pipeRef); virtual IOReturn ClearPipeStall(UInt8 pipeRef, bool bothEnds); virtual IOReturn SetPipePolicy(UInt8 pipeRef, UInt16 maxPacketSize, UInt8 maxInterval); virtual IOReturn ControlRequestIn(UInt32 param1, UInt32 param2, UInt32 noDataTimeout, UInt32 completionTimeout, void *buf, UInt32 *size); virtual IOReturn ControlRequestOut(UInt32 param1, UInt32 param2, UInt32 noDataTimeout, UInt32 completionTimeout, void *buf, UInt32 size); virtual IOReturn ControlRequestInOOL(IOUSBDevReqOOLTO *req, UInt32 *sizeOut, IOByteCount inCount, IOByteCount *outCount); virtual IOReturn ControlRequestOutOOL(IOUSBDevReqOOLTO *req, IOByteCount inCount); // async methods virtual IOReturn SetAsyncPort(OSAsyncReference asyncRef); virtual IOReturn ControlAsyncRequestOut(OSAsyncReference asyncRef, IOUSBDevReqOOLTO *reqIn, IOByteCount inCount); virtual IOReturn ControlAsyncRequestIn(OSAsyncReference asyncRef, IOUSBDevReqOOLTO *reqIn, IOByteCount inCount); virtual IOReturn AsyncReadPipe(OSAsyncReference asyncRef, UInt32 pipe, void *buf, UInt32 size, UInt32 noDataTimeout, UInt32 completionTimeout); virtual IOReturn AsyncWritePipe(OSAsyncReference asyncRef, UInt32 pipe, void *buf, UInt32 size, UInt32 noDataTimeout, UInt32 completionTimeout); virtual IOReturn ReadIsochPipe(OSAsyncReference asyncRef, IOUSBIsocStruct *stuff, UInt32 sizeIn); virtual IOReturn WriteIsochPipe(OSAsyncReference asyncRef, IOUSBIsocStruct *stuff, UInt32 sizeIn); virtual IOReturn LowLatencyReadIsochPipe(OSAsyncReference asyncRef, IOUSBLowLatencyIsocStruct *stuff, UInt32 sizeIn); virtual IOReturn LowLatencyWriteIsochPipe(OSAsyncReference asyncRef, IOUSBLowLatencyIsocStruct *stuff, UInt32 sizeIn); // bookkeeping methods void DecrementOutstandingIO(void); void IncrementOutstandingIO(void); UInt32 GetOutstandingIO(void); // Low Latency Buffer methods // virtual IOReturn LowLatencyPrepareBuffer(LowLatencyUserBufferInfo *dataBuffer); virtual IOReturn LowLatencyReleaseBuffer(LowLatencyUserBufferInfo *dataBuffer); virtual void AddDataBufferToList( LowLatencyUserClientBufferInfo * insertBuffer ); virtual LowLatencyUserClientBufferInfo * FindBufferCookieInList( UInt32 cookie); virtual bool RemoveDataBufferFromList( LowLatencyUserClientBufferInfo *removeBuffer); virtual void ReleasePreparedDescriptors(); // static methods static void ReqComplete(void *obj, void *param, IOReturn status, UInt32 remaining); static void IsoReqComplete(void *obj, void *param, IOReturn res, IOUSBIsocFrame *pFrames); static void LowLatencyIsoReqComplete(void *obj, void *param, IOReturn res, IOUSBLowLatencyIsocFrame *pFrames); static IOReturn ChangeOutstandingIO(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3); static IOReturn GetGatedOutstandingIO(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3); };