1N/A/*
1N/A * ************************************************************************
1N/A * Description
1N/A * HBAAPILIB.c - Implements a sample common (wrapper) HBA API library
1N/A *
1N/A * License:
1N/A * The contents of this file are subject to the SNIA Public License
1N/A * Version 1.0 (the "License"); you may not use this file except in
1N/A * compliance with the License. You may obtain a copy of the License at
1N/A *
1N/A * /http://www.snia.org/English/Resources/Code/OpenSource.html
1N/A *
1N/A * Software distributed under the License is distributed on an "AS IS"
1N/A * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
1N/A * the License for the specific language governing rights and limitations
1N/A * under the License.
1N/A *
1N/A * The Original Code is SNIA HBA API Wrapper Library
1N/A *
1N/A * The Initial Developer of the Original Code is:
1N/A * Benjamin F. Kuo, Troika Networks, Inc. (benk@troikanetworks.com)
1N/A *
1N/A * Contributor(s):
1N/A * Tuan Lam, QLogic Corp. (t_lam@qlc.com)
1N/A * Dan Willie, Emulex Corp. (Dan.Willie@emulex.com)
1N/A * Dixon Hutchinson, Legato Systems, Inc. (dhutchin@legato.com)
1N/A * David Dillard, VERITAS Software Corp. (david.dillard@veritas.com)
1N/A *
1N/A * ************************************************************************
1N/A *
1N/A * Adding on SM-HBA support
1N/A *
1N/A * The implementation includes Three different categories functions to support
1N/A * both HBAAPI and SM-HBA through the same library.
1N/A *
1N/A * SM-HBA unique interface:
1N/A * 1. CHECKLIBRARYANDVERSION(SMHBA) : match SMHBA VSL
1N/A * Or checking specifically if version is SMHBA beforehand.
1N/A * 2. resolved to ftable.smhbafunctiontable.{interface}
1N/A * HBAAPIV2 unique functions
1N/A * 1. CHECKLIBRARYANDVERSION(HBAAPIV2) : validate and match HBAAPI V2 VSL.
1N/A * Or checking specifically if version is HBAAPIV2 beforehand.
1N/A * 2. resolved to ftable.functiontable.{interface}
1N/A * Common interface between SM-HBA and HBAAPIV2.
1N/A * 1. CHECKLIBRARY() : to validate the VSL.
1N/A * 2. FUNCCOMMON macro to map the appropriate entry point table
1N/A * (union ftable).
1N/A * 3. If the interface is not supported by HBAAPI(Version 1)
1N/A * the funtiion ptr will be set to NULL.
1N/A * Common interface between HBAAPI and HBAAPIV2.
1N/A * 1. Check if version is not SMHBA).
1N/A * 2. ftable.functiontalbe.(interface)
1N/A *
1N/A * ************************************************************************
1N/A */
1N/A/*
1N/A * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
1N/A * Use is subject to license terms.
1N/A */
1N/A
1N/A#ifdef WIN32
1N/A#include <windows.h>
1N/A#include <string.h>
1N/A/*
1N/A * Next define forces entry points in the dll to be exported
1N/A * See hbaapi.h to see what it does.
1N/A */
1N/A#define HBAAPI_EXPORTS
1N/A#else
1N/A#include <dlfcn.h>
1N/A#include <strings.h>
1N/A#endif
1N/A#include <stdio.h>
1N/A#include <time.h>
1N/A#include "smhbaapi.h"
1N/A#include "vendorsmhbaapi.h"
1N/A#include <stdlib.h>
1N/A#ifdef USESYSLOG
1N/A#include <syslog.h>
1N/A#endif
1N/A#ifdef SOLARIS
1N/A#include <link.h>
1N/A#include <limits.h>
1N/Astatic int *handle;
1N/Astatic Link_map *map, *mp;
1N/A#endif
1N/A
1N/A/*
1N/A * LIBRARY_NUM is a shortcut to figure out which library we need to call.
1N/A * The top 16 bits of handle are the library index
1N/A */
1N/A#define LIBRARY_NUM(handle) ((handle)>>16)
1N/A
1N/A/*
1N/A * VENDOR_HANDLE turns a global library handle into a vendor specific handle,
1N/A * with all upper 16 bits set to 0
1N/A */
1N/A#define VENDOR_HANDLE(handle) ((handle)&0xFFFF)
1N/A
1N/A#define HBA_HANDLE_FROM_LOCAL(library, vendor) \
1N/A (((library)<<16) | ((vendor)&0x0000FFFF))
1N/A
1N/Aint _hbaapi_debuglevel = 0;
1N/A#define DEBUG(L, STR, A1, A2, A3)
1N/A
1N/A#if defined(USESYSLOG) && defined(USELOGFILE)
1N/AFILE *_hbaapi_debug_fd = NULL;
1N/Aint _hbaapi_sysloginit = 0;
1N/A#undef DEBUG
1N/A#ifdef WIN32
1N/A#define DEBUG(L, STR, A1, A2, A3)\
1N/A if ((L) <= _hbaapi_debuglevel) {\
1N/A if (_hbaapi_sysloginit == 0) {\
1N/A openlog("HBAAPI", LOG_PID|LOG_ODELAY, LOG_USER);\
1N/A _hbaapi_sysloginit = 1;\
1N/A }\
1N/A syslog(LOG_INFO, (STR), (A1), (A2), (A3));\
1N/A if (_hbaapi_debug_fd == NULL) {\
1N/A char _logFile[MAX_PATH]; \
1N/A GetTempPath(MAX_PATH, _logFile); \
1N/A strcat(_logFile, "HBAAPI.log"); \
1N/A _hbaapi_debug_fd = fopen(_logFile, "a");\
1N/A }\
1N/A if (_hbaapi_debug_fd != NULL) {\
1N/A fprintf(_hbaapi_debug_fd, #STR "\n", (A1), (A2), (A3));\
1N/A }\
1N/A }
1N/A#else /* WIN32 */
1N/A#define DEBUG(L, STR, A1, A2, A3)\
1N/A if ((L) <= _hbaapi_debuglevel) {\
1N/A if (_hbaapi_sysloginit == 0) {\
1N/A openlog("HBAAPI", LOG_PID|LOG_ODELAY, LOG_USER);\
1N/A _hbaapi_sysloginit = 1;\
1N/A }\
1N/A syslog(LOG_INFO, (STR), (A1), (A2), (A3));\
1N/A if (_hbaapi_debug_fd == NULL) {\
1N/A _hbaapi_debug_fd = fopen("/tmp/HBAAPI.log", "a");\
1N/A }\
1N/A if (_hbaapi_debug_fd != NULL) {\
1N/A fprintf(_hbaapi_debug_fd, #STR "\n", (A1), (A2), (A3));\
1N/A }\
1N/A }
1N/A#endif /* WIN32 */
1N/A
1N/A#else /* Not both USESYSLOG and USELOGFILE */
1N/A#if defined(USESYSLOG)
1N/Aint _hbaapi_sysloginit = 0;
1N/A#undef DEBUG
1N/A#define DEBUG(L, STR, A1, A2, A3) \
1N/A if ((L) <= _hbaapi_debuglevel) {\
1N/A if (_hbaapi_sysloginit == 0) {\
1N/A openlog("HBAAPI", LOG_PID|LOG_ODELAY, LOG_USER);\
1N/A _hbaapi_sysloginit = 1;\
1N/A }\
1N/A syslog(LOG_DEBUG, (STR), (A1), (A2), (A3));\
1N/A }
1N/A#endif /* USESYSLOG */
1N/A#if defined(USELOGFILE)
1N/AFILE *_hbaapi_debug_fd = NULL;
1N/A#undef DEBUG
1N/A#ifdef WIN32
1N/A#define DEBUG(L, STR, A1, A2, A3) \
1N/A if ((L) <= _hbaapi_debuglevel) {\
1N/A if (_hbaapi_debug_fd == NULL) {\
1N/A char _logFile[MAX_PATH]; \
1N/A GetTempPath(MAX_PATH, _logFile); \
1N/A strcat(_logFile, "HBAAPI.log"); \
1N/A _hbaapi_debug_fd = fopen(_logFile, "a");\
1N/A }\
1N/A }
1N/A#else /* WIN32 */
1N/A#define DEBUG(L, STR, A1, A2, A3) \
1N/A if ((L) <= _hbaapi_debuglevel) {\
1N/A if (_hbaapi_debug_fd == NULL) {\
1N/A _hbaapi_debug_fd = fopen("/tmp/HBAAPI.log", "a");\
1N/A }\
1N/A if (_hbaapi_debug_fd != NULL) { \
1N/A fprintf(_hbaapi_debug_fd, #STR "\n", (A1), (A2), (A3));\
1N/A }\
1N/A }
1N/A#endif /* WIN32 */
1N/A#endif /* USELOGFILE */
1N/A#endif /* Not both USELOGFILE and USESYSLOG */
1N/A
1N/A#ifdef POSIX_THREADS
1N/A#include <pthread.h>
1N/A/*
1N/A * When multiple mutex's are grabed, they must be always be grabbed in
1N/A * the same order, or deadlock can result. There are three levels
1N/A * of mutex's involved in this API. If LL_mutex is grabbed, always grap
1N/A * it first. If AL_mutex is grabbed, it may not be grabbed before
1N/A * LL_mutex. If grabbed in a multi grab sequence, the mutex's protecting
1N/A * the callback lists must always be grabbed last and release before calling
1N/A * a vendor specific library function that might invoke a callback function
1N/A * on the same thread.
1N/A */
1N/A#define GRAB_MUTEX(M) grab_mutex(M)
1N/A#define RELEASE_MUTEX(M) release_mutex(M)
1N/A#define RELEASE_MUTEX_RETURN(M, RET) release_mutex(M); return (RET)
1N/A#elif defined(WIN32)
1N/A#define GRAB_MUTEX(m) EnterCriticalSection(m)
1N/A#define RELEASE_MUTEX(m) LeaveCriticalSection(m)
1N/A#define RELEASE_MUTEX_RETURN(m, RET) LeaveCriticalSection(m); return (RET)
1N/A#else
1N/A#define GRAB_MUTEX(M)
1N/A#define RELEASE_MUTEX(M)
1N/A#define RELEASE_MUTEX_RETURN(M, RET) return (RET)
1N/A#endif
1N/A
1N/A/*
1N/A * Vendor library information
1N/A */
1N/Atypedef enum {
1N/A HBA_LIBRARY_UNKNOWN,
1N/A HBA_LIBRARY_LOADED,
1N/A HBA_LIBRARY_NOT_LOADED
1N/A} HBA_LIBRARY_STATUS;
1N/A
1N/Atypedef enum {
1N/A UNKNOWN = 1,
1N/A SMHBA,
1N/A HBAAPIV2,
1N/A HBAAPI
1N/A} LIBRARY_VERSION;
1N/A
1N/Atypedef struct hba_library_info {
1N/A struct hba_library_info
1N/A *next;
1N/A#ifdef WIN32
1N/A HINSTANCE hLibrary; /* Handle to a loaded DLL */
1N/A#else
1N/A char *LibraryName;
1N/A void* hLibrary; /* Handle to a loaded DLL */
1N/A#endif
1N/A char *LibraryPath;
1N/A LIBRARY_VERSION version; /* resolve union */
1N/A HBA_UINT32 numOfAdapters;
1N/A union {
1N/A SMHBA_ENTRYPOINTS smhbafunctionTable; /* smhba function pointers */
1N/A HBA_ENTRYPOINTSV2 functionTable; /* hba api function pointers */
1N/A } ftable;
1N/A HBA_LIBRARY_STATUS status; /* info on this library */
1N/A HBA_UINT32 index;
1N/A} HBA_LIBRARY_INFO, *PHBA_LIBRARY_INFO;
1N/A
1N/A#define ARE_WE_INITED() \
1N/A if (_hbaapi_librarylist == NULL) { \
1N/A return (HBA_STATUS_ERROR_NOT_LOADED); \
1N/A }
1N/AHBA_LIBRARY_INFO *_hbaapi_librarylist = NULL;
1N/AHBA_UINT32 _hbaapi_total_library_count = 0;
1N/A#ifdef POSIX_THREADS
1N/Apthread_mutex_t _hbaapi_LL_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/A#elif defined(WIN32)
1N/ACRITICAL_SECTION _hbaapi_LL_mutex;
1N/A#endif
1N/A
1N/A/*
1N/A * Macro to use the right function table between smhba and hbaapi.
1N/A */
1N/A#define FUNCTABLE(lib_infop) \
1N/A ((lib_infop->version == SMHBA) ? \
1N/A lib_infop->ftable.smhbafunctionTable : \
1N/A lib_infop->ftable.functionTable);
1N/A
1N/A/*
1N/A * Macro to use the right function ptr between smhba and hbaapi function table.
1N/A * Should be used for an interface common to SM-HBA and HBAAPIV2.
1N/A */
1N/A#define FUNCCOMMON(lib_infop, func) \
1N/A ((lib_infop->version == SMHBA) ? \
1N/A lib_infop->ftable.smhbafunctionTable.func : \
1N/A lib_infop->ftable.functionTable.func)
1N/A
1N/A/*
1N/A * Macro to use the hbaapi function ptr.
1N/A * Should be used for an interface applicable only HBAAPIV2.
1N/A */
1N/A#define FUNCHBAAPIV2(lib_infop, func) \
1N/A lib_infop->ftable.functionTable.func
1N/A
1N/A/*
1N/A * Macro to use the hbaapi function ptr.
1N/A * Should be used for an interface applicable only HBAAPIV2.
1N/A */
1N/A#define FUNCSMHBA(lib_infop, func) \
1N/A lib_infop->ftable.smhbafunctionTable.func
1N/A
1N/A/*
1N/A * Individual adapter (hba) information
1N/A */
1N/Atypedef struct hba_adapter_info {
1N/A struct hba_adapter_info
1N/A *next;
1N/A HBA_STATUS GNstatus; /* status from GetAdapterNameFunc */
1N/A char *name;
1N/A HBA_WWN nodeWWN;
1N/A HBA_LIBRARY_INFO *library;
1N/A HBA_UINT32 index;
1N/A} HBA_ADAPTER_INFO;
1N/A
1N/AHBA_ADAPTER_INFO *_hbaapi_adapterlist = NULL;
1N/AHBA_UINT32 _hbaapi_total_adapter_count = 0;
1N/A#ifdef POSIX_THREADS
1N/Apthread_mutex_t _hbaapi_AL_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/A#elif defined(WIN32)
1N/ACRITICAL_SECTION _hbaapi_AL_mutex;
1N/A#endif
1N/A
1N/A/*
1N/A * Call back registration
1N/A */
1N/Atypedef struct hba_vendorcallback_elem {
1N/A struct hba_vendorcallback_elem
1N/A *next;
1N/A HBA_CALLBACKHANDLE vendorcbhandle;
1N/A HBA_LIBRARY_INFO *lib_info;
1N/A} HBA_VENDORCALLBACK_ELEM;
1N/A
1N/A/*
1N/A * Each instance of HBA_ADAPTERCALLBACK_ELEM represents a call to one of
1N/A * "register" functions that apply to a particular adapter.
1N/A * HBA_ALLADAPTERSCALLBACK_ELEM is used just for HBA_RegisterForAdapterAddEvents
1N/A */
1N/Atypedef struct hba_adaptercallback_elem {
1N/A struct hba_adaptercallback_elem
1N/A *next;
1N/A HBA_LIBRARY_INFO *lib_info;
1N/A void *userdata;
1N/A HBA_CALLBACKHANDLE vendorcbhandle;
1N/A void (*callback)();
1N/A} HBA_ADAPTERCALLBACK_ELEM;
1N/A
1N/Atypedef struct hba_alladapterscallback_elem {
1N/A struct hba_alladapterscallback_elem
1N/A *next;
1N/A void *userdata;
1N/A HBA_VENDORCALLBACK_ELEM *vendorhandlelist;
1N/A void (*callback)();
1N/A} HBA_ALLADAPTERSCALLBACK_ELEM;
1N/A
1N/AHBA_ALLADAPTERSCALLBACK_ELEM *_hbaapi_adapteraddevents_callback_list = NULL;
1N/AHBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterevents_callback_list = NULL;
1N/AHBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterportevents_callback_list = NULL;
1N/AHBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterportstatevents_callback_list = NULL;
1N/AHBA_ADAPTERCALLBACK_ELEM *_hbaapi_targetevents_callback_list = NULL;
1N/AHBA_ADAPTERCALLBACK_ELEM *_hbaapi_linkevents_callback_list = NULL;
1N/A
1N/AHBA_ALLADAPTERSCALLBACK_ELEM *_smhba_adapteraddevents_callback_list = NULL;
1N/AHBA_ADAPTERCALLBACK_ELEM *_smhba_adapterevents_callback_list = NULL;
1N/AHBA_ADAPTERCALLBACK_ELEM *_smhba_adapterportevents_callback_list = NULL;
1N/AHBA_ADAPTERCALLBACK_ELEM *_smhba_adapterportstatevents_callback_list = NULL;
1N/AHBA_ADAPTERCALLBACK_ELEM *_smhba_adapterphystatevents_callback_list = NULL;
1N/AHBA_ADAPTERCALLBACK_ELEM *_smhba_targetevents_callback_list = NULL;
1N/A
1N/A#ifdef POSIX_THREADS
1N/A/* mutex's to protect each list */
1N/Apthread_mutex_t _hbaapi_AAE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/Apthread_mutex_t _hbaapi_AE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/Apthread_mutex_t _hbaapi_APE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/Apthread_mutex_t _hbaapi_APSE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/Apthread_mutex_t _hbaapi_TE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/Apthread_mutex_t _hbaapi_LE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/Apthread_mutex_t _smhba_AAE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/Apthread_mutex_t _smhba_AE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/Apthread_mutex_t _smhba_APE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/Apthread_mutex_t _smhba_APSE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/Apthread_mutex_t _smhba_APHYSE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/Apthread_mutex_t _smhba_TE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/Apthread_mutex_t _smhba_LE_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/A#elif defined(WIN32)
1N/ACRITICAL_SECTION _hbaapi_AAE_mutex;
1N/ACRITICAL_SECTION _hbaapi_AE_mutex;
1N/ACRITICAL_SECTION _hbaapi_APE_mutex;
1N/ACRITICAL_SECTION _hbaapi_APSE_mutex;
1N/ACRITICAL_SECTION _hbaapi_TE_mutex;
1N/ACRITICAL_SECTION _smhba_AAE_mutex;
1N/ACRITICAL_SECTION _smhba_AE_mutex;
1N/ACRITICAL_SECTION _smhba_APE_mutex;
1N/ACRITICAL_SECTION _smhba_APSE_mutex;
1N/ACRITICAL_SECTION _smhba_APHYSE_mutex;
1N/ACRITICAL_SECTION _smhba_TE_mutex;
1N/ACRITICAL_SECTION _hbaapi_LE_mutex;
1N/A#endif
1N/A
1N/AHBA_ADAPTERCALLBACK_ELEM **cb_lists_array[] = {
1N/A &_hbaapi_adapterevents_callback_list,
1N/A &_hbaapi_adapterportevents_callback_list,
1N/A &_hbaapi_adapterportstatevents_callback_list,
1N/A &_hbaapi_targetevents_callback_list,
1N/A &_hbaapi_linkevents_callback_list,
1N/A &_smhba_adapterevents_callback_list,
1N/A &_smhba_adapterportevents_callback_list,
1N/A &_smhba_adapterportstatevents_callback_list,
1N/A &_smhba_adapterphystatevents_callback_list,
1N/A &_smhba_targetevents_callback_list,
1N/A NULL};
1N/A
1N/A/*
1N/A * Common library internal. Mutex handling
1N/A */
1N/A#ifdef POSIX_THREADS
1N/Astatic void
1N/Agrab_mutex(pthread_mutex_t *mp) {
1N/A/* LINTED E_FUNC_SET_NOT_USED */
1N/A int ret;
1N/A if ((ret = pthread_mutex_lock(mp)) != 0) {
1N/A perror("pthread_mutex_lock - HBAAPI:");
1N/A DEBUG(1, "pthread_mutex_lock returned %d", ret, 0, 0);
1N/A }
1N/A}
1N/A
1N/Astatic void
1N/Arelease_mutex(pthread_mutex_t *mp) {
1N/A/* LINTED E_FUNC_SET_NOT_USED */
1N/A int ret;
1N/A if ((ret = pthread_mutex_unlock(mp)) != 0) {
1N/A perror("pthread_mutex_unlock - HBAAPI:");
1N/A DEBUG(1, "pthread_mutex_unlock returned %d", ret, 0, 0);
1N/A }
1N/A}
1N/A#endif
1N/A
1N/A/*
1N/A * Common library internal. Check library and return vendorhandle
1N/A */
1N/Astatic HBA_STATUS
1N/AHBA_CheckLibrary(HBA_HANDLE handle,
1N/A HBA_LIBRARY_INFO **lib_infopp,
1N/A HBA_HANDLE *vendorhandle) {
1N/A
1N/A HBA_UINT32 libraryIndex;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A
1N/A if (_hbaapi_librarylist == NULL) {
1N/A return (HBA_STATUS_ERROR);
1N/A }
1N/A libraryIndex = LIBRARY_NUM(handle);
1N/A
1N/A GRAB_MUTEX(&_hbaapi_LL_mutex);
1N/A for (lib_infop = _hbaapi_librarylist;
1N/A lib_infop != NULL;
1N/A lib_infop = lib_infop->next) {
1N/A if (lib_infop->index == libraryIndex) {
1N/A if (lib_infop->status != HBA_LIBRARY_LOADED) {
1N/A return (HBA_STATUS_ERROR);
1N/A }
1N/A *lib_infopp = lib_infop;
1N/A *vendorhandle = VENDOR_HANDLE(handle);
1N/A /* caller will release the mutex */
1N/A return (HBA_STATUS_OK);
1N/A }
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INVALID_HANDLE);
1N/A}
1N/A#define CHECKLIBRARY() \
1N/A status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);\
1N/A if (status != HBA_STATUS_OK) { \
1N/A return (status); \
1N/A }
1N/A
1N/A#define CHECKLIBRARYANDVERSION(ver) \
1N/A status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle); \
1N/A if (status != HBA_STATUS_OK) { \
1N/A return (status); \
1N/A } else { \
1N/A if (ver != lib_infop->version) { \
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, \
1N/A HBA_STATUS_ERROR_INCOMPATIBLE); \
1N/A } \
1N/A }
1N/A
1N/A/*
1N/A * freevendorhandlelist is called with _hbaapi_LL_mutex already held
1N/A */
1N/Astatic void
1N/Afreevendorhandlelist(HBA_VENDORCALLBACK_ELEM *vhlist) {
1N/A HBA_VENDORCALLBACK_ELEM *vhlp;
1N/A HBA_VENDORCALLBACK_ELEM *vnext;
1N/A HBARemoveCallbackFunc registeredfunc;
1N/A
1N/A for (vhlp = vhlist; vhlp != NULL; vhlp = vnext) {
1N/A vnext = vhlp->next;
1N/A registeredfunc =
1N/A FUNCCOMMON(vhlp->lib_info, RemoveCallbackHandler);
1N/A if (registeredfunc == NULL) {
1N/A continue;
1N/A }
1N/A (registeredfunc)(vhlp->vendorcbhandle);
1N/A free(vhlp);
1N/A }
1N/A}
1N/A
1N/Astatic
1N/AHBA_STATUS
1N/Alocal_remove_callback(HBA_CALLBACKHANDLE cbhandle) {
1N/A HBA_ADAPTERCALLBACK_ELEM ***listp;
1N/A HBA_ADAPTERCALLBACK_ELEM **lastp;
1N/A HBA_ALLADAPTERSCALLBACK_ELEM **lap;
1N/A HBA_ALLADAPTERSCALLBACK_ELEM *allcbp;
1N/A HBA_ADAPTERCALLBACK_ELEM *cbp;
1N/A HBARemoveCallbackFunc registeredfunc;
1N/A HBA_VENDORCALLBACK_ELEM *vhlp;
1N/A HBA_VENDORCALLBACK_ELEM *vnext;
1N/A int found;
1N/A HBA_STATUS status = HBA_STATUS_ERROR_INVALID_HANDLE;
1N/A
1N/A
1N/A /* search through the simple lists first */
1N/A GRAB_MUTEX(&_hbaapi_AAE_mutex);
1N/A GRAB_MUTEX(&_hbaapi_AE_mutex);
1N/A GRAB_MUTEX(&_hbaapi_APE_mutex);
1N/A GRAB_MUTEX(&_hbaapi_APSE_mutex);
1N/A GRAB_MUTEX(&_hbaapi_TE_mutex);
1N/A GRAB_MUTEX(&_hbaapi_LE_mutex);
1N/A GRAB_MUTEX(&_smhba_AAE_mutex);
1N/A GRAB_MUTEX(&_smhba_AE_mutex);
1N/A GRAB_MUTEX(&_smhba_APE_mutex);
1N/A GRAB_MUTEX(&_smhba_APSE_mutex);
1N/A GRAB_MUTEX(&_smhba_TE_mutex);
1N/A for (listp = cb_lists_array, found = 0;
1N/A (found == 0 && *listp != NULL); listp++) {
1N/A lastp = *listp;
1N/A for (cbp = **listp; cbp != NULL; cbp = cbp->next) {
1N/A if (cbhandle != (HBA_CALLBACKHANDLE)cbp) {
1N/A lastp = &(cbp->next);
1N/A continue;
1N/A }
1N/A found = 1;
1N/A registeredfunc =
1N/A FUNCCOMMON(cbp->lib_info, RemoveCallbackHandler);
1N/A if (registeredfunc == NULL) {
1N/A break;
1N/A }
1N/A (registeredfunc)(cbp->vendorcbhandle);
1N/A *lastp = cbp->next;
1N/A free(cbp);
1N/A break;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_LE_mutex);
1N/A RELEASE_MUTEX(&_hbaapi_TE_mutex);
1N/A RELEASE_MUTEX(&_hbaapi_APSE_mutex);
1N/A RELEASE_MUTEX(&_hbaapi_APE_mutex);
1N/A RELEASE_MUTEX(&_hbaapi_AE_mutex);
1N/A RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1N/A RELEASE_MUTEX(&_smhba_AAE_mutex);
1N/A RELEASE_MUTEX(&_smhba_AE_mutex);
1N/A RELEASE_MUTEX(&_smhba_APE_mutex);
1N/A RELEASE_MUTEX(&_smhba_APSE_mutex);
1N/A RELEASE_MUTEX(&_smhba_TE_mutex);
1N/A
1N/A if (found != 0) {
1N/A if (registeredfunc == NULL) {
1N/A return (HBA_STATUS_ERROR_NOT_SUPPORTED);
1N/A }
1N/A return (HBA_STATUS_OK);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_hbaapi_AAE_mutex);
1N/A /*
1N/A * if it wasnt in the simple lists,
1N/A * look in the list for adapteraddevents
1N/A */
1N/A lap = &_hbaapi_adapteraddevents_callback_list;
1N/A for (allcbp = _hbaapi_adapteraddevents_callback_list;
1N/A allcbp != NULL;
1N/A allcbp = allcbp->next) {
1N/A if (cbhandle != (HBA_CALLBACKHANDLE)allcbp) {
1N/A lap = &allcbp->next;
1N/A continue;
1N/A }
1N/A for (vhlp = allcbp->vendorhandlelist; vhlp != NULL; vhlp = vnext) {
1N/A vnext = vhlp->next;
1N/A /* should be HBAAPIV2 VSL to get to here */
1N/A registeredfunc =
1N/A vhlp->lib_info->ftable.functionTable.RemoveCallbackHandler;
1N/A if (registeredfunc == NULL) {
1N/A continue;
1N/A }
1N/A (registeredfunc)(vhlp->vendorcbhandle);
1N/A free(vhlp);
1N/A }
1N/A *lap = allcbp->next;
1N/A free(allcbp);
1N/A status = HBA_STATUS_OK;
1N/A break;
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1N/A
1N/A /* now search smhba adapteradd events. */
1N/A GRAB_MUTEX(&_smhba_AAE_mutex);
1N/A lap = &_smhba_adapteraddevents_callback_list;
1N/A for (allcbp = _smhba_adapteraddevents_callback_list;
1N/A allcbp != NULL;
1N/A allcbp = allcbp->next) {
1N/A if (cbhandle != (HBA_CALLBACKHANDLE)allcbp) {
1N/A lap = &allcbp->next;
1N/A continue;
1N/A }
1N/A for (vhlp = allcbp->vendorhandlelist; vhlp != NULL; vhlp = vnext) {
1N/A vnext = vhlp->next;
1N/A /* should be SMHBA VSL to get to here */
1N/A registeredfunc =
1N/A vhlp->lib_info->
1N/A ftable.smhbafunctionTable.RemoveCallbackHandler;
1N/A if (registeredfunc == NULL) {
1N/A continue;
1N/A }
1N/A (registeredfunc)(vhlp->vendorcbhandle);
1N/A free(vhlp);
1N/A }
1N/A *lap = allcbp->next;
1N/A free(allcbp);
1N/A status = HBA_STATUS_OK;
1N/A break;
1N/A }
1N/A RELEASE_MUTEX(&_smhba_AAE_mutex);
1N/A
1N/A return (status);
1N/A}
1N/A
1N/A/* LINTED E_STATIC_UE_STATIC_UNUSED */
1N/Astatic char wwn_str1[17];
1N/A/* LINTED E_STATIC_UE_STATIC_UNUSED */
1N/Astatic char wwn_str2[17];
1N/A/* LINTED E_STATIC_UE_STATIC_UNUSED */
1N/Astatic char wwn_str3[17];
1N/A#define WWN2STR1(wwn) WWN2str(wwn_str1, (wwn))
1N/A#define WWN2STR2(wwn) WWN2str(wwn_str2, (wwn))
1N/A#define WWN2STR3(wwn) WWN2str(wwn_str3, (wwn))
1N/Astatic char *
1N/A/* LINTED E_STATIC_UE_STATIC_UNUSED */
1N/AWWN2str(char *buf, HBA_WWN *wwn) {
1N/A int j;
1N/A unsigned char *pc = (unsigned char *)&(wwn->wwn[0]);
1N/A buf[0] = '\0';
1N/A for (j = 0; j < 16; j += 2) {
1N/A (void) sprintf(&buf[j], "%02X", (int)*pc++);
1N/A }
1N/A return (buf);
1N/A}
1N/A
1N/A#ifdef WIN32
1N/ABOOL APIENTRY
1N/ADllMain(HANDLE hModule,
1N/A DWORD ul_reason_for_call,
1N/A LPVOID lpReserved)
1N/A{
1N/A switch (ul_reason_for_call) {
1N/A case DLL_PROCESS_ATTACH:
1N/A break;
1N/A case DLL_PROCESS_DETACH:
1N/A break;
1N/A case DLL_THREAD_ATTACH:
1N/A case DLL_THREAD_DETACH:
1N/A break;
1N/A }
1N/A return (TRUE);
1N/A}
1N/A#endif
1N/A
1N/A/*
1N/A * Read in the config file and load all the specified vendor specific
1N/A * libraries and perform the function registration exercise
1N/A */
1N/AHBA_STATUS
1N/AHBA_LoadLibrary()
1N/A{
1N/A HBARegisterLibraryFunc RegisterFunc;
1N/A HBARegisterLibraryV2Func RegisterV2Func;
1N/A SMHBARegisterLibraryFunc RegisterSMHBAFunc;
1N/A HBALoadLibraryFunc LoadLibraryFunc;
1N/A HBAGetVersionFunc GetVersionFunc;
1N/A#ifdef POSIX_THREADS
1N/A int ret;
1N/A#endif
1N/A HBA_STATUS status;
1N/A HBA_UINT32 libversion;
1N/A
1N/A /* Open configuration file from known location */
1N/A#ifdef WIN32
1N/A LONG lStatus;
1N/A HKEY hkSniaHba, hkVendorLib;
1N/A FILETIME ftLastWriteTime;
1N/A TCHAR cSubKeyName[256];
1N/A DWORD i, dwSize, dwType;
1N/A BYTE byFileName[MAX_PATH];
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A
1N/A if (_hbaapi_librarylist != NULL) {
1N/A /* this is an app programming error */
1N/A return (HBA_STATUS_ERROR);
1N/A }
1N/A
1N/A lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\SNIA\\HBA",
1N/A 0, KEY_READ, &hkSniaHba);
1N/A if (lStatus != ERROR_SUCCESS) {
1N/A /* ???Opportunity to send error msg, configuration error */
1N/A return (HBA_STATUS_ERROR);
1N/A }
1N/A /*
1N/A * Enumerate all the subkeys. These have the form:
1N/A * HKLM\Software\SNIA\HBA\<Vendor id> - note that we don't care
1N/A * what the vendor id is
1N/A */
1N/A for (i = 0; ; i++) {
1N/A dwSize = 255; /* how big the buffer is */
1N/A lStatus = RegEnumKeyEx(hkSniaHba, i,
1N/A (char *)&cSubKeyName, &dwSize, NULL,
1N/A NULL, NULL, &ftLastWriteTime);
1N/A if (lStatus == ERROR_NO_MORE_ITEMS) {
1N/A break; /* we're done */
1N/A } else if (lStatus == ERROR_MORE_DATA) { /* buffer not big enough */
1N/A /* do whatever */
1N/A ;
1N/A }
1N/A /* Now open the subkey that pertains to this vendor's library */
1N/A lStatus = RegOpenKeyEx(hkSniaHba, cSubKeyName, 0, KEY_READ,
1N/A &hkVendorLib);
1N/A if (lStatus != ERROR_SUCCESS) {
1N/A RegCloseKey(hkSniaHba);
1N/A /* ???Opportunity to send error msg, installation error */
1N/A return (HBA_STATUS_ERROR);
1N/A /*
1N/A * you may want to return something
1N/A * else or keep trying
1N/A */
1N/A }
1N/A /*
1N/A * The name of the library is contained in a REG_SZ Value
1N/A * keyed to "LibraryFile"
1N/A */
1N/A dwSize = MAX_PATH;
1N/A lStatus = RegQueryValueEx(hkVendorLib, "LibraryFile", NULL, &dwType,
1N/A byFileName, &dwSize);
1N/A if (lStatus != ERROR_SUCCESS) {
1N/A RegCloseKey(hkVendorLib);
1N/A /* ???Opportunity to send error msg, installation error */
1N/A continue;
1N/A }
1N/A lib_infop = (HBA_LIBRARY_INFO *)calloc(1, sizeof (HBA_LIBRARY_INFO));
1N/A if (lib_infop == NULL) {
1N/A /* what is the right thing to do in MS land??? */
1N/A RegCloseKey(hkVendorLib);
1N/A /* ???Opportunity to send error msg, installation error */
1N/A return (HBA_STATUS_ERROR);
1N/A }
1N/A lib_infop->status = HBA_LIBRARY_NOT_LOADED;
1N/A lib_infop->next = _hbaapi_librarylist;
1N/A lib_infop->index = _hbaapi_total_library_count;
1N/A _hbaapi_total_library_count++;
1N/A _hbaapi_librarylist = lib_infop;
1N/A
1N/A /* Now I can try to load the library */
1N/A lib_infop->hLibrary = LoadLibrary(byFileName);
1N/A if (lib_infop->hLibrary == NULL) {
1N/A /* printf("unable to load library %s\n", librarypath); */
1N/A /* ???Opportunity to send error msg, installation error */
1N/A goto dud_library;
1N/A }
1N/A lib_infop->LibraryPath = strdup(byFileName);
1N/A DEBUG(1, "HBAAPI loading: %s\n", byFileName, 0, 0);
1N/A
1N/A RegisterSMHBAFunc = (SMHBARegisterLibraryFunc)
1N/A GetProcAddress(lib_infop->hLibrary, "SMHBA_RegisterLibrary");
1N/A if (RegisterSMHBAFunc != NULL) {
1N/A status = ((RegisterSMHBAFunc)(SMHBA_ENTRYPOINTS *)
1N/A (&lib_infop->ftable.smhbafunctionTable));
1N/A if (status != HBA_STATUS_OK) {
1N/A /* library not loaded */
1N/A /* ???Opportunity to send error msg, library error? */
1N/A goto dud_library;
1N/A } else {
1N/A lib_infop->version = SMHBA;
1N/A }
1N/A } else {
1N/A /* Call the registration function to get the list of pointers */
1N/A RegisterV2Func = (HBARegisterLibraryV2Func)GetProcAddress(
1N/A lib_infop->hLibrary, "HBA_RegisterLibraryV2");
1N/A if (RegisterV2Func != NULL) {
1N/A /*
1N/A * Load the function pointers directly into
1N/A * the table of functions
1N/A */
1N/A status = ((RegisterV2Func)
1N/A (HBA_ENTRYPOINTSV2 *)(&lib_infop->ftable.functionTable));
1N/A if (status != HBA_STATUS_OK) {
1N/A /* library not loaded */
1N/A /* ???Opportunity to send error msg, library error? */
1N/A goto dud_library;
1N/A } else {
1N/A lib_infop->version = HBAAPIV2;
1N/A }
1N/A } else {
1N/A /* Maybe the vendor library is only Rev1 */
1N/A RegisterFunc = (HBARegisterLibraryFunc)
1N/A GetProcAddress(lib_infop->hLibrary, "HBA_RegisterLibrary");
1N/A if (RegisterFunc == NULL) {
1N/A /* ???Opportunity to send error msg, library error? */
1N/A goto dud_library;
1N/A }
1N/A /*
1N/A * Load the function points directly into
1N/A * the Rev 2 table of functions
1N/A */
1N/A status = ((RegisterFunc)(
1N/A (HBA_ENTRYPOINTS *)(&lib_infop->ftable.functionTable)));
1N/A if (status != HBA_STATUS_OK) {
1N/A /* library not loaded */
1N/A /* ???Opportunity to send error msg, library error? */
1N/A goto dud_library;
1N/A } else {
1N/A lib_infop->version = HBAAPI;
1N/A }
1N/A }
1N/A }
1N/A
1N/A /* successfully loaded library */
1N/A /*
1N/A * SM-HBA and HBAAPI has a seperate handler for GetVersion but
1N/A * they have the same function signature so use the same variable here.
1N/A */
1N/A GetVersionFunc = FUNCCOMMON(lib_infop, GetVersionHandler);
1N/A if (GetVersionFunc != NULL) {
1N/A if (lib_infop->version == SMHBA) {
1N/A /* Check the version of this library before loading */
1N/A libversion = ((GetVersionFunc)());
1N/A#ifdef NOTDEF /* save for a later time... when it matters */
1N/A if (libversion < SMHBA_LIBVERSION) {
1N/A goto dud_library;
1N/A }
1N/A#endif
1N/A } else {
1N/A /* Check the version of this library before loading */
1N/A /* Actually... This wrapper is compatible with version 1 */
1N/A libversion = ((GetVersionFunc)());
1N/A#ifdef NOTDEF /* save for a later time... when it matters */
1N/A if (libversion < HBA_LIBVERSION) {
1N/A goto dud_library;
1N/A }
1N/A#endif
1N/A }
1N/A } else {
1N/A /* ???Opportunity to send error msg, library error? */
1N/A goto dud_library;
1N/A }
1N/A
1N/A LoadLibraryFunc = FUNCCOMMON(lib_infop, LoadLibraryHandler);
1N/A if (LoadLibraryFunc == NULL) {
1N/A /* Hmmm, dont we need to flag this in a realy big way??? */
1N/A /* How about messages to the system event logger ??? */
1N/A /* ???Opportunity to send error msg, library error? */
1N/A goto dud_library;
1N/A }
1N/A /* Initialize this library */
1N/A status = ((LoadLibraryFunc)());
1N/A if (status != HBA_STATUS_OK) {
1N/A /* ???Opportunity to send error msg, library error? */
1N/A continue;
1N/A }
1N/A /* successfully loaded library */
1N/A lib_infop->status = HBA_LIBRARY_LOADED;
1N/A
1N/A dud_library: /* its also just the end of the loop */
1N/A RegCloseKey(hkVendorLib);
1N/A }
1N/A RegCloseKey(hkSniaHba);
1N/A
1N/A#else /* Unix as opposed to Win32 */
1N/A FILE *hbaconf;
1N/A char fullline[512]; /* line read from HBA.conf */
1N/A char *libraryname; /* Read in from file HBA.conf */
1N/A char *librarypath; /* Read in from file HBA.conf */
1N/A char hbaConfFilePath[256];
1N/A char *charPtr;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A
1N/A GRAB_MUTEX(&_hbaapi_LL_mutex);
1N/A if (_hbaapi_librarylist != NULL) {
1N/A (void) fprintf(stderr,
1N/A "HBA_LoadLibrary: previously unfreed "
1N/A "libraries exist, call HBA_FreeLibrary().\n");
1N/A RELEASE_MUTEX(&_hbaapi_LL_mutex);
1N/A return (HBA_STATUS_ERROR);
1N/A }
1N/A
1N/A (void) strcpy(hbaConfFilePath, "/etc/smhba.conf");
1N/A
1N/A if ((hbaconf = fopen(hbaConfFilePath, "r")) == NULL) {
1N/A (void) printf("Cannot open %s\n", hbaConfFilePath);
1N/A RELEASE_MUTEX(&_hbaapi_LL_mutex);
1N/A return (HBA_STATUS_ERROR);
1N/A }
1N/A
1N/A /* Read in each line and load library */
1N/A while ((hbaconf != NULL) &&
1N/A (fgets(fullline, sizeof (fullline), hbaconf))) {
1N/A /* Skip the comments... */
1N/A if ((fullline[0] == '#') || (fullline[0] == '\n')) {
1N/A continue;
1N/A }
1N/A
1N/A /* grab first 'thing' in line (if its there) */
1N/A if ((libraryname = strtok(fullline, " \t\n")) != NULL) {
1N/A if (strlen(libraryname) >= 64) {
1N/A (void) fprintf(stderr,
1N/A "Library name(%s) in %s is > 64 characters\n",
1N/A libraryname, hbaConfFilePath);
1N/A }
1N/A }
1N/A /* grab second 'thing' in line (if its there) */
1N/A if ((librarypath = strtok(NULL, " \t\n")) != NULL) {
1N/A if (strlen(librarypath) >= 256) {
1N/A (void) fprintf(stderr,
1N/A "Library path(%s) in %s is > 256 characters\n",
1N/A librarypath, hbaConfFilePath);
1N/A }
1N/A }
1N/A
1N/A /* there should be no more 'things' in the line */
1N/A if ((charPtr = strtok(NULL, " \n\t")) != NULL) {
1N/A (void) fprintf(stderr, "Extraneous characters (\"%s\") in %s\n",
1N/A charPtr, hbaConfFilePath);
1N/A }
1N/A
1N/A /* Continue to the next line if library name or path is invalid */
1N/A if (libraryname == NULL ||
1N/A strlen(libraryname) == 0 ||
1N/A librarypath == NULL ||
1N/A (strlen(librarypath) == 0)) {
1N/A continue;
1N/A }
1N/A
1N/A /*
1N/A * Special case....
1N/A * Look for loglevel
1N/A */
1N/A if (strcmp(libraryname, "debuglevel") == 0) {
1N/A _hbaapi_debuglevel = strtol(librarypath, NULL, 10);
1N/A /* error handling does the right thing automagically */
1N/A continue;
1N/A }
1N/A
1N/A lib_infop = (HBA_LIBRARY_INFO *)calloc(1, sizeof (HBA_LIBRARY_INFO));
1N/A if (lib_infop == NULL) {
1N/A (void) fprintf(stderr, "HBA_LoadLibrary: out of memeory\n");
1N/A RELEASE_MUTEX(&_hbaapi_LL_mutex);
1N/A return (HBA_STATUS_ERROR);
1N/A }
1N/A lib_infop->status = HBA_LIBRARY_NOT_LOADED;
1N/A lib_infop->LibraryName = strdup(libraryname);
1N/A lib_infop->LibraryPath = strdup(librarypath);
1N/A lib_infop->numOfAdapters = 0;
1N/A lib_infop->version = UNKNOWN;
1N/A lib_infop->index = _hbaapi_total_library_count;
1N/A _hbaapi_total_library_count++;
1N/A lib_infop->next = _hbaapi_librarylist;
1N/A _hbaapi_librarylist = lib_infop;
1N/A
1N/A /* Load the DLL now */
1N/A if ((lib_infop->hLibrary = dlopen(librarypath, RTLD_LAZY)) == NULL) {
1N/A /* printf("unable to load library %s\n", librarypath); */
1N/A continue;
1N/A }
1N/A /* Call the registration function to get the list of pointers */
1N/A RegisterSMHBAFunc = (SMHBARegisterLibraryFunc)
1N/A dlsym(lib_infop->hLibrary, "SMHBA_RegisterLibrary");
1N/A if (RegisterSMHBAFunc != NULL) {
1N/A /*
1N/A * Load the function points directly into
1N/A * the table of functions
1N/A */
1N/A status = ((RegisterSMHBAFunc)
1N/A (&lib_infop->ftable.smhbafunctionTable));
1N/A if (status != HBA_STATUS_OK) {
1N/A /* library not loaded */
1N/A continue;
1N/A } else {
1N/A lib_infop->version = SMHBA;
1N/A }
1N/A } else {
1N/A RegisterV2Func = (HBARegisterLibraryV2Func)
1N/A dlsym(lib_infop->hLibrary, "HBA_RegisterLibraryV2");
1N/A if (RegisterV2Func != NULL) {
1N/A /*
1N/A * Load the function points directly into
1N/A * the table of functions
1N/A */
1N/A status = ((RegisterV2Func)((HBA_ENTRYPOINTSV2 *)
1N/A (&lib_infop->ftable.functionTable)));
1N/A if (status != HBA_STATUS_OK) {
1N/A /* library not loaded */
1N/A continue;
1N/A } else {
1N/A lib_infop->version = HBAAPIV2;
1N/A }
1N/A } else {
1N/A /* Maybe the vendor library is only Rev1 */
1N/A RegisterFunc = (HBARegisterLibraryFunc)
1N/A dlsym(lib_infop->hLibrary, "HBA_RegisterLibrary");
1N/A if (RegisterFunc == NULL) {
1N/A /* This function is required */
1N/A (void) fprintf(stderr,
1N/A "HBA_LoadLibrary: vendor specific RegisterLibrary "
1N/A "function not found. lib: %s\n", librarypath);
1N/A DEBUG(1, "HBA_LoadLibrary: vendor specific "
1N/A "RegisterLibrary function not found. lib: %s\n",
1N/A librarypath, 0, 0);
1N/A continue;
1N/A }
1N/A /*
1N/A * Load the function points directly into
1N/A * the table of functions
1N/A */
1N/A status = ((RegisterFunc)
1N/A ((HBA_ENTRYPOINTS *)(&lib_infop->ftable.functionTable)));
1N/A if (status != HBA_STATUS_OK) {
1N/A /* library not loaded */
1N/A (void) fprintf(stderr,
1N/A "HBA_LoadLibrary: vendor specific RegisterLibrary "
1N/A "function encountered an error. lib: %s\n",
1N/A librarypath);
1N/A DEBUG(1,
1N/A "HBA_LoadLibrary: vendor specific RegisterLibrary "
1N/A "function encountered an error. lib: %s\n",
1N/A librarypath, 0, 0);
1N/A continue;
1N/A } else {
1N/A lib_infop->version = HBAAPI;
1N/A }
1N/A }
1N/A }
1N/A
1N/A /* successfully loaded library */
1N/A /*
1N/A * SM-HBA and HBAAPI has a seperate handler for GetVersion but
1N/A * they have the same function signature so use the same variable here.
1N/A */
1N/A if ((GetVersionFunc = FUNCCOMMON(lib_infop, GetVersionHandler))
1N/A == NULL) {
1N/A continue;
1N/A }
1N/A if (lib_infop->version == SMHBA) {
1N/A libversion = ((GetVersionFunc)());
1N/A if (libversion < SMHBA_LIBVERSION) {
1N/A (void) printf("Library version mismatch."
1N/A "Got %d expected %d.\n",
1N/A libversion, SMHBA_LIBVERSION);
1N/A continue;
1N/A }
1N/A } else {
1N/A libversion = ((GetVersionFunc)());
1N/A /* Check the version of this library before loading */
1N/A /* Actually... This wrapper is compatible with version 1 */
1N/A if (libversion < HBA_LIBVERSION) {
1N/A (void) printf("Library version mismatch."
1N/A "Got %d expected %d.\n",
1N/A libversion, HBA_LIBVERSION);
1N/A continue;
1N/A }
1N/A }
1N/A
1N/A DEBUG(1, "%s libversion = %d", librarypath, libversion, 0);
1N/A LoadLibraryFunc = FUNCCOMMON(lib_infop, LoadLibraryHandler);
1N/A if (LoadLibraryFunc == NULL) {
1N/A /* this function is required */
1N/A (void) fprintf(stderr,
1N/A "HBA_LoadLibrary: vendor specific LoadLibrary "
1N/A "function not found. lib: %s\n", librarypath);
1N/A DEBUG(1, "HBA_LoadLibrary: vendor specific LoadLibrary "
1N/A "function not found. lib: %s\n", librarypath, 0, 0);
1N/A continue;
1N/A }
1N/A /* Initialize this library */
1N/A if ((status = ((LoadLibraryFunc)())) != HBA_STATUS_OK) {
1N/A /* maybe this should be a printf so that we CANNOT miss it */
1N/A (void) fprintf(stderr,
1N/A "HBA_LoadLibrary: Encounterd and error loading: %s",
1N/A librarypath);
1N/A DEBUG(1, "Encounterd and error loading: %s", librarypath, 0, 0);
1N/A DEBUG(1, " HBA_STATUS: %d", status, 0, 0);
1N/A continue;
1N/A }
1N/A /* successfully loaded library */
1N/A lib_infop->status = HBA_LIBRARY_LOADED;
1N/A }
1N/A#endif /* WIN32 or UNIX */
1N/A#ifdef POSIX_THREADS
1N/A /*
1N/A * The _hbaapi_LL_mutex is already grabbed to proctect the caller of
1N/A * HBA_FreeLibrary() during loading.
1N/A * The mutexes are already initialized
1N/A * with PTHREAD_MUTEX_INITIALIZER. Do we need to init again?
1N/A * Keeping the code from HBAAPI source...
1N/A */
1N/A ret = pthread_mutex_init(&_hbaapi_AL_mutex, NULL);
1N/A if (ret == 0) {
1N/A ret = pthread_mutex_init(&_hbaapi_AAE_mutex, NULL);
1N/A }
1N/A if (ret == 0) {
1N/A ret = pthread_mutex_init(&_hbaapi_AE_mutex, NULL);
1N/A }
1N/A if (ret == 0) {
1N/A ret = pthread_mutex_init(&_hbaapi_APE_mutex, NULL);
1N/A }
1N/A if (ret == 0) {
1N/A ret = pthread_mutex_init(&_hbaapi_APSE_mutex, NULL);
1N/A }
1N/A if (ret == 0) {
1N/A ret = pthread_mutex_init(&_hbaapi_TE_mutex, NULL);
1N/A }
1N/A if (ret == 0) {
1N/A ret = pthread_mutex_init(&_smhba_AAE_mutex, NULL);
1N/A }
1N/A if (ret == 0) {
1N/A ret = pthread_mutex_init(&_smhba_AE_mutex, NULL);
1N/A }
1N/A if (ret == 0) {
1N/A ret = pthread_mutex_init(&_smhba_APE_mutex, NULL);
1N/A }
1N/A if (ret == 0) {
1N/A ret = pthread_mutex_init(&_smhba_APSE_mutex, NULL);
1N/A }
1N/A if (ret == 0) {
1N/A ret = pthread_mutex_init(&_smhba_TE_mutex, NULL);
1N/A }
1N/A if (ret == 0) {
1N/A ret = pthread_mutex_init(&_hbaapi_LE_mutex, NULL);
1N/A }
1N/A if (ret != 0) {
1N/A perror("pthread_mutex_init - HBA_LoadLibrary");
1N/A RELEASE_MUTEX(&_hbaapi_LL_mutex);
1N/A return (HBA_STATUS_ERROR);
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_LL_mutex);
1N/A#elif defined(WIN32)
1N/A InitializeCriticalSection(&_hbaapi_LL_mutex);
1N/A InitializeCriticalSection(&_hbaapi_AL_mutex);
1N/A InitializeCriticalSection(&_hbaapi_AAE_mutex);
1N/A InitializeCriticalSection(&_hbaapi_AE_mutex);
1N/A InitializeCriticalSection(&_hbaapi_APE_mutex);
1N/A InitializeCriticalSection(&_hbaapi_APSE_mutex);
1N/A InitializeCriticalSection(&_hbaapi_TE_mutex);
1N/A InitializeCriticalSection(&_hbaapi_LE_mutex);
1N/A InitializeCriticalSection(&_smhba_AAE_mutex);
1N/A InitializeCriticalSection(&_smhba_AE_mutex);
1N/A InitializeCriticalSection(&_smhba_APE_mutex);
1N/A InitializeCriticalSection(&_smhba_APSE_mutex);
1N/A InitializeCriticalSection(&_smhba_TE_mutex);
1N/A#endif
1N/A
1N/A return (HBA_STATUS_OK);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_FreeLibrary() {
1N/A HBAFreeLibraryFunc FreeLibraryFunc;
1N/A/* LINTED E_FUNC_SET_NOT_USED */
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_LIBRARY_INFO *lib_next;
1N/A HBA_ADAPTERCALLBACK_ELEM
1N/A ***listp;
1N/A HBA_ADAPTER_INFO *adapt_infop;
1N/A HBA_ADAPTER_INFO *adapt_next;
1N/A
1N/A GRAB_MUTEX(&_hbaapi_LL_mutex);
1N/A if (_hbaapi_librarylist == NULL) {
1N/A RELEASE_MUTEX(&_hbaapi_LL_mutex);
1N/A return (HBA_STATUS_ERROR_NOT_LOADED);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_hbaapi_AL_mutex);
1N/A
1N/A DEBUG(1, "HBA_FreeLibrary()", 0, 0, 0);
1N/A for (lib_infop = _hbaapi_librarylist; lib_infop != NULL;
1N/A lib_infop = lib_next) {
1N/A lib_next = lib_infop->next;
1N/A if (lib_infop->status == HBA_LIBRARY_LOADED) {
1N/A FreeLibraryFunc = FUNCCOMMON(lib_infop, FreeLibraryHandler);
1N/A if (FreeLibraryFunc != NULL) {
1N/A /* Free this library */
1N/A status = ((FreeLibraryFunc)());
1N/A DEBUG(1, "HBA_FreeLibrary() Failed %d", status, 0, 0);
1N/A }
1N/A#ifdef WIN32
1N/A FreeLibrary(lib_infop->hLibrary); /* Unload DLL from memory */
1N/A#else
1N/A (void) dlclose(lib_infop->hLibrary); /* Unload DLL from memory */
1N/A#endif
1N/A }
1N/A#ifndef WIN32
1N/A free(lib_infop->LibraryName);
1N/A#endif
1N/A free(lib_infop->LibraryPath);
1N/A free(lib_infop);
1N/A
1N/A }
1N/A _hbaapi_librarylist = NULL;
1N/A /*
1N/A * OK, now all functions are disabled except for LoadLibrary,
1N/A * Hope no other thread calls it before we have returned
1N/A */
1N/A _hbaapi_total_library_count = 0;
1N/A
1N/A for (adapt_infop = _hbaapi_adapterlist;
1N/A adapt_infop != NULL;
1N/A adapt_infop = adapt_next) {
1N/A adapt_next = adapt_infop->next;
1N/A free(adapt_infop->name);
1N/A free(adapt_infop);
1N/A }
1N/A _hbaapi_adapterlist = NULL;
1N/A _hbaapi_total_adapter_count = 0;
1N/A
1N/A /*
1N/A * Free up the callbacks, this is not the most efficient, but it works
1N/A */
1N/A while ((volatile HBA_ADAPTERCALLBACK_ELEM *)
1N/A _hbaapi_adapteraddevents_callback_list
1N/A != NULL) {
1N/A (void) local_remove_callback((HBA_CALLBACKHANDLE)
1N/A _hbaapi_adapteraddevents_callback_list);
1N/A }
1N/A while ((volatile HBA_ADAPTERCALLBACK_ELEM *)
1N/A _smhba_adapteraddevents_callback_list
1N/A != NULL) {
1N/A (void) local_remove_callback((HBA_CALLBACKHANDLE)
1N/A _smhba_adapteraddevents_callback_list);
1N/A }
1N/A for (listp = cb_lists_array; *listp != NULL; listp++) {
1N/A while ((volatile HBA_ADAPTERCALLBACK_ELEM ***)**listp != NULL) {
1N/A (void) local_remove_callback((HBA_CALLBACKHANDLE)**listp);
1N/A }
1N/A }
1N/A
1N/A RELEASE_MUTEX(&_hbaapi_AL_mutex);
1N/A RELEASE_MUTEX(&_hbaapi_LL_mutex);
1N/A
1N/A#ifdef USESYSLOG
1N/A closelog();
1N/A#endif
1N/A#ifdef USELOGFILE
1N/A if (_hbaapi_debug_fd != NULL) {
1N/A fclose(_hbaapi_debug_fd);
1N/A }
1N/A _hbaapi_debug_fd = NULL;
1N/A#endif
1N/A#ifdef POSIX_THREADS
1N/A /* this will unlock them as well, but who cares */
1N/A (void) pthread_mutex_destroy(&_hbaapi_LE_mutex);
1N/A (void) pthread_mutex_destroy(&_hbaapi_TE_mutex);
1N/A (void) pthread_mutex_destroy(&_hbaapi_APSE_mutex);
1N/A (void) pthread_mutex_destroy(&_hbaapi_APE_mutex);
1N/A (void) pthread_mutex_destroy(&_hbaapi_AE_mutex);
1N/A (void) pthread_mutex_destroy(&_hbaapi_AAE_mutex);
1N/A (void) pthread_mutex_destroy(&_smhba_TE_mutex);
1N/A (void) pthread_mutex_destroy(&_smhba_APSE_mutex);
1N/A (void) pthread_mutex_destroy(&_smhba_APE_mutex);
1N/A (void) pthread_mutex_destroy(&_smhba_AE_mutex);
1N/A (void) pthread_mutex_destroy(&_smhba_AAE_mutex);
1N/A (void) pthread_mutex_destroy(&_hbaapi_AL_mutex);
1N/A (void) pthread_mutex_destroy(&_hbaapi_LL_mutex);
1N/A#elif defined(WIN32)
1N/A DeleteCriticalSection(&_hbaapi_LL_mutex);
1N/A DeleteCriticalSection(&_hbaapi_AL_mutex);
1N/A DeleteCriticalSection(&_hbaapi_AAE_mutex);
1N/A DeleteCriticalSection(&_hbaapi_AE_mutex);
1N/A DeleteCriticalSection(&_hbaapi_APE_mutex);
1N/A DeleteCriticalSection(&_hbaapi_APSE_mutex);
1N/A DeleteCriticalSection(&_hbaapi_TE_mutex);
1N/A DeleteCriticalSection(&_hbaapi_LE_mutex);
1N/A DeleteCriticalSection(&_smhba_TE_mutex);
1N/A DeleteCriticalSection(&_smhba_APSE_mutex);
1N/A DeleteCriticalSection(&_smhba_APE_mutex);
1N/A DeleteCriticalSection(&_smhba_AE_mutex);
1N/A DeleteCriticalSection(&_smhba_AAE_mutex);
1N/A#endif
1N/A
1N/A return (HBA_STATUS_OK);
1N/A}
1N/A
1N/A/*
1N/A * The API used to use fixed size tables as its primary data structure.
1N/A * Indexing from 1 to N identified each adapters. Now the adapters are
1N/A * on a linked list. There is a unique "index" foreach each adapter.
1N/A * Adapters always keep their index, even if they are removed from the
1N/A * hardware. The only time the indexing is reset is on HBA_FreeLibrary
1N/A */
1N/AHBA_UINT32
1N/AHBA_GetNumberOfAdapters()
1N/A{
1N/A int j = 0;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBAGetNumberOfAdaptersFunc GetNumberOfAdaptersFunc;
1N/A HBAGetAdapterNameFunc GetAdapterNameFunc;
1N/A HBA_BOOLEAN found_name;
1N/A HBA_ADAPTER_INFO *adapt_infop;
1N/A HBA_STATUS status;
1N/A
1N/A char adaptername[256];
1N/A int num_adapters; /* local */
1N/A
1N/A if (_hbaapi_librarylist == NULL) {
1N/A return (0);
1N/A }
1N/A GRAB_MUTEX(&_hbaapi_LL_mutex); /* pay attention to order */
1N/A GRAB_MUTEX(&_hbaapi_AL_mutex);
1N/A
1N/A for (lib_infop = _hbaapi_librarylist;
1N/A lib_infop != NULL;
1N/A lib_infop = lib_infop->next) {
1N/A
1N/A if (lib_infop->status != HBA_LIBRARY_LOADED) {
1N/A continue;
1N/A }
1N/A
1N/A GetNumberOfAdaptersFunc =
1N/A FUNCCOMMON(lib_infop, GetNumberOfAdaptersHandler);
1N/A if (GetNumberOfAdaptersFunc == NULL) {
1N/A continue;
1N/A }
1N/A num_adapters = ((GetNumberOfAdaptersFunc)());
1N/A#ifndef WIN32
1N/A DEBUG(1, "HBAAPI: num_adapters for %s = %d\n",
1N/A lib_infop->LibraryName, num_adapters, 0);
1N/A#else
1N/A DEBUG(1, "HBAAPI: num_adapters for %s = %d\n",
1N/A lib_infop->LibraryPath, num_adapters, 0);
1N/A#endif
1N/A
1N/A /* Also get the names of all the adapters here and cache */
1N/A GetAdapterNameFunc = FUNCCOMMON(lib_infop, GetAdapterNameHandler);
1N/A if (GetAdapterNameFunc == NULL) {
1N/A continue;
1N/A }
1N/A
1N/A for (j = 0; j < num_adapters; j++) {
1N/A found_name = 0;
1N/A status = (GetAdapterNameFunc)(j, (char *)&adaptername);
1N/A if (status == HBA_STATUS_OK) {
1N/A for (adapt_infop = _hbaapi_adapterlist;
1N/A adapt_infop != NULL;
1N/A adapt_infop = adapt_infop->next) {
1N/A /*
1N/A * check for duplicates, really,
1N/A * this may just be a second
1N/A * call to this function
1N/A * ??? how do we know when a name becomes stale?
1N/A */
1N/A if (strcmp(adaptername, adapt_infop->name) == 0) {
1N/A /* already got this one */
1N/A found_name++;
1N/A break;
1N/A }
1N/A }
1N/A if (found_name != 0) {
1N/A continue;
1N/A }
1N/A }
1N/A
1N/A adapt_infop = (HBA_ADAPTER_INFO *)
1N/A calloc(1, sizeof (HBA_ADAPTER_INFO));
1N/A if (adapt_infop == NULL) {
1N/A#ifndef WIN32
1N/A (void) fprintf(stderr,
1N/A "HBA_GetNumberOfAdapters: calloc failed"
1N/A " on sizeof:%lu\n",
1N/A (unsigned long)(sizeof (HBA_ADAPTER_INFO)));
1N/A#endif
1N/A RELEASE_MUTEX(&_hbaapi_AL_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
1N/A _hbaapi_total_adapter_count);
1N/A }
1N/A if ((adapt_infop->GNstatus = status) == HBA_STATUS_OK) {
1N/A adapt_infop->name = strdup(adaptername);
1N/A } else {
1N/A char dummyname[512];
1N/A (void) sprintf(dummyname, "NULLADAPTER-%255s-%03d",
1N/A lib_infop->LibraryPath, _hbaapi_total_adapter_count);
1N/A dummyname[511] = '\0';
1N/A adapt_infop->name = strdup(dummyname);
1N/A }
1N/A lib_infop->numOfAdapters++;
1N/A adapt_infop->library = lib_infop;
1N/A adapt_infop->next = _hbaapi_adapterlist;
1N/A adapt_infop->index = _hbaapi_total_adapter_count;
1N/A _hbaapi_adapterlist = adapt_infop;
1N/A _hbaapi_total_adapter_count++;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_AL_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, _hbaapi_total_adapter_count);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetAdapterName(
1N/A HBA_UINT32 adapterindex,
1N/A char *adaptername)
1N/A{
1N/A HBA_ADAPTER_INFO *adapt_infop;
1N/A HBA_STATUS ret = HBA_STATUS_ERROR_ILLEGAL_INDEX;
1N/A
1N/A if (adaptername == NULL) {
1N/A DEBUG(1, "HBA_GetAdapterName: NULL pointer adatpername",
1N/A 0, 0, 0);
1N/A return (HBA_STATUS_ERROR_ARG);
1N/A }
1N/A
1N/A /*
1N/A * The adapter index is from old code, but we have
1N/A * to support it. Go down the list looking for
1N/A * the adapter
1N/A */
1N/A ARE_WE_INITED();
1N/A GRAB_MUTEX(&_hbaapi_AL_mutex);
1N/A *adaptername = '\0';
1N/A for (adapt_infop = _hbaapi_adapterlist;
1N/A adapt_infop != NULL;
1N/A adapt_infop = adapt_infop->next) {
1N/A
1N/A if (adapt_infop->index == adapterindex) {
1N/A if (adapt_infop->name != NULL &&
1N/A adapt_infop->GNstatus == HBA_STATUS_OK) {
1N/A (void) strcpy(adaptername, adapt_infop->name);
1N/A } else {
1N/A *adaptername = '\0';
1N/A }
1N/A ret = adapt_infop->GNstatus;
1N/A break;
1N/A }
1N/A }
1N/A DEBUG(2, "GetAdapterName for index:%d ->%s",
1N/A adapterindex, adaptername, 0);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, ret);
1N/A}
1N/A
1N/AHBA_HANDLE
1N/AHBA_OpenAdapter(char *adaptername)
1N/A{
1N/A HBA_HANDLE handle;
1N/A HBAOpenAdapterFunc OpenAdapterFunc;
1N/A HBA_ADAPTER_INFO *adapt_infop;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A
1N/A DEBUG(2, "OpenAdapter: %s", adaptername, 0, 0);
1N/A
1N/A handle = HBA_HANDLE_INVALID;
1N/A if (_hbaapi_librarylist == NULL) {
1N/A return (handle);
1N/A }
1N/A if (adaptername == NULL) {
1N/A DEBUG(1, "HBA_OpenAdapter: NULL pointer adatpername",
1N/A 0, 0, 0);
1N/A return (handle);
1N/A }
1N/A GRAB_MUTEX(&_hbaapi_AL_mutex);
1N/A for (adapt_infop = _hbaapi_adapterlist;
1N/A adapt_infop != NULL;
1N/A adapt_infop = adapt_infop->next) {
1N/A if (strcmp(adaptername, adapt_infop->name) != 0) {
1N/A continue;
1N/A }
1N/A lib_infop = adapt_infop->library;
1N/A OpenAdapterFunc = FUNCCOMMON(lib_infop, OpenAdapterHandler);
1N/A
1N/A if (OpenAdapterFunc != NULL) {
1N/A /* retrieve the vendor handle */
1N/A handle = (OpenAdapterFunc)(adaptername);
1N/A if (handle != 0) {
1N/A /* or this with the library index to get the common handle */
1N/A handle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle);
1N/A }
1N/A }
1N/A break;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, handle);
1N/A}
1N/A
1N/A/*
1N/A * Finding an adapter with matching WWN.
1N/A */
1N/AHBA_STATUS
1N/AHBA_OpenAdapterByWWN(HBA_HANDLE *phandle, HBA_WWN nodeWWN) {
1N/A HBA_HANDLE handle;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBAGetNumberOfAdaptersFunc
1N/A GetNumberOfAdaptersFunc;
1N/A HBAOpenAdapterByWWNFunc
1N/A OpenAdapterFunc;
1N/A HBA_STATUS status;
1N/A
1N/A DEBUG(2, "OpenAdapterByWWN: %s", WWN2STR1(&nodeWWN), 0, 0);
1N/A ARE_WE_INITED();
1N/A
1N/A *phandle = HBA_HANDLE_INVALID;
1N/A
1N/A GRAB_MUTEX(&_hbaapi_LL_mutex);
1N/A for (lib_infop = _hbaapi_librarylist;
1N/A lib_infop != NULL;
1N/A lib_infop = lib_infop->next) {
1N/A
1N/A status = HBA_STATUS_ERROR_ILLEGAL_WWN;
1N/A
1N/A if (lib_infop->status != HBA_LIBRARY_LOADED) {
1N/A continue;
1N/A }
1N/A
1N/A /* only for HBAAPIV2 */
1N/A if (lib_infop->version != HBAAPIV2) {
1N/A continue;
1N/A }
1N/A
1N/A GetNumberOfAdaptersFunc =
1N/A FUNCCOMMON(lib_infop, GetNumberOfAdaptersHandler);
1N/A if (GetNumberOfAdaptersFunc == NULL) {
1N/A continue;
1N/A }
1N/A
1N/A /* look for new hardware */
1N/A (void) ((GetNumberOfAdaptersFunc)());
1N/A
1N/A OpenAdapterFunc =
1N/A lib_infop->ftable.functionTable.OpenAdapterByWWNHandler;
1N/A if (OpenAdapterFunc == NULL) {
1N/A continue;
1N/A }
1N/A /*
1N/A * We do not know if the WWN is known by this vendor,
1N/A * just try it
1N/A */
1N/A if ((status = (OpenAdapterFunc)(&handle, nodeWWN)) != HBA_STATUS_OK) {
1N/A continue;
1N/A }
1N/A /* OK, make a vendor non-specific handle */
1N/A *phandle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle);
1N/A status = HBA_STATUS_OK;
1N/A break;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/Avoid
1N/AHBA_RefreshAdapterConfiguration() {
1N/A DEBUG(2, "HBA_RefreshAdapterConfiguration", 0, 0, 0);
1N/A (void) HBA_GetNumberOfAdapters();
1N/A}
1N/A
1N/AHBA_UINT32
1N/AHBA_GetVersion() {
1N/A DEBUG(2, "HBA_GetVersion", 0, 0, 0);
1N/A return (HBA_LIBVERSION);
1N/A}
1N/A
1N/A/*
1N/A * This function is VERY OS dependent. Wing it as best you can.
1N/A */
1N/AHBA_UINT32
1N/AHBA_GetWrapperLibraryAttributes(
1N/A HBA_LIBRARYATTRIBUTES *attributes)
1N/A{
1N/A
1N/A DEBUG(2, "HBA_GetWrapperLibraryAttributes", 0, 0, 0);
1N/A
1N/A if (attributes == NULL) {
1N/A DEBUG(1, "HBA_GetWrapperLibraryAttributes:"
1N/A "NULL pointer attributes",
1N/A 0, 0, 0);
1N/A return (HBA_STATUS_ERROR_ARG);
1N/A }
1N/A
1N/A (void) memset(attributes, 0, sizeof (HBA_LIBRARYATTRIBUTES));
1N/A
1N/A#if defined(SOLARIS)
1N/A if ((handle = dlopen("libHBAAPI.so", RTLD_NOW)) != NULL) {
1N/A if (dlinfo(handle, RTLD_DI_LINKMAP, &map) >= 0) {
1N/A for (mp = map; mp != NULL; mp = mp->l_next) {
1N/A if (strlen(map->l_name) < 256) {
1N/A (void) strcpy(attributes->LibPath, map->l_name);
1N/A }
1N/A }
1N/A }
1N/A }
1N/A#elif defined(WIN32)
1N/A HMODULE module;
1N/A
1N/A /* No need to do anything with the module handle */
1N/A /* It wasn't alloocated so it doesn't need to be freed */
1N/A module = GetModuleHandle("HBAAPI");
1N/A if (module != NULL) {
1N/A if (GetModuleFileName(module, attributes->LibPath,
1N/A sizeof (attributes->LibPath)) == 0) {
1N/A attributes->LibPath[0] = '\0';
1N/A }
1N/A }
1N/A#endif
1N/A#if defined(VENDOR)
1N/A (void) strcpy(attributes->VName, VENDOR);
1N/A#else
1N/A attributes->VName[0] = '\0';
1N/A#endif
1N/A#if defined(VERSION)
1N/A (void) strcpy(attributes->VVersion, VERSION);
1N/A#else
1N/A attributes->VVersion[0] = '\0';
1N/A#endif
1N/A#if defined(BUILD_DATE)
1N/A#if defined(WIN32)
1N/A int matchCount;
1N/A matchCount = sscanf(BUILD_DATE, "%u/%u/%u %u:%u:%u",
1N/A &attributes->build_date.tm_year,
1N/A &attributes->build_date.tm_mon,
1N/A &attributes->build_date.tm_mday,
1N/A &attributes->build_date.tm_hour,
1N/A &attributes->build_date.tm_min,
1N/A &attributes->build_date.tm_sec);
1N/A
1N/A if (matchCount != 6) {
1N/A memset(&attributes->build_date, 0, sizeof (struct tm));
1N/A } else {
1N/A attributes->build_date.tm_year -= 1900;
1N/A attributes->build_date.tm_isdst = -1;
1N/A }
1N/A#else
1N/A if (strptime(BUILD_DATE,
1N/A "%Y/%m/%d %T %Z", &(attributes->build_date)) == NULL) {
1N/A (void) memset(&attributes->build_date, 0, sizeof (struct tm));
1N/A }
1N/A#endif
1N/A#else
1N/A (void) memset(&attributes->build_date, 0, sizeof (struct tm));
1N/A#endif
1N/A return (2);
1N/A}
1N/A
1N/A/*
1N/A * Callback registation and handling
1N/A */
1N/AHBA_STATUS
1N/AHBA_RemoveCallback(HBA_CALLBACKHANDLE cbhandle) {
1N/A HBA_STATUS status;
1N/A
1N/A DEBUG(2, "HBA_RemoveCallback", 0, 0, 0);
1N/A ARE_WE_INITED();
1N/A
1N/A GRAB_MUTEX(&_hbaapi_LL_mutex);
1N/A status = local_remove_callback(cbhandle);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/A/* Adapter Add Events ************************************************* */
1N/Astatic void
1N/A/* LINTED E_FUNC_ARG_UNUSED */
1N/Aadapteraddevents_callback(void *data, HBA_WWN PortWWN, HBA_UINT32 eventType) {
1N/A HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
1N/A
1N/A DEBUG(3, "AddAdapterEvent, port: %s", WWN2STR1(&PortWWN), 0, 0);
1N/A
1N/A GRAB_MUTEX(&_hbaapi_AAE_mutex);
1N/A for (cbp = _hbaapi_adapteraddevents_callback_list;
1N/A cbp != NULL;
1N/A cbp = cbp->next) {
1N/A (*cbp->callback)(data, PortWWN, HBA_EVENT_ADAPTER_ADD);
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1N/A
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_RegisterForAdapterAddEvents(
1N/A void (*callback)(
1N/A void *data,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType),
1N/A void *userData,
1N/A HBA_CALLBACKHANDLE *callbackHandle) {
1N/A
1N/A HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
1N/A HBA_VENDORCALLBACK_ELEM *vcbp;
1N/A HBA_VENDORCALLBACK_ELEM *vendorhandlelist;
1N/A HBARegisterForAdapterAddEventsFunc registeredfunc;
1N/A HBA_STATUS status = HBA_STATUS_OK;
1N/A HBA_STATUS failure = HBA_STATUS_OK;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A int registered_cnt = 0;
1N/A int vendor_cnt = 0;
1N/A int not_supported_cnt = 0;
1N/A int status_OK_bar_cnt = 0;
1N/A int status_OK_cnt = 0;
1N/A
1N/A DEBUG(2, "HBA_RegisterForAdapterAddEvents", 0, 0, 0);
1N/A ARE_WE_INITED();
1N/A
1N/A cbp = (HBA_ALLADAPTERSCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_ALLADAPTERSCALLBACK_ELEM));
1N/A *callbackHandle = (HBA_CALLBACKHANDLE) cbp;
1N/A if (cbp == NULL) {
1N/A#ifndef WIN32
1N/A (void) fprintf(stderr,
1N/A "HBA_RegisterForAdapterAddEvents: calloc failed "
1N/A "for %lu bytes\n",
1N/A (unsigned long)(sizeof (HBA_ALLADAPTERSCALLBACK_ELEM)));
1N/A#endif
1N/A return (HBA_STATUS_ERROR);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_hbaapi_LL_mutex);
1N/A GRAB_MUTEX(&_hbaapi_AAE_mutex);
1N/A cbp->callback = callback;
1N/A cbp->next = _hbaapi_adapteraddevents_callback_list;
1N/A _hbaapi_adapteraddevents_callback_list = cbp;
1N/A /*
1N/A * Need to release the mutex now incase the vendor function invokes the
1N/A * callback. We will grap the mutex later to attach the vendor handle
1N/A * list to the callback structure
1N/A */
1N/A RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1N/A
1N/A /*
1N/A * now create a list of vendors (vendor libraryies, NOT ADAPTERS)
1N/A * that have successfully registerred
1N/A */
1N/A vendorhandlelist = NULL;
1N/A for (lib_infop = _hbaapi_librarylist;
1N/A lib_infop != NULL;
1N/A lib_infop = lib_infop->next) {
1N/A
1N/A /* only for HBAAPI V2 */
1N/A if ((lib_infop->version != HBAAPIV2)) {
1N/A continue;
1N/A } else {
1N/A vendor_cnt++;
1N/A }
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.RegisterForAdapterAddEventsHandler;
1N/A if (registeredfunc == NULL) {
1N/A continue;
1N/A }
1N/A
1N/A vcbp = (HBA_VENDORCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_VENDORCALLBACK_ELEM));
1N/A if (vcbp == NULL) {
1N/A#ifndef WIN32
1N/A (void) fprintf(stderr,
1N/A "HBA_RegisterForAdapterAddEvents: "
1N/A "calloc failed for %lu bytes\n",
1N/A (unsigned long)(sizeof (HBA_VENDORCALLBACK_ELEM)));
1N/A#endif
1N/A freevendorhandlelist(vendorhandlelist);
1N/A status = HBA_STATUS_ERROR;
1N/A break;
1N/A }
1N/A
1N/A registered_cnt++;
1N/A status = (registeredfunc)(adapteraddevents_callback,
1N/A userData, &vcbp->vendorcbhandle);
1N/A if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
1N/A not_supported_cnt++;
1N/A free(vcbp);
1N/A continue;
1N/A } else if (status != HBA_STATUS_OK) {
1N/A status_OK_bar_cnt++;
1N/A DEBUG(1,
1N/A "HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
1N/A lib_infop->LibraryPath, status, 0);
1N/A#ifndef WIN32
1N/A (void) fprintf(stderr,
1N/A "HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
1N/A lib_infop->LibraryPath, status);
1N/A#endif
1N/A failure = status;
1N/A free(vcbp);
1N/A continue;
1N/A } else {
1N/A status_OK_cnt++;
1N/A }
1N/A vcbp->lib_info = lib_infop;
1N/A vcbp->next = vendorhandlelist;
1N/A vendorhandlelist = vcbp;
1N/A }
1N/A if (vendor_cnt == 0) {
1N/A /* no HBAAPIV2 is deteced. should be okay? */
1N/A status = HBA_STATUS_ERROR;
1N/A } else if (registered_cnt == 0) {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A freevendorhandlelist(vendorhandlelist);
1N/A (void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
1N/A } else if (status_OK_cnt == 0 && not_supported_cnt != 0) {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A } else if (status_OK_cnt == 0) {
1N/A /*
1N/A * At least one vendor library registered this function, but no
1N/A * vendor call succeeded
1N/A */
1N/A (void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
1N/A status = failure;
1N/A } else {
1N/A /* we have had atleast some success, now finish up */
1N/A GRAB_MUTEX(&_hbaapi_AAE_mutex);
1N/A /*
1N/A * this seems silly, but what if another thread called
1N/A * the callback remove
1N/A */
1N/A for (cbp = _hbaapi_adapteraddevents_callback_list;
1N/A cbp != NULL; cbp = cbp->next) {
1N/A if ((HBA_CALLBACKHANDLE)cbp == *callbackHandle) {
1N/A /* yup, its still there, hooray */
1N/A cbp->vendorhandlelist = vendorhandlelist;
1N/A vendorhandlelist = NULL;
1N/A break;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1N/A if (vendorhandlelist != NULL) {
1N/A /*
1N/A * bummer, somebody removed the callback before we finished
1N/A * registration, probably will never happen
1N/A */
1N/A freevendorhandlelist(vendorhandlelist);
1N/A DEBUG(1,
1N/A "HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was "
1N/A "called for a handle before registration was finished.",
1N/A 0, 0, 0);
1N/A status = HBA_STATUS_ERROR;
1N/A } else {
1N/A status = HBA_STATUS_OK;
1N/A }
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/A/* Adapter Events (other than add) ************************************** */
1N/Astatic void
1N/Aadapterevents_callback(void *data,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType) {
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A
1N/A DEBUG(3, "AdapterEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN),
1N/A eventType, 0);
1N/A
1N/A GRAB_MUTEX(&_hbaapi_AE_mutex);
1N/A for (acbp = _hbaapi_adapterevents_callback_list;
1N/A acbp != NULL;
1N/A acbp = acbp->next) {
1N/A if (data == (void *)acbp) {
1N/A (*acbp->callback)(acbp->userdata, PortWWN, eventType);
1N/A break;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_AE_mutex);
1N/A}
1N/AHBA_STATUS
1N/AHBA_RegisterForAdapterEvents(
1N/A void (*callback) (
1N/A void *data,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType),
1N/A void *userData,
1N/A HBA_HANDLE handle,
1N/A HBA_CALLBACKHANDLE *callbackHandle) {
1N/A
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A HBARegisterForAdapterEventsFunc registeredfunc;
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A
1N/A DEBUG(2, "HBA_RegisterForAdapterEvents", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A /* we now have the _hbaapi_LL_mutex */
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.RegisterForAdapterEventsHandler;
1N/A if (registeredfunc == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1N/A }
1N/A
1N/A /*
1N/A * that allocated memory is used both as the handle for the
1N/A * caller, and as userdata to the vendor call so that on
1N/A * callback the specific registration may be recalled
1N/A */
1N/A acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1N/A if (acbp == NULL) {
1N/A#ifndef WIN32
1N/A (void) fprintf(stderr,
1N/A "HBA_RegisterForAdapterEvents: calloc failed for %lu bytes\n",
1N/A (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
1N/A#endif
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1N/A }
1N/A *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1N/A acbp->callback = callback;
1N/A acbp->userdata = userData;
1N/A acbp->lib_info = lib_infop;
1N/A
1N/A status = (registeredfunc)(adapterevents_callback,
1N/A (void *)acbp,
1N/A vendorHandle,
1N/A &acbp->vendorcbhandle);
1N/A if (status != HBA_STATUS_OK) {
1N/A free(acbp);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_hbaapi_AE_mutex);
1N/A acbp->next = _hbaapi_adapterevents_callback_list;
1N/A _hbaapi_adapterevents_callback_list = acbp;
1N/A RELEASE_MUTEX(&_hbaapi_AE_mutex);
1N/A
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1N/A}
1N/A
1N/A/* Adapter Port Events ************************************************** */
1N/Astatic void
1N/Aadapterportevents_callback(void *data,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType,
1N/A HBA_UINT32 fabricPortID) {
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A
1N/A DEBUG(3, "AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x",
1N/A WWN2STR1(&PortWWN), eventType, fabricPortID);
1N/A
1N/A GRAB_MUTEX(&_hbaapi_APE_mutex);
1N/A
1N/A for (acbp = _hbaapi_adapterportevents_callback_list;
1N/A acbp != NULL;
1N/A acbp = acbp->next) {
1N/A if (data == (void *)acbp) {
1N/A (*acbp->callback)(acbp->userdata, PortWWN, eventType, fabricPortID);
1N/A break;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_APE_mutex);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_RegisterForAdapterPortEvents(
1N/A void (*callback) (
1N/A void *data,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType,
1N/A HBA_UINT32 fabricPortID),
1N/A void *userData,
1N/A HBA_HANDLE handle,
1N/A HBA_WWN PortWWN,
1N/A HBA_CALLBACKHANDLE *callbackHandle) {
1N/A
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A HBARegisterForAdapterPortEventsFunc registeredfunc;
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A
1N/A DEBUG(2, "HBA_RegisterForAdapterPortEvents for port: %s",
1N/A WWN2STR1(&PortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A /* we now have the _hbaapi_LL_mutex */
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.RegisterForAdapterPortEventsHandler;
1N/A if (registeredfunc == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1N/A }
1N/A
1N/A /*
1N/A * that allocated memory is used both as the handle for the
1N/A * caller, and as userdata to the vendor call so that on
1N/A * callback the specific registration may be recalled
1N/A */
1N/A acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1N/A if (acbp == NULL) {
1N/A#ifndef WIN32
1N/A (void) fprintf(stderr,
1N/A "HBA_RegisterForAdapterPortEvents: "
1N/A "calloc failed for %lu bytes\n",
1N/A (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
1N/A#endif
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1N/A
1N/A }
1N/A *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1N/A acbp->callback = callback;
1N/A acbp->userdata = userData;
1N/A acbp->lib_info = lib_infop;
1N/A
1N/A status = (registeredfunc)(adapterportevents_callback,
1N/A (void *)acbp,
1N/A vendorHandle,
1N/A PortWWN,
1N/A &acbp->vendorcbhandle);
1N/A if (status != HBA_STATUS_OK) {
1N/A free(acbp);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_hbaapi_APE_mutex);
1N/A acbp->next = _hbaapi_adapterportevents_callback_list;
1N/A _hbaapi_adapterportevents_callback_list = acbp;
1N/A RELEASE_MUTEX(&_hbaapi_APE_mutex);
1N/A
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1N/A}
1N/A
1N/A/* Adapter State Events ************************************************ */
1N/Astatic void
1N/Aadapterportstatevents_callback(void *data,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType) {
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A
1N/A DEBUG(3, "AdapterPortStatEvent, port:%s, eventType:%d",
1N/A WWN2STR1(&PortWWN),
1N/A eventType, 0);
1N/A
1N/A GRAB_MUTEX(&_hbaapi_APSE_mutex);
1N/A for (acbp = _hbaapi_adapterportstatevents_callback_list;
1N/A acbp != NULL;
1N/A acbp = acbp->next) {
1N/A if (data == (void *)acbp) {
1N/A (*acbp->callback)(acbp->userdata, PortWWN, eventType);
1N/A return;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_APSE_mutex);
1N/A}
1N/AHBA_STATUS
1N/AHBA_RegisterForAdapterPortStatEvents(
1N/A void (*callback) (
1N/A void *data,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType),
1N/A void *userData,
1N/A HBA_HANDLE handle,
1N/A HBA_WWN PortWWN,
1N/A HBA_PORTSTATISTICS stats,
1N/A HBA_UINT32 statType,
1N/A HBA_CALLBACKHANDLE *callbackHandle) {
1N/A
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A HBARegisterForAdapterPortStatEventsFunc
1N/A registeredfunc;
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A
1N/A DEBUG(2, "HBA_RegisterForAdapterPortStatEvents for port: %s",
1N/A WWN2STR1(&PortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A /* we now have the _hbaapi_LL_mutex */
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.RegisterForAdapterPortStatEventsHandler;
1N/A if (registeredfunc == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1N/A }
1N/A
1N/A /*
1N/A * that allocated memory is used both as the handle for the
1N/A * caller, and as userdata to the vendor call so that on
1N/A * callback the specific registration may be recalled
1N/A */
1N/A acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1N/A if (acbp == NULL) {
1N/A#ifndef WIN32
1N/A (void) fprintf(stderr,
1N/A "HBA_RegisterForAdapterPortStatEvents: "
1N/A "calloc failed for %lu bytes\n",
1N/A (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
1N/A#endif
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1N/A }
1N/A *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1N/A acbp->callback = callback;
1N/A acbp->userdata = userData;
1N/A acbp->lib_info = lib_infop;
1N/A
1N/A status = (registeredfunc)(adapterportstatevents_callback,
1N/A (void *)acbp,
1N/A vendorHandle,
1N/A PortWWN,
1N/A stats,
1N/A statType,
1N/A &acbp->vendorcbhandle);
1N/A if (status != HBA_STATUS_OK) {
1N/A free(acbp);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_hbaapi_APSE_mutex);
1N/A acbp->next = _hbaapi_adapterportstatevents_callback_list;
1N/A _hbaapi_adapterportstatevents_callback_list = acbp;
1N/A RELEASE_MUTEX(&_hbaapi_APSE_mutex);
1N/A
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1N/A}
1N/A
1N/A/* Target Events ******************************************************* */
1N/Astatic void
1N/Atargetevents_callback(void *data,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN discoveredPortWWN,
1N/A HBA_UINT32 eventType) {
1N/A
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A
1N/A DEBUG(3, "TargetEvent, hbaPort:%s, discoveredPort:%s eventType:%d",
1N/A WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), eventType);
1N/A
1N/A GRAB_MUTEX(&_hbaapi_TE_mutex);
1N/A for (acbp = _hbaapi_targetevents_callback_list;
1N/A acbp != NULL;
1N/A acbp = acbp->next) {
1N/A if (data == (void *)acbp) {
1N/A (*acbp->callback)(acbp->userdata, hbaPortWWN,
1N/A discoveredPortWWN, eventType);
1N/A break;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_TE_mutex);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_RegisterForTargetEvents(
1N/A void (*callback) (
1N/A void *data,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN discoveredPortWWN,
1N/A HBA_UINT32 eventType),
1N/A void *userData,
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN discoveredPortWWN,
1N/A HBA_CALLBACKHANDLE *callbackHandle,
1N/A HBA_UINT32 allTargets) {
1N/A
1N/A HBA_ADAPTERCALLBACK_ELEM
1N/A *acbp;
1N/A HBARegisterForTargetEventsFunc
1N/A registeredfunc;
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A
1N/A DEBUG(2, "HBA_RegisterForTargetEvents, hbaPort: %s, discoveredPort: %s",
1N/A WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A /* we now have the _hbaapi_LL_mutex */
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.RegisterForTargetEventsHandler;
1N/A if (registeredfunc == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1N/A }
1N/A
1N/A /*
1N/A * that allocated memory is used both as the handle for the
1N/A * caller, and as userdata to the vendor call so that on
1N/A * callback the specific registration may be recalled
1N/A */
1N/A acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1N/A if (acbp == NULL) {
1N/A#ifndef WIN32
1N/A (void) fprintf(stderr,
1N/A "HBA_RegisterForTargetEvents: calloc failed for %lu bytes\n",
1N/A (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
1N/A#endif
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1N/A }
1N/A *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1N/A acbp->callback = callback;
1N/A acbp->userdata = userData;
1N/A acbp->lib_info = lib_infop;
1N/A
1N/A status = (registeredfunc)(targetevents_callback,
1N/A (void *)acbp,
1N/A vendorHandle,
1N/A hbaPortWWN,
1N/A discoveredPortWWN,
1N/A &acbp->vendorcbhandle,
1N/A allTargets);
1N/A if (status != HBA_STATUS_OK) {
1N/A free(acbp);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_hbaapi_TE_mutex);
1N/A acbp->next = _hbaapi_targetevents_callback_list;
1N/A _hbaapi_targetevents_callback_list = acbp;
1N/A RELEASE_MUTEX(&_hbaapi_TE_mutex);
1N/A
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1N/A}
1N/A
1N/A/* Link Events ********************************************************* */
1N/Astatic void
1N/Alinkevents_callback(void *data,
1N/A HBA_WWN adapterWWN,
1N/A HBA_UINT32 eventType,
1N/A void *pRLIRBuffer,
1N/A HBA_UINT32 RLIRBufferSize) {
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A
1N/A DEBUG(3, "LinkEvent, hbaWWN:%s, eventType:%d",
1N/A WWN2STR1(&adapterWWN), eventType, 0);
1N/A
1N/A GRAB_MUTEX(&_hbaapi_LE_mutex);
1N/A for (acbp = _hbaapi_linkevents_callback_list;
1N/A acbp != NULL;
1N/A acbp = acbp->next) {
1N/A if (data == (void *)acbp) {
1N/A (*acbp->callback)(acbp->userdata, adapterWWN,
1N/A eventType, pRLIRBuffer, RLIRBufferSize);
1N/A break;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_LE_mutex);
1N/A}
1N/AHBA_STATUS
1N/AHBA_RegisterForLinkEvents(
1N/A void (*callback) (
1N/A void *data,
1N/A HBA_WWN adapterWWN,
1N/A HBA_UINT32 eventType,
1N/A void *pRLIRBuffer,
1N/A HBA_UINT32 RLIRBufferSize),
1N/A void *userData,
1N/A void *pRLIRBuffer,
1N/A HBA_UINT32 RLIRBufferSize,
1N/A HBA_HANDLE handle,
1N/A HBA_CALLBACKHANDLE *callbackHandle) {
1N/A
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A HBARegisterForLinkEventsFunc
1N/A registeredfunc;
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A
1N/A DEBUG(2, "HBA_RegisterForLinkEvents", 0, 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A /* we now have the _hbaapi_LL_mutex */
1N/A
1N/A registeredfunc = FUNCCOMMON(lib_infop, RegisterForLinkEventsHandler);
1N/A
1N/A if (registeredfunc == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1N/A }
1N/A
1N/A /*
1N/A * that allocated memory is used both as the handle for the
1N/A * caller, and as userdata to the vendor call so that on
1N/A * callback the specific registration may be recalled
1N/A */
1N/A acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1N/A if (acbp == NULL) {
1N/A#ifndef WIN32
1N/A (void) fprintf(stderr,
1N/A "HBA_RegisterForLinkEvents: calloc failed for %lu bytes\n",
1N/A (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
1N/A#endif
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1N/A }
1N/A *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1N/A acbp->callback = callback;
1N/A acbp->userdata = userData;
1N/A acbp->lib_info = lib_infop;
1N/A
1N/A status = (registeredfunc)(linkevents_callback,
1N/A (void *)acbp,
1N/A pRLIRBuffer,
1N/A RLIRBufferSize,
1N/A vendorHandle,
1N/A &acbp->vendorcbhandle);
1N/A if (status != HBA_STATUS_OK) {
1N/A free(acbp);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_hbaapi_LE_mutex);
1N/A acbp->next = _hbaapi_linkevents_callback_list;
1N/A _hbaapi_linkevents_callback_list = acbp;
1N/A RELEASE_MUTEX(&_hbaapi_LE_mutex);
1N/A
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1N/A}
1N/A
1N/A/*
1N/A * All of the functions below are almost passthru functions to the
1N/A * vendor specific function
1N/A */
1N/A
1N/Avoid
1N/AHBA_CloseAdapter(HBA_HANDLE handle) {
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBACloseAdapterFunc CloseAdapterFunc;
1N/A
1N/A DEBUG(2, "HBA_CloseAdapter", 0, 0, 0);
1N/A
1N/A status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
1N/A if (status == HBA_STATUS_OK) {
1N/A CloseAdapterFunc = FUNCCOMMON(lib_infop, CloseAdapterHandler);
1N/A if (CloseAdapterFunc != NULL) {
1N/A ((CloseAdapterFunc)(vendorHandle));
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_LL_mutex);
1N/A }
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetAdapterAttributes(
1N/A HBA_HANDLE handle,
1N/A HBA_ADAPTERATTRIBUTES
1N/A *hbaattributes)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetAdapterAttributesFunc GetAdapterAttributesFunc;
1N/A
1N/A DEBUG(2, "HBA_GetAdapterAttributes", 0, 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A GetAdapterAttributesFunc =
1N/A lib_infop->ftable.functionTable.GetAdapterAttributesHandler;
1N/A if (GetAdapterAttributesFunc != NULL) {
1N/A status = ((GetAdapterAttributesFunc)(vendorHandle, hbaattributes));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetAdapterPortAttributes(
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_PORTATTRIBUTES *portattributes)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetAdapterPortAttributesFunc
1N/A GetAdapterPortAttributesFunc;
1N/A
1N/A DEBUG(2, "HBA_GetAdapterPortAttributes", 0, 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A GetAdapterPortAttributesFunc =
1N/A lib_infop->ftable.functionTable.GetAdapterPortAttributesHandler;
1N/A if (GetAdapterPortAttributesFunc != NULL) {
1N/A status = ((GetAdapterPortAttributesFunc)
1N/A (vendorHandle, portindex, portattributes));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetPortStatistics(
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_PORTSTATISTICS *portstatistics)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetPortStatisticsFunc
1N/A GetPortStatisticsFunc;
1N/A
1N/A DEBUG(2, "HBA_GetPortStatistics", 0, 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A GetPortStatisticsFunc =
1N/A lib_infop->ftable.functionTable.GetPortStatisticsHandler;
1N/A if (GetPortStatisticsFunc != NULL) {
1N/A status = ((GetPortStatisticsFunc)
1N/A (vendorHandle, portindex, portstatistics));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetDiscoveredPortAttributes(
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_UINT32 discoveredportindex,
1N/A HBA_PORTATTRIBUTES *portattributes)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetDiscoveredPortAttributesFunc
1N/A GetDiscoveredPortAttributesFunc;
1N/A
1N/A DEBUG(2, "HBA_GetDiscoveredPortAttributes", 0, 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A GetDiscoveredPortAttributesFunc =
1N/A lib_infop->ftable.functionTable.GetDiscoveredPortAttributesHandler;
1N/A if (GetDiscoveredPortAttributesFunc != NULL) {
1N/A status = ((GetDiscoveredPortAttributesFunc)
1N/A (vendorHandle, portindex, discoveredportindex,
1N/A portattributes));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetPortAttributesByWWN(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN PortWWN,
1N/A HBA_PORTATTRIBUTES *portattributes)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetPortAttributesByWWNFunc
1N/A GetPortAttributesByWWNFunc;
1N/A
1N/A DEBUG(2, "HBA_GetPortAttributesByWWN: %s", WWN2STR1(&PortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A GetPortAttributesByWWNFunc =
1N/A lib_infop->ftable.functionTable.GetPortAttributesByWWNHandler;
1N/A if (GetPortAttributesByWWNFunc != NULL) {
1N/A status = ((GetPortAttributesByWWNFunc)
1N/A (vendorHandle, PortWWN, portattributes));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SendCTPassThru(
1N/A HBA_HANDLE handle,
1N/A void *pReqBuffer,
1N/A HBA_UINT32 ReqBufferSize,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 RspBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASendCTPassThruFunc
1N/A SendCTPassThruFunc;
1N/A
1N/A DEBUG(2, "HBA_SendCTPassThru", 0, 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A SendCTPassThruFunc =
1N/A lib_infop->ftable.functionTable.SendCTPassThruHandler;
1N/A if (SendCTPassThruFunc != NULL) {
1N/A status = (SendCTPassThruFunc)
1N/A (vendorHandle,
1N/A pReqBuffer, ReqBufferSize,
1N/A pRspBuffer, RspBufferSize);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SendCTPassThruV2(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A void *pReqBuffer,
1N/A HBA_UINT32 ReqBufferSize,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASendCTPassThruV2Func
1N/A registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_SendCTPassThruV2m hbaPortWWN: %s",
1N/A WWN2STR1(&hbaPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A registeredfunc = FUNCCOMMON(lib_infop, SendCTPassThruV2Handler);
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)
1N/A (vendorHandle, hbaPortWWN,
1N/A pReqBuffer, ReqBufferSize,
1N/A pRspBuffer, pRspBufferSize);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetEventBuffer(
1N/A HBA_HANDLE handle,
1N/A PHBA_EVENTINFO EventBuffer,
1N/A HBA_UINT32 *EventBufferCount)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetEventBufferFunc
1N/A GetEventBufferFunc;
1N/A
1N/A DEBUG(2, "HBA_GetEventBuffer", 0, 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A GetEventBufferFunc =
1N/A lib_infop->ftable.functionTable.GetEventBufferHandler;
1N/A if (GetEventBufferFunc != NULL) {
1N/A status = (GetEventBufferFunc)
1N/A (vendorHandle, EventBuffer, EventBufferCount);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SetRNIDMgmtInfo(HBA_HANDLE handle, HBA_MGMTINFO Info) {
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASetRNIDMgmtInfoFunc
1N/A SetRNIDMgmtInfoFunc;
1N/A
1N/A DEBUG(2, "HBA_SetRNIDMgmtInfo", 0, 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A SetRNIDMgmtInfoFunc = FUNCCOMMON(lib_infop, SetRNIDMgmtInfoHandler);
1N/A if (SetRNIDMgmtInfoFunc != NULL) {
1N/A status = (SetRNIDMgmtInfoFunc)(vendorHandle, Info);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetRNIDMgmtInfo(HBA_HANDLE handle, HBA_MGMTINFO *pInfo) {
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetRNIDMgmtInfoFunc
1N/A GetRNIDMgmtInfoFunc;
1N/A
1N/A DEBUG(2, "HBA_GetRNIDMgmtInfo", 0, 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A GetRNIDMgmtInfoFunc = FUNCCOMMON(lib_infop, GetRNIDMgmtInfoHandler);
1N/A if (GetRNIDMgmtInfoFunc != NULL) {
1N/A status = (GetRNIDMgmtInfoFunc)(vendorHandle, pInfo);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SendRNID(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN wwn,
1N/A HBA_WWNTYPE wwntype,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASendRNIDFunc SendRNIDFunc;
1N/A
1N/A DEBUG(2, "HBA_SendRNID for wwn: %s", WWN2STR1(&wwn), 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A SendRNIDFunc = lib_infop->ftable.functionTable.SendRNIDHandler;
1N/A if (SendRNIDFunc != NULL) {
1N/A status = ((SendRNIDFunc)(vendorHandle, wwn, wwntype,
1N/A pRspBuffer, pRspBufferSize));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SendRNIDV2(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN destWWN,
1N/A HBA_UINT32 destFCID,
1N/A HBA_UINT32 NodeIdDataFormat,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASendRNIDV2Func registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_SendRNIDV2, hbaPortWWN: %s", WWN2STR1(&hbaPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A registeredfunc = FUNCCOMMON(lib_infop, SendRNIDV2Handler);
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)
1N/A (vendorHandle, hbaPortWWN, destWWN, destFCID, NodeIdDataFormat,
1N/A pRspBuffer, pRspBufferSize);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/Avoid
1N/AHBA_RefreshInformation(HBA_HANDLE handle) {
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBARefreshInformationFunc
1N/A RefreshInformationFunc;
1N/A
1N/A DEBUG(2, "HBA_RefreshInformation", 0, 0, 0);
1N/A
1N/A status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
1N/A if (status == HBA_STATUS_OK) {
1N/A RefreshInformationFunc =
1N/A FUNCCOMMON(lib_infop, RefreshInformationHandler);
1N/A if (RefreshInformationFunc != NULL) {
1N/A ((RefreshInformationFunc)(vendorHandle));
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_LL_mutex);
1N/A }
1N/A}
1N/A
1N/Avoid
1N/AHBA_ResetStatistics(HBA_HANDLE handle, HBA_UINT32 portindex) {
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAResetStatisticsFunc
1N/A ResetStatisticsFunc;
1N/A
1N/A DEBUG(2, "HBA_ResetStatistics", 0, 0, 0);
1N/A
1N/A status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
1N/A if (status == HBA_STATUS_OK) {
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX(&_hbaapi_LL_mutex);
1N/A }
1N/A
1N/A ResetStatisticsFunc =
1N/A lib_infop->ftable.functionTable.ResetStatisticsHandler;
1N/A if (ResetStatisticsFunc != NULL) {
1N/A ((ResetStatisticsFunc)(vendorHandle, portindex));
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_LL_mutex);
1N/A }
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetFcpTargetMapping(HBA_HANDLE handle, PHBA_FCPTARGETMAPPING mapping) {
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetFcpTargetMappingFunc GetFcpTargetMappingFunc;
1N/A
1N/A DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A GetFcpTargetMappingFunc =
1N/A lib_infop->ftable.functionTable.GetFcpTargetMappingHandler;
1N/A if (GetFcpTargetMappingFunc != NULL) {
1N/A status = ((GetFcpTargetMappingFunc)(vendorHandle, mapping));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetFcpTargetMappingV2(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_FCPTARGETMAPPINGV2 *pmapping)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetFcpTargetMappingV2Func
1N/A registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.GetFcpTargetMappingV2Handler;
1N/A if (registeredfunc != NULL) {
1N/A status = ((registeredfunc)(vendorHandle, hbaPortWWN, pmapping));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetFcpPersistentBinding(HBA_HANDLE handle, PHBA_FCPBINDING binding) {
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetFcpPersistentBindingFunc
1N/A GetFcpPersistentBindingFunc;
1N/A
1N/A DEBUG(2, "HBA_GetFcpPersistentBinding", 0, 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A GetFcpPersistentBindingFunc =
1N/A lib_infop->ftable.functionTable.GetFcpPersistentBindingHandler;
1N/A if (GetFcpPersistentBindingFunc != NULL) {
1N/A status = ((GetFcpPersistentBindingFunc)(vendorHandle, binding));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_ScsiInquiryV2(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN discoveredPortWWN,
1N/A HBA_UINT64 fcLUN,
1N/A HBA_UINT8 CDB_Byte1,
1N/A HBA_UINT8 CDB_Byte2,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize,
1N/A HBA_UINT8 *pScsiStatus,
1N/A void *pSenseBuffer,
1N/A HBA_UINT32 *pSenseBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAScsiInquiryV2Func ScsiInquiryV2Func;
1N/A
1N/A DEBUG(2, "HBA_ScsiInquiryV2 to discoveredPortWWN: %s",
1N/A WWN2STR1(&discoveredPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A ScsiInquiryV2Func =
1N/A lib_infop->ftable.functionTable.ScsiInquiryV2Handler;
1N/A if (ScsiInquiryV2Func != NULL) {
1N/A status = ((ScsiInquiryV2Func)(
1N/A vendorHandle, hbaPortWWN, discoveredPortWWN, fcLUN, CDB_Byte1,
1N/A CDB_Byte2, pRspBuffer, pRspBufferSize, pScsiStatus,
1N/A pSenseBuffer, pSenseBufferSize));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SendScsiInquiry(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT64 fcLUN,
1N/A HBA_UINT8 EVPD,
1N/A HBA_UINT32 PageCode,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 RspBufferSize,
1N/A void *pSenseBuffer,
1N/A HBA_UINT32 SenseBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASendScsiInquiryFunc SendScsiInquiryFunc;
1N/A
1N/A DEBUG(2, "HBA_SendScsiInquiry to PortWWN: %s",
1N/A WWN2STR1(&PortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A SendScsiInquiryFunc =
1N/A lib_infop->ftable.functionTable.ScsiInquiryHandler;
1N/A if (SendScsiInquiryFunc != NULL) {
1N/A status = ((SendScsiInquiryFunc)(
1N/A vendorHandle, PortWWN, fcLUN, EVPD, PageCode, pRspBuffer,
1N/A RspBufferSize, pSenseBuffer, SenseBufferSize));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_ScsiReportLUNsV2(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN discoveredPortWWN,
1N/A void *pRespBuffer,
1N/A HBA_UINT32 *pRespBufferSize,
1N/A HBA_UINT8 *pScsiStatus,
1N/A void *pSenseBuffer,
1N/A HBA_UINT32 *pSenseBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAScsiReportLUNsV2Func ScsiReportLUNsV2Func;
1N/A
1N/A DEBUG(2, "HBA_ScsiReportLUNsV2 to discoveredPortWWN: %s",
1N/A WWN2STR1(&discoveredPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A ScsiReportLUNsV2Func =
1N/A lib_infop->ftable.functionTable.ScsiReportLUNsV2Handler;
1N/A if (ScsiReportLUNsV2Func != NULL) {
1N/A status = ((ScsiReportLUNsV2Func)(
1N/A vendorHandle, hbaPortWWN, discoveredPortWWN,
1N/A pRespBuffer, pRespBufferSize,
1N/A pScsiStatus,
1N/A pSenseBuffer, pSenseBufferSize));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SendReportLUNs(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN portWWN,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 RspBufferSize,
1N/A void *pSenseBuffer,
1N/A HBA_UINT32 SenseBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASendReportLUNsFunc SendReportLUNsFunc;
1N/A
1N/A DEBUG(2, "HBA_SendReportLUNs to PortWWN: %s", WWN2STR1(&portWWN), 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A SendReportLUNsFunc = lib_infop->ftable.functionTable.ReportLUNsHandler;
1N/A if (SendReportLUNsFunc != NULL) {
1N/A status = ((SendReportLUNsFunc)(
1N/A vendorHandle, portWWN, pRspBuffer,
1N/A RspBufferSize, pSenseBuffer, SenseBufferSize));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_ScsiReadCapacityV2(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN discoveredPortWWN,
1N/A HBA_UINT64 fcLUN,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize,
1N/A HBA_UINT8 *pScsiStatus,
1N/A void *pSenseBuffer,
1N/A HBA_UINT32 *SenseBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAScsiReadCapacityV2Func ScsiReadCapacityV2Func;
1N/A
1N/A DEBUG(2, "HBA_ScsiReadCapacityV2 to discoveredPortWWN: %s",
1N/A WWN2STR1(&discoveredPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A ScsiReadCapacityV2Func =
1N/A lib_infop->ftable.functionTable.ScsiReadCapacityV2Handler;
1N/A if (ScsiReadCapacityV2Func != NULL) {
1N/A status = ((ScsiReadCapacityV2Func)(
1N/A vendorHandle, hbaPortWWN, discoveredPortWWN, fcLUN,
1N/A pRspBuffer, pRspBufferSize,
1N/A pScsiStatus,
1N/A pSenseBuffer, SenseBufferSize));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SendReadCapacity(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN portWWN,
1N/A HBA_UINT64 fcLUN,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 RspBufferSize,
1N/A void *pSenseBuffer,
1N/A HBA_UINT32 SenseBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASendReadCapacityFunc SendReadCapacityFunc;
1N/A
1N/A DEBUG(2, "HBA_SendReadCapacity to portWWN: %s",
1N/A WWN2STR1(&portWWN), 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A if (lib_infop->version == SMHBA) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A SendReadCapacityFunc =
1N/A lib_infop->ftable.functionTable.ReadCapacityHandler;
1N/A if (SendReadCapacityFunc != NULL) {
1N/A status = ((SendReadCapacityFunc)
1N/A (vendorHandle, portWWN, fcLUN, pRspBuffer,
1N/A RspBufferSize, pSenseBuffer, SenseBufferSize));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SendRPL(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN agent_wwn,
1N/A HBA_UINT32 agent_domain,
1N/A HBA_UINT32 portindex,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASendRPLFunc registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_SendRPL to agent_wwn: %s:%d",
1N/A WWN2STR1(&agent_wwn), agent_domain, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A registeredfunc = FUNCCOMMON(lib_infop, SendRPLHandler);
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(
1N/A vendorHandle, hbaPortWWN, agent_wwn, agent_domain, portindex,
1N/A pRspBuffer, pRspBufferSize);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SendRPS(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN agent_wwn,
1N/A HBA_UINT32 agent_domain,
1N/A HBA_WWN object_wwn,
1N/A HBA_UINT32 object_port_number,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASendRPSFunc registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_SendRPS to agent_wwn: %s:%d",
1N/A WWN2STR1(&agent_wwn), agent_domain, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A registeredfunc = FUNCCOMMON(lib_infop, SendRPSHandler);
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(
1N/A vendorHandle, hbaPortWWN, agent_wwn, agent_domain,
1N/A object_wwn, object_port_number,
1N/A pRspBuffer, pRspBufferSize);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SendSRL(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN wwn,
1N/A HBA_UINT32 domain,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASendSRLFunc registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_SendSRL to wwn:%s domain:%d", WWN2STR1(&wwn), domain, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A registeredfunc = FUNCCOMMON(lib_infop, SendSRLHandler);
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(
1N/A vendorHandle, hbaPortWWN, wwn, domain,
1N/A pRspBuffer, pRspBufferSize);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/AHBA_STATUS
1N/AHBA_SendRLS(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN destWWN,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASendRLSFunc registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_SendRLS dest_wwn: %s",
1N/A WWN2STR1(&destWWN), 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A registeredfunc = FUNCCOMMON(lib_infop, SendRLSHandler);
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(
1N/A vendorHandle, hbaPortWWN, destWWN,
1N/A pRspBuffer, pRspBufferSize);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SendLIRR(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN sourceWWN,
1N/A HBA_WWN destWWN,
1N/A HBA_UINT8 function,
1N/A HBA_UINT8 type,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASendLIRRFunc registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_SendLIRR destWWN:%s", WWN2STR1(&destWWN), 0, 0);
1N/A
1N/A CHECKLIBRARY();
1N/A registeredfunc = FUNCCOMMON(lib_infop, SendLIRRHandler);
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(
1N/A vendorHandle, sourceWWN, destWWN, function, type,
1N/A pRspBuffer, pRspBufferSize);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetBindingCapability(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_BIND_CAPABILITY *pcapability)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetBindingCapabilityFunc
1N/A registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_GetBindingCapability", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.GetBindingCapabilityHandler;
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(vendorHandle, hbaPortWWN, pcapability);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetBindingSupport(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_BIND_CAPABILITY *pcapability)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetBindingSupportFunc
1N/A registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_GetBindingSupport", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.GetBindingSupportHandler;
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(vendorHandle, hbaPortWWN, pcapability);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SetBindingSupport(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_BIND_CAPABILITY capability)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASetBindingSupportFunc
1N/A registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_SetBindingSupport", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.SetBindingSupportHandler;
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(vendorHandle, hbaPortWWN, capability);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_SetPersistentBindingV2(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A const HBA_FCPBINDING2 *pbinding)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBASetPersistentBindingV2Func
1N/A registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_SetPersistentBindingV2 port: %s",
1N/A WWN2STR1(&hbaPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.SetPersistentBindingV2Handler;
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetPersistentBindingV2(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_FCPBINDING2 *pbinding)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetPersistentBindingV2Func
1N/A registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_GetPersistentBindingV2 port: %s",
1N/A WWN2STR1(&hbaPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.GetPersistentBindingV2Handler;
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_RemovePersistentBinding(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A const HBA_FCPBINDING2
1N/A *pbinding)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBARemovePersistentBindingFunc
1N/A registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_RemovePersistentBinding", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.RemovePersistentBindingHandler;
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_RemoveAllPersistentBindings(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBARemoveAllPersistentBindingsFunc
1N/A registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_RemoveAllPersistentBindings", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.RemoveAllPersistentBindingsHandler;
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(vendorHandle, hbaPortWWN);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetFC4Statistics(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN portWWN,
1N/A HBA_UINT8 FC4type,
1N/A HBA_FC4STATISTICS *pstatistics)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetFC4StatisticsFunc
1N/A registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_GetFC4Statistics port: %s", WWN2STR1(&portWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.GetFC4StatisticsHandler;
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)
1N/A (vendorHandle, portWWN, FC4type, pstatistics);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/AHBA_GetFCPStatistics(
1N/A HBA_HANDLE handle,
1N/A const HBA_SCSIID *lunit,
1N/A HBA_FC4STATISTICS *pstatistics)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A HBAGetFCPStatisticsFunc
1N/A registeredfunc;
1N/A
1N/A DEBUG(2, "HBA_GetFCPStatistics", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.functionTable.GetFCPStatisticsHandler;
1N/A if (registeredfunc != NULL) {
1N/A status = (registeredfunc)(vendorHandle, lunit, pstatistics);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_UINT32
1N/AHBA_GetVendorLibraryAttributes(
1N/A HBA_UINT32 adapter_index,
1N/A HBA_LIBRARYATTRIBUTES *attributes)
1N/A{
1N/A HBA_ADAPTER_INFO *adapt_infop;
1N/A HBAGetVendorLibraryAttributesFunc
1N/A registeredfunc;
1N/A HBA_UINT32 ret = 0;
1N/A
1N/A DEBUG(2, "HBA_GetVendorLibraryAttributes adapterindex:%d",
1N/A adapter_index, 0, 0);
1N/A if (_hbaapi_librarylist == NULL) {
1N/A DEBUG(1, "HBAAPI not loaded yet.", 0, 0, 0);
1N/A return (0);
1N/A }
1N/A
1N/A if (attributes == NULL) {
1N/A DEBUG(1,
1N/A "HBA_GetVendorLibraryAttributes: NULL pointer attributes",
1N/A 0, 0, 0);
1N/A return (HBA_STATUS_ERROR_ARG);
1N/A }
1N/A
1N/A (void) memset(attributes, 0, sizeof (HBA_LIBRARYATTRIBUTES));
1N/A
1N/A GRAB_MUTEX(&_hbaapi_LL_mutex);
1N/A GRAB_MUTEX(&_hbaapi_AL_mutex);
1N/A for (adapt_infop = _hbaapi_adapterlist;
1N/A adapt_infop != NULL;
1N/A adapt_infop = adapt_infop->next) {
1N/A
1N/A if (adapt_infop->index == adapter_index) {
1N/A
1N/A if (adapt_infop->library->version == SMHBA) {
1N/A RELEASE_MUTEX(&_hbaapi_AL_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
1N/A HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A registeredfunc = adapt_infop->library->
1N/A ftable.functionTable.GetVendorLibraryAttributesHandler;
1N/A if (registeredfunc != NULL) {
1N/A ret = (registeredfunc)(attributes);
1N/A } else {
1N/A /* Version 1 libary? */
1N/A HBAGetVersionFunc GetVersionFunc;
1N/A GetVersionFunc = adapt_infop->library->
1N/A ftable.functionTable.GetVersionHandler;
1N/A if (GetVersionFunc != NULL) {
1N/A ret = ((GetVersionFunc)());
1N/A }
1N/A#ifdef NOTDEF
1N/A else {
1N/A /* This should not happen, dont think its going to */
1N/A }
1N/A#endif
1N/A }
1N/A if (attributes->LibPath[0] == '\0') {
1N/A if (strlen(adapt_infop->library->LibraryPath) < 256) {
1N/A (void) strcpy(attributes->LibPath,
1N/A adapt_infop->library->LibraryPath);
1N/A }
1N/A }
1N/A break;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_AL_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, ret);
1N/A}
1N/A
1N/A
1N/A/*
1N/A * This function returns SM-HBA version that the warpper library implemented.
1N/A */
1N/AHBA_UINT32
1N/ASMHBA_GetVersion() {
1N/A DEBUG(2, "SMHBA_GetVersion", 0, 0, 0);
1N/A return (SMHBA_LIBVERSION);
1N/A}
1N/A
1N/A/*
1N/A * This function returns the attributes for the warpper library.
1N/A */
1N/AHBA_UINT32
1N/ASMHBA_GetWrapperLibraryAttributes(
1N/A SMHBA_LIBRARYATTRIBUTES *attributes)
1N/A{
1N/A
1N/A struct timeval tv;
1N/A struct tm tp;
1N/A
1N/A DEBUG(2, "SMHBA_GetWrapperLibraryAttributes", 0, 0, 0);
1N/A
1N/A if (attributes == NULL) {
1N/A DEBUG(1, "SMHBA_GetWrapperLibraryAttributes: "
1N/A "NULL pointer attributes",
1N/A 0, 0, 0);
1N/A return (HBA_STATUS_ERROR_ARG);
1N/A }
1N/A
1N/A (void) memset(attributes, 0, sizeof (SMHBA_LIBRARYATTRIBUTES));
1N/A
1N/A#if defined(SOLARIS)
1N/A if ((handle = dlopen("libSMHBAAPI.so", RTLD_NOW)) != NULL) {
1N/A if (dlinfo(handle, RTLD_DI_LINKMAP, &map) >= 0) {
1N/A for (mp = map; mp != NULL; mp = mp->l_next) {
1N/A if (strlen(map->l_name) < 256) {
1N/A (void) strcpy(attributes->LibPath, map->l_name);
1N/A }
1N/A }
1N/A }
1N/A }
1N/A
1N/A#endif
1N/A
1N/A#if defined(VENDOR)
1N/A (void) strcpy(attributes->VName, VENDOR);
1N/A#else
1N/A attributes->VName[0] = '\0';
1N/A#endif
1N/A#if defined(VERSION)
1N/A (void) strcpy(attributes->VVersion, VERSION);
1N/A#else
1N/A attributes->VVersion[0] = '\0';
1N/A#endif
1N/A
1N/A if (gettimeofday(&tv, (void *)0) == 0) {
1N/A if (localtime_r(&tv.tv_sec, &tp) != NULL) {
1N/A attributes->build_date.tm_mday = tp.tm_mday;
1N/A attributes->build_date.tm_mon = tp.tm_mon;
1N/A attributes->build_date.tm_year = tp.tm_year;
1N/A } else {
1N/A (void) memset(&attributes->build_date, 0,
1N/A sizeof (attributes->build_date));
1N/A }
1N/A (void) memset(&attributes->build_date, 0,
1N/A sizeof (attributes->build_date));
1N/A }
1N/A
1N/A return (1);
1N/A}
1N/A
1N/A/*
1N/A * This function returns the attributes for the warpper library.
1N/A */
1N/AHBA_UINT32
1N/ASMHBA_GetVendorLibraryAttributes(
1N/A HBA_UINT32 adapter_index,
1N/A SMHBA_LIBRARYATTRIBUTES *attributes)
1N/A{
1N/A HBA_ADAPTER_INFO *adapt_infop;
1N/A SMHBAGetVendorLibraryAttributesFunc
1N/A registeredfunc;
1N/A HBA_UINT32 ret = 0;
1N/A
1N/A DEBUG(2, "SMHBA_GetVendorLibraryAttributes adapterindex:%d",
1N/A adapter_index, 0, 0);
1N/A if (_hbaapi_librarylist == NULL) {
1N/A DEBUG(1, "SMHBAAPI not loaded yet.", 0, 0, 0);
1N/A return (0);
1N/A }
1N/A
1N/A if (attributes == NULL) {
1N/A DEBUG(1, "SMHBA_GetVendorLibraryAttributes: "
1N/A "NULL pointer attributes",
1N/A 0, 0, 0);
1N/A return (HBA_STATUS_ERROR_ARG);
1N/A }
1N/A
1N/A (void) memset(attributes, 0, sizeof (SMHBA_LIBRARYATTRIBUTES));
1N/A
1N/A GRAB_MUTEX(&_hbaapi_LL_mutex);
1N/A GRAB_MUTEX(&_hbaapi_AL_mutex);
1N/A for (adapt_infop = _hbaapi_adapterlist;
1N/A adapt_infop != NULL;
1N/A adapt_infop = adapt_infop->next) {
1N/A
1N/A if (adapt_infop->index == adapter_index) {
1N/A
1N/A if (adapt_infop->library->version != SMHBA) {
1N/A RELEASE_MUTEX(&_hbaapi_AL_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
1N/A HBA_STATUS_ERROR_INCOMPATIBLE);
1N/A }
1N/A
1N/A registeredfunc = adapt_infop->library->
1N/A ftable.smhbafunctionTable.GetVendorLibraryAttributesHandler;
1N/A if (registeredfunc != NULL) {
1N/A ret = (registeredfunc)(attributes);
1N/A#ifdef NOTDEF
1N/A } else {
1N/A /* This should not happen since the VSL is already loaded. */
1N/A#endif
1N/A }
1N/A if (attributes->LibPath[0] == '\0') {
1N/A if (strlen(adapt_infop->library->LibraryPath) < 256) {
1N/A (void) strcpy(attributes->LibPath,
1N/A adapt_infop->library->LibraryPath);
1N/A }
1N/A }
1N/A break;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_AL_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, ret);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetAdapterAttributes(
1N/A HBA_HANDLE handle,
1N/A SMHBA_ADAPTERATTRIBUTES *hbaattributes)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetAdapterAttributesFunc GetAdapterAttributesFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetAdapterAttributesFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetAdapterAttributesHandler;
1N/A if (GetAdapterAttributesFunc != NULL) {
1N/A status = ((GetAdapterAttributesFunc)(vendorHandle, hbaattributes));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetNumberOfPorts(
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 *numberofports)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetNumberOfPortsFunc GetNumberOfPortsFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetNumberOfPortsFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetNumberOfPortsHandler;
1N/A if (GetNumberOfPortsFunc != NULL) {
1N/A status = ((GetNumberOfPortsFunc)(vendorHandle, numberofports));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetPortType(
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_PORTTYPE *porttype)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetPortTypeFunc GetPortTypeFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetPortTypeFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetPortTypeHandler;
1N/A if (GetPortTypeFunc != NULL) {
1N/A status = ((GetPortTypeFunc)(vendorHandle, portindex, porttype));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetAdapterPortAttributes(
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A SMHBA_PORTATTRIBUTES *portattributes)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetAdapterPortAttributesFunc
1N/A GetAdapterPortAttributesFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetAdapterPortAttributes", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetAdapterPortAttributesFunc =
1N/A lib_infop->ftable.smhbafunctionTable.\
1N/A GetAdapterPortAttributesHandler;
1N/A if (GetAdapterPortAttributesFunc != NULL) {
1N/A status = ((GetAdapterPortAttributesFunc)
1N/A (vendorHandle, portindex, portattributes));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetDiscoveredPortAttributes(
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_UINT32 discoveredportindex,
1N/A SMHBA_PORTATTRIBUTES *portattributes)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetDiscoveredPortAttributesFunc
1N/A GetDiscoveredPortAttributesFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetDiscoveredPortAttributes", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetDiscoveredPortAttributesFunc =
1N/A lib_infop->ftable.smhbafunctionTable.\
1N/A GetDiscoveredPortAttributesHandler;
1N/A if (GetDiscoveredPortAttributesFunc != NULL) {
1N/A status = ((GetDiscoveredPortAttributesFunc)
1N/A (vendorHandle, portindex, discoveredportindex,
1N/A portattributes));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetPortAttributesByWWN(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN portWWN,
1N/A HBA_WWN domainPortWWN,
1N/A SMHBA_PORTATTRIBUTES *portattributes)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetPortAttributesByWWNFunc
1N/A GetPortAttributesByWWNFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetPortAttributesByWWN: %s", WWN2STR1(&portWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetPortAttributesByWWNFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetPortAttributesByWWNHandler;
1N/A if (GetPortAttributesByWWNFunc != NULL) {
1N/A status = ((GetPortAttributesByWWNFunc)
1N/A (vendorHandle, portWWN, domainPortWWN, portattributes));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetFCPhyAttributes(
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_UINT32 phyindex,
1N/A SMHBA_FC_PHY *phytype)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetFCPhyAttributesFunc GetFCPhyAttributesFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetFCPhyAttributesByWWN", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetFCPhyAttributesFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetFCPhyAttributesHandler;
1N/A if (GetFCPhyAttributesFunc != NULL) {
1N/A status = ((GetFCPhyAttributesFunc)
1N/A (vendorHandle, portindex, phyindex, phytype));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetSASPhyAttributes(
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_UINT32 phyindex,
1N/A SMHBA_SAS_PHY *phytype)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetSASPhyAttributesFunc GetSASPhyAttributesFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetFCPhyAttributesByWWN", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetSASPhyAttributesFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetSASPhyAttributesHandler;
1N/A if (GetSASPhyAttributesFunc != NULL) {
1N/A status = ((GetSASPhyAttributesFunc)
1N/A (vendorHandle, portindex, phyindex, phytype));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetProtocolStatistics(
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_UINT32 protocoltype,
1N/A SMHBA_PROTOCOLSTATISTICS *pProtocolStatistics)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetProtocolStatisticsFunc
1N/A GetProtocolStatisticsFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetProtocolStatistics port index: %d protocol type: %d",
1N/A portindex, protocoltype, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetProtocolStatisticsFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetProtocolStatisticsHandler;
1N/A if (GetProtocolStatisticsFunc != NULL) {
1N/A status = (GetProtocolStatisticsFunc)
1N/A (vendorHandle, portindex, protocoltype, pProtocolStatistics);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetPhyStatistics(
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_UINT32 phyindex,
1N/A SMHBA_PHYSTATISTICS *pPhyStatistics)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetPhyStatisticsFunc
1N/A GetPhyStatisticsFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetPhyStatistics port index: %d phy idex: %d",
1N/A portindex, phyindex, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetPhyStatisticsFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetPhyStatisticsHandler;
1N/A if (GetPhyStatisticsFunc != NULL) {
1N/A status = (GetPhyStatisticsFunc)
1N/A (vendorHandle, portindex, phyindex, pPhyStatistics);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetBindingCapability(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A SMHBA_BIND_CAPABILITY *pFlags)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetBindingCapabilityFunc GetBindingCapabilityFunc;
1N/A
1N/A DEBUG(2, "HBA_GetBindingCapability", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetBindingCapabilityFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetBindingCapabilityHandler;
1N/A if (GetBindingCapabilityFunc != NULL) {
1N/A status = (GetBindingCapabilityFunc)(vendorHandle, hbaPortWWN,
1N/A domainPortWWN, pFlags);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetBindingSupport(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A SMHBA_BIND_CAPABILITY *pFlags)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetBindingSupportFunc
1N/A GetBindingSupporFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetBindingSupport port: %s",
1N/A WWN2STR1(&hbaPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetBindingSupporFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetBindingSupportHandler;
1N/A if (GetBindingSupporFunc != NULL) {
1N/A status = (GetBindingSupporFunc)(vendorHandle,
1N/A hbaPortWWN, domainPortWWN, pFlags);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_SetBindingSupport(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A SMHBA_BIND_CAPABILITY flags)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBASetBindingSupportFunc
1N/A SetBindingSupporFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetBindingSupport port: %s",
1N/A WWN2STR1(&hbaPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(HBAAPIV2);
1N/A
1N/A SetBindingSupporFunc =
1N/A lib_infop->ftable.smhbafunctionTable.SetBindingSupportHandler;
1N/A if (SetBindingSupporFunc != NULL) {
1N/A status = (SetBindingSupporFunc)
1N/A (vendorHandle, hbaPortWWN, domainPortWWN, flags);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetTargetMapping(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A SMHBA_TARGETMAPPING *pMapping)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetTargetMappingFunc GetTargetMappingFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetTargetMapping port WWN: %s",
1N/A WWN2STR1(&hbaPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetTargetMappingFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetTargetMappingHandler;
1N/A if (GetTargetMappingFunc != NULL) {
1N/A status = ((GetTargetMappingFunc)(vendorHandle,
1N/A hbaPortWWN, domainPortWWN, pMapping));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetPersistentBinding(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A SMHBA_BINDING *binding)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetPersistentBindingFunc
1N/A GetPersistentBindingFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetPersistentBinding port WWN: %s",
1N/A WWN2STR1(&hbaPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetPersistentBindingFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetPersistentBindingHandler;
1N/A if (GetPersistentBindingFunc != NULL) {
1N/A status = ((GetPersistentBindingFunc)(vendorHandle,
1N/A hbaPortWWN, domainPortWWN, binding));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_SetPersistentBinding(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A const SMHBA_BINDING *binding)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBASetPersistentBindingFunc
1N/A SetPersistentBindingFunc;
1N/A
1N/A DEBUG(2, "SMHBA_SetPersistentBinding port WWN: %s",
1N/A WWN2STR1(&hbaPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A SetPersistentBindingFunc =
1N/A lib_infop->ftable.smhbafunctionTable.SetPersistentBindingHandler;
1N/A if (SetPersistentBindingFunc != NULL) {
1N/A status = ((SetPersistentBindingFunc)(vendorHandle,
1N/A hbaPortWWN, domainPortWWN, binding));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_RemovePersistentBinding(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A const SMHBA_BINDING *binding)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBARemovePersistentBindingFunc
1N/A RemovePersistentBindingFunc;
1N/A
1N/A DEBUG(2, "SMHBA_RemovePersistentBinding port WWN: %s",
1N/A WWN2STR1(&hbaPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A RemovePersistentBindingFunc =
1N/A lib_infop->ftable.smhbafunctionTable.RemovePersistentBindingHandler;
1N/A if (RemovePersistentBindingFunc != NULL) {
1N/A status = ((RemovePersistentBindingFunc)(vendorHandle,
1N/A hbaPortWWN, domainPortWWN, binding));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_RemoveAllPersistentBindings(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN domainPortWWN)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBARemoveAllPersistentBindingsFunc
1N/A RemoveAllPersistentBindingsFunc;
1N/A
1N/A DEBUG(2, "SMHBA_RemoveAllPersistentBinding port WWN: %s",
1N/A WWN2STR1(&hbaPortWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A RemoveAllPersistentBindingsFunc =
1N/A lib_infop->ftable.smhbafunctionTable.\
1N/A RemoveAllPersistentBindingsHandler;
1N/A if (RemoveAllPersistentBindingsFunc != NULL) {
1N/A status = ((RemoveAllPersistentBindingsFunc)(vendorHandle,
1N/A hbaPortWWN, domainPortWWN));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_GetLUNStatistics(
1N/A HBA_HANDLE handle,
1N/A const HBA_SCSIID *lunit,
1N/A SMHBA_PROTOCOLSTATISTICS *statistics)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAGetLUNStatisticsFunc GetLUNStatisticsFunc;
1N/A
1N/A DEBUG(2, "SMHBA_GetLUNStatistics", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A GetLUNStatisticsFunc =
1N/A lib_infop->ftable.smhbafunctionTable.GetLUNStatisticsHandler;
1N/A if (GetLUNStatisticsFunc != NULL) {
1N/A status = ((GetLUNStatisticsFunc)(vendorHandle, lunit, statistics));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_ScsiInquiry(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN discoveredPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A SMHBA_SCSILUN smhbaLUN,
1N/A HBA_UINT8 CDB_Byte1,
1N/A HBA_UINT8 CDB_Byte2,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize,
1N/A HBA_UINT8 *pScsiStatus,
1N/A void *pSenseBuffer,
1N/A HBA_UINT32 *pSenseBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAScsiInquiryFunc ScsiInquiryFunc;
1N/A
1N/A DEBUG(2, "SMHBA_ScsiInquiry to hba port: %s discoveredPortWWN: %s",
1N/A WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A ScsiInquiryFunc =
1N/A lib_infop->ftable.smhbafunctionTable.ScsiInquiryHandler;
1N/A if (ScsiInquiryFunc != NULL) {
1N/A status = ((ScsiInquiryFunc)(
1N/A vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN,
1N/A smhbaLUN, CDB_Byte1, CDB_Byte2, pRspBuffer, pRspBufferSize,
1N/A pScsiStatus, pSenseBuffer, pSenseBufferSize));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_ScsiReportLUNs(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN discoveredPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize,
1N/A HBA_UINT8 *pScsiStatus,
1N/A void *pSenseBuffer,
1N/A HBA_UINT32 *pSenseBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAScsiReportLUNsFunc ScsiReportLUNsFunc;
1N/A
1N/A DEBUG(2, "SMHBA_ScsiReportLuns to hba port: %s discoveredPortWWN: %s",
1N/A WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A ScsiReportLUNsFunc =
1N/A lib_infop->ftable.smhbafunctionTable.ScsiReportLUNsHandler;
1N/A if (ScsiReportLUNsFunc != NULL) {
1N/A status = ((ScsiReportLUNsFunc)(
1N/A vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN,
1N/A pRspBuffer, pRspBufferSize, pScsiStatus, pSenseBuffer,
1N/A pSenseBufferSize));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_ScsiReadCapacity(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN discoveredPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A SMHBA_SCSILUN smhbaLUN,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize,
1N/A HBA_UINT8 *pScsiStatus,
1N/A void *pSenseBuffer,
1N/A HBA_UINT32 *pSenseBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBAScsiReadCapacityFunc ScsiReadCapacityFunc;
1N/A
1N/A DEBUG(2, "SMHBA_ScsiReadCapacity to hba port: %s discoveredPortWWN: %s",
1N/A WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A ScsiReadCapacityFunc =
1N/A lib_infop->ftable.smhbafunctionTable.ScsiReadCapacityHandler;
1N/A if (ScsiReadCapacityFunc != NULL) {
1N/A status = ((ScsiReadCapacityFunc)(
1N/A vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN,
1N/A smhbaLUN, pRspBuffer, pRspBufferSize, pScsiStatus, pSenseBuffer,
1N/A pSenseBufferSize));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_SendTEST(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN destWWN,
1N/A HBA_UINT32 destFCID,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 pRspBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBASendTESTFunc SendTESTFunc;
1N/A
1N/A DEBUG(2, "SMHBA_SendTEST, hbaPortWWN: %s destWWN",
1N/A WWN2STR1(&hbaPortWWN),
1N/A WWN2STR1(&destWWN), 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A SendTESTFunc = lib_infop->ftable.smhbafunctionTable.SendTESTHandler;
1N/A if (SendTESTFunc != NULL) {
1N/A status = (SendTESTFunc)
1N/A (vendorHandle, hbaPortWWN, destWWN, destFCID,
1N/A pRspBuffer, pRspBufferSize);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_SendECHO(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN destWWN,
1N/A HBA_UINT32 destFCID,
1N/A void *pReqBuffer,
1N/A HBA_UINT32 ReqBufferSize,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBASendECHOFunc SendECHOFunc;
1N/A
1N/A DEBUG(2, "SMHBA_SendECHO, hbaPortWWN: %s destWWN",
1N/A WWN2STR1(&hbaPortWWN), WWN2STR1(&destWWN), 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A SendECHOFunc = lib_infop->ftable.smhbafunctionTable.SendECHOHandler;
1N/A if (SendECHOFunc != NULL) {
1N/A status = (SendECHOFunc)
1N/A (vendorHandle, hbaPortWWN, destWWN, destFCID,
1N/A pReqBuffer, ReqBufferSize, pRspBuffer, pRspBufferSize);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_SendSMPPassThru(
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN destWWN,
1N/A HBA_WWN domainPortWWN,
1N/A void *pReqBuffer,
1N/A HBA_UINT32 ReqBufferSize,
1N/A void *pRspBuffer,
1N/A HBA_UINT32 *pRspBufferSize)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A SMHBASendSMPPassThruFunc SendSMPPassThruFunc;
1N/A
1N/A DEBUG(2, "SMHBA_SendSMPPassThru, hbaPortWWN: %s destWWN: %s",
1N/A WWN2STR1(&hbaPortWWN), WWN2STR1(&destWWN), 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A SendSMPPassThruFunc = lib_infop->ftable.\
1N/A smhbafunctionTable.SendSMPPassThruHandler;
1N/A
1N/A if (SendSMPPassThruFunc != NULL) {
1N/A status = (SendSMPPassThruFunc)
1N/A (vendorHandle, hbaPortWWN, destWWN, domainPortWWN,
1N/A pReqBuffer, ReqBufferSize, pRspBuffer, pRspBufferSize);
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/A/*
1N/A * Following the similar logic of HBAAPI addaspterevents_callback.
1N/A *
1N/A * Unlike other events Adapter Add Event is not limited to a specific
1N/A * adpater(i.e. no adatper handle is passed for registration) so
1N/A * the event should be passed to all registrants. The routine below
1N/A * is passed to the VSLs as a callback and when Adapter Add event is detected
1N/A * by VSL it will call smhba_adapteraddevents_callback() which in turn check
1N/A * if the passed userdata ptr matches with the one stored in the callback list
1N/A * and calls the stored callback.
1N/A *
1N/A * For the situation that multiple clients are registered for Adapter Add event
1N/A * each registration is passed to VSLs so VSL may call
1N/A * smhba_adapteraddevents_callback() multiple times or it may call only once
1N/A * since the callback function is same. For this implemneation, the userdata
1N/A * is stored in HBA_ALLADAPTERSCALLBACK_ELEM so it is expected that VSL call
1N/A * smhba_adapteraddevents_callback() only once and
1N/A * smhba_adapteraddevents_callback() will call the client callback with proper
1N/A * userdata.
1N/A */
1N/Astatic void
1N/Asmhba_adapteraddevents_callback(
1N/A/* LINTED E_FUNC_ARG_UNUSED */
1N/A void *data,
1N/A HBA_WWN PortWWN,
1N/A/* LINTED E_FUNC_ARG_UNUSED */
1N/A HBA_UINT32 eventType)
1N/A{
1N/A HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
1N/A
1N/A DEBUG(3, "AddAdapterEvent, port:%s", WWN2STR1(&PortWWN), 0, 0);
1N/A
1N/A GRAB_MUTEX(&_smhba_AAE_mutex);
1N/A for (cbp = _smhba_adapteraddevents_callback_list;
1N/A cbp != NULL;
1N/A cbp = cbp->next) {
1N/A (*cbp->callback)(cbp->userdata, PortWWN, HBA_EVENT_ADAPTER_ADD);
1N/A }
1N/A RELEASE_MUTEX(&_smhba_AAE_mutex);
1N/A
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_RegisterForAdapterAddEvents(
1N/A void (*pCallback) (
1N/A void *data,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType),
1N/A void *pUserData,
1N/A HBA_CALLBACKHANDLE *pCallbackHandle) {
1N/A
1N/A HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
1N/A HBA_VENDORCALLBACK_ELEM *vcbp;
1N/A HBA_VENDORCALLBACK_ELEM *vendorhandlelist;
1N/A SMHBARegisterForAdapterAddEventsFunc registeredfunc;
1N/A HBA_STATUS status = HBA_STATUS_OK;
1N/A HBA_STATUS failure = HBA_STATUS_OK;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A int registered_cnt = 0;
1N/A int vendor_cnt = 0;
1N/A int not_supported_cnt = 0;
1N/A int status_OK_bar_cnt = 0;
1N/A int status_OK_cnt = 0;
1N/A
1N/A DEBUG(2, "SMHBA_RegisterForAdapterAddEvents", 0, 0, 0);
1N/A ARE_WE_INITED();
1N/A
1N/A cbp = (HBA_ALLADAPTERSCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_ALLADAPTERSCALLBACK_ELEM));
1N/A *pCallbackHandle = (HBA_CALLBACKHANDLE) cbp;
1N/A if (cbp == NULL) {
1N/A return (HBA_STATUS_ERROR);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_hbaapi_LL_mutex);
1N/A GRAB_MUTEX(&_smhba_AAE_mutex);
1N/A cbp->callback = pCallback;
1N/A cbp->userdata = pUserData;
1N/A cbp->next = _smhba_adapteraddevents_callback_list;
1N/A _smhba_adapteraddevents_callback_list = cbp;
1N/A
1N/A /*
1N/A * Need to release the mutex now incase the vendor function invokes the
1N/A * callback. We will grap the mutex later to attach the vendor handle
1N/A * list to the callback structure
1N/A */
1N/A RELEASE_MUTEX(&_smhba_AAE_mutex);
1N/A
1N/A
1N/A /*
1N/A * now create a list of vendors (vendor libraryies, NOT ADAPTERS)
1N/A * that have successfully registerred
1N/A */
1N/A vendorhandlelist = NULL;
1N/A for (lib_infop = _hbaapi_librarylist;
1N/A lib_infop != NULL;
1N/A lib_infop = lib_infop->next) {
1N/A
1N/A /* only for HBAAPI V2 */
1N/A if (lib_infop->version != SMHBA) {
1N/A continue;
1N/A } else {
1N/A vendor_cnt++;
1N/A }
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.smhbafunctionTable.\
1N/A RegisterForAdapterAddEventsHandler;
1N/A if (registeredfunc == NULL) {
1N/A continue;
1N/A }
1N/A
1N/A vcbp = (HBA_VENDORCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_VENDORCALLBACK_ELEM));
1N/A if (vcbp == NULL) {
1N/A freevendorhandlelist(vendorhandlelist);
1N/A status = HBA_STATUS_ERROR;
1N/A break;
1N/A }
1N/A
1N/A registered_cnt++;
1N/A status = (registeredfunc)(smhba_adapteraddevents_callback,
1N/A pUserData, &vcbp->vendorcbhandle);
1N/A if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
1N/A not_supported_cnt++;
1N/A free(vcbp);
1N/A continue;
1N/A } else if (status != HBA_STATUS_OK) {
1N/A status_OK_bar_cnt++;
1N/A DEBUG(1,
1N/A "SMHBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
1N/A lib_infop->LibraryPath, status, 0);
1N/A failure = status;
1N/A free(vcbp);
1N/A continue;
1N/A } else {
1N/A status_OK_cnt++;
1N/A }
1N/A vcbp->lib_info = lib_infop;
1N/A vcbp->next = vendorhandlelist;
1N/A vendorhandlelist = vcbp;
1N/A }
1N/A
1N/A if (vendor_cnt == 0) {
1N/A /* no SMHBA VSL found. Should be okay?? */
1N/A status = HBA_STATUS_ERROR;
1N/A } else if (registered_cnt == 0) {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A freevendorhandlelist(vendorhandlelist);
1N/A (void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
1N/A } else if (status_OK_cnt == 0 && not_supported_cnt != 0) {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A } else if (status_OK_cnt == 0) {
1N/A /*
1N/A * At least one vendor library registered this function, but no
1N/A * vendor call succeeded
1N/A */
1N/A (void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
1N/A status = failure;
1N/A } else {
1N/A /* we have had atleast some success, now finish up */
1N/A GRAB_MUTEX(&_smhba_AAE_mutex);
1N/A /*
1N/A * this seems silly, but what if another thread called
1N/A * the callback remove
1N/A */
1N/A for (cbp = _smhba_adapteraddevents_callback_list;
1N/A cbp != NULL; cbp = cbp->next) {
1N/A if ((HBA_CALLBACKHANDLE)cbp == *pCallbackHandle) {
1N/A /* yup, its still there, hooray */
1N/A cbp->vendorhandlelist = vendorhandlelist;
1N/A vendorhandlelist = NULL;
1N/A break;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_smhba_AAE_mutex);
1N/A if (vendorhandlelist != NULL) {
1N/A /*
1N/A * bummer, somebody removed the callback before we finished
1N/A * registration, probably will never happen
1N/A */
1N/A freevendorhandlelist(vendorhandlelist);
1N/A DEBUG(1,
1N/A "HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was "
1N/A "called for a handle before registration was finished.",
1N/A 0, 0, 0);
1N/A status = HBA_STATUS_ERROR;
1N/A } else {
1N/A status = HBA_STATUS_OK;
1N/A }
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/A/* SMHBA Adapter Events (other than add) ******************************** */
1N/Astatic void
1N/Asmhba_adapterevents_callback(void *data,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType)
1N/A{
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A
1N/A DEBUG(3, "AdapterEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN),
1N/A eventType, 0);
1N/A
1N/A GRAB_MUTEX(&_hbaapi_AE_mutex);
1N/A for (acbp = _smhba_adapterevents_callback_list;
1N/A acbp != NULL;
1N/A acbp = acbp->next) {
1N/A if (data == (void *)acbp) {
1N/A (*acbp->callback)(acbp->userdata, PortWWN, eventType);
1N/A break;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_AE_mutex);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_RegisterForAdapterEvents(
1N/A void (*pCallback) (
1N/A void *data,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType),
1N/A void *pUserData,
1N/A HBA_HANDLE handle,
1N/A HBA_CALLBACKHANDLE *pCallbackHandle) {
1N/A
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A SMHBARegisterForAdapterEventsFunc registeredfunc;
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A
1N/A DEBUG(2, "SMHBA_RegisterForAdapterEvents", 0, 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A
1N/A /* we now have the _hbaapi_LL_mutex */
1N/A
1N/A registeredfunc = lib_infop->ftable.smhbafunctionTable.\
1N/A RegisterForAdapterEventsHandler;
1N/A if (registeredfunc == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1N/A }
1N/A
1N/A /*
1N/A * that allocated memory is used both as the handle for the
1N/A * caller, and as userdata to the vendor call so that on
1N/A * callback the specific registration may be recalled
1N/A */
1N/A acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1N/A if (acbp == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1N/A }
1N/A *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
1N/A acbp->callback = pCallback;
1N/A acbp->userdata = pUserData;
1N/A acbp->lib_info = lib_infop;
1N/A
1N/A status = (registeredfunc)(smhba_adapterevents_callback,
1N/A (void *)acbp,
1N/A vendorHandle,
1N/A &acbp->vendorcbhandle);
1N/A if (status != HBA_STATUS_OK) {
1N/A free(acbp);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_smhba_AE_mutex);
1N/A acbp->next = _smhba_adapterevents_callback_list;
1N/A _hbaapi_adapterevents_callback_list = acbp;
1N/A
1N/A RELEASE_MUTEX(&_smhba_AE_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1N/A}
1N/A
1N/A/* Adapter Port Events *********************************************** */
1N/Astatic void
1N/Asmhba_adapterportevents_callback(void *data,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType,
1N/A HBA_UINT32 fabricPortID)
1N/A{
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A
1N/A DEBUG(3,
1N/A "SMHBA_AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x",
1N/A WWN2STR1(&PortWWN), eventType, fabricPortID);
1N/A
1N/A GRAB_MUTEX(&_smhba_APE_mutex);
1N/A
1N/A for (acbp = _smhba_adapterportevents_callback_list;
1N/A acbp != NULL;
1N/A acbp = acbp->next) {
1N/A if (data == (void *)acbp) {
1N/A (*acbp->callback)(acbp->userdata, PortWWN,
1N/A eventType, fabricPortID);
1N/A break;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_smhba_APE_mutex);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_RegisterForAdapterPortEvents(
1N/A void (*pCallback) (
1N/A void *pData,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType,
1N/A HBA_UINT32 fabricPortID),
1N/A void *pUserData,
1N/A HBA_HANDLE handle,
1N/A HBA_WWN portWWN,
1N/A HBA_UINT32 specificEventType,
1N/A HBA_CALLBACKHANDLE *pCallbackHandle) {
1N/A
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A SMHBARegisterForAdapterPortEventsFunc registeredfunc;
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A
1N/A DEBUG(2, "SMHBA_RegisterForAdapterPortEvents for port: %s",
1N/A WWN2STR1(&portWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A /* we now have the _hbaapi_LL_mutex */
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.smhbafunctionTable.\
1N/A RegisterForAdapterPortEventsHandler;
1N/A if (registeredfunc == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1N/A }
1N/A
1N/A /*
1N/A * that allocated memory is used both as the handle for the
1N/A * caller, and as userdata to the vendor call so that on
1N/A * callback the specific registration may be recalled
1N/A */
1N/A acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1N/A if (acbp == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1N/A }
1N/A *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
1N/A acbp->callback = pCallback;
1N/A acbp->userdata = pUserData;
1N/A acbp->lib_info = lib_infop;
1N/A
1N/A status = (registeredfunc)(smhba_adapterportevents_callback,
1N/A (void *)acbp,
1N/A vendorHandle,
1N/A portWWN,
1N/A specificEventType,
1N/A &acbp->vendorcbhandle);
1N/A if (status != HBA_STATUS_OK) {
1N/A free(acbp);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_smhba_APE_mutex);
1N/A acbp->next = _smhba_adapterportevents_callback_list;
1N/A _smhba_adapterportevents_callback_list = acbp;
1N/A
1N/A RELEASE_MUTEX(&_smhba_APE_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1N/A}
1N/A
1N/A/* SMHBA Adapter Port Stat Events ******************************** */
1N/Astatic void
1N/Asmhba_adapterportstatevents_callback(void *data,
1N/A HBA_WWN portWWN,
1N/A HBA_UINT32 protocolType,
1N/A HBA_UINT32 eventType)
1N/A{
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A
1N/A DEBUG(3,
1N/A "SMBA_AdapterPortStateEvent, port:%s, eventType:%d",
1N/A WWN2STR1(&portWWN), eventType, 0);
1N/A
1N/A GRAB_MUTEX(&_smhba_APSE_mutex);
1N/A for (acbp = _smhba_adapterportstatevents_callback_list;
1N/A acbp != NULL;
1N/A acbp = acbp->next) {
1N/A if (data == (void *)acbp) {
1N/A (*acbp->callback)(acbp->userdata, portWWN,
1N/A protocolType, eventType);
1N/A return;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_smhba_APSE_mutex);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_RegisterForAdapterPortStatEvents(
1N/A void (*pCallback) (
1N/A void *pData,
1N/A HBA_WWN portWWN,
1N/A HBA_UINT32 protocolType,
1N/A HBA_UINT32 eventType),
1N/A void *pUserData,
1N/A HBA_HANDLE handle,
1N/A HBA_WWN portWWN,
1N/A HBA_UINT32 protocolType,
1N/A SMHBA_PROTOCOLSTATISTICS stats,
1N/A HBA_UINT32 statType,
1N/A HBA_CALLBACKHANDLE *pCallbackHandle) {
1N/A
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A SMHBARegisterForAdapterPortStatEventsFunc
1N/A registeredfunc;
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A
1N/A DEBUG(2, "SMHBA_RegisterForAdapterPortStatEvents for port: %s",
1N/A WWN2STR1(&portWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A /* we now have the _hbaapi_LL_mutex */
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.smhbafunctionTable.\
1N/A RegisterForAdapterPortStatEventsHandler;
1N/A if (registeredfunc == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1N/A }
1N/A
1N/A /*
1N/A * that allocated memory is used both as the handle for the
1N/A * caller, and as userdata to the vendor call so that on
1N/A * callback the specific registration may be recalled
1N/A */
1N/A acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1N/A if (acbp == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1N/A }
1N/A *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
1N/A acbp->callback = pCallback;
1N/A acbp->userdata = pUserData;
1N/A acbp->lib_info = lib_infop;
1N/A
1N/A status = (registeredfunc)(smhba_adapterportstatevents_callback,
1N/A (void *)acbp,
1N/A vendorHandle,
1N/A portWWN,
1N/A protocolType,
1N/A stats,
1N/A statType,
1N/A &acbp->vendorcbhandle);
1N/A if (status != HBA_STATUS_OK) {
1N/A free(acbp);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_smhba_APSE_mutex);
1N/A acbp->next = _smhba_adapterportstatevents_callback_list;
1N/A _smhba_adapterportstatevents_callback_list = acbp;
1N/A
1N/A RELEASE_MUTEX(&_smhba_APSE_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1N/A}
1N/A
1N/A/* SMHBA Adapter Port Phy Stat Events ************************************ */
1N/Astatic void
1N/Asmhba_adapterphystatevents_callback(void *data,
1N/A HBA_WWN portWWN,
1N/A HBA_UINT32 phyIndex,
1N/A HBA_UINT32 eventType)
1N/A{
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A
1N/A DEBUG(3,
1N/A "SMBA_AdapterPortStateEvent, port:%s, eventType:%d",
1N/A WWN2STR1(&portWWN), eventType, 0);
1N/A
1N/A GRAB_MUTEX(&_smhba_APHYSE_mutex);
1N/A for (acbp = _smhba_adapterphystatevents_callback_list;
1N/A acbp != NULL;
1N/A acbp = acbp->next) {
1N/A if (data == (void *)acbp) {
1N/A (*acbp->callback)(acbp->userdata, portWWN, phyIndex, eventType);
1N/A return;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_smhba_APHYSE_mutex);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_RegisterForAdapterPhyStatEvents(
1N/A void (*pCallback) (
1N/A void *pData,
1N/A HBA_WWN portWWN,
1N/A HBA_UINT32 phyIndex,
1N/A HBA_UINT32 eventType),
1N/A void *pUserData,
1N/A HBA_HANDLE handle,
1N/A HBA_WWN portWWN,
1N/A HBA_UINT32 phyIndex,
1N/A SMHBA_PHYSTATISTICS stats,
1N/A HBA_UINT32 statType,
1N/A HBA_CALLBACKHANDLE *pCallbackHandle) {
1N/A
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A SMHBARegisterForAdapterPhyStatEventsFunc
1N/A registeredfunc;
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A
1N/A DEBUG(2, "SMHBA_RegisterForAdapterPhyStatEvents for port: %s",
1N/A WWN2STR1(&portWWN), 0, 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A /* we now have the _hbaapi_LL_mutex */
1N/A
1N/A registeredfunc =
1N/A lib_infop->ftable.smhbafunctionTable.\
1N/A RegisterForAdapterPhyStatEventsHandler;
1N/A if (registeredfunc == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1N/A }
1N/A
1N/A /*
1N/A * that allocated memory is used both as the handle for the
1N/A * caller, and as userdata to the vendor call so that on
1N/A * callback the specific registration may be recalled
1N/A */
1N/A acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1N/A if (acbp == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1N/A }
1N/A *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
1N/A acbp->callback = pCallback;
1N/A acbp->userdata = pUserData;
1N/A acbp->lib_info = lib_infop;
1N/A
1N/A status = (registeredfunc)(smhba_adapterphystatevents_callback,
1N/A (void *)acbp,
1N/A vendorHandle,
1N/A portWWN,
1N/A phyIndex,
1N/A stats,
1N/A statType,
1N/A &acbp->vendorcbhandle);
1N/A if (status != HBA_STATUS_OK) {
1N/A free(acbp);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_smhba_APHYSE_mutex);
1N/A acbp->next = _smhba_adapterphystatevents_callback_list;
1N/A _smhba_adapterphystatevents_callback_list = acbp;
1N/A
1N/A RELEASE_MUTEX(&_smhba_APHYSE_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1N/A}
1N/A
1N/A/* SMHBA Target Events ********************************************* */
1N/Astatic void
1N/Asmhba_targetevents_callback(void *data,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN discoveredPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A HBA_UINT32 eventType)
1N/A{
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A
1N/A DEBUG(3, "TargetEvent, hbaPort:%s, discoveredPort:%s eventType:%d",
1N/A WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), eventType);
1N/A
1N/A GRAB_MUTEX(&_smhba_TE_mutex);
1N/A for (acbp = _smhba_targetevents_callback_list;
1N/A acbp != NULL;
1N/A acbp = acbp->next) {
1N/A if (data == (void *)acbp) {
1N/A (*acbp->callback)(acbp->userdata, hbaPortWWN,
1N/A discoveredPortWWN, domainPortWWN, eventType);
1N/A break;
1N/A }
1N/A }
1N/A RELEASE_MUTEX(&_smhba_TE_mutex);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASMHBA_RegisterForTargetEvents(
1N/A void (*pCallback) (
1N/A void *pData,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN discoveredPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A HBA_UINT32 eventType),
1N/A void *pUserData,
1N/A HBA_HANDLE handle,
1N/A HBA_WWN hbaPortWWN,
1N/A HBA_WWN discoveredPortWWN,
1N/A HBA_WWN domainPortWWN,
1N/A HBA_CALLBACKHANDLE *pCallbackHandle,
1N/A HBA_UINT32 allTargets) {
1N/A
1N/A HBA_ADAPTERCALLBACK_ELEM *acbp;
1N/A SMHBARegisterForTargetEventsFunc
1N/A registeredfunc;
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A
1N/A DEBUG(2, "SMHBA_RegisterForTargetEvents, hbaPort:"
1N/A "%s, discoveredPort: %s",
1N/A WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), 0);
1N/A
1N/A CHECKLIBRARYANDVERSION(SMHBA);
1N/A /* we now have the _hbaapi_LL_mutex */
1N/A
1N/A registeredfunc = lib_infop->ftable.smhbafunctionTable.\
1N/A RegisterForTargetEventsHandler;
1N/A
1N/A if (registeredfunc == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1N/A }
1N/A
1N/A /*
1N/A * that allocated memory is used both as the handle for the
1N/A * caller, and as userdata to the vendor call so that on
1N/A * callback the specific registration may be recalled
1N/A */
1N/A acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1N/A calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1N/A if (acbp == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1N/A }
1N/A *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
1N/A acbp->callback = pCallback;
1N/A acbp->userdata = pUserData;
1N/A acbp->lib_info = lib_infop;
1N/A
1N/A status = (registeredfunc)(smhba_targetevents_callback,
1N/A (void *)acbp,
1N/A vendorHandle,
1N/A hbaPortWWN,
1N/A discoveredPortWWN,
1N/A domainPortWWN,
1N/A &acbp->vendorcbhandle,
1N/A allTargets);
1N/A if (status != HBA_STATUS_OK) {
1N/A free(acbp);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A }
1N/A
1N/A GRAB_MUTEX(&_smhba_TE_mutex);
1N/A acbp->next = _smhba_targetevents_callback_list;
1N/A _smhba_targetevents_callback_list = acbp;
1N/A
1N/A RELEASE_MUTEX(&_smhba_TE_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1N/A}