/*
* ************************************************************************
* Description
* HBAAPILIB.c - Implements a sample common (wrapper) HBA API library
*
* License:
* The contents of this file are subject to the SNIA Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is SNIA HBA API Wrapper Library
*
* The Initial Developer of the Original Code is:
* Benjamin F. Kuo, Troika Networks, Inc. (benk@troikanetworks.com)
*
* Contributor(s):
* Tuan Lam, QLogic Corp. (t_lam@qlc.com)
* Dan Willie, Emulex Corp. (Dan.Willie@emulex.com)
* Dixon Hutchinson, Legato Systems, Inc. (dhutchin@legato.com)
* David Dillard, VERITAS Software Corp. (david.dillard@veritas.com)
*
* ************************************************************************
*
* Adding on SM-HBA support
*
* The implementation includes Three different categories functions to support
* both HBAAPI and SM-HBA through the same library.
*
* SM-HBA unique interface:
* 1. CHECKLIBRARYANDVERSION(SMHBA) : match SMHBA VSL
* Or checking specifically if version is SMHBA beforehand.
* 2. resolved to ftable.smhbafunctiontable.{interface}
* HBAAPIV2 unique functions
* 1. CHECKLIBRARYANDVERSION(HBAAPIV2) : validate and match HBAAPI V2 VSL.
* Or checking specifically if version is HBAAPIV2 beforehand.
* 2. resolved to ftable.functiontable.{interface}
* Common interface between SM-HBA and HBAAPIV2.
* 1. CHECKLIBRARY() : to validate the VSL.
* 2. FUNCCOMMON macro to map the appropriate entry point table
* (union ftable).
* 3. If the interface is not supported by HBAAPI(Version 1)
* the funtiion ptr will be set to NULL.
* Common interface between HBAAPI and HBAAPIV2.
* 1. Check if version is not SMHBA).
* 2. ftable.functiontalbe.(interface)
*
* ************************************************************************
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifdef WIN32
#include <windows.h>
#include <string.h>
/*
* Next define forces entry points in the dll to be exported
* See hbaapi.h to see what it does.
*/
#define HBAAPI_EXPORTS
#else
#include <dlfcn.h>
#include <strings.h>
#endif
#include <stdio.h>
#include <time.h>
#include "smhbaapi.h"
#include "vendorsmhbaapi.h"
#include <stdlib.h>
#ifdef USESYSLOG
#include <syslog.h>
#endif
#ifdef SOLARIS
#include <link.h>
#include <limits.h>
static int *handle;
#endif
/*
* LIBRARY_NUM is a shortcut to figure out which library we need to call.
* The top 16 bits of handle are the library index
*/
/*
* VENDOR_HANDLE turns a global library handle into a vendor specific handle,
* with all upper 16 bits set to 0
*/
int _hbaapi_debuglevel = 0;
#if defined(USESYSLOG) && defined(USELOGFILE)
int _hbaapi_sysloginit = 0;
#ifdef WIN32
if ((L) <= _hbaapi_debuglevel) {\
if (_hbaapi_sysloginit == 0) {\
_hbaapi_sysloginit = 1;\
}\
if (_hbaapi_debug_fd == NULL) {\
}\
if (_hbaapi_debug_fd != NULL) {\
}\
}
#else /* WIN32 */
if ((L) <= _hbaapi_debuglevel) {\
if (_hbaapi_sysloginit == 0) {\
_hbaapi_sysloginit = 1;\
}\
if (_hbaapi_debug_fd == NULL) {\
}\
if (_hbaapi_debug_fd != NULL) {\
}\
}
#endif /* WIN32 */
#else /* Not both USESYSLOG and USELOGFILE */
#if defined(USESYSLOG)
int _hbaapi_sysloginit = 0;
if ((L) <= _hbaapi_debuglevel) {\
if (_hbaapi_sysloginit == 0) {\
_hbaapi_sysloginit = 1;\
}\
}
#endif /* USESYSLOG */
#if defined(USELOGFILE)
#ifdef WIN32
if ((L) <= _hbaapi_debuglevel) {\
if (_hbaapi_debug_fd == NULL) {\
}\
}
#else /* WIN32 */
if ((L) <= _hbaapi_debuglevel) {\
if (_hbaapi_debug_fd == NULL) {\
}\
if (_hbaapi_debug_fd != NULL) { \
}\
}
#endif /* WIN32 */
#endif /* USELOGFILE */
#endif /* Not both USELOGFILE and USESYSLOG */
#ifdef POSIX_THREADS
#include <pthread.h>
/*
* When multiple mutex's are grabed, they must be always be grabbed in
* the same order, or deadlock can result. There are three levels
* of mutex's involved in this API. If LL_mutex is grabbed, always grap
* it first. If AL_mutex is grabbed, it may not be grabbed before
* LL_mutex. If grabbed in a multi grab sequence, the mutex's protecting
* the callback lists must always be grabbed last and release before calling
* a vendor specific library function that might invoke a callback function
* on the same thread.
*/
#else
#define GRAB_MUTEX(M)
#define RELEASE_MUTEX(M)
#endif
/*
* Vendor library information
*/
typedef enum {
typedef enum {
typedef struct hba_library_info {
struct hba_library_info
*next;
#ifdef WIN32
#else
char *LibraryName;
#endif
char *LibraryPath;
union {
} ftable;
#define ARE_WE_INITED() \
if (_hbaapi_librarylist == NULL) { \
return (HBA_STATUS_ERROR_NOT_LOADED); \
}
#ifdef POSIX_THREADS
#endif
/*
* Macro to use the right function table between smhba and hbaapi.
*/
/*
* Macro to use the right function ptr between smhba and hbaapi function table.
* Should be used for an interface common to SM-HBA and HBAAPIV2.
*/
/*
* Macro to use the hbaapi function ptr.
* Should be used for an interface applicable only HBAAPIV2.
*/
/*
* Macro to use the hbaapi function ptr.
* Should be used for an interface applicable only HBAAPIV2.
*/
/*
* Individual adapter (hba) information
*/
typedef struct hba_adapter_info {
struct hba_adapter_info
*next;
char *name;
#ifdef POSIX_THREADS
#endif
/*
* Call back registration
*/
typedef struct hba_vendorcallback_elem {
struct hba_vendorcallback_elem
*next;
/*
* Each instance of HBA_ADAPTERCALLBACK_ELEM represents a call to one of
* "register" functions that apply to a particular adapter.
* HBA_ALLADAPTERSCALLBACK_ELEM is used just for HBA_RegisterForAdapterAddEvents
*/
typedef struct hba_adaptercallback_elem {
struct hba_adaptercallback_elem
*next;
void *userdata;
void (*callback)();
typedef struct hba_alladapterscallback_elem {
struct hba_alladapterscallback_elem
*next;
void *userdata;
void (*callback)();
#ifdef POSIX_THREADS
/* mutex's to protect each list */
#endif
NULL};
/*
* Common library internal. Mutex handling
*/
#ifdef POSIX_THREADS
static void
/* LINTED E_FUNC_SET_NOT_USED */
int ret;
perror("pthread_mutex_lock - HBAAPI:");
}
}
static void
/* LINTED E_FUNC_SET_NOT_USED */
int ret;
perror("pthread_mutex_unlock - HBAAPI:");
}
}
#endif
/*
* Common library internal. Check library and return vendorhandle
*/
static HBA_STATUS
if (_hbaapi_librarylist == NULL) {
return (HBA_STATUS_ERROR);
}
for (lib_infop = _hbaapi_librarylist;
return (HBA_STATUS_ERROR);
}
*lib_infopp = lib_infop;
/* caller will release the mutex */
return (HBA_STATUS_OK);
}
}
}
#define CHECKLIBRARY() \
if (status != HBA_STATUS_OK) { \
return (status); \
}
if (status != HBA_STATUS_OK) { \
return (status); \
} else { \
} \
}
/*
* freevendorhandlelist is called with _hbaapi_LL_mutex already held
*/
static void
if (registeredfunc == NULL) {
continue;
}
}
}
static
int found;
/* search through the simple lists first */
continue;
}
found = 1;
if (registeredfunc == NULL) {
break;
}
break;
}
}
if (found != 0) {
if (registeredfunc == NULL) {
return (HBA_STATUS_ERROR_NOT_SUPPORTED);
}
return (HBA_STATUS_OK);
}
/*
* if it wasnt in the simple lists,
* look in the list for adapteraddevents
*/
continue;
}
/* should be HBAAPIV2 VSL to get to here */
if (registeredfunc == NULL) {
continue;
}
}
break;
}
/* now search smhba adapteradd events. */
continue;
}
/* should be SMHBA VSL to get to here */
if (registeredfunc == NULL) {
continue;
}
}
break;
}
return (status);
}
/* LINTED E_STATIC_UE_STATIC_UNUSED */
/* LINTED E_STATIC_UE_STATIC_UNUSED */
/* LINTED E_STATIC_UE_STATIC_UNUSED */
static char *
/* LINTED E_STATIC_UE_STATIC_UNUSED */
int j;
buf[0] = '\0';
for (j = 0; j < 16; j += 2) {
}
return (buf);
}
#ifdef WIN32
{
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return (TRUE);
}
#endif
/*
* Read in the config file and load all the specified vendor specific
* libraries and perform the function registration exercise
*/
{
#ifdef POSIX_THREADS
int ret;
#endif
/* Open configuration file from known location */
#ifdef WIN32
if (_hbaapi_librarylist != NULL) {
/* this is an app programming error */
return (HBA_STATUS_ERROR);
}
if (lStatus != ERROR_SUCCESS) {
/* ???Opportunity to send error msg, configuration error */
return (HBA_STATUS_ERROR);
}
/*
* Enumerate all the subkeys. These have the form:
* HKLM\Software\SNIA\HBA\<Vendor id> - note that we don't care
* what the vendor id is
*/
for (i = 0; ; i++) {
if (lStatus == ERROR_NO_MORE_ITEMS) {
break; /* we're done */
/* do whatever */
;
}
/* Now open the subkey that pertains to this vendor's library */
&hkVendorLib);
if (lStatus != ERROR_SUCCESS) {
/* ???Opportunity to send error msg, installation error */
return (HBA_STATUS_ERROR);
/*
* you may want to return something
* else or keep trying
*/
}
/*
* The name of the library is contained in a REG_SZ Value
* keyed to "LibraryFile"
*/
byFileName, &dwSize);
if (lStatus != ERROR_SUCCESS) {
/* ???Opportunity to send error msg, installation error */
continue;
}
/* what is the right thing to do in MS land??? */
/* ???Opportunity to send error msg, installation error */
return (HBA_STATUS_ERROR);
}
/* Now I can try to load the library */
/* printf("unable to load library %s\n", librarypath); */
/* ???Opportunity to send error msg, installation error */
goto dud_library;
}
if (RegisterSMHBAFunc != NULL) {
if (status != HBA_STATUS_OK) {
/* library not loaded */
/* ???Opportunity to send error msg, library error? */
goto dud_library;
} else {
}
} else {
/* Call the registration function to get the list of pointers */
if (RegisterV2Func != NULL) {
/*
* Load the function pointers directly into
* the table of functions
*/
status = ((RegisterV2Func)
if (status != HBA_STATUS_OK) {
/* library not loaded */
/* ???Opportunity to send error msg, library error? */
goto dud_library;
} else {
}
} else {
/* Maybe the vendor library is only Rev1 */
if (RegisterFunc == NULL) {
/* ???Opportunity to send error msg, library error? */
goto dud_library;
}
/*
* Load the function points directly into
* the Rev 2 table of functions
*/
status = ((RegisterFunc)(
if (status != HBA_STATUS_OK) {
/* library not loaded */
/* ???Opportunity to send error msg, library error? */
goto dud_library;
} else {
}
}
}
/* successfully loaded library */
/*
* SM-HBA and HBAAPI has a seperate handler for GetVersion but
* they have the same function signature so use the same variable here.
*/
if (GetVersionFunc != NULL) {
/* Check the version of this library before loading */
libversion = ((GetVersionFunc)());
#ifdef NOTDEF /* save for a later time... when it matters */
if (libversion < SMHBA_LIBVERSION) {
goto dud_library;
}
#endif
} else {
/* Check the version of this library before loading */
/* Actually... This wrapper is compatible with version 1 */
libversion = ((GetVersionFunc)());
#ifdef NOTDEF /* save for a later time... when it matters */
if (libversion < HBA_LIBVERSION) {
goto dud_library;
}
#endif
}
} else {
/* ???Opportunity to send error msg, library error? */
goto dud_library;
}
if (LoadLibraryFunc == NULL) {
/* Hmmm, dont we need to flag this in a realy big way??? */
/* How about messages to the system event logger ??? */
/* ???Opportunity to send error msg, library error? */
goto dud_library;
}
/* Initialize this library */
status = ((LoadLibraryFunc)());
if (status != HBA_STATUS_OK) {
/* ???Opportunity to send error msg, library error? */
continue;
}
/* successfully loaded library */
dud_library: /* its also just the end of the loop */
}
#else /* Unix as opposed to Win32 */
char *charPtr;
if (_hbaapi_librarylist != NULL) {
"HBA_LoadLibrary: previously unfreed "
"libraries exist, call HBA_FreeLibrary().\n");
return (HBA_STATUS_ERROR);
}
return (HBA_STATUS_ERROR);
}
/* Read in each line and load library */
/* Skip the comments... */
continue;
}
/* grab first 'thing' in line (if its there) */
"Library name(%s) in %s is > 64 characters\n",
}
}
/* grab second 'thing' in line (if its there) */
"Library path(%s) in %s is > 256 characters\n",
}
}
/* there should be no more 'things' in the line */
}
/* Continue to the next line if library name or path is invalid */
if (libraryname == NULL ||
strlen(libraryname) == 0 ||
librarypath == NULL ||
(strlen(librarypath) == 0)) {
continue;
}
/*
* Special case....
* Look for loglevel
*/
/* error handling does the right thing automagically */
continue;
}
return (HBA_STATUS_ERROR);
}
lib_infop->numOfAdapters = 0;
/* Load the DLL now */
/* printf("unable to load library %s\n", librarypath); */
continue;
}
/* Call the registration function to get the list of pointers */
if (RegisterSMHBAFunc != NULL) {
/*
* Load the function points directly into
* the table of functions
*/
status = ((RegisterSMHBAFunc)
if (status != HBA_STATUS_OK) {
/* library not loaded */
continue;
} else {
}
} else {
if (RegisterV2Func != NULL) {
/*
* Load the function points directly into
* the table of functions
*/
if (status != HBA_STATUS_OK) {
/* library not loaded */
continue;
} else {
}
} else {
/* Maybe the vendor library is only Rev1 */
if (RegisterFunc == NULL) {
/* This function is required */
"HBA_LoadLibrary: vendor specific RegisterLibrary "
"function not found. lib: %s\n", librarypath);
"RegisterLibrary function not found. lib: %s\n",
librarypath, 0, 0);
continue;
}
/*
* Load the function points directly into
* the table of functions
*/
status = ((RegisterFunc)
if (status != HBA_STATUS_OK) {
/* library not loaded */
"HBA_LoadLibrary: vendor specific RegisterLibrary "
"function encountered an error. lib: %s\n",
DEBUG(1,
"HBA_LoadLibrary: vendor specific RegisterLibrary "
"function encountered an error. lib: %s\n",
librarypath, 0, 0);
continue;
} else {
}
}
}
/* successfully loaded library */
/*
* SM-HBA and HBAAPI has a seperate handler for GetVersion but
* they have the same function signature so use the same variable here.
*/
== NULL) {
continue;
}
libversion = ((GetVersionFunc)());
if (libversion < SMHBA_LIBVERSION) {
(void) printf("Library version mismatch."
"Got %d expected %d.\n",
continue;
}
} else {
libversion = ((GetVersionFunc)());
/* Check the version of this library before loading */
/* Actually... This wrapper is compatible with version 1 */
if (libversion < HBA_LIBVERSION) {
(void) printf("Library version mismatch."
"Got %d expected %d.\n",
continue;
}
}
if (LoadLibraryFunc == NULL) {
/* this function is required */
"HBA_LoadLibrary: vendor specific LoadLibrary "
"function not found. lib: %s\n", librarypath);
"function not found. lib: %s\n", librarypath, 0, 0);
continue;
}
/* Initialize this library */
/* maybe this should be a printf so that we CANNOT miss it */
"HBA_LoadLibrary: Encounterd and error loading: %s",
continue;
}
/* successfully loaded library */
}
#endif /* WIN32 or UNIX */
#ifdef POSIX_THREADS
/*
* The _hbaapi_LL_mutex is already grabbed to proctect the caller of
* HBA_FreeLibrary() during loading.
* The mutexes are already initialized
* with PTHREAD_MUTEX_INITIALIZER. Do we need to init again?
* Keeping the code from HBAAPI source...
*/
if (ret == 0) {
}
if (ret == 0) {
}
if (ret == 0) {
}
if (ret == 0) {
}
if (ret == 0) {
}
if (ret == 0) {
}
if (ret == 0) {
}
if (ret == 0) {
}
if (ret == 0) {
}
if (ret == 0) {
}
if (ret == 0) {
}
if (ret != 0) {
perror("pthread_mutex_init - HBA_LoadLibrary");
return (HBA_STATUS_ERROR);
}
#endif
return (HBA_STATUS_OK);
}
HBA_FreeLibrary() {
/* LINTED E_FUNC_SET_NOT_USED */
***listp;
if (_hbaapi_librarylist == NULL) {
return (HBA_STATUS_ERROR_NOT_LOADED);
}
if (FreeLibraryFunc != NULL) {
/* Free this library */
status = ((FreeLibraryFunc)());
}
#ifdef WIN32
#else
#endif
}
#ifndef WIN32
#endif
}
/*
* OK, now all functions are disabled except for LoadLibrary,
* Hope no other thread calls it before we have returned
*/
for (adapt_infop = _hbaapi_adapterlist;
adapt_infop != NULL;
adapt_infop = adapt_next) {
}
/*
* Free up the callbacks, this is not the most efficient, but it works
*/
while ((volatile HBA_ADAPTERCALLBACK_ELEM *)
!= NULL) {
(void) local_remove_callback((HBA_CALLBACKHANDLE)
}
while ((volatile HBA_ADAPTERCALLBACK_ELEM *)
!= NULL) {
(void) local_remove_callback((HBA_CALLBACKHANDLE)
}
}
}
#ifdef USESYSLOG
closelog();
#endif
#ifdef USELOGFILE
if (_hbaapi_debug_fd != NULL) {
}
#endif
#ifdef POSIX_THREADS
/* this will unlock them as well, but who cares */
(void) pthread_mutex_destroy(&_hbaapi_LE_mutex);
(void) pthread_mutex_destroy(&_hbaapi_TE_mutex);
(void) pthread_mutex_destroy(&_hbaapi_APSE_mutex);
(void) pthread_mutex_destroy(&_hbaapi_APE_mutex);
(void) pthread_mutex_destroy(&_hbaapi_AE_mutex);
(void) pthread_mutex_destroy(&_hbaapi_AAE_mutex);
(void) pthread_mutex_destroy(&_smhba_TE_mutex);
(void) pthread_mutex_destroy(&_smhba_APSE_mutex);
(void) pthread_mutex_destroy(&_smhba_APE_mutex);
(void) pthread_mutex_destroy(&_smhba_AE_mutex);
(void) pthread_mutex_destroy(&_smhba_AAE_mutex);
(void) pthread_mutex_destroy(&_hbaapi_AL_mutex);
(void) pthread_mutex_destroy(&_hbaapi_LL_mutex);
#endif
return (HBA_STATUS_OK);
}
/*
* The API used to use fixed size tables as its primary data structure.
* Indexing from 1 to N identified each adapters. Now the adapters are
* on a linked list. There is a unique "index" foreach each adapter.
* Adapters always keep their index, even if they are removed from the
* hardware. The only time the indexing is reset is on HBA_FreeLibrary
*/
{
int j = 0;
if (_hbaapi_librarylist == NULL) {
return (0);
}
for (lib_infop = _hbaapi_librarylist;
continue;
}
if (GetNumberOfAdaptersFunc == NULL) {
continue;
}
num_adapters = ((GetNumberOfAdaptersFunc)());
#ifndef WIN32
#else
#endif
/* Also get the names of all the adapters here and cache */
if (GetAdapterNameFunc == NULL) {
continue;
}
for (j = 0; j < num_adapters; j++) {
found_name = 0;
if (status == HBA_STATUS_OK) {
for (adapt_infop = _hbaapi_adapterlist;
adapt_infop != NULL;
/*
* check for duplicates, really,
* this may just be a second
* call to this function
* ??? how do we know when a name becomes stale?
*/
/* already got this one */
found_name++;
break;
}
}
if (found_name != 0) {
continue;
}
}
adapt_infop = (HBA_ADAPTER_INFO *)
if (adapt_infop == NULL) {
#ifndef WIN32
"HBA_GetNumberOfAdapters: calloc failed"
" on sizeof:%lu\n",
(unsigned long)(sizeof (HBA_ADAPTER_INFO)));
#endif
}
} else {
}
}
}
}
char *adaptername)
{
if (adaptername == NULL) {
0, 0, 0);
return (HBA_STATUS_ERROR_ARG);
}
/*
* The adapter index is from old code, but we have
* to support it. Go down the list looking for
* the adapter
*/
*adaptername = '\0';
for (adapt_infop = _hbaapi_adapterlist;
adapt_infop != NULL;
} else {
*adaptername = '\0';
}
break;
}
}
adapterindex, adaptername, 0);
}
{
if (_hbaapi_librarylist == NULL) {
return (handle);
}
if (adaptername == NULL) {
0, 0, 0);
return (handle);
}
for (adapt_infop = _hbaapi_adapterlist;
adapt_infop != NULL;
continue;
}
if (OpenAdapterFunc != NULL) {
/* retrieve the vendor handle */
if (handle != 0) {
/* or this with the library index to get the common handle */
}
}
break;
}
}
/*
* Finding an adapter with matching WWN.
*/
for (lib_infop = _hbaapi_librarylist;
continue;
}
/* only for HBAAPIV2 */
continue;
}
if (GetNumberOfAdaptersFunc == NULL) {
continue;
}
/* look for new hardware */
(void) ((GetNumberOfAdaptersFunc)());
if (OpenAdapterFunc == NULL) {
continue;
}
/*
* We do not know if the WWN is known by this vendor,
* just try it
*/
continue;
}
/* OK, make a vendor non-specific handle */
break;
}
}
void
(void) HBA_GetNumberOfAdapters();
}
HBA_GetVersion() {
return (HBA_LIBVERSION);
}
/*
* This function is VERY OS dependent. Wing it as best you can.
*/
{
if (attributes == NULL) {
"NULL pointer attributes",
0, 0, 0);
return (HBA_STATUS_ERROR_ARG);
}
#if defined(SOLARIS)
}
}
}
}
/* No need to do anything with the module handle */
/* It wasn't alloocated so it doesn't need to be freed */
sizeof (attributes->LibPath)) == 0) {
}
}
#endif
#if defined(VENDOR)
#else
#endif
#if defined(VERSION)
#else
#endif
#if defined(BUILD_DATE)
#if defined(WIN32)
int matchCount;
if (matchCount != 6) {
} else {
}
#else
if (strptime(BUILD_DATE,
}
#endif
#else
#endif
return (2);
}
/*
* Callback registation and handling
*/
}
/* Adapter Add Events ************************************************* */
static void
/* LINTED E_FUNC_ARG_UNUSED */
}
}
void (*callback)(
void *data,
void *userData,
int registered_cnt = 0;
int vendor_cnt = 0;
int not_supported_cnt = 0;
int status_OK_bar_cnt = 0;
int status_OK_cnt = 0;
#ifndef WIN32
"HBA_RegisterForAdapterAddEvents: calloc failed "
"for %lu bytes\n",
(unsigned long)(sizeof (HBA_ALLADAPTERSCALLBACK_ELEM)));
#endif
return (HBA_STATUS_ERROR);
}
/*
* Need to release the mutex now incase the vendor function invokes the
* callback. We will grap the mutex later to attach the vendor handle
* list to the callback structure
*/
/*
* now create a list of vendors (vendor libraryies, NOT ADAPTERS)
* that have successfully registerred
*/
for (lib_infop = _hbaapi_librarylist;
/* only for HBAAPI V2 */
continue;
} else {
vendor_cnt++;
}
if (registeredfunc == NULL) {
continue;
}
vcbp = (HBA_VENDORCALLBACK_ELEM *)
#ifndef WIN32
"HBA_RegisterForAdapterAddEvents: "
"calloc failed for %lu bytes\n",
(unsigned long)(sizeof (HBA_VENDORCALLBACK_ELEM)));
#endif
break;
}
if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
continue;
} else if (status != HBA_STATUS_OK) {
DEBUG(1,
"HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
#ifndef WIN32
"HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
#endif
continue;
} else {
}
}
if (vendor_cnt == 0) {
/* no HBAAPIV2 is deteced. should be okay? */
} else if (registered_cnt == 0) {
} else if (status_OK_cnt == 0 && not_supported_cnt != 0) {
} else if (status_OK_cnt == 0) {
/*
* At least one vendor library registered this function, but no
* vendor call succeeded
*/
} else {
/* we have had atleast some success, now finish up */
/*
* this seems silly, but what if another thread called
* the callback remove
*/
/* yup, its still there, hooray */
break;
}
}
if (vendorhandlelist != NULL) {
/*
* bummer, somebody removed the callback before we finished
* registration, probably will never happen
*/
DEBUG(1,
"HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was "
"called for a handle before registration was finished.",
0, 0, 0);
} else {
}
}
}
/* Adapter Events (other than add) ************************************** */
static void
eventType, 0);
break;
}
}
}
void (*callback) (
void *data,
void *userData,
/* we now have the _hbaapi_LL_mutex */
if (registeredfunc == NULL) {
}
/*
* that allocated memory is used both as the handle for the
* caller, and as userdata to the vendor call so that on
* callback the specific registration may be recalled
*/
acbp = (HBA_ADAPTERCALLBACK_ELEM *)
#ifndef WIN32
"HBA_RegisterForAdapterEvents: calloc failed for %lu bytes\n",
(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
#endif
}
(void *)acbp,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
}
}
/* Adapter Port Events ************************************************** */
static void
break;
}
}
}
void (*callback) (
void *data,
void *userData,
/* we now have the _hbaapi_LL_mutex */
if (registeredfunc == NULL) {
}
/*
* that allocated memory is used both as the handle for the
* caller, and as userdata to the vendor call so that on
* callback the specific registration may be recalled
*/
acbp = (HBA_ADAPTERCALLBACK_ELEM *)
#ifndef WIN32
"HBA_RegisterForAdapterPortEvents: "
"calloc failed for %lu bytes\n",
(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
#endif
}
(void *)acbp,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
}
}
/* Adapter State Events ************************************************ */
static void
eventType, 0);
return;
}
}
}
void (*callback) (
void *data,
void *userData,
/* we now have the _hbaapi_LL_mutex */
if (registeredfunc == NULL) {
}
/*
* that allocated memory is used both as the handle for the
* caller, and as userdata to the vendor call so that on
* callback the specific registration may be recalled
*/
acbp = (HBA_ADAPTERCALLBACK_ELEM *)
#ifndef WIN32
"HBA_RegisterForAdapterPortStatEvents: "
"calloc failed for %lu bytes\n",
(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
#endif
}
(void *)acbp,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
}
}
/* Target Events ******************************************************* */
static void
break;
}
}
}
void (*callback) (
void *data,
void *userData,
*acbp;
/* we now have the _hbaapi_LL_mutex */
if (registeredfunc == NULL) {
}
/*
* that allocated memory is used both as the handle for the
* caller, and as userdata to the vendor call so that on
* callback the specific registration may be recalled
*/
acbp = (HBA_ADAPTERCALLBACK_ELEM *)
#ifndef WIN32
"HBA_RegisterForTargetEvents: calloc failed for %lu bytes\n",
(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
#endif
}
(void *)acbp,
if (status != HBA_STATUS_OK) {
}
}
/* Link Events ********************************************************* */
static void
void *pRLIRBuffer,
for (acbp = _hbaapi_linkevents_callback_list;
break;
}
}
}
void (*callback) (
void *data,
void *pRLIRBuffer,
void *userData,
void *pRLIRBuffer,
CHECKLIBRARY();
/* we now have the _hbaapi_LL_mutex */
if (registeredfunc == NULL) {
}
/*
* that allocated memory is used both as the handle for the
* caller, and as userdata to the vendor call so that on
* callback the specific registration may be recalled
*/
acbp = (HBA_ADAPTERCALLBACK_ELEM *)
#ifndef WIN32
"HBA_RegisterForLinkEvents: calloc failed for %lu bytes\n",
(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
#endif
}
(void *)acbp,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
}
}
/*
* All of the functions below are almost passthru functions to the
* vendor specific function
*/
void
if (status == HBA_STATUS_OK) {
if (CloseAdapterFunc != NULL) {
((CloseAdapterFunc)(vendorHandle));
}
}
}
{
CHECKLIBRARY();
}
if (GetAdapterAttributesFunc != NULL) {
} else {
}
}
{
CHECKLIBRARY();
}
if (GetAdapterPortAttributesFunc != NULL) {
} else {
}
}
{
CHECKLIBRARY();
}
if (GetPortStatisticsFunc != NULL) {
} else {
}
}
{
CHECKLIBRARY();
}
if (GetDiscoveredPortAttributesFunc != NULL) {
} else {
}
}
{
CHECKLIBRARY();
}
if (GetPortAttributesByWWNFunc != NULL) {
} else {
}
}
void *pReqBuffer,
void *pRspBuffer,
{
CHECKLIBRARY();
}
if (SendCTPassThruFunc != NULL) {
} else {
}
}
void *pReqBuffer,
void *pRspBuffer,
{
WWN2STR1(&hbaPortWWN), 0, 0);
if (registeredfunc != NULL) {
status = (registeredfunc)
} else {
}
}
{
CHECKLIBRARY();
}
if (GetEventBufferFunc != NULL) {
} else {
}
}
CHECKLIBRARY();
if (SetRNIDMgmtInfoFunc != NULL) {
} else {
}
}
CHECKLIBRARY();
if (GetRNIDMgmtInfoFunc != NULL) {
} else {
}
}
void *pRspBuffer,
{
CHECKLIBRARY();
}
if (SendRNIDFunc != NULL) {
} else {
}
}
void *pRspBuffer,
{
CHECKLIBRARY();
if (registeredfunc != NULL) {
status = (registeredfunc)
} else {
}
}
void
if (status == HBA_STATUS_OK) {
if (RefreshInformationFunc != NULL) {
}
}
}
void
if (status == HBA_STATUS_OK) {
}
if (ResetStatisticsFunc != NULL) {
}
}
}
CHECKLIBRARY();
}
if (GetFcpTargetMappingFunc != NULL) {
} else {
}
}
{
if (registeredfunc != NULL) {
} else {
}
}
CHECKLIBRARY();
}
if (GetFcpPersistentBindingFunc != NULL) {
} else {
}
}
void *pRspBuffer,
void *pSenseBuffer,
{
WWN2STR1(&discoveredPortWWN), 0, 0);
if (ScsiInquiryV2Func != NULL) {
status = ((ScsiInquiryV2Func)(
} else {
}
}
void *pRspBuffer,
void *pSenseBuffer,
{
CHECKLIBRARY();
}
if (SendScsiInquiryFunc != NULL) {
status = ((SendScsiInquiryFunc)(
} else {
}
}
void *pRespBuffer,
void *pSenseBuffer,
{
WWN2STR1(&discoveredPortWWN), 0, 0);
if (ScsiReportLUNsV2Func != NULL) {
status = ((ScsiReportLUNsV2Func)(
} else {
}
}
void *pRspBuffer,
void *pSenseBuffer,
{
CHECKLIBRARY();
}
if (SendReportLUNsFunc != NULL) {
status = ((SendReportLUNsFunc)(
} else {
}
}
void *pRspBuffer,
void *pSenseBuffer,
{
WWN2STR1(&discoveredPortWWN), 0, 0);
if (ScsiReadCapacityV2Func != NULL) {
status = ((ScsiReadCapacityV2Func)(
} else {
}
}
void *pRspBuffer,
void *pSenseBuffer,
{
CHECKLIBRARY();
}
if (SendReadCapacityFunc != NULL) {
} else {
}
}
void *pRspBuffer,
{
CHECKLIBRARY();
if (registeredfunc != NULL) {
status = (registeredfunc)(
} else {
}
}
void *pRspBuffer,
{
CHECKLIBRARY();
if (registeredfunc != NULL) {
status = (registeredfunc)(
} else {
}
}
void *pRspBuffer,
{
CHECKLIBRARY();
if (registeredfunc != NULL) {
status = (registeredfunc)(
} else {
}
}
void *pRspBuffer,
{
CHECKLIBRARY();
if (registeredfunc != NULL) {
status = (registeredfunc)(
} else {
}
}
void *pRspBuffer,
{
CHECKLIBRARY();
if (registeredfunc != NULL) {
status = (registeredfunc)(
} else {
}
}
{
if (registeredfunc != NULL) {
} else {
}
}
{
if (registeredfunc != NULL) {
} else {
}
}
{
if (registeredfunc != NULL) {
} else {
}
}
const HBA_FCPBINDING2 *pbinding)
{
WWN2STR1(&hbaPortWWN), 0, 0);
if (registeredfunc != NULL) {
} else {
}
}
{
WWN2STR1(&hbaPortWWN), 0, 0);
if (registeredfunc != NULL) {
} else {
}
}
const HBA_FCPBINDING2
*pbinding)
{
if (registeredfunc != NULL) {
} else {
}
}
{
if (registeredfunc != NULL) {
} else {
}
}
{
if (registeredfunc != NULL) {
status = (registeredfunc)
} else {
}
}
const HBA_SCSIID *lunit,
{
if (registeredfunc != NULL) {
} else {
}
}
{
adapter_index, 0, 0);
if (_hbaapi_librarylist == NULL) {
return (0);
}
if (attributes == NULL) {
DEBUG(1,
"HBA_GetVendorLibraryAttributes: NULL pointer attributes",
0, 0, 0);
return (HBA_STATUS_ERROR_ARG);
}
for (adapt_infop = _hbaapi_adapterlist;
adapt_infop != NULL;
}
if (registeredfunc != NULL) {
} else {
/* Version 1 libary? */
if (GetVersionFunc != NULL) {
ret = ((GetVersionFunc)());
}
#ifdef NOTDEF
else {
/* This should not happen, dont think its going to */
}
#endif
}
}
}
break;
}
}
}
/*
* This function returns SM-HBA version that the warpper library implemented.
*/
SMHBA_GetVersion() {
return (SMHBA_LIBVERSION);
}
/*
* This function returns the attributes for the warpper library.
*/
{
if (attributes == NULL) {
"NULL pointer attributes",
0, 0, 0);
return (HBA_STATUS_ERROR_ARG);
}
#if defined(SOLARIS)
}
}
}
}
#endif
#if defined(VENDOR)
#else
#endif
#if defined(VERSION)
#else
#endif
if (gettimeofday(&tv, (void *)0) == 0) {
} else {
sizeof (attributes->build_date));
}
sizeof (attributes->build_date));
}
return (1);
}
/*
* This function returns the attributes for the warpper library.
*/
{
adapter_index, 0, 0);
if (_hbaapi_librarylist == NULL) {
return (0);
}
if (attributes == NULL) {
"NULL pointer attributes",
0, 0, 0);
return (HBA_STATUS_ERROR_ARG);
}
for (adapt_infop = _hbaapi_adapterlist;
adapt_infop != NULL;
}
if (registeredfunc != NULL) {
#ifdef NOTDEF
} else {
/* This should not happen since the VSL is already loaded. */
#endif
}
}
}
break;
}
}
}
{
if (GetAdapterAttributesFunc != NULL) {
} else {
}
}
{
if (GetNumberOfPortsFunc != NULL) {
} else {
}
}
{
if (GetPortTypeFunc != NULL) {
} else {
}
}
{
if (GetAdapterPortAttributesFunc != NULL) {
} else {
}
}
{
if (GetDiscoveredPortAttributesFunc != NULL) {
} else {
}
}
{
if (GetPortAttributesByWWNFunc != NULL) {
} else {
}
}
{
if (GetFCPhyAttributesFunc != NULL) {
} else {
}
}
{
if (GetSASPhyAttributesFunc != NULL) {
} else {
}
}
{
portindex, protocoltype, 0);
if (GetProtocolStatisticsFunc != NULL) {
} else {
}
}
{
if (GetPhyStatisticsFunc != NULL) {
} else {
}
}
{
if (GetBindingCapabilityFunc != NULL) {
} else {
}
}
{
WWN2STR1(&hbaPortWWN), 0, 0);
if (GetBindingSupporFunc != NULL) {
} else {
}
}
{
WWN2STR1(&hbaPortWWN), 0, 0);
if (SetBindingSupporFunc != NULL) {
} else {
}
}
{
WWN2STR1(&hbaPortWWN), 0, 0);
if (GetTargetMappingFunc != NULL) {
} else {
}
}
{
WWN2STR1(&hbaPortWWN), 0, 0);
if (GetPersistentBindingFunc != NULL) {
} else {
}
}
const SMHBA_BINDING *binding)
{
WWN2STR1(&hbaPortWWN), 0, 0);
if (SetPersistentBindingFunc != NULL) {
} else {
}
}
const SMHBA_BINDING *binding)
{
WWN2STR1(&hbaPortWWN), 0, 0);
if (RemovePersistentBindingFunc != NULL) {
} else {
}
}
{
WWN2STR1(&hbaPortWWN), 0, 0);
if (RemoveAllPersistentBindingsFunc != NULL) {
} else {
}
}
const HBA_SCSIID *lunit,
{
if (GetLUNStatisticsFunc != NULL) {
} else {
}
}
void *pRspBuffer,
void *pSenseBuffer,
{
if (ScsiInquiryFunc != NULL) {
status = ((ScsiInquiryFunc)(
} else {
}
}
void *pRspBuffer,
void *pSenseBuffer,
{
if (ScsiReportLUNsFunc != NULL) {
status = ((ScsiReportLUNsFunc)(
} else {
}
}
void *pRspBuffer,
void *pSenseBuffer,
{
if (ScsiReadCapacityFunc != NULL) {
status = ((ScsiReadCapacityFunc)(
} else {
}
}
void *pRspBuffer,
{
if (SendTESTFunc != NULL) {
status = (SendTESTFunc)
} else {
}
}
void *pReqBuffer,
void *pRspBuffer,
{
if (SendECHOFunc != NULL) {
status = (SendECHOFunc)
} else {
}
}
void *pReqBuffer,
void *pRspBuffer,
{
if (SendSMPPassThruFunc != NULL) {
} else {
}
}
/*
* Following the similar logic of HBAAPI addaspterevents_callback.
*
* Unlike other events Adapter Add Event is not limited to a specific
* adpater(i.e. no adatper handle is passed for registration) so
* the event should be passed to all registrants. The routine below
* is passed to the VSLs as a callback and when Adapter Add event is detected
* by VSL it will call smhba_adapteraddevents_callback() which in turn check
* if the passed userdata ptr matches with the one stored in the callback list
* and calls the stored callback.
*
* For the situation that multiple clients are registered for Adapter Add event
* each registration is passed to VSLs so VSL may call
* smhba_adapteraddevents_callback() multiple times or it may call only once
* since the callback function is same. For this implemneation, the userdata
* is stored in HBA_ALLADAPTERSCALLBACK_ELEM so it is expected that VSL call
* smhba_adapteraddevents_callback() only once and
* smhba_adapteraddevents_callback() will call the client callback with proper
* userdata.
*/
static void
/* LINTED E_FUNC_ARG_UNUSED */
void *data,
/* LINTED E_FUNC_ARG_UNUSED */
{
}
}
void (*pCallback) (
void *data,
void *pUserData,
int registered_cnt = 0;
int vendor_cnt = 0;
int not_supported_cnt = 0;
int status_OK_bar_cnt = 0;
int status_OK_cnt = 0;
return (HBA_STATUS_ERROR);
}
/*
* Need to release the mutex now incase the vendor function invokes the
* callback. We will grap the mutex later to attach the vendor handle
* list to the callback structure
*/
/*
* now create a list of vendors (vendor libraryies, NOT ADAPTERS)
* that have successfully registerred
*/
for (lib_infop = _hbaapi_librarylist;
/* only for HBAAPI V2 */
continue;
} else {
vendor_cnt++;
}
if (registeredfunc == NULL) {
continue;
}
vcbp = (HBA_VENDORCALLBACK_ELEM *)
break;
}
if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
continue;
} else if (status != HBA_STATUS_OK) {
DEBUG(1,
"SMHBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
continue;
} else {
}
}
if (vendor_cnt == 0) {
/* no SMHBA VSL found. Should be okay?? */
} else if (registered_cnt == 0) {
} else if (status_OK_cnt == 0 && not_supported_cnt != 0) {
} else if (status_OK_cnt == 0) {
/*
* At least one vendor library registered this function, but no
* vendor call succeeded
*/
} else {
/* we have had atleast some success, now finish up */
/*
* this seems silly, but what if another thread called
* the callback remove
*/
/* yup, its still there, hooray */
break;
}
}
if (vendorhandlelist != NULL) {
/*
* bummer, somebody removed the callback before we finished
* registration, probably will never happen
*/
DEBUG(1,
"HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was "
"called for a handle before registration was finished.",
0, 0, 0);
} else {
}
}
}
/* SMHBA Adapter Events (other than add) ******************************** */
static void
{
eventType, 0);
break;
}
}
}
void (*pCallback) (
void *data,
void *pUserData,
/* we now have the _hbaapi_LL_mutex */
if (registeredfunc == NULL) {
}
/*
* that allocated memory is used both as the handle for the
* caller, and as userdata to the vendor call so that on
* callback the specific registration may be recalled
*/
acbp = (HBA_ADAPTERCALLBACK_ELEM *)
}
(void *)acbp,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
}
}
/* Adapter Port Events *********************************************** */
static void
{
DEBUG(3,
"SMHBA_AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x",
break;
}
}
}
void (*pCallback) (
void *pData,
void *pUserData,
/* we now have the _hbaapi_LL_mutex */
if (registeredfunc == NULL) {
}
/*
* that allocated memory is used both as the handle for the
* caller, and as userdata to the vendor call so that on
* callback the specific registration may be recalled
*/
acbp = (HBA_ADAPTERCALLBACK_ELEM *)
}
(void *)acbp,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
}
}
/* SMHBA Adapter Port Stat Events ******************************** */
static void
{
DEBUG(3,
"SMBA_AdapterPortStateEvent, port:%s, eventType:%d",
return;
}
}
}
void (*pCallback) (
void *pData,
void *pUserData,
/* we now have the _hbaapi_LL_mutex */
if (registeredfunc == NULL) {
}
/*
* that allocated memory is used both as the handle for the
* caller, and as userdata to the vendor call so that on
* callback the specific registration may be recalled
*/
acbp = (HBA_ADAPTERCALLBACK_ELEM *)
}
(void *)acbp,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
}
}
/* SMHBA Adapter Port Phy Stat Events ************************************ */
static void
{
DEBUG(3,
"SMBA_AdapterPortStateEvent, port:%s, eventType:%d",
return;
}
}
}
void (*pCallback) (
void *pData,
void *pUserData,
/* we now have the _hbaapi_LL_mutex */
if (registeredfunc == NULL) {
}
/*
* that allocated memory is used both as the handle for the
* caller, and as userdata to the vendor call so that on
* callback the specific registration may be recalled
*/
acbp = (HBA_ADAPTERCALLBACK_ELEM *)
}
(void *)acbp,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
}
}
/* SMHBA Target Events ********************************************* */
static void
{
break;
}
}
}
void (*pCallback) (
void *pData,
void *pUserData,
"%s, discoveredPort: %s",
/* we now have the _hbaapi_LL_mutex */
if (registeredfunc == NULL) {
}
/*
* that allocated memory is used both as the handle for the
* caller, and as userdata to the vendor call so that on
* callback the specific registration may be recalled
*/
acbp = (HBA_ADAPTERCALLBACK_ELEM *)
}
(void *)acbp,
if (status != HBA_STATUS_OK) {
}
}