/* * Copyright (c) 2001-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@ */ //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // Includes //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // Core Foundation includes #include // IOSCSIArchitectureModelFamily includes #include // Private includes #include "SCSITaskDeviceClass.h" #include "SCSITaskClass.h" // C Library includes #include // Since mach headers donÕt have C++ wrappers we have to // declare extern ÒCÓ before including them. #ifdef __cplusplus extern "C" { #endif #include #include #ifdef __cplusplus } #endif //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // Macros //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ #define DEBUG 0 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "SCSITaskDeviceClass" #if DEBUG #define PRINT(x) printf x #else #define PRINT(x) #endif #include "IOSCSIArchitectureModelFamilyDebugging.h" //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // Static variable initialization //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOCFPlugInInterface SCSITaskDeviceClass::sIOCFPlugInInterface = { 0, &SCSITaskIUnknown::sQueryInterface, &SCSITaskIUnknown::sAddRef, &SCSITaskIUnknown::sRelease, 1, 0, // version/revision &SCSITaskDeviceClass::sProbe, &SCSITaskDeviceClass::sStart, &SCSITaskDeviceClass::sStop }; SCSITaskDeviceInterface SCSITaskDeviceClass::sSCSITaskDeviceInterface = { 0, &SCSITaskDeviceClass::sQueryInterface, &SCSITaskDeviceClass::sAddRef, &SCSITaskDeviceClass::sRelease, 1, 0, // version/revision &SCSITaskDeviceClass::sIsExclusiveAccessAvailable, &SCSITaskDeviceClass::sAddCallbackDispatcherToRunLoop, &SCSITaskDeviceClass::sRemoveCallbackDispatcherFromRunLoop, &SCSITaskDeviceClass::sObtainExclusiveAccess, &SCSITaskDeviceClass::sReleaseExclusiveAccess, &SCSITaskDeviceClass::sCreateSCSITask, }; #if 0 #pragma mark - #pragma mark Public Methods #pragma mark - #endif //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ alloc - Called to allocate an instance of the class [PUBLIC] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOCFPlugInInterface ** SCSITaskDeviceClass::alloc ( void ) { SCSITaskDeviceClass * userClient = NULL; IOCFPlugInInterface ** interface = NULL; IOReturn status = kIOReturnSuccess; PRINT ( ( "SCSITaskDeviceClass::alloc called\n" ) ); userClient = new SCSITaskDeviceClass; require_nonzero ( userClient, Error_Exit ); status = userClient->Init ( ); require_success_action_string ( status, Error_Exit, delete userClient, "Init failed" ); userClient->AddRef ( ); interface = ( IOCFPlugInInterface ** ) &userClient->fInterfaceMap.pseudoVTable; Error_Exit: return interface; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ alloc - Called to allocate an instance of the class [PUBLIC] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ SCSITaskDeviceInterface ** SCSITaskDeviceClass::alloc ( io_service_t service, io_connect_t connection ) { SCSITaskDeviceClass * userClient = NULL; SCSITaskDeviceInterface ** interface = NULL; IOReturn status = kIOReturnSuccess; PRINT ( ( "SCSITaskDeviceClass::alloc called\n" ) ); userClient = new SCSITaskDeviceClass; require_nonzero ( userClient, Error_Exit ); status = userClient->InitWithConnection ( service, connection ); require_success_action_string ( status, Error_Exit, delete userClient, "InitWithConnection failed" ); userClient->AddRef ( ); interface = ( SCSITaskDeviceInterface ** ) &userClient->fSCSITaskDeviceInterfaceMap.pseudoVTable; Error_Exit: return interface; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ Init - Called to initialize an instance of the class [PUBLIC] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::Init ( void ) { IOReturn status = kIOReturnNoResources; PRINT ( ( "SCSITaskDeviceClass::Init called\n" ) ); fTaskSet = CFSetCreateMutable ( kCFAllocatorDefault, 0, NULL ); require_nonzero ( fTaskSet, Error_Exit ); status = kIOReturnSuccess; Error_Exit: return status; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ Init - Called to initialize an instance of the class with a connection // established by another object [PUBLIC] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::InitWithConnection ( io_service_t service, io_connect_t connection ) { IOReturn status = kIOReturnBadArgument; PRINT ( ( "SCSITaskDeviceClass::InitWithConnection called\n" ) ); require_nonzero ( service, Error_Exit ); require_nonzero ( connection, Error_Exit ); status = Init ( ); require_success ( status, Error_Exit ); fService = service; fConnection = connection; fIsServicesLayerInterface = true; status = kIOReturnSuccess; Error_Exit: return status; } #if 0 #pragma mark - #pragma mark Protected Methods #pragma mark - #endif //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ Default Constructor - Called on allocation [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ SCSITaskDeviceClass::SCSITaskDeviceClass ( void ) : SCSITaskIUnknown ( &sIOCFPlugInInterface ) { PRINT ( ( "SCSITaskDeviceClass constructor called\n" ) ); // Init callback stuff fAsyncPort = MACH_PORT_NULL; fCFRunLoop = 0; fCFRunLoopSource = 0; fTaskSet = 0; // init user client connection fConnection = MACH_PORT_NULL; fService = MACH_PORT_NULL; fHasExclusiveAccess = false; fIsServicesLayerInterface = false; // create driver interface map fSCSITaskDeviceInterfaceMap.pseudoVTable = ( IUnknownVTbl * ) &sSCSITaskDeviceInterface; fSCSITaskDeviceInterfaceMap.obj = this; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ Default Destructor - Called on deallocation [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ SCSITaskDeviceClass::~SCSITaskDeviceClass ( void ) { PRINT ( ( "SCSITaskDeviceClass : Destructor called\n" ) ); if ( fAsyncPort != MACH_PORT_NULL ) { PRINT ( ( "SCSITaskDeviceClass : fAsyncPort != MACH_PORT_NULL\n" ) ); IOObjectRelease ( fAsyncPort ); fAsyncPort = MACH_PORT_NULL; } if ( fTaskSet != 0 ) { PRINT ( ( "SCSITaskDeviceClass : fTaskSet != 0\n" ) ); CFRelease ( fTaskSet ); } } #if 0 #pragma mark - #endif //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ QueryInterface - Called to obtain the presence of an interface // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ HRESULT SCSITaskDeviceClass::QueryInterface ( REFIID iid, void ** ppv ) { CFUUIDRef uuid = CFUUIDCreateFromUUIDBytes ( NULL, iid ); HRESULT result = S_OK; PRINT ( ( "SCSITaskDeviceClass : QueryInterface called\n" ) ); if ( CFEqual ( uuid, IUnknownUUID ) || CFEqual ( uuid, kIOCFPlugInInterfaceID ) ) { *ppv = &fInterfaceMap; AddRef ( ); } else if ( CFEqual ( uuid, kIOSCSITaskDeviceInterfaceID ) ) { PRINT ( ( "kSCSITaskDeviceUserClientInterfaceID requested\n" ) ); *ppv = &fSCSITaskDeviceInterfaceMap; AddRef ( ); } else { *ppv = 0; result = E_NOINTERFACE; } CFRelease ( uuid ); return result; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ Probe - Called by IOKit to ascertain whether we can drive the provided // io_service_t [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::Probe ( CFDictionaryRef propertyTable, io_service_t inService, SInt32 * order ) { CFMutableDictionaryRef dict = 0; IOReturn status = kIOReturnBadArgument; Boolean ok = false; PRINT ( ( "SCSITaskDeviceClass::Probe called\n" ) ); // Sanity check require_nonzero ( inService, Error_Exit ); status = IORegistryEntryCreateCFProperties ( inService, &dict, NULL, 0 ); require_success ( status, Error_Exit ); ok = CFDictionaryContainsKey ( dict, CFSTR ( "IOCFPlugInTypes" ) ); require_action ( ok, ReleaseDictionary, status = kIOReturnNoDevice ); status = kIOReturnSuccess; ReleaseDictionary: require_nonzero ( dict, Error_Exit ); CFRelease ( dict ); Error_Exit: return status; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ Start - Called to start providing our services. [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::Start ( CFDictionaryRef propertyTable, io_service_t service ) { IOReturn status = kIOReturnNoDevice; PRINT ( ( "SCSITaskDeviceClass : Start\n" ) ); fService = service; status = IOServiceOpen ( fService, mach_task_self ( ), kSCSITaskLibConnection, &fConnection ); require_success ( status, Error_Exit ); require_nonzero_action ( fConnection, Error_Exit, status = kIOReturnNoDevice ); fHasExclusiveAccess = true; PRINT ( ( "SCSITaskDeviceClass : IOServiceOpen status = 0x%08lx, connection = %d\n", ( UInt32 ) status, fConnection ) ); Error_Exit: return status; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ Stop - Called to stop providing our services. [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::Stop ( void ) { PRINT ( ( "SCSITaskDeviceClass : Stop\n" ) ); if ( fTaskSet != 0 ) { // CFSetApplyFunction ( fTaskSet, &SCSITaskClass::sAbortAndReleaseTasks, 0 ); CFRelease ( fTaskSet ); fTaskSet = 0; } if ( fConnection != 0 ) { PRINT ( ( "SCSITaskDeviceClass : IOServiceClose connection = %d\n", fConnection ) ); IOServiceClose ( fConnection ); fConnection = MACH_PORT_NULL; } return kIOReturnSuccess; } #if 0 #pragma mark - #endif //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ IsExclusiveAccessAvailable - Called to ascertain if exclusive access is // available. [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ Boolean SCSITaskDeviceClass::IsExclusiveAccessAvailable ( void ) { Boolean result = false; IOReturn status = kIOReturnSuccess; PRINT ( ( "SCSITaskDeviceClass : IsExclusiveAccessAvailable\n" ) ); require_nonzero ( fConnection, Error_Exit ); // We only have to do this if the services layer // is involved. Otherwise, its handled in Start. if ( fIsServicesLayerInterface ) { status = IOConnectMethodScalarIScalarO ( fConnection, kSCSITaskUserClientIsExclusiveAccessAvailable, 0, 0 ); if ( status == kIOReturnSuccess ) { result = true; } } else { result = true; } Error_Exit: return result; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ CreateDeviceAsyncEventSource - Called to create an async event source // in the form of a CFRunLoopSourceRef. // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::CreateDeviceAsyncEventSource ( CFRunLoopSourceRef * source ) { IOReturn status = kIOReturnNoDevice; CFMachPortRef cfMachPort = NULL; CFMachPortContext context; Boolean shouldFreeInfo; // zzz what's this for? PRINT ( ( "SCSITaskDeviceClass : CreateDeviceAsyncEventSource\n" ) ); require_nonzero ( fConnection, Error_Exit ); status = CreateDeviceAsyncPort ( NULL ); require ( ( status == kIOReturnNotPermitted ) || ( status == kIOReturnSuccess ), Error_Exit ); context.version = 1; context.info = this; context.retain = NULL; context.release = NULL; context.copyDescription = NULL; cfMachPort = CFMachPortCreateWithPort ( kCFAllocatorDefault, fAsyncPort, ( CFMachPortCallBack ) IODispatchCalloutFromMessage, &context, &shouldFreeInfo ); require_nonzero_action ( cfMachPort, Error_Exit, status = kIOReturnNoMemory ); PRINT ( ( "CFMachPortCreateWithPort\n" ) ); fCFRunLoopSource = CFMachPortCreateRunLoopSource ( kCFAllocatorDefault, cfMachPort, 0 ); require_nonzero_action ( fCFRunLoopSource, Error_Exit, status = kIOReturnNoMemory ); PRINT ( ( "CFMachPortCreateRunLoopSource\n" ) ); status = kIOReturnSuccess; require_nonzero ( source, Error_Exit ); *source = fCFRunLoopSource; Error_Exit: if ( cfMachPort != 0 ) { CFRelease ( cfMachPort ); } return status; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ GetDeviceAsyncEventSource - Called to get the CFRunLoopSourceRef. // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ CFRunLoopSourceRef SCSITaskDeviceClass::GetDeviceAsyncEventSource ( void ) { PRINT ( ( "GetDeviceAsyncEventSource, %p\n", fCFRunLoopSource ) ); return fCFRunLoopSource; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ CreateDeviceAsyncPort - Called to create a mach port on which // to receive an async callback notification. // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::CreateDeviceAsyncPort ( mach_port_t * port ) { IOReturn status = kIOReturnNotPermitted; MyConnectionAndPortContext context; PRINT ( ( "CreateDeviceAsyncPort called\n" ) ); require ( ( fAsyncPort == MACH_PORT_NULL ), Error_Exit ); IOCreateReceivePort ( kOSAsyncCompleteMessageID, &fAsyncPort ); context.connection = fConnection; context.asyncPort = fAsyncPort; CFSetApplyFunction ( fTaskSet, &SCSITaskClass::sSetConnectionAndPort, &context ); status = kIOReturnSuccess; require_nonzero ( port, Error_Exit ); *port = fAsyncPort; Error_Exit: return status; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ GetDeviceAsyncPort - Called to get the mach port used for async // callback notifications. [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ mach_port_t SCSITaskDeviceClass::GetDeviceAsyncPort ( void ) { PRINT ( ( "GetDeviceAsyncPort : %d\n", fAsyncPort ) ); return fAsyncPort; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ AddCallbackDispatcherToRunLoop - Called to add an async callback // dispatch mechanism to the runloop // provided. [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::AddCallbackDispatcherToRunLoop ( CFRunLoopRef cfRunLoopRef ) { IOReturn status = kIOReturnNoDevice; PRINT ( ( "SCSITaskDeviceClass : AddCallbackDispatcherToRunLoop\n" ) ); require_nonzero ( fConnection, Error_Exit ); status = CreateDeviceAsyncEventSource ( NULL ); require_success ( status, Error_Exit ); fCFRunLoop = cfRunLoopRef; CFRunLoopAddSource ( fCFRunLoop, fCFRunLoopSource, kCFRunLoopCommonModes ); PRINT ( ( "CFRunLoopAddSource\n" ) ); Error_Exit: return status; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ RemoveCallbackDispatcherFromRunLoop - Called to remove an async callback // dispatch mechanism from the runloop. // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ void SCSITaskDeviceClass::RemoveCallbackDispatcherFromRunLoop ( void ) { PRINT ( ( "SCSITaskDeviceClass : RemoveCallbackDispatcherFromRunLoop\n" ) ); if ( fCFRunLoopSource != 0 ) { CFRunLoopRemoveSource ( fCFRunLoop, fCFRunLoopSource, kCFRunLoopCommonModes ); fCFRunLoopSource = 0; } if ( fAsyncPort != MACH_PORT_NULL ) { IOObjectRelease ( fAsyncPort ); fAsyncPort = MACH_PORT_NULL; } } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ ObtainExclusiveAccess - Called to obtain exclusive access to the device. // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::ObtainExclusiveAccess ( void ) { IOReturn status = kIOReturnSuccess; PRINT ( ( "SCSITaskDeviceClass : ObtainExclusiveAccess\n" ) ); // We only have to do this if the services layer // is involved. Otherwise, it's handled in Start. require ( fIsServicesLayerInterface, Exit ); status = IOConnectMethodScalarIScalarO ( fConnection, kSCSITaskUserClientObtainExclusiveAccess, 0, 0 ); require_success ( status, Error_Exit ); PRINT ( ( "we have exclusive access\n" ) ); fHasExclusiveAccess = true; Error_Exit: Exit: return status; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ ReleaseExclusiveAccess - Called to release exclusive access to the device. // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::ReleaseExclusiveAccess ( void ) { IOReturn status = kIOReturnExclusiveAccess; PRINT ( ( "SCSITaskDeviceClass : ReleaseExclusiveAccess\n" ) ); // Sanity check: make sure we have exclusive access already require ( fHasExclusiveAccess, Error_Exit ); // If this isn't the services layer, short-circuit out require_action ( fIsServicesLayerInterface, Exit, status = kIOReturnSuccess ); status = IOConnectMethodScalarIScalarO ( fConnection, kSCSITaskUserClientReleaseExclusiveAccess, 0, 0 ); PRINT ( ( "ReleaseExclusiveAccess status = 0x%08x\n", status ) ); Error_Exit: Exit: return status; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ CreateSCSITask - Called to create a SCSITaskInterface object. // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ SCSITaskInterface ** SCSITaskDeviceClass::CreateSCSITask ( void ) { SCSITaskInterface ** interface = NULL; PRINT ( ( "SCSITaskDeviceClass : CreateSCSITask\n" ) ); require ( fHasExclusiveAccess, Error_Exit ); interface = SCSITaskClass::alloc ( this, fConnection, fAsyncPort ); require_nonzero ( interface, Error_Exit ); CFSetAddValue ( fTaskSet, interface ); Error_Exit: return interface; } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ RemoveTaskFromTaskSet - Called to remove a SCSITaskInterface object // from the set of tasks. // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ void SCSITaskDeviceClass::RemoveTaskFromTaskSet ( SCSITaskInterface ** task ) { PRINT ( ( "SCSITaskDeviceClass : RemoveTaskFromTaskSet called\n" ) ); check ( task ); if ( fTaskSet ) { CFSetRemoveValue ( fTaskSet, task ); } } #if 0 #pragma mark - #pragma mark Static C->C++ Glue Functions #pragma mark - #endif //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sProbe - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::sProbe ( void * self, CFDictionaryRef propertyTable, io_service_t service, SInt32 * order ) { check ( self ); return getThis ( self )->Probe ( propertyTable, service, order ); } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sStart - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::sStart ( void * self, CFDictionaryRef propertyTable, io_service_t service ) { check ( self ); return getThis ( self )->Start ( propertyTable, service ); } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sStop - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::sStop ( void * self ) { check ( self ); return getThis ( self )->Stop ( ); } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sIsExclusiveAccessAvailable - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ Boolean SCSITaskDeviceClass::sIsExclusiveAccessAvailable ( void * self ) { check ( self ); return getThis ( self )->IsExclusiveAccessAvailable ( ); } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sCreateDeviceAsyncEventSource - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::sCreateDeviceAsyncEventSource ( void * self, CFRunLoopSourceRef * source ) { check ( self ); return getThis ( self )->CreateDeviceAsyncEventSource ( source ); } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sGetDeviceAsyncEventSource - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ CFRunLoopSourceRef SCSITaskDeviceClass::sGetDeviceAsyncEventSource ( void * self ) { check ( self ); return getThis ( self )->GetDeviceAsyncEventSource ( ); } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sCreateDeviceAsyncPort - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::sCreateDeviceAsyncPort ( void * self, mach_port_t * port ) { check ( self ); return getThis ( self )->CreateDeviceAsyncPort ( port ); } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sGetDeviceAsyncPort - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ mach_port_t SCSITaskDeviceClass::sGetDeviceAsyncPort ( void * self ) { check ( self ); return getThis ( self )->GetDeviceAsyncPort ( ); } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sAddCallbackDispatcherToRunLoop - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::sAddCallbackDispatcherToRunLoop ( void * self, CFRunLoopRef cfRunLoopRef ) { check ( self ); return getThis ( self )->AddCallbackDispatcherToRunLoop ( cfRunLoopRef ); } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sRemoveCallbackDispatcherFromRunLoop - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ void SCSITaskDeviceClass::sRemoveCallbackDispatcherFromRunLoop ( void * self ) { check ( self ); return getThis ( self )->RemoveCallbackDispatcherFromRunLoop ( ); } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sObtainExclusiveAccess - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::sObtainExclusiveAccess ( void * self ) { check ( self ); return getThis ( self )->ObtainExclusiveAccess ( ); } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sReleaseExclusiveAccess - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ IOReturn SCSITaskDeviceClass::sReleaseExclusiveAccess ( void * self ) { check ( self ); return getThis ( self )->ReleaseExclusiveAccess ( ); } //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ // ¥ sCreateSCSITask - Static function for C->C++ glue // [PROTECTED] //ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ SCSITaskInterface ** SCSITaskDeviceClass::sCreateSCSITask ( void * self ) { check ( self ); return getThis ( self )->CreateSCSITask ( ); }