1N/A/*************************************************************************
1N/A * Description
1N/A * HBAAPILIB-sun.c - Implements the Sun Extention for Target mode
1N/A * FCHBA discovery
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 *************************************************************************
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 <dlfcn.h>
1N/A#include "hbaapi.h"
1N/A#include "hbaapi-sun.h"
1N/A#include "vendorhbaapi.h"
1N/A#include <stdlib.h>
1N/A#ifdef USESYSLOG
1N/A#include <syslog.h>
1N/A#endif
1N/A
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/Aextern int _hbaapi_debuglevel;
1N/A#define DEBUG(L, STR, A1, A2, A3)
1N/A
1N/A#if defined(USESYSLOG) && defined(USELOGFILE)
1N/Aextern FILE *_hbaapi_debug_fd;
1N/Aextern int _hbaapi_sysloginit;
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_INFO, (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 * HBA_LIBRARY_STATUS and HBA_LIBRARY_INFO are redefined here.
1N/A * Avoid any change in the common code.
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 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 HBA_ENTRYPOINTSV2 functionTable; /* Function pointers */
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); \
1N/A }
1N/A
1N/Aextern HBA_LIBRARY_INFO *_hbaapi_librarylist;
1N/Aextern HBA_UINT32 _hbaapi_total_library_count;
1N/A#ifdef POSIX_THREADS
1N/Aextern pthread_mutex_t _hbaapi_LL_mutex;
1N/A#elif defined(WIN32)
1N/Aextern CRITICAL_SECTION _hbaapi_LL_mutex;
1N/A#endif
1N/A
1N/A/*
1N/A * Function type def fop Sun extentions.
1N/A */
1N/Atypedef HBA_UINT32 (* Sun_HBAGetNumberOfTgtAdaptersFunc)();
1N/Atypedef HBA_STATUS (* Sun_HBAGetTgtAdapterNameFunc)(HBA_UINT32, char *);
1N/Atypedef HBA_HANDLE (* Sun_HBAOpenTgtAdapterFunc)(char *);
1N/Atypedef HBA_STATUS (* Sun_HBAOpenTgtAdapterByWWNFunc)
1N/A (HBA_HANDLE *, HBA_WWN);
1N/Atypedef HBA_STATUS (* Sun_HBANPIVGetAdapterAttributesFunc)
1N/A (HBA_HANDLE, HBA_ADAPTERATTRIBUTES *);
1N/Atypedef HBA_STATUS (* Sun_HBAGetNPIVPortInfoFunc)
1N/A (HBA_HANDLE, HBA_UINT32, HBA_UINT32, HBA_NPIVATTRIBUTES *);
1N/Atypedef HBA_STATUS (* Sun_HBADeleteNPIVPortFunc)
1N/A (HBA_HANDLE, HBA_UINT32, HBA_WWN);
1N/Atypedef HBA_STATUS (* Sun_HBACreateNPIVPortFunc)
1N/A (HBA_HANDLE, HBA_UINT32, HBA_WWN, HBA_WWN, HBA_UINT32 *);
1N/Atypedef HBA_STATUS (* Sun_HBAAdapterReturnWWNFunc)
1N/A (HBA_HANDLE, HBA_UINT32, HBA_WWN *, HBA_WWN *);
1N/Atypedef HBA_STATUS (* Sun_HBAAdapterCreateWWNFunc)
1N/A (HBA_HANDLE, HBA_UINT32, HBA_WWN *, HBA_WWN *, HBA_WWN *,
1N/A HBA_INT32);
1N/Atypedef HBA_STATUS (* Sun_HBAGetPortNPIVAttributesFunc)
1N/A (HBA_HANDLE, HBA_UINT32, HBA_PORTNPIVATTRIBUTES *);
1N/Atypedef HBA_STATUS (* Sun_HBARegisterForAdapterDeviceEventsFunc)
1N/A (void (*)(void *, HBA_WWN, HBA_UINT32, HBA_UINT32),
1N/A void *, HBA_HANDLE, HBA_WWN, HBA_CALLBACKHANDLE *);
1N/Atypedef HBA_STATUS (* Sun_HBADoForceLipFunc)(HBA_HANDLE, int *);
1N/A
1N/A/*
1N/A * Individual adapter (hba) information
1N/A * Same as hbaadapter with different structure name.
1N/A */
1N/Atypedef struct hba_tgtadapter_info {
1N/A struct hba_tgtadapter_info
1N/A *next;
1N/A HBA_STATUS GNstatus; /* status from GetTgtAdapterNameFunc */
1N/A char *name;
1N/A HBA_WWN nodeWWN;
1N/A HBA_LIBRARY_INFO *library;
1N/A HBA_UINT32 index;
1N/A} HBA_TGTADAPTER_INFO;
1N/A
1N/A/*
1N/A * Make the list as an array with max size 16
1N/A */
1N/AHBA_TGTADAPTER_INFO *_hbaapi_tgtadapterlist;
1N/AHBA_UINT32 _hbaapi_total_tgtadapter_count = 0;
1N/A#ifdef POSIX_THREADS
1N/Apthread_mutex_t _hbaapi_tgtAL_mutex = PTHREAD_MUTEX_INITIALIZER;
1N/A#elif defined(WIN32)
1N/ACRITICAL_SECTION _hbaapi_tgtAL_mutex;
1N/A#endif
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 int ret;
1N/A if((ret = pthread_mutex_lock(mp)) != 0) {
1N/A perror("pthread_mutex_lock - HBAAPI:");
1N/A DEBUG(0, "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 int ret;
1N/A if((ret = pthread_mutex_unlock(mp)) != 0) {
1N/A perror("pthread_mutex_unlock - HBAAPI:");
1N/A DEBUG(0, "pthread_mutex_unlock returned %d", ret, 0, 0);
1N/A }
1N/A}
1N/A#endif
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/ASun_HBA_GetNumberOfTgtAdapters()
1N/A{
1N/A int j=0;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A Sun_HBAGetNumberOfTgtAdaptersFunc
1N/A GetNumberOfTgtAdaptersFunc = NULL;
1N/A Sun_HBAGetTgtAdapterNameFunc
1N/A GetTgtAdapterNameFunc = NULL;
1N/A HBA_BOOLEAN found_name;
1N/A HBA_TGTADAPTER_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_tgtAL_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 if (lib_infop->hLibrary != NULL) {
1N/A GetNumberOfTgtAdaptersFunc = (Sun_HBAGetNumberOfTgtAdaptersFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcGetNumberOfTgtAdapters");
1N/A GetTgtAdapterNameFunc = (Sun_HBAGetTgtAdapterNameFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcGetTgtAdapterName");
1N/A if (GetNumberOfTgtAdaptersFunc == NULL ||
1N/A GetTgtAdapterNameFunc == NULL) {
1N/A GetNumberOfTgtAdaptersFunc = GetTgtAdapterNameFunc = NULL;
1N/A continue;
1N/A }
1N/A } else {
1N/A continue;
1N/A }
1N/A
1N/A num_adapters = ((GetNumberOfTgtAdaptersFunc)());
1N/A#ifndef WIN32
1N/A DEBUG(1, "HBAAPI: number of target mode adapters for %s = %d\n",
1N/A lib_infop->LibraryName, num_adapters, 0);
1N/A#else
1N/A DEBUG(1, "HBAAPI: number of target mode_adapters for %s = %d\n",
1N/A lib_infop->LibraryPath, num_adapters, 0);
1N/A#endif
1N/A
1N/A for (j = 0; j < num_adapters; j++) {
1N/A found_name = 0;
1N/A status = (GetTgtAdapterNameFunc)(j, (char *)&adaptername);
1N/A if(status == HBA_STATUS_OK) {
1N/A for(adapt_infop = _hbaapi_tgtadapterlist;
1N/A adapt_infop != NULL;
1N/A adapt_infop = adapt_infop->next) {
1N/A /*
1N/A * check for duplicates, really, 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_TGTADAPTER_INFO *)
1N/A calloc(1, sizeof(HBA_TGTADAPTER_INFO));
1N/A if(adapt_infop == NULL) {
1N/A#ifndef WIN32
1N/A fprintf(stderr,
1N/A "HBA_GetNumberOfAdapters: calloc failed on sizeof:%d\n",
1N/A sizeof(HBA_TGTADAPTER_INFO));
1N/A#endif
1N/A RELEASE_MUTEX(&_hbaapi_tgtAL_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
1N/A _hbaapi_total_tgtadapter_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 sprintf(dummyname, "NULLADAPTER-%s-%03d",
1N/A lib_infop->LibraryPath, _hbaapi_total_tgtadapter_count);
1N/A dummyname[255] = '\0';
1N/A adapt_infop->name = strdup(dummyname);
1N/A }
1N/A adapt_infop->library = lib_infop;
1N/A adapt_infop->next = _hbaapi_tgtadapterlist;
1N/A adapt_infop->index = _hbaapi_total_tgtadapter_count;
1N/A _hbaapi_tgtadapterlist = adapt_infop;
1N/A _hbaapi_total_tgtadapter_count++;
1N/A }
1N/A GetNumberOfTgtAdaptersFunc = GetTgtAdapterNameFunc = NULL;
1N/A }
1N/A RELEASE_MUTEX(&_hbaapi_tgtAL_mutex);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, _hbaapi_total_tgtadapter_count);
1N/A}
1N/A
1N/AHBA_STATUS
1N/ASun_HBA_GetTgtAdapterName(
1N/A HBA_UINT32 adapterindex,
1N/A char *adaptername)
1N/A{
1N/A HBA_TGTADAPTER_INFO *adapt_infop;
1N/A HBA_STATUS ret = HBA_STATUS_ERROR_ILLEGAL_INDEX;
1N/A
1N/A if (adaptername == NULL) {
1N/A return(HBA_STATUS_ERROR_ARG);
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_tgtAL_mutex);
1N/A *adaptername = '\0';
1N/A for(adapt_infop = _hbaapi_tgtadapterlist;
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 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", adapterindex, adaptername, 0);
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, ret);
1N/A}
1N/A
1N/AHBA_HANDLE
1N/ASun_HBA_OpenTgtAdapter(char* adaptername)
1N/A{
1N/A HBA_HANDLE handle;
1N/A Sun_HBAOpenTgtAdapterFunc OpenTgtAdapterFunc;
1N/A HBA_TGTADAPTER_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 if(_hbaapi_librarylist == NULL) {
1N/A return(HBA_HANDLE_INVALID);
1N/A }
1N/A if (adaptername == NULL) {
1N/A return(HBA_STATUS_ERROR_ARG);
1N/A }
1N/A handle = HBA_HANDLE_INVALID;
1N/A GRAB_MUTEX(&_hbaapi_AL_mutex);
1N/A for(adapt_infop = _hbaapi_tgtadapterlist;
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 OpenTgtAdapterFunc = (Sun_HBAOpenTgtAdapterFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcOpenTgtAdapter");
1N/A if (OpenTgtAdapterFunc != NULL) {
1N/A /* retrieve the vendor handle */
1N/A handle = (OpenTgtAdapterFunc)(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 * This function ignores the list of known adapters and instead tries
1N/A * each vendors open function to see if one of them
1N/A * can open an adapter when referenced with a particular WWN
1N/A */
1N/AHBA_STATUS
1N/ASun_HBA_OpenTgtAdapterByWWN(HBA_HANDLE *phandle, HBA_WWN nodeWWN)
1N/A{
1N/A HBA_HANDLE handle;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A Sun_HBAGetNumberOfTgtAdaptersFunc
1N/A GetNumberOfTgtAdaptersFunc;
1N/A Sun_HBAOpenTgtAdapterByWWNFunc
1N/A OpenTgtAdapterByWWNFunc;
1N/A HBA_STATUS status;
1N/A
1N/A DEBUG(2, "OpenAdapterByWWN: %s", WWN2STR1(&nodeWWN), 0, 0);
1N/A
1N/A if (phandle == NULL) {
1N/A return(HBA_STATUS_ERROR_ARG);
1N/A }
1N/A
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 GetNumberOfTgtAdaptersFunc = (Sun_HBAGetNumberOfTgtAdaptersFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcGetNumberOfTgtAdapters");
1N/A OpenTgtAdapterByWWNFunc = (Sun_HBAOpenTgtAdapterByWWNFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcOpenTgtAdapterByWWN");
1N/A if (GetNumberOfTgtAdaptersFunc == NULL ||
1N/A OpenTgtAdapterByWWNFunc == NULL) {
1N/A GetNumberOfTgtAdaptersFunc = OpenTgtAdapterByWWNFunc = NULL;
1N/A continue;
1N/A }
1N/A
1N/A (void) ((GetNumberOfTgtAdaptersFunc)());
1N/A
1N/A if((status = (OpenTgtAdapterByWWNFunc)(&handle, nodeWWN))
1N/A != HBA_STATUS_OK) {
1N/A GetNumberOfTgtAdaptersFunc = OpenTgtAdapterByWWNFunc = NULL;
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 GetNumberOfTgtAdaptersFunc = OpenTgtAdapterByWWNFunc = NULL;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}
1N/A
1N/Astatic HBA_STATUS
1N/AHBA_NPIV_CheckLibrary(HBA_HANDLE handle,
1N/A HBA_LIBRARY_INFO **lib_infopp,
1N/A HBA_HANDLE *vendorhandle) {
1N/A HBA_UINT32 libraryIndex;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A
1N/A if (vendorhandle == NULL) {
1N/A return(HBA_STATUS_ERROR_ARG);
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 NPIVCHECKLIBRARY() \
1N/A status = HBA_NPIV_CheckLibrary(handle, &lib_infop, &vendorHandle); \
1N/A if(status != HBA_STATUS_OK) { \
1N/A return(status); \
1N/A }
1N/A
1N/AHBA_STATUS
1N/ASun_HBA_NPIVGetAdapterAttributes (
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 Sun_HBANPIVGetAdapterAttributesFunc NPIVGetAdapterAttributesFunc;
1N/A
1N/A DEBUG(2, "HBA_NPIVGetAdapterAttributes", 0, 0, 0);
1N/A
1N/A NPIVCHECKLIBRARY();
1N/A NPIVGetAdapterAttributesFunc = (Sun_HBANPIVGetAdapterAttributesFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcNPIVGetAdapterAttributes");
1N/A if (NPIVGetAdapterAttributesFunc != NULL) {
1N/A status = ((NPIVGetAdapterAttributesFunc)(vendorHandle,
1N/A 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/ASun_HBA_GetNPIVPortInfo (
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_UINT32 vportindex,
1N/A HBA_NPIVATTRIBUTES *attributes)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A Sun_HBAGetNPIVPortInfoFunc GetNPIVPortInfoFunc;
1N/A
1N/A NPIVCHECKLIBRARY();
1N/A GetNPIVPortInfoFunc = (Sun_HBAGetNPIVPortInfoFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcGetNPIVPortInfo");
1N/A if (GetNPIVPortInfoFunc != NULL) {
1N/A status = ((GetNPIVPortInfoFunc)(vendorHandle, portindex,
1N/A vportindex, attributes));
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/ASun_HBA_DeleteNPIVPort (
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_WWN vportWWN)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A Sun_HBADeleteNPIVPortFunc DeleteNPIVPortFunc;
1N/A
1N/A NPIVCHECKLIBRARY();
1N/A DeleteNPIVPortFunc = (Sun_HBADeleteNPIVPortFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcDeleteNPIVPort");
1N/A if (DeleteNPIVPortFunc != NULL) {
1N/A status = ((DeleteNPIVPortFunc)(vendorHandle,
1N/A portindex, vportWWN));
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/ASun_HBA_CreateNPIVPort (
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_WWN vnodeWWN,
1N/A HBA_WWN vportWWN,
1N/A HBA_UINT32 *vportindex)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A Sun_HBACreateNPIVPortFunc CreateNPIVPortFunc;
1N/A
1N/A NPIVCHECKLIBRARY();
1N/A CreateNPIVPortFunc = (Sun_HBACreateNPIVPortFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcCreateNPIVPort");
1N/A if (CreateNPIVPortFunc != NULL) {
1N/A status = ((CreateNPIVPortFunc)(vendorHandle,
1N/A portindex, vnodeWWN, vportWWN, vportindex));
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/ASun_HBA_GetPortNPIVAttributes (
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_PORTNPIVATTRIBUTES *portnpivattributes)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A Sun_HBAGetPortNPIVAttributesFunc GetPortNPIVAttributesFunc;
1N/A
1N/A NPIVCHECKLIBRARY();
1N/A GetPortNPIVAttributesFunc = (Sun_HBAGetPortNPIVAttributesFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcGetPortNPIVAttributes");
1N/A if (GetPortNPIVAttributesFunc != NULL) {
1N/A status = ((GetPortNPIVAttributesFunc)(
1N/A vendorHandle, portindex, portnpivattributes));
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/ASun_HBA_AdapterCreateWWN (
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_WWN *nwwn,
1N/A HBA_WWN *pwwn,
1N/A HBA_WWN *OUI,
1N/A HBA_INT32 method)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A Sun_HBAAdapterCreateWWNFunc AdapterCreateWWNFunc;
1N/A
1N/A NPIVCHECKLIBRARY();
1N/A AdapterCreateWWNFunc = (Sun_HBAAdapterCreateWWNFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcAdapterCreateWWN");
1N/A if (AdapterCreateWWNFunc != NULL) {
1N/A status = ((AdapterCreateWWNFunc)(vendorHandle,
1N/A portindex, nwwn, pwwn, OUI, method));
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/ASun_HBA_AdapterReturnWWN (
1N/A HBA_HANDLE handle,
1N/A HBA_UINT32 portindex,
1N/A HBA_WWN *nwwn,
1N/A HBA_WWN *pwwn)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A Sun_HBAAdapterReturnWWNFunc AdapterReturnWWNFunc;
1N/A
1N/A NPIVCHECKLIBRARY();
1N/A AdapterReturnWWNFunc = (Sun_HBAAdapterReturnWWNFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcAdapterReturnWWN");
1N/A if (AdapterReturnWWNFunc != NULL) {
1N/A status = ((AdapterReturnWWNFunc)(vendorHandle,
1N/A portindex, nwwn, pwwn));
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/Atypedef struct hba_npivadaptercallback_elem {
1N/A struct hba_npivadaptercallback_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_NPIVADAPTERCALLBACK_ELEM;
1N/Aextern HBA_NPIVADAPTERCALLBACK_ELEM *_hbaapi_adapterdeviceevents_callback_list;
1N/A
1N/A/* Adapter Device Events ********************************************************/
1N/Astatic void
1N/Aadapterdeviceevents_callback (void *data,
1N/A HBA_WWN PortWWN,
1N/A HBA_UINT32 eventType,
1N/A HBA_UINT32 fabricPortID)
1N/A{
1N/A HBA_NPIVADAPTERCALLBACK_ELEM *acbp;
1N/A
1N/A DEBUG(3, "AdapterDeviceEvent, 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_adapterdeviceevents_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/ASun_HBA_RegisterForAdapterDeviceEvents (
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 ),
1N/A void *userData,
1N/A HBA_HANDLE handle,
1N/A HBA_WWN PortWWN,
1N/A HBA_CALLBACKHANDLE *callbackHandle)
1N/A{
1N/A HBA_NPIVADAPTERCALLBACK_ELEM *acbp;
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A Sun_HBARegisterForAdapterDeviceEventsFunc
1N/A registeredfunc;
1N/A
1N/A if (callbackHandle == NULL) {
1N/A return(HBA_STATUS_ERROR_ARG);
1N/A }
1N/A
1N/A NPIVCHECKLIBRARY();
1N/A registeredfunc = (Sun_HBARegisterForAdapterDeviceEventsFunc)
1N/A dlsym(lib_infop->hLibrary,
1N/A "Sun_fcRegisterForAdapterDeviceEvents");
1N/A if (registeredfunc == NULL) {
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1N/A }
1N/A
1N/A acbp = (HBA_NPIVADAPTERCALLBACK_ELEM *)
1N/A calloc(1, sizeof(HBA_NPIVADAPTERCALLBACK_ELEM));
1N/A
1N/A if(acbp == NULL) {
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)(adapterdeviceevents_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_adapterdeviceevents_callback_list;
1N/A _hbaapi_adapterdeviceevents_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/AHBA_STATUS
1N/ASun_HBA_ForceLip(HBA_HANDLE handle, int *rval)
1N/A{
1N/A HBA_STATUS status;
1N/A HBA_LIBRARY_INFO *lib_infop;
1N/A HBA_HANDLE vendorHandle;
1N/A
1N/A Sun_HBADoForceLipFunc DoForceLipFunc;
1N/A
1N/A DEBUG(2, "Sun_HBA_DoForceLip", 0, 0, 0);
1N/A
1N/A NPIVCHECKLIBRARY();
1N/A DoForceLipFunc = (Sun_HBADoForceLipFunc)
1N/A dlsym(lib_infop->hLibrary, "Sun_fcDoForceLip");
1N/A if (DoForceLipFunc != NULL) {
1N/A status = ((DoForceLipFunc)(vendorHandle, rval));
1N/A } else {
1N/A status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1N/A }
1N/A RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1N/A}