IOReturn IOFireWireSBP2LibORB::init( io_connect_t connection, mach_port_t asyncPort )
{
	IOReturn status = kIOReturnSuccess;

	fConnection = connection;
	fAsyncPort = asyncPort;
	
	FWLOG(( "IOFireWireSBP2LibORB : fConnection %d, fAsyncPort %d\n", 
												fConnection, fAsyncPort ));
	
	if( !fConnection || !fAsyncPort )
		status = kIOReturnError;
		
	if( status == kIOReturnSuccess )
	{
		uint32_t len = 1;
		status = IOConnectCallScalarMethod( connection, kIOFWSBP2UserClientCreateORB, 
											NULL, 0, &fORBRef, &len );
		if( status != kIOReturnSuccess )
			fORBRef = 0; // just to make sure
													
		FWLOG(( "IOFireWireSBP2LibORB :  status = 0x%08x = fORBRef 0x%08lx\n",
																	status, fORBRef ));
	}
			
	return status;
}
void SBP2SampleLoginController::loginCompletion( FWSBP2LoginCompleteParams * params )
{	
	FWLOG(( "SBP2SampleLoginController : loginCompletion\n" ));

	// NOTE: the param block and any pointers in the param block
    // are only guaranteed to be valid until this function returns

    // NOTE: do not modify the loginResponse block or the statusBlock

    // check params->status for success
    // if params->statusBlock != NULL, the status block was received; check for further status
    // login response is supplied in params->loginResponse on a successful login
    
	FWSBP2StatusBlock * statusBlock = params->statusBlock;
	
	//zzz may want to check device specific status for success as well
    if( params->status == kIOReturnSuccess &&
		(statusBlock->details & 0x30) == 0 && 	// resp == REQUEST_COMPLETE
		statusBlock->sbpStatus == 0 )			// sbp_status == No additional info
    {
        FWLOG(( "SBP2SampleLoginController : login successful\n" ));
		fLoggedIn = true;
		loginResumed();
    }
    else
    {
		// we just retry a bunch of times if we didn't get good status
		//zzz we could look at the status and determine if there is any chance a retry will succeed
		//zzz may want to check device specific errors as well
		
        FWLOG( ( "SBP2SampleLoginController : login unsuccessful, status = 0x%08x\n", params->status ) );

		if( fPhysicallyConnected )
		{
			if( fLoginRetries > 0 )
			{
				fLoginRetries--;
				(*fSBP2LoginInterface)->submitLogin( fSBP2LoginInterface );
			}
			else
			{
				fNeedLogin = true;
				loginLost();
			}
		}
		else
		{
			fNeedLogin = true;
		}
	}
}
Example #3
0
void IOFireWireSBP2LibLUN::messageCallback( IOReturn result, io_user_reference_t *args, int numArgs )
{
    FWLOG(( "IOFireWireSBP2LibLUN : messageCallback numArgs = %d\n", numArgs ));

    FWSBP2ReconnectParams params;
    void * outArgs = NULL;

    UInt32 type = (UInt32)args[11];
    if( type == kIOMessageFWSBP2ReconnectComplete ||
            type == kIOMessageFWSBP2ReconnectFailed )
    {
        UInt32 statusBlock[8];

        {
            int i;

            for( i = 0; i < 8; i++ )
            {
                IF_ROSETTA()
                {
                    statusBlock[i] = OSSwapInt32( (UInt32)args[3+i] );
                }
                else
                {
                    statusBlock[i] = (UInt32)args[3+i];
                }
            }
        }
void SBP2SampleLoginController::logoutCompletion( FWSBP2LogoutCompleteParams * params )
{
	FWLOG(( "SBP2SampleLoginController : logoutCompletion\n" ));
	
	fLoggedIn = false;
	
	SBP2SampleSBP2LibGlue::logoutCompletion( params );
}
Example #5
0
void *IOFireWireSBP2LibFactory( CFAllocatorRef allocator, CFUUIDRef typeID )
{
    FWLOG(( "IOFireWireSBP2LibFactory called\n" ));

    if( CFEqual(typeID, kIOFireWireSBP2LibTypeID) )
        return (void *) IOFireWireSBP2LibLUN::alloc();
    else
        return NULL;
}
IOReturn IOFireWireSBP2LibORB::setCommandBuffersAsRanges( FWSBP2VirtualRange * ranges, 
										UInt32 withCount, UInt32 withDirection, 
										UInt32 offset, 
										UInt32 length )
{
	IOReturn status = kIOReturnSuccess;
	
	uint32_t len = 0;
	uint64_t params[6];
	
	FWLOG(( "IOFireWireSBP2LibORB : setCommandBuffersAsRanges\n" ));
//	printf( "IOFireWireSBP2LibORB : setCommandBuffersAsRanges\n" );

	//
	// create or grow range scratch
	//
	
	UInt32 range_length = withCount * sizeof(FWSBP2PrivateVirtualRange);
			
	if( fRangeScratchLength < range_length )
	{
		if( fRangeScratch != NULL )
		{
			// delete it
			vm_deallocate( mach_task_self(), (vm_address_t)fRangeScratch, fRangeScratchLength );
			fRangeScratch = NULL;
			fRangeScratchLength = 0;
		}
		
		// alloc a bigger one
		vm_allocate( mach_task_self(), (vm_address_t*)&fRangeScratch, range_length, true /*anywhere*/ );
		if( fRangeScratch != NULL )
		{
			fRangeScratchLength = range_length;
		}
	}

	//
	// fill range scratch
	//
	
	if( fRangeScratch != NULL )
	{
		for( UInt32 i = 0; i < withCount; i++ )
		{
			fRangeScratch[i].address = (uint64_t)ranges[i].address;
			fRangeScratch[i].length = ranges[i].length;

			ROSETTA_ONLY(
				fRangeScratch[i].address = OSSwapInt64( fRangeScratch[i].address );
				fRangeScratch[i].length = OSSwapInt64( fRangeScratch[i].length );
			);
		}
	}
void IOFireWireSBP2LibORB::setToDummy( void )
{
	IOReturn status = kIOReturnSuccess;
	
	FWLOG(( "IOFireWireSBP2LibORB : setToDummy\n" ));
		
	uint32_t len = 0;
	status = IOConnectCallScalarMethod( fConnection, 	
										kIOFWSBP2UserClientSetToDummy, 
										&fORBRef, 1, NULL, &len );
}
Example #8
0
void IOFireWireSBP2LibLUN::close( void )
{
    if( !fConnection )
        return;

    FWLOG(( "IOFireWireSBP2LUN : close\n" ));

    uint32_t len = 0;
    IOConnectCallScalarMethod(	fConnection, kIOFWSBP2UserClientClose,
                                NULL, 0, NULL, &len );

}
Example #9
0
IOReturn IOFireWireSBP2LibLUN::start( CFDictionaryRef propertyTable, io_service_t service )
{
    IOReturn status = kIOReturnSuccess;

    FWLOG(( "IOFireWireSBP2LibLUN : start\n" ));

    fService = service;
    status = IOServiceOpen( fService, mach_task_self(),
                            kIOFireWireSBP2LibConnection, &fConnection );
    if( !fConnection )
        status = kIOReturnNoDevice;

    if( status == kIOReturnSuccess )
    {
        status = IOCreateReceivePort( kOSAsyncCompleteMessageID, &fAsyncPort );
    }

    FWLOG(( "IOFireWireSBP2LibLUN : IOServiceOpen status = 0x%08lx, connection = %d\n", (UInt32) status, fConnection ));

    return status;
}
Example #10
0
IOReturn IOFireWireSBP2LibLUN::addIODispatcherToRunLoop( CFRunLoopRef cfRunLoopRef )
{
    IOReturn 				status = kIOReturnSuccess;

    FWLOG(( "IOFireWireSBP2LibLUN : addIODispatcherToRunLoop\n" ));

    if( !fConnection )
        return kIOReturnNoDevice;

    if( status == kIOReturnSuccess )
    {
        CFMachPortContext context;
        Boolean	shouldFreeInfo; // zzz what's this for?

        context.version = 1;
        context.info = this;
        context.retain = NULL;
        context.release = NULL;
        context.copyDescription = NULL;

        fCFAsyncPort = CFMachPortCreateWithPort( kCFAllocatorDefault, fAsyncPort,
                       (CFMachPortCallBack) IODispatchCalloutFromMessage,
                       &context, &shouldFreeInfo );
        if( !fCFAsyncPort )
            status = kIOReturnNoMemory;
    }

    if( status == kIOReturnSuccess )
    {
        fCFRunLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault, fCFAsyncPort, 0 );
        if( !fCFRunLoopSource )
            status = kIOReturnNoMemory;
    }

    if( status == kIOReturnSuccess )
    {
        fCFRunLoop = cfRunLoopRef;
        CFRunLoopAddSource( fCFRunLoop, fCFRunLoopSource, kCFRunLoopCommonModes );
    }

    if( status == kIOReturnSuccess )
    {
        io_async_ref64_t asyncRef;
        mach_msg_type_number_t	size = 0;

        asyncRef[kIOAsyncCalloutFuncIndex] = (uint64_t)&IOFireWireSBP2LibLUN::staticMessageCallback;
        asyncRef[kIOAsyncCalloutRefconIndex] = (uint64_t)this;

        status = IOConnectCallAsyncScalarMethod( fConnection, kIOFWSBP2UserClientSetMessageCallback, fAsyncPort, asyncRef, kOSAsyncRef64Count, NULL, 0, NULL, &size  );
    }

    return status;
}
void SBP2SampleLoginController::logoutOfDevice( void )
{
	IOReturn status = kIOReturnSuccess;
	
	FWLOG(( "SBP2SampleLoginController : logoutOfDevice\n"));
	
	// allow the driver to unload
    fMaintainLogin = false;

    // we don't want to start logging in if we receive a resume messsage during logout
    fNeedLogin = false;

	FWLOG(( "SBP2SampleLoginController : submitLogout\n" ));

	status = (*fSBP2LoginInterface)->submitLogout(fSBP2LoginInterface);
	//zzz there is a bug in MacOS X 1.0 where we will return kIOReturnBusy when we mean kIOReturnSuccess
	if( status == kIOReturnBusy )
		status = kIOReturnSuccess;

	fLoggedIn = false;  // we do this in the completion too
}
IOFireWireSBP2LibORB::~IOFireWireSBP2LibORB()
{
	if( fORBRef ) 
	{
		IOReturn status = kIOReturnSuccess;
		
		uint32_t len = 0;
		status = IOConnectCallScalarMethod( fConnection, 	
											kIOFWSBP2UserClientReleaseORB, 
											&fORBRef, 1, NULL, &len );
		FWLOG(( "IOFireWireSBP2LibORB : release orb status = 0x%08x\n", status ));
	}
}
Example #13
0
IOReturn IOFireWireSBP2LibLUN::stop( void )
{
    FWLOG(( "IOFireWireSBP2LibLUN : stop\n" ));

    removeIODispatcherFromRunLoop();

    if( fConnection )
    {
        FWLOG(( "IOFireWireSBP2LibLUN : IOServiceClose connection = %d\n", fConnection ));
        IOServiceClose( fConnection );
        fConnection = MACH_PORT_NULL;
    }

    if( fAsyncPort != MACH_PORT_NULL )
    {
        FWLOG(( "IOFireWireSBP2LibLUN : release fAsyncPort\n" ));
        mach_port_destroy( mach_task_self(), fAsyncPort );
        fAsyncPort = MACH_PORT_NULL;
    }

    return kIOReturnSuccess;
}
void IOFireWireSBP2LibORB::setCommandGeneration( UInt32 generation )
{
	FWLOG(( "IOFireWireSBP2LibORB : setCommandGeneration = %ld\n", generation ));
		
	uint32_t len = 0;
	uint64_t params[2];
	
	params[0] = fORBRef;
	params[1] = generation;
	
	IOConnectCallScalarMethod(	fConnection, 	
								kIOFWSBP2UserClientSetCommandGeneration, 
								params, 2, NULL, &len );
}
void IOFireWireSBP2LibORB::setCommandTimeout( UInt32 timeout )
{
	FWLOG(( "IOFireWireSBP2LibORB : setCommandTimeout = %ld\n", timeout ));
		
	uint32_t len = 0;
	uint64_t params[2];
	
	params[0] = fORBRef;
	params[1] = timeout;
	
	IOConnectCallScalarMethod(	fConnection, 	
								kIOFWSBP2UserClientSetCommandTimeout, 
								params, 2, NULL, &len );
}
void IOFireWireSBP2LibORB::setMaxORBPayloadSize( UInt32 size )
{
	FWLOG(( "IOFireWireSBP2LibORB : setMaxORBPayloadSize = %ld\n", size ));
		
	uint32_t len = 0;
	uint64_t params[2];
	
	params[0] = fORBRef;
	params[1] = size;
	
	IOConnectCallScalarMethod( fConnection, 	
									   kIOFWSBP2UserClientSetMaxORBPayloadSize, 
									   params, 2, NULL, &len );
}
void IOFireWireSBP2LibORB::setCommandFlags( UInt32 flags )
{
	FWLOG(( "IOFireWireSBP2LibORB : setCommandFlags = %ld\n", flags ));
		
	uint32_t len = 0;
	uint64_t params[2];
	
	params[0] = fORBRef;
	params[1] = flags;
	
	IOConnectCallScalarMethod(	fConnection, 	
								kIOFWSBP2UserClientSetCommandFlags, 
								params, 2, NULL, &len );
}
Example #18
0
IOReturn IOFireWireSBP2LibLUN::open( void )
{
    IOReturn status = kIOReturnSuccess;

    if( !fConnection )
        return kIOReturnNoDevice;

    FWLOG(( "IOFireWireSBP2LUN : open\n" ));

    uint32_t len = 0;
    status = IOConnectCallScalarMethod( fConnection,
                                        kIOFWSBP2UserClientOpen,
                                        NULL, 0, NULL, &len );
    return status;
}
void SBP2SampleLoginController::loginToDevice( void )
{
	IOReturn status = kIOReturnSuccess;
	
	FWLOG(( "SBP2SampleLoginController : loginToDevice\n"));
	
	//
	// submit login
	//
	
	if( status == kIOReturnSuccess )
	{
		// don't allow driver to unload
		fMaintainLogin = true;

		// when this is set we attempt to login to the device when we recieve a resume message
		// since we are about to login we don't want this to happen
		fNeedLogin = false;
		fLoggedIn = false;
	
		FWLOG(( "SBP2SampleLoginController : submitLogin\n" ));
		
		fLoginRetries = kMaxLoginRetries;
		(*fSBP2LoginInterface)->setLoginFlags( fSBP2LoginInterface, kFWSBP2ExclusiveLogin );
		status = (*fSBP2LoginInterface)->submitLogin(fSBP2LoginInterface);	
		//zzz there is a bug in MacOS X 1.0 where we will return kIOReturnBusy when we mean kIOReturnSuccess
		if( status == kIOReturnBusy )
			status = kIOReturnSuccess;
	}
	
	if( status != kIOReturnSuccess )
	{
		fNeedLogin = true;
		loginSuspended();
	}
}
void IOFireWireSBP2LibORB::setRefCon( void * refCon )
{
	FWLOG(( "IOFireWireSBP2LibORB : setRefCon\n"));

	fRefCon = refCon;

	uint32_t len = 0;
	uint64_t params[2];
	
	params[0] = fORBRef;
	params[1] = (uint64_t)refCon;
	
	IOConnectCallScalarMethod(	fConnection, 	
								kIOFWSBP2UserClientSetORBRefCon, 
								params, 2, NULL, &len );	
}
Example #21
0
IOReturn IOFireWireSBP2LibLUN::openWithSessionRef( IOFireWireSessionRef sessionRef )
{
    IOReturn status = kIOReturnSuccess;

    if( !fConnection )
        return kIOReturnNoDevice;

    FWLOG(( "IOFireWireSBP2LUN : openWithSessionRef\n" ));

    uint32_t len = 0;
    uint64_t session_ref_64 = (uint64_t)sessionRef;
    status = IOConnectCallScalarMethod( fConnection, kIOFWSBP2UserClientOpenWithSessionRef,
                                        &session_ref_64, 1, NULL, &len );

    return status;
}
Example #22
0
void IOFireWireSBP2LibLUN::removeIODispatcherFromRunLoop( void )
{
    if( fCFRunLoopSource != NULL )
    {
        CFRunLoopRemoveSource( fCFRunLoop, fCFRunLoopSource, kCFRunLoopCommonModes );
        CFRelease( fCFRunLoopSource );
        fCFRunLoopSource = NULL;
    }

    if( fCFAsyncPort != NULL )
    {
        FWLOG(( "IOFireWireSBP2LibLUN : release fCFAsyncPort\n" ));
        CFMachPortInvalidate( fCFAsyncPort );
        CFRelease( fCFAsyncPort );
        fCFAsyncPort = NULL;
    }
}
Example #23
0
IOFireWireSessionRef IOFireWireSBP2LibLUN::getSessionRef( void )
{
    IOReturn status = kIOReturnSuccess;
    uint64_t sessionRef = 0;

    if( !fConnection )
        return (IOFireWireSessionRef)sessionRef;

    FWLOG(( "IOFireWireSBP2LUN : getSessionRef\n" ));

    uint32_t len = 1;
    status = IOConnectCallScalarMethod( fConnection, kIOFWSBP2UserClientGetSessionRef,
                                        NULL, 0, &sessionRef, &len );

    if( status != kIOReturnSuccess )
        sessionRef = 0; // just to make sure

    return (IOFireWireSessionRef)sessionRef;
}
void SBP2SampleLoginController::message( UInt32 type, void * arg )
{
	FWLOG(( "SBP2SampleLoginController : message type = 0x%08lx\n", type ));
	
    FWSBP2ReconnectParams * params;

    // arg and any pointers in it are only valid until this function returns
    // do not modify and data in the reconnectStatusBlock

	switch (type)
	{
		case kIOMessageServiceIsSuspended:
			
			// a bus reset occured
			FWLOG( ( "SBP2SampleLoginController : kIOMessageServiceIsSuspended\n" ) );
		
			fPhysicallyConnected = false;
		
			if( fLoggedIn )
			{
				fLoggedIn = false;
				loginSuspended();				
			}
			
			break;

		case kIOMessageServiceIsResumed:
			
			// we have processed the self-ids and rediscovered this device
			FWLOG( ( "SBP2SampleLoginController : kIOMessageServiceIsResumed\n" ) );

			fPhysicallyConnected = true;
			
			if( fNeedLogin )
			{
				fNeedLogin = false;
				fLoginRetries = kMaxLoginRetries;
				(*fSBP2LoginInterface)->submitLogin(fSBP2LoginInterface);
			}
			
			break;

		case kIOMessageFWSBP2ReconnectComplete:
			// we reconnected sucessfully to this device
			// status block is supplied in params->statusBlock for further status
			params = (FWSBP2ReconnectParams*)arg;
			fLoggedIn = true;
			FWLOG(( "SBP2SampleORBTransport : kIOMessageFWSBP2ReconnectComplete\n" ));
			
			loginResumed();
			
			break;

		case kIOMessageFWSBP2ReconnectFailed:
			FWLOG(( "SBP2SampleORBTransport : kIOMessageFWSBP2ReconnectFailed\n" ));
			
			// we did not reconnect successfully to this device
		
			// check params->status for error
			// if params->statusBlock != NULL, the status block was received; check for further status

			if( fPhysicallyConnected )
			{
				fLoginRetries = kMaxLoginRetries;
				
				//zzz could decide if this has any chance of success from returned status
				(*fSBP2LoginInterface)->submitLogin(fSBP2LoginInterface);
			}
			else
			{
				fNeedLogin = true;
			}
				
			params = (FWSBP2ReconnectParams*)arg;

			
			break;
						
		case kIOMessageServiceIsRequestingClose:
			// we have processsed the self-ids and did not rediscover this device
			FWLOG( ( "SBP2SampleORBTransport : kIOMessageServiceIsRequestingClose\n" ));
			
			// firewire is requesting to close this driver, calling close on the provider here
			// results in terminiation
			
			loginLost();
			
			break;

		case kIOMessageServiceIsTerminated:
			// the driver has been terminated
			FWLOG( ( "SBP2SampleORBTransport : kIOMessageServiceIsTerminated\n" ) );
			break;

		default:
			break;
	}
 }