SMHBAAPILIB.c revision 9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bb
/*
* ************************************************************************
* 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
*
* /http://www.snia.org/English/Resources/Code/OpenSource.html
*
* 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;
static Link_map *map, *mp;
#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
*/
#define LIBRARY_NUM(handle) ((handle)>>16)
/*
* VENDOR_HANDLE turns a global library handle into a vendor specific handle,
* with all upper 16 bits set to 0
*/
#define VENDOR_HANDLE(handle) ((handle)&0xFFFF)
#define HBA_HANDLE_FROM_LOCAL(library, vendor) \
(((library)<<16) | ((vendor)&0x0000FFFF))
int _hbaapi_debuglevel = 0;
#define DEBUG(L, STR, A1, A2, A3)
#if defined(USESYSLOG) && defined(USELOGFILE)
FILE *_hbaapi_debug_fd = NULL;
int _hbaapi_sysloginit = 0;
#undef DEBUG
#ifdef WIN32
#define DEBUG(L, STR, A1, A2, A3)\
if ((L) <= _hbaapi_debuglevel) {\
if (_hbaapi_sysloginit == 0) {\
openlog("HBAAPI", LOG_PID|LOG_ODELAY, LOG_USER);\
_hbaapi_sysloginit = 1;\
}\
syslog(LOG_INFO, (STR), (A1), (A2), (A3));\
if (_hbaapi_debug_fd == NULL) {\
char _logFile[MAX_PATH]; \
GetTempPath(MAX_PATH, _logFile); \
strcat(_logFile, "HBAAPI.log"); \
_hbaapi_debug_fd = fopen(_logFile, "a");\
}\
if (_hbaapi_debug_fd != NULL) {\
fprintf(_hbaapi_debug_fd, #STR "\n", (A1), (A2), (A3));\
}\
}
#else /* WIN32 */
#define DEBUG(L, STR, A1, A2, A3)\
if ((L) <= _hbaapi_debuglevel) {\
if (_hbaapi_sysloginit == 0) {\
openlog("HBAAPI", LOG_PID|LOG_ODELAY, LOG_USER);\
_hbaapi_sysloginit = 1;\
}\
syslog(LOG_INFO, (STR), (A1), (A2), (A3));\
if (_hbaapi_debug_fd == NULL) {\
_hbaapi_debug_fd = fopen("/tmp/HBAAPI.log", "a");\
}\
if (_hbaapi_debug_fd != NULL) {\
fprintf(_hbaapi_debug_fd, #STR "\n", (A1), (A2), (A3));\
}\
}
#endif /* WIN32 */
#else /* Not both USESYSLOG and USELOGFILE */
#if defined(USESYSLOG)
int _hbaapi_sysloginit = 0;
#undef DEBUG
#define DEBUG(L, STR, A1, A2, A3) \
if ((L) <= _hbaapi_debuglevel) {\
if (_hbaapi_sysloginit == 0) {\
openlog("HBAAPI", LOG_PID|LOG_ODELAY, LOG_USER);\
_hbaapi_sysloginit = 1;\
}\
syslog(LOG_DEBUG, (STR), (A1), (A2), (A3));\
}
#endif /* USESYSLOG */
#if defined(USELOGFILE)
FILE *_hbaapi_debug_fd = NULL;
#undef DEBUG
#ifdef WIN32
#define DEBUG(L, STR, A1, A2, A3) \
if ((L) <= _hbaapi_debuglevel) {\
if (_hbaapi_debug_fd == NULL) {\
char _logFile[MAX_PATH]; \
GetTempPath(MAX_PATH, _logFile); \
strcat(_logFile, "HBAAPI.log"); \
_hbaapi_debug_fd = fopen(_logFile, "a");\
}\
}
#else /* WIN32 */
#define DEBUG(L, STR, A1, A2, A3) \
if ((L) <= _hbaapi_debuglevel) {\
if (_hbaapi_debug_fd == NULL) {\
_hbaapi_debug_fd = fopen("/tmp/HBAAPI.log", "a");\
}\
if (_hbaapi_debug_fd != NULL) { \
fprintf(_hbaapi_debug_fd, #STR "\n", (A1), (A2), (A3));\
}\
}
#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.
*/
#define GRAB_MUTEX(M) grab_mutex(M)
#define RELEASE_MUTEX(M) release_mutex(M)
#define RELEASE_MUTEX_RETURN(M, RET) release_mutex(M); return (RET)
#elif defined(WIN32)
#define GRAB_MUTEX(m) EnterCriticalSection(m)
#define RELEASE_MUTEX(m) LeaveCriticalSection(m)
#define RELEASE_MUTEX_RETURN(m, RET) LeaveCriticalSection(m); return (RET)
#else
#define GRAB_MUTEX(M)
#define RELEASE_MUTEX(M)
#define RELEASE_MUTEX_RETURN(M, RET) return (RET)
#endif
/*
* Vendor library information
*/
typedef enum {
HBA_LIBRARY_UNKNOWN,
HBA_LIBRARY_LOADED,
HBA_LIBRARY_NOT_LOADED
} HBA_LIBRARY_STATUS;
typedef enum {
UNKNOWN = 1,
SMHBA,
HBAAPIV2,
HBAAPI
} LIBRARY_VERSION;
typedef struct hba_library_info {
struct hba_library_info
*next;
#ifdef WIN32
HINSTANCE hLibrary; /* Handle to a loaded DLL */
#else
char *LibraryName;
void* hLibrary; /* Handle to a loaded DLL */
#endif
char *LibraryPath;
LIBRARY_VERSION version; /* resolve union */
HBA_UINT32 numOfAdapters;
union {
SMHBA_ENTRYPOINTS smhbafunctionTable; /* smhba function pointers */
HBA_ENTRYPOINTSV2 functionTable; /* hba api function pointers */
} ftable;
HBA_LIBRARY_STATUS status; /* info on this library */
HBA_UINT32 index;
} HBA_LIBRARY_INFO, *PHBA_LIBRARY_INFO;
#define ARE_WE_INITED() \
if (_hbaapi_librarylist == NULL) { \
return (HBA_STATUS_ERROR_NOT_LOADED); \
}
HBA_LIBRARY_INFO *_hbaapi_librarylist = NULL;
HBA_UINT32 _hbaapi_total_library_count = 0;
#ifdef POSIX_THREADS
pthread_mutex_t _hbaapi_LL_mutex = PTHREAD_MUTEX_INITIALIZER;
#elif defined(WIN32)
CRITICAL_SECTION _hbaapi_LL_mutex;
#endif
/*
* Macro to use the right function table between smhba and hbaapi.
*/
#define FUNCTABLE(lib_infop) \
((lib_infop->version == SMHBA) ? \
lib_infop->ftable.smhbafunctionTable : \
lib_infop->ftable.functionTable);
/*
* 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.
*/
#define FUNCCOMMON(lib_infop, func) \
((lib_infop->version == SMHBA) ? \
lib_infop->ftable.smhbafunctionTable.func : \
lib_infop->ftable.functionTable.func)
/*
* Macro to use the hbaapi function ptr.
* Should be used for an interface applicable only HBAAPIV2.
*/
#define FUNCHBAAPIV2(lib_infop, func) \
lib_infop->ftable.functionTable.func
/*
* Macro to use the hbaapi function ptr.
* Should be used for an interface applicable only HBAAPIV2.
*/
#define FUNCSMHBA(lib_infop, func) \
lib_infop->ftable.smhbafunctionTable.func
/*
* Individual adapter (hba) information
*/
typedef struct hba_adapter_info {
struct hba_adapter_info
*next;
HBA_STATUS GNstatus; /* status from GetAdapterNameFunc */
char *name;
HBA_WWN nodeWWN;
HBA_LIBRARY_INFO *library;
HBA_UINT32 index;
} HBA_ADAPTER_INFO;
HBA_ADAPTER_INFO *_hbaapi_adapterlist = NULL;
HBA_UINT32 _hbaapi_total_adapter_count = 0;
#ifdef POSIX_THREADS
pthread_mutex_t _hbaapi_AL_mutex = PTHREAD_MUTEX_INITIALIZER;
#elif defined(WIN32)
CRITICAL_SECTION _hbaapi_AL_mutex;
#endif
/*
* Call back registration
*/
typedef struct hba_vendorcallback_elem {
struct hba_vendorcallback_elem
*next;
HBA_CALLBACKHANDLE vendorcbhandle;
HBA_LIBRARY_INFO *lib_info;
} HBA_VENDORCALLBACK_ELEM;
/*
* 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;
HBA_LIBRARY_INFO *lib_info;
void *userdata;
HBA_CALLBACKHANDLE vendorcbhandle;
void (*callback)();
} HBA_ADAPTERCALLBACK_ELEM;
typedef struct hba_alladapterscallback_elem {
struct hba_alladapterscallback_elem
*next;
void *userdata;
HBA_VENDORCALLBACK_ELEM *vendorhandlelist;
void (*callback)();
} HBA_ALLADAPTERSCALLBACK_ELEM;
HBA_ALLADAPTERSCALLBACK_ELEM *_hbaapi_adapteraddevents_callback_list = NULL;
HBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterevents_callback_list = NULL;
HBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterportevents_callback_list = NULL;
HBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterportstatevents_callback_list = NULL;
HBA_ADAPTERCALLBACK_ELEM *_hbaapi_targetevents_callback_list = NULL;
HBA_ADAPTERCALLBACK_ELEM *_hbaapi_linkevents_callback_list = NULL;
HBA_ALLADAPTERSCALLBACK_ELEM *_smhba_adapteraddevents_callback_list = NULL;
HBA_ADAPTERCALLBACK_ELEM *_smhba_adapterevents_callback_list = NULL;
HBA_ADAPTERCALLBACK_ELEM *_smhba_adapterportevents_callback_list = NULL;
HBA_ADAPTERCALLBACK_ELEM *_smhba_adapterportstatevents_callback_list = NULL;
HBA_ADAPTERCALLBACK_ELEM *_smhba_adapterphystatevents_callback_list = NULL;
HBA_ADAPTERCALLBACK_ELEM *_smhba_targetevents_callback_list = NULL;
#ifdef POSIX_THREADS
/* mutex's to protect each list */
pthread_mutex_t _hbaapi_AAE_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _hbaapi_AE_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _hbaapi_APE_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _hbaapi_APSE_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _hbaapi_TE_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _hbaapi_LE_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _smhba_AAE_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _smhba_AE_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _smhba_APE_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _smhba_APSE_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _smhba_APHYSE_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _smhba_TE_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _smhba_LE_mutex = PTHREAD_MUTEX_INITIALIZER;
#elif defined(WIN32)
CRITICAL_SECTION _hbaapi_AAE_mutex;
CRITICAL_SECTION _hbaapi_AE_mutex;
CRITICAL_SECTION _hbaapi_APE_mutex;
CRITICAL_SECTION _hbaapi_APSE_mutex;
CRITICAL_SECTION _hbaapi_TE_mutex;
CRITICAL_SECTION _smhba_AAE_mutex;
CRITICAL_SECTION _smhba_AE_mutex;
CRITICAL_SECTION _smhba_APE_mutex;
CRITICAL_SECTION _smhba_APSE_mutex;
CRITICAL_SECTION _smhba_APHYSE_mutex;
CRITICAL_SECTION _smhba_TE_mutex;
CRITICAL_SECTION _hbaapi_LE_mutex;
#endif
HBA_ADAPTERCALLBACK_ELEM **cb_lists_array[] = {
&_hbaapi_adapterevents_callback_list,
&_hbaapi_adapterportevents_callback_list,
&_hbaapi_adapterportstatevents_callback_list,
&_hbaapi_targetevents_callback_list,
&_hbaapi_linkevents_callback_list,
&_smhba_adapterevents_callback_list,
&_smhba_adapterportevents_callback_list,
&_smhba_adapterportstatevents_callback_list,
&_smhba_adapterphystatevents_callback_list,
&_smhba_targetevents_callback_list,
NULL};
/*
* Common library internal. Mutex handling
*/
#ifdef POSIX_THREADS
static void
grab_mutex(pthread_mutex_t *mp) {
/* LINTED E_FUNC_SET_NOT_USED */
int ret;
if ((ret = pthread_mutex_lock(mp)) != 0) {
perror("pthread_mutex_lock - HBAAPI:");
DEBUG(1, "pthread_mutex_lock returned %d", ret, 0, 0);
}
}
static void
release_mutex(pthread_mutex_t *mp) {
/* LINTED E_FUNC_SET_NOT_USED */
int ret;
if ((ret = pthread_mutex_unlock(mp)) != 0) {
perror("pthread_mutex_unlock - HBAAPI:");
DEBUG(1, "pthread_mutex_unlock returned %d", ret, 0, 0);
}
}
#endif
/*
* Common library internal. Check library and return vendorhandle
*/
static HBA_STATUS
HBA_CheckLibrary(HBA_HANDLE handle,
HBA_LIBRARY_INFO **lib_infopp,
HBA_HANDLE *vendorhandle) {
HBA_UINT32 libraryIndex;
HBA_LIBRARY_INFO *lib_infop;
if (_hbaapi_librarylist == NULL) {
return (HBA_STATUS_ERROR);
}
libraryIndex = LIBRARY_NUM(handle);
GRAB_MUTEX(&_hbaapi_LL_mutex);
for (lib_infop = _hbaapi_librarylist;
lib_infop != NULL;
lib_infop = lib_infop->next) {
if (lib_infop->index == libraryIndex) {
if (lib_infop->status != HBA_LIBRARY_LOADED) {
return (HBA_STATUS_ERROR);
}
*lib_infopp = lib_infop;
*vendorhandle = VENDOR_HANDLE(handle);
/* caller will release the mutex */
return (HBA_STATUS_OK);
}
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INVALID_HANDLE);
}
#define CHECKLIBRARY() \
status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);\
if (status != HBA_STATUS_OK) { \
return (status); \
}
#define CHECKLIBRARYANDVERSION(ver) \
status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle); \
if (status != HBA_STATUS_OK) { \
return (status); \
} else { \
if (ver != lib_infop->version) { \
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, \
HBA_STATUS_ERROR_INCOMPATIBLE); \
} \
}
/*
* freevendorhandlelist is called with _hbaapi_LL_mutex already held
*/
static void
freevendorhandlelist(HBA_VENDORCALLBACK_ELEM *vhlist) {
HBA_VENDORCALLBACK_ELEM *vhlp;
HBA_VENDORCALLBACK_ELEM *vnext;
HBARemoveCallbackFunc registeredfunc;
for (vhlp = vhlist; vhlp != NULL; vhlp = vnext) {
vnext = vhlp->next;
registeredfunc =
FUNCCOMMON(vhlp->lib_info, RemoveCallbackHandler);
if (registeredfunc == NULL) {
continue;
}
(registeredfunc)(vhlp->vendorcbhandle);
free(vhlp);
}
}
static
HBA_STATUS
local_remove_callback(HBA_CALLBACKHANDLE cbhandle) {
HBA_ADAPTERCALLBACK_ELEM ***listp;
HBA_ADAPTERCALLBACK_ELEM **lastp;
HBA_ALLADAPTERSCALLBACK_ELEM **lap;
HBA_ALLADAPTERSCALLBACK_ELEM *allcbp;
HBA_ADAPTERCALLBACK_ELEM *cbp;
HBARemoveCallbackFunc registeredfunc;
HBA_VENDORCALLBACK_ELEM *vhlp;
HBA_VENDORCALLBACK_ELEM *vnext;
int found;
HBA_STATUS status = HBA_STATUS_ERROR_INVALID_HANDLE;
/* search through the simple lists first */
GRAB_MUTEX(&_hbaapi_AAE_mutex);
GRAB_MUTEX(&_hbaapi_AE_mutex);
GRAB_MUTEX(&_hbaapi_APE_mutex);
GRAB_MUTEX(&_hbaapi_APSE_mutex);
GRAB_MUTEX(&_hbaapi_TE_mutex);
GRAB_MUTEX(&_hbaapi_LE_mutex);
GRAB_MUTEX(&_smhba_AAE_mutex);
GRAB_MUTEX(&_smhba_AE_mutex);
GRAB_MUTEX(&_smhba_APE_mutex);
GRAB_MUTEX(&_smhba_APSE_mutex);
GRAB_MUTEX(&_smhba_TE_mutex);
for (listp = cb_lists_array, found = 0;
(found == 0 && *listp != NULL); listp++) {
lastp = *listp;
for (cbp = **listp; cbp != NULL; cbp = cbp->next) {
if (cbhandle != (HBA_CALLBACKHANDLE)cbp) {
lastp = &(cbp->next);
continue;
}
found = 1;
registeredfunc =
FUNCCOMMON(cbp->lib_info, RemoveCallbackHandler);
if (registeredfunc == NULL) {
break;
}
(registeredfunc)(cbp->vendorcbhandle);
*lastp = cbp->next;
free(cbp);
break;
}
}
RELEASE_MUTEX(&_hbaapi_LE_mutex);
RELEASE_MUTEX(&_hbaapi_TE_mutex);
RELEASE_MUTEX(&_hbaapi_APSE_mutex);
RELEASE_MUTEX(&_hbaapi_APE_mutex);
RELEASE_MUTEX(&_hbaapi_AE_mutex);
RELEASE_MUTEX(&_hbaapi_AAE_mutex);
RELEASE_MUTEX(&_smhba_AAE_mutex);
RELEASE_MUTEX(&_smhba_AE_mutex);
RELEASE_MUTEX(&_smhba_APE_mutex);
RELEASE_MUTEX(&_smhba_APSE_mutex);
RELEASE_MUTEX(&_smhba_TE_mutex);
if (found != 0) {
if (registeredfunc == NULL) {
return (HBA_STATUS_ERROR_NOT_SUPPORTED);
}
return (HBA_STATUS_OK);
}
GRAB_MUTEX(&_hbaapi_AAE_mutex);
/*
* if it wasnt in the simple lists,
* look in the list for adapteraddevents
*/
lap = &_hbaapi_adapteraddevents_callback_list;
for (allcbp = _hbaapi_adapteraddevents_callback_list;
allcbp != NULL;
allcbp = allcbp->next) {
if (cbhandle != (HBA_CALLBACKHANDLE)allcbp) {
lap = &allcbp->next;
continue;
}
for (vhlp = allcbp->vendorhandlelist; vhlp != NULL; vhlp = vnext) {
vnext = vhlp->next;
/* should be HBAAPIV2 VSL to get to here */
registeredfunc =
vhlp->lib_info->ftable.functionTable.RemoveCallbackHandler;
if (registeredfunc == NULL) {
continue;
}
(registeredfunc)(vhlp->vendorcbhandle);
free(vhlp);
}
*lap = allcbp->next;
free(allcbp);
status = HBA_STATUS_OK;
break;
}
RELEASE_MUTEX(&_hbaapi_AAE_mutex);
/* now search smhba adapteradd events. */
GRAB_MUTEX(&_smhba_AAE_mutex);
lap = &_smhba_adapteraddevents_callback_list;
for (allcbp = _smhba_adapteraddevents_callback_list;
allcbp != NULL;
allcbp = allcbp->next) {
if (cbhandle != (HBA_CALLBACKHANDLE)allcbp) {
lap = &allcbp->next;
continue;
}
for (vhlp = allcbp->vendorhandlelist; vhlp != NULL; vhlp = vnext) {
vnext = vhlp->next;
/* should be SMHBA VSL to get to here */
registeredfunc =
vhlp->lib_info->
ftable.smhbafunctionTable.RemoveCallbackHandler;
if (registeredfunc == NULL) {
continue;
}
(registeredfunc)(vhlp->vendorcbhandle);
free(vhlp);
}
*lap = allcbp->next;
free(allcbp);
status = HBA_STATUS_OK;
break;
}
RELEASE_MUTEX(&_smhba_AAE_mutex);
return (status);
}
/* LINTED E_STATIC_UE_STATIC_UNUSED */
static char wwn_str1[17];
/* LINTED E_STATIC_UE_STATIC_UNUSED */
static char wwn_str2[17];
/* LINTED E_STATIC_UE_STATIC_UNUSED */
static char wwn_str3[17];
#define WWN2STR1(wwn) WWN2str(wwn_str1, (wwn))
#define WWN2STR2(wwn) WWN2str(wwn_str2, (wwn))
#define WWN2STR3(wwn) WWN2str(wwn_str3, (wwn))
static char *
/* LINTED E_STATIC_UE_STATIC_UNUSED */
WWN2str(char *buf, HBA_WWN *wwn) {
int j;
unsigned char *pc = (unsigned char *)&(wwn->wwn[0]);
buf[0] = '\0';
for (j = 0; j < 16; j += 2) {
(void) sprintf(&buf[j], "%02X", (int)*pc++);
}
return (buf);
}
#ifdef WIN32
BOOL APIENTRY
DllMain(HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
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
*/
HBA_STATUS
HBA_LoadLibrary()
{
HBARegisterLibraryFunc RegisterFunc;
HBARegisterLibraryV2Func RegisterV2Func;
SMHBARegisterLibraryFunc RegisterSMHBAFunc;
HBALoadLibraryFunc LoadLibraryFunc;
HBAGetVersionFunc GetVersionFunc;
#ifdef POSIX_THREADS
int ret;
#endif
HBA_STATUS status;
HBA_UINT32 libversion;
/* Open configuration file from known location */
#ifdef WIN32
LONG lStatus;
HKEY hkSniaHba, hkVendorLib;
FILETIME ftLastWriteTime;
TCHAR cSubKeyName[256];
DWORD i, dwSize, dwType;
BYTE byFileName[MAX_PATH];
HBA_LIBRARY_INFO *lib_infop;
if (_hbaapi_librarylist != NULL) {
/* this is an app programming error */
return (HBA_STATUS_ERROR);
}
lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\SNIA\\HBA",
0, KEY_READ, &hkSniaHba);
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++) {
dwSize = 255; /* how big the buffer is */
lStatus = RegEnumKeyEx(hkSniaHba, i,
(char *)&cSubKeyName, &dwSize, NULL,
NULL, NULL, &ftLastWriteTime);
if (lStatus == ERROR_NO_MORE_ITEMS) {
break; /* we're done */
} else if (lStatus == ERROR_MORE_DATA) { /* buffer not big enough */
/* do whatever */
;
}
/* Now open the subkey that pertains to this vendor's library */
lStatus = RegOpenKeyEx(hkSniaHba, cSubKeyName, 0, KEY_READ,
&hkVendorLib);
if (lStatus != ERROR_SUCCESS) {
RegCloseKey(hkSniaHba);
/* ???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"
*/
dwSize = MAX_PATH;
lStatus = RegQueryValueEx(hkVendorLib, "LibraryFile", NULL, &dwType,
byFileName, &dwSize);
if (lStatus != ERROR_SUCCESS) {
RegCloseKey(hkVendorLib);
/* ???Opportunity to send error msg, installation error */
continue;
}
lib_infop = (HBA_LIBRARY_INFO *)calloc(1, sizeof (HBA_LIBRARY_INFO));
if (lib_infop == NULL) {
/* what is the right thing to do in MS land??? */
RegCloseKey(hkVendorLib);
/* ???Opportunity to send error msg, installation error */
return (HBA_STATUS_ERROR);
}
lib_infop->status = HBA_LIBRARY_NOT_LOADED;
lib_infop->next = _hbaapi_librarylist;
lib_infop->index = _hbaapi_total_library_count;
_hbaapi_total_library_count++;
_hbaapi_librarylist = lib_infop;
/* Now I can try to load the library */
lib_infop->hLibrary = LoadLibrary(byFileName);
if (lib_infop->hLibrary == NULL) {
/* printf("unable to load library %s\n", librarypath); */
/* ???Opportunity to send error msg, installation error */
goto dud_library;
}
lib_infop->LibraryPath = strdup(byFileName);
DEBUG(1, "HBAAPI loading: %s\n", byFileName, 0, 0);
RegisterSMHBAFunc = (SMHBARegisterLibraryFunc)
GetProcAddress(lib_infop->hLibrary, "SMHBA_RegisterLibrary");
if (RegisterSMHBAFunc != NULL) {
status = ((RegisterSMHBAFunc)(SMHBA_ENTRYPOINTS *)
(&lib_infop->ftable.smhbafunctionTable));
if (status != HBA_STATUS_OK) {
/* library not loaded */
/* ???Opportunity to send error msg, library error? */
goto dud_library;
} else {
lib_infop->version = SMHBA;
}
} else {
/* Call the registration function to get the list of pointers */
RegisterV2Func = (HBARegisterLibraryV2Func)GetProcAddress(
lib_infop->hLibrary, "HBA_RegisterLibraryV2");
if (RegisterV2Func != NULL) {
/*
* Load the function pointers directly into
* the table of functions
*/
status = ((RegisterV2Func)
(HBA_ENTRYPOINTSV2 *)(&lib_infop->ftable.functionTable));
if (status != HBA_STATUS_OK) {
/* library not loaded */
/* ???Opportunity to send error msg, library error? */
goto dud_library;
} else {
lib_infop->version = HBAAPIV2;
}
} else {
/* Maybe the vendor library is only Rev1 */
RegisterFunc = (HBARegisterLibraryFunc)
GetProcAddress(lib_infop->hLibrary, "HBA_RegisterLibrary");
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)(
(HBA_ENTRYPOINTS *)(&lib_infop->ftable.functionTable)));
if (status != HBA_STATUS_OK) {
/* library not loaded */
/* ???Opportunity to send error msg, library error? */
goto dud_library;
} else {
lib_infop->version = HBAAPI;
}
}
}
/* 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.
*/
GetVersionFunc = FUNCCOMMON(lib_infop, GetVersionHandler);
if (GetVersionFunc != NULL) {
if (lib_infop->version == SMHBA) {
/* 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;
}
LoadLibraryFunc = FUNCCOMMON(lib_infop, LoadLibraryHandler);
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 */
lib_infop->status = HBA_LIBRARY_LOADED;
dud_library: /* its also just the end of the loop */
RegCloseKey(hkVendorLib);
}
RegCloseKey(hkSniaHba);
#else /* Unix as opposed to Win32 */
FILE *hbaconf;
char fullline[512]; /* line read from HBA.conf */
char *libraryname; /* Read in from file HBA.conf */
char *librarypath; /* Read in from file HBA.conf */
char hbaConfFilePath[256];
char *charPtr;
HBA_LIBRARY_INFO *lib_infop;
GRAB_MUTEX(&_hbaapi_LL_mutex);
if (_hbaapi_librarylist != NULL) {
(void) fprintf(stderr,
"HBA_LoadLibrary: previously unfreed "
"libraries exist, call HBA_FreeLibrary().\n");
RELEASE_MUTEX(&_hbaapi_LL_mutex);
return (HBA_STATUS_ERROR);
}
(void) strcpy(hbaConfFilePath, "/etc/smhba.conf");
if ((hbaconf = fopen(hbaConfFilePath, "r")) == NULL) {
(void) printf("Cannot open %s\n", hbaConfFilePath);
RELEASE_MUTEX(&_hbaapi_LL_mutex);
return (HBA_STATUS_ERROR);
}
/* Read in each line and load library */
while ((hbaconf != NULL) &&
(fgets(fullline, sizeof (fullline), hbaconf))) {
/* Skip the comments... */
if ((fullline[0] == '#') || (fullline[0] == '\n')) {
continue;
}
/* grab first 'thing' in line (if its there) */
if ((libraryname = strtok(fullline, " \t\n")) != NULL) {
if (strlen(libraryname) >= 64) {
(void) fprintf(stderr,
"Library name(%s) in %s is > 64 characters\n",
libraryname, hbaConfFilePath);
}
}
/* grab second 'thing' in line (if its there) */
if ((librarypath = strtok(NULL, " \t\n")) != NULL) {
if (strlen(librarypath) >= 256) {
(void) fprintf(stderr,
"Library path(%s) in %s is > 256 characters\n",
librarypath, hbaConfFilePath);
}
}
/* there should be no more 'things' in the line */
if ((charPtr = strtok(NULL, " \n\t")) != NULL) {
(void) fprintf(stderr, "Extraneous characters (\"%s\") in %s\n",
charPtr, hbaConfFilePath);
}
/* 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
*/
if (strcmp(libraryname, "debuglevel") == 0) {
_hbaapi_debuglevel = strtol(librarypath, NULL, 10);
/* error handling does the right thing automagically */
continue;
}
lib_infop = (HBA_LIBRARY_INFO *)calloc(1, sizeof (HBA_LIBRARY_INFO));
if (lib_infop == NULL) {
(void) fprintf(stderr, "HBA_LoadLibrary: out of memeory\n");
RELEASE_MUTEX(&_hbaapi_LL_mutex);
return (HBA_STATUS_ERROR);
}
lib_infop->status = HBA_LIBRARY_NOT_LOADED;
lib_infop->LibraryName = strdup(libraryname);
lib_infop->LibraryPath = strdup(librarypath);
lib_infop->numOfAdapters = 0;
lib_infop->version = UNKNOWN;
lib_infop->index = _hbaapi_total_library_count;
_hbaapi_total_library_count++;
lib_infop->next = _hbaapi_librarylist;
_hbaapi_librarylist = lib_infop;
/* Load the DLL now */
if ((lib_infop->hLibrary = dlopen(librarypath, RTLD_LAZY)) == NULL) {
/* printf("unable to load library %s\n", librarypath); */
continue;
}
/* Call the registration function to get the list of pointers */
RegisterSMHBAFunc = (SMHBARegisterLibraryFunc)
dlsym(lib_infop->hLibrary, "SMHBA_RegisterLibrary");
if (RegisterSMHBAFunc != NULL) {
/*
* Load the function points directly into
* the table of functions
*/
status = ((RegisterSMHBAFunc)
(&lib_infop->ftable.smhbafunctionTable));
if (status != HBA_STATUS_OK) {
/* library not loaded */
continue;
} else {
lib_infop->version = SMHBA;
}
} else {
RegisterV2Func = (HBARegisterLibraryV2Func)
dlsym(lib_infop->hLibrary, "HBA_RegisterLibraryV2");
if (RegisterV2Func != NULL) {
/*
* Load the function points directly into
* the table of functions
*/
status = ((RegisterV2Func)((HBA_ENTRYPOINTSV2 *)
(&lib_infop->ftable.functionTable)));
if (status != HBA_STATUS_OK) {
/* library not loaded */
continue;
} else {
lib_infop->version = HBAAPIV2;
}
} else {
/* Maybe the vendor library is only Rev1 */
RegisterFunc = (HBARegisterLibraryFunc)
dlsym(lib_infop->hLibrary, "HBA_RegisterLibrary");
if (RegisterFunc == NULL) {
/* This function is required */
(void) fprintf(stderr,
"HBA_LoadLibrary: vendor specific RegisterLibrary "
"function not found. lib: %s\n", librarypath);
DEBUG(1, "HBA_LoadLibrary: vendor specific "
"RegisterLibrary function not found. lib: %s\n",
librarypath, 0, 0);
continue;
}
/*
* Load the function points directly into
* the table of functions
*/
status = ((RegisterFunc)
((HBA_ENTRYPOINTS *)(&lib_infop->ftable.functionTable)));
if (status != HBA_STATUS_OK) {
/* library not loaded */
(void) fprintf(stderr,
"HBA_LoadLibrary: vendor specific RegisterLibrary "
"function encountered an error. lib: %s\n",
librarypath);
DEBUG(1,
"HBA_LoadLibrary: vendor specific RegisterLibrary "
"function encountered an error. lib: %s\n",
librarypath, 0, 0);
continue;
} else {
lib_infop->version = HBAAPI;
}
}
}
/* 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 = FUNCCOMMON(lib_infop, GetVersionHandler))
== NULL) {
continue;
}
if (lib_infop->version == SMHBA) {
libversion = ((GetVersionFunc)());
if (libversion < SMHBA_LIBVERSION) {
(void) printf("Library version mismatch."
"Got %d expected %d.\n",
libversion, SMHBA_LIBVERSION);
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",
libversion, HBA_LIBVERSION);
continue;
}
}
DEBUG(1, "%s libversion = %d", librarypath, libversion, 0);
LoadLibraryFunc = FUNCCOMMON(lib_infop, LoadLibraryHandler);
if (LoadLibraryFunc == NULL) {
/* this function is required */
(void) fprintf(stderr,
"HBA_LoadLibrary: vendor specific LoadLibrary "
"function not found. lib: %s\n", librarypath);
DEBUG(1, "HBA_LoadLibrary: vendor specific LoadLibrary "
"function not found. lib: %s\n", librarypath, 0, 0);
continue;
}
/* Initialize this library */
if ((status = ((LoadLibraryFunc)())) != HBA_STATUS_OK) {
/* maybe this should be a printf so that we CANNOT miss it */
(void) fprintf(stderr,
"HBA_LoadLibrary: Encounterd and error loading: %s",
librarypath);
DEBUG(1, "Encounterd and error loading: %s", librarypath, 0, 0);
DEBUG(1, " HBA_STATUS: %d", status, 0, 0);
continue;
}
/* successfully loaded library */
lib_infop->status = HBA_LIBRARY_LOADED;
}
#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...
*/
ret = pthread_mutex_init(&_hbaapi_AL_mutex, NULL);
if (ret == 0) {
ret = pthread_mutex_init(&_hbaapi_AAE_mutex, NULL);
}
if (ret == 0) {
ret = pthread_mutex_init(&_hbaapi_AE_mutex, NULL);
}
if (ret == 0) {
ret = pthread_mutex_init(&_hbaapi_APE_mutex, NULL);
}
if (ret == 0) {
ret = pthread_mutex_init(&_hbaapi_APSE_mutex, NULL);
}
if (ret == 0) {
ret = pthread_mutex_init(&_hbaapi_TE_mutex, NULL);
}
if (ret == 0) {
ret = pthread_mutex_init(&_smhba_AAE_mutex, NULL);
}
if (ret == 0) {
ret = pthread_mutex_init(&_smhba_AE_mutex, NULL);
}
if (ret == 0) {
ret = pthread_mutex_init(&_smhba_APE_mutex, NULL);
}
if (ret == 0) {
ret = pthread_mutex_init(&_smhba_APSE_mutex, NULL);
}
if (ret == 0) {
ret = pthread_mutex_init(&_smhba_TE_mutex, NULL);
}
if (ret == 0) {
ret = pthread_mutex_init(&_hbaapi_LE_mutex, NULL);
}
if (ret != 0) {
perror("pthread_mutex_init - HBA_LoadLibrary");
RELEASE_MUTEX(&_hbaapi_LL_mutex);
return (HBA_STATUS_ERROR);
}
RELEASE_MUTEX(&_hbaapi_LL_mutex);
#elif defined(WIN32)
InitializeCriticalSection(&_hbaapi_LL_mutex);
InitializeCriticalSection(&_hbaapi_AL_mutex);
InitializeCriticalSection(&_hbaapi_AAE_mutex);
InitializeCriticalSection(&_hbaapi_AE_mutex);
InitializeCriticalSection(&_hbaapi_APE_mutex);
InitializeCriticalSection(&_hbaapi_APSE_mutex);
InitializeCriticalSection(&_hbaapi_TE_mutex);
InitializeCriticalSection(&_hbaapi_LE_mutex);
InitializeCriticalSection(&_smhba_AAE_mutex);
InitializeCriticalSection(&_smhba_AE_mutex);
InitializeCriticalSection(&_smhba_APE_mutex);
InitializeCriticalSection(&_smhba_APSE_mutex);
InitializeCriticalSection(&_smhba_TE_mutex);
#endif
return (HBA_STATUS_OK);
}
HBA_STATUS
HBA_FreeLibrary() {
HBAFreeLibraryFunc FreeLibraryFunc;
/* LINTED E_FUNC_SET_NOT_USED */
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_LIBRARY_INFO *lib_next;
HBA_ADAPTERCALLBACK_ELEM
***listp;
HBA_ADAPTER_INFO *adapt_infop;
HBA_ADAPTER_INFO *adapt_next;
GRAB_MUTEX(&_hbaapi_LL_mutex);
if (_hbaapi_librarylist == NULL) {
RELEASE_MUTEX(&_hbaapi_LL_mutex);
return (HBA_STATUS_ERROR_NOT_LOADED);
}
GRAB_MUTEX(&_hbaapi_AL_mutex);
DEBUG(1, "HBA_FreeLibrary()", 0, 0, 0);
for (lib_infop = _hbaapi_librarylist; lib_infop != NULL;
lib_infop = lib_next) {
lib_next = lib_infop->next;
if (lib_infop->status == HBA_LIBRARY_LOADED) {
FreeLibraryFunc = FUNCCOMMON(lib_infop, FreeLibraryHandler);
if (FreeLibraryFunc != NULL) {
/* Free this library */
status = ((FreeLibraryFunc)());
DEBUG(1, "HBA_FreeLibrary() Failed %d", status, 0, 0);
}
#ifdef WIN32
FreeLibrary(lib_infop->hLibrary); /* Unload DLL from memory */
#else
(void) dlclose(lib_infop->hLibrary); /* Unload DLL from memory */
#endif
}
#ifndef WIN32
free(lib_infop->LibraryName);
#endif
free(lib_infop->LibraryPath);
free(lib_infop);
}
_hbaapi_librarylist = NULL;
/*
* OK, now all functions are disabled except for LoadLibrary,
* Hope no other thread calls it before we have returned
*/
_hbaapi_total_library_count = 0;
for (adapt_infop = _hbaapi_adapterlist;
adapt_infop != NULL;
adapt_infop = adapt_next) {
adapt_next = adapt_infop->next;
free(adapt_infop->name);
free(adapt_infop);
}
_hbaapi_adapterlist = NULL;
_hbaapi_total_adapter_count = 0;
/*
* Free up the callbacks, this is not the most efficient, but it works
*/
while ((volatile HBA_ADAPTERCALLBACK_ELEM *)
_hbaapi_adapteraddevents_callback_list
!= NULL) {
(void) local_remove_callback((HBA_CALLBACKHANDLE)
_hbaapi_adapteraddevents_callback_list);
}
while ((volatile HBA_ADAPTERCALLBACK_ELEM *)
_smhba_adapteraddevents_callback_list
!= NULL) {
(void) local_remove_callback((HBA_CALLBACKHANDLE)
_smhba_adapteraddevents_callback_list);
}
for (listp = cb_lists_array; *listp != NULL; listp++) {
while ((volatile HBA_ADAPTERCALLBACK_ELEM ***)**listp != NULL) {
(void) local_remove_callback((HBA_CALLBACKHANDLE)**listp);
}
}
RELEASE_MUTEX(&_hbaapi_AL_mutex);
RELEASE_MUTEX(&_hbaapi_LL_mutex);
#ifdef USESYSLOG
closelog();
#endif
#ifdef USELOGFILE
if (_hbaapi_debug_fd != NULL) {
fclose(_hbaapi_debug_fd);
}
_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);
#elif defined(WIN32)
DeleteCriticalSection(&_hbaapi_LL_mutex);
DeleteCriticalSection(&_hbaapi_AL_mutex);
DeleteCriticalSection(&_hbaapi_AAE_mutex);
DeleteCriticalSection(&_hbaapi_AE_mutex);
DeleteCriticalSection(&_hbaapi_APE_mutex);
DeleteCriticalSection(&_hbaapi_APSE_mutex);
DeleteCriticalSection(&_hbaapi_TE_mutex);
DeleteCriticalSection(&_hbaapi_LE_mutex);
DeleteCriticalSection(&_smhba_TE_mutex);
DeleteCriticalSection(&_smhba_APSE_mutex);
DeleteCriticalSection(&_smhba_APE_mutex);
DeleteCriticalSection(&_smhba_AE_mutex);
DeleteCriticalSection(&_smhba_AAE_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
*/
HBA_UINT32
HBA_GetNumberOfAdapters()
{
int j = 0;
HBA_LIBRARY_INFO *lib_infop;
HBAGetNumberOfAdaptersFunc GetNumberOfAdaptersFunc;
HBAGetAdapterNameFunc GetAdapterNameFunc;
HBA_BOOLEAN found_name;
HBA_ADAPTER_INFO *adapt_infop;
HBA_STATUS status;
char adaptername[256];
int num_adapters; /* local */
if (_hbaapi_librarylist == NULL) {
return (0);
}
GRAB_MUTEX(&_hbaapi_LL_mutex); /* pay attention to order */
GRAB_MUTEX(&_hbaapi_AL_mutex);
for (lib_infop = _hbaapi_librarylist;
lib_infop != NULL;
lib_infop = lib_infop->next) {
if (lib_infop->status != HBA_LIBRARY_LOADED) {
continue;
}
GetNumberOfAdaptersFunc =
FUNCCOMMON(lib_infop, GetNumberOfAdaptersHandler);
if (GetNumberOfAdaptersFunc == NULL) {
continue;
}
num_adapters = ((GetNumberOfAdaptersFunc)());
#ifndef WIN32
DEBUG(1, "HBAAPI: num_adapters for %s = %d\n",
lib_infop->LibraryName, num_adapters, 0);
#else
DEBUG(1, "HBAAPI: num_adapters for %s = %d\n",
lib_infop->LibraryPath, num_adapters, 0);
#endif
/* Also get the names of all the adapters here and cache */
GetAdapterNameFunc = FUNCCOMMON(lib_infop, GetAdapterNameHandler);
if (GetAdapterNameFunc == NULL) {
continue;
}
for (j = 0; j < num_adapters; j++) {
found_name = 0;
status = (GetAdapterNameFunc)(j, (char *)&adaptername);
if (status == HBA_STATUS_OK) {
for (adapt_infop = _hbaapi_adapterlist;
adapt_infop != NULL;
adapt_infop = adapt_infop->next) {
/*
* check for duplicates, really,
* this may just be a second
* call to this function
* ??? how do we know when a name becomes stale?
*/
if (strcmp(adaptername, adapt_infop->name) == 0) {
/* already got this one */
found_name++;
break;
}
}
if (found_name != 0) {
continue;
}
}
adapt_infop = (HBA_ADAPTER_INFO *)
calloc(1, sizeof (HBA_ADAPTER_INFO));
if (adapt_infop == NULL) {
#ifndef WIN32
(void) fprintf(stderr,
"HBA_GetNumberOfAdapters: calloc failed"
" on sizeof:%lu\n",
(unsigned long)(sizeof (HBA_ADAPTER_INFO)));
#endif
RELEASE_MUTEX(&_hbaapi_AL_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
_hbaapi_total_adapter_count);
}
if ((adapt_infop->GNstatus = status) == HBA_STATUS_OK) {
adapt_infop->name = strdup(adaptername);
} else {
char dummyname[512];
(void) sprintf(dummyname, "NULLADAPTER-%255s-%03d",
lib_infop->LibraryPath, _hbaapi_total_adapter_count);
dummyname[511] = '\0';
adapt_infop->name = strdup(dummyname);
}
lib_infop->numOfAdapters++;
adapt_infop->library = lib_infop;
adapt_infop->next = _hbaapi_adapterlist;
adapt_infop->index = _hbaapi_total_adapter_count;
_hbaapi_adapterlist = adapt_infop;
_hbaapi_total_adapter_count++;
}
}
RELEASE_MUTEX(&_hbaapi_AL_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, _hbaapi_total_adapter_count);
}
HBA_STATUS
HBA_GetAdapterName(
HBA_UINT32 adapterindex,
char *adaptername)
{
HBA_ADAPTER_INFO *adapt_infop;
HBA_STATUS ret = HBA_STATUS_ERROR_ILLEGAL_INDEX;
if (adaptername == NULL) {
DEBUG(1, "HBA_GetAdapterName: NULL pointer adatpername",
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
*/
ARE_WE_INITED();
GRAB_MUTEX(&_hbaapi_AL_mutex);
*adaptername = '\0';
for (adapt_infop = _hbaapi_adapterlist;
adapt_infop != NULL;
adapt_infop = adapt_infop->next) {
if (adapt_infop->index == adapterindex) {
if (adapt_infop->name != NULL &&
adapt_infop->GNstatus == HBA_STATUS_OK) {
(void) strcpy(adaptername, adapt_infop->name);
} else {
*adaptername = '\0';
}
ret = adapt_infop->GNstatus;
break;
}
}
DEBUG(2, "GetAdapterName for index:%d ->%s",
adapterindex, adaptername, 0);
RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, ret);
}
HBA_HANDLE
HBA_OpenAdapter(char *adaptername)
{
HBA_HANDLE handle;
HBAOpenAdapterFunc OpenAdapterFunc;
HBA_ADAPTER_INFO *adapt_infop;
HBA_LIBRARY_INFO *lib_infop;
DEBUG(2, "OpenAdapter: %s", adaptername, 0, 0);
handle = HBA_HANDLE_INVALID;
if (_hbaapi_librarylist == NULL) {
return (handle);
}
if (adaptername == NULL) {
DEBUG(1, "HBA_OpenAdapter: NULL pointer adatpername",
0, 0, 0);
return (handle);
}
GRAB_MUTEX(&_hbaapi_AL_mutex);
for (adapt_infop = _hbaapi_adapterlist;
adapt_infop != NULL;
adapt_infop = adapt_infop->next) {
if (strcmp(adaptername, adapt_infop->name) != 0) {
continue;
}
lib_infop = adapt_infop->library;
OpenAdapterFunc = FUNCCOMMON(lib_infop, OpenAdapterHandler);
if (OpenAdapterFunc != NULL) {
/* retrieve the vendor handle */
handle = (OpenAdapterFunc)(adaptername);
if (handle != 0) {
/* or this with the library index to get the common handle */
handle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle);
}
}
break;
}
RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, handle);
}
/*
* Finding an adapter with matching WWN.
*/
HBA_STATUS
HBA_OpenAdapterByWWN(HBA_HANDLE *phandle, HBA_WWN nodeWWN) {
HBA_HANDLE handle;
HBA_LIBRARY_INFO *lib_infop;
HBAGetNumberOfAdaptersFunc
GetNumberOfAdaptersFunc;
HBAOpenAdapterByWWNFunc
OpenAdapterFunc;
HBA_STATUS status;
DEBUG(2, "OpenAdapterByWWN: %s", WWN2STR1(&nodeWWN), 0, 0);
ARE_WE_INITED();
*phandle = HBA_HANDLE_INVALID;
GRAB_MUTEX(&_hbaapi_LL_mutex);
for (lib_infop = _hbaapi_librarylist;
lib_infop != NULL;
lib_infop = lib_infop->next) {
status = HBA_STATUS_ERROR_ILLEGAL_WWN;
if (lib_infop->status != HBA_LIBRARY_LOADED) {
continue;
}
/* only for HBAAPIV2 */
if (lib_infop->version != HBAAPIV2) {
continue;
}
GetNumberOfAdaptersFunc =
FUNCCOMMON(lib_infop, GetNumberOfAdaptersHandler);
if (GetNumberOfAdaptersFunc == NULL) {
continue;
}
/* look for new hardware */
(void) ((GetNumberOfAdaptersFunc)());
OpenAdapterFunc =
lib_infop->ftable.functionTable.OpenAdapterByWWNHandler;
if (OpenAdapterFunc == NULL) {
continue;
}
/*
* We do not know if the WWN is known by this vendor,
* just try it
*/
if ((status = (OpenAdapterFunc)(&handle, nodeWWN)) != HBA_STATUS_OK) {
continue;
}
/* OK, make a vendor non-specific handle */
*phandle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle);
status = HBA_STATUS_OK;
break;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
void
HBA_RefreshAdapterConfiguration() {
DEBUG(2, "HBA_RefreshAdapterConfiguration", 0, 0, 0);
(void) HBA_GetNumberOfAdapters();
}
HBA_UINT32
HBA_GetVersion() {
DEBUG(2, "HBA_GetVersion", 0, 0, 0);
return (HBA_LIBVERSION);
}
/*
* This function is VERY OS dependent. Wing it as best you can.
*/
HBA_UINT32
HBA_GetWrapperLibraryAttributes(
HBA_LIBRARYATTRIBUTES *attributes)
{
DEBUG(2, "HBA_GetWrapperLibraryAttributes", 0, 0, 0);
if (attributes == NULL) {
DEBUG(1, "HBA_GetWrapperLibraryAttributes:"
"NULL pointer attributes",
0, 0, 0);
return (HBA_STATUS_ERROR_ARG);
}
(void) memset(attributes, 0, sizeof (HBA_LIBRARYATTRIBUTES));
#if defined(SOLARIS)
if ((handle = dlopen("libHBAAPI.so", RTLD_NOW)) != NULL) {
if (dlinfo(handle, RTLD_DI_LINKMAP, &map) >= 0) {
for (mp = map; mp != NULL; mp = mp->l_next) {
if (strlen(map->l_name) < 256) {
(void) strcpy(attributes->LibPath, map->l_name);
}
}
}
}
#elif defined(WIN32)
HMODULE module;
/* No need to do anything with the module handle */
/* It wasn't alloocated so it doesn't need to be freed */
module = GetModuleHandle("HBAAPI");
if (module != NULL) {
if (GetModuleFileName(module, attributes->LibPath,
sizeof (attributes->LibPath)) == 0) {
attributes->LibPath[0] = '\0';
}
}
#endif
#if defined(VENDOR)
(void) strcpy(attributes->VName, VENDOR);
#else
attributes->VName[0] = '\0';
#endif
#if defined(VERSION)
(void) strcpy(attributes->VVersion, VERSION);
#else
attributes->VVersion[0] = '\0';
#endif
#if defined(BUILD_DATE)
#if defined(WIN32)
int matchCount;
matchCount = sscanf(BUILD_DATE, "%u/%u/%u %u:%u:%u",
&attributes->build_date.tm_year,
&attributes->build_date.tm_mon,
&attributes->build_date.tm_mday,
&attributes->build_date.tm_hour,
&attributes->build_date.tm_min,
&attributes->build_date.tm_sec);
if (matchCount != 6) {
memset(&attributes->build_date, 0, sizeof (struct tm));
} else {
attributes->build_date.tm_year -= 1900;
attributes->build_date.tm_isdst = -1;
}
#else
if (strptime(BUILD_DATE,
"%Y/%m/%d %T %Z", &(attributes->build_date)) == NULL) {
(void) memset(&attributes->build_date, 0, sizeof (struct tm));
}
#endif
#else
(void) memset(&attributes->build_date, 0, sizeof (struct tm));
#endif
return (2);
}
/*
* Callback registation and handling
*/
HBA_STATUS
HBA_RemoveCallback(HBA_CALLBACKHANDLE cbhandle) {
HBA_STATUS status;
DEBUG(2, "HBA_RemoveCallback", 0, 0, 0);
ARE_WE_INITED();
GRAB_MUTEX(&_hbaapi_LL_mutex);
status = local_remove_callback(cbhandle);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
/* Adapter Add Events ************************************************* */
static void
/* LINTED E_FUNC_ARG_UNUSED */
adapteraddevents_callback(void *data, HBA_WWN PortWWN, HBA_UINT32 eventType) {
HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
DEBUG(3, "AddAdapterEvent, port: %s", WWN2STR1(&PortWWN), 0, 0);
GRAB_MUTEX(&_hbaapi_AAE_mutex);
for (cbp = _hbaapi_adapteraddevents_callback_list;
cbp != NULL;
cbp = cbp->next) {
(*cbp->callback)(data, PortWWN, HBA_EVENT_ADAPTER_ADD);
}
RELEASE_MUTEX(&_hbaapi_AAE_mutex);
}
HBA_STATUS
HBA_RegisterForAdapterAddEvents(
void (*callback)(
void *data,
HBA_WWN PortWWN,
HBA_UINT32 eventType),
void *userData,
HBA_CALLBACKHANDLE *callbackHandle) {
HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
HBA_VENDORCALLBACK_ELEM *vcbp;
HBA_VENDORCALLBACK_ELEM *vendorhandlelist;
HBARegisterForAdapterAddEventsFunc registeredfunc;
HBA_STATUS status = HBA_STATUS_OK;
HBA_STATUS failure = HBA_STATUS_OK;
HBA_LIBRARY_INFO *lib_infop;
int registered_cnt = 0;
int vendor_cnt = 0;
int not_supported_cnt = 0;
int status_OK_bar_cnt = 0;
int status_OK_cnt = 0;
DEBUG(2, "HBA_RegisterForAdapterAddEvents", 0, 0, 0);
ARE_WE_INITED();
cbp = (HBA_ALLADAPTERSCALLBACK_ELEM *)
calloc(1, sizeof (HBA_ALLADAPTERSCALLBACK_ELEM));
*callbackHandle = (HBA_CALLBACKHANDLE) cbp;
if (cbp == NULL) {
#ifndef WIN32
(void) fprintf(stderr,
"HBA_RegisterForAdapterAddEvents: calloc failed "
"for %lu bytes\n",
(unsigned long)(sizeof (HBA_ALLADAPTERSCALLBACK_ELEM)));
#endif
return (HBA_STATUS_ERROR);
}
GRAB_MUTEX(&_hbaapi_LL_mutex);
GRAB_MUTEX(&_hbaapi_AAE_mutex);
cbp->callback = callback;
cbp->next = _hbaapi_adapteraddevents_callback_list;
_hbaapi_adapteraddevents_callback_list = cbp;
/*
* 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
*/
RELEASE_MUTEX(&_hbaapi_AAE_mutex);
/*
* now create a list of vendors (vendor libraryies, NOT ADAPTERS)
* that have successfully registerred
*/
vendorhandlelist = NULL;
for (lib_infop = _hbaapi_librarylist;
lib_infop != NULL;
lib_infop = lib_infop->next) {
/* only for HBAAPI V2 */
if ((lib_infop->version != HBAAPIV2)) {
continue;
} else {
vendor_cnt++;
}
registeredfunc =
lib_infop->ftable.functionTable.RegisterForAdapterAddEventsHandler;
if (registeredfunc == NULL) {
continue;
}
vcbp = (HBA_VENDORCALLBACK_ELEM *)
calloc(1, sizeof (HBA_VENDORCALLBACK_ELEM));
if (vcbp == NULL) {
#ifndef WIN32
(void) fprintf(stderr,
"HBA_RegisterForAdapterAddEvents: "
"calloc failed for %lu bytes\n",
(unsigned long)(sizeof (HBA_VENDORCALLBACK_ELEM)));
#endif
freevendorhandlelist(vendorhandlelist);
status = HBA_STATUS_ERROR;
break;
}
registered_cnt++;
status = (registeredfunc)(adapteraddevents_callback,
userData, &vcbp->vendorcbhandle);
if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
not_supported_cnt++;
free(vcbp);
continue;
} else if (status != HBA_STATUS_OK) {
status_OK_bar_cnt++;
DEBUG(1,
"HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
lib_infop->LibraryPath, status, 0);
#ifndef WIN32
(void) fprintf(stderr,
"HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
lib_infop->LibraryPath, status);
#endif
failure = status;
free(vcbp);
continue;
} else {
status_OK_cnt++;
}
vcbp->lib_info = lib_infop;
vcbp->next = vendorhandlelist;
vendorhandlelist = vcbp;
}
if (vendor_cnt == 0) {
/* no HBAAPIV2 is deteced. should be okay? */
status = HBA_STATUS_ERROR;
} else if (registered_cnt == 0) {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
freevendorhandlelist(vendorhandlelist);
(void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
} else if (status_OK_cnt == 0 && not_supported_cnt != 0) {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
} else if (status_OK_cnt == 0) {
/*
* At least one vendor library registered this function, but no
* vendor call succeeded
*/
(void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
status = failure;
} else {
/* we have had atleast some success, now finish up */
GRAB_MUTEX(&_hbaapi_AAE_mutex);
/*
* this seems silly, but what if another thread called
* the callback remove
*/
for (cbp = _hbaapi_adapteraddevents_callback_list;
cbp != NULL; cbp = cbp->next) {
if ((HBA_CALLBACKHANDLE)cbp == *callbackHandle) {
/* yup, its still there, hooray */
cbp->vendorhandlelist = vendorhandlelist;
vendorhandlelist = NULL;
break;
}
}
RELEASE_MUTEX(&_hbaapi_AAE_mutex);
if (vendorhandlelist != NULL) {
/*
* bummer, somebody removed the callback before we finished
* registration, probably will never happen
*/
freevendorhandlelist(vendorhandlelist);
DEBUG(1,
"HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was "
"called for a handle before registration was finished.",
0, 0, 0);
status = HBA_STATUS_ERROR;
} else {
status = HBA_STATUS_OK;
}
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
/* Adapter Events (other than add) ************************************** */
static void
adapterevents_callback(void *data,
HBA_WWN PortWWN,
HBA_UINT32 eventType) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
DEBUG(3, "AdapterEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN),
eventType, 0);
GRAB_MUTEX(&_hbaapi_AE_mutex);
for (acbp = _hbaapi_adapterevents_callback_list;
acbp != NULL;
acbp = acbp->next) {
if (data == (void *)acbp) {
(*acbp->callback)(acbp->userdata, PortWWN, eventType);
break;
}
}
RELEASE_MUTEX(&_hbaapi_AE_mutex);
}
HBA_STATUS
HBA_RegisterForAdapterEvents(
void (*callback) (
void *data,
HBA_WWN PortWWN,
HBA_UINT32 eventType),
void *userData,
HBA_HANDLE handle,
HBA_CALLBACKHANDLE *callbackHandle) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
HBARegisterForAdapterEventsFunc registeredfunc;
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
DEBUG(2, "HBA_RegisterForAdapterEvents", 0, 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
/* we now have the _hbaapi_LL_mutex */
registeredfunc =
lib_infop->ftable.functionTable.RegisterForAdapterEventsHandler;
if (registeredfunc == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
}
/*
* 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 *)
calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
if (acbp == NULL) {
#ifndef WIN32
(void) fprintf(stderr,
"HBA_RegisterForAdapterEvents: calloc failed for %lu bytes\n",
(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
#endif
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
}
*callbackHandle = (HBA_CALLBACKHANDLE) acbp;
acbp->callback = callback;
acbp->userdata = userData;
acbp->lib_info = lib_infop;
status = (registeredfunc)(adapterevents_callback,
(void *)acbp,
vendorHandle,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
free(acbp);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
GRAB_MUTEX(&_hbaapi_AE_mutex);
acbp->next = _hbaapi_adapterevents_callback_list;
_hbaapi_adapterevents_callback_list = acbp;
RELEASE_MUTEX(&_hbaapi_AE_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
}
/* Adapter Port Events ************************************************** */
static void
adapterportevents_callback(void *data,
HBA_WWN PortWWN,
HBA_UINT32 eventType,
HBA_UINT32 fabricPortID) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
DEBUG(3, "AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x",
WWN2STR1(&PortWWN), eventType, fabricPortID);
GRAB_MUTEX(&_hbaapi_APE_mutex);
for (acbp = _hbaapi_adapterportevents_callback_list;
acbp != NULL;
acbp = acbp->next) {
if (data == (void *)acbp) {
(*acbp->callback)(acbp->userdata, PortWWN, eventType, fabricPortID);
break;
}
}
RELEASE_MUTEX(&_hbaapi_APE_mutex);
}
HBA_STATUS
HBA_RegisterForAdapterPortEvents(
void (*callback) (
void *data,
HBA_WWN PortWWN,
HBA_UINT32 eventType,
HBA_UINT32 fabricPortID),
void *userData,
HBA_HANDLE handle,
HBA_WWN PortWWN,
HBA_CALLBACKHANDLE *callbackHandle) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
HBARegisterForAdapterPortEventsFunc registeredfunc;
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
DEBUG(2, "HBA_RegisterForAdapterPortEvents for port: %s",
WWN2STR1(&PortWWN), 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
/* we now have the _hbaapi_LL_mutex */
registeredfunc =
lib_infop->ftable.functionTable.RegisterForAdapterPortEventsHandler;
if (registeredfunc == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
}
/*
* 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 *)
calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
if (acbp == NULL) {
#ifndef WIN32
(void) fprintf(stderr,
"HBA_RegisterForAdapterPortEvents: "
"calloc failed for %lu bytes\n",
(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
#endif
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
}
*callbackHandle = (HBA_CALLBACKHANDLE) acbp;
acbp->callback = callback;
acbp->userdata = userData;
acbp->lib_info = lib_infop;
status = (registeredfunc)(adapterportevents_callback,
(void *)acbp,
vendorHandle,
PortWWN,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
free(acbp);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
GRAB_MUTEX(&_hbaapi_APE_mutex);
acbp->next = _hbaapi_adapterportevents_callback_list;
_hbaapi_adapterportevents_callback_list = acbp;
RELEASE_MUTEX(&_hbaapi_APE_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
}
/* Adapter State Events ************************************************ */
static void
adapterportstatevents_callback(void *data,
HBA_WWN PortWWN,
HBA_UINT32 eventType) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
DEBUG(3, "AdapterPortStatEvent, port:%s, eventType:%d",
WWN2STR1(&PortWWN),
eventType, 0);
GRAB_MUTEX(&_hbaapi_APSE_mutex);
for (acbp = _hbaapi_adapterportstatevents_callback_list;
acbp != NULL;
acbp = acbp->next) {
if (data == (void *)acbp) {
(*acbp->callback)(acbp->userdata, PortWWN, eventType);
return;
}
}
RELEASE_MUTEX(&_hbaapi_APSE_mutex);
}
HBA_STATUS
HBA_RegisterForAdapterPortStatEvents(
void (*callback) (
void *data,
HBA_WWN PortWWN,
HBA_UINT32 eventType),
void *userData,
HBA_HANDLE handle,
HBA_WWN PortWWN,
HBA_PORTSTATISTICS stats,
HBA_UINT32 statType,
HBA_CALLBACKHANDLE *callbackHandle) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
HBARegisterForAdapterPortStatEventsFunc
registeredfunc;
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
DEBUG(2, "HBA_RegisterForAdapterPortStatEvents for port: %s",
WWN2STR1(&PortWWN), 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
/* we now have the _hbaapi_LL_mutex */
registeredfunc =
lib_infop->ftable.functionTable.RegisterForAdapterPortStatEventsHandler;
if (registeredfunc == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
}
/*
* 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 *)
calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
if (acbp == NULL) {
#ifndef WIN32
(void) fprintf(stderr,
"HBA_RegisterForAdapterPortStatEvents: "
"calloc failed for %lu bytes\n",
(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
#endif
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
}
*callbackHandle = (HBA_CALLBACKHANDLE) acbp;
acbp->callback = callback;
acbp->userdata = userData;
acbp->lib_info = lib_infop;
status = (registeredfunc)(adapterportstatevents_callback,
(void *)acbp,
vendorHandle,
PortWWN,
stats,
statType,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
free(acbp);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
GRAB_MUTEX(&_hbaapi_APSE_mutex);
acbp->next = _hbaapi_adapterportstatevents_callback_list;
_hbaapi_adapterportstatevents_callback_list = acbp;
RELEASE_MUTEX(&_hbaapi_APSE_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
}
/* Target Events ******************************************************* */
static void
targetevents_callback(void *data,
HBA_WWN hbaPortWWN,
HBA_WWN discoveredPortWWN,
HBA_UINT32 eventType) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
DEBUG(3, "TargetEvent, hbaPort:%s, discoveredPort:%s eventType:%d",
WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), eventType);
GRAB_MUTEX(&_hbaapi_TE_mutex);
for (acbp = _hbaapi_targetevents_callback_list;
acbp != NULL;
acbp = acbp->next) {
if (data == (void *)acbp) {
(*acbp->callback)(acbp->userdata, hbaPortWWN,
discoveredPortWWN, eventType);
break;
}
}
RELEASE_MUTEX(&_hbaapi_TE_mutex);
}
HBA_STATUS
HBA_RegisterForTargetEvents(
void (*callback) (
void *data,
HBA_WWN hbaPortWWN,
HBA_WWN discoveredPortWWN,
HBA_UINT32 eventType),
void *userData,
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN discoveredPortWWN,
HBA_CALLBACKHANDLE *callbackHandle,
HBA_UINT32 allTargets) {
HBA_ADAPTERCALLBACK_ELEM
*acbp;
HBARegisterForTargetEventsFunc
registeredfunc;
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
DEBUG(2, "HBA_RegisterForTargetEvents, hbaPort: %s, discoveredPort: %s",
WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
/* we now have the _hbaapi_LL_mutex */
registeredfunc =
lib_infop->ftable.functionTable.RegisterForTargetEventsHandler;
if (registeredfunc == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
}
/*
* 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 *)
calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
if (acbp == NULL) {
#ifndef WIN32
(void) fprintf(stderr,
"HBA_RegisterForTargetEvents: calloc failed for %lu bytes\n",
(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
#endif
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
}
*callbackHandle = (HBA_CALLBACKHANDLE) acbp;
acbp->callback = callback;
acbp->userdata = userData;
acbp->lib_info = lib_infop;
status = (registeredfunc)(targetevents_callback,
(void *)acbp,
vendorHandle,
hbaPortWWN,
discoveredPortWWN,
&acbp->vendorcbhandle,
allTargets);
if (status != HBA_STATUS_OK) {
free(acbp);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
GRAB_MUTEX(&_hbaapi_TE_mutex);
acbp->next = _hbaapi_targetevents_callback_list;
_hbaapi_targetevents_callback_list = acbp;
RELEASE_MUTEX(&_hbaapi_TE_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
}
/* Link Events ********************************************************* */
static void
linkevents_callback(void *data,
HBA_WWN adapterWWN,
HBA_UINT32 eventType,
void *pRLIRBuffer,
HBA_UINT32 RLIRBufferSize) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
DEBUG(3, "LinkEvent, hbaWWN:%s, eventType:%d",
WWN2STR1(&adapterWWN), eventType, 0);
GRAB_MUTEX(&_hbaapi_LE_mutex);
for (acbp = _hbaapi_linkevents_callback_list;
acbp != NULL;
acbp = acbp->next) {
if (data == (void *)acbp) {
(*acbp->callback)(acbp->userdata, adapterWWN,
eventType, pRLIRBuffer, RLIRBufferSize);
break;
}
}
RELEASE_MUTEX(&_hbaapi_LE_mutex);
}
HBA_STATUS
HBA_RegisterForLinkEvents(
void (*callback) (
void *data,
HBA_WWN adapterWWN,
HBA_UINT32 eventType,
void *pRLIRBuffer,
HBA_UINT32 RLIRBufferSize),
void *userData,
void *pRLIRBuffer,
HBA_UINT32 RLIRBufferSize,
HBA_HANDLE handle,
HBA_CALLBACKHANDLE *callbackHandle) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
HBARegisterForLinkEventsFunc
registeredfunc;
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
DEBUG(2, "HBA_RegisterForLinkEvents", 0, 0, 0);
CHECKLIBRARY();
/* we now have the _hbaapi_LL_mutex */
registeredfunc = FUNCCOMMON(lib_infop, RegisterForLinkEventsHandler);
if (registeredfunc == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
}
/*
* 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 *)
calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
if (acbp == NULL) {
#ifndef WIN32
(void) fprintf(stderr,
"HBA_RegisterForLinkEvents: calloc failed for %lu bytes\n",
(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
#endif
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
}
*callbackHandle = (HBA_CALLBACKHANDLE) acbp;
acbp->callback = callback;
acbp->userdata = userData;
acbp->lib_info = lib_infop;
status = (registeredfunc)(linkevents_callback,
(void *)acbp,
pRLIRBuffer,
RLIRBufferSize,
vendorHandle,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
free(acbp);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
GRAB_MUTEX(&_hbaapi_LE_mutex);
acbp->next = _hbaapi_linkevents_callback_list;
_hbaapi_linkevents_callback_list = acbp;
RELEASE_MUTEX(&_hbaapi_LE_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
}
/*
* All of the functions below are almost passthru functions to the
* vendor specific function
*/
void
HBA_CloseAdapter(HBA_HANDLE handle) {
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBACloseAdapterFunc CloseAdapterFunc;
DEBUG(2, "HBA_CloseAdapter", 0, 0, 0);
status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
if (status == HBA_STATUS_OK) {
CloseAdapterFunc = FUNCCOMMON(lib_infop, CloseAdapterHandler);
if (CloseAdapterFunc != NULL) {
((CloseAdapterFunc)(vendorHandle));
}
RELEASE_MUTEX(&_hbaapi_LL_mutex);
}
}
HBA_STATUS
HBA_GetAdapterAttributes(
HBA_HANDLE handle,
HBA_ADAPTERATTRIBUTES
*hbaattributes)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetAdapterAttributesFunc GetAdapterAttributesFunc;
DEBUG(2, "HBA_GetAdapterAttributes", 0, 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
GetAdapterAttributesFunc =
lib_infop->ftable.functionTable.GetAdapterAttributesHandler;
if (GetAdapterAttributesFunc != NULL) {
status = ((GetAdapterAttributesFunc)(vendorHandle, hbaattributes));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetAdapterPortAttributes(
HBA_HANDLE handle,
HBA_UINT32 portindex,
HBA_PORTATTRIBUTES *portattributes)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetAdapterPortAttributesFunc
GetAdapterPortAttributesFunc;
DEBUG(2, "HBA_GetAdapterPortAttributes", 0, 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
GetAdapterPortAttributesFunc =
lib_infop->ftable.functionTable.GetAdapterPortAttributesHandler;
if (GetAdapterPortAttributesFunc != NULL) {
status = ((GetAdapterPortAttributesFunc)
(vendorHandle, portindex, portattributes));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetPortStatistics(
HBA_HANDLE handle,
HBA_UINT32 portindex,
HBA_PORTSTATISTICS *portstatistics)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetPortStatisticsFunc
GetPortStatisticsFunc;
DEBUG(2, "HBA_GetPortStatistics", 0, 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
GetPortStatisticsFunc =
lib_infop->ftable.functionTable.GetPortStatisticsHandler;
if (GetPortStatisticsFunc != NULL) {
status = ((GetPortStatisticsFunc)
(vendorHandle, portindex, portstatistics));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetDiscoveredPortAttributes(
HBA_HANDLE handle,
HBA_UINT32 portindex,
HBA_UINT32 discoveredportindex,
HBA_PORTATTRIBUTES *portattributes)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetDiscoveredPortAttributesFunc
GetDiscoveredPortAttributesFunc;
DEBUG(2, "HBA_GetDiscoveredPortAttributes", 0, 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
GetDiscoveredPortAttributesFunc =
lib_infop->ftable.functionTable.GetDiscoveredPortAttributesHandler;
if (GetDiscoveredPortAttributesFunc != NULL) {
status = ((GetDiscoveredPortAttributesFunc)
(vendorHandle, portindex, discoveredportindex,
portattributes));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetPortAttributesByWWN(
HBA_HANDLE handle,
HBA_WWN PortWWN,
HBA_PORTATTRIBUTES *portattributes)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetPortAttributesByWWNFunc
GetPortAttributesByWWNFunc;
DEBUG(2, "HBA_GetPortAttributesByWWN: %s", WWN2STR1(&PortWWN), 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
GetPortAttributesByWWNFunc =
lib_infop->ftable.functionTable.GetPortAttributesByWWNHandler;
if (GetPortAttributesByWWNFunc != NULL) {
status = ((GetPortAttributesByWWNFunc)
(vendorHandle, PortWWN, portattributes));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SendCTPassThru(
HBA_HANDLE handle,
void *pReqBuffer,
HBA_UINT32 ReqBufferSize,
void *pRspBuffer,
HBA_UINT32 RspBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASendCTPassThruFunc
SendCTPassThruFunc;
DEBUG(2, "HBA_SendCTPassThru", 0, 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
SendCTPassThruFunc =
lib_infop->ftable.functionTable.SendCTPassThruHandler;
if (SendCTPassThruFunc != NULL) {
status = (SendCTPassThruFunc)
(vendorHandle,
pReqBuffer, ReqBufferSize,
pRspBuffer, RspBufferSize);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SendCTPassThruV2(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
void *pReqBuffer,
HBA_UINT32 ReqBufferSize,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASendCTPassThruV2Func
registeredfunc;
DEBUG(2, "HBA_SendCTPassThruV2m hbaPortWWN: %s",
WWN2STR1(&hbaPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
registeredfunc = FUNCCOMMON(lib_infop, SendCTPassThruV2Handler);
if (registeredfunc != NULL) {
status = (registeredfunc)
(vendorHandle, hbaPortWWN,
pReqBuffer, ReqBufferSize,
pRspBuffer, pRspBufferSize);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetEventBuffer(
HBA_HANDLE handle,
PHBA_EVENTINFO EventBuffer,
HBA_UINT32 *EventBufferCount)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetEventBufferFunc
GetEventBufferFunc;
DEBUG(2, "HBA_GetEventBuffer", 0, 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
GetEventBufferFunc =
lib_infop->ftable.functionTable.GetEventBufferHandler;
if (GetEventBufferFunc != NULL) {
status = (GetEventBufferFunc)
(vendorHandle, EventBuffer, EventBufferCount);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SetRNIDMgmtInfo(HBA_HANDLE handle, HBA_MGMTINFO Info) {
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASetRNIDMgmtInfoFunc
SetRNIDMgmtInfoFunc;
DEBUG(2, "HBA_SetRNIDMgmtInfo", 0, 0, 0);
CHECKLIBRARY();
SetRNIDMgmtInfoFunc = FUNCCOMMON(lib_infop, SetRNIDMgmtInfoHandler);
if (SetRNIDMgmtInfoFunc != NULL) {
status = (SetRNIDMgmtInfoFunc)(vendorHandle, Info);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetRNIDMgmtInfo(HBA_HANDLE handle, HBA_MGMTINFO *pInfo) {
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetRNIDMgmtInfoFunc
GetRNIDMgmtInfoFunc;
DEBUG(2, "HBA_GetRNIDMgmtInfo", 0, 0, 0);
CHECKLIBRARY();
GetRNIDMgmtInfoFunc = FUNCCOMMON(lib_infop, GetRNIDMgmtInfoHandler);
if (GetRNIDMgmtInfoFunc != NULL) {
status = (GetRNIDMgmtInfoFunc)(vendorHandle, pInfo);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SendRNID(
HBA_HANDLE handle,
HBA_WWN wwn,
HBA_WWNTYPE wwntype,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASendRNIDFunc SendRNIDFunc;
DEBUG(2, "HBA_SendRNID for wwn: %s", WWN2STR1(&wwn), 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
SendRNIDFunc = lib_infop->ftable.functionTable.SendRNIDHandler;
if (SendRNIDFunc != NULL) {
status = ((SendRNIDFunc)(vendorHandle, wwn, wwntype,
pRspBuffer, pRspBufferSize));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SendRNIDV2(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN destWWN,
HBA_UINT32 destFCID,
HBA_UINT32 NodeIdDataFormat,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASendRNIDV2Func registeredfunc;
DEBUG(2, "HBA_SendRNIDV2, hbaPortWWN: %s", WWN2STR1(&hbaPortWWN), 0, 0);
CHECKLIBRARY();
registeredfunc = FUNCCOMMON(lib_infop, SendRNIDV2Handler);
if (registeredfunc != NULL) {
status = (registeredfunc)
(vendorHandle, hbaPortWWN, destWWN, destFCID, NodeIdDataFormat,
pRspBuffer, pRspBufferSize);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
void
HBA_RefreshInformation(HBA_HANDLE handle) {
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBARefreshInformationFunc
RefreshInformationFunc;
DEBUG(2, "HBA_RefreshInformation", 0, 0, 0);
status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
if (status == HBA_STATUS_OK) {
RefreshInformationFunc =
FUNCCOMMON(lib_infop, RefreshInformationHandler);
if (RefreshInformationFunc != NULL) {
((RefreshInformationFunc)(vendorHandle));
}
RELEASE_MUTEX(&_hbaapi_LL_mutex);
}
}
void
HBA_ResetStatistics(HBA_HANDLE handle, HBA_UINT32 portindex) {
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAResetStatisticsFunc
ResetStatisticsFunc;
DEBUG(2, "HBA_ResetStatistics", 0, 0, 0);
status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
if (status == HBA_STATUS_OK) {
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX(&_hbaapi_LL_mutex);
}
ResetStatisticsFunc =
lib_infop->ftable.functionTable.ResetStatisticsHandler;
if (ResetStatisticsFunc != NULL) {
((ResetStatisticsFunc)(vendorHandle, portindex));
}
RELEASE_MUTEX(&_hbaapi_LL_mutex);
}
}
HBA_STATUS
HBA_GetFcpTargetMapping(HBA_HANDLE handle, PHBA_FCPTARGETMAPPING mapping) {
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetFcpTargetMappingFunc GetFcpTargetMappingFunc;
DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
GetFcpTargetMappingFunc =
lib_infop->ftable.functionTable.GetFcpTargetMappingHandler;
if (GetFcpTargetMappingFunc != NULL) {
status = ((GetFcpTargetMappingFunc)(vendorHandle, mapping));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetFcpTargetMappingV2(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_FCPTARGETMAPPINGV2 *pmapping)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetFcpTargetMappingV2Func
registeredfunc;
DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
registeredfunc =
lib_infop->ftable.functionTable.GetFcpTargetMappingV2Handler;
if (registeredfunc != NULL) {
status = ((registeredfunc)(vendorHandle, hbaPortWWN, pmapping));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetFcpPersistentBinding(HBA_HANDLE handle, PHBA_FCPBINDING binding) {
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetFcpPersistentBindingFunc
GetFcpPersistentBindingFunc;
DEBUG(2, "HBA_GetFcpPersistentBinding", 0, 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
GetFcpPersistentBindingFunc =
lib_infop->ftable.functionTable.GetFcpPersistentBindingHandler;
if (GetFcpPersistentBindingFunc != NULL) {
status = ((GetFcpPersistentBindingFunc)(vendorHandle, binding));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_ScsiInquiryV2(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN discoveredPortWWN,
HBA_UINT64 fcLUN,
HBA_UINT8 CDB_Byte1,
HBA_UINT8 CDB_Byte2,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize,
HBA_UINT8 *pScsiStatus,
void *pSenseBuffer,
HBA_UINT32 *pSenseBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAScsiInquiryV2Func ScsiInquiryV2Func;
DEBUG(2, "HBA_ScsiInquiryV2 to discoveredPortWWN: %s",
WWN2STR1(&discoveredPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
ScsiInquiryV2Func =
lib_infop->ftable.functionTable.ScsiInquiryV2Handler;
if (ScsiInquiryV2Func != NULL) {
status = ((ScsiInquiryV2Func)(
vendorHandle, hbaPortWWN, discoveredPortWWN, fcLUN, CDB_Byte1,
CDB_Byte2, pRspBuffer, pRspBufferSize, pScsiStatus,
pSenseBuffer, pSenseBufferSize));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SendScsiInquiry(
HBA_HANDLE handle,
HBA_WWN PortWWN,
HBA_UINT64 fcLUN,
HBA_UINT8 EVPD,
HBA_UINT32 PageCode,
void *pRspBuffer,
HBA_UINT32 RspBufferSize,
void *pSenseBuffer,
HBA_UINT32 SenseBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASendScsiInquiryFunc SendScsiInquiryFunc;
DEBUG(2, "HBA_SendScsiInquiry to PortWWN: %s",
WWN2STR1(&PortWWN), 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
SendScsiInquiryFunc =
lib_infop->ftable.functionTable.ScsiInquiryHandler;
if (SendScsiInquiryFunc != NULL) {
status = ((SendScsiInquiryFunc)(
vendorHandle, PortWWN, fcLUN, EVPD, PageCode, pRspBuffer,
RspBufferSize, pSenseBuffer, SenseBufferSize));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_ScsiReportLUNsV2(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN discoveredPortWWN,
void *pRespBuffer,
HBA_UINT32 *pRespBufferSize,
HBA_UINT8 *pScsiStatus,
void *pSenseBuffer,
HBA_UINT32 *pSenseBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAScsiReportLUNsV2Func ScsiReportLUNsV2Func;
DEBUG(2, "HBA_ScsiReportLUNsV2 to discoveredPortWWN: %s",
WWN2STR1(&discoveredPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
ScsiReportLUNsV2Func =
lib_infop->ftable.functionTable.ScsiReportLUNsV2Handler;
if (ScsiReportLUNsV2Func != NULL) {
status = ((ScsiReportLUNsV2Func)(
vendorHandle, hbaPortWWN, discoveredPortWWN,
pRespBuffer, pRespBufferSize,
pScsiStatus,
pSenseBuffer, pSenseBufferSize));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SendReportLUNs(
HBA_HANDLE handle,
HBA_WWN portWWN,
void *pRspBuffer,
HBA_UINT32 RspBufferSize,
void *pSenseBuffer,
HBA_UINT32 SenseBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASendReportLUNsFunc SendReportLUNsFunc;
DEBUG(2, "HBA_SendReportLUNs to PortWWN: %s", WWN2STR1(&portWWN), 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
SendReportLUNsFunc = lib_infop->ftable.functionTable.ReportLUNsHandler;
if (SendReportLUNsFunc != NULL) {
status = ((SendReportLUNsFunc)(
vendorHandle, portWWN, pRspBuffer,
RspBufferSize, pSenseBuffer, SenseBufferSize));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_ScsiReadCapacityV2(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN discoveredPortWWN,
HBA_UINT64 fcLUN,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize,
HBA_UINT8 *pScsiStatus,
void *pSenseBuffer,
HBA_UINT32 *SenseBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAScsiReadCapacityV2Func ScsiReadCapacityV2Func;
DEBUG(2, "HBA_ScsiReadCapacityV2 to discoveredPortWWN: %s",
WWN2STR1(&discoveredPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
ScsiReadCapacityV2Func =
lib_infop->ftable.functionTable.ScsiReadCapacityV2Handler;
if (ScsiReadCapacityV2Func != NULL) {
status = ((ScsiReadCapacityV2Func)(
vendorHandle, hbaPortWWN, discoveredPortWWN, fcLUN,
pRspBuffer, pRspBufferSize,
pScsiStatus,
pSenseBuffer, SenseBufferSize));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SendReadCapacity(
HBA_HANDLE handle,
HBA_WWN portWWN,
HBA_UINT64 fcLUN,
void *pRspBuffer,
HBA_UINT32 RspBufferSize,
void *pSenseBuffer,
HBA_UINT32 SenseBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASendReadCapacityFunc SendReadCapacityFunc;
DEBUG(2, "HBA_SendReadCapacity to portWWN: %s",
WWN2STR1(&portWWN), 0, 0);
CHECKLIBRARY();
if (lib_infop->version == SMHBA) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
}
SendReadCapacityFunc =
lib_infop->ftable.functionTable.ReadCapacityHandler;
if (SendReadCapacityFunc != NULL) {
status = ((SendReadCapacityFunc)
(vendorHandle, portWWN, fcLUN, pRspBuffer,
RspBufferSize, pSenseBuffer, SenseBufferSize));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SendRPL(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN agent_wwn,
HBA_UINT32 agent_domain,
HBA_UINT32 portindex,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASendRPLFunc registeredfunc;
DEBUG(2, "HBA_SendRPL to agent_wwn: %s:%d",
WWN2STR1(&agent_wwn), agent_domain, 0);
CHECKLIBRARY();
registeredfunc = FUNCCOMMON(lib_infop, SendRPLHandler);
if (registeredfunc != NULL) {
status = (registeredfunc)(
vendorHandle, hbaPortWWN, agent_wwn, agent_domain, portindex,
pRspBuffer, pRspBufferSize);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SendRPS(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN agent_wwn,
HBA_UINT32 agent_domain,
HBA_WWN object_wwn,
HBA_UINT32 object_port_number,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASendRPSFunc registeredfunc;
DEBUG(2, "HBA_SendRPS to agent_wwn: %s:%d",
WWN2STR1(&agent_wwn), agent_domain, 0);
CHECKLIBRARY();
registeredfunc = FUNCCOMMON(lib_infop, SendRPSHandler);
if (registeredfunc != NULL) {
status = (registeredfunc)(
vendorHandle, hbaPortWWN, agent_wwn, agent_domain,
object_wwn, object_port_number,
pRspBuffer, pRspBufferSize);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SendSRL(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN wwn,
HBA_UINT32 domain,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASendSRLFunc registeredfunc;
DEBUG(2, "HBA_SendSRL to wwn:%s domain:%d", WWN2STR1(&wwn), domain, 0);
CHECKLIBRARY();
registeredfunc = FUNCCOMMON(lib_infop, SendSRLHandler);
if (registeredfunc != NULL) {
status = (registeredfunc)(
vendorHandle, hbaPortWWN, wwn, domain,
pRspBuffer, pRspBufferSize);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SendRLS(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN destWWN,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASendRLSFunc registeredfunc;
DEBUG(2, "HBA_SendRLS dest_wwn: %s",
WWN2STR1(&destWWN), 0, 0);
CHECKLIBRARY();
registeredfunc = FUNCCOMMON(lib_infop, SendRLSHandler);
if (registeredfunc != NULL) {
status = (registeredfunc)(
vendorHandle, hbaPortWWN, destWWN,
pRspBuffer, pRspBufferSize);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SendLIRR(
HBA_HANDLE handle,
HBA_WWN sourceWWN,
HBA_WWN destWWN,
HBA_UINT8 function,
HBA_UINT8 type,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASendLIRRFunc registeredfunc;
DEBUG(2, "HBA_SendLIRR destWWN:%s", WWN2STR1(&destWWN), 0, 0);
CHECKLIBRARY();
registeredfunc = FUNCCOMMON(lib_infop, SendLIRRHandler);
if (registeredfunc != NULL) {
status = (registeredfunc)(
vendorHandle, sourceWWN, destWWN, function, type,
pRspBuffer, pRspBufferSize);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetBindingCapability(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_BIND_CAPABILITY *pcapability)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetBindingCapabilityFunc
registeredfunc;
DEBUG(2, "HBA_GetBindingCapability", 0, 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
registeredfunc =
lib_infop->ftable.functionTable.GetBindingCapabilityHandler;
if (registeredfunc != NULL) {
status = (registeredfunc)(vendorHandle, hbaPortWWN, pcapability);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetBindingSupport(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_BIND_CAPABILITY *pcapability)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetBindingSupportFunc
registeredfunc;
DEBUG(2, "HBA_GetBindingSupport", 0, 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
registeredfunc =
lib_infop->ftable.functionTable.GetBindingSupportHandler;
if (registeredfunc != NULL) {
status = (registeredfunc)(vendorHandle, hbaPortWWN, pcapability);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SetBindingSupport(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_BIND_CAPABILITY capability)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASetBindingSupportFunc
registeredfunc;
DEBUG(2, "HBA_SetBindingSupport", 0, 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
registeredfunc =
lib_infop->ftable.functionTable.SetBindingSupportHandler;
if (registeredfunc != NULL) {
status = (registeredfunc)(vendorHandle, hbaPortWWN, capability);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_SetPersistentBindingV2(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
const HBA_FCPBINDING2 *pbinding)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBASetPersistentBindingV2Func
registeredfunc;
DEBUG(2, "HBA_SetPersistentBindingV2 port: %s",
WWN2STR1(&hbaPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
registeredfunc =
lib_infop->ftable.functionTable.SetPersistentBindingV2Handler;
if (registeredfunc != NULL) {
status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetPersistentBindingV2(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_FCPBINDING2 *pbinding)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetPersistentBindingV2Func
registeredfunc;
DEBUG(2, "HBA_GetPersistentBindingV2 port: %s",
WWN2STR1(&hbaPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
registeredfunc =
lib_infop->ftable.functionTable.GetPersistentBindingV2Handler;
if (registeredfunc != NULL) {
status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_RemovePersistentBinding(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
const HBA_FCPBINDING2
*pbinding)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBARemovePersistentBindingFunc
registeredfunc;
DEBUG(2, "HBA_RemovePersistentBinding", 0, 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
registeredfunc =
lib_infop->ftable.functionTable.RemovePersistentBindingHandler;
if (registeredfunc != NULL) {
status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_RemoveAllPersistentBindings(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBARemoveAllPersistentBindingsFunc
registeredfunc;
DEBUG(2, "HBA_RemoveAllPersistentBindings", 0, 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
registeredfunc =
lib_infop->ftable.functionTable.RemoveAllPersistentBindingsHandler;
if (registeredfunc != NULL) {
status = (registeredfunc)(vendorHandle, hbaPortWWN);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetFC4Statistics(
HBA_HANDLE handle,
HBA_WWN portWWN,
HBA_UINT8 FC4type,
HBA_FC4STATISTICS *pstatistics)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetFC4StatisticsFunc
registeredfunc;
DEBUG(2, "HBA_GetFC4Statistics port: %s", WWN2STR1(&portWWN), 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
registeredfunc =
lib_infop->ftable.functionTable.GetFC4StatisticsHandler;
if (registeredfunc != NULL) {
status = (registeredfunc)
(vendorHandle, portWWN, FC4type, pstatistics);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
HBA_GetFCPStatistics(
HBA_HANDLE handle,
const HBA_SCSIID *lunit,
HBA_FC4STATISTICS *pstatistics)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
HBAGetFCPStatisticsFunc
registeredfunc;
DEBUG(2, "HBA_GetFCPStatistics", 0, 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
registeredfunc =
lib_infop->ftable.functionTable.GetFCPStatisticsHandler;
if (registeredfunc != NULL) {
status = (registeredfunc)(vendorHandle, lunit, pstatistics);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_UINT32
HBA_GetVendorLibraryAttributes(
HBA_UINT32 adapter_index,
HBA_LIBRARYATTRIBUTES *attributes)
{
HBA_ADAPTER_INFO *adapt_infop;
HBAGetVendorLibraryAttributesFunc
registeredfunc;
HBA_UINT32 ret = 0;
DEBUG(2, "HBA_GetVendorLibraryAttributes adapterindex:%d",
adapter_index, 0, 0);
if (_hbaapi_librarylist == NULL) {
DEBUG(1, "HBAAPI not loaded yet.", 0, 0, 0);
return (0);
}
if (attributes == NULL) {
DEBUG(1,
"HBA_GetVendorLibraryAttributes: NULL pointer attributes",
0, 0, 0);
return (HBA_STATUS_ERROR_ARG);
}
(void) memset(attributes, 0, sizeof (HBA_LIBRARYATTRIBUTES));
GRAB_MUTEX(&_hbaapi_LL_mutex);
GRAB_MUTEX(&_hbaapi_AL_mutex);
for (adapt_infop = _hbaapi_adapterlist;
adapt_infop != NULL;
adapt_infop = adapt_infop->next) {
if (adapt_infop->index == adapter_index) {
if (adapt_infop->library->version == SMHBA) {
RELEASE_MUTEX(&_hbaapi_AL_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
HBA_STATUS_ERROR_INCOMPATIBLE);
}
registeredfunc = adapt_infop->library->
ftable.functionTable.GetVendorLibraryAttributesHandler;
if (registeredfunc != NULL) {
ret = (registeredfunc)(attributes);
} else {
/* Version 1 libary? */
HBAGetVersionFunc GetVersionFunc;
GetVersionFunc = adapt_infop->library->
ftable.functionTable.GetVersionHandler;
if (GetVersionFunc != NULL) {
ret = ((GetVersionFunc)());
}
#ifdef NOTDEF
else {
/* This should not happen, dont think its going to */
}
#endif
}
if (attributes->LibPath[0] == '\0') {
if (strlen(adapt_infop->library->LibraryPath) < 256) {
(void) strcpy(attributes->LibPath,
adapt_infop->library->LibraryPath);
}
}
break;
}
}
RELEASE_MUTEX(&_hbaapi_AL_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, ret);
}
/*
* This function returns SM-HBA version that the warpper library implemented.
*/
HBA_UINT32
SMHBA_GetVersion() {
DEBUG(2, "SMHBA_GetVersion", 0, 0, 0);
return (SMHBA_LIBVERSION);
}
/*
* This function returns the attributes for the warpper library.
*/
HBA_UINT32
SMHBA_GetWrapperLibraryAttributes(
SMHBA_LIBRARYATTRIBUTES *attributes)
{
struct timeval tv;
struct tm tp;
DEBUG(2, "SMHBA_GetWrapperLibraryAttributes", 0, 0, 0);
if (attributes == NULL) {
DEBUG(1, "SMHBA_GetWrapperLibraryAttributes: "
"NULL pointer attributes",
0, 0, 0);
return (HBA_STATUS_ERROR_ARG);
}
(void) memset(attributes, 0, sizeof (SMHBA_LIBRARYATTRIBUTES));
#if defined(SOLARIS)
if ((handle = dlopen("libSMHBAAPI.so", RTLD_NOW)) != NULL) {
if (dlinfo(handle, RTLD_DI_LINKMAP, &map) >= 0) {
for (mp = map; mp != NULL; mp = mp->l_next) {
if (strlen(map->l_name) < 256) {
(void) strcpy(attributes->LibPath, map->l_name);
}
}
}
}
#endif
#if defined(VENDOR)
(void) strcpy(attributes->VName, VENDOR);
#else
attributes->VName[0] = '\0';
#endif
#if defined(VERSION)
(void) strcpy(attributes->VVersion, VERSION);
#else
attributes->VVersion[0] = '\0';
#endif
if (gettimeofday(&tv, (void *)0) == 0) {
if (localtime_r(&tv.tv_sec, &tp) != NULL) {
attributes->build_date.tm_mday = tp.tm_mday;
attributes->build_date.tm_mon = tp.tm_mon;
attributes->build_date.tm_year = tp.tm_year;
} else {
(void) memset(&attributes->build_date, 0,
sizeof (attributes->build_date));
}
(void) memset(&attributes->build_date, 0,
sizeof (attributes->build_date));
}
return (1);
}
/*
* This function returns the attributes for the warpper library.
*/
HBA_UINT32
SMHBA_GetVendorLibraryAttributes(
HBA_UINT32 adapter_index,
SMHBA_LIBRARYATTRIBUTES *attributes)
{
HBA_ADAPTER_INFO *adapt_infop;
SMHBAGetVendorLibraryAttributesFunc
registeredfunc;
HBA_UINT32 ret = 0;
DEBUG(2, "SMHBA_GetVendorLibraryAttributes adapterindex:%d",
adapter_index, 0, 0);
if (_hbaapi_librarylist == NULL) {
DEBUG(1, "SMHBAAPI not loaded yet.", 0, 0, 0);
return (0);
}
if (attributes == NULL) {
DEBUG(1, "SMHBA_GetVendorLibraryAttributes: "
"NULL pointer attributes",
0, 0, 0);
return (HBA_STATUS_ERROR_ARG);
}
(void) memset(attributes, 0, sizeof (SMHBA_LIBRARYATTRIBUTES));
GRAB_MUTEX(&_hbaapi_LL_mutex);
GRAB_MUTEX(&_hbaapi_AL_mutex);
for (adapt_infop = _hbaapi_adapterlist;
adapt_infop != NULL;
adapt_infop = adapt_infop->next) {
if (adapt_infop->index == adapter_index) {
if (adapt_infop->library->version != SMHBA) {
RELEASE_MUTEX(&_hbaapi_AL_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
HBA_STATUS_ERROR_INCOMPATIBLE);
}
registeredfunc = adapt_infop->library->
ftable.smhbafunctionTable.GetVendorLibraryAttributesHandler;
if (registeredfunc != NULL) {
ret = (registeredfunc)(attributes);
#ifdef NOTDEF
} else {
/* This should not happen since the VSL is already loaded. */
#endif
}
if (attributes->LibPath[0] == '\0') {
if (strlen(adapt_infop->library->LibraryPath) < 256) {
(void) strcpy(attributes->LibPath,
adapt_infop->library->LibraryPath);
}
}
break;
}
}
RELEASE_MUTEX(&_hbaapi_AL_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, ret);
}
HBA_STATUS
SMHBA_GetAdapterAttributes(
HBA_HANDLE handle,
SMHBA_ADAPTERATTRIBUTES *hbaattributes)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetAdapterAttributesFunc GetAdapterAttributesFunc;
DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetAdapterAttributesFunc =
lib_infop->ftable.smhbafunctionTable.GetAdapterAttributesHandler;
if (GetAdapterAttributesFunc != NULL) {
status = ((GetAdapterAttributesFunc)(vendorHandle, hbaattributes));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetNumberOfPorts(
HBA_HANDLE handle,
HBA_UINT32 *numberofports)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetNumberOfPortsFunc GetNumberOfPortsFunc;
DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetNumberOfPortsFunc =
lib_infop->ftable.smhbafunctionTable.GetNumberOfPortsHandler;
if (GetNumberOfPortsFunc != NULL) {
status = ((GetNumberOfPortsFunc)(vendorHandle, numberofports));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetPortType(
HBA_HANDLE handle,
HBA_UINT32 portindex,
HBA_PORTTYPE *porttype)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetPortTypeFunc GetPortTypeFunc;
DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetPortTypeFunc =
lib_infop->ftable.smhbafunctionTable.GetPortTypeHandler;
if (GetPortTypeFunc != NULL) {
status = ((GetPortTypeFunc)(vendorHandle, portindex, porttype));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetAdapterPortAttributes(
HBA_HANDLE handle,
HBA_UINT32 portindex,
SMHBA_PORTATTRIBUTES *portattributes)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetAdapterPortAttributesFunc
GetAdapterPortAttributesFunc;
DEBUG(2, "SMHBA_GetAdapterPortAttributes", 0, 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetAdapterPortAttributesFunc =
lib_infop->ftable.smhbafunctionTable.\
GetAdapterPortAttributesHandler;
if (GetAdapterPortAttributesFunc != NULL) {
status = ((GetAdapterPortAttributesFunc)
(vendorHandle, portindex, portattributes));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetDiscoveredPortAttributes(
HBA_HANDLE handle,
HBA_UINT32 portindex,
HBA_UINT32 discoveredportindex,
SMHBA_PORTATTRIBUTES *portattributes)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetDiscoveredPortAttributesFunc
GetDiscoveredPortAttributesFunc;
DEBUG(2, "SMHBA_GetDiscoveredPortAttributes", 0, 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetDiscoveredPortAttributesFunc =
lib_infop->ftable.smhbafunctionTable.\
GetDiscoveredPortAttributesHandler;
if (GetDiscoveredPortAttributesFunc != NULL) {
status = ((GetDiscoveredPortAttributesFunc)
(vendorHandle, portindex, discoveredportindex,
portattributes));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetPortAttributesByWWN(
HBA_HANDLE handle,
HBA_WWN portWWN,
HBA_WWN domainPortWWN,
SMHBA_PORTATTRIBUTES *portattributes)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetPortAttributesByWWNFunc
GetPortAttributesByWWNFunc;
DEBUG(2, "SMHBA_GetPortAttributesByWWN: %s", WWN2STR1(&portWWN), 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetPortAttributesByWWNFunc =
lib_infop->ftable.smhbafunctionTable.GetPortAttributesByWWNHandler;
if (GetPortAttributesByWWNFunc != NULL) {
status = ((GetPortAttributesByWWNFunc)
(vendorHandle, portWWN, domainPortWWN, portattributes));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetFCPhyAttributes(
HBA_HANDLE handle,
HBA_UINT32 portindex,
HBA_UINT32 phyindex,
SMHBA_FC_PHY *phytype)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetFCPhyAttributesFunc GetFCPhyAttributesFunc;
DEBUG(2, "SMHBA_GetFCPhyAttributesByWWN", 0, 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetFCPhyAttributesFunc =
lib_infop->ftable.smhbafunctionTable.GetFCPhyAttributesHandler;
if (GetFCPhyAttributesFunc != NULL) {
status = ((GetFCPhyAttributesFunc)
(vendorHandle, portindex, phyindex, phytype));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetSASPhyAttributes(
HBA_HANDLE handle,
HBA_UINT32 portindex,
HBA_UINT32 phyindex,
SMHBA_SAS_PHY *phytype)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetSASPhyAttributesFunc GetSASPhyAttributesFunc;
DEBUG(2, "SMHBA_GetFCPhyAttributesByWWN", 0, 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetSASPhyAttributesFunc =
lib_infop->ftable.smhbafunctionTable.GetSASPhyAttributesHandler;
if (GetSASPhyAttributesFunc != NULL) {
status = ((GetSASPhyAttributesFunc)
(vendorHandle, portindex, phyindex, phytype));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetProtocolStatistics(
HBA_HANDLE handle,
HBA_UINT32 portindex,
HBA_UINT32 protocoltype,
SMHBA_PROTOCOLSTATISTICS *pProtocolStatistics)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetProtocolStatisticsFunc
GetProtocolStatisticsFunc;
DEBUG(2, "SMHBA_GetProtocolStatistics port index: %d protocol type: %d",
portindex, protocoltype, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetProtocolStatisticsFunc =
lib_infop->ftable.smhbafunctionTable.GetProtocolStatisticsHandler;
if (GetProtocolStatisticsFunc != NULL) {
status = (GetProtocolStatisticsFunc)
(vendorHandle, portindex, protocoltype, pProtocolStatistics);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetPhyStatistics(
HBA_HANDLE handle,
HBA_UINT32 portindex,
HBA_UINT32 phyindex,
SMHBA_PHYSTATISTICS *pPhyStatistics)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetPhyStatisticsFunc
GetPhyStatisticsFunc;
DEBUG(2, "SMHBA_GetPhyStatistics port index: %d phy idex: %d",
portindex, phyindex, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetPhyStatisticsFunc =
lib_infop->ftable.smhbafunctionTable.GetPhyStatisticsHandler;
if (GetPhyStatisticsFunc != NULL) {
status = (GetPhyStatisticsFunc)
(vendorHandle, portindex, phyindex, pPhyStatistics);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetBindingCapability(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN domainPortWWN,
SMHBA_BIND_CAPABILITY *pFlags)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetBindingCapabilityFunc GetBindingCapabilityFunc;
DEBUG(2, "HBA_GetBindingCapability", 0, 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetBindingCapabilityFunc =
lib_infop->ftable.smhbafunctionTable.GetBindingCapabilityHandler;
if (GetBindingCapabilityFunc != NULL) {
status = (GetBindingCapabilityFunc)(vendorHandle, hbaPortWWN,
domainPortWWN, pFlags);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetBindingSupport(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN domainPortWWN,
SMHBA_BIND_CAPABILITY *pFlags)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetBindingSupportFunc
GetBindingSupporFunc;
DEBUG(2, "SMHBA_GetBindingSupport port: %s",
WWN2STR1(&hbaPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetBindingSupporFunc =
lib_infop->ftable.smhbafunctionTable.GetBindingSupportHandler;
if (GetBindingSupporFunc != NULL) {
status = (GetBindingSupporFunc)(vendorHandle,
hbaPortWWN, domainPortWWN, pFlags);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_SetBindingSupport(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN domainPortWWN,
SMHBA_BIND_CAPABILITY flags)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBASetBindingSupportFunc
SetBindingSupporFunc;
DEBUG(2, "SMHBA_GetBindingSupport port: %s",
WWN2STR1(&hbaPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(HBAAPIV2);
SetBindingSupporFunc =
lib_infop->ftable.smhbafunctionTable.SetBindingSupportHandler;
if (SetBindingSupporFunc != NULL) {
status = (SetBindingSupporFunc)
(vendorHandle, hbaPortWWN, domainPortWWN, flags);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetTargetMapping(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN domainPortWWN,
SMHBA_TARGETMAPPING *pMapping)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetTargetMappingFunc GetTargetMappingFunc;
DEBUG(2, "SMHBA_GetTargetMapping port WWN: %s",
WWN2STR1(&hbaPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetTargetMappingFunc =
lib_infop->ftable.smhbafunctionTable.GetTargetMappingHandler;
if (GetTargetMappingFunc != NULL) {
status = ((GetTargetMappingFunc)(vendorHandle,
hbaPortWWN, domainPortWWN, pMapping));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetPersistentBinding(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN domainPortWWN,
SMHBA_BINDING *binding)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetPersistentBindingFunc
GetPersistentBindingFunc;
DEBUG(2, "SMHBA_GetPersistentBinding port WWN: %s",
WWN2STR1(&hbaPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetPersistentBindingFunc =
lib_infop->ftable.smhbafunctionTable.GetPersistentBindingHandler;
if (GetPersistentBindingFunc != NULL) {
status = ((GetPersistentBindingFunc)(vendorHandle,
hbaPortWWN, domainPortWWN, binding));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_SetPersistentBinding(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN domainPortWWN,
const SMHBA_BINDING *binding)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBASetPersistentBindingFunc
SetPersistentBindingFunc;
DEBUG(2, "SMHBA_SetPersistentBinding port WWN: %s",
WWN2STR1(&hbaPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
SetPersistentBindingFunc =
lib_infop->ftable.smhbafunctionTable.SetPersistentBindingHandler;
if (SetPersistentBindingFunc != NULL) {
status = ((SetPersistentBindingFunc)(vendorHandle,
hbaPortWWN, domainPortWWN, binding));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_RemovePersistentBinding(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN domainPortWWN,
const SMHBA_BINDING *binding)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBARemovePersistentBindingFunc
RemovePersistentBindingFunc;
DEBUG(2, "SMHBA_RemovePersistentBinding port WWN: %s",
WWN2STR1(&hbaPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
RemovePersistentBindingFunc =
lib_infop->ftable.smhbafunctionTable.RemovePersistentBindingHandler;
if (RemovePersistentBindingFunc != NULL) {
status = ((RemovePersistentBindingFunc)(vendorHandle,
hbaPortWWN, domainPortWWN, binding));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_RemoveAllPersistentBindings(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN domainPortWWN)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBARemoveAllPersistentBindingsFunc
RemoveAllPersistentBindingsFunc;
DEBUG(2, "SMHBA_RemoveAllPersistentBinding port WWN: %s",
WWN2STR1(&hbaPortWWN), 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
RemoveAllPersistentBindingsFunc =
lib_infop->ftable.smhbafunctionTable.\
RemoveAllPersistentBindingsHandler;
if (RemoveAllPersistentBindingsFunc != NULL) {
status = ((RemoveAllPersistentBindingsFunc)(vendorHandle,
hbaPortWWN, domainPortWWN));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_GetLUNStatistics(
HBA_HANDLE handle,
const HBA_SCSIID *lunit,
SMHBA_PROTOCOLSTATISTICS *statistics)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAGetLUNStatisticsFunc GetLUNStatisticsFunc;
DEBUG(2, "SMHBA_GetLUNStatistics", 0, 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
GetLUNStatisticsFunc =
lib_infop->ftable.smhbafunctionTable.GetLUNStatisticsHandler;
if (GetLUNStatisticsFunc != NULL) {
status = ((GetLUNStatisticsFunc)(vendorHandle, lunit, statistics));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_ScsiInquiry(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN discoveredPortWWN,
HBA_WWN domainPortWWN,
SMHBA_SCSILUN smhbaLUN,
HBA_UINT8 CDB_Byte1,
HBA_UINT8 CDB_Byte2,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize,
HBA_UINT8 *pScsiStatus,
void *pSenseBuffer,
HBA_UINT32 *pSenseBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAScsiInquiryFunc ScsiInquiryFunc;
DEBUG(2, "SMHBA_ScsiInquiry to hba port: %s discoveredPortWWN: %s",
WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0);
CHECKLIBRARYANDVERSION(SMHBA);
ScsiInquiryFunc =
lib_infop->ftable.smhbafunctionTable.ScsiInquiryHandler;
if (ScsiInquiryFunc != NULL) {
status = ((ScsiInquiryFunc)(
vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN,
smhbaLUN, CDB_Byte1, CDB_Byte2, pRspBuffer, pRspBufferSize,
pScsiStatus, pSenseBuffer, pSenseBufferSize));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_ScsiReportLUNs(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN discoveredPortWWN,
HBA_WWN domainPortWWN,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize,
HBA_UINT8 *pScsiStatus,
void *pSenseBuffer,
HBA_UINT32 *pSenseBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAScsiReportLUNsFunc ScsiReportLUNsFunc;
DEBUG(2, "SMHBA_ScsiReportLuns to hba port: %s discoveredPortWWN: %s",
WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0);
CHECKLIBRARYANDVERSION(SMHBA);
ScsiReportLUNsFunc =
lib_infop->ftable.smhbafunctionTable.ScsiReportLUNsHandler;
if (ScsiReportLUNsFunc != NULL) {
status = ((ScsiReportLUNsFunc)(
vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN,
pRspBuffer, pRspBufferSize, pScsiStatus, pSenseBuffer,
pSenseBufferSize));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_ScsiReadCapacity(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN discoveredPortWWN,
HBA_WWN domainPortWWN,
SMHBA_SCSILUN smhbaLUN,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize,
HBA_UINT8 *pScsiStatus,
void *pSenseBuffer,
HBA_UINT32 *pSenseBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBAScsiReadCapacityFunc ScsiReadCapacityFunc;
DEBUG(2, "SMHBA_ScsiReadCapacity to hba port: %s discoveredPortWWN: %s",
WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0);
CHECKLIBRARYANDVERSION(SMHBA);
ScsiReadCapacityFunc =
lib_infop->ftable.smhbafunctionTable.ScsiReadCapacityHandler;
if (ScsiReadCapacityFunc != NULL) {
status = ((ScsiReadCapacityFunc)(
vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN,
smhbaLUN, pRspBuffer, pRspBufferSize, pScsiStatus, pSenseBuffer,
pSenseBufferSize));
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_SendTEST(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN destWWN,
HBA_UINT32 destFCID,
void *pRspBuffer,
HBA_UINT32 pRspBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBASendTESTFunc SendTESTFunc;
DEBUG(2, "SMHBA_SendTEST, hbaPortWWN: %s destWWN",
WWN2STR1(&hbaPortWWN),
WWN2STR1(&destWWN), 0);
CHECKLIBRARYANDVERSION(SMHBA);
SendTESTFunc = lib_infop->ftable.smhbafunctionTable.SendTESTHandler;
if (SendTESTFunc != NULL) {
status = (SendTESTFunc)
(vendorHandle, hbaPortWWN, destWWN, destFCID,
pRspBuffer, pRspBufferSize);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_SendECHO(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN destWWN,
HBA_UINT32 destFCID,
void *pReqBuffer,
HBA_UINT32 ReqBufferSize,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBASendECHOFunc SendECHOFunc;
DEBUG(2, "SMHBA_SendECHO, hbaPortWWN: %s destWWN",
WWN2STR1(&hbaPortWWN), WWN2STR1(&destWWN), 0);
CHECKLIBRARYANDVERSION(SMHBA);
SendECHOFunc = lib_infop->ftable.smhbafunctionTable.SendECHOHandler;
if (SendECHOFunc != NULL) {
status = (SendECHOFunc)
(vendorHandle, hbaPortWWN, destWWN, destFCID,
pReqBuffer, ReqBufferSize, pRspBuffer, pRspBufferSize);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
HBA_STATUS
SMHBA_SendSMPPassThru(
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN destWWN,
HBA_WWN domainPortWWN,
void *pReqBuffer,
HBA_UINT32 ReqBufferSize,
void *pRspBuffer,
HBA_UINT32 *pRspBufferSize)
{
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
SMHBASendSMPPassThruFunc SendSMPPassThruFunc;
DEBUG(2, "SMHBA_SendSMPPassThru, hbaPortWWN: %s destWWN: %s",
WWN2STR1(&hbaPortWWN), WWN2STR1(&destWWN), 0);
CHECKLIBRARYANDVERSION(SMHBA);
SendSMPPassThruFunc = lib_infop->ftable.\
smhbafunctionTable.SendSMPPassThruHandler;
if (SendSMPPassThruFunc != NULL) {
status = (SendSMPPassThruFunc)
(vendorHandle, hbaPortWWN, destWWN, domainPortWWN,
pReqBuffer, ReqBufferSize, pRspBuffer, pRspBufferSize);
} else {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
/*
* 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
smhba_adapteraddevents_callback(
/* LINTED E_FUNC_ARG_UNUSED */
void *data,
HBA_WWN PortWWN,
/* LINTED E_FUNC_ARG_UNUSED */
HBA_UINT32 eventType)
{
HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
DEBUG(3, "AddAdapterEvent, port:%s", WWN2STR1(&PortWWN), 0, 0);
GRAB_MUTEX(&_smhba_AAE_mutex);
for (cbp = _smhba_adapteraddevents_callback_list;
cbp != NULL;
cbp = cbp->next) {
(*cbp->callback)(cbp->userdata, PortWWN, HBA_EVENT_ADAPTER_ADD);
}
RELEASE_MUTEX(&_smhba_AAE_mutex);
}
HBA_STATUS
SMHBA_RegisterForAdapterAddEvents(
void (*pCallback) (
void *data,
HBA_WWN PortWWN,
HBA_UINT32 eventType),
void *pUserData,
HBA_CALLBACKHANDLE *pCallbackHandle) {
HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
HBA_VENDORCALLBACK_ELEM *vcbp;
HBA_VENDORCALLBACK_ELEM *vendorhandlelist;
SMHBARegisterForAdapterAddEventsFunc registeredfunc;
HBA_STATUS status = HBA_STATUS_OK;
HBA_STATUS failure = HBA_STATUS_OK;
HBA_LIBRARY_INFO *lib_infop;
int registered_cnt = 0;
int vendor_cnt = 0;
int not_supported_cnt = 0;
int status_OK_bar_cnt = 0;
int status_OK_cnt = 0;
DEBUG(2, "SMHBA_RegisterForAdapterAddEvents", 0, 0, 0);
ARE_WE_INITED();
cbp = (HBA_ALLADAPTERSCALLBACK_ELEM *)
calloc(1, sizeof (HBA_ALLADAPTERSCALLBACK_ELEM));
*pCallbackHandle = (HBA_CALLBACKHANDLE) cbp;
if (cbp == NULL) {
return (HBA_STATUS_ERROR);
}
GRAB_MUTEX(&_hbaapi_LL_mutex);
GRAB_MUTEX(&_smhba_AAE_mutex);
cbp->callback = pCallback;
cbp->userdata = pUserData;
cbp->next = _smhba_adapteraddevents_callback_list;
_smhba_adapteraddevents_callback_list = cbp;
/*
* 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
*/
RELEASE_MUTEX(&_smhba_AAE_mutex);
/*
* now create a list of vendors (vendor libraryies, NOT ADAPTERS)
* that have successfully registerred
*/
vendorhandlelist = NULL;
for (lib_infop = _hbaapi_librarylist;
lib_infop != NULL;
lib_infop = lib_infop->next) {
/* only for HBAAPI V2 */
if (lib_infop->version != SMHBA) {
continue;
} else {
vendor_cnt++;
}
registeredfunc =
lib_infop->ftable.smhbafunctionTable.\
RegisterForAdapterAddEventsHandler;
if (registeredfunc == NULL) {
continue;
}
vcbp = (HBA_VENDORCALLBACK_ELEM *)
calloc(1, sizeof (HBA_VENDORCALLBACK_ELEM));
if (vcbp == NULL) {
freevendorhandlelist(vendorhandlelist);
status = HBA_STATUS_ERROR;
break;
}
registered_cnt++;
status = (registeredfunc)(smhba_adapteraddevents_callback,
pUserData, &vcbp->vendorcbhandle);
if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
not_supported_cnt++;
free(vcbp);
continue;
} else if (status != HBA_STATUS_OK) {
status_OK_bar_cnt++;
DEBUG(1,
"SMHBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
lib_infop->LibraryPath, status, 0);
failure = status;
free(vcbp);
continue;
} else {
status_OK_cnt++;
}
vcbp->lib_info = lib_infop;
vcbp->next = vendorhandlelist;
vendorhandlelist = vcbp;
}
if (vendor_cnt == 0) {
/* no SMHBA VSL found. Should be okay?? */
status = HBA_STATUS_ERROR;
} else if (registered_cnt == 0) {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
freevendorhandlelist(vendorhandlelist);
(void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
} else if (status_OK_cnt == 0 && not_supported_cnt != 0) {
status = HBA_STATUS_ERROR_NOT_SUPPORTED;
} else if (status_OK_cnt == 0) {
/*
* At least one vendor library registered this function, but no
* vendor call succeeded
*/
(void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
status = failure;
} else {
/* we have had atleast some success, now finish up */
GRAB_MUTEX(&_smhba_AAE_mutex);
/*
* this seems silly, but what if another thread called
* the callback remove
*/
for (cbp = _smhba_adapteraddevents_callback_list;
cbp != NULL; cbp = cbp->next) {
if ((HBA_CALLBACKHANDLE)cbp == *pCallbackHandle) {
/* yup, its still there, hooray */
cbp->vendorhandlelist = vendorhandlelist;
vendorhandlelist = NULL;
break;
}
}
RELEASE_MUTEX(&_smhba_AAE_mutex);
if (vendorhandlelist != NULL) {
/*
* bummer, somebody removed the callback before we finished
* registration, probably will never happen
*/
freevendorhandlelist(vendorhandlelist);
DEBUG(1,
"HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was "
"called for a handle before registration was finished.",
0, 0, 0);
status = HBA_STATUS_ERROR;
} else {
status = HBA_STATUS_OK;
}
}
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
/* SMHBA Adapter Events (other than add) ******************************** */
static void
smhba_adapterevents_callback(void *data,
HBA_WWN PortWWN,
HBA_UINT32 eventType)
{
HBA_ADAPTERCALLBACK_ELEM *acbp;
DEBUG(3, "AdapterEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN),
eventType, 0);
GRAB_MUTEX(&_hbaapi_AE_mutex);
for (acbp = _smhba_adapterevents_callback_list;
acbp != NULL;
acbp = acbp->next) {
if (data == (void *)acbp) {
(*acbp->callback)(acbp->userdata, PortWWN, eventType);
break;
}
}
RELEASE_MUTEX(&_hbaapi_AE_mutex);
}
HBA_STATUS
SMHBA_RegisterForAdapterEvents(
void (*pCallback) (
void *data,
HBA_WWN PortWWN,
HBA_UINT32 eventType),
void *pUserData,
HBA_HANDLE handle,
HBA_CALLBACKHANDLE *pCallbackHandle) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
SMHBARegisterForAdapterEventsFunc registeredfunc;
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
DEBUG(2, "SMHBA_RegisterForAdapterEvents", 0, 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
/* we now have the _hbaapi_LL_mutex */
registeredfunc = lib_infop->ftable.smhbafunctionTable.\
RegisterForAdapterEventsHandler;
if (registeredfunc == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
}
/*
* 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 *)
calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
if (acbp == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
}
*pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
acbp->callback = pCallback;
acbp->userdata = pUserData;
acbp->lib_info = lib_infop;
status = (registeredfunc)(smhba_adapterevents_callback,
(void *)acbp,
vendorHandle,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
free(acbp);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
GRAB_MUTEX(&_smhba_AE_mutex);
acbp->next = _smhba_adapterevents_callback_list;
_hbaapi_adapterevents_callback_list = acbp;
RELEASE_MUTEX(&_smhba_AE_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
}
/* Adapter Port Events *********************************************** */
static void
smhba_adapterportevents_callback(void *data,
HBA_WWN PortWWN,
HBA_UINT32 eventType,
HBA_UINT32 fabricPortID)
{
HBA_ADAPTERCALLBACK_ELEM *acbp;
DEBUG(3,
"SMHBA_AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x",
WWN2STR1(&PortWWN), eventType, fabricPortID);
GRAB_MUTEX(&_smhba_APE_mutex);
for (acbp = _smhba_adapterportevents_callback_list;
acbp != NULL;
acbp = acbp->next) {
if (data == (void *)acbp) {
(*acbp->callback)(acbp->userdata, PortWWN,
eventType, fabricPortID);
break;
}
}
RELEASE_MUTEX(&_smhba_APE_mutex);
}
HBA_STATUS
SMHBA_RegisterForAdapterPortEvents(
void (*pCallback) (
void *pData,
HBA_WWN PortWWN,
HBA_UINT32 eventType,
HBA_UINT32 fabricPortID),
void *pUserData,
HBA_HANDLE handle,
HBA_WWN portWWN,
HBA_UINT32 specificEventType,
HBA_CALLBACKHANDLE *pCallbackHandle) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
SMHBARegisterForAdapterPortEventsFunc registeredfunc;
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
DEBUG(2, "SMHBA_RegisterForAdapterPortEvents for port: %s",
WWN2STR1(&portWWN), 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
/* we now have the _hbaapi_LL_mutex */
registeredfunc =
lib_infop->ftable.smhbafunctionTable.\
RegisterForAdapterPortEventsHandler;
if (registeredfunc == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
}
/*
* 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 *)
calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
if (acbp == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
}
*pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
acbp->callback = pCallback;
acbp->userdata = pUserData;
acbp->lib_info = lib_infop;
status = (registeredfunc)(smhba_adapterportevents_callback,
(void *)acbp,
vendorHandle,
portWWN,
specificEventType,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
free(acbp);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
GRAB_MUTEX(&_smhba_APE_mutex);
acbp->next = _smhba_adapterportevents_callback_list;
_smhba_adapterportevents_callback_list = acbp;
RELEASE_MUTEX(&_smhba_APE_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
}
/* SMHBA Adapter Port Stat Events ******************************** */
static void
smhba_adapterportstatevents_callback(void *data,
HBA_WWN portWWN,
HBA_UINT32 protocolType,
HBA_UINT32 eventType)
{
HBA_ADAPTERCALLBACK_ELEM *acbp;
DEBUG(3,
"SMBA_AdapterPortStateEvent, port:%s, eventType:%d",
WWN2STR1(&portWWN), eventType, 0);
GRAB_MUTEX(&_smhba_APSE_mutex);
for (acbp = _smhba_adapterportstatevents_callback_list;
acbp != NULL;
acbp = acbp->next) {
if (data == (void *)acbp) {
(*acbp->callback)(acbp->userdata, portWWN,
protocolType, eventType);
return;
}
}
RELEASE_MUTEX(&_smhba_APSE_mutex);
}
HBA_STATUS
SMHBA_RegisterForAdapterPortStatEvents(
void (*pCallback) (
void *pData,
HBA_WWN portWWN,
HBA_UINT32 protocolType,
HBA_UINT32 eventType),
void *pUserData,
HBA_HANDLE handle,
HBA_WWN portWWN,
HBA_UINT32 protocolType,
SMHBA_PROTOCOLSTATISTICS stats,
HBA_UINT32 statType,
HBA_CALLBACKHANDLE *pCallbackHandle) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
SMHBARegisterForAdapterPortStatEventsFunc
registeredfunc;
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
DEBUG(2, "SMHBA_RegisterForAdapterPortStatEvents for port: %s",
WWN2STR1(&portWWN), 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
/* we now have the _hbaapi_LL_mutex */
registeredfunc =
lib_infop->ftable.smhbafunctionTable.\
RegisterForAdapterPortStatEventsHandler;
if (registeredfunc == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
}
/*
* 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 *)
calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
if (acbp == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
}
*pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
acbp->callback = pCallback;
acbp->userdata = pUserData;
acbp->lib_info = lib_infop;
status = (registeredfunc)(smhba_adapterportstatevents_callback,
(void *)acbp,
vendorHandle,
portWWN,
protocolType,
stats,
statType,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
free(acbp);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
GRAB_MUTEX(&_smhba_APSE_mutex);
acbp->next = _smhba_adapterportstatevents_callback_list;
_smhba_adapterportstatevents_callback_list = acbp;
RELEASE_MUTEX(&_smhba_APSE_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
}
/* SMHBA Adapter Port Phy Stat Events ************************************ */
static void
smhba_adapterphystatevents_callback(void *data,
HBA_WWN portWWN,
HBA_UINT32 phyIndex,
HBA_UINT32 eventType)
{
HBA_ADAPTERCALLBACK_ELEM *acbp;
DEBUG(3,
"SMBA_AdapterPortStateEvent, port:%s, eventType:%d",
WWN2STR1(&portWWN), eventType, 0);
GRAB_MUTEX(&_smhba_APHYSE_mutex);
for (acbp = _smhba_adapterphystatevents_callback_list;
acbp != NULL;
acbp = acbp->next) {
if (data == (void *)acbp) {
(*acbp->callback)(acbp->userdata, portWWN, phyIndex, eventType);
return;
}
}
RELEASE_MUTEX(&_smhba_APHYSE_mutex);
}
HBA_STATUS
SMHBA_RegisterForAdapterPhyStatEvents(
void (*pCallback) (
void *pData,
HBA_WWN portWWN,
HBA_UINT32 phyIndex,
HBA_UINT32 eventType),
void *pUserData,
HBA_HANDLE handle,
HBA_WWN portWWN,
HBA_UINT32 phyIndex,
SMHBA_PHYSTATISTICS stats,
HBA_UINT32 statType,
HBA_CALLBACKHANDLE *pCallbackHandle) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
SMHBARegisterForAdapterPhyStatEventsFunc
registeredfunc;
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
DEBUG(2, "SMHBA_RegisterForAdapterPhyStatEvents for port: %s",
WWN2STR1(&portWWN), 0, 0);
CHECKLIBRARYANDVERSION(SMHBA);
/* we now have the _hbaapi_LL_mutex */
registeredfunc =
lib_infop->ftable.smhbafunctionTable.\
RegisterForAdapterPhyStatEventsHandler;
if (registeredfunc == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
}
/*
* 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 *)
calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
if (acbp == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
}
*pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
acbp->callback = pCallback;
acbp->userdata = pUserData;
acbp->lib_info = lib_infop;
status = (registeredfunc)(smhba_adapterphystatevents_callback,
(void *)acbp,
vendorHandle,
portWWN,
phyIndex,
stats,
statType,
&acbp->vendorcbhandle);
if (status != HBA_STATUS_OK) {
free(acbp);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
GRAB_MUTEX(&_smhba_APHYSE_mutex);
acbp->next = _smhba_adapterphystatevents_callback_list;
_smhba_adapterphystatevents_callback_list = acbp;
RELEASE_MUTEX(&_smhba_APHYSE_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
}
/* SMHBA Target Events ********************************************* */
static void
smhba_targetevents_callback(void *data,
HBA_WWN hbaPortWWN,
HBA_WWN discoveredPortWWN,
HBA_WWN domainPortWWN,
HBA_UINT32 eventType)
{
HBA_ADAPTERCALLBACK_ELEM *acbp;
DEBUG(3, "TargetEvent, hbaPort:%s, discoveredPort:%s eventType:%d",
WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), eventType);
GRAB_MUTEX(&_smhba_TE_mutex);
for (acbp = _smhba_targetevents_callback_list;
acbp != NULL;
acbp = acbp->next) {
if (data == (void *)acbp) {
(*acbp->callback)(acbp->userdata, hbaPortWWN,
discoveredPortWWN, domainPortWWN, eventType);
break;
}
}
RELEASE_MUTEX(&_smhba_TE_mutex);
}
HBA_STATUS
SMHBA_RegisterForTargetEvents(
void (*pCallback) (
void *pData,
HBA_WWN hbaPortWWN,
HBA_WWN discoveredPortWWN,
HBA_WWN domainPortWWN,
HBA_UINT32 eventType),
void *pUserData,
HBA_HANDLE handle,
HBA_WWN hbaPortWWN,
HBA_WWN discoveredPortWWN,
HBA_WWN domainPortWWN,
HBA_CALLBACKHANDLE *pCallbackHandle,
HBA_UINT32 allTargets) {
HBA_ADAPTERCALLBACK_ELEM *acbp;
SMHBARegisterForTargetEventsFunc
registeredfunc;
HBA_STATUS status;
HBA_LIBRARY_INFO *lib_infop;
HBA_HANDLE vendorHandle;
DEBUG(2, "SMHBA_RegisterForTargetEvents, hbaPort:"
"%s, discoveredPort: %s",
WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), 0);
CHECKLIBRARYANDVERSION(SMHBA);
/* we now have the _hbaapi_LL_mutex */
registeredfunc = lib_infop->ftable.smhbafunctionTable.\
RegisterForTargetEventsHandler;
if (registeredfunc == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
}
/*
* 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 *)
calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
if (acbp == NULL) {
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
}
*pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
acbp->callback = pCallback;
acbp->userdata = pUserData;
acbp->lib_info = lib_infop;
status = (registeredfunc)(smhba_targetevents_callback,
(void *)acbp,
vendorHandle,
hbaPortWWN,
discoveredPortWWN,
domainPortWWN,
&acbp->vendorcbhandle,
allTargets);
if (status != HBA_STATUS_OK) {
free(acbp);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
}
GRAB_MUTEX(&_smhba_TE_mutex);
acbp->next = _smhba_targetevents_callback_list;
_smhba_targetevents_callback_list = acbp;
RELEASE_MUTEX(&_smhba_TE_mutex);
RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
}