#include "Probing.h"
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
#include <IOKit/scsi/SCSITask.h>
#define DEBUG 0
#define DEBUG_ASSERT_COMPONENT_NAME_STRING "Probing"
#if DEBUG
#define DEBUG_ASSERT_MESSAGE(componentNameString, \
assertionString, \
exceptionLabelString, \
errorString, \
fileName, \
lineNumber, \
errorCode) \
DebugAssert(componentNameString, \
assertionString, \
exceptionLabelString, \
errorString, \
fileName, \
lineNumber, \
errorCode) \
static void
DebugAssert ( const char * componentNameString,
const char * assertionString,
const char * exceptionLabelString,
const char * errorString,
const char * fileName,
long lineNumber,
int errorCode )
{
if ( ( assertionString != NULL ) && ( *assertionString != '\0' ) )
printf ( "Assertion failed: %s: %s\n", componentNameString, assertionString );
else
printf ( "Check failed: %s:\n", componentNameString );
if ( exceptionLabelString != NULL )
printf ( " %s\n", exceptionLabelString );
if ( errorString != NULL )
printf ( " %s\n", errorString );
if ( fileName != NULL )
printf ( " file: %s\n", fileName );
if ( lineNumber != 0 )
printf ( " line: %ld\n", lineNumber );
if ( errorCode != 0 )
printf ( " error: %d\n", errorCode );
}
#endif
#include <AssertMacros.h>
#define kIOSCSIParallelInterfaceControllerClassString "IOSCSIParallelInterfaceController"
static IOReturn
ReprobeTargetDevice ( io_service_t controller, SCSITargetIdentifier targetID );
IOReturn
ReprobeDomainTarget ( UInt64 domainID,
SCSITargetIdentifier targetID )
{
IOReturn result = kIOReturnSuccess;
io_service_t service = MACH_PORT_NULL;
io_iterator_t iterator = MACH_PORT_NULL;
boolean_t found = false;
result = IOServiceGetMatchingServices ( kIOMasterPortDefault,
IOServiceMatching ( kIOSCSIParallelInterfaceControllerClassString ),
&iterator );
require ( ( result == kIOReturnSuccess ), ErrorExit );
service = IOIteratorNext ( iterator );
while ( service != MACH_PORT_NULL )
{
if ( found == false )
{
CFMutableDictionaryRef deviceDict = NULL;
CFDictionaryRef subDict = NULL;
result = IORegistryEntryCreateCFProperties ( service,
&deviceDict,
kCFAllocatorDefault,
0 );
subDict = ( CFDictionaryRef ) CFDictionaryGetValue ( deviceDict, CFSTR ( kIOPropertyProtocolCharacteristicsKey ) );
if ( subDict != NULL )
{
CFNumberRef deviceDomainIDRef = 0;
deviceDomainIDRef = ( CFNumberRef ) CFDictionaryGetValue ( subDict, CFSTR ( kIOPropertySCSIDomainIdentifierKey ) );
if ( deviceDomainIDRef != 0 )
{
UInt64 deviceDomainID = 0;
if ( CFNumberGetValue ( deviceDomainIDRef, kCFNumberLongLongType, &deviceDomainID ) )
{
if ( domainID == deviceDomainID )
{
result = ReprobeTargetDevice ( service, targetID );
found = true;
}
}
}
}
if ( deviceDict != NULL )
CFRelease ( deviceDict );
}
IOObjectRelease ( service );
service = IOIteratorNext ( iterator );
}
IOObjectRelease ( iterator );
iterator = MACH_PORT_NULL;
if ( found == false )
result = kIOReturnNoDevice;
ErrorExit:
return result;
}
static IOReturn
ReprobeTargetDevice ( io_service_t controller, SCSITargetIdentifier targetID )
{
IOReturn result = kIOReturnSuccess;
io_iterator_t childIter = MACH_PORT_NULL;
io_service_t service = MACH_PORT_NULL;
boolean_t found = false;
result = IORegistryEntryGetChildIterator ( controller, kIOServicePlane, &childIter );
require ( ( result == kIOReturnSuccess ), ErrorExit );
service = IOIteratorNext ( childIter );
while ( service != MACH_PORT_NULL )
{
if ( found == false )
{
CFMutableDictionaryRef deviceDict = NULL;
CFDictionaryRef subDict = NULL;
result = IORegistryEntryCreateCFProperties ( service,
&deviceDict,
kCFAllocatorDefault,
0 );
subDict = ( CFDictionaryRef ) CFDictionaryGetValue ( deviceDict, CFSTR ( kIOPropertyProtocolCharacteristicsKey ) );
if ( subDict != NULL )
{
CFNumberRef deviceTargetIDRef = 0;
deviceTargetIDRef = ( CFNumberRef ) CFDictionaryGetValue ( subDict, CFSTR ( kIOPropertySCSITargetIdentifierKey ) );
if ( deviceTargetIDRef != 0 )
{
UInt64 deviceTargetID = 0;
if ( CFNumberGetValue ( deviceTargetIDRef, kCFNumberLongLongType, &deviceTargetID ) )
{
if ( targetID == deviceTargetID )
{
result = IOServiceRequestProbe ( service, 0 );
found = true;
}
}
}
}
if ( deviceDict != NULL )
CFRelease ( deviceDict );
}
IOObjectRelease ( service );
service = IOIteratorNext ( childIter );
}
IOObjectRelease ( childIter );
childIter = MACH_PORT_NULL;
if ( found == false )
result = kIOReturnNoDevice;
ErrorExit:
return result;
}