1/* 2 * Copyright (c) 1998-2002 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include <IOKit/IOKitLib.h> 25#include <IOKit/firewire/IOFireWireLib.h> 26#include <IOKit/avc/IOFireWireAVCLib.h> 27 28// Turn on logging of when events happen, and log dump when something takes too long 29//#define TIMING 1 30 31//#define kIDH_Verbose_Debug_Logging 1 32 33#define kDVMaxDevicesActive 64 // max devices on firewire bus 34#define kDVMaxStreamsActive 64 // max isoc channels on fw bus 35 36#define kLogSize 20 37typedef struct _Log { 38 UInt32 tag; 39 CFAbsoluteTime start; 40 CFAbsoluteTime end; 41} Log; 42 43 44// pthread stuff 45typedef struct _syncStruct 46{ 47 pthread_mutex_t fMutex; // lock this before updating globals 48 pthread_cond_t fSyncCond; // To synchronize threads. 49} ThreadSyncer; 50 51typedef struct _DVThread DVThread; 52struct DVGlobalOutStruct; 53typedef struct DVGlobalOutStruct DVGlobalOut, *DVGlobalOutPtr; 54 55struct DVGlobalInStruct; 56typedef struct DVGlobalInStruct DVGlobalIn, *DVGlobalInPtr; 57 58// device structure 59typedef struct _DVDevice 60{ 61 DVThread *fThread; 62 io_object_t fObject; 63 IOFireWireLibDeviceRef fDevInterface; 64 IOFireWireAVCLibUnitInterface **fAVCInterface; 65 IOFireWireAVCLibProtocolInterface **fAVCProtoInterface; 66 UInt64 fGUID; 67 char fName[256]; 68 UInt32 fOutPlug; 69 UInt32 fDVFormats; // DV formats supported by device 70 UInt8 standard; // device standard - NTSC/PAL 71 UInt8 fWriteChan; // Channel the Mac writes to the device on 72 UInt8 fReadChan; // Channel the Mac reads from the device on 73 UInt8 fMaxSpeed; // Max bus speed for isoc channel 74 bool fSupportsFCP; // Does device support AVC commands using the FCP protocol? 75 UInt8 p2pConnected; 76 UInt32 p2pPlug; 77 UInt32 p2pChan; 78 UInt32 deviceIndex; // 1-based device index for message callback refcon 79} DVDevice; 80 81// callback functions 82 83typedef void (*DVDeviceArrivedFunc)(void *refcon, DVDevice *device, UInt32 index, UInt32 refound); 84 85struct _DVThread 86{ 87 pthread_t fRTThread; // Real Time thread, avoid CF. 88 pthread_t fRLThread; // Run-loop thread for device messages 89 IONotificationPortRef fNotifyPort; // Our IOKit notification port 90 CFRunLoopSourceRef fNotifySource; // notify port as a runloop source 91#if 0 92 CFRunLoopSourceRef fRequestSource; // runloop source to ask workthread to do stuff 93 CFRunLoopTimerRef fTimerSource; 94#else 95 mach_port_t fRequestMachPort; // for requests to real time thread 96 CFRunLoopTimerCallBack fTimerFunc; // Fake CR timer callbacks on RT thread 97 void * fTimerRefCon; 98#endif 99 CFRunLoopRef fWorkLoop; 100 io_iterator_t fMatchEnumer; // Iterator over matching devices 101 io_iterator_t fTermEnumer; // Iterator over terminated devices 102 DVDeviceArrivedFunc fAddedFunc; 103 void * fAddedRefCon; 104 IOServiceMatchingCallback fRemovedFunc; 105 void * fRemovedRefCon; 106 IOFWAVCMessageCallback fDeviceMessage; 107 pthread_mutex_t fRequestMutex; 108 ThreadSyncer fRequestSyncer; 109 UInt32 fSyncRequest; // Flag to indicate completion of synchronous operation 110 IOReturn (*fRequestFunc)(void *arg, UInt32 param); 111 void * fRequestArg; 112 UInt32 fRequestParam; 113 IOReturn fRequestResult; 114 UInt32 fNumDevices; 115 DVDevice fDevices[kDVMaxDevicesActive]; 116 CFAbsoluteTime setTimeoutTime; 117 CFAbsoluteTime requestTimeoutTime; 118 DVGlobalOut * fOutStreams[kDVMaxStreamsActive]; 119 DVGlobalIn * fInStreams[kDVMaxStreamsActive]; 120 121 UInt32 fLogPos; 122 Log fLog[kLogSize]; 123 124 io_object_t fPowerManagementNotifier; 125 IONotificationPortRef fPowerNotifyPort; 126 CFRunLoopSourceRef fPowerNotifySource; 127 io_connect_t fPowerNotifyConnect; 128 bool fRunLoopIsRunning; 129}; 130 131 132enum { 133 kNumPlayBufferGroups = 6, // Blocks of packet send ops in output program 134 kDVMaxFrames = 20 // Max number of DV frames in ring buffer 135}; 136 137enum { 138 kEmpty = 0, 139 kReading = 1, 140 kWriting = 2, 141 kReady = 3, 142 143}; 144 145typedef struct _DVSharedVars { 146 UInt32 fNumGroups; // Number of blocks in DCL program 147 UInt32 fGroupSize; // Number of data packets in DCL group 148 UInt32 fAlignedPacketSize; // Total packet size (offset from one to next) 149 UInt32 fPacketDataSize; // Size of DV data in packet 150 UInt32 fDMAPos; // Which block DMA has just done 151 volatile UInt32 * fTimeStampPtrs; // Pointer to array of timestamps, taken at end of block transmit 152 UInt32 fDataOffset[kNumPlayBufferGroups]; // into DCL data buffer 153} DVSharedVars; 154 155typedef struct _DVFrameVars { 156 volatile UInt32 fReader; 157 volatile UInt32 fWriter; 158 volatile UInt32 fDroppedFrames; 159 volatile UInt32 fStatus; 160 volatile UInt32 fFrameSize[kDVMaxFrames]; 161 volatile UInt8 fFrameStandard[kDVMaxFrames]; 162 volatile UInt32 fFrameTime[kDVMaxFrames]; 163 volatile UInt8 fFrameStatus[kDVMaxFrames]; 164 UInt32 fNumFrames; 165 UInt8 * fFrames; 166} DVFrameVars; 167 168 169extern DVThread * DVCreateThread(DVDeviceArrivedFunc deviceAdded, void * addedRefCon, 170 CFRunLoopTimerCallBack timerTick, void *timerRefCon, IOFWAVCMessageCallback deviceMessage); 171extern void DVRunThread(DVThread *thread); 172extern void DVFreeThread(DVThread *thread); 173extern void DVSetTimeoutTime(DVThread * dvThread, CFAbsoluteTime fireDate); 174 175extern void DVSignalSync(ThreadSyncer *sync, UInt32 *var, UInt32 val); 176extern void DVWaitSync(ThreadSyncer *sync, UInt32 *var); 177extern void DVLock(ThreadSyncer *sync); 178extern void DVUnlock(ThreadSyncer *sync); 179extern IOReturn DVRequest(DVThread *thread, IOReturn (*func)(void *arg, UInt32 param), void *arg, UInt32 param); 180 181extern IOReturn openFireWireUnit(IOFireWireAVCLibUnitInterface **avcInterface, IOFireWireSessionRef session, IOFireWireLibDeviceRef *retInterface, DVThread *thread); 182extern IOReturn openAVCUnit(io_object_t obj, IOFireWireAVCLibUnitInterface ***retInterface, DVThread *thread); 183extern IOReturn openAVCProto(IOFireWireAVCLibUnitInterface **avcInterface, IOFireWireAVCLibProtocolInterface ***retInterface, DVThread *thread); 184 185extern IOReturn DVDeviceInit(DVThread *thread, DVDevice *device, 186 io_object_t obj, IOServiceInterestCallback deviceMessage, void * refCon); 187extern void DVDeviceTerminate(DVDevice *device); 188extern IOReturn DVDeviceOpen(DVThread *thread, DVDevice *device); 189extern void DVDeviceClose(DVDevice *device); 190 191extern DVGlobalOutPtr DVAllocWrite(DVDevice *device, DVThread *thread); 192extern IOReturn DVWriteSetSignalMode(DVGlobalOutPtr globs, UInt8 mode); 193extern IOReturn DVWriteAllocFrames(DVGlobalOutPtr globs, UInt32 numFrames, 194 DVFrameVars **frameVars, UInt8 **frames); 195extern UInt8 * DVWriteGetDCLBuffer(DVGlobalOutPtr globs, DVSharedVars **varPtr); 196extern IOReturn DVWriteStart(DVGlobalOutPtr globs); 197extern void DVWriteStop(DVGlobalOutPtr globs); 198extern void DVWriteFreeFrames(DVGlobalOutPtr globs); 199extern void DVWriteFree(DVGlobalOutPtr globs); 200 201extern DVGlobalInPtr DVAllocRead(DVDevice *device, DVThread *thread); 202extern IOReturn DVReadSetSignalMode(DVGlobalInPtr globs, UInt8 mode); 203extern IOReturn DVReadAllocFrames(DVGlobalInPtr globs, UInt32 numFrames, 204 DVFrameVars **frameVars, UInt8 **frames); 205extern IOReturn DVReadStart(DVGlobalInPtr globs); 206extern void DVReadStop(DVGlobalInPtr globs); 207extern void DVReadFreeFrames(DVGlobalInPtr globs); 208extern void DVReadFree(DVGlobalInPtr globs); 209 210extern void DVSilenceFrame(UInt8 mode, UInt8* frame); 211 212extern void DVLog(DVThread *thread, UInt32 tag, CFAbsoluteTime start, CFAbsoluteTime end); 213extern void DVDumpLog(DVThread *thread); 214