/* * 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@ */ //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // Includes //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // SCSI Architecture Model Family includes #include <IOKit/scsi-commands/IOSCSIProtocolInterface.h> //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // Macros //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ #define DEBUG 0 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "SCSIProtocolInterface" #if DEBUG #define SCSI_PROTOCOL_INTERFACE_DEBUGGING_LEVEL 0 #endif // This module needs SAM_MODULE defined in order to pick up the // static debugging function. #define SAM_MODULE 1 #include "IOSCSIArchitectureModelFamilyDebugging.h" #if ( SCSI_PROTOCOL_INTERFACE_DEBUGGING_LEVEL >= 1 ) #define PANIC_NOW(x) IOPanic x #else #define PANIC_NOW(x) #endif #if ( SCSI_PROTOCOL_INTERFACE_DEBUGGING_LEVEL >= 2 ) #define ERROR_LOG(x) IOLog x #else #define ERROR_LOG(x) #endif #if ( SCSI_PROTOCOL_INTERFACE_DEBUGGING_LEVEL >= 3 ) #define STATUS_LOG(x) IOLog x #else #define STATUS_LOG(x) #endif #if ( SCSI_PROTOCOL_INTERFACE_POWER_DEBUGGING ) #define SERIAL_STATUS_LOG(x) kprintf(x) #else #define SERIAL_STATUS_LOG(x) #endif #define super IOService OSDefineMetaClass ( IOSCSIProtocolInterface, IOService ); OSDefineAbstractStructors ( IOSCSIProtocolInterface, IOService ); //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // Constants //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ enum { kThreadDelayInterval = 500, //( 0.5 second in ms ) k100SecondsInMicroSeconds = 100 * 1000 * 1000 }; /* * Since most, if not all, IOSCSIArchitectureModelFamily drivers * must support power management in some way or another, the support * has been moved up into the highest layers of the object hierarchy. * This mechanism allows for many different power management schemes, * depending on how the specification defines power management. Each * protocol layer and application layer driver is responsible for * implementing power management as the governing specification defines * it. From there, developers can subclass and add any vendor-specific * workarounds necessary for power management or they can make the * power management scheme more elaborate or more simplistic. * */ #if 0 #pragma mark - #pragma mark ₯ Public Methods #pragma mark - #endif //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ start - Called by IOKit to start our services. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIProtocolInterface::start ( IOService * provider ) { bool result = false; IOWorkLoop * workLoop = NULL; workLoop = getWorkLoop ( ); require_nonzero ( workLoop, ErrorExit ); fCommandGate = IOCommandGate::commandGate ( this ); require_nonzero ( fCommandGate, ErrorExit ); workLoop->addEventSource ( fCommandGate ); fPowerAckInProgress = false; fPowerTransitionInProgress = false; fPowerManagementInitialized = false; fUserClientExclusiveControlled = false; // Allocate the thread on which to do power management fPowerManagementThread = thread_call_allocate ( ( thread_call_func_t ) IOSCSIProtocolInterface::sPowerManagement, ( thread_call_param_t ) this ); require_nonzero ( fPowerManagementThread, ReleaseCommandGate ); result = true; return result; ReleaseCommandGate: workLoop->removeEventSource ( fCommandGate ); fCommandGate->release ( ); fCommandGate = NULL; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ free - Called by IOKit to deallocate any resources. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIProtocolInterface::free ( void ) { IOWorkLoop * workLoop = NULL; if ( fCommandGate != NULL ) { workLoop = getWorkLoop ( ); if ( workLoop != NULL ) { // Remove our command gate as an event source on // the workloop workLoop->removeEventSource ( fCommandGate ); } fCommandGate->release ( ); fCommandGate = NULL; } if ( fPowerManagementThread != NULL ) { // Free the thread we allocated for power management thread_call_free ( fPowerManagementThread ); fPowerManagementThread = NULL; } super::free ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ GetUserClientExclusivityState - Call to see if user client is in // exclusive mode. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIProtocolInterface::GetUserClientExclusivityState ( void ) { bool state; fCommandGate->runAction ( ( IOCommandGate::Action ) &IOSCSIProtocolInterface::sGetUserClientExclusivityState, ( void * ) &state ); return state; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ SetUserClientExclusivityState - Call to see if user client is in // exclusive mode. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ IOReturn IOSCSIProtocolInterface::SetUserClientExclusivityState ( IOService * userClient, bool state ) { IOReturn status = kIOReturnExclusiveAccess; fCommandGate->runAction ( ( IOCommandGate::Action ) &IOSCSIProtocolInterface::sSetUserClientExclusivityState, ( void * ) &status, ( void * ) userClient, ( void * ) state ); return status; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ initialPowerStateForDomainState - Returns to the power manager what // initial state the device should be in. // [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ UInt32 IOSCSIProtocolInterface::initialPowerStateForDomainState ( IOPMPowerFlags flags ) { // We ignore the flags since we are always active at startup time and we // just report what our initial power state is. return GetInitialPowerState ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ setPowerState - Set/Change the power state of the device [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ IOReturn IOSCSIProtocolInterface::setPowerState ( UInt32 powerStateOrdinal, IOService * whichDevice ) { return fCommandGate->runAction ( ( IOCommandGate::Action ) &IOSCSIProtocolInterface::sHandleSetPowerState, ( void * ) powerStateOrdinal ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ IsPowerManagementIntialized - Returns fPowerManagementInitialized.[PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIProtocolInterface::IsPowerManagementIntialized ( void ) { return fPowerManagementInitialized; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ CheckPowerState - Checks if it is ok for I/O to come through. If it is // not ok, then we block the thread. [PUBLIC] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIProtocolInterface::CheckPowerState ( void ) { // Tell the power manager we must be in active state to handle requests // "active" state means the minimal possible state in which the driver can // handle I/O. This may be set to standby, but there is no gain to setting // the drive to standby and then issuing an I/O, it just requires more time. // Also, if the drive was asleep, it might need a reset which could put it // in standby mode anyway, so we usually request the max state from the power // manager TicklePowerManager ( ); // Now run an action behind a command gate to block the threads if necessary fCommandGate->runAction ( ( IOCommandGate::Action ) &IOSCSIProtocolInterface::sHandleCheckPowerState ); } #if 0 #pragma mark - #pragma mark ₯ Protected Methods #pragma mark - #endif //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ finalize - Terminates all power management. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIProtocolInterface::finalize ( IOOptionBits options ) { if ( fPowerManagementInitialized ) { bool powerTransistionStillInProgress = true; // need to wait for power transistion in progress to // finish before finalizing or the transistion will // attempt to complete after we are gone while ( 1 ) { powerTransistionStillInProgress = ( bool ) fCommandGate->runAction ( ( IOCommandGate::Action ) &IOSCSIProtocolInterface::sGetPowerTransistionInProgress ); if ( powerTransistionStillInProgress ) { IOSleep ( 1 ); } else { break; } } fCommandGate->commandWakeup ( &fCurrentPowerState, false ); fCommandGate->runAction ( ( IOCommandGate::Action ) &IOSCSIProtocolInterface::sGetPowerTransistionInProgress ); STATUS_LOG ( ( "PMstop about to be called.\n" ) ); PMstop ( ); if ( fPowerManagementThread != NULL ) { // If the power management thread is scheduled, unschedule it. thread_call_cancel ( fPowerManagementThread ); } fPowerManagementInitialized = false; } return super::finalize ( options ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ InitializePowerManagement - Joins PM tree and initializes pm vars. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIProtocolInterface::InitializePowerManagement ( IOService * provider ) { PMinit ( ); setIdleTimerPeriod ( 5 * 60 ); // set 5 minute idle timer until system sends us // new values via setAggressiveness() provider->joinPMtree ( this ); // Call makeUsable here to tell the power manager to put us in our // highest power state when we call registerPowerDriver(). makeUsable ( ); fPowerManagementInitialized = true; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ HandleSetPowerState - Synchronized form of changing a power state. // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIProtocolInterface::HandleSetPowerState ( UInt32 powerStateOrdinal ) { AbsoluteTime time; fProposedPowerState = powerStateOrdinal; if ( ( fPowerTransitionInProgress == false ) || fPowerAckInProgress ) { // mark us as being in progress, then call the thread which is // the power management state machine fPowerTransitionInProgress = true; // We use a delayed thread call in order to allow the thread we're // on (the power manager thread) to get back to business doing // whatever it needs to with the rest of the system clock_interval_to_deadline ( kThreadDelayInterval, kMillisecondScale, &time ); ( void ) thread_call_enter_delayed ( fPowerManagementThread, time ); } } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ HandleCheckPowerState - Called on safe side of command gate to // serialize access to the sleep related // variables. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIProtocolInterface::HandleCheckPowerState ( UInt32 maxPowerState ) { STATUS_LOG ( ( "IOSCSIProtocolInterface::%s called\n", __FUNCTION__ ) ); // A while loop is used here in case the power is changed on us while // the power state-machine is running. If the power manager tells us to // wake up, we unblock the thread by calling fCommandGate->commandWakeup, but // while we do this we may block and inbetween getting rescheduled, the // power manager might tell us to change states again, so we guard against // this scenario by looping and verifying that the state does indeed go to // active. while ( ( fCurrentPowerState != maxPowerState ) && ( isInactive ( ) == false ) && ( getWorkLoop ( )->onThread ( ) == false ) ) { fCommandGate->commandSleep ( &fCurrentPowerState, THREAD_UNINT ); } } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ TicklePowerManager - Convenience function to call power manager's // activity tickle routine. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIProtocolInterface::TicklePowerManager ( UInt32 maxPowerState ) { // Tell the power manager we must be in active state to handle requests // "active" state means the minimal possible state in which the driver can // handle I/O. This may be set to standby, but there is no gain to setting // the drive to standby and then issuing an I/O, it just requires more time. // Also, if the drive was asleep, it might need a reset which could put it // in standby mode anyway, so we usually request the max state from the power // manager return ( activityTickle ( kIOPMSuperclassPolicy1, maxPowerState ) ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ HandleGetUserClientExclusivityState - Checks to see what state the user // client is in. [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIProtocolInterface::HandleGetUserClientExclusivityState ( void ) { return fUserClientExclusiveControlled; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ HandleSetUserClientExclusivityState - Sets the state the user client is in // [PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ IOReturn IOSCSIProtocolInterface::HandleSetUserClientExclusivityState ( IOService * userClient, bool state ) { IOReturn status = kIOReturnExclusiveAccess; if ( fUserClient == NULL ) { STATUS_LOG ( ( "fUserClient is NULL\n" ) ); if ( state != false ) { STATUS_LOG ( ( "state is true\n" ) ); fUserClient = userClient; fUserClientExclusiveControlled = state; status = kIOReturnSuccess; } else { STATUS_LOG ( ( "state is false\n" ) ); status = kIOReturnBadArgument; } } else if ( fUserClient == userClient ) { STATUS_LOG ( ( "fUserClient is same as userClient\n" ) ); if ( state == false ) { STATUS_LOG ( ( "state is false\n" ) ); fUserClient = NULL; fUserClientExclusiveControlled = state; status = kIOReturnSuccess; } status = kIOReturnSuccess; } STATUS_LOG ( ( "HandleSetUserClientExclusivityState status = %d\n", status ) ); return status; } #if 0 #pragma mark - #pragma mark ₯ Static Methods (C->C++ glue) #pragma mark - #endif //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ sHandleSetPowerState - C->C++ glue. [STATIC][PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ IOReturn IOSCSIProtocolInterface::sHandleSetPowerState ( IOSCSIProtocolInterface * self, UInt32 powerStateOrdinal ) { IOReturn result = 0; if ( self->isInactive ( ) == false ) { self->HandleSetPowerState ( powerStateOrdinal ); result = k100SecondsInMicroSeconds; } return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ sGetPowerTransistionInProgress - Returns power transition status. // [STATIC][PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool IOSCSIProtocolInterface::sGetPowerTransistionInProgress ( IOSCSIProtocolInterface * self ) { return ( self->fPowerTransitionInProgress ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ sPowerManagement - C->C++ glue. [STATIC][PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIProtocolInterface::sPowerManagement ( thread_call_param_t whichDevice ) { IOSCSIProtocolInterface * self; self = ( IOSCSIProtocolInterface * ) whichDevice; if ( ( self != NULL ) && ( self->isInactive ( ) == false ) ) { self->retain ( ); self->HandlePowerChange ( ); self->fPowerAckInProgress = true; self->acknowledgeSetPowerState ( ); self->fPowerAckInProgress = false; self->fPowerTransitionInProgress = false; self->release ( ); } else { self->fPowerTransitionInProgress = false; } } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ sHandleCheckPowerState - C->C++ glue. [STATIC][PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIProtocolInterface::sHandleCheckPowerState ( IOSCSIProtocolInterface * self ) { self->HandleCheckPowerState ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ sGetUserClientExclusivityState - C->C++ glue. [STATIC][PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIProtocolInterface::sGetUserClientExclusivityState ( IOSCSIProtocolInterface * self, bool * state ) { *state = self->HandleGetUserClientExclusivityState ( ); } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // ₯ sSetUserClientExclusivityState - C->C++ glue. [STATIC][PROTECTED] //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ void IOSCSIProtocolInterface::sSetUserClientExclusivityState ( IOSCSIProtocolInterface * self, IOReturn * status, IOService * userClient, bool state ) { *status = self->HandleSetUserClientExclusivityState ( userClient, state ); } #if 0 #pragma mark - #pragma mark ₯ Static Debugging Assertion Method #pragma mark - #endif void IOSCSIArchitectureModelFamilyDebugAssert ( const char * componentNameString, const char * assertionString, const char * exceptionLabelString, const char * errorString, const char * fileName, long lineNumber, int errorCode ) { IOLog ( "%s Assert failed: %s ", componentNameString, assertionString ); if ( exceptionLabelString != NULL ) IOLog ( "%s ", exceptionLabelString ); if ( errorString != NULL ) IOLog ( "%s ", errorString ); if ( fileName != NULL ) IOLog ( "file: %s ", fileName ); if ( lineNumber != 0 ) IOLog ( "line: %ld ", lineNumber ); if ( ( long ) errorCode != 0 ) IOLog ( "error: %ld ", ( long ) errorCode ); IOLog ( "\n" ); } #if 0 #pragma mark - #pragma mark ₯ VTable Padding #pragma mark - #endif OSMetaClassDefineReservedUsed ( IOSCSIProtocolInterface, 1 ); // Used by the abstract member routine: // virtual SCSIServiceResponse AbortTask ( UInt8 theLogicalUnit, SCSITaggedTaskIdentifier theTag ) = 0; OSMetaClassDefineReservedUsed ( IOSCSIProtocolInterface, 2 ); // Used by the abstract member routine: // virtual SCSIServiceResponse AbortTaskSet ( UInt8 theLogicalUnit ) = 0; OSMetaClassDefineReservedUsed ( IOSCSIProtocolInterface, 3 ); // Used by the abstract member routine: // virtual SCSIServiceResponse ClearACA ( UInt8 theLogicalUnit ) = 0; OSMetaClassDefineReservedUsed ( IOSCSIProtocolInterface, 4 ); // Used by the abstract member routine: // virtual SCSIServiceResponse ClearTaskSet ( UInt8 theLogicalUnit ) = 0; OSMetaClassDefineReservedUsed ( IOSCSIProtocolInterface, 5 ); // Used by the abstract member routine: // virtual SCSIServiceResponse LogicalUnitReset ( UInt8 theLogicalUnit ) = 0; OSMetaClassDefineReservedUsed ( IOSCSIProtocolInterface, 6 ); // Used by the abstract member routine: // virtual SCSIServiceResponse TargetReset ( void ) = 0; // Space reserved for future expansion. OSMetaClassDefineReservedUnused ( IOSCSIProtocolInterface, 7 ); OSMetaClassDefineReservedUnused ( IOSCSIProtocolInterface, 8 ); OSMetaClassDefineReservedUnused ( IOSCSIProtocolInterface, 9 ); OSMetaClassDefineReservedUnused ( IOSCSIProtocolInterface, 10 ); OSMetaClassDefineReservedUnused ( IOSCSIProtocolInterface, 11 ); OSMetaClassDefineReservedUnused ( IOSCSIProtocolInterface, 12 ); OSMetaClassDefineReservedUnused ( IOSCSIProtocolInterface, 13 ); OSMetaClassDefineReservedUnused ( IOSCSIProtocolInterface, 14 ); OSMetaClassDefineReservedUnused ( IOSCSIProtocolInterface, 15 ); OSMetaClassDefineReservedUnused ( IOSCSIProtocolInterface, 16 );