Code:
#include "hbainfo.h"
int DEBUG = 0;
void WWN2Cstring(char *dst, HBA_WWN *WWN) {
/*
============================================================================
Name : WWN2Cstring
Description: transform the WWN into a colon separated string.
Notes :
Input : (1) pointer to destination buffer
: (2) pointer to wwn structure
============================================================================
*/
snprintf( dst, 24, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
WWN->wwn[0], WWN->wwn[1], WWN->wwn[2], WWN->wwn[3],
WWN->wwn[4], WWN->wwn[5], WWN->wwn[6], WWN->wwn[7] );
}
void WWN2string(char *dst, HBA_WWN *WWN) {
/*
============================================================================
Name : WWN2string
Description: transform the WWN into a standard string.
Notes :
Input : (1) pointer to destination buffer
: (2) pointer to wwn structure
============================================================================
*/
snprintf( dst, 24, "%02x%02x%02x%02x%02x%02x%02x%02x",
WWN->wwn[0], WWN->wwn[1], WWN->wwn[2], WWN->wwn[3],
WWN->wwn[4], WWN->wwn[5], WWN->wwn[6], WWN->wwn[7] );
}
char *squeeze(char *str) {
/*
============================================================================
Name : squeeze
Description: replace double whitespace and control characters with a single
space.
============================================================================
*/
int r = 0, w = 0;
while (str[r]) {
if (isspace((int)str[r]) || iscntrl((int)str[r])) {
if (w > 0 && !isspace((int)str[w-1])) { str[w++] = ' '; }
} else {
str[w++] = str[r];
}
r++;
}
str[w] = '\0';
return ( str );
}
void hba_status_check ( HBA_STATUS status, char *msg ){
/*
============================================================================
Name : hba_status_check
Description: print the common HBA return status.
Notes : It is not the responsibily of this function to set or change
: the return value in any way--just display what happened.
Input : (1) HBA status return code
: (2) Calling function message
============================================================================
*/
switch ( status ) {
case HBA_STATUS_OK:
( void )fprintf( stderr, "debug: [%s]: successful\n", msg );
break;
case HBA_STATUS_ERROR:
( void )fprintf( stderr, "debug: [%s]: unspecified error occurred that prevented the retrieval of the HBA information\n", msg );
break;
case HBA_STATUS_ERROR_NOT_SUPPORTED:
( void )fprintf( stderr, "debug: [%s]: Function not supported\n", msg );
break;
case HBA_STATUS_ERROR_INVALID_HANDLE:
( void )fprintf( stderr, "debug: [%s]: Invalid handle\n", msg );
break;
case HBA_STATUS_ERROR_ARG:
( void )fprintf( stderr, "debug: [%s]: Bad argument\n", msg );
break;
case HBA_STATUS_ERROR_ILLEGAL_WWN:
( void )fprintf( stderr, "debug: [%s]: Worldwide name not recognized\n", msg );
break;
case HBA_STATUS_ERROR_ILLEGAL_INDEX:
( void )fprintf( stderr, "debug: [%s]: Index not recognized\n", msg );
break;
case HBA_STATUS_ERROR_MORE_DATA:
( void )fprintf( stderr, "debug: [%s]: Larger buffer required.\n", msg );
break;
case HBA_STATUS_ERROR_STALE_DATA:
( void )fprintf( stderr, "debug: [%s]: Information has changed since the last refresh operation\n", msg );
break;
case HBA_STATUS_SCSI_CHECK_CONDITION:
( void )fprintf( stderr, "debug: [%s]: SCSI Check Condition reported\n", msg );
break;
case HBA_STATUS_ERROR_BUSY:
( void )fprintf( stderr, "debug: [%s]: Adapter busy or reserved, retry might be required\n", msg );
break;
case HBA_STATUS_ERROR_TRY_AGAIN:
( void )fprintf( stderr, "debug: [%s]: Request timed out, retry might be required\n", msg );
break;
case HBA_STATUS_ERROR_UNAVAILABLE:
( void )fprintf( stderr, "debug: [%s]: Referenced HBA has been removed or deactivated\n", msg );
break;
case HBA_STATUS_ERROR_ELS_REJECT:
( void )fprintf( stderr, "debug: [%s]: The requested ELS was rejected by the local adapter\n", msg );
break;
case HBA_STATUS_ERROR_INVALID_LUN:
( void )fprintf( stderr, "debug: [%s]: The specified LUN is not provided by the specified adapter\n", msg );
break;
case HBA_STATUS_ERROR_INCOMPATIBLE:
( void )fprintf( stderr, "debug: [%s]: An incompatibility has been detected\n", msg );
break;
case HBA_STATUS_ERROR_AMBIGUOUS_WWN:
( void )fprintf( stderr, "debug: [%s]: Multiple adapters have a matching worldwide name (WWN)\n", msg );
break;
case HBA_STATUS_ERROR_LOCAL_BUS:
( void )fprintf( stderr, "debug: [%s]: A persistent binding request included a bad local SCSI bus number\n", msg );
break;
case HBA_STATUS_ERROR_LOCAL_TARGET:
( void )fprintf( stderr, "debug: [%s]: A persistent binding request included a bad local SCSI target number\n", msg );
break;
case HBA_STATUS_ERROR_LOCAL_LUN:
( void )fprintf( stderr, "debug: [%s]: A persistent binding request included a bad local SCSI LUN\n", msg );
break;
case HBA_STATUS_ERROR_LOCAL_SCSIID_BOUND:
( void )fprintf( stderr, "debug: [%s]: A persistent binding set request included a local SCSI ID that was already bound\n", msg );
break;
case HBA_STATUS_ERROR_TARGET_FCID:
( void )fprintf( stderr, "debug: [%s]: A persistent binding request included an invalid FCP target FCID\n", msg );
break;
case HBA_STATUS_ERROR_TARGET_NODE_WWN:
( void )fprintf( stderr, "debug: [%s]: A persistent binding request included a bad FCP target node WWN\n", msg );
break;
case HBA_STATUS_ERROR_TARGET_PORT_WWN:
( void )fprintf( stderr, "debug: [%s]: A persistent binding request included a bad FCP target port WWN\n", msg );
break;
case HBA_STATUS_ERROR_TARGET_LUN:
( void )fprintf( stderr, "debug: [%s]: A persistent binding request included an FCP LUN that the target does not recognize\n", msg );
break;
case HBA_STATUS_ERROR_TARGET_LUID:
( void )fprintf( stderr, "debug: [%s]: A persistent binding request contained an undefined or otherwise inaccessible logical unit unique identifier\n", msg );
break;
case HBA_STATUS_ERROR_NO_SUCH_BINDING:
( void )fprintf( stderr, "debug: [%s]: A persistent binding remove request contained a binding which did not match a binding established by the specified port\n", msg );
break;
case HBA_STATUS_ERROR_NOT_A_TARGET:
( void )fprintf( stderr, "debug: [%s]: A SCSI command was sent to an Nx_Port that was not a SCSI target port\n", msg );
break;
case HBA_STATUS_ERROR_UNSUPPORTED_FC4:
( void )fprintf( stderr, "debug: [%s]: A request was made concerning an unsupported FC-4 protocol\n", msg );
break;
case HBA_STATUS_ERROR_INCAPABLE:
( void )fprintf( stderr, "debug: [%s]: A request was made to enable unimplemented capabilities for a port\n", msg );
break;
case HBA_STATUS_ERROR_TARGET_BUSY:
( void )fprintf( stderr, "debug: [%s]: Executing the requested SCSI command would cause a SCSI overlapped command condition\n", msg );
break;
default:
( void )fprintf( stderr, "debug: [%s]: unknown status code: %d\n", msg, status );
break;
}
}
void hba_fcp_target_mapping_status_check ( HBA_STATUS status, char *msg ) {
/*
============================================================================
Name : hba_fcp_target_mapping_status_check
Description: print the fiber channel port mappings return status.
Notes : It is not the responsibily of this function to set or change
: the return value in any way--just display what happened.
Input : (1) HBA status return code
: (2) Calling function message
============================================================================
*/
switch ( status ) {
case HBA_STATUS_OK:
( void )fprintf( stderr, "debug: [%s]: successful\n", msg );
break;
case HBA_STATUS_ERROR_MORE_DATA:
( void )fprintf( stderr, "debug: [%s]: buffer space is insufficient to hold all of the target mappings\n", msg );
break;
case HBA_STATUS_ERROR_ILLEGAL_WWN: /* V2 Only */
( void )fprintf( stderr, "debug: [%s]: HBA referenced by HBA Handle does not contain a port with a name of hbaPortWWN\n", msg );
break;
case HBA_STATUS_ERROR_NOT_SUPPORTED: /* V2 Only */
( void )fprintf( stderr, "debug: [%s]: HBA referenced by HbaHandle does not support target mapping\n", msg );
break;
case HBA_STATUS_ERROR:
( void )fprintf( stderr, "debug: [%s]: unspecified error occurred that prevented the retrieval of the mapping information\n", msg );
break;
default:
( void )fprintf( stderr, "debug: [%s]: unknown status code: %d\n", msg, status );
break;
}
}
int hba_load_library( void ) {
/*
============================================================================
Name : hba_load_library
Description: load (open) the hba library.
Notes :
Input : void
============================================================================
*/
HBA_STATUS status;
status = HBA_LoadLibrary();
if ( DEBUG ) { hba_status_check( status, "HBA_LoadLibrary" ); }
return ( status == HBA_STATUS_OK ) ? 0 : -1;
}
int hba_free_library( void ) {
/*
============================================================================
Name : hba_free_library
Description: free (unload) the hba library
Notes :
Input : void
============================================================================
*/
HBA_STATUS status;
status = HBA_FreeLibrary();
if ( DEBUG ) hba_status_check( status, "HBA_FreeLibrary" );
return ( status == HBA_STATUS_OK ) ? 0 : -1;
}
HBA_UINT32 hba_get_number_of_adapters( void ) {
/*
============================================================================
Name : hba_get_number_of_adapters
Description: get the number of adapters
Notes :
Input : void
============================================================================
*/
return ( HBA_GetNumberOfAdapters() );
}
int hba_get_adapter_name(int adapter_number, char *adapter_name) {
/*
============================================================================
Name : hba_get_adapter_name
Description: get the HBA adapter name
Notes :
Input : (1) current adapter number
: (2) pointer to adapter name
============================================================================
*/
HBA_STATUS status;
status = HBA_GetAdapterName( adapter_number, adapter_name );
if ( DEBUG ) { hba_status_check( status, "HBA_GetAdapterName" ); }
if ( ( status != HBA_STATUS_OK ) ||
( strlen(adapter_name) == 0 ) ) {
if ( DEBUG )
( void )fprintf( stderr, "debug: failed HBA_GetAdapterName for adapter number %d\n", adapter_number );
return ( -1 );
}
return ( 0 );
}
HBA_HANDLE hba_open_adapter(char *adapter_name) {
/*
============================================================================
Name : hba_open_adapter
Description: open an HBA adapter
Notes : If successful, the HBA_OpenAdapter subroutine returns an
HBA_HANDLE with a value greater than 0. If unsuccessful,
the subroutine returns a 0.
Input : (1) pointer to current adapter name.
============================================================================
*/
HBA_HANDLE adapter_handle = HBA_OpenAdapter( adapter_name );
if ( ( adapter_handle == HBA_HANDLE_INVALID ) && ( DEBUG ) )
( void )fprintf( stderr, "debug: [HBA_OpenAdapter]: failed HBA_OpenAdapter for adapter %s\n", adapter_name );
return ( adapter_handle );
}
void hba_close_adapter(HBA_HANDLE adapter_handle) {
/*
============================================================================
Name : hba_close_adapter
Description: close an open adapter handle
Notes :
Input : (1) open (non-zero) adapter handle
============================================================================
*/
if ( adapter_handle != HBA_HANDLE_INVALID )
HBA_CloseAdapter( adapter_handle );
}
int hba_print_adapter_attributes(char *adapter_name, HBA_HANDLE adapter_handle, HBA_UINT32 hba) {
/*
============================================================================
Name : hba_print_adapter_attributes
Description: print the HBA adapter attributes
Notes : this function uses alloca--never use free against an alloca.
: remember that alloca allocates to the stack and is automatically
: cleaned at program termination.
Input : (1) pointer to adapter name
: (2) open adapter handle
: (3) current hba number
============================================================================
*/
HBA_STATUS status;
/* initialize the adapter attributes structure */
HBA_ADAPTERATTRIBUTES adapter_attributes;
memset( &adapter_attributes, 0, sizeof( HBA_ADAPTERATTRIBUTES ) );
status = HBA_GetAdapterAttributes( adapter_handle, &adapter_attributes );
if ( DEBUG ) { hba_status_check( status, "HBA_GetAdapterAttributes" ); }
if ( status != HBA_STATUS_OK ) { return ( -1 ); }
char *wwn = ( char * )alloca( WWN_SIZE );
if ( wwn == NULL ) {
if ( DEBUG )
( void )fprintf( stderr, "debug: failed to allocate memory for WWN\n" );
hba_close_adapter( adapter_handle );
hba_free_library();
exit ( EX_OSERR );
}
WWN2Cstring( wwn, &adapter_attributes.NodeWWN );
/* Print the results */
( void )fprintf( stdout, "%s\n", REC_SEP );
( void )fprintf( stdout, "hba.%d.Name = %s\n", hba, adapter_name );
( void )fprintf( stdout, "hba.%d.Manufacturer = %s\n", hba,
( strlen(adapter_attributes.Manufacturer) == 0 )
? NO_SUPP : adapter_attributes.Manufacturer );
( void )fprintf( stdout, "hba.%d.SerialNumber = %s\n", hba,
( strlen( adapter_attributes.SerialNumber ) == 0 )
? NO_SUPP : adapter_attributes.SerialNumber );
( void )fprintf( stdout, "hba.%d.Model = %s\n", hba,
( strlen(adapter_attributes.Model) == 0 )
? NO_SUPP : adapter_attributes.Model );
( void )fprintf( stdout, "hba.%d.Description = %s\n", hba,
( strlen(adapter_attributes.ModelDescription) == 0 )
? NO_SUPP : adapter_attributes.ModelDescription );
( void )fprintf( stdout, "hba.%d.SymbolicName = %s\n", hba,
( strlen(adapter_attributes.NodeSymbolicName) == 0 )
? NO_SUPP : adapter_attributes.NodeSymbolicName );
( void )fprintf( stdout, "hba.%d.HardwareVersion = %s\n", hba,
( strlen(adapter_attributes.HardwareVersion) == 0 )
? NO_SUPP : adapter_attributes.HardwareVersion );
( void )fprintf( stdout, "hba.%d.DriverVersion = %s\n", hba,
( strlen(adapter_attributes.DriverVersion) == 0 )
? NO_SUPP : adapter_attributes.DriverVersion );
( void )fprintf( stdout, "hba.%d.OptionROMVersion = %s\n", hba,
( strlen(adapter_attributes.OptionROMVersion) == 0 )
? NO_SUPP : adapter_attributes.OptionROMVersion );
( void )fprintf( stdout, "hba.%d.FirmwareVersion = %s\n", hba,
( strlen(adapter_attributes.FirmwareVersion) == 0 )
? NO_SUPP : adapter_attributes.FirmwareVersion );
( void )fprintf( stdout, "hba.%d.DriverName = %s\n", hba,
( strlen(adapter_attributes.DriverName) == 0 )
? NO_SUPP : adapter_attributes.DriverName );
( void )fprintf( stdout, "hba.%d.NumberOfPorts = %d\n", hba,
adapter_attributes.NumberOfPorts );
( void )fprintf( stdout, "hba.%d.NodeWWN = %s\n", hba,
( strlen(wwn) == 0 ) ? NO_SUPP : wwn );
/* Clean-up and Return */
return ( 0 );
}
void hba_print_port_speed ( HBA_UINT32 hba, HBA_UINT32 port, HBA_UINT32 speed ) {
if ( DEBUG ){ ( void )fprintf( stderr, "debug: [PortSpeed]: port_attributes.PortSpeed value: %d\n", speed ); }
switch( speed ) {
case HBA_PORTSPEED_UNKNOWN:
( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "UNKNOWN" );
break;
case HBA_PORTSPEED_1GBIT:
( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "1 Gigabit" );
break;
case HBA_PORTSPEED_2GBIT:
( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "2 Gigabit" );
break;
case HBA_PORTSPEED_4GBIT:
( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "4 Gigabit" );
break;
case HBA_PORTSPEED_8GBIT:
( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "8 Gigabit" );
break;
case HBA_PORTSPEED_10GBIT:
( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "10 Gigabit" );
break;
case HBA_PORTSPEED_NOT_NEGOTIATED:
( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "Not Negotiated" );
break;
default:
( void )fprintf( stdout, "hba.%d.port.%d.PortSpeed = %s\n", hba, port, "ERROR" );
break;
}
}
int hba_print_port_attributes(char *adapter_name, HBA_HANDLE adapter_handle, HBA_UINT32 hba) {
/*
============================================================================
Name : hba_print_port_attributes
Description: print the HBA port attributes.
Notes : this function uses alloca--never use free against an alloca.
: remember that alloca allocates to the stack and is automatically
: cleaned at program termination.
Input : (1) pointer to adapter name
: (2) open adapter handle
: (3) current hba number
============================================================================
*/
HBA_STATUS status;
/* initialize the adapter attributes structure */
HBA_ADAPTERATTRIBUTES adapter_attributes;
memset( &adapter_attributes, 0, sizeof( HBA_ADAPTERATTRIBUTES ) );
/* get the adapter attributes */
status = HBA_GetAdapterAttributes( adapter_handle, &adapter_attributes );
if ( DEBUG ) { hba_status_check( status, "HBA_GetAdapterAttributes" ); }
if ( status != HBA_STATUS_OK ) { return ( -1 ); }
HBA_UINT32 port;
HBA_PORTATTRIBUTES port_attributes;
memset(&port_attributes, 0, sizeof(HBA_PORTATTRIBUTES));
char *fwwn = ( char * )alloca( WWN_SIZE );
char *nwwn = ( char * )alloca( WWN_SIZE );
char *pwwn = ( char * )alloca( WWN_SIZE );
if ( ( fwwn == NULL ) || ( pwwn == NULL ) || ( nwwn == NULL ) ) {
if ( DEBUG )
( void )fprintf( stderr, "debug: failed to allocate memory for WWN\n" );
hba_close_adapter( adapter_handle );
hba_free_library();
exit ( EX_OSERR );
}
for ( port = 0; port < adapter_attributes.NumberOfPorts; port++ ) {
status = HBA_GetAdapterPortAttributes( adapter_handle, port, &port_attributes );
if ( DEBUG ) { hba_status_check( status, "HBA_GetAdapterPortAttributes" ); }
if ( status != HBA_STATUS_OK ) { continue; }
WWN2Cstring( fwwn, &port_attributes.FabricName );
WWN2Cstring( nwwn, &port_attributes.NodeWWN );
WWN2Cstring( pwwn, &port_attributes.PortWWN );
( void )fprintf( stdout, "hba.%d.port.%d.FabricName = %s\n", hba, port, fwwn );
( void )fprintf( stdout, "hba.%d.port.%d.NodeWWN = %s\n", hba, port, nwwn );
( void )fprintf( stdout, "hba.%d.port.%d.PortWWN = %s\n", hba, port, pwwn );
hba_print_port_speed( hba, port, port_attributes.PortSpeed );
}
/* Clean-up and Return */
return ( 0 );
}
int hba_print_fcp_target_mapping(char *adapter_name, HBA_HANDLE adapter_handle, HBA_UINT32 hba){
/*
============================================================================
Name : hba_print_fcp_target_mapping
Description: print the fiber channel port mappings.
Notes : this function uses malloc and free.
: this function uses alloca--never use free against an alloca.
: remember that alloca allocates to the stack and is automatically
: cleaned at program termination.
Input : (1) pointer to adapter name
: (2) open adapter handle
: (3) current hba number
============================================================================
*/
HBA_STATUS status;
/* initialize the target map(s) structures */
HBA_FCPTARGETMAPPING fcp_target_map;
PHBA_FCPTARGETMAPPING fcp_target_maps;
memset( &fcp_target_map, 0, sizeof( HBA_FCPTARGETMAPPING ) );
char *pwwn = ( char * )alloca( WWN_SIZE );
char *nwwn = ( char * )alloca( WWN_SIZE );
if ( ( pwwn == NULL ) || ( nwwn == NULL ) ) {
if ( DEBUG )
( void )fprintf( stderr, "debug: failed to allocate memory for WWN\n" );
hba_close_adapter( adapter_handle );
hba_free_library();
exit ( EX_OSERR );
}
fcp_target_map.NumberOfEntries = 1;
status = HBA_GetFcpTargetMapping( adapter_handle, &fcp_target_map );
if ( DEBUG ) { hba_fcp_target_mapping_status_check( status, "HBA_GetFcpTargetMapping" ); }
if ( status == HBA_STATUS_ERROR_MORE_DATA ) {
/* there are more entries, allocate memory and get the data */
if ( fcp_target_map.NumberOfEntries > 0 ) {
HBA_UINT32 mapsize = fcp_target_map.NumberOfEntries;
fcp_target_maps = ( PHBA_FCPTARGETMAPPING )malloc( ( mapsize ) * sizeof( HBA_FCPTARGETMAPPING ) );
if (fcp_target_maps) {
memset( fcp_target_maps, 0, ( mapsize )*sizeof( HBA_FCPTARGETMAPPING ) );
fcp_target_maps->NumberOfEntries = mapsize;
status = HBA_GetFcpTargetMapping( adapter_handle, fcp_target_maps );
if ( DEBUG ) { hba_fcp_target_mapping_status_check( status, "HBA_GetFcpTargetMapping" ); }
if ( status != HBA_STATUS_OK ) {
if ( fcp_target_maps != NULL ) { free( fcp_target_maps ); fcp_target_maps = NULL; }
return ( -1 );
}
( void )fprintf( stdout, "hba.%d.NumberOfLUNs = %d\n", hba, fcp_target_maps->NumberOfEntries );
int lun;
for ( lun = 0; lun < fcp_target_maps->NumberOfEntries; lun++ ) {
/* Display the information */
WWN2Cstring( pwwn, &fcp_target_maps->entry[lun].FcpId.PortWWN );
WWN2Cstring( nwwn, &fcp_target_maps->entry[lun].FcpId.NodeWWN );
( void )fprintf( stdout, "hba.%d.lun_mapping.NodeWWN.%s.PortWWN.%s.BusNumber.%d.TargetNumber.%d.OSLun.%d.OSDeviceName.%s\n",
hba, nwwn, pwwn,
fcp_target_maps->entry[lun].ScsiId.ScsiBusNumber,
fcp_target_maps->entry[lun].ScsiId.ScsiTargetNumber,
fcp_target_maps->entry[lun].ScsiId.ScsiOSLun,
( strlen( fcp_target_maps->entry[lun].ScsiId.OSDeviceName ) > 0 )
? fcp_target_maps->entry[lun].ScsiId.OSDeviceName : NO_SUPP );
}
} else {
/* memory allocation failed. clean-up and exit */
if ( DEBUG )
( void )fprintf( stderr, "debug: failed to allocate memory for PHBA_FCPTARGETMAPPING\n" );
if( fcp_target_maps != NULL ) { free(fcp_target_maps); fcp_target_maps = NULL; }
hba_close_adapter( adapter_handle );
hba_free_library();
exit (EX_OSERR);
}
/* we have no entries. clean-up what has been allocated */
if ( fcp_target_maps != NULL ) { free( fcp_target_maps ); fcp_target_maps = NULL; }
}
} else {
/* there are either no adapters or we have an error */
if ( status != HBA_STATUS_OK ) {
if ( DEBUG ) { hba_fcp_target_mapping_status_check( status, "HBA_GetFcpTargetMapping" ); }
return ( -1 );
}
( void )fprintf( stdout, "hba.%d.NumberOfLUNs = %d\n", hba, fcp_target_map.NumberOfEntries );
}
/* Clean-up and Return */
return ( 0 );
}
void get_systopo_hbainfo(int debug) {
/*
============================================================================
Name : get_systopo_hbainfo
Description: obtain and print the requested HBA information.
Notes : this function uses alloca--never use free against an alloca.
: remember that alloca allocates to the stack and is automatically
: cleaned at program termination.
Input : (1) integer value for debug (0 = off, 1 = on)
============================================================================
*/
DEBUG = debug;
if ( (hba_load_library()) == -1 ) { exit ( EX_UNAVAILABLE ); }
HBA_UINT32 adapter_count = hba_get_number_of_adapters();
( void )fprintf( stdout, "hba.total.count = %d\n", adapter_count );
HBA_STATUS status;
HBA_UINT32 hba;
HBA_HANDLE adapter_handle = 0;
for ( hba = 0; hba < adapter_count; hba++ ) {
/* Allocate and Initialize the adapter name */
char *adapter_name = ( char * )alloca( MAX_HBA_NAME );
if ( adapter_name == NULL ) {
if ( DEBUG )
( void )fprintf( stderr, "debug: failed to allocate memory for adapter_name\n" );
if ( adapter_handle > 0 ) { hba_close_adapter(adapter_handle); }
hba_free_library();
exit ( EX_OSERR );
}
/* Get the current hba adapter name */
if ( ( status = hba_get_adapter_name( hba, adapter_name ) ) == -1 ){ continue; }
/* Close existing adapter handle before opening a new one */
if ( adapter_handle != HBA_HANDLE_INVALID ) { hba_close_adapter( adapter_handle ); }
HBA_HANDLE adapter_handle = hba_open_adapter( adapter_name );
if ( adapter_handle == HBA_HANDLE_INVALID ) { continue; }
/* Get and print the HBA information */
if ( ( status = hba_print_adapter_attributes(adapter_name, adapter_handle, hba ) ) == -1 ){ continue; }
if ( ( status = hba_print_port_attributes(adapter_name, adapter_handle, hba ) ) == -1 ){ continue; }
if ( ( status = hba_print_fcp_target_mapping(adapter_name, adapter_handle, hba ) ) == -1 ){ continue; }
}
/* Clean-up and Return */
if ( adapter_handle != HBA_HANDLE_INVALID ) { hba_close_adapter( adapter_handle ); }
hba_free_library();
}