1/* 2 * IOFireWireLibIRMAllocation.cpp 3 * IOFireWireFamily 4 * 5 * Created by Andy on 02/06/07. 6 * Copyright (c) 2007 Apple Computer, Inc. All rights reserved. 7 * 8 * $ Log: $ 9 */ 10 11#import "IOFireWireLibIRMAllocation.h" 12#import "IOFireWireLibDevice.h" 13#import "IOFireWireLibPriv.h" 14 15#import <IOKit/iokitmig.h> 16 17namespace IOFireWireLib { 18 19#pragma mark IRMAllocation - 20 21 // ============================================================ 22 // IRMAllocation 23 // ============================================================ 24 IRMAllocation::IRMAllocation( const IUnknownVTbl& interface, 25 Device& userclient, 26 UserObjectHandle inKernIRMAllocationRef, 27 void* inCallBack, 28 void* inRefCon ) 29 : IOFireWireIUnknown( interface ), 30 mNotifyIsOn(false), 31 mUserClient(userclient), 32 mKernIRMAllocationRef(inKernIRMAllocationRef), 33 mLostHandler( (IOFireWireLibIRMAllocationLostNotificationProc) inCallBack ), 34 mUserRefCon(inRefCon), 35 mRefInterface( reinterpret_cast<IOFireWireLibIRMAllocationRef>( & GetInterface() ) ) 36 { 37 userclient.AddRef() ; 38 } 39 40 41 IRMAllocation::~IRMAllocation() 42 { 43 uint32_t outputCnt = 0; 44 const uint64_t inputs[1]={(const uint64_t)mKernIRMAllocationRef}; 45 46 IOConnectCallScalarMethod(mUserClient.GetUserClientConnection(), 47 kReleaseUserObject, 48 inputs,1, 49 NULL,&outputCnt); 50 51 mUserClient.Release() ; 52 } 53 54 Boolean 55 IRMAllocation::NotificationIsOn ( IOFireWireLibIRMAllocationRef self ) 56 { 57 return mNotifyIsOn ; 58 } 59 60 Boolean 61 IRMAllocation::TurnOnNotification ( IOFireWireLibIRMAllocationRef self ) 62 { 63 IOReturn err = kIOReturnSuccess ; 64 io_connect_t connection = mUserClient.GetUserClientConnection() ; 65 66 // if notification is already on, skip out. 67 if (mNotifyIsOn) 68 return true ; 69 70 if (!connection) 71 err = kIOReturnNoDevice ; 72 73 if ( kIOReturnSuccess == err ) 74 { 75 uint64_t refrncData[kOSAsyncRef64Count]; 76 refrncData[kIOAsyncCalloutFuncIndex] = (uint64_t) 0; 77 refrncData[kIOAsyncCalloutRefconIndex] = (unsigned long) 0; 78 const uint64_t inputs[3] = {(const uint64_t)mKernIRMAllocationRef,(const uint64_t)&IRMAllocation::LostProc,(const uint64_t)self}; 79 uint32_t outputCnt = 0; 80 err = IOConnectCallAsyncScalarMethod(connection, 81 kIRMAllocation_SetRef, 82 mUserClient.GetAsyncPort(), 83 refrncData,kOSAsyncRef64Count, 84 inputs,3, 85 NULL,&outputCnt); 86 } 87 88 if ( kIOReturnSuccess == err ) 89 mNotifyIsOn = true ; 90 91 return ( kIOReturnSuccess == err ) ; 92 } 93 94 void 95 IRMAllocation::TurnOffNotification ( IOFireWireLibIRMAllocationRef self ) 96 { 97 IOReturn err = kIOReturnSuccess ; 98 io_connect_t connection = mUserClient.GetUserClientConnection() ; 99 100 // if notification isn't on, skip out. 101 if (!mNotifyIsOn) 102 return ; 103 104 if (!connection) 105 err = kIOReturnNoDevice ; 106 107 if ( kIOReturnSuccess == err ) 108 { 109 uint64_t refrncData[kOSAsyncRef64Count]; 110 refrncData[kIOAsyncCalloutFuncIndex] = (uint64_t) 0; 111 refrncData[kIOAsyncCalloutRefconIndex] = (unsigned long) 0; 112 const uint64_t inputs[3] = {(const uint64_t)mKernIRMAllocationRef,0,(const uint64_t)self}; 113 uint32_t outputCnt = 0; 114 115 // set callback for writes to 0 116 err = IOConnectCallAsyncScalarMethod(connection, 117 kIRMAllocation_SetRef, 118 mUserClient.GetIsochAsyncPort(), 119 refrncData,kOSAsyncRef64Count, 120 inputs,3, 121 NULL,&outputCnt); 122 123 } 124 125 mNotifyIsOn = false ; 126 } 127 128 void IRMAllocation::SetReleaseIRMResourcesOnFree ( IOFireWireLibIRMAllocationRef self, Boolean doRelease) 129 { 130 uint32_t outputCnt = 0; 131 const uint64_t inputs[2]={(const uint64_t)mKernIRMAllocationRef,doRelease}; 132 133 IOConnectCallScalarMethod(mUserClient.GetUserClientConnection(), 134 kIRMAllocation_setDeallocateOnRelease, 135 inputs,2, 136 NULL,&outputCnt); 137 } 138 139 IOReturn IRMAllocation::AllocateIsochResources(IOFireWireLibIRMAllocationRef self, UInt8 isochChannel, UInt32 bandwidthUnits) 140 { 141 uint32_t outputCnt = 0; 142 const uint64_t inputs[3]={(const uint64_t)mKernIRMAllocationRef,isochChannel,bandwidthUnits}; 143 144 return IOConnectCallScalarMethod(mUserClient.GetUserClientConnection(), 145 kIRMAllocation_AllocateResources, 146 inputs,3, 147 NULL,&outputCnt); 148 } 149 150 IOReturn IRMAllocation::DeallocateIsochResources(IOFireWireLibIRMAllocationRef self) 151 { 152 uint32_t outputCnt = 0; 153 const uint64_t inputs[1]={(const uint64_t)mKernIRMAllocationRef}; 154 155 return IOConnectCallScalarMethod(mUserClient.GetUserClientConnection(), 156 kIRMAllocation_DeallocateResources, 157 inputs,1, 158 NULL,&outputCnt); 159 } 160 161 Boolean IRMAllocation::AreIsochResourcesAllocated(IOFireWireLibIRMAllocationRef self, UInt8 *pAllocatedIsochChannel, UInt32 *pAllocatedBandwidthUnits) 162 { 163 uint32_t outputCnt = 2; 164 uint64_t outputVal[2]; 165 const uint64_t inputs[1]={(const uint64_t)mKernIRMAllocationRef}; 166 Boolean result; 167 168 result = IOConnectCallScalarMethod(mUserClient.GetUserClientConnection(), 169 kIRMAllocation_areResourcesAllocated, 170 inputs,1, 171 outputVal,&outputCnt); 172 173 if (result) 174 { 175 *pAllocatedIsochChannel = outputVal[0]; 176 *pAllocatedBandwidthUnits = outputVal[1]; 177 } 178 return result; 179 } 180 181 void IRMAllocation::SetRefCon(IOFireWireLibIRMAllocationRef self, void* refCon) 182 { 183 mUserRefCon = refCon; 184 } 185 186 void* IRMAllocation::GetRefCon(IOFireWireLibIRMAllocationRef self) 187 { 188 return mUserRefCon; 189 } 190 191 void IRMAllocation::LostProc( IOFireWireLibIRMAllocationRef refcon, IOReturn result, void** args, int numArgs) 192 { 193 IRMAllocation* me = IOFireWireIUnknown::InterfaceMap<IRMAllocation>::GetThis(refcon) ; 194 if (me->mLostHandler) 195 me->mLostHandler(refcon,me->mUserRefCon); 196 } 197 198 199#pragma mark IRMAllocationCOM - 200 201 IRMAllocationCOM::Interface IRMAllocationCOM::sInterface = 202 { 203 INTERFACEIMP_INTERFACE, 204 1, 0, 205 &IRMAllocationCOM::SSetReleaseIRMResourcesOnFree, 206 &IRMAllocationCOM::SAllocateIsochResources, 207 &IRMAllocationCOM::SDeallocateIsochResources, 208 &IRMAllocationCOM::SAreIsochResourcesAllocated, 209 &IRMAllocationCOM::SNotificationIsOn, 210 &IRMAllocationCOM::STurnOnNotification, 211 &IRMAllocationCOM::STurnOffNotification, 212 &IRMAllocationCOM::SSetRefCon, 213 &IRMAllocationCOM::SGetRefCon 214 } ; 215 216 // 217 // --- ctor/dtor ----------------------- 218 // 219 220 IRMAllocationCOM::IRMAllocationCOM( Device& userclient, 221 UserObjectHandle inKernIRMAllocationRef, 222 void* inCallBack, 223 void* inRefCon ) 224 : IRMAllocation( reinterpret_cast<const IUnknownVTbl &>( sInterface ), userclient, inKernIRMAllocationRef, inCallBack, inRefCon ) 225 { 226 } 227 228 IRMAllocationCOM::~IRMAllocationCOM() 229 { 230 } 231 232 // 233 // --- IUNKNOWN support ---------------- 234 // 235 236 IUnknownVTbl** 237 IRMAllocationCOM::Alloc(Device& userclient, 238 UserObjectHandle inKernIRMAllocationRef, 239 void* inCallBack, 240 void* inRefCon ) 241 { 242 IRMAllocationCOM* me = nil ; 243 244 try { 245 me = new IRMAllocationCOM( userclient, inKernIRMAllocationRef, inCallBack, inRefCon ) ; 246 } catch(...) { 247 } 248 249 return ( nil == me ) ? nil : reinterpret_cast<IUnknownVTbl**>(& me->GetInterface()) ; 250 } 251 252 HRESULT 253 IRMAllocationCOM::QueryInterface(REFIID iid, void ** ppv ) 254 { 255 HRESULT result = S_OK ; 256 *ppv = nil ; 257 258 CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, iid) ; 259 260 if ( CFEqual(interfaceID, IUnknownUUID) || CFEqual(interfaceID, kIOFireWireIRMAllocationInterfaceID) ) 261 { 262 *ppv = & GetInterface() ; 263 AddRef() ; 264 } 265 else 266 { 267 *ppv = nil ; 268 result = E_NOINTERFACE ; 269 } 270 271 CFRelease(interfaceID) ; 272 return result ; 273 } 274 275 // 276 // --- static methods ------------------ 277 // 278 const void IRMAllocationCOM::SSetReleaseIRMResourcesOnFree (IOFireWireLibIRMAllocationRef self, Boolean doRelease ) 279 { 280 return IOFireWireIUnknown::InterfaceMap<IRMAllocationCOM>::GetThis(self)->SetReleaseIRMResourcesOnFree( self, doRelease ) ; 281 } 282 283 IOReturn IRMAllocationCOM::SAllocateIsochResources(IOFireWireLibIRMAllocationRef self, UInt8 isochChannel, UInt32 bandwidthUnits) 284 { 285 return IOFireWireIUnknown::InterfaceMap<IRMAllocationCOM>::GetThis(self)->AllocateIsochResources( self, isochChannel, bandwidthUnits) ; 286 } 287 288 IOReturn IRMAllocationCOM::SDeallocateIsochResources(IOFireWireLibIRMAllocationRef self) 289 { 290 return IOFireWireIUnknown::InterfaceMap<IRMAllocationCOM>::GetThis(self)->DeallocateIsochResources(self) ; 291 } 292 293 Boolean IRMAllocationCOM::SAreIsochResourcesAllocated(IOFireWireLibIRMAllocationRef self, UInt8 *pAllocatedIsochChannel, UInt32 *pAllocatedBandwidthUnits) 294 { 295 return IOFireWireIUnknown::InterfaceMap<IRMAllocationCOM>::GetThis(self)->AreIsochResourcesAllocated(self, pAllocatedIsochChannel, pAllocatedBandwidthUnits) ; 296 } 297 298 Boolean IRMAllocationCOM::SNotificationIsOn(IOFireWireLibIRMAllocationRef self) 299 { 300 return IOFireWireIUnknown::InterfaceMap<IRMAllocationCOM>::GetThis(self)->NotificationIsOn(self) ; 301 } 302 303 Boolean IRMAllocationCOM::STurnOnNotification(IOFireWireLibIRMAllocationRef self) 304 { 305 return IOFireWireIUnknown::InterfaceMap<IRMAllocationCOM>::GetThis(self)->TurnOnNotification(self) ; 306 } 307 308 void IRMAllocationCOM::STurnOffNotification(IOFireWireLibIRMAllocationRef self) 309 { 310 return IOFireWireIUnknown::InterfaceMap<IRMAllocationCOM>::GetThis(self)->TurnOffNotification(self); 311 } 312 313 void IRMAllocationCOM::SSetRefCon(IOFireWireLibIRMAllocationRef self, void* refCon) 314 { 315 return IOFireWireIUnknown::InterfaceMap<IRMAllocationCOM>::GetThis(self)->SetRefCon(self,refCon); 316 } 317 318 void* IRMAllocationCOM::SGetRefCon(IOFireWireLibIRMAllocationRef self) 319 { 320 return IOFireWireIUnknown::InterfaceMap<IRMAllocationCOM>::GetThis(self)->GetRefCon(self); 321 } 322}