xref: /titanic_44/usr/src/lib/smhba/common/SMHBAAPILIB.c (revision 9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bb)
1*9e86db79SHyon Kim /*
2*9e86db79SHyon Kim  * ************************************************************************
3*9e86db79SHyon Kim  * Description
4*9e86db79SHyon Kim  *	HBAAPILIB.c - Implements a sample common (wrapper) HBA API library
5*9e86db79SHyon Kim  *
6*9e86db79SHyon Kim  * License:
7*9e86db79SHyon Kim  *	The contents of this file are subject to the SNIA Public License
8*9e86db79SHyon Kim  *	Version 1.0 (the "License"); you may not use this file except in
9*9e86db79SHyon Kim  *	compliance with the License. You may obtain a copy of the License at
10*9e86db79SHyon Kim  *
11*9e86db79SHyon Kim  *	/http://www.snia.org/English/Resources/Code/OpenSource.html
12*9e86db79SHyon Kim  *
13*9e86db79SHyon Kim  *	Software distributed under the License is distributed on an "AS IS"
14*9e86db79SHyon Kim  *	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
15*9e86db79SHyon Kim  *	the License for the specific language governing rights and limitations
16*9e86db79SHyon Kim  *	under the License.
17*9e86db79SHyon Kim  *
18*9e86db79SHyon Kim  * The Original Code is  SNIA HBA API Wrapper Library
19*9e86db79SHyon Kim  *
20*9e86db79SHyon Kim  * The Initial Developer of the Original Code is:
21*9e86db79SHyon Kim  *	Benjamin F. Kuo, Troika Networks, Inc. (benk@troikanetworks.com)
22*9e86db79SHyon Kim  *
23*9e86db79SHyon Kim  * Contributor(s):
24*9e86db79SHyon Kim  *	Tuan Lam, QLogic Corp. (t_lam@qlc.com)
25*9e86db79SHyon Kim  *	Dan Willie, Emulex Corp. (Dan.Willie@emulex.com)
26*9e86db79SHyon Kim  *	Dixon Hutchinson, Legato Systems, Inc. (dhutchin@legato.com)
27*9e86db79SHyon Kim  *	David Dillard, VERITAS Software Corp. (david.dillard@veritas.com)
28*9e86db79SHyon Kim  *
29*9e86db79SHyon Kim  * ************************************************************************
30*9e86db79SHyon Kim  *
31*9e86db79SHyon Kim  * Adding on SM-HBA support
32*9e86db79SHyon Kim  *
33*9e86db79SHyon Kim  * The implementation includes Three different categories functions to support
34*9e86db79SHyon Kim  * both HBAAPI and SM-HBA through the same library.
35*9e86db79SHyon Kim  *
36*9e86db79SHyon Kim  * SM-HBA unique interface:
37*9e86db79SHyon Kim  *	1. CHECKLIBRARYANDVERSION(SMHBA) : match SMHBA VSL
38*9e86db79SHyon Kim  *	   Or checking specifically if version is SMHBA beforehand.
39*9e86db79SHyon Kim  *	2. resolved to ftable.smhbafunctiontable.{interface}
40*9e86db79SHyon Kim  * HBAAPIV2 unique functions
41*9e86db79SHyon Kim  *	1. CHECKLIBRARYANDVERSION(HBAAPIV2) : validate and match HBAAPI V2 VSL.
42*9e86db79SHyon Kim  *	   Or checking specifically if version is HBAAPIV2 beforehand.
43*9e86db79SHyon Kim  *	2. resolved to ftable.functiontable.{interface}
44*9e86db79SHyon Kim  * Common interface between SM-HBA and HBAAPIV2.
45*9e86db79SHyon Kim  *	1. CHECKLIBRARY() : to validate the VSL.
46*9e86db79SHyon Kim  *	2. FUNCCOMMON macro to map the appropriate entry point table
47*9e86db79SHyon Kim  *	    (union ftable).
48*9e86db79SHyon Kim  *	3. If the interface is not supported by HBAAPI(Version 1)
49*9e86db79SHyon Kim  *	   the funtiion ptr will be set to NULL.
50*9e86db79SHyon Kim  * Common interface between HBAAPI and HBAAPIV2.
51*9e86db79SHyon Kim  *	1. Check if version is not SMHBA).
52*9e86db79SHyon Kim  *	2. ftable.functiontalbe.(interface)
53*9e86db79SHyon Kim  *
54*9e86db79SHyon Kim  * ************************************************************************
55*9e86db79SHyon Kim  */
56*9e86db79SHyon Kim /*
57*9e86db79SHyon Kim  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
58*9e86db79SHyon Kim  * Use is subject to license terms.
59*9e86db79SHyon Kim  */
60*9e86db79SHyon Kim 
61*9e86db79SHyon Kim #ifdef WIN32
62*9e86db79SHyon Kim #include <windows.h>
63*9e86db79SHyon Kim #include <string.h>
64*9e86db79SHyon Kim /*
65*9e86db79SHyon Kim  * Next define forces entry points in the dll to be exported
66*9e86db79SHyon Kim  * See hbaapi.h to see what it does.
67*9e86db79SHyon Kim  */
68*9e86db79SHyon Kim #define	HBAAPI_EXPORTS
69*9e86db79SHyon Kim #else
70*9e86db79SHyon Kim #include <dlfcn.h>
71*9e86db79SHyon Kim #include <strings.h>
72*9e86db79SHyon Kim #endif
73*9e86db79SHyon Kim #include <stdio.h>
74*9e86db79SHyon Kim #include <time.h>
75*9e86db79SHyon Kim #include "smhbaapi.h"
76*9e86db79SHyon Kim #include "vendorsmhbaapi.h"
77*9e86db79SHyon Kim #include <stdlib.h>
78*9e86db79SHyon Kim #ifdef USESYSLOG
79*9e86db79SHyon Kim #include <syslog.h>
80*9e86db79SHyon Kim #endif
81*9e86db79SHyon Kim #ifdef SOLARIS
82*9e86db79SHyon Kim #include <link.h>
83*9e86db79SHyon Kim #include <limits.h>
84*9e86db79SHyon Kim static int	*handle;
85*9e86db79SHyon Kim static Link_map *map, *mp;
86*9e86db79SHyon Kim #endif
87*9e86db79SHyon Kim 
88*9e86db79SHyon Kim /*
89*9e86db79SHyon Kim  * LIBRARY_NUM is a shortcut to figure out which library we need to call.
90*9e86db79SHyon Kim  *  The top 16 bits of handle are the library index
91*9e86db79SHyon Kim  */
92*9e86db79SHyon Kim #define	LIBRARY_NUM(handle)	((handle)>>16)
93*9e86db79SHyon Kim 
94*9e86db79SHyon Kim /*
95*9e86db79SHyon Kim  * VENDOR_HANDLE turns a global library handle into a vendor specific handle,
96*9e86db79SHyon Kim  * with all upper 16 bits set to 0
97*9e86db79SHyon Kim  */
98*9e86db79SHyon Kim #define	VENDOR_HANDLE(handle)	((handle)&0xFFFF)
99*9e86db79SHyon Kim 
100*9e86db79SHyon Kim #define	HBA_HANDLE_FROM_LOCAL(library, vendor) \
101*9e86db79SHyon Kim 				(((library)<<16) | ((vendor)&0x0000FFFF))
102*9e86db79SHyon Kim 
103*9e86db79SHyon Kim int _hbaapi_debuglevel = 0;
104*9e86db79SHyon Kim #define	DEBUG(L, STR, A1, A2, A3)
105*9e86db79SHyon Kim 
106*9e86db79SHyon Kim #if defined(USESYSLOG) && defined(USELOGFILE)
107*9e86db79SHyon Kim FILE *_hbaapi_debug_fd = NULL;
108*9e86db79SHyon Kim int _hbaapi_sysloginit = 0;
109*9e86db79SHyon Kim #undef DEBUG
110*9e86db79SHyon Kim #ifdef WIN32
111*9e86db79SHyon Kim #define	DEBUG(L, STR, A1, A2, A3)\
112*9e86db79SHyon Kim     if ((L) <= _hbaapi_debuglevel) {\
113*9e86db79SHyon Kim 	if (_hbaapi_sysloginit == 0) {\
114*9e86db79SHyon Kim 	    openlog("HBAAPI", LOG_PID|LOG_ODELAY, LOG_USER);\
115*9e86db79SHyon Kim 	    _hbaapi_sysloginit = 1;\
116*9e86db79SHyon Kim 	}\
117*9e86db79SHyon Kim 	syslog(LOG_INFO, (STR), (A1), (A2), (A3));\
118*9e86db79SHyon Kim 	if (_hbaapi_debug_fd == NULL) {\
119*9e86db79SHyon Kim 	    char _logFile[MAX_PATH]; \
120*9e86db79SHyon Kim 	    GetTempPath(MAX_PATH, _logFile); \
121*9e86db79SHyon Kim 	    strcat(_logFile, "HBAAPI.log"); \
122*9e86db79SHyon Kim 	    _hbaapi_debug_fd = fopen(_logFile, "a");\
123*9e86db79SHyon Kim 	}\
124*9e86db79SHyon Kim 	if (_hbaapi_debug_fd != NULL) {\
125*9e86db79SHyon Kim 	    fprintf(_hbaapi_debug_fd, #STR "\n", (A1), (A2), (A3));\
126*9e86db79SHyon Kim 	}\
127*9e86db79SHyon Kim 	}
128*9e86db79SHyon Kim #else /* WIN32 */
129*9e86db79SHyon Kim #define	DEBUG(L, STR, A1, A2, A3)\
130*9e86db79SHyon Kim 	if ((L) <= _hbaapi_debuglevel) {\
131*9e86db79SHyon Kim 	if (_hbaapi_sysloginit == 0) {\
132*9e86db79SHyon Kim 	    openlog("HBAAPI", LOG_PID|LOG_ODELAY, LOG_USER);\
133*9e86db79SHyon Kim 	    _hbaapi_sysloginit = 1;\
134*9e86db79SHyon Kim 	}\
135*9e86db79SHyon Kim 	syslog(LOG_INFO, (STR), (A1), (A2), (A3));\
136*9e86db79SHyon Kim 	if (_hbaapi_debug_fd == NULL) {\
137*9e86db79SHyon Kim 	    _hbaapi_debug_fd = fopen("/tmp/HBAAPI.log", "a");\
138*9e86db79SHyon Kim 	}\
139*9e86db79SHyon Kim 	if (_hbaapi_debug_fd != NULL) {\
140*9e86db79SHyon Kim 	    fprintf(_hbaapi_debug_fd, #STR  "\n", (A1), (A2), (A3));\
141*9e86db79SHyon Kim 	}\
142*9e86db79SHyon Kim 	}
143*9e86db79SHyon Kim #endif /* WIN32 */
144*9e86db79SHyon Kim 
145*9e86db79SHyon Kim #else /* Not both USESYSLOG and USELOGFILE */
146*9e86db79SHyon Kim #if defined(USESYSLOG)
147*9e86db79SHyon Kim int _hbaapi_sysloginit = 0;
148*9e86db79SHyon Kim #undef DEBUG
149*9e86db79SHyon Kim #define	DEBUG(L, STR, A1, A2, A3) \
150*9e86db79SHyon Kim     if ((L) <= _hbaapi_debuglevel) {\
151*9e86db79SHyon Kim 	if (_hbaapi_sysloginit == 0) {\
152*9e86db79SHyon Kim 	    openlog("HBAAPI", LOG_PID|LOG_ODELAY, LOG_USER);\
153*9e86db79SHyon Kim 	    _hbaapi_sysloginit = 1;\
154*9e86db79SHyon Kim 	}\
155*9e86db79SHyon Kim 	syslog(LOG_DEBUG, (STR), (A1), (A2), (A3));\
156*9e86db79SHyon Kim 	}
157*9e86db79SHyon Kim #endif /* USESYSLOG */
158*9e86db79SHyon Kim #if defined(USELOGFILE)
159*9e86db79SHyon Kim FILE *_hbaapi_debug_fd = NULL;
160*9e86db79SHyon Kim #undef DEBUG
161*9e86db79SHyon Kim #ifdef WIN32
162*9e86db79SHyon Kim #define	DEBUG(L, STR, A1, A2, A3) \
163*9e86db79SHyon Kim     if ((L) <= _hbaapi_debuglevel) {\
164*9e86db79SHyon Kim 	if (_hbaapi_debug_fd == NULL) {\
165*9e86db79SHyon Kim 	    char _logFile[MAX_PATH]; \
166*9e86db79SHyon Kim 	    GetTempPath(MAX_PATH, _logFile); \
167*9e86db79SHyon Kim 	    strcat(_logFile, "HBAAPI.log"); \
168*9e86db79SHyon Kim 	    _hbaapi_debug_fd = fopen(_logFile, "a");\
169*9e86db79SHyon Kim 	}\
170*9e86db79SHyon Kim 	}
171*9e86db79SHyon Kim #else /* WIN32 */
172*9e86db79SHyon Kim #define	DEBUG(L, STR, A1, A2, A3) \
173*9e86db79SHyon Kim     if ((L) <= _hbaapi_debuglevel) {\
174*9e86db79SHyon Kim 	if (_hbaapi_debug_fd == NULL) {\
175*9e86db79SHyon Kim 	    _hbaapi_debug_fd = fopen("/tmp/HBAAPI.log", "a");\
176*9e86db79SHyon Kim 	}\
177*9e86db79SHyon Kim 	if (_hbaapi_debug_fd != NULL) { \
178*9e86db79SHyon Kim 	    fprintf(_hbaapi_debug_fd, #STR "\n", (A1), (A2), (A3));\
179*9e86db79SHyon Kim 	}\
180*9e86db79SHyon Kim 	}
181*9e86db79SHyon Kim #endif /* WIN32 */
182*9e86db79SHyon Kim #endif /* USELOGFILE */
183*9e86db79SHyon Kim #endif /* Not both USELOGFILE and USESYSLOG */
184*9e86db79SHyon Kim 
185*9e86db79SHyon Kim #ifdef POSIX_THREADS
186*9e86db79SHyon Kim #include <pthread.h>
187*9e86db79SHyon Kim /*
188*9e86db79SHyon Kim  * When multiple mutex's are grabed, they must be always be grabbed in
189*9e86db79SHyon Kim  * the same order, or deadlock can result.  There are three levels
190*9e86db79SHyon Kim  * of mutex's involved in this API.  If LL_mutex is grabbed, always grap
191*9e86db79SHyon Kim  * it first.  If AL_mutex is grabbed, it may not be grabbed before
192*9e86db79SHyon Kim  * LL_mutex.  If grabbed in a multi grab sequence, the mutex's protecting
193*9e86db79SHyon Kim  * the callback lists must always be grabbed last and release before calling
194*9e86db79SHyon Kim  * a vendor specific library function that might invoke a callback function
195*9e86db79SHyon Kim  * on the same thread.
196*9e86db79SHyon Kim  */
197*9e86db79SHyon Kim #define	GRAB_MUTEX(M)			grab_mutex(M)
198*9e86db79SHyon Kim #define	RELEASE_MUTEX(M)		release_mutex(M)
199*9e86db79SHyon Kim #define	RELEASE_MUTEX_RETURN(M, RET)	release_mutex(M); return (RET)
200*9e86db79SHyon Kim #elif defined(WIN32)
201*9e86db79SHyon Kim #define	GRAB_MUTEX(m)			EnterCriticalSection(m)
202*9e86db79SHyon Kim #define	RELEASE_MUTEX(m)		LeaveCriticalSection(m)
203*9e86db79SHyon Kim #define	RELEASE_MUTEX_RETURN(m, RET)	LeaveCriticalSection(m); return (RET)
204*9e86db79SHyon Kim #else
205*9e86db79SHyon Kim #define	GRAB_MUTEX(M)
206*9e86db79SHyon Kim #define	RELEASE_MUTEX(M)
207*9e86db79SHyon Kim #define	RELEASE_MUTEX_RETURN(M, RET)	return (RET)
208*9e86db79SHyon Kim #endif
209*9e86db79SHyon Kim 
210*9e86db79SHyon Kim /*
211*9e86db79SHyon Kim  * Vendor library information
212*9e86db79SHyon Kim  */
213*9e86db79SHyon Kim typedef enum {
214*9e86db79SHyon Kim     HBA_LIBRARY_UNKNOWN,
215*9e86db79SHyon Kim     HBA_LIBRARY_LOADED,
216*9e86db79SHyon Kim     HBA_LIBRARY_NOT_LOADED
217*9e86db79SHyon Kim } HBA_LIBRARY_STATUS;
218*9e86db79SHyon Kim 
219*9e86db79SHyon Kim typedef enum {
220*9e86db79SHyon Kim     UNKNOWN = 1,
221*9e86db79SHyon Kim     SMHBA,
222*9e86db79SHyon Kim     HBAAPIV2,
223*9e86db79SHyon Kim     HBAAPI
224*9e86db79SHyon Kim } LIBRARY_VERSION;
225*9e86db79SHyon Kim 
226*9e86db79SHyon Kim typedef struct hba_library_info {
227*9e86db79SHyon Kim     struct hba_library_info
228*9e86db79SHyon Kim 			*next;
229*9e86db79SHyon Kim #ifdef WIN32
230*9e86db79SHyon Kim     HINSTANCE		hLibrary;		/* Handle to a loaded DLL */
231*9e86db79SHyon Kim #else
232*9e86db79SHyon Kim     char		*LibraryName;
233*9e86db79SHyon Kim     void*		hLibrary;		/* Handle to a loaded DLL */
234*9e86db79SHyon Kim #endif
235*9e86db79SHyon Kim     char		*LibraryPath;
236*9e86db79SHyon Kim     LIBRARY_VERSION	version;		/* resolve union */
237*9e86db79SHyon Kim     HBA_UINT32		numOfAdapters;
238*9e86db79SHyon Kim     union {
239*9e86db79SHyon Kim 	SMHBA_ENTRYPOINTS   smhbafunctionTable;	/* smhba function pointers */
240*9e86db79SHyon Kim 	HBA_ENTRYPOINTSV2   functionTable;	/* hba api function pointers */
241*9e86db79SHyon Kim 	} ftable;
242*9e86db79SHyon Kim     HBA_LIBRARY_STATUS	status;			/* info on this library */
243*9e86db79SHyon Kim     HBA_UINT32		index;
244*9e86db79SHyon Kim } HBA_LIBRARY_INFO, *PHBA_LIBRARY_INFO;
245*9e86db79SHyon Kim 
246*9e86db79SHyon Kim #define	ARE_WE_INITED() \
247*9e86db79SHyon Kim 	if (_hbaapi_librarylist == NULL) { \
248*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR_NOT_LOADED); \
249*9e86db79SHyon Kim 	}
250*9e86db79SHyon Kim HBA_LIBRARY_INFO *_hbaapi_librarylist = NULL;
251*9e86db79SHyon Kim HBA_UINT32 _hbaapi_total_library_count = 0;
252*9e86db79SHyon Kim #ifdef POSIX_THREADS
253*9e86db79SHyon Kim pthread_mutex_t _hbaapi_LL_mutex = PTHREAD_MUTEX_INITIALIZER;
254*9e86db79SHyon Kim #elif defined(WIN32)
255*9e86db79SHyon Kim CRITICAL_SECTION _hbaapi_LL_mutex;
256*9e86db79SHyon Kim #endif
257*9e86db79SHyon Kim 
258*9e86db79SHyon Kim /*
259*9e86db79SHyon Kim  * Macro to use the right function table between smhba and hbaapi.
260*9e86db79SHyon Kim  */
261*9e86db79SHyon Kim #define	FUNCTABLE(lib_infop) \
262*9e86db79SHyon Kim 	((lib_infop->version == SMHBA) ? \
263*9e86db79SHyon Kim 	lib_infop->ftable.smhbafunctionTable : \
264*9e86db79SHyon Kim 	lib_infop->ftable.functionTable);
265*9e86db79SHyon Kim 
266*9e86db79SHyon Kim /*
267*9e86db79SHyon Kim  * Macro to use the right function ptr between smhba and hbaapi function table.
268*9e86db79SHyon Kim  * Should be used for an interface common to SM-HBA and HBAAPIV2.
269*9e86db79SHyon Kim  */
270*9e86db79SHyon Kim #define	FUNCCOMMON(lib_infop, func) \
271*9e86db79SHyon Kim 	((lib_infop->version == SMHBA) ? \
272*9e86db79SHyon Kim 	lib_infop->ftable.smhbafunctionTable.func : \
273*9e86db79SHyon Kim 	lib_infop->ftable.functionTable.func)
274*9e86db79SHyon Kim 
275*9e86db79SHyon Kim /*
276*9e86db79SHyon Kim  * Macro to use the hbaapi function ptr.
277*9e86db79SHyon Kim  * Should be used for an interface applicable only HBAAPIV2.
278*9e86db79SHyon Kim  */
279*9e86db79SHyon Kim #define	FUNCHBAAPIV2(lib_infop, func) \
280*9e86db79SHyon Kim 	lib_infop->ftable.functionTable.func
281*9e86db79SHyon Kim 
282*9e86db79SHyon Kim /*
283*9e86db79SHyon Kim  * Macro to use the hbaapi function ptr.
284*9e86db79SHyon Kim  * Should be used for an interface applicable only HBAAPIV2.
285*9e86db79SHyon Kim  */
286*9e86db79SHyon Kim #define	FUNCSMHBA(lib_infop, func) \
287*9e86db79SHyon Kim 	lib_infop->ftable.smhbafunctionTable.func
288*9e86db79SHyon Kim 
289*9e86db79SHyon Kim /*
290*9e86db79SHyon Kim  * Individual adapter (hba) information
291*9e86db79SHyon Kim  */
292*9e86db79SHyon Kim typedef struct hba_adapter_info {
293*9e86db79SHyon Kim     struct hba_adapter_info
294*9e86db79SHyon Kim 			*next;
295*9e86db79SHyon Kim     HBA_STATUS		GNstatus;	/* status from GetAdapterNameFunc */
296*9e86db79SHyon Kim     char		*name;
297*9e86db79SHyon Kim     HBA_WWN		nodeWWN;
298*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*library;
299*9e86db79SHyon Kim     HBA_UINT32		index;
300*9e86db79SHyon Kim } HBA_ADAPTER_INFO;
301*9e86db79SHyon Kim 
302*9e86db79SHyon Kim HBA_ADAPTER_INFO *_hbaapi_adapterlist = NULL;
303*9e86db79SHyon Kim HBA_UINT32 _hbaapi_total_adapter_count = 0;
304*9e86db79SHyon Kim #ifdef POSIX_THREADS
305*9e86db79SHyon Kim pthread_mutex_t _hbaapi_AL_mutex = PTHREAD_MUTEX_INITIALIZER;
306*9e86db79SHyon Kim #elif defined(WIN32)
307*9e86db79SHyon Kim CRITICAL_SECTION _hbaapi_AL_mutex;
308*9e86db79SHyon Kim #endif
309*9e86db79SHyon Kim 
310*9e86db79SHyon Kim /*
311*9e86db79SHyon Kim  * Call back registration
312*9e86db79SHyon Kim  */
313*9e86db79SHyon Kim typedef struct hba_vendorcallback_elem {
314*9e86db79SHyon Kim     struct hba_vendorcallback_elem
315*9e86db79SHyon Kim 				*next;
316*9e86db79SHyon Kim     HBA_CALLBACKHANDLE		vendorcbhandle;
317*9e86db79SHyon Kim     HBA_LIBRARY_INFO		*lib_info;
318*9e86db79SHyon Kim } HBA_VENDORCALLBACK_ELEM;
319*9e86db79SHyon Kim 
320*9e86db79SHyon Kim /*
321*9e86db79SHyon Kim  * Each instance of HBA_ADAPTERCALLBACK_ELEM represents a call to one of
322*9e86db79SHyon Kim  * "register" functions that apply to a particular adapter.
323*9e86db79SHyon Kim  * HBA_ALLADAPTERSCALLBACK_ELEM is used just for HBA_RegisterForAdapterAddEvents
324*9e86db79SHyon Kim  */
325*9e86db79SHyon Kim typedef struct hba_adaptercallback_elem {
326*9e86db79SHyon Kim     struct hba_adaptercallback_elem
327*9e86db79SHyon Kim 			*next;
328*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_info;
329*9e86db79SHyon Kim     void		*userdata;
330*9e86db79SHyon Kim     HBA_CALLBACKHANDLE	vendorcbhandle;
331*9e86db79SHyon Kim     void		(*callback)();
332*9e86db79SHyon Kim } HBA_ADAPTERCALLBACK_ELEM;
333*9e86db79SHyon Kim 
334*9e86db79SHyon Kim typedef struct hba_alladapterscallback_elem {
335*9e86db79SHyon Kim     struct hba_alladapterscallback_elem
336*9e86db79SHyon Kim 				*next;
337*9e86db79SHyon Kim     void			*userdata;
338*9e86db79SHyon Kim     HBA_VENDORCALLBACK_ELEM	*vendorhandlelist;
339*9e86db79SHyon Kim     void			(*callback)();
340*9e86db79SHyon Kim } HBA_ALLADAPTERSCALLBACK_ELEM;
341*9e86db79SHyon Kim 
342*9e86db79SHyon Kim HBA_ALLADAPTERSCALLBACK_ELEM *_hbaapi_adapteraddevents_callback_list = NULL;
343*9e86db79SHyon Kim HBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterevents_callback_list = NULL;
344*9e86db79SHyon Kim HBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterportevents_callback_list = NULL;
345*9e86db79SHyon Kim HBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterportstatevents_callback_list = NULL;
346*9e86db79SHyon Kim HBA_ADAPTERCALLBACK_ELEM *_hbaapi_targetevents_callback_list = NULL;
347*9e86db79SHyon Kim HBA_ADAPTERCALLBACK_ELEM *_hbaapi_linkevents_callback_list = NULL;
348*9e86db79SHyon Kim 
349*9e86db79SHyon Kim HBA_ALLADAPTERSCALLBACK_ELEM *_smhba_adapteraddevents_callback_list = NULL;
350*9e86db79SHyon Kim HBA_ADAPTERCALLBACK_ELEM *_smhba_adapterevents_callback_list = NULL;
351*9e86db79SHyon Kim HBA_ADAPTERCALLBACK_ELEM *_smhba_adapterportevents_callback_list = NULL;
352*9e86db79SHyon Kim HBA_ADAPTERCALLBACK_ELEM *_smhba_adapterportstatevents_callback_list = NULL;
353*9e86db79SHyon Kim HBA_ADAPTERCALLBACK_ELEM *_smhba_adapterphystatevents_callback_list = NULL;
354*9e86db79SHyon Kim HBA_ADAPTERCALLBACK_ELEM *_smhba_targetevents_callback_list = NULL;
355*9e86db79SHyon Kim 
356*9e86db79SHyon Kim #ifdef POSIX_THREADS
357*9e86db79SHyon Kim /* mutex's to protect each list */
358*9e86db79SHyon Kim pthread_mutex_t _hbaapi_AAE_mutex = PTHREAD_MUTEX_INITIALIZER;
359*9e86db79SHyon Kim pthread_mutex_t _hbaapi_AE_mutex = PTHREAD_MUTEX_INITIALIZER;
360*9e86db79SHyon Kim pthread_mutex_t _hbaapi_APE_mutex = PTHREAD_MUTEX_INITIALIZER;
361*9e86db79SHyon Kim pthread_mutex_t _hbaapi_APSE_mutex = PTHREAD_MUTEX_INITIALIZER;
362*9e86db79SHyon Kim pthread_mutex_t _hbaapi_TE_mutex = PTHREAD_MUTEX_INITIALIZER;
363*9e86db79SHyon Kim pthread_mutex_t _hbaapi_LE_mutex = PTHREAD_MUTEX_INITIALIZER;
364*9e86db79SHyon Kim pthread_mutex_t _smhba_AAE_mutex = PTHREAD_MUTEX_INITIALIZER;
365*9e86db79SHyon Kim pthread_mutex_t _smhba_AE_mutex = PTHREAD_MUTEX_INITIALIZER;
366*9e86db79SHyon Kim pthread_mutex_t _smhba_APE_mutex = PTHREAD_MUTEX_INITIALIZER;
367*9e86db79SHyon Kim pthread_mutex_t _smhba_APSE_mutex = PTHREAD_MUTEX_INITIALIZER;
368*9e86db79SHyon Kim pthread_mutex_t _smhba_APHYSE_mutex = PTHREAD_MUTEX_INITIALIZER;
369*9e86db79SHyon Kim pthread_mutex_t _smhba_TE_mutex = PTHREAD_MUTEX_INITIALIZER;
370*9e86db79SHyon Kim pthread_mutex_t _smhba_LE_mutex = PTHREAD_MUTEX_INITIALIZER;
371*9e86db79SHyon Kim #elif defined(WIN32)
372*9e86db79SHyon Kim CRITICAL_SECTION _hbaapi_AAE_mutex;
373*9e86db79SHyon Kim CRITICAL_SECTION _hbaapi_AE_mutex;
374*9e86db79SHyon Kim CRITICAL_SECTION _hbaapi_APE_mutex;
375*9e86db79SHyon Kim CRITICAL_SECTION _hbaapi_APSE_mutex;
376*9e86db79SHyon Kim CRITICAL_SECTION _hbaapi_TE_mutex;
377*9e86db79SHyon Kim CRITICAL_SECTION _smhba_AAE_mutex;
378*9e86db79SHyon Kim CRITICAL_SECTION _smhba_AE_mutex;
379*9e86db79SHyon Kim CRITICAL_SECTION _smhba_APE_mutex;
380*9e86db79SHyon Kim CRITICAL_SECTION _smhba_APSE_mutex;
381*9e86db79SHyon Kim CRITICAL_SECTION _smhba_APHYSE_mutex;
382*9e86db79SHyon Kim CRITICAL_SECTION _smhba_TE_mutex;
383*9e86db79SHyon Kim CRITICAL_SECTION _hbaapi_LE_mutex;
384*9e86db79SHyon Kim #endif
385*9e86db79SHyon Kim 
386*9e86db79SHyon Kim HBA_ADAPTERCALLBACK_ELEM **cb_lists_array[] = {
387*9e86db79SHyon Kim 	&_hbaapi_adapterevents_callback_list,
388*9e86db79SHyon Kim 	&_hbaapi_adapterportevents_callback_list,
389*9e86db79SHyon Kim 	&_hbaapi_adapterportstatevents_callback_list,
390*9e86db79SHyon Kim 	&_hbaapi_targetevents_callback_list,
391*9e86db79SHyon Kim 	&_hbaapi_linkevents_callback_list,
392*9e86db79SHyon Kim 	&_smhba_adapterevents_callback_list,
393*9e86db79SHyon Kim 	&_smhba_adapterportevents_callback_list,
394*9e86db79SHyon Kim 	&_smhba_adapterportstatevents_callback_list,
395*9e86db79SHyon Kim 	&_smhba_adapterphystatevents_callback_list,
396*9e86db79SHyon Kim 	&_smhba_targetevents_callback_list,
397*9e86db79SHyon Kim 	NULL};
398*9e86db79SHyon Kim 
399*9e86db79SHyon Kim /*
400*9e86db79SHyon Kim  * Common library internal. Mutex handling
401*9e86db79SHyon Kim  */
402*9e86db79SHyon Kim #ifdef POSIX_THREADS
403*9e86db79SHyon Kim static void
404*9e86db79SHyon Kim grab_mutex(pthread_mutex_t *mp) {
405*9e86db79SHyon Kim /* LINTED E_FUNC_SET_NOT_USED */
406*9e86db79SHyon Kim     int ret;
407*9e86db79SHyon Kim     if ((ret = pthread_mutex_lock(mp)) != 0) {
408*9e86db79SHyon Kim 	perror("pthread_mutex_lock - HBAAPI:");
409*9e86db79SHyon Kim 	DEBUG(1, "pthread_mutex_lock returned %d", ret, 0, 0);
410*9e86db79SHyon Kim 	}
411*9e86db79SHyon Kim }
412*9e86db79SHyon Kim 
413*9e86db79SHyon Kim static void
414*9e86db79SHyon Kim release_mutex(pthread_mutex_t *mp) {
415*9e86db79SHyon Kim /* LINTED E_FUNC_SET_NOT_USED */
416*9e86db79SHyon Kim     int ret;
417*9e86db79SHyon Kim     if ((ret = pthread_mutex_unlock(mp)) != 0) {
418*9e86db79SHyon Kim 	perror("pthread_mutex_unlock - HBAAPI:");
419*9e86db79SHyon Kim 	DEBUG(1, "pthread_mutex_unlock returned %d", ret, 0, 0);
420*9e86db79SHyon Kim 	}
421*9e86db79SHyon Kim }
422*9e86db79SHyon Kim #endif
423*9e86db79SHyon Kim 
424*9e86db79SHyon Kim /*
425*9e86db79SHyon Kim  * Common library internal. Check library and return vendorhandle
426*9e86db79SHyon Kim  */
427*9e86db79SHyon Kim static HBA_STATUS
428*9e86db79SHyon Kim HBA_CheckLibrary(HBA_HANDLE handle,
429*9e86db79SHyon Kim     HBA_LIBRARY_INFO **lib_infopp,
430*9e86db79SHyon Kim     HBA_HANDLE *vendorhandle) {
431*9e86db79SHyon Kim 
432*9e86db79SHyon Kim     HBA_UINT32		libraryIndex;
433*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_infop;
434*9e86db79SHyon Kim 
435*9e86db79SHyon Kim     if (_hbaapi_librarylist == NULL) {
436*9e86db79SHyon Kim 	return (HBA_STATUS_ERROR);
437*9e86db79SHyon Kim 	}
438*9e86db79SHyon Kim     libraryIndex = LIBRARY_NUM(handle);
439*9e86db79SHyon Kim 
440*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_LL_mutex);
441*9e86db79SHyon Kim     for (lib_infop = _hbaapi_librarylist;
442*9e86db79SHyon Kim 	lib_infop != NULL;
443*9e86db79SHyon Kim 	lib_infop = lib_infop->next) {
444*9e86db79SHyon Kim 	if (lib_infop->index == libraryIndex) {
445*9e86db79SHyon Kim 	    if (lib_infop->status != HBA_LIBRARY_LOADED) {
446*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR);
447*9e86db79SHyon Kim 	    }
448*9e86db79SHyon Kim 	    *lib_infopp = lib_infop;
449*9e86db79SHyon Kim 	    *vendorhandle = VENDOR_HANDLE(handle);
450*9e86db79SHyon Kim 	    /* caller will release the mutex */
451*9e86db79SHyon Kim 	    return (HBA_STATUS_OK);
452*9e86db79SHyon Kim 	}
453*9e86db79SHyon Kim 	}
454*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INVALID_HANDLE);
455*9e86db79SHyon Kim }
456*9e86db79SHyon Kim #define	CHECKLIBRARY() \
457*9e86db79SHyon Kim 	status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);\
458*9e86db79SHyon Kim 	if (status != HBA_STATUS_OK) { \
459*9e86db79SHyon Kim 	    return (status); \
460*9e86db79SHyon Kim 	}
461*9e86db79SHyon Kim 
462*9e86db79SHyon Kim #define	CHECKLIBRARYANDVERSION(ver) \
463*9e86db79SHyon Kim 	status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle); \
464*9e86db79SHyon Kim 	if (status != HBA_STATUS_OK) { \
465*9e86db79SHyon Kim 	    return (status); \
466*9e86db79SHyon Kim 	} else { \
467*9e86db79SHyon Kim 	    if (ver != lib_infop->version) { \
468*9e86db79SHyon Kim 		RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, \
469*9e86db79SHyon Kim 		    HBA_STATUS_ERROR_INCOMPATIBLE); \
470*9e86db79SHyon Kim 	    } \
471*9e86db79SHyon Kim 	}
472*9e86db79SHyon Kim 
473*9e86db79SHyon Kim /*
474*9e86db79SHyon Kim  * freevendorhandlelist is called with _hbaapi_LL_mutex already held
475*9e86db79SHyon Kim  */
476*9e86db79SHyon Kim static void
477*9e86db79SHyon Kim freevendorhandlelist(HBA_VENDORCALLBACK_ELEM *vhlist) {
478*9e86db79SHyon Kim     HBA_VENDORCALLBACK_ELEM	*vhlp;
479*9e86db79SHyon Kim     HBA_VENDORCALLBACK_ELEM	*vnext;
480*9e86db79SHyon Kim     HBARemoveCallbackFunc	registeredfunc;
481*9e86db79SHyon Kim 
482*9e86db79SHyon Kim     for (vhlp = vhlist; vhlp != NULL; vhlp = vnext) {
483*9e86db79SHyon Kim 	vnext = vhlp->next;
484*9e86db79SHyon Kim 	registeredfunc =
485*9e86db79SHyon Kim 	    FUNCCOMMON(vhlp->lib_info, RemoveCallbackHandler);
486*9e86db79SHyon Kim 	if (registeredfunc == NULL) {
487*9e86db79SHyon Kim 	    continue;
488*9e86db79SHyon Kim 	}
489*9e86db79SHyon Kim 	(registeredfunc)(vhlp->vendorcbhandle);
490*9e86db79SHyon Kim 	free(vhlp);
491*9e86db79SHyon Kim 	}
492*9e86db79SHyon Kim }
493*9e86db79SHyon Kim 
494*9e86db79SHyon Kim static
495*9e86db79SHyon Kim HBA_STATUS
496*9e86db79SHyon Kim local_remove_callback(HBA_CALLBACKHANDLE cbhandle) {
497*9e86db79SHyon Kim     HBA_ADAPTERCALLBACK_ELEM		***listp;
498*9e86db79SHyon Kim     HBA_ADAPTERCALLBACK_ELEM		**lastp;
499*9e86db79SHyon Kim     HBA_ALLADAPTERSCALLBACK_ELEM	**lap;
500*9e86db79SHyon Kim     HBA_ALLADAPTERSCALLBACK_ELEM	*allcbp;
501*9e86db79SHyon Kim     HBA_ADAPTERCALLBACK_ELEM		*cbp;
502*9e86db79SHyon Kim     HBARemoveCallbackFunc		registeredfunc;
503*9e86db79SHyon Kim     HBA_VENDORCALLBACK_ELEM		*vhlp;
504*9e86db79SHyon Kim     HBA_VENDORCALLBACK_ELEM		*vnext;
505*9e86db79SHyon Kim     int					found;
506*9e86db79SHyon Kim     HBA_STATUS			status = HBA_STATUS_ERROR_INVALID_HANDLE;
507*9e86db79SHyon Kim 
508*9e86db79SHyon Kim 
509*9e86db79SHyon Kim 	/* search through the simple lists first */
510*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_AAE_mutex);
511*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_AE_mutex);
512*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_APE_mutex);
513*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_APSE_mutex);
514*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_TE_mutex);
515*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_LE_mutex);
516*9e86db79SHyon Kim     GRAB_MUTEX(&_smhba_AAE_mutex);
517*9e86db79SHyon Kim     GRAB_MUTEX(&_smhba_AE_mutex);
518*9e86db79SHyon Kim     GRAB_MUTEX(&_smhba_APE_mutex);
519*9e86db79SHyon Kim     GRAB_MUTEX(&_smhba_APSE_mutex);
520*9e86db79SHyon Kim     GRAB_MUTEX(&_smhba_TE_mutex);
521*9e86db79SHyon Kim     for (listp = cb_lists_array, found = 0;
522*9e86db79SHyon Kim 	    (found == 0 && *listp != NULL); listp++) {
523*9e86db79SHyon Kim 	lastp = *listp;
524*9e86db79SHyon Kim 	for (cbp = **listp; cbp != NULL; cbp = cbp->next) {
525*9e86db79SHyon Kim 	    if (cbhandle != (HBA_CALLBACKHANDLE)cbp) {
526*9e86db79SHyon Kim 		lastp = &(cbp->next);
527*9e86db79SHyon Kim 		continue;
528*9e86db79SHyon Kim 	    }
529*9e86db79SHyon Kim 	    found = 1;
530*9e86db79SHyon Kim 	    registeredfunc =
531*9e86db79SHyon Kim 		FUNCCOMMON(cbp->lib_info, RemoveCallbackHandler);
532*9e86db79SHyon Kim 	    if (registeredfunc == NULL) {
533*9e86db79SHyon Kim 		break;
534*9e86db79SHyon Kim 	    }
535*9e86db79SHyon Kim 	    (registeredfunc)(cbp->vendorcbhandle);
536*9e86db79SHyon Kim 	    *lastp = cbp->next;
537*9e86db79SHyon Kim 	    free(cbp);
538*9e86db79SHyon Kim 	    break;
539*9e86db79SHyon Kim 	}
540*9e86db79SHyon Kim 	}
541*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_LE_mutex);
542*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_TE_mutex);
543*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_APSE_mutex);
544*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_APE_mutex);
545*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_AE_mutex);
546*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_AAE_mutex);
547*9e86db79SHyon Kim     RELEASE_MUTEX(&_smhba_AAE_mutex);
548*9e86db79SHyon Kim     RELEASE_MUTEX(&_smhba_AE_mutex);
549*9e86db79SHyon Kim     RELEASE_MUTEX(&_smhba_APE_mutex);
550*9e86db79SHyon Kim     RELEASE_MUTEX(&_smhba_APSE_mutex);
551*9e86db79SHyon Kim     RELEASE_MUTEX(&_smhba_TE_mutex);
552*9e86db79SHyon Kim 
553*9e86db79SHyon Kim     if (found != 0) {
554*9e86db79SHyon Kim 	if (registeredfunc == NULL) {
555*9e86db79SHyon Kim 	    return (HBA_STATUS_ERROR_NOT_SUPPORTED);
556*9e86db79SHyon Kim 	}
557*9e86db79SHyon Kim 	return (HBA_STATUS_OK);
558*9e86db79SHyon Kim 	}
559*9e86db79SHyon Kim 
560*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_AAE_mutex);
561*9e86db79SHyon Kim 	/*
562*9e86db79SHyon Kim 	 * if it wasnt in the simple lists,
563*9e86db79SHyon Kim 	 * look in the list for adapteraddevents
564*9e86db79SHyon Kim 	 */
565*9e86db79SHyon Kim     lap = &_hbaapi_adapteraddevents_callback_list;
566*9e86db79SHyon Kim     for (allcbp = _hbaapi_adapteraddevents_callback_list;
567*9e86db79SHyon Kim 	    allcbp != NULL;
568*9e86db79SHyon Kim 	    allcbp = allcbp->next) {
569*9e86db79SHyon Kim 	if (cbhandle != (HBA_CALLBACKHANDLE)allcbp) {
570*9e86db79SHyon Kim 	    lap = &allcbp->next;
571*9e86db79SHyon Kim 	    continue;
572*9e86db79SHyon Kim 	}
573*9e86db79SHyon Kim 	for (vhlp = allcbp->vendorhandlelist; vhlp != NULL; vhlp = vnext) {
574*9e86db79SHyon Kim 	    vnext = vhlp->next;
575*9e86db79SHyon Kim 	    /* should be HBAAPIV2 VSL to get to here */
576*9e86db79SHyon Kim 	    registeredfunc =
577*9e86db79SHyon Kim 		    vhlp->lib_info->ftable.functionTable.RemoveCallbackHandler;
578*9e86db79SHyon Kim 	    if (registeredfunc == NULL) {
579*9e86db79SHyon Kim 		continue;
580*9e86db79SHyon Kim 	    }
581*9e86db79SHyon Kim 	    (registeredfunc)(vhlp->vendorcbhandle);
582*9e86db79SHyon Kim 	    free(vhlp);
583*9e86db79SHyon Kim 	}
584*9e86db79SHyon Kim 	*lap = allcbp->next;
585*9e86db79SHyon Kim 	free(allcbp);
586*9e86db79SHyon Kim 	status = HBA_STATUS_OK;
587*9e86db79SHyon Kim 	break;
588*9e86db79SHyon Kim 	}
589*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_AAE_mutex);
590*9e86db79SHyon Kim 
591*9e86db79SHyon Kim 	/* now search smhba adapteradd events. */
592*9e86db79SHyon Kim     GRAB_MUTEX(&_smhba_AAE_mutex);
593*9e86db79SHyon Kim     lap = &_smhba_adapteraddevents_callback_list;
594*9e86db79SHyon Kim     for (allcbp = _smhba_adapteraddevents_callback_list;
595*9e86db79SHyon Kim 	allcbp != NULL;
596*9e86db79SHyon Kim 	allcbp = allcbp->next) {
597*9e86db79SHyon Kim 	if (cbhandle != (HBA_CALLBACKHANDLE)allcbp) {
598*9e86db79SHyon Kim 	    lap = &allcbp->next;
599*9e86db79SHyon Kim 	    continue;
600*9e86db79SHyon Kim 	}
601*9e86db79SHyon Kim 	for (vhlp = allcbp->vendorhandlelist; vhlp != NULL; vhlp = vnext) {
602*9e86db79SHyon Kim 	    vnext = vhlp->next;
603*9e86db79SHyon Kim 	    /* should be SMHBA VSL to get to here */
604*9e86db79SHyon Kim 	    registeredfunc =
605*9e86db79SHyon Kim 		    vhlp->lib_info->
606*9e86db79SHyon Kim 			ftable.smhbafunctionTable.RemoveCallbackHandler;
607*9e86db79SHyon Kim 	    if (registeredfunc == NULL) {
608*9e86db79SHyon Kim 		continue;
609*9e86db79SHyon Kim 	    }
610*9e86db79SHyon Kim 	    (registeredfunc)(vhlp->vendorcbhandle);
611*9e86db79SHyon Kim 	    free(vhlp);
612*9e86db79SHyon Kim 	}
613*9e86db79SHyon Kim 	*lap = allcbp->next;
614*9e86db79SHyon Kim 	free(allcbp);
615*9e86db79SHyon Kim 	status = HBA_STATUS_OK;
616*9e86db79SHyon Kim 	break;
617*9e86db79SHyon Kim 	}
618*9e86db79SHyon Kim     RELEASE_MUTEX(&_smhba_AAE_mutex);
619*9e86db79SHyon Kim 
620*9e86db79SHyon Kim     return (status);
621*9e86db79SHyon Kim }
622*9e86db79SHyon Kim 
623*9e86db79SHyon Kim /* LINTED E_STATIC_UE_STATIC_UNUSED */
624*9e86db79SHyon Kim static char wwn_str1[17];
625*9e86db79SHyon Kim /* LINTED E_STATIC_UE_STATIC_UNUSED */
626*9e86db79SHyon Kim static char wwn_str2[17];
627*9e86db79SHyon Kim /* LINTED E_STATIC_UE_STATIC_UNUSED */
628*9e86db79SHyon Kim static char wwn_str3[17];
629*9e86db79SHyon Kim #define	WWN2STR1(wwn) WWN2str(wwn_str1, (wwn))
630*9e86db79SHyon Kim #define	WWN2STR2(wwn) WWN2str(wwn_str2, (wwn))
631*9e86db79SHyon Kim #define	WWN2STR3(wwn) WWN2str(wwn_str3, (wwn))
632*9e86db79SHyon Kim static char *
633*9e86db79SHyon Kim /* LINTED E_STATIC_UE_STATIC_UNUSED */
634*9e86db79SHyon Kim WWN2str(char *buf, HBA_WWN *wwn) {
635*9e86db79SHyon Kim     int j;
636*9e86db79SHyon Kim     unsigned char *pc = (unsigned char *)&(wwn->wwn[0]);
637*9e86db79SHyon Kim     buf[0] = '\0';
638*9e86db79SHyon Kim     for (j = 0; j < 16; j += 2) {
639*9e86db79SHyon Kim 		(void) sprintf(&buf[j], "%02X", (int)*pc++);
640*9e86db79SHyon Kim 	}
641*9e86db79SHyon Kim     return (buf);
642*9e86db79SHyon Kim }
643*9e86db79SHyon Kim 
644*9e86db79SHyon Kim #ifdef WIN32
645*9e86db79SHyon Kim BOOL APIENTRY
646*9e86db79SHyon Kim DllMain(HANDLE hModule,
647*9e86db79SHyon Kim     DWORD  ul_reason_for_call,
648*9e86db79SHyon Kim     LPVOID lpReserved)
649*9e86db79SHyon Kim {
650*9e86db79SHyon Kim 	switch (ul_reason_for_call) {
651*9e86db79SHyon Kim 	case DLL_PROCESS_ATTACH:
652*9e86db79SHyon Kim 		break;
653*9e86db79SHyon Kim 	case DLL_PROCESS_DETACH:
654*9e86db79SHyon Kim 		break;
655*9e86db79SHyon Kim 	case DLL_THREAD_ATTACH:
656*9e86db79SHyon Kim 	case DLL_THREAD_DETACH:
657*9e86db79SHyon Kim 		break;
658*9e86db79SHyon Kim 	}
659*9e86db79SHyon Kim 	return (TRUE);
660*9e86db79SHyon Kim }
661*9e86db79SHyon Kim #endif
662*9e86db79SHyon Kim 
663*9e86db79SHyon Kim /*
664*9e86db79SHyon Kim  * Read in the config file and load all the specified vendor specific
665*9e86db79SHyon Kim  * libraries and perform the function registration exercise
666*9e86db79SHyon Kim  */
667*9e86db79SHyon Kim HBA_STATUS
668*9e86db79SHyon Kim HBA_LoadLibrary()
669*9e86db79SHyon Kim {
670*9e86db79SHyon Kim 	HBARegisterLibraryFunc RegisterFunc;
671*9e86db79SHyon Kim 	HBARegisterLibraryV2Func RegisterV2Func;
672*9e86db79SHyon Kim 	SMHBARegisterLibraryFunc RegisterSMHBAFunc;
673*9e86db79SHyon Kim 	HBALoadLibraryFunc	LoadLibraryFunc;
674*9e86db79SHyon Kim 	HBAGetVersionFunc	GetVersionFunc;
675*9e86db79SHyon Kim #ifdef	POSIX_THREADS
676*9e86db79SHyon Kim 	int			ret;
677*9e86db79SHyon Kim #endif
678*9e86db79SHyon Kim 	HBA_STATUS		status;
679*9e86db79SHyon Kim 	HBA_UINT32		libversion;
680*9e86db79SHyon Kim 
681*9e86db79SHyon Kim 	/* Open configuration file from known location */
682*9e86db79SHyon Kim #ifdef WIN32
683*9e86db79SHyon Kim 	LONG		lStatus;
684*9e86db79SHyon Kim 	HKEY		hkSniaHba, hkVendorLib;
685*9e86db79SHyon Kim 	FILETIME		ftLastWriteTime;
686*9e86db79SHyon Kim 	TCHAR		cSubKeyName[256];
687*9e86db79SHyon Kim 	DWORD		i, dwSize, dwType;
688*9e86db79SHyon Kim 	BYTE		byFileName[MAX_PATH];
689*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
690*9e86db79SHyon Kim 
691*9e86db79SHyon Kim 	if (_hbaapi_librarylist != NULL) {
692*9e86db79SHyon Kim 		/* this is an app programming error */
693*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR);
694*9e86db79SHyon Kim 	}
695*9e86db79SHyon Kim 
696*9e86db79SHyon Kim 	lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\SNIA\\HBA",
697*9e86db79SHyon Kim 	    0, KEY_READ, &hkSniaHba);
698*9e86db79SHyon Kim 	if (lStatus != ERROR_SUCCESS) {
699*9e86db79SHyon Kim 		/* ???Opportunity to send error msg, configuration error */
700*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR);
701*9e86db79SHyon Kim 	}
702*9e86db79SHyon Kim 	/*
703*9e86db79SHyon Kim 	 * Enumerate all the subkeys. These have the form:
704*9e86db79SHyon Kim 	 * HKLM\Software\SNIA\HBA\<Vendor id> - note that we don't care
705*9e86db79SHyon Kim 	 * what the vendor id is
706*9e86db79SHyon Kim 	 */
707*9e86db79SHyon Kim 	for (i = 0; ; i++) {
708*9e86db79SHyon Kim 		dwSize = 255;	/* how big the buffer is */
709*9e86db79SHyon Kim 		lStatus = RegEnumKeyEx(hkSniaHba, i,
710*9e86db79SHyon Kim 		    (char *)&cSubKeyName, &dwSize, NULL,
711*9e86db79SHyon Kim 		    NULL, NULL, &ftLastWriteTime);
712*9e86db79SHyon Kim 	if (lStatus == ERROR_NO_MORE_ITEMS) {
713*9e86db79SHyon Kim 		break;	/* we're done */
714*9e86db79SHyon Kim 	} else if (lStatus == ERROR_MORE_DATA) { /* buffer not big enough */
715*9e86db79SHyon Kim 		/* do whatever */
716*9e86db79SHyon Kim 		;
717*9e86db79SHyon Kim 	}
718*9e86db79SHyon Kim 	/* Now open the subkey that pertains to this vendor's library */
719*9e86db79SHyon Kim 	lStatus = RegOpenKeyEx(hkSniaHba, cSubKeyName, 0, KEY_READ,
720*9e86db79SHyon Kim 	    &hkVendorLib);
721*9e86db79SHyon Kim 	if (lStatus != ERROR_SUCCESS) {
722*9e86db79SHyon Kim 		RegCloseKey(hkSniaHba);
723*9e86db79SHyon Kim 	    /* ???Opportunity to send error msg, installation error */
724*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR);
725*9e86db79SHyon Kim 		/*
726*9e86db79SHyon Kim 		 * you may want to return something
727*9e86db79SHyon Kim 		 * else or keep trying
728*9e86db79SHyon Kim 		 */
729*9e86db79SHyon Kim 	}
730*9e86db79SHyon Kim 	/*
731*9e86db79SHyon Kim 	 * The name of the library is contained in a REG_SZ Value
732*9e86db79SHyon Kim 	 * keyed to "LibraryFile"
733*9e86db79SHyon Kim 	 */
734*9e86db79SHyon Kim 	dwSize = MAX_PATH;
735*9e86db79SHyon Kim 	lStatus = RegQueryValueEx(hkVendorLib, "LibraryFile", NULL, &dwType,
736*9e86db79SHyon Kim 	    byFileName, &dwSize);
737*9e86db79SHyon Kim 	if (lStatus != ERROR_SUCCESS) {
738*9e86db79SHyon Kim 		RegCloseKey(hkVendorLib);
739*9e86db79SHyon Kim 	    /* ???Opportunity to send error msg, installation error */
740*9e86db79SHyon Kim 		continue;
741*9e86db79SHyon Kim 	}
742*9e86db79SHyon Kim 	lib_infop = (HBA_LIBRARY_INFO *)calloc(1, sizeof (HBA_LIBRARY_INFO));
743*9e86db79SHyon Kim 	if (lib_infop == NULL) {
744*9e86db79SHyon Kim 	    /* what is the right thing to do in MS land??? */
745*9e86db79SHyon Kim 		RegCloseKey(hkVendorLib);
746*9e86db79SHyon Kim 		/* ???Opportunity to send error msg, installation error */
747*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR);
748*9e86db79SHyon Kim 	}
749*9e86db79SHyon Kim 	lib_infop->status = HBA_LIBRARY_NOT_LOADED;
750*9e86db79SHyon Kim 	lib_infop->next = _hbaapi_librarylist;
751*9e86db79SHyon Kim 	lib_infop->index = _hbaapi_total_library_count;
752*9e86db79SHyon Kim 	_hbaapi_total_library_count++;
753*9e86db79SHyon Kim 	_hbaapi_librarylist = lib_infop;
754*9e86db79SHyon Kim 
755*9e86db79SHyon Kim 	/* Now I can try to load the library */
756*9e86db79SHyon Kim 	lib_infop->hLibrary = LoadLibrary(byFileName);
757*9e86db79SHyon Kim 	if (lib_infop->hLibrary == NULL) {
758*9e86db79SHyon Kim 	    /* printf("unable to load library %s\n", librarypath); */
759*9e86db79SHyon Kim 	    /* ???Opportunity to send error msg, installation error */
760*9e86db79SHyon Kim 		goto dud_library;
761*9e86db79SHyon Kim 	}
762*9e86db79SHyon Kim 	lib_infop->LibraryPath = strdup(byFileName);
763*9e86db79SHyon Kim 	DEBUG(1, "HBAAPI loading: %s\n", byFileName, 0, 0);
764*9e86db79SHyon Kim 
765*9e86db79SHyon Kim 	RegisterSMHBAFunc = (SMHBARegisterLibraryFunc)
766*9e86db79SHyon Kim 	    GetProcAddress(lib_infop->hLibrary, "SMHBA_RegisterLibrary");
767*9e86db79SHyon Kim 	if (RegisterSMHBAFunc != NULL) {
768*9e86db79SHyon Kim 		status = ((RegisterSMHBAFunc)(SMHBA_ENTRYPOINTS *)
769*9e86db79SHyon Kim 		    (&lib_infop->ftable.smhbafunctionTable));
770*9e86db79SHyon Kim 		if (status != HBA_STATUS_OK) {
771*9e86db79SHyon Kim 			/* library not loaded */
772*9e86db79SHyon Kim 			/* ???Opportunity to send error msg, library error? */
773*9e86db79SHyon Kim 			goto dud_library;
774*9e86db79SHyon Kim 		} else {
775*9e86db79SHyon Kim 			lib_infop->version = SMHBA;
776*9e86db79SHyon Kim 		}
777*9e86db79SHyon Kim 	} else {
778*9e86db79SHyon Kim 	    /* Call the registration function to get the list of pointers */
779*9e86db79SHyon Kim 		RegisterV2Func = (HBARegisterLibraryV2Func)GetProcAddress(
780*9e86db79SHyon Kim 		    lib_infop->hLibrary, "HBA_RegisterLibraryV2");
781*9e86db79SHyon Kim 		if (RegisterV2Func != NULL) {
782*9e86db79SHyon Kim 		/*
783*9e86db79SHyon Kim 		 * Load the function pointers directly into
784*9e86db79SHyon Kim 		 * the table of functions
785*9e86db79SHyon Kim 		 */
786*9e86db79SHyon Kim 		status = ((RegisterV2Func)
787*9e86db79SHyon Kim 		    (HBA_ENTRYPOINTSV2 *)(&lib_infop->ftable.functionTable));
788*9e86db79SHyon Kim 		if (status != HBA_STATUS_OK) {
789*9e86db79SHyon Kim 		    /* library not loaded */
790*9e86db79SHyon Kim 		    /* ???Opportunity to send error msg, library error? */
791*9e86db79SHyon Kim 			goto dud_library;
792*9e86db79SHyon Kim 		} else {
793*9e86db79SHyon Kim 			lib_infop->version = HBAAPIV2;
794*9e86db79SHyon Kim 		}
795*9e86db79SHyon Kim 		} else {
796*9e86db79SHyon Kim 		/* Maybe the vendor library is only Rev1 */
797*9e86db79SHyon Kim 		RegisterFunc = (HBARegisterLibraryFunc)
798*9e86db79SHyon Kim 		    GetProcAddress(lib_infop->hLibrary, "HBA_RegisterLibrary");
799*9e86db79SHyon Kim 		if (RegisterFunc == NULL) {
800*9e86db79SHyon Kim 		    /* ???Opportunity to send error msg, library error? */
801*9e86db79SHyon Kim 			goto dud_library;
802*9e86db79SHyon Kim 		}
803*9e86db79SHyon Kim 		/*
804*9e86db79SHyon Kim 		 * Load the function points directly into
805*9e86db79SHyon Kim 		 * the Rev 2 table of functions
806*9e86db79SHyon Kim 		 */
807*9e86db79SHyon Kim 		status = ((RegisterFunc)(
808*9e86db79SHyon Kim 		    (HBA_ENTRYPOINTS *)(&lib_infop->ftable.functionTable)));
809*9e86db79SHyon Kim 		if (status != HBA_STATUS_OK) {
810*9e86db79SHyon Kim 		    /* library not loaded */
811*9e86db79SHyon Kim 		    /* ???Opportunity to send error msg, library error? */
812*9e86db79SHyon Kim 			goto dud_library;
813*9e86db79SHyon Kim 		} else {
814*9e86db79SHyon Kim 			lib_infop->version = HBAAPI;
815*9e86db79SHyon Kim 		}
816*9e86db79SHyon Kim 		}
817*9e86db79SHyon Kim 	}
818*9e86db79SHyon Kim 
819*9e86db79SHyon Kim 	/* successfully loaded library */
820*9e86db79SHyon Kim 	/*
821*9e86db79SHyon Kim 	 * SM-HBA and HBAAPI has a seperate handler for GetVersion but
822*9e86db79SHyon Kim 	 * they have the same function signature so use the same variable here.
823*9e86db79SHyon Kim 	 */
824*9e86db79SHyon Kim 	GetVersionFunc = FUNCCOMMON(lib_infop, GetVersionHandler);
825*9e86db79SHyon Kim 	if (GetVersionFunc != NULL) {
826*9e86db79SHyon Kim 		if (lib_infop->version == SMHBA) {
827*9e86db79SHyon Kim 		/* Check the version of this library before loading */
828*9e86db79SHyon Kim 		libversion = ((GetVersionFunc)());
829*9e86db79SHyon Kim #ifdef NOTDEF /* save for a later time... when it matters */
830*9e86db79SHyon Kim 		if (libversion < SMHBA_LIBVERSION) {
831*9e86db79SHyon Kim 			goto dud_library;
832*9e86db79SHyon Kim 		}
833*9e86db79SHyon Kim #endif
834*9e86db79SHyon Kim 		} else {
835*9e86db79SHyon Kim 		/* Check the version of this library before loading */
836*9e86db79SHyon Kim 	    /* Actually... This wrapper is compatible with version 1 */
837*9e86db79SHyon Kim 		libversion = ((GetVersionFunc)());
838*9e86db79SHyon Kim #ifdef NOTDEF /* save for a later time... when it matters */
839*9e86db79SHyon Kim 		if (libversion < HBA_LIBVERSION) {
840*9e86db79SHyon Kim 			goto dud_library;
841*9e86db79SHyon Kim 		}
842*9e86db79SHyon Kim #endif
843*9e86db79SHyon Kim 		}
844*9e86db79SHyon Kim 	} else {
845*9e86db79SHyon Kim 	    /* ???Opportunity to send error msg, library error? */
846*9e86db79SHyon Kim 		goto dud_library;
847*9e86db79SHyon Kim 	}
848*9e86db79SHyon Kim 
849*9e86db79SHyon Kim 	LoadLibraryFunc = FUNCCOMMON(lib_infop, LoadLibraryHandler);
850*9e86db79SHyon Kim 	if (LoadLibraryFunc == NULL) {
851*9e86db79SHyon Kim 	    /* Hmmm, dont we need to flag this in a realy big way??? */
852*9e86db79SHyon Kim 	    /* How about messages to the system event logger ??? */
853*9e86db79SHyon Kim 	    /* ???Opportunity to send error msg, library error? */
854*9e86db79SHyon Kim 		goto dud_library;
855*9e86db79SHyon Kim 	}
856*9e86db79SHyon Kim 	/* Initialize this library */
857*9e86db79SHyon Kim 	status = ((LoadLibraryFunc)());
858*9e86db79SHyon Kim 	if (status != HBA_STATUS_OK) {
859*9e86db79SHyon Kim 	    /* ???Opportunity to send error msg, library error? */
860*9e86db79SHyon Kim 		continue;
861*9e86db79SHyon Kim 	}
862*9e86db79SHyon Kim 	/* successfully loaded library */
863*9e86db79SHyon Kim 	lib_infop->status = HBA_LIBRARY_LOADED;
864*9e86db79SHyon Kim 
865*9e86db79SHyon Kim 	dud_library: /* its also just the end of the loop */
866*9e86db79SHyon Kim 	RegCloseKey(hkVendorLib);
867*9e86db79SHyon Kim 	}
868*9e86db79SHyon Kim 	RegCloseKey(hkSniaHba);
869*9e86db79SHyon Kim 
870*9e86db79SHyon Kim #else /* Unix as opposed to Win32 */
871*9e86db79SHyon Kim 	FILE		*hbaconf;
872*9e86db79SHyon Kim 	char		fullline[512];		/* line read from HBA.conf */
873*9e86db79SHyon Kim 	char		*libraryname;		/* Read in from file HBA.conf */
874*9e86db79SHyon Kim 	char		*librarypath;		/* Read in from file HBA.conf */
875*9e86db79SHyon Kim 	char		hbaConfFilePath[256];
876*9e86db79SHyon Kim 	char		*charPtr;
877*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
878*9e86db79SHyon Kim 
879*9e86db79SHyon Kim 	GRAB_MUTEX(&_hbaapi_LL_mutex);
880*9e86db79SHyon Kim 	if (_hbaapi_librarylist != NULL) {
881*9e86db79SHyon Kim 		(void) fprintf(stderr,
882*9e86db79SHyon Kim 		    "HBA_LoadLibrary: previously unfreed "
883*9e86db79SHyon Kim 		    "libraries exist, call HBA_FreeLibrary().\n");
884*9e86db79SHyon Kim 		RELEASE_MUTEX(&_hbaapi_LL_mutex);
885*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR);
886*9e86db79SHyon Kim 	}
887*9e86db79SHyon Kim 
888*9e86db79SHyon Kim 	(void) strcpy(hbaConfFilePath, "/etc/smhba.conf");
889*9e86db79SHyon Kim 
890*9e86db79SHyon Kim 	if ((hbaconf = fopen(hbaConfFilePath, "r")) == NULL) {
891*9e86db79SHyon Kim 		(void) printf("Cannot open %s\n", hbaConfFilePath);
892*9e86db79SHyon Kim 		RELEASE_MUTEX(&_hbaapi_LL_mutex);
893*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR);
894*9e86db79SHyon Kim 	}
895*9e86db79SHyon Kim 
896*9e86db79SHyon Kim 	/* Read in each line and load library */
897*9e86db79SHyon Kim 	while ((hbaconf != NULL) &&
898*9e86db79SHyon Kim 	    (fgets(fullline, sizeof (fullline), hbaconf))) {
899*9e86db79SHyon Kim 		/* Skip the comments... */
900*9e86db79SHyon Kim 		if ((fullline[0] == '#') || (fullline[0] == '\n')) {
901*9e86db79SHyon Kim 			continue;
902*9e86db79SHyon Kim 		}
903*9e86db79SHyon Kim 
904*9e86db79SHyon Kim 	/* grab first 'thing' in line (if its there) */
905*9e86db79SHyon Kim 	if ((libraryname = strtok(fullline, " \t\n")) != NULL) {
906*9e86db79SHyon Kim 		if (strlen(libraryname) >= 64) {
907*9e86db79SHyon Kim 			(void) fprintf(stderr,
908*9e86db79SHyon Kim 			    "Library name(%s) in %s is > 64 characters\n",
909*9e86db79SHyon Kim 			    libraryname, hbaConfFilePath);
910*9e86db79SHyon Kim 		}
911*9e86db79SHyon Kim 	}
912*9e86db79SHyon Kim 	/* grab second 'thing' in line (if its there) */
913*9e86db79SHyon Kim 	if ((librarypath = strtok(NULL, " \t\n")) != NULL) {
914*9e86db79SHyon Kim 		if (strlen(librarypath) >= 256) {
915*9e86db79SHyon Kim 		(void) fprintf(stderr,
916*9e86db79SHyon Kim 		    "Library path(%s) in %s is > 256 characters\n",
917*9e86db79SHyon Kim 		    librarypath, hbaConfFilePath);
918*9e86db79SHyon Kim 		}
919*9e86db79SHyon Kim 	}
920*9e86db79SHyon Kim 
921*9e86db79SHyon Kim 	/* there should be no more 'things' in the line */
922*9e86db79SHyon Kim 	if ((charPtr = strtok(NULL, " \n\t")) != NULL) {
923*9e86db79SHyon Kim 		(void) fprintf(stderr, "Extraneous characters (\"%s\") in %s\n",
924*9e86db79SHyon Kim 		    charPtr, hbaConfFilePath);
925*9e86db79SHyon Kim 	}
926*9e86db79SHyon Kim 
927*9e86db79SHyon Kim 	/* Continue to the next line if library name or path is invalid */
928*9e86db79SHyon Kim 	if (libraryname == NULL ||
929*9e86db79SHyon Kim 	    strlen(libraryname) == 0 ||
930*9e86db79SHyon Kim 	    librarypath == NULL ||
931*9e86db79SHyon Kim 	    (strlen(librarypath) == 0)) {
932*9e86db79SHyon Kim 		continue;
933*9e86db79SHyon Kim 	}
934*9e86db79SHyon Kim 
935*9e86db79SHyon Kim 	/*
936*9e86db79SHyon Kim 	 * Special case....
937*9e86db79SHyon Kim 	 * Look for loglevel
938*9e86db79SHyon Kim 	 */
939*9e86db79SHyon Kim 	if (strcmp(libraryname, "debuglevel") == 0) {
940*9e86db79SHyon Kim 		_hbaapi_debuglevel = strtol(librarypath, NULL, 10);
941*9e86db79SHyon Kim 	    /* error handling does the right thing automagically */
942*9e86db79SHyon Kim 		continue;
943*9e86db79SHyon Kim 	}
944*9e86db79SHyon Kim 
945*9e86db79SHyon Kim 	lib_infop = (HBA_LIBRARY_INFO *)calloc(1, sizeof (HBA_LIBRARY_INFO));
946*9e86db79SHyon Kim 	if (lib_infop == NULL) {
947*9e86db79SHyon Kim 		(void) fprintf(stderr, "HBA_LoadLibrary: out of memeory\n");
948*9e86db79SHyon Kim 		RELEASE_MUTEX(&_hbaapi_LL_mutex);
949*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR);
950*9e86db79SHyon Kim 	}
951*9e86db79SHyon Kim 	lib_infop->status = HBA_LIBRARY_NOT_LOADED;
952*9e86db79SHyon Kim 	lib_infop->LibraryName = strdup(libraryname);
953*9e86db79SHyon Kim 	lib_infop->LibraryPath = strdup(librarypath);
954*9e86db79SHyon Kim 	lib_infop->numOfAdapters = 0;
955*9e86db79SHyon Kim 	lib_infop->version = UNKNOWN;
956*9e86db79SHyon Kim 	lib_infop->index = _hbaapi_total_library_count;
957*9e86db79SHyon Kim 	_hbaapi_total_library_count++;
958*9e86db79SHyon Kim 	lib_infop->next = _hbaapi_librarylist;
959*9e86db79SHyon Kim 	_hbaapi_librarylist = lib_infop;
960*9e86db79SHyon Kim 
961*9e86db79SHyon Kim 	/* Load the DLL now */
962*9e86db79SHyon Kim 	if ((lib_infop->hLibrary = dlopen(librarypath, RTLD_LAZY)) == NULL) {
963*9e86db79SHyon Kim 	    /* printf("unable to load library %s\n", librarypath); */
964*9e86db79SHyon Kim 		continue;
965*9e86db79SHyon Kim 	}
966*9e86db79SHyon Kim 	/* Call the registration function to get the list of pointers */
967*9e86db79SHyon Kim 	RegisterSMHBAFunc = (SMHBARegisterLibraryFunc)
968*9e86db79SHyon Kim 	    dlsym(lib_infop->hLibrary, "SMHBA_RegisterLibrary");
969*9e86db79SHyon Kim 	if (RegisterSMHBAFunc != NULL) {
970*9e86db79SHyon Kim 		/*
971*9e86db79SHyon Kim 		 * Load the function points directly into
972*9e86db79SHyon Kim 		 * the table of functions
973*9e86db79SHyon Kim 		 */
974*9e86db79SHyon Kim 		status = ((RegisterSMHBAFunc)
975*9e86db79SHyon Kim 		    (&lib_infop->ftable.smhbafunctionTable));
976*9e86db79SHyon Kim 		if (status != HBA_STATUS_OK) {
977*9e86db79SHyon Kim 			/* library not loaded */
978*9e86db79SHyon Kim 			continue;
979*9e86db79SHyon Kim 		} else {
980*9e86db79SHyon Kim 			lib_infop->version = SMHBA;
981*9e86db79SHyon Kim 		}
982*9e86db79SHyon Kim 	} else {
983*9e86db79SHyon Kim 		RegisterV2Func = (HBARegisterLibraryV2Func)
984*9e86db79SHyon Kim 		    dlsym(lib_infop->hLibrary, "HBA_RegisterLibraryV2");
985*9e86db79SHyon Kim 		if (RegisterV2Func != NULL) {
986*9e86db79SHyon Kim 		/*
987*9e86db79SHyon Kim 		 * Load the function points directly into
988*9e86db79SHyon Kim 		 * the table of functions
989*9e86db79SHyon Kim 		 */
990*9e86db79SHyon Kim 		status = ((RegisterV2Func)((HBA_ENTRYPOINTSV2 *)
991*9e86db79SHyon Kim 		    (&lib_infop->ftable.functionTable)));
992*9e86db79SHyon Kim 		if (status != HBA_STATUS_OK) {
993*9e86db79SHyon Kim 		    /* library not loaded */
994*9e86db79SHyon Kim 			continue;
995*9e86db79SHyon Kim 		} else {
996*9e86db79SHyon Kim 			lib_infop->version = HBAAPIV2;
997*9e86db79SHyon Kim 		}
998*9e86db79SHyon Kim 		} else {
999*9e86db79SHyon Kim 		/* Maybe the vendor library is only Rev1 */
1000*9e86db79SHyon Kim 		RegisterFunc = (HBARegisterLibraryFunc)
1001*9e86db79SHyon Kim 		    dlsym(lib_infop->hLibrary, "HBA_RegisterLibrary");
1002*9e86db79SHyon Kim 		if (RegisterFunc == NULL) {
1003*9e86db79SHyon Kim 		    /* This function is required */
1004*9e86db79SHyon Kim 			(void) fprintf(stderr,
1005*9e86db79SHyon Kim 			    "HBA_LoadLibrary: vendor specific RegisterLibrary "
1006*9e86db79SHyon Kim 			    "function not found.  lib: %s\n", librarypath);
1007*9e86db79SHyon Kim 			DEBUG(1, "HBA_LoadLibrary: vendor specific "
1008*9e86db79SHyon Kim 			    "RegisterLibrary function not found.  lib: %s\n",
1009*9e86db79SHyon Kim 			    librarypath, 0, 0);
1010*9e86db79SHyon Kim 			continue;
1011*9e86db79SHyon Kim 		}
1012*9e86db79SHyon Kim 		/*
1013*9e86db79SHyon Kim 		 * Load the function points directly into
1014*9e86db79SHyon Kim 		 * the table of functions
1015*9e86db79SHyon Kim 		 */
1016*9e86db79SHyon Kim 		status = ((RegisterFunc)
1017*9e86db79SHyon Kim 		    ((HBA_ENTRYPOINTS *)(&lib_infop->ftable.functionTable)));
1018*9e86db79SHyon Kim 		if (status != HBA_STATUS_OK) {
1019*9e86db79SHyon Kim 		    /* library not loaded */
1020*9e86db79SHyon Kim 			(void) fprintf(stderr,
1021*9e86db79SHyon Kim 			    "HBA_LoadLibrary: vendor specific RegisterLibrary "
1022*9e86db79SHyon Kim 			    "function encountered an error.  lib: %s\n",
1023*9e86db79SHyon Kim 			    librarypath);
1024*9e86db79SHyon Kim 			DEBUG(1,
1025*9e86db79SHyon Kim 			    "HBA_LoadLibrary: vendor specific RegisterLibrary "
1026*9e86db79SHyon Kim 			    "function encountered an error. lib: %s\n",
1027*9e86db79SHyon Kim 			    librarypath, 0, 0);
1028*9e86db79SHyon Kim 			continue;
1029*9e86db79SHyon Kim 		} else {
1030*9e86db79SHyon Kim 			lib_infop->version = HBAAPI;
1031*9e86db79SHyon Kim 		}
1032*9e86db79SHyon Kim 		}
1033*9e86db79SHyon Kim 	}
1034*9e86db79SHyon Kim 
1035*9e86db79SHyon Kim 	/* successfully loaded library */
1036*9e86db79SHyon Kim 	/*
1037*9e86db79SHyon Kim 	 * SM-HBA and HBAAPI has a seperate handler for GetVersion but
1038*9e86db79SHyon Kim 	 * they have the same function signature so use the same variable here.
1039*9e86db79SHyon Kim 	 */
1040*9e86db79SHyon Kim 	if ((GetVersionFunc = FUNCCOMMON(lib_infop, GetVersionHandler))
1041*9e86db79SHyon Kim 	    == NULL) {
1042*9e86db79SHyon Kim 		continue;
1043*9e86db79SHyon Kim 	}
1044*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
1045*9e86db79SHyon Kim 		libversion = ((GetVersionFunc)());
1046*9e86db79SHyon Kim 		if (libversion < SMHBA_LIBVERSION) {
1047*9e86db79SHyon Kim 			(void) printf("Library version mismatch."
1048*9e86db79SHyon Kim 			    "Got %d expected %d.\n",
1049*9e86db79SHyon Kim 			    libversion, SMHBA_LIBVERSION);
1050*9e86db79SHyon Kim 			continue;
1051*9e86db79SHyon Kim 		}
1052*9e86db79SHyon Kim 	} else {
1053*9e86db79SHyon Kim 		libversion = ((GetVersionFunc)());
1054*9e86db79SHyon Kim 	    /* Check the version of this library before loading */
1055*9e86db79SHyon Kim 	    /* Actually... This wrapper is compatible with version 1 */
1056*9e86db79SHyon Kim 		if (libversion < HBA_LIBVERSION) {
1057*9e86db79SHyon Kim 			(void) printf("Library version mismatch."
1058*9e86db79SHyon Kim 			    "Got %d expected %d.\n",
1059*9e86db79SHyon Kim 			    libversion, HBA_LIBVERSION);
1060*9e86db79SHyon Kim 			continue;
1061*9e86db79SHyon Kim 		}
1062*9e86db79SHyon Kim 	}
1063*9e86db79SHyon Kim 
1064*9e86db79SHyon Kim 	DEBUG(1, "%s libversion = %d", librarypath, libversion, 0);
1065*9e86db79SHyon Kim 	LoadLibraryFunc = FUNCCOMMON(lib_infop, LoadLibraryHandler);
1066*9e86db79SHyon Kim 	if (LoadLibraryFunc == NULL) {
1067*9e86db79SHyon Kim 	    /* this function is required */
1068*9e86db79SHyon Kim 		(void) fprintf(stderr,
1069*9e86db79SHyon Kim 		    "HBA_LoadLibrary: vendor specific LoadLibrary "
1070*9e86db79SHyon Kim 		    "function not found.  lib: %s\n", librarypath);
1071*9e86db79SHyon Kim 		DEBUG(1, "HBA_LoadLibrary: vendor specific LoadLibrary "
1072*9e86db79SHyon Kim 		    "function not found.  lib: %s\n", librarypath, 0, 0);
1073*9e86db79SHyon Kim 		continue;
1074*9e86db79SHyon Kim 	}
1075*9e86db79SHyon Kim 	/* Initialize this library */
1076*9e86db79SHyon Kim 	if ((status = ((LoadLibraryFunc)())) != HBA_STATUS_OK) {
1077*9e86db79SHyon Kim 	    /* maybe this should be a printf so that we CANNOT miss it */
1078*9e86db79SHyon Kim 		(void) fprintf(stderr,
1079*9e86db79SHyon Kim 		    "HBA_LoadLibrary: Encounterd and error loading: %s",
1080*9e86db79SHyon Kim 		    librarypath);
1081*9e86db79SHyon Kim 		DEBUG(1, "Encounterd and error loading: %s", librarypath, 0, 0);
1082*9e86db79SHyon Kim 		DEBUG(1, "  HBA_STATUS: %d", status, 0, 0);
1083*9e86db79SHyon Kim 		continue;
1084*9e86db79SHyon Kim 	}
1085*9e86db79SHyon Kim 	/* successfully loaded library */
1086*9e86db79SHyon Kim 	lib_infop->status = HBA_LIBRARY_LOADED;
1087*9e86db79SHyon Kim 	}
1088*9e86db79SHyon Kim #endif /* WIN32 or UNIX */
1089*9e86db79SHyon Kim #ifdef POSIX_THREADS
1090*9e86db79SHyon Kim 	/*
1091*9e86db79SHyon Kim 	 * The _hbaapi_LL_mutex is already grabbed to proctect the caller of
1092*9e86db79SHyon Kim 	 * HBA_FreeLibrary() during loading.
1093*9e86db79SHyon Kim 	 * The mutexes are already initialized
1094*9e86db79SHyon Kim 	 * with PTHREAD_MUTEX_INITIALIZER.  Do we need to init again?
1095*9e86db79SHyon Kim 	 * Keeping the code from HBAAPI source...
1096*9e86db79SHyon Kim 	 */
1097*9e86db79SHyon Kim 	ret = pthread_mutex_init(&_hbaapi_AL_mutex, NULL);
1098*9e86db79SHyon Kim 	if (ret == 0) {
1099*9e86db79SHyon Kim 		ret = pthread_mutex_init(&_hbaapi_AAE_mutex, NULL);
1100*9e86db79SHyon Kim 	}
1101*9e86db79SHyon Kim 	if (ret == 0) {
1102*9e86db79SHyon Kim 		ret = pthread_mutex_init(&_hbaapi_AE_mutex, NULL);
1103*9e86db79SHyon Kim 	}
1104*9e86db79SHyon Kim 	if (ret == 0) {
1105*9e86db79SHyon Kim 		ret = pthread_mutex_init(&_hbaapi_APE_mutex, NULL);
1106*9e86db79SHyon Kim 	}
1107*9e86db79SHyon Kim 	if (ret == 0) {
1108*9e86db79SHyon Kim 		ret = pthread_mutex_init(&_hbaapi_APSE_mutex, NULL);
1109*9e86db79SHyon Kim 	}
1110*9e86db79SHyon Kim 	if (ret == 0) {
1111*9e86db79SHyon Kim 		ret = pthread_mutex_init(&_hbaapi_TE_mutex, NULL);
1112*9e86db79SHyon Kim 	}
1113*9e86db79SHyon Kim 	if (ret == 0) {
1114*9e86db79SHyon Kim 		ret = pthread_mutex_init(&_smhba_AAE_mutex, NULL);
1115*9e86db79SHyon Kim 	}
1116*9e86db79SHyon Kim 	if (ret == 0) {
1117*9e86db79SHyon Kim 		ret = pthread_mutex_init(&_smhba_AE_mutex, NULL);
1118*9e86db79SHyon Kim 	}
1119*9e86db79SHyon Kim 	if (ret == 0) {
1120*9e86db79SHyon Kim 		ret = pthread_mutex_init(&_smhba_APE_mutex, NULL);
1121*9e86db79SHyon Kim 	}
1122*9e86db79SHyon Kim 	if (ret == 0) {
1123*9e86db79SHyon Kim 		ret = pthread_mutex_init(&_smhba_APSE_mutex, NULL);
1124*9e86db79SHyon Kim 	}
1125*9e86db79SHyon Kim 	if (ret == 0) {
1126*9e86db79SHyon Kim 		ret = pthread_mutex_init(&_smhba_TE_mutex, NULL);
1127*9e86db79SHyon Kim 	}
1128*9e86db79SHyon Kim 	if (ret == 0) {
1129*9e86db79SHyon Kim 		ret = pthread_mutex_init(&_hbaapi_LE_mutex, NULL);
1130*9e86db79SHyon Kim 	}
1131*9e86db79SHyon Kim 	if (ret != 0) {
1132*9e86db79SHyon Kim 		perror("pthread_mutex_init - HBA_LoadLibrary");
1133*9e86db79SHyon Kim 		RELEASE_MUTEX(&_hbaapi_LL_mutex);
1134*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR);
1135*9e86db79SHyon Kim 	}
1136*9e86db79SHyon Kim 	RELEASE_MUTEX(&_hbaapi_LL_mutex);
1137*9e86db79SHyon Kim #elif defined(WIN32)
1138*9e86db79SHyon Kim 	InitializeCriticalSection(&_hbaapi_LL_mutex);
1139*9e86db79SHyon Kim 	InitializeCriticalSection(&_hbaapi_AL_mutex);
1140*9e86db79SHyon Kim 	InitializeCriticalSection(&_hbaapi_AAE_mutex);
1141*9e86db79SHyon Kim 	InitializeCriticalSection(&_hbaapi_AE_mutex);
1142*9e86db79SHyon Kim 	InitializeCriticalSection(&_hbaapi_APE_mutex);
1143*9e86db79SHyon Kim 	InitializeCriticalSection(&_hbaapi_APSE_mutex);
1144*9e86db79SHyon Kim 	InitializeCriticalSection(&_hbaapi_TE_mutex);
1145*9e86db79SHyon Kim 	InitializeCriticalSection(&_hbaapi_LE_mutex);
1146*9e86db79SHyon Kim 	InitializeCriticalSection(&_smhba_AAE_mutex);
1147*9e86db79SHyon Kim 	InitializeCriticalSection(&_smhba_AE_mutex);
1148*9e86db79SHyon Kim 	InitializeCriticalSection(&_smhba_APE_mutex);
1149*9e86db79SHyon Kim 	InitializeCriticalSection(&_smhba_APSE_mutex);
1150*9e86db79SHyon Kim 	InitializeCriticalSection(&_smhba_TE_mutex);
1151*9e86db79SHyon Kim #endif
1152*9e86db79SHyon Kim 
1153*9e86db79SHyon Kim 	return (HBA_STATUS_OK);
1154*9e86db79SHyon Kim }
1155*9e86db79SHyon Kim 
1156*9e86db79SHyon Kim HBA_STATUS
1157*9e86db79SHyon Kim HBA_FreeLibrary() {
1158*9e86db79SHyon Kim     HBAFreeLibraryFunc	FreeLibraryFunc;
1159*9e86db79SHyon Kim /* LINTED E_FUNC_SET_NOT_USED */
1160*9e86db79SHyon Kim     HBA_STATUS		status;
1161*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_infop;
1162*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_next;
1163*9e86db79SHyon Kim     HBA_ADAPTERCALLBACK_ELEM
1164*9e86db79SHyon Kim 			***listp;
1165*9e86db79SHyon Kim     HBA_ADAPTER_INFO	*adapt_infop;
1166*9e86db79SHyon Kim     HBA_ADAPTER_INFO	*adapt_next;
1167*9e86db79SHyon Kim 
1168*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_LL_mutex);
1169*9e86db79SHyon Kim     if (_hbaapi_librarylist == NULL) {
1170*9e86db79SHyon Kim 	RELEASE_MUTEX(&_hbaapi_LL_mutex);
1171*9e86db79SHyon Kim 	return (HBA_STATUS_ERROR_NOT_LOADED);
1172*9e86db79SHyon Kim 	}
1173*9e86db79SHyon Kim 
1174*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_AL_mutex);
1175*9e86db79SHyon Kim 
1176*9e86db79SHyon Kim     DEBUG(1, "HBA_FreeLibrary()", 0, 0, 0);
1177*9e86db79SHyon Kim     for (lib_infop = _hbaapi_librarylist; lib_infop != NULL;
1178*9e86db79SHyon Kim 	    lib_infop = lib_next) {
1179*9e86db79SHyon Kim 	lib_next = lib_infop->next;
1180*9e86db79SHyon Kim 	if (lib_infop->status == HBA_LIBRARY_LOADED) {
1181*9e86db79SHyon Kim 	    FreeLibraryFunc = FUNCCOMMON(lib_infop, FreeLibraryHandler);
1182*9e86db79SHyon Kim 	    if (FreeLibraryFunc != NULL) {
1183*9e86db79SHyon Kim 		/* Free this library */
1184*9e86db79SHyon Kim 		status = ((FreeLibraryFunc)());
1185*9e86db79SHyon Kim 		DEBUG(1, "HBA_FreeLibrary() Failed %d", status, 0, 0);
1186*9e86db79SHyon Kim 	    }
1187*9e86db79SHyon Kim #ifdef WIN32
1188*9e86db79SHyon Kim 	    FreeLibrary(lib_infop->hLibrary);	/* Unload DLL from memory */
1189*9e86db79SHyon Kim #else
1190*9e86db79SHyon Kim 	    (void) dlclose(lib_infop->hLibrary); /* Unload DLL from memory */
1191*9e86db79SHyon Kim #endif
1192*9e86db79SHyon Kim 	}
1193*9e86db79SHyon Kim #ifndef WIN32
1194*9e86db79SHyon Kim 	free(lib_infop->LibraryName);
1195*9e86db79SHyon Kim #endif
1196*9e86db79SHyon Kim 	free(lib_infop->LibraryPath);
1197*9e86db79SHyon Kim 	free(lib_infop);
1198*9e86db79SHyon Kim 
1199*9e86db79SHyon Kim 	}
1200*9e86db79SHyon Kim     _hbaapi_librarylist = NULL;
1201*9e86db79SHyon Kim 	/*
1202*9e86db79SHyon Kim 	 * OK, now all functions are disabled except for LoadLibrary,
1203*9e86db79SHyon Kim 	 * Hope no other thread calls it before we have returned
1204*9e86db79SHyon Kim 	 */
1205*9e86db79SHyon Kim     _hbaapi_total_library_count = 0;
1206*9e86db79SHyon Kim 
1207*9e86db79SHyon Kim     for (adapt_infop = _hbaapi_adapterlist;
1208*9e86db79SHyon Kim 	    adapt_infop != NULL;
1209*9e86db79SHyon Kim 	    adapt_infop = adapt_next) {
1210*9e86db79SHyon Kim 		adapt_next = adapt_infop->next;
1211*9e86db79SHyon Kim 		free(adapt_infop->name);
1212*9e86db79SHyon Kim 		free(adapt_infop);
1213*9e86db79SHyon Kim 	}
1214*9e86db79SHyon Kim     _hbaapi_adapterlist = NULL;
1215*9e86db79SHyon Kim     _hbaapi_total_adapter_count = 0;
1216*9e86db79SHyon Kim 
1217*9e86db79SHyon Kim 	/*
1218*9e86db79SHyon Kim 	 * Free up the callbacks, this is not the most efficient, but it works
1219*9e86db79SHyon Kim 	 */
1220*9e86db79SHyon Kim 	while ((volatile HBA_ADAPTERCALLBACK_ELEM *)
1221*9e86db79SHyon Kim 	    _hbaapi_adapteraddevents_callback_list
1222*9e86db79SHyon Kim 	    != NULL) {
1223*9e86db79SHyon Kim 	(void) local_remove_callback((HBA_CALLBACKHANDLE)
1224*9e86db79SHyon Kim 	    _hbaapi_adapteraddevents_callback_list);
1225*9e86db79SHyon Kim 	}
1226*9e86db79SHyon Kim 	while ((volatile HBA_ADAPTERCALLBACK_ELEM *)
1227*9e86db79SHyon Kim 	    _smhba_adapteraddevents_callback_list
1228*9e86db79SHyon Kim 	    != NULL) {
1229*9e86db79SHyon Kim 	(void) local_remove_callback((HBA_CALLBACKHANDLE)
1230*9e86db79SHyon Kim 	    _smhba_adapteraddevents_callback_list);
1231*9e86db79SHyon Kim 	}
1232*9e86db79SHyon Kim     for (listp = cb_lists_array; *listp != NULL; listp++) {
1233*9e86db79SHyon Kim 	while ((volatile HBA_ADAPTERCALLBACK_ELEM ***)**listp != NULL) {
1234*9e86db79SHyon Kim 	    (void) local_remove_callback((HBA_CALLBACKHANDLE)**listp);
1235*9e86db79SHyon Kim 	}
1236*9e86db79SHyon Kim 	}
1237*9e86db79SHyon Kim 
1238*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_AL_mutex);
1239*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_LL_mutex);
1240*9e86db79SHyon Kim 
1241*9e86db79SHyon Kim #ifdef USESYSLOG
1242*9e86db79SHyon Kim     closelog();
1243*9e86db79SHyon Kim #endif
1244*9e86db79SHyon Kim #ifdef USELOGFILE
1245*9e86db79SHyon Kim     if (_hbaapi_debug_fd != NULL) {
1246*9e86db79SHyon Kim 	fclose(_hbaapi_debug_fd);
1247*9e86db79SHyon Kim 	}
1248*9e86db79SHyon Kim     _hbaapi_debug_fd = NULL;
1249*9e86db79SHyon Kim #endif
1250*9e86db79SHyon Kim #ifdef POSIX_THREADS
1251*9e86db79SHyon Kim 	/* this will unlock them as well, but who cares */
1252*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_hbaapi_LE_mutex);
1253*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_hbaapi_TE_mutex);
1254*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_hbaapi_APSE_mutex);
1255*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_hbaapi_APE_mutex);
1256*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_hbaapi_AE_mutex);
1257*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_hbaapi_AAE_mutex);
1258*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_smhba_TE_mutex);
1259*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_smhba_APSE_mutex);
1260*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_smhba_APE_mutex);
1261*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_smhba_AE_mutex);
1262*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_smhba_AAE_mutex);
1263*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_hbaapi_AL_mutex);
1264*9e86db79SHyon Kim 	(void) pthread_mutex_destroy(&_hbaapi_LL_mutex);
1265*9e86db79SHyon Kim #elif defined(WIN32)
1266*9e86db79SHyon Kim     DeleteCriticalSection(&_hbaapi_LL_mutex);
1267*9e86db79SHyon Kim     DeleteCriticalSection(&_hbaapi_AL_mutex);
1268*9e86db79SHyon Kim     DeleteCriticalSection(&_hbaapi_AAE_mutex);
1269*9e86db79SHyon Kim     DeleteCriticalSection(&_hbaapi_AE_mutex);
1270*9e86db79SHyon Kim     DeleteCriticalSection(&_hbaapi_APE_mutex);
1271*9e86db79SHyon Kim     DeleteCriticalSection(&_hbaapi_APSE_mutex);
1272*9e86db79SHyon Kim     DeleteCriticalSection(&_hbaapi_TE_mutex);
1273*9e86db79SHyon Kim     DeleteCriticalSection(&_hbaapi_LE_mutex);
1274*9e86db79SHyon Kim     DeleteCriticalSection(&_smhba_TE_mutex);
1275*9e86db79SHyon Kim     DeleteCriticalSection(&_smhba_APSE_mutex);
1276*9e86db79SHyon Kim     DeleteCriticalSection(&_smhba_APE_mutex);
1277*9e86db79SHyon Kim     DeleteCriticalSection(&_smhba_AE_mutex);
1278*9e86db79SHyon Kim     DeleteCriticalSection(&_smhba_AAE_mutex);
1279*9e86db79SHyon Kim #endif
1280*9e86db79SHyon Kim 
1281*9e86db79SHyon Kim 	return (HBA_STATUS_OK);
1282*9e86db79SHyon Kim }
1283*9e86db79SHyon Kim 
1284*9e86db79SHyon Kim /*
1285*9e86db79SHyon Kim  * The API used to use fixed size tables as its primary data structure.
1286*9e86db79SHyon Kim  * Indexing from 1 to N identified each adapters.  Now the adapters are
1287*9e86db79SHyon Kim  * on a linked list.  There is a unique "index" foreach each adapter.
1288*9e86db79SHyon Kim  * Adapters always keep their index, even if they are removed from the
1289*9e86db79SHyon Kim  * hardware.  The only time the indexing is reset is on HBA_FreeLibrary
1290*9e86db79SHyon Kim  */
1291*9e86db79SHyon Kim HBA_UINT32
1292*9e86db79SHyon Kim HBA_GetNumberOfAdapters()
1293*9e86db79SHyon Kim {
1294*9e86db79SHyon Kim 	int j = 0;
1295*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
1296*9e86db79SHyon Kim 	HBAGetNumberOfAdaptersFunc GetNumberOfAdaptersFunc;
1297*9e86db79SHyon Kim 	HBAGetAdapterNameFunc GetAdapterNameFunc;
1298*9e86db79SHyon Kim 	HBA_BOOLEAN		found_name;
1299*9e86db79SHyon Kim 	HBA_ADAPTER_INFO	*adapt_infop;
1300*9e86db79SHyon Kim 	HBA_STATUS		status;
1301*9e86db79SHyon Kim 
1302*9e86db79SHyon Kim 	char adaptername[256];
1303*9e86db79SHyon Kim 	int num_adapters; /* local */
1304*9e86db79SHyon Kim 
1305*9e86db79SHyon Kim 	if (_hbaapi_librarylist == NULL) {
1306*9e86db79SHyon Kim 		return (0);
1307*9e86db79SHyon Kim 	}
1308*9e86db79SHyon Kim 	GRAB_MUTEX(&_hbaapi_LL_mutex); /* pay attention to order */
1309*9e86db79SHyon Kim 	GRAB_MUTEX(&_hbaapi_AL_mutex);
1310*9e86db79SHyon Kim 
1311*9e86db79SHyon Kim 	for (lib_infop = _hbaapi_librarylist;
1312*9e86db79SHyon Kim 	    lib_infop != NULL;
1313*9e86db79SHyon Kim 	    lib_infop = lib_infop->next) {
1314*9e86db79SHyon Kim 
1315*9e86db79SHyon Kim 	if (lib_infop->status != HBA_LIBRARY_LOADED) {
1316*9e86db79SHyon Kim 		continue;
1317*9e86db79SHyon Kim 	}
1318*9e86db79SHyon Kim 
1319*9e86db79SHyon Kim 	GetNumberOfAdaptersFunc =
1320*9e86db79SHyon Kim 	    FUNCCOMMON(lib_infop, GetNumberOfAdaptersHandler);
1321*9e86db79SHyon Kim 	if (GetNumberOfAdaptersFunc == NULL)  {
1322*9e86db79SHyon Kim 		continue;
1323*9e86db79SHyon Kim 	}
1324*9e86db79SHyon Kim 	num_adapters = ((GetNumberOfAdaptersFunc)());
1325*9e86db79SHyon Kim #ifndef WIN32
1326*9e86db79SHyon Kim 	DEBUG(1, "HBAAPI: num_adapters for %s = %d\n",
1327*9e86db79SHyon Kim 	    lib_infop->LibraryName, num_adapters, 0);
1328*9e86db79SHyon Kim #else
1329*9e86db79SHyon Kim 	DEBUG(1, "HBAAPI: num_adapters for %s = %d\n",
1330*9e86db79SHyon Kim 	    lib_infop->LibraryPath, num_adapters, 0);
1331*9e86db79SHyon Kim #endif
1332*9e86db79SHyon Kim 
1333*9e86db79SHyon Kim 	/* Also get the names of all the adapters here and cache */
1334*9e86db79SHyon Kim 	GetAdapterNameFunc = FUNCCOMMON(lib_infop, GetAdapterNameHandler);
1335*9e86db79SHyon Kim 	if (GetAdapterNameFunc == NULL) {
1336*9e86db79SHyon Kim 		continue;
1337*9e86db79SHyon Kim 	}
1338*9e86db79SHyon Kim 
1339*9e86db79SHyon Kim 	for (j = 0; j < num_adapters; j++) {
1340*9e86db79SHyon Kim 		found_name = 0;
1341*9e86db79SHyon Kim 		status = (GetAdapterNameFunc)(j, (char *)&adaptername);
1342*9e86db79SHyon Kim 		if (status == HBA_STATUS_OK) {
1343*9e86db79SHyon Kim 		for (adapt_infop = _hbaapi_adapterlist;
1344*9e86db79SHyon Kim 		    adapt_infop != NULL;
1345*9e86db79SHyon Kim 		    adapt_infop = adapt_infop->next) {
1346*9e86db79SHyon Kim 			/*
1347*9e86db79SHyon Kim 			 * check for duplicates, really,
1348*9e86db79SHyon Kim 			 * this may just be a second
1349*9e86db79SHyon Kim 			 * call to this function
1350*9e86db79SHyon Kim 			 * ??? how do we know when a name becomes stale?
1351*9e86db79SHyon Kim 			 */
1352*9e86db79SHyon Kim 			if (strcmp(adaptername, adapt_infop->name) == 0) {
1353*9e86db79SHyon Kim 				/* already got this one */
1354*9e86db79SHyon Kim 				found_name++;
1355*9e86db79SHyon Kim 			break;
1356*9e86db79SHyon Kim 			}
1357*9e86db79SHyon Kim 		}
1358*9e86db79SHyon Kim 		if (found_name != 0) {
1359*9e86db79SHyon Kim 			continue;
1360*9e86db79SHyon Kim 		}
1361*9e86db79SHyon Kim 		}
1362*9e86db79SHyon Kim 
1363*9e86db79SHyon Kim 		adapt_infop = (HBA_ADAPTER_INFO *)
1364*9e86db79SHyon Kim 		    calloc(1, sizeof (HBA_ADAPTER_INFO));
1365*9e86db79SHyon Kim 		if (adapt_infop == NULL) {
1366*9e86db79SHyon Kim #ifndef WIN32
1367*9e86db79SHyon Kim 		(void) fprintf(stderr,
1368*9e86db79SHyon Kim 		    "HBA_GetNumberOfAdapters: calloc failed"
1369*9e86db79SHyon Kim 		    " on sizeof:%lu\n",
1370*9e86db79SHyon Kim 		    (unsigned long)(sizeof (HBA_ADAPTER_INFO)));
1371*9e86db79SHyon Kim #endif
1372*9e86db79SHyon Kim 		RELEASE_MUTEX(&_hbaapi_AL_mutex);
1373*9e86db79SHyon Kim 		RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
1374*9e86db79SHyon Kim 		    _hbaapi_total_adapter_count);
1375*9e86db79SHyon Kim 		}
1376*9e86db79SHyon Kim 		if ((adapt_infop->GNstatus = status) == HBA_STATUS_OK) {
1377*9e86db79SHyon Kim 		adapt_infop->name = strdup(adaptername);
1378*9e86db79SHyon Kim 		} else {
1379*9e86db79SHyon Kim 		char dummyname[512];
1380*9e86db79SHyon Kim 		(void) sprintf(dummyname, "NULLADAPTER-%255s-%03d",
1381*9e86db79SHyon Kim 		    lib_infop->LibraryPath, _hbaapi_total_adapter_count);
1382*9e86db79SHyon Kim 		dummyname[511] = '\0';
1383*9e86db79SHyon Kim 		adapt_infop->name = strdup(dummyname);
1384*9e86db79SHyon Kim 		}
1385*9e86db79SHyon Kim 		lib_infop->numOfAdapters++;
1386*9e86db79SHyon Kim 		adapt_infop->library = lib_infop;
1387*9e86db79SHyon Kim 		adapt_infop->next = _hbaapi_adapterlist;
1388*9e86db79SHyon Kim 		adapt_infop->index = _hbaapi_total_adapter_count;
1389*9e86db79SHyon Kim 		_hbaapi_adapterlist = adapt_infop;
1390*9e86db79SHyon Kim 		_hbaapi_total_adapter_count++;
1391*9e86db79SHyon Kim 	}
1392*9e86db79SHyon Kim 	}
1393*9e86db79SHyon Kim 	RELEASE_MUTEX(&_hbaapi_AL_mutex);
1394*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, _hbaapi_total_adapter_count);
1395*9e86db79SHyon Kim }
1396*9e86db79SHyon Kim 
1397*9e86db79SHyon Kim HBA_STATUS
1398*9e86db79SHyon Kim HBA_GetAdapterName(
1399*9e86db79SHyon Kim     HBA_UINT32 adapterindex,
1400*9e86db79SHyon Kim     char *adaptername)
1401*9e86db79SHyon Kim {
1402*9e86db79SHyon Kim 	HBA_ADAPTER_INFO	*adapt_infop;
1403*9e86db79SHyon Kim 	HBA_STATUS		ret = HBA_STATUS_ERROR_ILLEGAL_INDEX;
1404*9e86db79SHyon Kim 
1405*9e86db79SHyon Kim 	if (adaptername == NULL) {
1406*9e86db79SHyon Kim 		DEBUG(1, "HBA_GetAdapterName: NULL pointer adatpername",
1407*9e86db79SHyon Kim 		    0, 0, 0);
1408*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR_ARG);
1409*9e86db79SHyon Kim 	}
1410*9e86db79SHyon Kim 
1411*9e86db79SHyon Kim 	/*
1412*9e86db79SHyon Kim 	 * The adapter index is from old code, but we have
1413*9e86db79SHyon Kim 	 * to support it.  Go down the list looking for
1414*9e86db79SHyon Kim 	 * the adapter
1415*9e86db79SHyon Kim 	 */
1416*9e86db79SHyon Kim 	ARE_WE_INITED();
1417*9e86db79SHyon Kim 	GRAB_MUTEX(&_hbaapi_AL_mutex);
1418*9e86db79SHyon Kim 	*adaptername = '\0';
1419*9e86db79SHyon Kim 	for (adapt_infop = _hbaapi_adapterlist;
1420*9e86db79SHyon Kim 	    adapt_infop != NULL;
1421*9e86db79SHyon Kim 	    adapt_infop = adapt_infop->next) {
1422*9e86db79SHyon Kim 
1423*9e86db79SHyon Kim 	if (adapt_infop->index == adapterindex) {
1424*9e86db79SHyon Kim 		if (adapt_infop->name != NULL &&
1425*9e86db79SHyon Kim 		    adapt_infop->GNstatus == HBA_STATUS_OK) {
1426*9e86db79SHyon Kim 		(void) strcpy(adaptername, adapt_infop->name);
1427*9e86db79SHyon Kim 		} else {
1428*9e86db79SHyon Kim 		*adaptername = '\0';
1429*9e86db79SHyon Kim 		}
1430*9e86db79SHyon Kim 		ret = adapt_infop->GNstatus;
1431*9e86db79SHyon Kim 		break;
1432*9e86db79SHyon Kim 	}
1433*9e86db79SHyon Kim 	}
1434*9e86db79SHyon Kim 	DEBUG(2, "GetAdapterName for index:%d ->%s",
1435*9e86db79SHyon Kim 	    adapterindex, adaptername, 0);
1436*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, ret);
1437*9e86db79SHyon Kim }
1438*9e86db79SHyon Kim 
1439*9e86db79SHyon Kim HBA_HANDLE
1440*9e86db79SHyon Kim HBA_OpenAdapter(char *adaptername)
1441*9e86db79SHyon Kim {
1442*9e86db79SHyon Kim 	HBA_HANDLE		handle;
1443*9e86db79SHyon Kim 	HBAOpenAdapterFunc	OpenAdapterFunc;
1444*9e86db79SHyon Kim 	HBA_ADAPTER_INFO	*adapt_infop;
1445*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
1446*9e86db79SHyon Kim 
1447*9e86db79SHyon Kim 	DEBUG(2, "OpenAdapter: %s", adaptername, 0, 0);
1448*9e86db79SHyon Kim 
1449*9e86db79SHyon Kim 	handle = HBA_HANDLE_INVALID;
1450*9e86db79SHyon Kim 	if (_hbaapi_librarylist == NULL) {
1451*9e86db79SHyon Kim 		return (handle);
1452*9e86db79SHyon Kim 	}
1453*9e86db79SHyon Kim 	if (adaptername == NULL) {
1454*9e86db79SHyon Kim 		DEBUG(1, "HBA_OpenAdapter: NULL pointer adatpername",
1455*9e86db79SHyon Kim 		    0, 0, 0);
1456*9e86db79SHyon Kim 		return (handle);
1457*9e86db79SHyon Kim 	}
1458*9e86db79SHyon Kim 	GRAB_MUTEX(&_hbaapi_AL_mutex);
1459*9e86db79SHyon Kim 	for (adapt_infop = _hbaapi_adapterlist;
1460*9e86db79SHyon Kim 	    adapt_infop != NULL;
1461*9e86db79SHyon Kim 	    adapt_infop = adapt_infop->next) {
1462*9e86db79SHyon Kim 	if (strcmp(adaptername, adapt_infop->name) != 0) {
1463*9e86db79SHyon Kim 		continue;
1464*9e86db79SHyon Kim 	}
1465*9e86db79SHyon Kim 	lib_infop = adapt_infop->library;
1466*9e86db79SHyon Kim 	OpenAdapterFunc = FUNCCOMMON(lib_infop, OpenAdapterHandler);
1467*9e86db79SHyon Kim 
1468*9e86db79SHyon Kim 	if (OpenAdapterFunc != NULL) {
1469*9e86db79SHyon Kim 	    /* retrieve the vendor handle */
1470*9e86db79SHyon Kim 		handle = (OpenAdapterFunc)(adaptername);
1471*9e86db79SHyon Kim 		if (handle != 0) {
1472*9e86db79SHyon Kim 		/* or this with the library index to get the common handle */
1473*9e86db79SHyon Kim 		handle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle);
1474*9e86db79SHyon Kim 		}
1475*9e86db79SHyon Kim 	}
1476*9e86db79SHyon Kim 	break;
1477*9e86db79SHyon Kim 	}
1478*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, handle);
1479*9e86db79SHyon Kim }
1480*9e86db79SHyon Kim 
1481*9e86db79SHyon Kim /*
1482*9e86db79SHyon Kim  * Finding an adapter with matching WWN.
1483*9e86db79SHyon Kim  */
1484*9e86db79SHyon Kim HBA_STATUS
1485*9e86db79SHyon Kim HBA_OpenAdapterByWWN(HBA_HANDLE *phandle, HBA_WWN nodeWWN) {
1486*9e86db79SHyon Kim     HBA_HANDLE		handle;
1487*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_infop;
1488*9e86db79SHyon Kim     HBAGetNumberOfAdaptersFunc
1489*9e86db79SHyon Kim 			GetNumberOfAdaptersFunc;
1490*9e86db79SHyon Kim     HBAOpenAdapterByWWNFunc
1491*9e86db79SHyon Kim 			OpenAdapterFunc;
1492*9e86db79SHyon Kim     HBA_STATUS		status;
1493*9e86db79SHyon Kim 
1494*9e86db79SHyon Kim     DEBUG(2, "OpenAdapterByWWN: %s", WWN2STR1(&nodeWWN), 0, 0);
1495*9e86db79SHyon Kim     ARE_WE_INITED();
1496*9e86db79SHyon Kim 
1497*9e86db79SHyon Kim 	*phandle = HBA_HANDLE_INVALID;
1498*9e86db79SHyon Kim 
1499*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_LL_mutex);
1500*9e86db79SHyon Kim     for (lib_infop = _hbaapi_librarylist;
1501*9e86db79SHyon Kim 	    lib_infop != NULL;
1502*9e86db79SHyon Kim 	    lib_infop = lib_infop->next) {
1503*9e86db79SHyon Kim 
1504*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_ILLEGAL_WWN;
1505*9e86db79SHyon Kim 
1506*9e86db79SHyon Kim 	if (lib_infop->status != HBA_LIBRARY_LOADED) {
1507*9e86db79SHyon Kim 	    continue;
1508*9e86db79SHyon Kim 	}
1509*9e86db79SHyon Kim 
1510*9e86db79SHyon Kim 	/* only for HBAAPIV2 */
1511*9e86db79SHyon Kim 	if (lib_infop->version != HBAAPIV2) {
1512*9e86db79SHyon Kim 	    continue;
1513*9e86db79SHyon Kim 	}
1514*9e86db79SHyon Kim 
1515*9e86db79SHyon Kim 	GetNumberOfAdaptersFunc =
1516*9e86db79SHyon Kim 		FUNCCOMMON(lib_infop, GetNumberOfAdaptersHandler);
1517*9e86db79SHyon Kim 	if (GetNumberOfAdaptersFunc == NULL)  {
1518*9e86db79SHyon Kim 	    continue;
1519*9e86db79SHyon Kim 	}
1520*9e86db79SHyon Kim 
1521*9e86db79SHyon Kim 	/* look for new hardware */
1522*9e86db79SHyon Kim 	(void) ((GetNumberOfAdaptersFunc)());
1523*9e86db79SHyon Kim 
1524*9e86db79SHyon Kim 	OpenAdapterFunc =
1525*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.OpenAdapterByWWNHandler;
1526*9e86db79SHyon Kim 	if (OpenAdapterFunc == NULL) {
1527*9e86db79SHyon Kim 	    continue;
1528*9e86db79SHyon Kim 	}
1529*9e86db79SHyon Kim 	/*
1530*9e86db79SHyon Kim 	 * We do not know if the WWN is known by this vendor,
1531*9e86db79SHyon Kim 	 * just try it
1532*9e86db79SHyon Kim 	 */
1533*9e86db79SHyon Kim 	if ((status = (OpenAdapterFunc)(&handle, nodeWWN)) != HBA_STATUS_OK) {
1534*9e86db79SHyon Kim 	    continue;
1535*9e86db79SHyon Kim 	}
1536*9e86db79SHyon Kim 	/* OK, make a vendor non-specific handle */
1537*9e86db79SHyon Kim 	*phandle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle);
1538*9e86db79SHyon Kim 	status = HBA_STATUS_OK;
1539*9e86db79SHyon Kim 	break;
1540*9e86db79SHyon Kim 	}
1541*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1542*9e86db79SHyon Kim }
1543*9e86db79SHyon Kim 
1544*9e86db79SHyon Kim void
1545*9e86db79SHyon Kim HBA_RefreshAdapterConfiguration() {
1546*9e86db79SHyon Kim     DEBUG(2, "HBA_RefreshAdapterConfiguration", 0, 0, 0);
1547*9e86db79SHyon Kim 	(void) HBA_GetNumberOfAdapters();
1548*9e86db79SHyon Kim }
1549*9e86db79SHyon Kim 
1550*9e86db79SHyon Kim HBA_UINT32
1551*9e86db79SHyon Kim HBA_GetVersion() {
1552*9e86db79SHyon Kim     DEBUG(2, "HBA_GetVersion", 0, 0, 0);
1553*9e86db79SHyon Kim 	return (HBA_LIBVERSION);
1554*9e86db79SHyon Kim }
1555*9e86db79SHyon Kim 
1556*9e86db79SHyon Kim /*
1557*9e86db79SHyon Kim  * This function is VERY OS dependent.  Wing it as best you can.
1558*9e86db79SHyon Kim  */
1559*9e86db79SHyon Kim HBA_UINT32
1560*9e86db79SHyon Kim HBA_GetWrapperLibraryAttributes(
1561*9e86db79SHyon Kim     HBA_LIBRARYATTRIBUTES *attributes)
1562*9e86db79SHyon Kim {
1563*9e86db79SHyon Kim 
1564*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetWrapperLibraryAttributes", 0, 0, 0);
1565*9e86db79SHyon Kim 
1566*9e86db79SHyon Kim 	if (attributes == NULL) {
1567*9e86db79SHyon Kim 		DEBUG(1, "HBA_GetWrapperLibraryAttributes:"
1568*9e86db79SHyon Kim 		    "NULL pointer attributes",
1569*9e86db79SHyon Kim 		    0, 0, 0);
1570*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR_ARG);
1571*9e86db79SHyon Kim 	}
1572*9e86db79SHyon Kim 
1573*9e86db79SHyon Kim 	(void) memset(attributes, 0, sizeof (HBA_LIBRARYATTRIBUTES));
1574*9e86db79SHyon Kim 
1575*9e86db79SHyon Kim #if defined(SOLARIS)
1576*9e86db79SHyon Kim 	if ((handle = dlopen("libHBAAPI.so", RTLD_NOW)) != NULL) {
1577*9e86db79SHyon Kim 	if (dlinfo(handle, RTLD_DI_LINKMAP, &map) >= 0) {
1578*9e86db79SHyon Kim 		for (mp = map; mp != NULL; mp = mp->l_next) {
1579*9e86db79SHyon Kim 		if (strlen(map->l_name) < 256) {
1580*9e86db79SHyon Kim 			(void) strcpy(attributes->LibPath, map->l_name);
1581*9e86db79SHyon Kim 		}
1582*9e86db79SHyon Kim 		}
1583*9e86db79SHyon Kim 	}
1584*9e86db79SHyon Kim 	}
1585*9e86db79SHyon Kim #elif defined(WIN32)
1586*9e86db79SHyon Kim 	HMODULE module;
1587*9e86db79SHyon Kim 
1588*9e86db79SHyon Kim 	/* No need to do anything with the module handle */
1589*9e86db79SHyon Kim 	/* It wasn't alloocated so it doesn't need to be freed */
1590*9e86db79SHyon Kim 	module = GetModuleHandle("HBAAPI");
1591*9e86db79SHyon Kim 	if (module != NULL) {
1592*9e86db79SHyon Kim 		if (GetModuleFileName(module, attributes->LibPath,
1593*9e86db79SHyon Kim 		    sizeof (attributes->LibPath)) == 0) {
1594*9e86db79SHyon Kim 			attributes->LibPath[0] = '\0';
1595*9e86db79SHyon Kim 		}
1596*9e86db79SHyon Kim 	}
1597*9e86db79SHyon Kim #endif
1598*9e86db79SHyon Kim #if defined(VENDOR)
1599*9e86db79SHyon Kim 	(void) strcpy(attributes->VName, VENDOR);
1600*9e86db79SHyon Kim #else
1601*9e86db79SHyon Kim 	attributes->VName[0] = '\0';
1602*9e86db79SHyon Kim #endif
1603*9e86db79SHyon Kim #if defined(VERSION)
1604*9e86db79SHyon Kim 	(void) strcpy(attributes->VVersion, VERSION);
1605*9e86db79SHyon Kim #else
1606*9e86db79SHyon Kim 	attributes->VVersion[0] = '\0';
1607*9e86db79SHyon Kim #endif
1608*9e86db79SHyon Kim #if defined(BUILD_DATE)
1609*9e86db79SHyon Kim #if defined(WIN32)
1610*9e86db79SHyon Kim 	int matchCount;
1611*9e86db79SHyon Kim 	matchCount = sscanf(BUILD_DATE, "%u/%u/%u %u:%u:%u",
1612*9e86db79SHyon Kim 	    &attributes->build_date.tm_year,
1613*9e86db79SHyon Kim 	    &attributes->build_date.tm_mon,
1614*9e86db79SHyon Kim 	    &attributes->build_date.tm_mday,
1615*9e86db79SHyon Kim 	    &attributes->build_date.tm_hour,
1616*9e86db79SHyon Kim 	    &attributes->build_date.tm_min,
1617*9e86db79SHyon Kim 	    &attributes->build_date.tm_sec);
1618*9e86db79SHyon Kim 
1619*9e86db79SHyon Kim 	if (matchCount != 6) {
1620*9e86db79SHyon Kim 		memset(&attributes->build_date, 0, sizeof (struct tm));
1621*9e86db79SHyon Kim 	} else {
1622*9e86db79SHyon Kim 		attributes->build_date.tm_year -= 1900;
1623*9e86db79SHyon Kim 		attributes->build_date.tm_isdst = -1;
1624*9e86db79SHyon Kim 	}
1625*9e86db79SHyon Kim #else
1626*9e86db79SHyon Kim 	if (strptime(BUILD_DATE,
1627*9e86db79SHyon Kim 	    "%Y/%m/%d %T %Z", &(attributes->build_date)) == NULL) {
1628*9e86db79SHyon Kim 		(void) memset(&attributes->build_date, 0, sizeof (struct tm));
1629*9e86db79SHyon Kim 	}
1630*9e86db79SHyon Kim #endif
1631*9e86db79SHyon Kim #else
1632*9e86db79SHyon Kim 	(void) memset(&attributes->build_date, 0, sizeof (struct tm));
1633*9e86db79SHyon Kim #endif
1634*9e86db79SHyon Kim 	return (2);
1635*9e86db79SHyon Kim }
1636*9e86db79SHyon Kim 
1637*9e86db79SHyon Kim /*
1638*9e86db79SHyon Kim  * Callback registation and handling
1639*9e86db79SHyon Kim  */
1640*9e86db79SHyon Kim HBA_STATUS
1641*9e86db79SHyon Kim HBA_RemoveCallback(HBA_CALLBACKHANDLE cbhandle) {
1642*9e86db79SHyon Kim     HBA_STATUS	status;
1643*9e86db79SHyon Kim 
1644*9e86db79SHyon Kim     DEBUG(2, "HBA_RemoveCallback", 0, 0, 0);
1645*9e86db79SHyon Kim     ARE_WE_INITED();
1646*9e86db79SHyon Kim 
1647*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_LL_mutex);
1648*9e86db79SHyon Kim     status = local_remove_callback(cbhandle);
1649*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1650*9e86db79SHyon Kim }
1651*9e86db79SHyon Kim 
1652*9e86db79SHyon Kim /* Adapter Add Events ************************************************* */
1653*9e86db79SHyon Kim static void
1654*9e86db79SHyon Kim /* LINTED E_FUNC_ARG_UNUSED */
1655*9e86db79SHyon Kim adapteraddevents_callback(void *data, HBA_WWN PortWWN, HBA_UINT32 eventType) {
1656*9e86db79SHyon Kim     HBA_ALLADAPTERSCALLBACK_ELEM	*cbp;
1657*9e86db79SHyon Kim 
1658*9e86db79SHyon Kim     DEBUG(3, "AddAdapterEvent, port: %s", WWN2STR1(&PortWWN), 0, 0);
1659*9e86db79SHyon Kim 
1660*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_AAE_mutex);
1661*9e86db79SHyon Kim     for (cbp = _hbaapi_adapteraddevents_callback_list;
1662*9e86db79SHyon Kim 	    cbp != NULL;
1663*9e86db79SHyon Kim 	    cbp = cbp->next) {
1664*9e86db79SHyon Kim 	(*cbp->callback)(data, PortWWN, HBA_EVENT_ADAPTER_ADD);
1665*9e86db79SHyon Kim 	}
1666*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1667*9e86db79SHyon Kim 
1668*9e86db79SHyon Kim }
1669*9e86db79SHyon Kim 
1670*9e86db79SHyon Kim HBA_STATUS
1671*9e86db79SHyon Kim HBA_RegisterForAdapterAddEvents(
1672*9e86db79SHyon Kim     void		(*callback)(
1673*9e86db79SHyon Kim 	void		*data,
1674*9e86db79SHyon Kim 	HBA_WWN		PortWWN,
1675*9e86db79SHyon Kim 	HBA_UINT32	eventType),
1676*9e86db79SHyon Kim 	void		*userData,
1677*9e86db79SHyon Kim     HBA_CALLBACKHANDLE *callbackHandle) {
1678*9e86db79SHyon Kim 
1679*9e86db79SHyon Kim     HBA_ALLADAPTERSCALLBACK_ELEM	*cbp;
1680*9e86db79SHyon Kim     HBA_VENDORCALLBACK_ELEM		*vcbp;
1681*9e86db79SHyon Kim     HBA_VENDORCALLBACK_ELEM		*vendorhandlelist;
1682*9e86db79SHyon Kim     HBARegisterForAdapterAddEventsFunc	registeredfunc;
1683*9e86db79SHyon Kim     HBA_STATUS				status = HBA_STATUS_OK;
1684*9e86db79SHyon Kim     HBA_STATUS				failure = HBA_STATUS_OK;
1685*9e86db79SHyon Kim     HBA_LIBRARY_INFO			*lib_infop;
1686*9e86db79SHyon Kim     int					registered_cnt = 0;
1687*9e86db79SHyon Kim     int					vendor_cnt = 0;
1688*9e86db79SHyon Kim     int					not_supported_cnt = 0;
1689*9e86db79SHyon Kim     int					status_OK_bar_cnt = 0;
1690*9e86db79SHyon Kim     int					status_OK_cnt = 0;
1691*9e86db79SHyon Kim 
1692*9e86db79SHyon Kim     DEBUG(2, "HBA_RegisterForAdapterAddEvents", 0, 0, 0);
1693*9e86db79SHyon Kim     ARE_WE_INITED();
1694*9e86db79SHyon Kim 
1695*9e86db79SHyon Kim     cbp = (HBA_ALLADAPTERSCALLBACK_ELEM *)
1696*9e86db79SHyon Kim 	calloc(1, sizeof (HBA_ALLADAPTERSCALLBACK_ELEM));
1697*9e86db79SHyon Kim 	*callbackHandle = (HBA_CALLBACKHANDLE) cbp;
1698*9e86db79SHyon Kim 	if (cbp == NULL) {
1699*9e86db79SHyon Kim #ifndef WIN32
1700*9e86db79SHyon Kim 	(void) fprintf(stderr,
1701*9e86db79SHyon Kim 		"HBA_RegisterForAdapterAddEvents: calloc failed "
1702*9e86db79SHyon Kim 		"for %lu bytes\n",
1703*9e86db79SHyon Kim 		(unsigned long)(sizeof (HBA_ALLADAPTERSCALLBACK_ELEM)));
1704*9e86db79SHyon Kim #endif
1705*9e86db79SHyon Kim 	return (HBA_STATUS_ERROR);
1706*9e86db79SHyon Kim 	}
1707*9e86db79SHyon Kim 
1708*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_LL_mutex);
1709*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_AAE_mutex);
1710*9e86db79SHyon Kim     cbp->callback = callback;
1711*9e86db79SHyon Kim     cbp->next = _hbaapi_adapteraddevents_callback_list;
1712*9e86db79SHyon Kim     _hbaapi_adapteraddevents_callback_list = cbp;
1713*9e86db79SHyon Kim 	/*
1714*9e86db79SHyon Kim 	 * Need to release the mutex now incase the vendor function invokes the
1715*9e86db79SHyon Kim 	 * callback.  We will grap the mutex later to attach the vendor handle
1716*9e86db79SHyon Kim 	 * list to the callback structure
1717*9e86db79SHyon Kim 	 */
1718*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1719*9e86db79SHyon Kim 
1720*9e86db79SHyon Kim 	/*
1721*9e86db79SHyon Kim 	 * now create a list of vendors (vendor libraryies, NOT ADAPTERS)
1722*9e86db79SHyon Kim 	 * that have successfully registerred
1723*9e86db79SHyon Kim 	 */
1724*9e86db79SHyon Kim 	vendorhandlelist = NULL;
1725*9e86db79SHyon Kim     for (lib_infop = _hbaapi_librarylist;
1726*9e86db79SHyon Kim 	    lib_infop != NULL;
1727*9e86db79SHyon Kim 	    lib_infop = lib_infop->next) {
1728*9e86db79SHyon Kim 
1729*9e86db79SHyon Kim 	/* only for HBAAPI V2 */
1730*9e86db79SHyon Kim 	if ((lib_infop->version != HBAAPIV2)) {
1731*9e86db79SHyon Kim 	    continue;
1732*9e86db79SHyon Kim 	} else {
1733*9e86db79SHyon Kim 	    vendor_cnt++;
1734*9e86db79SHyon Kim 	}
1735*9e86db79SHyon Kim 
1736*9e86db79SHyon Kim 	registeredfunc =
1737*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.RegisterForAdapterAddEventsHandler;
1738*9e86db79SHyon Kim 	if (registeredfunc == NULL) {
1739*9e86db79SHyon Kim 	    continue;
1740*9e86db79SHyon Kim 	}
1741*9e86db79SHyon Kim 
1742*9e86db79SHyon Kim 	vcbp = (HBA_VENDORCALLBACK_ELEM *)
1743*9e86db79SHyon Kim 	    calloc(1, sizeof (HBA_VENDORCALLBACK_ELEM));
1744*9e86db79SHyon Kim 	if (vcbp == NULL) {
1745*9e86db79SHyon Kim #ifndef WIN32
1746*9e86db79SHyon Kim 	    (void) fprintf(stderr,
1747*9e86db79SHyon Kim 		    "HBA_RegisterForAdapterAddEvents: "
1748*9e86db79SHyon Kim 		    "calloc failed for %lu bytes\n",
1749*9e86db79SHyon Kim 		    (unsigned long)(sizeof (HBA_VENDORCALLBACK_ELEM)));
1750*9e86db79SHyon Kim #endif
1751*9e86db79SHyon Kim 	    freevendorhandlelist(vendorhandlelist);
1752*9e86db79SHyon Kim 	    status = HBA_STATUS_ERROR;
1753*9e86db79SHyon Kim 	    break;
1754*9e86db79SHyon Kim 	}
1755*9e86db79SHyon Kim 
1756*9e86db79SHyon Kim 	registered_cnt++;
1757*9e86db79SHyon Kim 	status = (registeredfunc)(adapteraddevents_callback,
1758*9e86db79SHyon Kim 	    userData, &vcbp->vendorcbhandle);
1759*9e86db79SHyon Kim 	if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
1760*9e86db79SHyon Kim 	    not_supported_cnt++;
1761*9e86db79SHyon Kim 	    free(vcbp);
1762*9e86db79SHyon Kim 	    continue;
1763*9e86db79SHyon Kim 	} else if (status != HBA_STATUS_OK) {
1764*9e86db79SHyon Kim 	    status_OK_bar_cnt++;
1765*9e86db79SHyon Kim 	    DEBUG(1,
1766*9e86db79SHyon Kim 		    "HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
1767*9e86db79SHyon Kim 		    lib_infop->LibraryPath, status, 0);
1768*9e86db79SHyon Kim #ifndef WIN32
1769*9e86db79SHyon Kim 	    (void) fprintf(stderr,
1770*9e86db79SHyon Kim 		    "HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
1771*9e86db79SHyon Kim 		    lib_infop->LibraryPath, status);
1772*9e86db79SHyon Kim #endif
1773*9e86db79SHyon Kim 	    failure = status;
1774*9e86db79SHyon Kim 	    free(vcbp);
1775*9e86db79SHyon Kim 	    continue;
1776*9e86db79SHyon Kim 	} else {
1777*9e86db79SHyon Kim 	    status_OK_cnt++;
1778*9e86db79SHyon Kim 	}
1779*9e86db79SHyon Kim 	vcbp->lib_info = lib_infop;
1780*9e86db79SHyon Kim 	vcbp->next = vendorhandlelist;
1781*9e86db79SHyon Kim 	vendorhandlelist = vcbp;
1782*9e86db79SHyon Kim 	}
1783*9e86db79SHyon Kim     if (vendor_cnt == 0) {
1784*9e86db79SHyon Kim 	/* no HBAAPIV2 is deteced.  should be okay? */
1785*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR;
1786*9e86db79SHyon Kim 	} else if (registered_cnt == 0) {
1787*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1788*9e86db79SHyon Kim 	freevendorhandlelist(vendorhandlelist);
1789*9e86db79SHyon Kim 	(void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
1790*9e86db79SHyon Kim 	} else if (status_OK_cnt == 0 && not_supported_cnt != 0) {
1791*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1792*9e86db79SHyon Kim 	} else if (status_OK_cnt == 0) {
1793*9e86db79SHyon Kim 	/*
1794*9e86db79SHyon Kim 	 * At least one vendor library registered this function, but no
1795*9e86db79SHyon Kim 	 * vendor call succeeded
1796*9e86db79SHyon Kim 	 */
1797*9e86db79SHyon Kim 	(void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
1798*9e86db79SHyon Kim 	status = failure;
1799*9e86db79SHyon Kim 	} else {
1800*9e86db79SHyon Kim 	/* we have had atleast some success, now finish up */
1801*9e86db79SHyon Kim 	GRAB_MUTEX(&_hbaapi_AAE_mutex);
1802*9e86db79SHyon Kim 	/*
1803*9e86db79SHyon Kim 	 * this seems silly, but what if another thread called
1804*9e86db79SHyon Kim 	 * the callback remove
1805*9e86db79SHyon Kim 	 */
1806*9e86db79SHyon Kim 	for (cbp = _hbaapi_adapteraddevents_callback_list;
1807*9e86db79SHyon Kim 	    cbp != NULL; cbp = cbp->next) {
1808*9e86db79SHyon Kim 	    if ((HBA_CALLBACKHANDLE)cbp == *callbackHandle) {
1809*9e86db79SHyon Kim 		/* yup, its still there, hooray */
1810*9e86db79SHyon Kim 		cbp->vendorhandlelist = vendorhandlelist;
1811*9e86db79SHyon Kim 		vendorhandlelist = NULL;
1812*9e86db79SHyon Kim 		break;
1813*9e86db79SHyon Kim 	    }
1814*9e86db79SHyon Kim 	}
1815*9e86db79SHyon Kim 	RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1816*9e86db79SHyon Kim 	if (vendorhandlelist != NULL) {
1817*9e86db79SHyon Kim 		/*
1818*9e86db79SHyon Kim 		 * bummer, somebody removed the callback before we finished
1819*9e86db79SHyon Kim 		 * registration, probably will never happen
1820*9e86db79SHyon Kim 		 */
1821*9e86db79SHyon Kim 	    freevendorhandlelist(vendorhandlelist);
1822*9e86db79SHyon Kim 	    DEBUG(1,
1823*9e86db79SHyon Kim 		    "HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was "
1824*9e86db79SHyon Kim 		    "called for a handle before registration was finished.",
1825*9e86db79SHyon Kim 		    0, 0, 0);
1826*9e86db79SHyon Kim 	    status = HBA_STATUS_ERROR;
1827*9e86db79SHyon Kim 	} else {
1828*9e86db79SHyon Kim 	    status = HBA_STATUS_OK;
1829*9e86db79SHyon Kim 	}
1830*9e86db79SHyon Kim 	}
1831*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1832*9e86db79SHyon Kim }
1833*9e86db79SHyon Kim 
1834*9e86db79SHyon Kim /* Adapter Events (other than add) ************************************** */
1835*9e86db79SHyon Kim static void
1836*9e86db79SHyon Kim adapterevents_callback(void *data,
1837*9e86db79SHyon Kim 			HBA_WWN PortWWN,
1838*9e86db79SHyon Kim 			HBA_UINT32 eventType) {
1839*9e86db79SHyon Kim     HBA_ADAPTERCALLBACK_ELEM	*acbp;
1840*9e86db79SHyon Kim 
1841*9e86db79SHyon Kim     DEBUG(3, "AdapterEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN),
1842*9e86db79SHyon Kim 	    eventType, 0);
1843*9e86db79SHyon Kim 
1844*9e86db79SHyon Kim 	GRAB_MUTEX(&_hbaapi_AE_mutex);
1845*9e86db79SHyon Kim 	for (acbp = _hbaapi_adapterevents_callback_list;
1846*9e86db79SHyon Kim 	acbp != NULL;
1847*9e86db79SHyon Kim 	acbp = acbp->next) {
1848*9e86db79SHyon Kim 	if (data == (void *)acbp) {
1849*9e86db79SHyon Kim 	    (*acbp->callback)(acbp->userdata, PortWWN, eventType);
1850*9e86db79SHyon Kim 	    break;
1851*9e86db79SHyon Kim 	}
1852*9e86db79SHyon Kim 	}
1853*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_AE_mutex);
1854*9e86db79SHyon Kim }
1855*9e86db79SHyon Kim HBA_STATUS
1856*9e86db79SHyon Kim HBA_RegisterForAdapterEvents(
1857*9e86db79SHyon Kim     void		(*callback) (
1858*9e86db79SHyon Kim 	void		*data,
1859*9e86db79SHyon Kim 	HBA_WWN		PortWWN,
1860*9e86db79SHyon Kim 	HBA_UINT32	eventType),
1861*9e86db79SHyon Kim     void		*userData,
1862*9e86db79SHyon Kim     HBA_HANDLE		handle,
1863*9e86db79SHyon Kim     HBA_CALLBACKHANDLE	*callbackHandle) {
1864*9e86db79SHyon Kim 
1865*9e86db79SHyon Kim     HBA_ADAPTERCALLBACK_ELEM		*acbp;
1866*9e86db79SHyon Kim     HBARegisterForAdapterEventsFunc	registeredfunc;
1867*9e86db79SHyon Kim     HBA_STATUS				status;
1868*9e86db79SHyon Kim     HBA_LIBRARY_INFO			*lib_infop;
1869*9e86db79SHyon Kim     HBA_HANDLE				vendorHandle;
1870*9e86db79SHyon Kim 
1871*9e86db79SHyon Kim     DEBUG(2, "HBA_RegisterForAdapterEvents", 0, 0, 0);
1872*9e86db79SHyon Kim 
1873*9e86db79SHyon Kim     CHECKLIBRARYANDVERSION(HBAAPIV2);
1874*9e86db79SHyon Kim 
1875*9e86db79SHyon Kim 	/* we now have the _hbaapi_LL_mutex */
1876*9e86db79SHyon Kim 
1877*9e86db79SHyon Kim     registeredfunc =
1878*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.RegisterForAdapterEventsHandler;
1879*9e86db79SHyon Kim     if (registeredfunc == NULL) {
1880*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1881*9e86db79SHyon Kim 	}
1882*9e86db79SHyon Kim 
1883*9e86db79SHyon Kim 	/*
1884*9e86db79SHyon Kim 	 * that allocated memory is used both as the handle for the
1885*9e86db79SHyon Kim 	 * caller, and as userdata to the vendor call so that on
1886*9e86db79SHyon Kim 	 * callback the specific registration may be recalled
1887*9e86db79SHyon Kim 	 */
1888*9e86db79SHyon Kim     acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1889*9e86db79SHyon Kim 	calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1890*9e86db79SHyon Kim     if (acbp == NULL) {
1891*9e86db79SHyon Kim #ifndef WIN32
1892*9e86db79SHyon Kim 	(void) fprintf(stderr,
1893*9e86db79SHyon Kim 		"HBA_RegisterForAdapterEvents: calloc failed for %lu bytes\n",
1894*9e86db79SHyon Kim 		(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
1895*9e86db79SHyon Kim #endif
1896*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1897*9e86db79SHyon Kim 	}
1898*9e86db79SHyon Kim 	*callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1899*9e86db79SHyon Kim     acbp->callback = callback;
1900*9e86db79SHyon Kim     acbp->userdata = userData;
1901*9e86db79SHyon Kim     acbp->lib_info = lib_infop;
1902*9e86db79SHyon Kim 
1903*9e86db79SHyon Kim     status = (registeredfunc)(adapterevents_callback,
1904*9e86db79SHyon Kim 	    (void *)acbp,
1905*9e86db79SHyon Kim 	    vendorHandle,
1906*9e86db79SHyon Kim 	    &acbp->vendorcbhandle);
1907*9e86db79SHyon Kim     if (status != HBA_STATUS_OK) {
1908*9e86db79SHyon Kim 	free(acbp);
1909*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1910*9e86db79SHyon Kim 	}
1911*9e86db79SHyon Kim 
1912*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_AE_mutex);
1913*9e86db79SHyon Kim     acbp->next = _hbaapi_adapterevents_callback_list;
1914*9e86db79SHyon Kim     _hbaapi_adapterevents_callback_list = acbp;
1915*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_AE_mutex);
1916*9e86db79SHyon Kim 
1917*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1918*9e86db79SHyon Kim }
1919*9e86db79SHyon Kim 
1920*9e86db79SHyon Kim /* Adapter Port Events ************************************************** */
1921*9e86db79SHyon Kim static void
1922*9e86db79SHyon Kim adapterportevents_callback(void *data,
1923*9e86db79SHyon Kim 			    HBA_WWN PortWWN,
1924*9e86db79SHyon Kim 			    HBA_UINT32 eventType,
1925*9e86db79SHyon Kim 			    HBA_UINT32 fabricPortID) {
1926*9e86db79SHyon Kim     HBA_ADAPTERCALLBACK_ELEM	*acbp;
1927*9e86db79SHyon Kim 
1928*9e86db79SHyon Kim     DEBUG(3, "AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x",
1929*9e86db79SHyon Kim 	    WWN2STR1(&PortWWN), eventType, fabricPortID);
1930*9e86db79SHyon Kim 
1931*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_APE_mutex);
1932*9e86db79SHyon Kim 
1933*9e86db79SHyon Kim     for (acbp = _hbaapi_adapterportevents_callback_list;
1934*9e86db79SHyon Kim 	acbp != NULL;
1935*9e86db79SHyon Kim 	acbp = acbp->next) {
1936*9e86db79SHyon Kim 	if (data == (void *)acbp) {
1937*9e86db79SHyon Kim 	    (*acbp->callback)(acbp->userdata, PortWWN, eventType, fabricPortID);
1938*9e86db79SHyon Kim 	    break;
1939*9e86db79SHyon Kim 	}
1940*9e86db79SHyon Kim 	}
1941*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_APE_mutex);
1942*9e86db79SHyon Kim }
1943*9e86db79SHyon Kim 
1944*9e86db79SHyon Kim HBA_STATUS
1945*9e86db79SHyon Kim HBA_RegisterForAdapterPortEvents(
1946*9e86db79SHyon Kim     void		(*callback) (
1947*9e86db79SHyon Kim 	void		*data,
1948*9e86db79SHyon Kim 	HBA_WWN		PortWWN,
1949*9e86db79SHyon Kim 	HBA_UINT32	eventType,
1950*9e86db79SHyon Kim 	HBA_UINT32	fabricPortID),
1951*9e86db79SHyon Kim     void		*userData,
1952*9e86db79SHyon Kim     HBA_HANDLE		handle,
1953*9e86db79SHyon Kim     HBA_WWN		PortWWN,
1954*9e86db79SHyon Kim     HBA_CALLBACKHANDLE	*callbackHandle) {
1955*9e86db79SHyon Kim 
1956*9e86db79SHyon Kim     HBA_ADAPTERCALLBACK_ELEM		*acbp;
1957*9e86db79SHyon Kim     HBARegisterForAdapterPortEventsFunc	registeredfunc;
1958*9e86db79SHyon Kim     HBA_STATUS				status;
1959*9e86db79SHyon Kim     HBA_LIBRARY_INFO			*lib_infop;
1960*9e86db79SHyon Kim     HBA_HANDLE				vendorHandle;
1961*9e86db79SHyon Kim 
1962*9e86db79SHyon Kim     DEBUG(2, "HBA_RegisterForAdapterPortEvents for port: %s",
1963*9e86db79SHyon Kim 	    WWN2STR1(&PortWWN), 0, 0);
1964*9e86db79SHyon Kim 
1965*9e86db79SHyon Kim     CHECKLIBRARYANDVERSION(HBAAPIV2);
1966*9e86db79SHyon Kim 	/* we now have the _hbaapi_LL_mutex */
1967*9e86db79SHyon Kim 
1968*9e86db79SHyon Kim 	registeredfunc =
1969*9e86db79SHyon Kim 	lib_infop->ftable.functionTable.RegisterForAdapterPortEventsHandler;
1970*9e86db79SHyon Kim     if (registeredfunc == NULL) {
1971*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1972*9e86db79SHyon Kim 	}
1973*9e86db79SHyon Kim 
1974*9e86db79SHyon Kim 	/*
1975*9e86db79SHyon Kim 	 * that allocated memory is used both as the handle for the
1976*9e86db79SHyon Kim 	 * caller, and as userdata to the vendor call so that on
1977*9e86db79SHyon Kim 	 * callback the specific registration may be recalled
1978*9e86db79SHyon Kim 	 */
1979*9e86db79SHyon Kim 	acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1980*9e86db79SHyon Kim 	calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1981*9e86db79SHyon Kim     if (acbp == NULL) {
1982*9e86db79SHyon Kim #ifndef WIN32
1983*9e86db79SHyon Kim 	(void) fprintf(stderr,
1984*9e86db79SHyon Kim 		"HBA_RegisterForAdapterPortEvents: "
1985*9e86db79SHyon Kim 		"calloc failed for %lu bytes\n",
1986*9e86db79SHyon Kim 		(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
1987*9e86db79SHyon Kim #endif
1988*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1989*9e86db79SHyon Kim 
1990*9e86db79SHyon Kim 	}
1991*9e86db79SHyon Kim 	*callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1992*9e86db79SHyon Kim     acbp->callback = callback;
1993*9e86db79SHyon Kim     acbp->userdata = userData;
1994*9e86db79SHyon Kim     acbp->lib_info = lib_infop;
1995*9e86db79SHyon Kim 
1996*9e86db79SHyon Kim     status = (registeredfunc)(adapterportevents_callback,
1997*9e86db79SHyon Kim 	    (void *)acbp,
1998*9e86db79SHyon Kim 	    vendorHandle,
1999*9e86db79SHyon Kim 	    PortWWN,
2000*9e86db79SHyon Kim 	    &acbp->vendorcbhandle);
2001*9e86db79SHyon Kim     if (status != HBA_STATUS_OK) {
2002*9e86db79SHyon Kim 	free(acbp);
2003*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2004*9e86db79SHyon Kim 	}
2005*9e86db79SHyon Kim 
2006*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_APE_mutex);
2007*9e86db79SHyon Kim     acbp->next = _hbaapi_adapterportevents_callback_list;
2008*9e86db79SHyon Kim     _hbaapi_adapterportevents_callback_list = acbp;
2009*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_APE_mutex);
2010*9e86db79SHyon Kim 
2011*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
2012*9e86db79SHyon Kim }
2013*9e86db79SHyon Kim 
2014*9e86db79SHyon Kim /* Adapter State Events ************************************************ */
2015*9e86db79SHyon Kim static void
2016*9e86db79SHyon Kim adapterportstatevents_callback(void *data,
2017*9e86db79SHyon Kim 				HBA_WWN PortWWN,
2018*9e86db79SHyon Kim 				HBA_UINT32 eventType) {
2019*9e86db79SHyon Kim     HBA_ADAPTERCALLBACK_ELEM	*acbp;
2020*9e86db79SHyon Kim 
2021*9e86db79SHyon Kim 	DEBUG(3, "AdapterPortStatEvent, port:%s, eventType:%d",
2022*9e86db79SHyon Kim 	    WWN2STR1(&PortWWN),
2023*9e86db79SHyon Kim 	    eventType, 0);
2024*9e86db79SHyon Kim 
2025*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_APSE_mutex);
2026*9e86db79SHyon Kim     for (acbp = _hbaapi_adapterportstatevents_callback_list;
2027*9e86db79SHyon Kim 	acbp != NULL;
2028*9e86db79SHyon Kim 	acbp = acbp->next) {
2029*9e86db79SHyon Kim 	if (data == (void *)acbp) {
2030*9e86db79SHyon Kim 	    (*acbp->callback)(acbp->userdata, PortWWN, eventType);
2031*9e86db79SHyon Kim 	    return;
2032*9e86db79SHyon Kim 	}
2033*9e86db79SHyon Kim 	}
2034*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_APSE_mutex);
2035*9e86db79SHyon Kim }
2036*9e86db79SHyon Kim HBA_STATUS
2037*9e86db79SHyon Kim HBA_RegisterForAdapterPortStatEvents(
2038*9e86db79SHyon Kim     void		(*callback) (
2039*9e86db79SHyon Kim 	void		*data,
2040*9e86db79SHyon Kim 	HBA_WWN		PortWWN,
2041*9e86db79SHyon Kim 	HBA_UINT32	eventType),
2042*9e86db79SHyon Kim     void		*userData,
2043*9e86db79SHyon Kim     HBA_HANDLE		handle,
2044*9e86db79SHyon Kim     HBA_WWN		PortWWN,
2045*9e86db79SHyon Kim     HBA_PORTSTATISTICS	stats,
2046*9e86db79SHyon Kim     HBA_UINT32		statType,
2047*9e86db79SHyon Kim     HBA_CALLBACKHANDLE	*callbackHandle) {
2048*9e86db79SHyon Kim 
2049*9e86db79SHyon Kim     HBA_ADAPTERCALLBACK_ELEM	*acbp;
2050*9e86db79SHyon Kim     HBARegisterForAdapterPortStatEventsFunc
2051*9e86db79SHyon Kim 				registeredfunc;
2052*9e86db79SHyon Kim     HBA_STATUS			status;
2053*9e86db79SHyon Kim     HBA_LIBRARY_INFO		*lib_infop;
2054*9e86db79SHyon Kim     HBA_HANDLE			vendorHandle;
2055*9e86db79SHyon Kim 
2056*9e86db79SHyon Kim     DEBUG(2, "HBA_RegisterForAdapterPortStatEvents for port: %s",
2057*9e86db79SHyon Kim 	    WWN2STR1(&PortWWN), 0, 0);
2058*9e86db79SHyon Kim 
2059*9e86db79SHyon Kim     CHECKLIBRARYANDVERSION(HBAAPIV2);
2060*9e86db79SHyon Kim 	/* we now have the _hbaapi_LL_mutex */
2061*9e86db79SHyon Kim 
2062*9e86db79SHyon Kim     registeredfunc =
2063*9e86db79SHyon Kim 	lib_infop->ftable.functionTable.RegisterForAdapterPortStatEventsHandler;
2064*9e86db79SHyon Kim     if (registeredfunc == NULL) {
2065*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
2066*9e86db79SHyon Kim 	}
2067*9e86db79SHyon Kim 
2068*9e86db79SHyon Kim 	/*
2069*9e86db79SHyon Kim 	 * that allocated memory is used both as the handle for the
2070*9e86db79SHyon Kim 	 * caller, and as userdata to the vendor call so that on
2071*9e86db79SHyon Kim 	 * callback the specific registration may be recalled
2072*9e86db79SHyon Kim 	 */
2073*9e86db79SHyon Kim     acbp = (HBA_ADAPTERCALLBACK_ELEM *)
2074*9e86db79SHyon Kim 	calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
2075*9e86db79SHyon Kim     if (acbp == NULL) {
2076*9e86db79SHyon Kim #ifndef WIN32
2077*9e86db79SHyon Kim 	(void) fprintf(stderr,
2078*9e86db79SHyon Kim 		"HBA_RegisterForAdapterPortStatEvents: "
2079*9e86db79SHyon Kim 		"calloc failed for %lu bytes\n",
2080*9e86db79SHyon Kim 		(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
2081*9e86db79SHyon Kim #endif
2082*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
2083*9e86db79SHyon Kim 	}
2084*9e86db79SHyon Kim 	*callbackHandle = (HBA_CALLBACKHANDLE) acbp;
2085*9e86db79SHyon Kim     acbp->callback = callback;
2086*9e86db79SHyon Kim     acbp->userdata = userData;
2087*9e86db79SHyon Kim     acbp->lib_info = lib_infop;
2088*9e86db79SHyon Kim 
2089*9e86db79SHyon Kim     status = (registeredfunc)(adapterportstatevents_callback,
2090*9e86db79SHyon Kim 	    (void *)acbp,
2091*9e86db79SHyon Kim 	    vendorHandle,
2092*9e86db79SHyon Kim 	    PortWWN,
2093*9e86db79SHyon Kim 	    stats,
2094*9e86db79SHyon Kim 	    statType,
2095*9e86db79SHyon Kim 	    &acbp->vendorcbhandle);
2096*9e86db79SHyon Kim     if (status != HBA_STATUS_OK) {
2097*9e86db79SHyon Kim 	free(acbp);
2098*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2099*9e86db79SHyon Kim 	}
2100*9e86db79SHyon Kim 
2101*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_APSE_mutex);
2102*9e86db79SHyon Kim     acbp->next = _hbaapi_adapterportstatevents_callback_list;
2103*9e86db79SHyon Kim     _hbaapi_adapterportstatevents_callback_list = acbp;
2104*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_APSE_mutex);
2105*9e86db79SHyon Kim 
2106*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
2107*9e86db79SHyon Kim }
2108*9e86db79SHyon Kim 
2109*9e86db79SHyon Kim /* Target Events ******************************************************* */
2110*9e86db79SHyon Kim static void
2111*9e86db79SHyon Kim targetevents_callback(void *data,
2112*9e86db79SHyon Kim     HBA_WWN hbaPortWWN,
2113*9e86db79SHyon Kim     HBA_WWN discoveredPortWWN,
2114*9e86db79SHyon Kim     HBA_UINT32 eventType) {
2115*9e86db79SHyon Kim 
2116*9e86db79SHyon Kim 	HBA_ADAPTERCALLBACK_ELEM	*acbp;
2117*9e86db79SHyon Kim 
2118*9e86db79SHyon Kim     DEBUG(3, "TargetEvent, hbaPort:%s, discoveredPort:%s eventType:%d",
2119*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), eventType);
2120*9e86db79SHyon Kim 
2121*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_TE_mutex);
2122*9e86db79SHyon Kim     for (acbp = _hbaapi_targetevents_callback_list;
2123*9e86db79SHyon Kim 	acbp != NULL;
2124*9e86db79SHyon Kim 	acbp = acbp->next) {
2125*9e86db79SHyon Kim 	if (data == (void *)acbp) {
2126*9e86db79SHyon Kim 	    (*acbp->callback)(acbp->userdata, hbaPortWWN,
2127*9e86db79SHyon Kim 	    discoveredPortWWN, eventType);
2128*9e86db79SHyon Kim 	    break;
2129*9e86db79SHyon Kim 	}
2130*9e86db79SHyon Kim 	}
2131*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_TE_mutex);
2132*9e86db79SHyon Kim }
2133*9e86db79SHyon Kim 
2134*9e86db79SHyon Kim HBA_STATUS
2135*9e86db79SHyon Kim HBA_RegisterForTargetEvents(
2136*9e86db79SHyon Kim     void		(*callback) (
2137*9e86db79SHyon Kim 	void		*data,
2138*9e86db79SHyon Kim 	HBA_WWN		hbaPortWWN,
2139*9e86db79SHyon Kim 	HBA_WWN		discoveredPortWWN,
2140*9e86db79SHyon Kim 	HBA_UINT32	eventType),
2141*9e86db79SHyon Kim     void		*userData,
2142*9e86db79SHyon Kim     HBA_HANDLE		handle,
2143*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
2144*9e86db79SHyon Kim     HBA_WWN		discoveredPortWWN,
2145*9e86db79SHyon Kim     HBA_CALLBACKHANDLE	*callbackHandle,
2146*9e86db79SHyon Kim     HBA_UINT32		allTargets) {
2147*9e86db79SHyon Kim 
2148*9e86db79SHyon Kim     HBA_ADAPTERCALLBACK_ELEM
2149*9e86db79SHyon Kim 			*acbp;
2150*9e86db79SHyon Kim     HBARegisterForTargetEventsFunc
2151*9e86db79SHyon Kim 			registeredfunc;
2152*9e86db79SHyon Kim     HBA_STATUS		status;
2153*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_infop;
2154*9e86db79SHyon Kim     HBA_HANDLE		vendorHandle;
2155*9e86db79SHyon Kim 
2156*9e86db79SHyon Kim     DEBUG(2, "HBA_RegisterForTargetEvents, hbaPort: %s, discoveredPort: %s",
2157*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), 0);
2158*9e86db79SHyon Kim 
2159*9e86db79SHyon Kim     CHECKLIBRARYANDVERSION(HBAAPIV2);
2160*9e86db79SHyon Kim 	/* we now have the _hbaapi_LL_mutex */
2161*9e86db79SHyon Kim 
2162*9e86db79SHyon Kim     registeredfunc =
2163*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.RegisterForTargetEventsHandler;
2164*9e86db79SHyon Kim     if (registeredfunc == NULL) {
2165*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
2166*9e86db79SHyon Kim 	}
2167*9e86db79SHyon Kim 
2168*9e86db79SHyon Kim 	/*
2169*9e86db79SHyon Kim 	 * that allocated memory is used both as the handle for the
2170*9e86db79SHyon Kim 	 * caller, and as userdata to the vendor call so that on
2171*9e86db79SHyon Kim 	 * callback the specific registration may be recalled
2172*9e86db79SHyon Kim 	 */
2173*9e86db79SHyon Kim 	acbp = (HBA_ADAPTERCALLBACK_ELEM *)
2174*9e86db79SHyon Kim 	calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
2175*9e86db79SHyon Kim     if (acbp == NULL) {
2176*9e86db79SHyon Kim #ifndef WIN32
2177*9e86db79SHyon Kim 	(void) fprintf(stderr,
2178*9e86db79SHyon Kim 		"HBA_RegisterForTargetEvents: calloc failed for %lu bytes\n",
2179*9e86db79SHyon Kim 		(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
2180*9e86db79SHyon Kim #endif
2181*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
2182*9e86db79SHyon Kim 	}
2183*9e86db79SHyon Kim 	*callbackHandle = (HBA_CALLBACKHANDLE) acbp;
2184*9e86db79SHyon Kim     acbp->callback = callback;
2185*9e86db79SHyon Kim     acbp->userdata = userData;
2186*9e86db79SHyon Kim     acbp->lib_info = lib_infop;
2187*9e86db79SHyon Kim 
2188*9e86db79SHyon Kim     status = (registeredfunc)(targetevents_callback,
2189*9e86db79SHyon Kim 	    (void *)acbp,
2190*9e86db79SHyon Kim 	    vendorHandle,
2191*9e86db79SHyon Kim 	    hbaPortWWN,
2192*9e86db79SHyon Kim 	    discoveredPortWWN,
2193*9e86db79SHyon Kim 	    &acbp->vendorcbhandle,
2194*9e86db79SHyon Kim 	    allTargets);
2195*9e86db79SHyon Kim     if (status != HBA_STATUS_OK) {
2196*9e86db79SHyon Kim 	free(acbp);
2197*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2198*9e86db79SHyon Kim 	}
2199*9e86db79SHyon Kim 
2200*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_TE_mutex);
2201*9e86db79SHyon Kim     acbp->next = _hbaapi_targetevents_callback_list;
2202*9e86db79SHyon Kim     _hbaapi_targetevents_callback_list = acbp;
2203*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_TE_mutex);
2204*9e86db79SHyon Kim 
2205*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
2206*9e86db79SHyon Kim }
2207*9e86db79SHyon Kim 
2208*9e86db79SHyon Kim /* Link Events ********************************************************* */
2209*9e86db79SHyon Kim static void
2210*9e86db79SHyon Kim linkevents_callback(void *data,
2211*9e86db79SHyon Kim     HBA_WWN adapterWWN,
2212*9e86db79SHyon Kim     HBA_UINT32 eventType,
2213*9e86db79SHyon Kim     void *pRLIRBuffer,
2214*9e86db79SHyon Kim     HBA_UINT32 RLIRBufferSize) {
2215*9e86db79SHyon Kim 	HBA_ADAPTERCALLBACK_ELEM	*acbp;
2216*9e86db79SHyon Kim 
2217*9e86db79SHyon Kim     DEBUG(3, "LinkEvent, hbaWWN:%s, eventType:%d",
2218*9e86db79SHyon Kim 	    WWN2STR1(&adapterWWN), eventType, 0);
2219*9e86db79SHyon Kim 
2220*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_LE_mutex);
2221*9e86db79SHyon Kim     for (acbp = _hbaapi_linkevents_callback_list;
2222*9e86db79SHyon Kim 	acbp != NULL;
2223*9e86db79SHyon Kim 	acbp = acbp->next) {
2224*9e86db79SHyon Kim 	if (data == (void *)acbp) {
2225*9e86db79SHyon Kim 	    (*acbp->callback)(acbp->userdata, adapterWWN,
2226*9e86db79SHyon Kim 		eventType, pRLIRBuffer, RLIRBufferSize);
2227*9e86db79SHyon Kim 	    break;
2228*9e86db79SHyon Kim 	}
2229*9e86db79SHyon Kim 	}
2230*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_LE_mutex);
2231*9e86db79SHyon Kim }
2232*9e86db79SHyon Kim HBA_STATUS
2233*9e86db79SHyon Kim HBA_RegisterForLinkEvents(
2234*9e86db79SHyon Kim     void		(*callback) (
2235*9e86db79SHyon Kim 	void		*data,
2236*9e86db79SHyon Kim 	HBA_WWN		adapterWWN,
2237*9e86db79SHyon Kim 	HBA_UINT32	eventType,
2238*9e86db79SHyon Kim 	void		*pRLIRBuffer,
2239*9e86db79SHyon Kim 	HBA_UINT32	RLIRBufferSize),
2240*9e86db79SHyon Kim     void		*userData,
2241*9e86db79SHyon Kim     void		*pRLIRBuffer,
2242*9e86db79SHyon Kim     HBA_UINT32		RLIRBufferSize,
2243*9e86db79SHyon Kim     HBA_HANDLE		handle,
2244*9e86db79SHyon Kim     HBA_CALLBACKHANDLE	*callbackHandle) {
2245*9e86db79SHyon Kim 
2246*9e86db79SHyon Kim     HBA_ADAPTERCALLBACK_ELEM	*acbp;
2247*9e86db79SHyon Kim     HBARegisterForLinkEventsFunc
2248*9e86db79SHyon Kim 				registeredfunc;
2249*9e86db79SHyon Kim     HBA_STATUS			status;
2250*9e86db79SHyon Kim     HBA_LIBRARY_INFO		*lib_infop;
2251*9e86db79SHyon Kim     HBA_HANDLE			vendorHandle;
2252*9e86db79SHyon Kim 
2253*9e86db79SHyon Kim     DEBUG(2, "HBA_RegisterForLinkEvents", 0, 0, 0);
2254*9e86db79SHyon Kim 
2255*9e86db79SHyon Kim     CHECKLIBRARY();
2256*9e86db79SHyon Kim 	/* we now have the _hbaapi_LL_mutex */
2257*9e86db79SHyon Kim 
2258*9e86db79SHyon Kim     registeredfunc = FUNCCOMMON(lib_infop, RegisterForLinkEventsHandler);
2259*9e86db79SHyon Kim 
2260*9e86db79SHyon Kim     if (registeredfunc == NULL) {
2261*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
2262*9e86db79SHyon Kim 	}
2263*9e86db79SHyon Kim 
2264*9e86db79SHyon Kim 	/*
2265*9e86db79SHyon Kim 	 * that allocated memory is used both as the handle for the
2266*9e86db79SHyon Kim 	 * caller, and as userdata to the vendor call so that on
2267*9e86db79SHyon Kim 	 * callback the specific registration may be recalled
2268*9e86db79SHyon Kim 	 */
2269*9e86db79SHyon Kim     acbp = (HBA_ADAPTERCALLBACK_ELEM *)
2270*9e86db79SHyon Kim 	calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
2271*9e86db79SHyon Kim     if (acbp == NULL) {
2272*9e86db79SHyon Kim #ifndef WIN32
2273*9e86db79SHyon Kim 	(void) fprintf(stderr,
2274*9e86db79SHyon Kim 		"HBA_RegisterForLinkEvents: calloc failed for %lu bytes\n",
2275*9e86db79SHyon Kim 		(unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
2276*9e86db79SHyon Kim #endif
2277*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
2278*9e86db79SHyon Kim 	}
2279*9e86db79SHyon Kim 	*callbackHandle = (HBA_CALLBACKHANDLE) acbp;
2280*9e86db79SHyon Kim     acbp->callback = callback;
2281*9e86db79SHyon Kim     acbp->userdata = userData;
2282*9e86db79SHyon Kim     acbp->lib_info = lib_infop;
2283*9e86db79SHyon Kim 
2284*9e86db79SHyon Kim     status = (registeredfunc)(linkevents_callback,
2285*9e86db79SHyon Kim 	    (void *)acbp,
2286*9e86db79SHyon Kim 	    pRLIRBuffer,
2287*9e86db79SHyon Kim 	    RLIRBufferSize,
2288*9e86db79SHyon Kim 	    vendorHandle,
2289*9e86db79SHyon Kim 	    &acbp->vendorcbhandle);
2290*9e86db79SHyon Kim     if (status != HBA_STATUS_OK) {
2291*9e86db79SHyon Kim 	free(acbp);
2292*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2293*9e86db79SHyon Kim 	}
2294*9e86db79SHyon Kim 
2295*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_LE_mutex);
2296*9e86db79SHyon Kim     acbp->next = _hbaapi_linkevents_callback_list;
2297*9e86db79SHyon Kim     _hbaapi_linkevents_callback_list = acbp;
2298*9e86db79SHyon Kim     RELEASE_MUTEX(&_hbaapi_LE_mutex);
2299*9e86db79SHyon Kim 
2300*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
2301*9e86db79SHyon Kim }
2302*9e86db79SHyon Kim 
2303*9e86db79SHyon Kim /*
2304*9e86db79SHyon Kim  * All of the functions below are almost passthru functions to the
2305*9e86db79SHyon Kim  * vendor specific function
2306*9e86db79SHyon Kim  */
2307*9e86db79SHyon Kim 
2308*9e86db79SHyon Kim void
2309*9e86db79SHyon Kim HBA_CloseAdapter(HBA_HANDLE handle) {
2310*9e86db79SHyon Kim     HBA_STATUS		status;
2311*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_infop;
2312*9e86db79SHyon Kim     HBA_HANDLE		vendorHandle;
2313*9e86db79SHyon Kim     HBACloseAdapterFunc CloseAdapterFunc;
2314*9e86db79SHyon Kim 
2315*9e86db79SHyon Kim     DEBUG(2, "HBA_CloseAdapter", 0, 0, 0);
2316*9e86db79SHyon Kim 
2317*9e86db79SHyon Kim     status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
2318*9e86db79SHyon Kim     if (status == HBA_STATUS_OK) {
2319*9e86db79SHyon Kim 	CloseAdapterFunc = FUNCCOMMON(lib_infop, CloseAdapterHandler);
2320*9e86db79SHyon Kim 	if (CloseAdapterFunc != NULL) {
2321*9e86db79SHyon Kim 	    ((CloseAdapterFunc)(vendorHandle));
2322*9e86db79SHyon Kim 	}
2323*9e86db79SHyon Kim 	RELEASE_MUTEX(&_hbaapi_LL_mutex);
2324*9e86db79SHyon Kim 	}
2325*9e86db79SHyon Kim }
2326*9e86db79SHyon Kim 
2327*9e86db79SHyon Kim HBA_STATUS
2328*9e86db79SHyon Kim HBA_GetAdapterAttributes(
2329*9e86db79SHyon Kim     HBA_HANDLE		handle,
2330*9e86db79SHyon Kim     HBA_ADAPTERATTRIBUTES
2331*9e86db79SHyon Kim 			*hbaattributes)
2332*9e86db79SHyon Kim {
2333*9e86db79SHyon Kim 	HBA_STATUS		status;
2334*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2335*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2336*9e86db79SHyon Kim 	HBAGetAdapterAttributesFunc GetAdapterAttributesFunc;
2337*9e86db79SHyon Kim 
2338*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetAdapterAttributes", 0, 0, 0);
2339*9e86db79SHyon Kim 
2340*9e86db79SHyon Kim 	CHECKLIBRARY();
2341*9e86db79SHyon Kim 
2342*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2343*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2344*9e86db79SHyon Kim 	}
2345*9e86db79SHyon Kim 
2346*9e86db79SHyon Kim 	GetAdapterAttributesFunc =
2347*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetAdapterAttributesHandler;
2348*9e86db79SHyon Kim 	if (GetAdapterAttributesFunc != NULL) {
2349*9e86db79SHyon Kim 	status = ((GetAdapterAttributesFunc)(vendorHandle, hbaattributes));
2350*9e86db79SHyon Kim 	} else {
2351*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2352*9e86db79SHyon Kim 	}
2353*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2354*9e86db79SHyon Kim }
2355*9e86db79SHyon Kim 
2356*9e86db79SHyon Kim HBA_STATUS
2357*9e86db79SHyon Kim HBA_GetAdapterPortAttributes(
2358*9e86db79SHyon Kim     HBA_HANDLE		handle,
2359*9e86db79SHyon Kim     HBA_UINT32		portindex,
2360*9e86db79SHyon Kim     HBA_PORTATTRIBUTES	*portattributes)
2361*9e86db79SHyon Kim {
2362*9e86db79SHyon Kim 	HBA_STATUS		status;
2363*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2364*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2365*9e86db79SHyon Kim 	HBAGetAdapterPortAttributesFunc
2366*9e86db79SHyon Kim 	    GetAdapterPortAttributesFunc;
2367*9e86db79SHyon Kim 
2368*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetAdapterPortAttributes", 0, 0, 0);
2369*9e86db79SHyon Kim 
2370*9e86db79SHyon Kim 	CHECKLIBRARY();
2371*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2372*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2373*9e86db79SHyon Kim 	}
2374*9e86db79SHyon Kim 
2375*9e86db79SHyon Kim 	GetAdapterPortAttributesFunc =
2376*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetAdapterPortAttributesHandler;
2377*9e86db79SHyon Kim 	if (GetAdapterPortAttributesFunc != NULL) {
2378*9e86db79SHyon Kim 	status = ((GetAdapterPortAttributesFunc)
2379*9e86db79SHyon Kim 	    (vendorHandle, portindex, portattributes));
2380*9e86db79SHyon Kim 	} else {
2381*9e86db79SHyon Kim 		status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2382*9e86db79SHyon Kim 	}
2383*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2384*9e86db79SHyon Kim }
2385*9e86db79SHyon Kim 
2386*9e86db79SHyon Kim HBA_STATUS
2387*9e86db79SHyon Kim HBA_GetPortStatistics(
2388*9e86db79SHyon Kim     HBA_HANDLE		handle,
2389*9e86db79SHyon Kim     HBA_UINT32		portindex,
2390*9e86db79SHyon Kim     HBA_PORTSTATISTICS	*portstatistics)
2391*9e86db79SHyon Kim {
2392*9e86db79SHyon Kim 	HBA_STATUS		status;
2393*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2394*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2395*9e86db79SHyon Kim 	HBAGetPortStatisticsFunc
2396*9e86db79SHyon Kim 	    GetPortStatisticsFunc;
2397*9e86db79SHyon Kim 
2398*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetPortStatistics", 0, 0, 0);
2399*9e86db79SHyon Kim 
2400*9e86db79SHyon Kim 	CHECKLIBRARY();
2401*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2402*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2403*9e86db79SHyon Kim 	}
2404*9e86db79SHyon Kim 
2405*9e86db79SHyon Kim 	GetPortStatisticsFunc =
2406*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetPortStatisticsHandler;
2407*9e86db79SHyon Kim 	if (GetPortStatisticsFunc != NULL) {
2408*9e86db79SHyon Kim 	status = ((GetPortStatisticsFunc)
2409*9e86db79SHyon Kim 	    (vendorHandle, portindex, portstatistics));
2410*9e86db79SHyon Kim 	} else {
2411*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2412*9e86db79SHyon Kim 	}
2413*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2414*9e86db79SHyon Kim }
2415*9e86db79SHyon Kim 
2416*9e86db79SHyon Kim HBA_STATUS
2417*9e86db79SHyon Kim HBA_GetDiscoveredPortAttributes(
2418*9e86db79SHyon Kim     HBA_HANDLE		handle,
2419*9e86db79SHyon Kim     HBA_UINT32		portindex,
2420*9e86db79SHyon Kim     HBA_UINT32		discoveredportindex,
2421*9e86db79SHyon Kim     HBA_PORTATTRIBUTES	*portattributes)
2422*9e86db79SHyon Kim {
2423*9e86db79SHyon Kim 	HBA_STATUS		status;
2424*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2425*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2426*9e86db79SHyon Kim 	HBAGetDiscoveredPortAttributesFunc
2427*9e86db79SHyon Kim 	    GetDiscoveredPortAttributesFunc;
2428*9e86db79SHyon Kim 
2429*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetDiscoveredPortAttributes", 0, 0, 0);
2430*9e86db79SHyon Kim 
2431*9e86db79SHyon Kim 	CHECKLIBRARY();
2432*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2433*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2434*9e86db79SHyon Kim 	}
2435*9e86db79SHyon Kim 
2436*9e86db79SHyon Kim 	GetDiscoveredPortAttributesFunc =
2437*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetDiscoveredPortAttributesHandler;
2438*9e86db79SHyon Kim 	if (GetDiscoveredPortAttributesFunc != NULL)  {
2439*9e86db79SHyon Kim 	status = ((GetDiscoveredPortAttributesFunc)
2440*9e86db79SHyon Kim 	    (vendorHandle, portindex, discoveredportindex,
2441*9e86db79SHyon Kim 	    portattributes));
2442*9e86db79SHyon Kim 	} else {
2443*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2444*9e86db79SHyon Kim 	}
2445*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2446*9e86db79SHyon Kim }
2447*9e86db79SHyon Kim 
2448*9e86db79SHyon Kim HBA_STATUS
2449*9e86db79SHyon Kim HBA_GetPortAttributesByWWN(
2450*9e86db79SHyon Kim     HBA_HANDLE		handle,
2451*9e86db79SHyon Kim     HBA_WWN		PortWWN,
2452*9e86db79SHyon Kim     HBA_PORTATTRIBUTES	*portattributes)
2453*9e86db79SHyon Kim {
2454*9e86db79SHyon Kim 	HBA_STATUS		status;
2455*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2456*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2457*9e86db79SHyon Kim 	HBAGetPortAttributesByWWNFunc
2458*9e86db79SHyon Kim 	    GetPortAttributesByWWNFunc;
2459*9e86db79SHyon Kim 
2460*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetPortAttributesByWWN: %s", WWN2STR1(&PortWWN), 0, 0);
2461*9e86db79SHyon Kim 
2462*9e86db79SHyon Kim 	CHECKLIBRARY();
2463*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2464*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2465*9e86db79SHyon Kim 	}
2466*9e86db79SHyon Kim 
2467*9e86db79SHyon Kim 	GetPortAttributesByWWNFunc =
2468*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetPortAttributesByWWNHandler;
2469*9e86db79SHyon Kim 	if (GetPortAttributesByWWNFunc != NULL) {
2470*9e86db79SHyon Kim 	status = ((GetPortAttributesByWWNFunc)
2471*9e86db79SHyon Kim 	    (vendorHandle, PortWWN, portattributes));
2472*9e86db79SHyon Kim 	} else {
2473*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2474*9e86db79SHyon Kim 	}
2475*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2476*9e86db79SHyon Kim }
2477*9e86db79SHyon Kim 
2478*9e86db79SHyon Kim HBA_STATUS
2479*9e86db79SHyon Kim HBA_SendCTPassThru(
2480*9e86db79SHyon Kim     HBA_HANDLE		handle,
2481*9e86db79SHyon Kim     void		*pReqBuffer,
2482*9e86db79SHyon Kim     HBA_UINT32		ReqBufferSize,
2483*9e86db79SHyon Kim     void		*pRspBuffer,
2484*9e86db79SHyon Kim     HBA_UINT32		RspBufferSize)
2485*9e86db79SHyon Kim {
2486*9e86db79SHyon Kim 	HBA_STATUS		status;
2487*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2488*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2489*9e86db79SHyon Kim 	HBASendCTPassThruFunc
2490*9e86db79SHyon Kim 	    SendCTPassThruFunc;
2491*9e86db79SHyon Kim 
2492*9e86db79SHyon Kim 	DEBUG(2, "HBA_SendCTPassThru", 0, 0, 0);
2493*9e86db79SHyon Kim 
2494*9e86db79SHyon Kim 	CHECKLIBRARY();
2495*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2496*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2497*9e86db79SHyon Kim 	}
2498*9e86db79SHyon Kim 
2499*9e86db79SHyon Kim 	SendCTPassThruFunc =
2500*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.SendCTPassThruHandler;
2501*9e86db79SHyon Kim 	if (SendCTPassThruFunc != NULL) {
2502*9e86db79SHyon Kim 	status = (SendCTPassThruFunc)
2503*9e86db79SHyon Kim 	    (vendorHandle,
2504*9e86db79SHyon Kim 	    pReqBuffer, ReqBufferSize,
2505*9e86db79SHyon Kim 	    pRspBuffer, RspBufferSize);
2506*9e86db79SHyon Kim 	} else {
2507*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2508*9e86db79SHyon Kim 	}
2509*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2510*9e86db79SHyon Kim }
2511*9e86db79SHyon Kim 
2512*9e86db79SHyon Kim HBA_STATUS
2513*9e86db79SHyon Kim HBA_SendCTPassThruV2(
2514*9e86db79SHyon Kim     HBA_HANDLE		handle,
2515*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
2516*9e86db79SHyon Kim     void		*pReqBuffer,
2517*9e86db79SHyon Kim     HBA_UINT32		ReqBufferSize,
2518*9e86db79SHyon Kim     void		*pRspBuffer,
2519*9e86db79SHyon Kim     HBA_UINT32		*pRspBufferSize)
2520*9e86db79SHyon Kim {
2521*9e86db79SHyon Kim 	HBA_STATUS		status;
2522*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2523*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2524*9e86db79SHyon Kim 	HBASendCTPassThruV2Func
2525*9e86db79SHyon Kim 	    registeredfunc;
2526*9e86db79SHyon Kim 
2527*9e86db79SHyon Kim 	DEBUG(2, "HBA_SendCTPassThruV2m hbaPortWWN: %s",
2528*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), 0, 0);
2529*9e86db79SHyon Kim 
2530*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
2531*9e86db79SHyon Kim 	registeredfunc = FUNCCOMMON(lib_infop, SendCTPassThruV2Handler);
2532*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
2533*9e86db79SHyon Kim 	status = (registeredfunc)
2534*9e86db79SHyon Kim 	    (vendorHandle, hbaPortWWN,
2535*9e86db79SHyon Kim 	    pReqBuffer, ReqBufferSize,
2536*9e86db79SHyon Kim 	    pRspBuffer, pRspBufferSize);
2537*9e86db79SHyon Kim 	} else {
2538*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2539*9e86db79SHyon Kim 	}
2540*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2541*9e86db79SHyon Kim }
2542*9e86db79SHyon Kim 
2543*9e86db79SHyon Kim HBA_STATUS
2544*9e86db79SHyon Kim HBA_GetEventBuffer(
2545*9e86db79SHyon Kim     HBA_HANDLE		handle,
2546*9e86db79SHyon Kim     PHBA_EVENTINFO	EventBuffer,
2547*9e86db79SHyon Kim     HBA_UINT32		*EventBufferCount)
2548*9e86db79SHyon Kim {
2549*9e86db79SHyon Kim 	HBA_STATUS		status;
2550*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2551*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2552*9e86db79SHyon Kim 	HBAGetEventBufferFunc
2553*9e86db79SHyon Kim 	    GetEventBufferFunc;
2554*9e86db79SHyon Kim 
2555*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetEventBuffer", 0, 0, 0);
2556*9e86db79SHyon Kim 
2557*9e86db79SHyon Kim 	CHECKLIBRARY();
2558*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2559*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2560*9e86db79SHyon Kim 	}
2561*9e86db79SHyon Kim 
2562*9e86db79SHyon Kim 	GetEventBufferFunc =
2563*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetEventBufferHandler;
2564*9e86db79SHyon Kim 	if (GetEventBufferFunc != NULL) {
2565*9e86db79SHyon Kim 	status = (GetEventBufferFunc)
2566*9e86db79SHyon Kim 	    (vendorHandle, EventBuffer, EventBufferCount);
2567*9e86db79SHyon Kim 	} else {
2568*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2569*9e86db79SHyon Kim 	}
2570*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2571*9e86db79SHyon Kim }
2572*9e86db79SHyon Kim 
2573*9e86db79SHyon Kim HBA_STATUS
2574*9e86db79SHyon Kim HBA_SetRNIDMgmtInfo(HBA_HANDLE handle, HBA_MGMTINFO Info) {
2575*9e86db79SHyon Kim     HBA_STATUS		status;
2576*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_infop;
2577*9e86db79SHyon Kim     HBA_HANDLE		vendorHandle;
2578*9e86db79SHyon Kim     HBASetRNIDMgmtInfoFunc
2579*9e86db79SHyon Kim 			SetRNIDMgmtInfoFunc;
2580*9e86db79SHyon Kim 
2581*9e86db79SHyon Kim     DEBUG(2, "HBA_SetRNIDMgmtInfo", 0, 0, 0);
2582*9e86db79SHyon Kim 
2583*9e86db79SHyon Kim     CHECKLIBRARY();
2584*9e86db79SHyon Kim     SetRNIDMgmtInfoFunc = FUNCCOMMON(lib_infop, SetRNIDMgmtInfoHandler);
2585*9e86db79SHyon Kim     if (SetRNIDMgmtInfoFunc != NULL) {
2586*9e86db79SHyon Kim 	status = (SetRNIDMgmtInfoFunc)(vendorHandle, Info);
2587*9e86db79SHyon Kim 	} else {
2588*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2589*9e86db79SHyon Kim 	}
2590*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2591*9e86db79SHyon Kim }
2592*9e86db79SHyon Kim 
2593*9e86db79SHyon Kim HBA_STATUS
2594*9e86db79SHyon Kim HBA_GetRNIDMgmtInfo(HBA_HANDLE handle, HBA_MGMTINFO *pInfo) {
2595*9e86db79SHyon Kim     HBA_STATUS		status;
2596*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_infop;
2597*9e86db79SHyon Kim     HBA_HANDLE		vendorHandle;
2598*9e86db79SHyon Kim     HBAGetRNIDMgmtInfoFunc
2599*9e86db79SHyon Kim 	    GetRNIDMgmtInfoFunc;
2600*9e86db79SHyon Kim 
2601*9e86db79SHyon Kim     DEBUG(2, "HBA_GetRNIDMgmtInfo", 0, 0, 0);
2602*9e86db79SHyon Kim 
2603*9e86db79SHyon Kim     CHECKLIBRARY();
2604*9e86db79SHyon Kim     GetRNIDMgmtInfoFunc = FUNCCOMMON(lib_infop, GetRNIDMgmtInfoHandler);
2605*9e86db79SHyon Kim     if (GetRNIDMgmtInfoFunc != NULL) {
2606*9e86db79SHyon Kim 	status = (GetRNIDMgmtInfoFunc)(vendorHandle, pInfo);
2607*9e86db79SHyon Kim 	} else {
2608*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2609*9e86db79SHyon Kim 	}
2610*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2611*9e86db79SHyon Kim }
2612*9e86db79SHyon Kim 
2613*9e86db79SHyon Kim HBA_STATUS
2614*9e86db79SHyon Kim HBA_SendRNID(
2615*9e86db79SHyon Kim     HBA_HANDLE		handle,
2616*9e86db79SHyon Kim     HBA_WWN		wwn,
2617*9e86db79SHyon Kim     HBA_WWNTYPE		wwntype,
2618*9e86db79SHyon Kim     void		*pRspBuffer,
2619*9e86db79SHyon Kim     HBA_UINT32		*pRspBufferSize)
2620*9e86db79SHyon Kim {
2621*9e86db79SHyon Kim 	HBA_STATUS		status;
2622*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2623*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2624*9e86db79SHyon Kim 	HBASendRNIDFunc	SendRNIDFunc;
2625*9e86db79SHyon Kim 
2626*9e86db79SHyon Kim 	DEBUG(2, "HBA_SendRNID for wwn: %s", WWN2STR1(&wwn), 0, 0);
2627*9e86db79SHyon Kim 
2628*9e86db79SHyon Kim 	CHECKLIBRARY();
2629*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2630*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2631*9e86db79SHyon Kim 	}
2632*9e86db79SHyon Kim 
2633*9e86db79SHyon Kim 	SendRNIDFunc = lib_infop->ftable.functionTable.SendRNIDHandler;
2634*9e86db79SHyon Kim 	if (SendRNIDFunc != NULL) {
2635*9e86db79SHyon Kim 	status = ((SendRNIDFunc)(vendorHandle, wwn, wwntype,
2636*9e86db79SHyon Kim 	    pRspBuffer, pRspBufferSize));
2637*9e86db79SHyon Kim 	} else {
2638*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2639*9e86db79SHyon Kim 	}
2640*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2641*9e86db79SHyon Kim }
2642*9e86db79SHyon Kim 
2643*9e86db79SHyon Kim HBA_STATUS
2644*9e86db79SHyon Kim HBA_SendRNIDV2(
2645*9e86db79SHyon Kim     HBA_HANDLE		handle,
2646*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
2647*9e86db79SHyon Kim     HBA_WWN		destWWN,
2648*9e86db79SHyon Kim     HBA_UINT32		destFCID,
2649*9e86db79SHyon Kim     HBA_UINT32		NodeIdDataFormat,
2650*9e86db79SHyon Kim     void		*pRspBuffer,
2651*9e86db79SHyon Kim     HBA_UINT32		*pRspBufferSize)
2652*9e86db79SHyon Kim {
2653*9e86db79SHyon Kim 	HBA_STATUS		status;
2654*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2655*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2656*9e86db79SHyon Kim 	HBASendRNIDV2Func	registeredfunc;
2657*9e86db79SHyon Kim 
2658*9e86db79SHyon Kim 	DEBUG(2, "HBA_SendRNIDV2, hbaPortWWN: %s", WWN2STR1(&hbaPortWWN), 0, 0);
2659*9e86db79SHyon Kim 
2660*9e86db79SHyon Kim 	CHECKLIBRARY();
2661*9e86db79SHyon Kim 	registeredfunc = FUNCCOMMON(lib_infop, SendRNIDV2Handler);
2662*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
2663*9e86db79SHyon Kim 	status = (registeredfunc)
2664*9e86db79SHyon Kim 	    (vendorHandle, hbaPortWWN, destWWN, destFCID, NodeIdDataFormat,
2665*9e86db79SHyon Kim 	    pRspBuffer, pRspBufferSize);
2666*9e86db79SHyon Kim 	} else {
2667*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2668*9e86db79SHyon Kim 	}
2669*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2670*9e86db79SHyon Kim }
2671*9e86db79SHyon Kim 
2672*9e86db79SHyon Kim void
2673*9e86db79SHyon Kim HBA_RefreshInformation(HBA_HANDLE handle) {
2674*9e86db79SHyon Kim     HBA_STATUS		status;
2675*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_infop;
2676*9e86db79SHyon Kim     HBA_HANDLE		vendorHandle;
2677*9e86db79SHyon Kim     HBARefreshInformationFunc
2678*9e86db79SHyon Kim 	    RefreshInformationFunc;
2679*9e86db79SHyon Kim 
2680*9e86db79SHyon Kim 	DEBUG(2, "HBA_RefreshInformation", 0, 0, 0);
2681*9e86db79SHyon Kim 
2682*9e86db79SHyon Kim 	status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
2683*9e86db79SHyon Kim 	if (status == HBA_STATUS_OK) {
2684*9e86db79SHyon Kim 	RefreshInformationFunc =
2685*9e86db79SHyon Kim 	    FUNCCOMMON(lib_infop, RefreshInformationHandler);
2686*9e86db79SHyon Kim 	if (RefreshInformationFunc != NULL) {
2687*9e86db79SHyon Kim 	    ((RefreshInformationFunc)(vendorHandle));
2688*9e86db79SHyon Kim 	}
2689*9e86db79SHyon Kim 	RELEASE_MUTEX(&_hbaapi_LL_mutex);
2690*9e86db79SHyon Kim 	}
2691*9e86db79SHyon Kim }
2692*9e86db79SHyon Kim 
2693*9e86db79SHyon Kim void
2694*9e86db79SHyon Kim HBA_ResetStatistics(HBA_HANDLE handle, HBA_UINT32 portindex) {
2695*9e86db79SHyon Kim     HBA_STATUS		status;
2696*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_infop;
2697*9e86db79SHyon Kim     HBA_HANDLE		vendorHandle;
2698*9e86db79SHyon Kim     HBAResetStatisticsFunc
2699*9e86db79SHyon Kim 			ResetStatisticsFunc;
2700*9e86db79SHyon Kim 
2701*9e86db79SHyon Kim     DEBUG(2, "HBA_ResetStatistics", 0, 0, 0);
2702*9e86db79SHyon Kim 
2703*9e86db79SHyon Kim     status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
2704*9e86db79SHyon Kim     if (status == HBA_STATUS_OK) {
2705*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2706*9e86db79SHyon Kim 		RELEASE_MUTEX(&_hbaapi_LL_mutex);
2707*9e86db79SHyon Kim 	}
2708*9e86db79SHyon Kim 
2709*9e86db79SHyon Kim 	ResetStatisticsFunc =
2710*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.ResetStatisticsHandler;
2711*9e86db79SHyon Kim 	if (ResetStatisticsFunc != NULL) {
2712*9e86db79SHyon Kim 	    ((ResetStatisticsFunc)(vendorHandle, portindex));
2713*9e86db79SHyon Kim 	}
2714*9e86db79SHyon Kim 	RELEASE_MUTEX(&_hbaapi_LL_mutex);
2715*9e86db79SHyon Kim 	}
2716*9e86db79SHyon Kim }
2717*9e86db79SHyon Kim 
2718*9e86db79SHyon Kim HBA_STATUS
2719*9e86db79SHyon Kim HBA_GetFcpTargetMapping(HBA_HANDLE handle, PHBA_FCPTARGETMAPPING mapping) {
2720*9e86db79SHyon Kim     HBA_STATUS		status;
2721*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_infop;
2722*9e86db79SHyon Kim     HBA_HANDLE		vendorHandle;
2723*9e86db79SHyon Kim     HBAGetFcpTargetMappingFunc GetFcpTargetMappingFunc;
2724*9e86db79SHyon Kim 
2725*9e86db79SHyon Kim     DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0);
2726*9e86db79SHyon Kim 
2727*9e86db79SHyon Kim     CHECKLIBRARY();
2728*9e86db79SHyon Kim     if (lib_infop->version == SMHBA) {
2729*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2730*9e86db79SHyon Kim 	}
2731*9e86db79SHyon Kim 
2732*9e86db79SHyon Kim     GetFcpTargetMappingFunc =
2733*9e86db79SHyon Kim 	lib_infop->ftable.functionTable.GetFcpTargetMappingHandler;
2734*9e86db79SHyon Kim     if (GetFcpTargetMappingFunc != NULL) {
2735*9e86db79SHyon Kim 	status = ((GetFcpTargetMappingFunc)(vendorHandle, mapping));
2736*9e86db79SHyon Kim 	} else {
2737*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2738*9e86db79SHyon Kim 	}
2739*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2740*9e86db79SHyon Kim }
2741*9e86db79SHyon Kim 
2742*9e86db79SHyon Kim HBA_STATUS
2743*9e86db79SHyon Kim HBA_GetFcpTargetMappingV2(
2744*9e86db79SHyon Kim     HBA_HANDLE		handle,
2745*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
2746*9e86db79SHyon Kim     HBA_FCPTARGETMAPPINGV2 *pmapping)
2747*9e86db79SHyon Kim {
2748*9e86db79SHyon Kim 	HBA_STATUS		status;
2749*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2750*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2751*9e86db79SHyon Kim 	HBAGetFcpTargetMappingV2Func
2752*9e86db79SHyon Kim 	    registeredfunc;
2753*9e86db79SHyon Kim 
2754*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0);
2755*9e86db79SHyon Kim 
2756*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
2757*9e86db79SHyon Kim 
2758*9e86db79SHyon Kim 	registeredfunc =
2759*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetFcpTargetMappingV2Handler;
2760*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
2761*9e86db79SHyon Kim 	status = ((registeredfunc)(vendorHandle, hbaPortWWN, pmapping));
2762*9e86db79SHyon Kim 	} else {
2763*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2764*9e86db79SHyon Kim 	}
2765*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2766*9e86db79SHyon Kim }
2767*9e86db79SHyon Kim 
2768*9e86db79SHyon Kim HBA_STATUS
2769*9e86db79SHyon Kim HBA_GetFcpPersistentBinding(HBA_HANDLE handle, PHBA_FCPBINDING binding) {
2770*9e86db79SHyon Kim     HBA_STATUS		status;
2771*9e86db79SHyon Kim     HBA_LIBRARY_INFO	*lib_infop;
2772*9e86db79SHyon Kim     HBA_HANDLE		vendorHandle;
2773*9e86db79SHyon Kim     HBAGetFcpPersistentBindingFunc
2774*9e86db79SHyon Kim 	    GetFcpPersistentBindingFunc;
2775*9e86db79SHyon Kim 
2776*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetFcpPersistentBinding", 0, 0, 0);
2777*9e86db79SHyon Kim 
2778*9e86db79SHyon Kim 	CHECKLIBRARY();
2779*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2780*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2781*9e86db79SHyon Kim 	}
2782*9e86db79SHyon Kim 
2783*9e86db79SHyon Kim 	GetFcpPersistentBindingFunc =
2784*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetFcpPersistentBindingHandler;
2785*9e86db79SHyon Kim 	if (GetFcpPersistentBindingFunc != NULL) {
2786*9e86db79SHyon Kim 	status = ((GetFcpPersistentBindingFunc)(vendorHandle, binding));
2787*9e86db79SHyon Kim 	} else {
2788*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2789*9e86db79SHyon Kim 	}
2790*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2791*9e86db79SHyon Kim }
2792*9e86db79SHyon Kim 
2793*9e86db79SHyon Kim HBA_STATUS
2794*9e86db79SHyon Kim HBA_ScsiInquiryV2(
2795*9e86db79SHyon Kim     HBA_HANDLE	handle,
2796*9e86db79SHyon Kim     HBA_WWN	hbaPortWWN,
2797*9e86db79SHyon Kim     HBA_WWN	discoveredPortWWN,
2798*9e86db79SHyon Kim     HBA_UINT64	fcLUN,
2799*9e86db79SHyon Kim     HBA_UINT8	CDB_Byte1,
2800*9e86db79SHyon Kim     HBA_UINT8	CDB_Byte2,
2801*9e86db79SHyon Kim     void	*pRspBuffer,
2802*9e86db79SHyon Kim     HBA_UINT32	*pRspBufferSize,
2803*9e86db79SHyon Kim     HBA_UINT8	*pScsiStatus,
2804*9e86db79SHyon Kim     void	*pSenseBuffer,
2805*9e86db79SHyon Kim     HBA_UINT32	*pSenseBufferSize)
2806*9e86db79SHyon Kim {
2807*9e86db79SHyon Kim 	HBA_STATUS		status;
2808*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2809*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2810*9e86db79SHyon Kim 	HBAScsiInquiryV2Func ScsiInquiryV2Func;
2811*9e86db79SHyon Kim 
2812*9e86db79SHyon Kim 	DEBUG(2, "HBA_ScsiInquiryV2 to discoveredPortWWN: %s",
2813*9e86db79SHyon Kim 	    WWN2STR1(&discoveredPortWWN), 0, 0);
2814*9e86db79SHyon Kim 
2815*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
2816*9e86db79SHyon Kim 
2817*9e86db79SHyon Kim 	ScsiInquiryV2Func =
2818*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.ScsiInquiryV2Handler;
2819*9e86db79SHyon Kim 	if (ScsiInquiryV2Func != NULL) {
2820*9e86db79SHyon Kim 	status = ((ScsiInquiryV2Func)(
2821*9e86db79SHyon Kim 	    vendorHandle, hbaPortWWN, discoveredPortWWN, fcLUN, CDB_Byte1,
2822*9e86db79SHyon Kim 	    CDB_Byte2, pRspBuffer, pRspBufferSize, pScsiStatus,
2823*9e86db79SHyon Kim 	    pSenseBuffer, pSenseBufferSize));
2824*9e86db79SHyon Kim 	} else {
2825*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2826*9e86db79SHyon Kim 	}
2827*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2828*9e86db79SHyon Kim }
2829*9e86db79SHyon Kim 
2830*9e86db79SHyon Kim HBA_STATUS
2831*9e86db79SHyon Kim HBA_SendScsiInquiry(
2832*9e86db79SHyon Kim     HBA_HANDLE	handle,
2833*9e86db79SHyon Kim     HBA_WWN	PortWWN,
2834*9e86db79SHyon Kim     HBA_UINT64	fcLUN,
2835*9e86db79SHyon Kim     HBA_UINT8	EVPD,
2836*9e86db79SHyon Kim     HBA_UINT32	PageCode,
2837*9e86db79SHyon Kim     void	*pRspBuffer,
2838*9e86db79SHyon Kim     HBA_UINT32	RspBufferSize,
2839*9e86db79SHyon Kim     void	*pSenseBuffer,
2840*9e86db79SHyon Kim     HBA_UINT32	SenseBufferSize)
2841*9e86db79SHyon Kim {
2842*9e86db79SHyon Kim 	HBA_STATUS		status;
2843*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2844*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2845*9e86db79SHyon Kim 	HBASendScsiInquiryFunc SendScsiInquiryFunc;
2846*9e86db79SHyon Kim 
2847*9e86db79SHyon Kim 	DEBUG(2, "HBA_SendScsiInquiry to PortWWN: %s",
2848*9e86db79SHyon Kim 	    WWN2STR1(&PortWWN), 0, 0);
2849*9e86db79SHyon Kim 
2850*9e86db79SHyon Kim 	CHECKLIBRARY();
2851*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2852*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2853*9e86db79SHyon Kim 	}
2854*9e86db79SHyon Kim 
2855*9e86db79SHyon Kim 	SendScsiInquiryFunc =
2856*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.ScsiInquiryHandler;
2857*9e86db79SHyon Kim 	if (SendScsiInquiryFunc != NULL) {
2858*9e86db79SHyon Kim 	status = ((SendScsiInquiryFunc)(
2859*9e86db79SHyon Kim 	    vendorHandle, PortWWN, fcLUN, EVPD, PageCode, pRspBuffer,
2860*9e86db79SHyon Kim 	    RspBufferSize, pSenseBuffer, SenseBufferSize));
2861*9e86db79SHyon Kim 	} else {
2862*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2863*9e86db79SHyon Kim 	}
2864*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2865*9e86db79SHyon Kim }
2866*9e86db79SHyon Kim 
2867*9e86db79SHyon Kim HBA_STATUS
2868*9e86db79SHyon Kim HBA_ScsiReportLUNsV2(
2869*9e86db79SHyon Kim     HBA_HANDLE		handle,
2870*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
2871*9e86db79SHyon Kim     HBA_WWN		discoveredPortWWN,
2872*9e86db79SHyon Kim     void		*pRespBuffer,
2873*9e86db79SHyon Kim     HBA_UINT32		*pRespBufferSize,
2874*9e86db79SHyon Kim     HBA_UINT8		*pScsiStatus,
2875*9e86db79SHyon Kim     void		*pSenseBuffer,
2876*9e86db79SHyon Kim     HBA_UINT32		*pSenseBufferSize)
2877*9e86db79SHyon Kim {
2878*9e86db79SHyon Kim 	HBA_STATUS		status;
2879*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2880*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2881*9e86db79SHyon Kim 	HBAScsiReportLUNsV2Func ScsiReportLUNsV2Func;
2882*9e86db79SHyon Kim 
2883*9e86db79SHyon Kim 	DEBUG(2, "HBA_ScsiReportLUNsV2 to discoveredPortWWN: %s",
2884*9e86db79SHyon Kim 	    WWN2STR1(&discoveredPortWWN), 0, 0);
2885*9e86db79SHyon Kim 
2886*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
2887*9e86db79SHyon Kim 
2888*9e86db79SHyon Kim 	ScsiReportLUNsV2Func =
2889*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.ScsiReportLUNsV2Handler;
2890*9e86db79SHyon Kim 	if (ScsiReportLUNsV2Func != NULL) {
2891*9e86db79SHyon Kim 	status = ((ScsiReportLUNsV2Func)(
2892*9e86db79SHyon Kim 	    vendorHandle, hbaPortWWN, discoveredPortWWN,
2893*9e86db79SHyon Kim 	    pRespBuffer, pRespBufferSize,
2894*9e86db79SHyon Kim 	    pScsiStatus,
2895*9e86db79SHyon Kim 	    pSenseBuffer, pSenseBufferSize));
2896*9e86db79SHyon Kim 	} else {
2897*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2898*9e86db79SHyon Kim 	}
2899*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2900*9e86db79SHyon Kim }
2901*9e86db79SHyon Kim 
2902*9e86db79SHyon Kim HBA_STATUS
2903*9e86db79SHyon Kim HBA_SendReportLUNs(
2904*9e86db79SHyon Kim     HBA_HANDLE handle,
2905*9e86db79SHyon Kim     HBA_WWN portWWN,
2906*9e86db79SHyon Kim     void *pRspBuffer,
2907*9e86db79SHyon Kim     HBA_UINT32 RspBufferSize,
2908*9e86db79SHyon Kim     void *pSenseBuffer,
2909*9e86db79SHyon Kim     HBA_UINT32 SenseBufferSize)
2910*9e86db79SHyon Kim {
2911*9e86db79SHyon Kim 	HBA_STATUS		status;
2912*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2913*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2914*9e86db79SHyon Kim 	HBASendReportLUNsFunc SendReportLUNsFunc;
2915*9e86db79SHyon Kim 
2916*9e86db79SHyon Kim 	DEBUG(2, "HBA_SendReportLUNs to PortWWN: %s", WWN2STR1(&portWWN), 0, 0);
2917*9e86db79SHyon Kim 
2918*9e86db79SHyon Kim 	CHECKLIBRARY();
2919*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2920*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2921*9e86db79SHyon Kim 	}
2922*9e86db79SHyon Kim 
2923*9e86db79SHyon Kim 	SendReportLUNsFunc = lib_infop->ftable.functionTable.ReportLUNsHandler;
2924*9e86db79SHyon Kim 	if (SendReportLUNsFunc != NULL) {
2925*9e86db79SHyon Kim 	status = ((SendReportLUNsFunc)(
2926*9e86db79SHyon Kim 	    vendorHandle, portWWN, pRspBuffer,
2927*9e86db79SHyon Kim 	    RspBufferSize, pSenseBuffer, SenseBufferSize));
2928*9e86db79SHyon Kim 	} else {
2929*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2930*9e86db79SHyon Kim 	}
2931*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2932*9e86db79SHyon Kim }
2933*9e86db79SHyon Kim 
2934*9e86db79SHyon Kim HBA_STATUS
2935*9e86db79SHyon Kim HBA_ScsiReadCapacityV2(
2936*9e86db79SHyon Kim     HBA_HANDLE		handle,
2937*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
2938*9e86db79SHyon Kim     HBA_WWN		discoveredPortWWN,
2939*9e86db79SHyon Kim     HBA_UINT64		fcLUN,
2940*9e86db79SHyon Kim     void		*pRspBuffer,
2941*9e86db79SHyon Kim     HBA_UINT32		*pRspBufferSize,
2942*9e86db79SHyon Kim     HBA_UINT8		*pScsiStatus,
2943*9e86db79SHyon Kim     void		*pSenseBuffer,
2944*9e86db79SHyon Kim     HBA_UINT32		*SenseBufferSize)
2945*9e86db79SHyon Kim {
2946*9e86db79SHyon Kim 	HBA_STATUS		status;
2947*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2948*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2949*9e86db79SHyon Kim 	HBAScsiReadCapacityV2Func ScsiReadCapacityV2Func;
2950*9e86db79SHyon Kim 
2951*9e86db79SHyon Kim 	DEBUG(2, "HBA_ScsiReadCapacityV2 to discoveredPortWWN: %s",
2952*9e86db79SHyon Kim 	    WWN2STR1(&discoveredPortWWN), 0, 0);
2953*9e86db79SHyon Kim 
2954*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
2955*9e86db79SHyon Kim 
2956*9e86db79SHyon Kim 	ScsiReadCapacityV2Func =
2957*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.ScsiReadCapacityV2Handler;
2958*9e86db79SHyon Kim 	if (ScsiReadCapacityV2Func != NULL) {
2959*9e86db79SHyon Kim 	status = ((ScsiReadCapacityV2Func)(
2960*9e86db79SHyon Kim 	    vendorHandle, hbaPortWWN, discoveredPortWWN, fcLUN,
2961*9e86db79SHyon Kim 	    pRspBuffer, pRspBufferSize,
2962*9e86db79SHyon Kim 	    pScsiStatus,
2963*9e86db79SHyon Kim 	    pSenseBuffer, SenseBufferSize));
2964*9e86db79SHyon Kim 	} else {
2965*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2966*9e86db79SHyon Kim 	}
2967*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2968*9e86db79SHyon Kim }
2969*9e86db79SHyon Kim 
2970*9e86db79SHyon Kim HBA_STATUS
2971*9e86db79SHyon Kim HBA_SendReadCapacity(
2972*9e86db79SHyon Kim     HBA_HANDLE handle,
2973*9e86db79SHyon Kim     HBA_WWN portWWN,
2974*9e86db79SHyon Kim     HBA_UINT64 fcLUN,
2975*9e86db79SHyon Kim     void *pRspBuffer,
2976*9e86db79SHyon Kim     HBA_UINT32 RspBufferSize,
2977*9e86db79SHyon Kim     void *pSenseBuffer,
2978*9e86db79SHyon Kim     HBA_UINT32 SenseBufferSize)
2979*9e86db79SHyon Kim {
2980*9e86db79SHyon Kim 	HBA_STATUS		status;
2981*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
2982*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
2983*9e86db79SHyon Kim 	HBASendReadCapacityFunc SendReadCapacityFunc;
2984*9e86db79SHyon Kim 
2985*9e86db79SHyon Kim 	DEBUG(2, "HBA_SendReadCapacity to portWWN: %s",
2986*9e86db79SHyon Kim 	    WWN2STR1(&portWWN), 0, 0);
2987*9e86db79SHyon Kim 
2988*9e86db79SHyon Kim 	CHECKLIBRARY();
2989*9e86db79SHyon Kim 	if (lib_infop->version == SMHBA) {
2990*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2991*9e86db79SHyon Kim 	}
2992*9e86db79SHyon Kim 
2993*9e86db79SHyon Kim 	SendReadCapacityFunc =
2994*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.ReadCapacityHandler;
2995*9e86db79SHyon Kim 	if (SendReadCapacityFunc != NULL) {
2996*9e86db79SHyon Kim 	status = ((SendReadCapacityFunc)
2997*9e86db79SHyon Kim 	    (vendorHandle, portWWN, fcLUN, pRspBuffer,
2998*9e86db79SHyon Kim 	    RspBufferSize, pSenseBuffer, SenseBufferSize));
2999*9e86db79SHyon Kim 	} else {
3000*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3001*9e86db79SHyon Kim 	}
3002*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3003*9e86db79SHyon Kim }
3004*9e86db79SHyon Kim 
3005*9e86db79SHyon Kim HBA_STATUS
3006*9e86db79SHyon Kim HBA_SendRPL(
3007*9e86db79SHyon Kim     HBA_HANDLE		handle,
3008*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3009*9e86db79SHyon Kim     HBA_WWN		agent_wwn,
3010*9e86db79SHyon Kim     HBA_UINT32		agent_domain,
3011*9e86db79SHyon Kim     HBA_UINT32		portindex,
3012*9e86db79SHyon Kim     void		*pRspBuffer,
3013*9e86db79SHyon Kim     HBA_UINT32		*pRspBufferSize)
3014*9e86db79SHyon Kim {
3015*9e86db79SHyon Kim 	HBA_STATUS		status;
3016*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3017*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3018*9e86db79SHyon Kim 	HBASendRPLFunc registeredfunc;
3019*9e86db79SHyon Kim 
3020*9e86db79SHyon Kim 	DEBUG(2, "HBA_SendRPL to agent_wwn: %s:%d",
3021*9e86db79SHyon Kim 	    WWN2STR1(&agent_wwn), agent_domain, 0);
3022*9e86db79SHyon Kim 
3023*9e86db79SHyon Kim 	CHECKLIBRARY();
3024*9e86db79SHyon Kim 	registeredfunc = FUNCCOMMON(lib_infop, SendRPLHandler);
3025*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3026*9e86db79SHyon Kim 	status = (registeredfunc)(
3027*9e86db79SHyon Kim 	    vendorHandle, hbaPortWWN, agent_wwn, agent_domain, portindex,
3028*9e86db79SHyon Kim 	    pRspBuffer, pRspBufferSize);
3029*9e86db79SHyon Kim 	} else {
3030*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3031*9e86db79SHyon Kim 	}
3032*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3033*9e86db79SHyon Kim }
3034*9e86db79SHyon Kim 
3035*9e86db79SHyon Kim HBA_STATUS
3036*9e86db79SHyon Kim HBA_SendRPS(
3037*9e86db79SHyon Kim     HBA_HANDLE		handle,
3038*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3039*9e86db79SHyon Kim     HBA_WWN		agent_wwn,
3040*9e86db79SHyon Kim     HBA_UINT32		agent_domain,
3041*9e86db79SHyon Kim     HBA_WWN		object_wwn,
3042*9e86db79SHyon Kim     HBA_UINT32		object_port_number,
3043*9e86db79SHyon Kim     void		*pRspBuffer,
3044*9e86db79SHyon Kim     HBA_UINT32		*pRspBufferSize)
3045*9e86db79SHyon Kim {
3046*9e86db79SHyon Kim 	HBA_STATUS		status;
3047*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3048*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3049*9e86db79SHyon Kim 	HBASendRPSFunc registeredfunc;
3050*9e86db79SHyon Kim 
3051*9e86db79SHyon Kim 	DEBUG(2, "HBA_SendRPS  to agent_wwn: %s:%d",
3052*9e86db79SHyon Kim 	    WWN2STR1(&agent_wwn), agent_domain, 0);
3053*9e86db79SHyon Kim 
3054*9e86db79SHyon Kim 	CHECKLIBRARY();
3055*9e86db79SHyon Kim 	registeredfunc = FUNCCOMMON(lib_infop, SendRPSHandler);
3056*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3057*9e86db79SHyon Kim 	status = (registeredfunc)(
3058*9e86db79SHyon Kim 	    vendorHandle, hbaPortWWN, agent_wwn, agent_domain,
3059*9e86db79SHyon Kim 	    object_wwn, object_port_number,
3060*9e86db79SHyon Kim 	    pRspBuffer, pRspBufferSize);
3061*9e86db79SHyon Kim 	} else {
3062*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3063*9e86db79SHyon Kim 	}
3064*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3065*9e86db79SHyon Kim }
3066*9e86db79SHyon Kim 
3067*9e86db79SHyon Kim HBA_STATUS
3068*9e86db79SHyon Kim HBA_SendSRL(
3069*9e86db79SHyon Kim     HBA_HANDLE		handle,
3070*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3071*9e86db79SHyon Kim     HBA_WWN		wwn,
3072*9e86db79SHyon Kim     HBA_UINT32		domain,
3073*9e86db79SHyon Kim     void		*pRspBuffer,
3074*9e86db79SHyon Kim     HBA_UINT32		*pRspBufferSize)
3075*9e86db79SHyon Kim {
3076*9e86db79SHyon Kim 	HBA_STATUS		status;
3077*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3078*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3079*9e86db79SHyon Kim 	HBASendSRLFunc registeredfunc;
3080*9e86db79SHyon Kim 
3081*9e86db79SHyon Kim 	DEBUG(2, "HBA_SendSRL to wwn:%s domain:%d", WWN2STR1(&wwn), domain, 0);
3082*9e86db79SHyon Kim 
3083*9e86db79SHyon Kim 	CHECKLIBRARY();
3084*9e86db79SHyon Kim 	registeredfunc = FUNCCOMMON(lib_infop, SendSRLHandler);
3085*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3086*9e86db79SHyon Kim 	status = (registeredfunc)(
3087*9e86db79SHyon Kim 	    vendorHandle, hbaPortWWN, wwn, domain,
3088*9e86db79SHyon Kim 	    pRspBuffer, pRspBufferSize);
3089*9e86db79SHyon Kim 	} else {
3090*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3091*9e86db79SHyon Kim 	}
3092*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3093*9e86db79SHyon Kim }
3094*9e86db79SHyon Kim HBA_STATUS
3095*9e86db79SHyon Kim HBA_SendRLS(
3096*9e86db79SHyon Kim     HBA_HANDLE		handle,
3097*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3098*9e86db79SHyon Kim     HBA_WWN		destWWN,
3099*9e86db79SHyon Kim     void		*pRspBuffer,
3100*9e86db79SHyon Kim     HBA_UINT32		*pRspBufferSize)
3101*9e86db79SHyon Kim {
3102*9e86db79SHyon Kim 	HBA_STATUS		status;
3103*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3104*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3105*9e86db79SHyon Kim 	HBASendRLSFunc registeredfunc;
3106*9e86db79SHyon Kim 
3107*9e86db79SHyon Kim 	DEBUG(2, "HBA_SendRLS dest_wwn: %s",
3108*9e86db79SHyon Kim 	    WWN2STR1(&destWWN), 0, 0);
3109*9e86db79SHyon Kim 
3110*9e86db79SHyon Kim 	CHECKLIBRARY();
3111*9e86db79SHyon Kim 	registeredfunc = FUNCCOMMON(lib_infop, SendRLSHandler);
3112*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3113*9e86db79SHyon Kim 	status = (registeredfunc)(
3114*9e86db79SHyon Kim 	    vendorHandle, hbaPortWWN, destWWN,
3115*9e86db79SHyon Kim 	    pRspBuffer, pRspBufferSize);
3116*9e86db79SHyon Kim 	} else {
3117*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3118*9e86db79SHyon Kim 	}
3119*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3120*9e86db79SHyon Kim }
3121*9e86db79SHyon Kim 
3122*9e86db79SHyon Kim HBA_STATUS
3123*9e86db79SHyon Kim HBA_SendLIRR(
3124*9e86db79SHyon Kim     HBA_HANDLE		handle,
3125*9e86db79SHyon Kim     HBA_WWN		sourceWWN,
3126*9e86db79SHyon Kim     HBA_WWN		destWWN,
3127*9e86db79SHyon Kim     HBA_UINT8		function,
3128*9e86db79SHyon Kim     HBA_UINT8		type,
3129*9e86db79SHyon Kim     void		*pRspBuffer,
3130*9e86db79SHyon Kim     HBA_UINT32		*pRspBufferSize)
3131*9e86db79SHyon Kim {
3132*9e86db79SHyon Kim 	HBA_STATUS		status;
3133*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3134*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3135*9e86db79SHyon Kim 	HBASendLIRRFunc registeredfunc;
3136*9e86db79SHyon Kim 
3137*9e86db79SHyon Kim 	DEBUG(2, "HBA_SendLIRR destWWN:%s", WWN2STR1(&destWWN), 0, 0);
3138*9e86db79SHyon Kim 
3139*9e86db79SHyon Kim 	CHECKLIBRARY();
3140*9e86db79SHyon Kim 	registeredfunc = FUNCCOMMON(lib_infop, SendLIRRHandler);
3141*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3142*9e86db79SHyon Kim 	status = (registeredfunc)(
3143*9e86db79SHyon Kim 	    vendorHandle, sourceWWN, destWWN, function, type,
3144*9e86db79SHyon Kim 	    pRspBuffer, pRspBufferSize);
3145*9e86db79SHyon Kim 	} else {
3146*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3147*9e86db79SHyon Kim 	}
3148*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3149*9e86db79SHyon Kim }
3150*9e86db79SHyon Kim 
3151*9e86db79SHyon Kim HBA_STATUS
3152*9e86db79SHyon Kim HBA_GetBindingCapability(
3153*9e86db79SHyon Kim     HBA_HANDLE		handle,
3154*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3155*9e86db79SHyon Kim     HBA_BIND_CAPABILITY *pcapability)
3156*9e86db79SHyon Kim {
3157*9e86db79SHyon Kim 	HBA_STATUS		status;
3158*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3159*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3160*9e86db79SHyon Kim 	HBAGetBindingCapabilityFunc
3161*9e86db79SHyon Kim 	    registeredfunc;
3162*9e86db79SHyon Kim 
3163*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetBindingCapability", 0, 0, 0);
3164*9e86db79SHyon Kim 
3165*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
3166*9e86db79SHyon Kim 
3167*9e86db79SHyon Kim 	registeredfunc =
3168*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetBindingCapabilityHandler;
3169*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3170*9e86db79SHyon Kim 	status = (registeredfunc)(vendorHandle, hbaPortWWN, pcapability);
3171*9e86db79SHyon Kim 	} else {
3172*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3173*9e86db79SHyon Kim 	}
3174*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3175*9e86db79SHyon Kim }
3176*9e86db79SHyon Kim 
3177*9e86db79SHyon Kim HBA_STATUS
3178*9e86db79SHyon Kim HBA_GetBindingSupport(
3179*9e86db79SHyon Kim     HBA_HANDLE		handle,
3180*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3181*9e86db79SHyon Kim     HBA_BIND_CAPABILITY *pcapability)
3182*9e86db79SHyon Kim {
3183*9e86db79SHyon Kim 	HBA_STATUS		status;
3184*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3185*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3186*9e86db79SHyon Kim 	HBAGetBindingSupportFunc
3187*9e86db79SHyon Kim 	    registeredfunc;
3188*9e86db79SHyon Kim 
3189*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetBindingSupport", 0, 0, 0);
3190*9e86db79SHyon Kim 
3191*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
3192*9e86db79SHyon Kim 
3193*9e86db79SHyon Kim 	registeredfunc =
3194*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetBindingSupportHandler;
3195*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3196*9e86db79SHyon Kim 	status = (registeredfunc)(vendorHandle, hbaPortWWN, pcapability);
3197*9e86db79SHyon Kim 	} else {
3198*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3199*9e86db79SHyon Kim 	}
3200*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3201*9e86db79SHyon Kim }
3202*9e86db79SHyon Kim 
3203*9e86db79SHyon Kim HBA_STATUS
3204*9e86db79SHyon Kim HBA_SetBindingSupport(
3205*9e86db79SHyon Kim     HBA_HANDLE		handle,
3206*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3207*9e86db79SHyon Kim     HBA_BIND_CAPABILITY capability)
3208*9e86db79SHyon Kim {
3209*9e86db79SHyon Kim 	HBA_STATUS		status;
3210*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3211*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3212*9e86db79SHyon Kim 	HBASetBindingSupportFunc
3213*9e86db79SHyon Kim 	    registeredfunc;
3214*9e86db79SHyon Kim 
3215*9e86db79SHyon Kim 	DEBUG(2, "HBA_SetBindingSupport", 0, 0, 0);
3216*9e86db79SHyon Kim 
3217*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
3218*9e86db79SHyon Kim 
3219*9e86db79SHyon Kim 	registeredfunc =
3220*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.SetBindingSupportHandler;
3221*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3222*9e86db79SHyon Kim 	status = (registeredfunc)(vendorHandle, hbaPortWWN, capability);
3223*9e86db79SHyon Kim 	} else {
3224*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3225*9e86db79SHyon Kim 	}
3226*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3227*9e86db79SHyon Kim }
3228*9e86db79SHyon Kim 
3229*9e86db79SHyon Kim HBA_STATUS
3230*9e86db79SHyon Kim HBA_SetPersistentBindingV2(
3231*9e86db79SHyon Kim     HBA_HANDLE		handle,
3232*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3233*9e86db79SHyon Kim     const HBA_FCPBINDING2 *pbinding)
3234*9e86db79SHyon Kim {
3235*9e86db79SHyon Kim 	HBA_STATUS		status;
3236*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3237*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3238*9e86db79SHyon Kim 	HBASetPersistentBindingV2Func
3239*9e86db79SHyon Kim 	    registeredfunc;
3240*9e86db79SHyon Kim 
3241*9e86db79SHyon Kim 	DEBUG(2, "HBA_SetPersistentBindingV2 port: %s",
3242*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), 0, 0);
3243*9e86db79SHyon Kim 
3244*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
3245*9e86db79SHyon Kim 
3246*9e86db79SHyon Kim 	registeredfunc =
3247*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.SetPersistentBindingV2Handler;
3248*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3249*9e86db79SHyon Kim 	status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
3250*9e86db79SHyon Kim 	} else {
3251*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3252*9e86db79SHyon Kim 	}
3253*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3254*9e86db79SHyon Kim }
3255*9e86db79SHyon Kim 
3256*9e86db79SHyon Kim HBA_STATUS
3257*9e86db79SHyon Kim HBA_GetPersistentBindingV2(
3258*9e86db79SHyon Kim     HBA_HANDLE		handle,
3259*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3260*9e86db79SHyon Kim     HBA_FCPBINDING2	*pbinding)
3261*9e86db79SHyon Kim {
3262*9e86db79SHyon Kim 	HBA_STATUS		status;
3263*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3264*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3265*9e86db79SHyon Kim 	HBAGetPersistentBindingV2Func
3266*9e86db79SHyon Kim 	    registeredfunc;
3267*9e86db79SHyon Kim 
3268*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetPersistentBindingV2 port: %s",
3269*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), 0, 0);
3270*9e86db79SHyon Kim 
3271*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
3272*9e86db79SHyon Kim 
3273*9e86db79SHyon Kim 	registeredfunc =
3274*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetPersistentBindingV2Handler;
3275*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3276*9e86db79SHyon Kim 	status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
3277*9e86db79SHyon Kim 	} else {
3278*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3279*9e86db79SHyon Kim 	}
3280*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3281*9e86db79SHyon Kim }
3282*9e86db79SHyon Kim 
3283*9e86db79SHyon Kim HBA_STATUS
3284*9e86db79SHyon Kim HBA_RemovePersistentBinding(
3285*9e86db79SHyon Kim     HBA_HANDLE		handle,
3286*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3287*9e86db79SHyon Kim     const HBA_FCPBINDING2
3288*9e86db79SHyon Kim 			*pbinding)
3289*9e86db79SHyon Kim {
3290*9e86db79SHyon Kim 	HBA_STATUS		status;
3291*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3292*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3293*9e86db79SHyon Kim 	HBARemovePersistentBindingFunc
3294*9e86db79SHyon Kim 	    registeredfunc;
3295*9e86db79SHyon Kim 
3296*9e86db79SHyon Kim 	DEBUG(2, "HBA_RemovePersistentBinding", 0, 0, 0);
3297*9e86db79SHyon Kim 
3298*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
3299*9e86db79SHyon Kim 
3300*9e86db79SHyon Kim 	registeredfunc =
3301*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.RemovePersistentBindingHandler;
3302*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3303*9e86db79SHyon Kim 	status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
3304*9e86db79SHyon Kim 	} else {
3305*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3306*9e86db79SHyon Kim 	}
3307*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3308*9e86db79SHyon Kim }
3309*9e86db79SHyon Kim 
3310*9e86db79SHyon Kim HBA_STATUS
3311*9e86db79SHyon Kim HBA_RemoveAllPersistentBindings(
3312*9e86db79SHyon Kim     HBA_HANDLE		handle,
3313*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN)
3314*9e86db79SHyon Kim {
3315*9e86db79SHyon Kim 	HBA_STATUS		status;
3316*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3317*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3318*9e86db79SHyon Kim 	HBARemoveAllPersistentBindingsFunc
3319*9e86db79SHyon Kim 	    registeredfunc;
3320*9e86db79SHyon Kim 
3321*9e86db79SHyon Kim 	DEBUG(2, "HBA_RemoveAllPersistentBindings", 0, 0, 0);
3322*9e86db79SHyon Kim 
3323*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
3324*9e86db79SHyon Kim 
3325*9e86db79SHyon Kim 	registeredfunc =
3326*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.RemoveAllPersistentBindingsHandler;
3327*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3328*9e86db79SHyon Kim 	status = (registeredfunc)(vendorHandle, hbaPortWWN);
3329*9e86db79SHyon Kim 	} else {
3330*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3331*9e86db79SHyon Kim 	}
3332*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3333*9e86db79SHyon Kim }
3334*9e86db79SHyon Kim 
3335*9e86db79SHyon Kim HBA_STATUS
3336*9e86db79SHyon Kim HBA_GetFC4Statistics(
3337*9e86db79SHyon Kim     HBA_HANDLE		handle,
3338*9e86db79SHyon Kim     HBA_WWN		portWWN,
3339*9e86db79SHyon Kim     HBA_UINT8		FC4type,
3340*9e86db79SHyon Kim     HBA_FC4STATISTICS	*pstatistics)
3341*9e86db79SHyon Kim {
3342*9e86db79SHyon Kim 	HBA_STATUS		status;
3343*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3344*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3345*9e86db79SHyon Kim 	HBAGetFC4StatisticsFunc
3346*9e86db79SHyon Kim 	    registeredfunc;
3347*9e86db79SHyon Kim 
3348*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetFC4Statistics port: %s", WWN2STR1(&portWWN), 0, 0);
3349*9e86db79SHyon Kim 
3350*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
3351*9e86db79SHyon Kim 
3352*9e86db79SHyon Kim 	registeredfunc =
3353*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetFC4StatisticsHandler;
3354*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3355*9e86db79SHyon Kim 	status = (registeredfunc)
3356*9e86db79SHyon Kim 	    (vendorHandle, portWWN, FC4type, pstatistics);
3357*9e86db79SHyon Kim 	} else {
3358*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3359*9e86db79SHyon Kim 	}
3360*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3361*9e86db79SHyon Kim }
3362*9e86db79SHyon Kim 
3363*9e86db79SHyon Kim HBA_STATUS
3364*9e86db79SHyon Kim HBA_GetFCPStatistics(
3365*9e86db79SHyon Kim     HBA_HANDLE		handle,
3366*9e86db79SHyon Kim     const HBA_SCSIID	*lunit,
3367*9e86db79SHyon Kim     HBA_FC4STATISTICS	*pstatistics)
3368*9e86db79SHyon Kim {
3369*9e86db79SHyon Kim 	HBA_STATUS		status;
3370*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3371*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3372*9e86db79SHyon Kim 	HBAGetFCPStatisticsFunc
3373*9e86db79SHyon Kim 	    registeredfunc;
3374*9e86db79SHyon Kim 
3375*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetFCPStatistics", 0, 0, 0);
3376*9e86db79SHyon Kim 
3377*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
3378*9e86db79SHyon Kim 
3379*9e86db79SHyon Kim 	registeredfunc =
3380*9e86db79SHyon Kim 	    lib_infop->ftable.functionTable.GetFCPStatisticsHandler;
3381*9e86db79SHyon Kim 	if (registeredfunc != NULL) {
3382*9e86db79SHyon Kim 	status = (registeredfunc)(vendorHandle, lunit, pstatistics);
3383*9e86db79SHyon Kim 	} else {
3384*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3385*9e86db79SHyon Kim 	}
3386*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3387*9e86db79SHyon Kim }
3388*9e86db79SHyon Kim 
3389*9e86db79SHyon Kim HBA_UINT32
3390*9e86db79SHyon Kim HBA_GetVendorLibraryAttributes(
3391*9e86db79SHyon Kim     HBA_UINT32 adapter_index,
3392*9e86db79SHyon Kim     HBA_LIBRARYATTRIBUTES *attributes)
3393*9e86db79SHyon Kim {
3394*9e86db79SHyon Kim 	HBA_ADAPTER_INFO	*adapt_infop;
3395*9e86db79SHyon Kim 	HBAGetVendorLibraryAttributesFunc
3396*9e86db79SHyon Kim 	    registeredfunc;
3397*9e86db79SHyon Kim 	HBA_UINT32		ret = 0;
3398*9e86db79SHyon Kim 
3399*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetVendorLibraryAttributes adapterindex:%d",
3400*9e86db79SHyon Kim 	    adapter_index, 0, 0);
3401*9e86db79SHyon Kim 	if (_hbaapi_librarylist == NULL) {
3402*9e86db79SHyon Kim 	DEBUG(1, "HBAAPI not loaded yet.", 0, 0, 0);
3403*9e86db79SHyon Kim 	return (0);
3404*9e86db79SHyon Kim 	}
3405*9e86db79SHyon Kim 
3406*9e86db79SHyon Kim 	if (attributes == NULL) {
3407*9e86db79SHyon Kim 		DEBUG(1,
3408*9e86db79SHyon Kim 		    "HBA_GetVendorLibraryAttributes: NULL pointer attributes",
3409*9e86db79SHyon Kim 		    0, 0, 0);
3410*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR_ARG);
3411*9e86db79SHyon Kim 	}
3412*9e86db79SHyon Kim 
3413*9e86db79SHyon Kim 	(void) memset(attributes, 0, sizeof (HBA_LIBRARYATTRIBUTES));
3414*9e86db79SHyon Kim 
3415*9e86db79SHyon Kim 	GRAB_MUTEX(&_hbaapi_LL_mutex);
3416*9e86db79SHyon Kim 	GRAB_MUTEX(&_hbaapi_AL_mutex);
3417*9e86db79SHyon Kim 	for (adapt_infop = _hbaapi_adapterlist;
3418*9e86db79SHyon Kim 	    adapt_infop != NULL;
3419*9e86db79SHyon Kim 	    adapt_infop = adapt_infop->next) {
3420*9e86db79SHyon Kim 
3421*9e86db79SHyon Kim 	if (adapt_infop->index == adapter_index) {
3422*9e86db79SHyon Kim 
3423*9e86db79SHyon Kim 		if (adapt_infop->library->version == SMHBA) {
3424*9e86db79SHyon Kim 		RELEASE_MUTEX(&_hbaapi_AL_mutex);
3425*9e86db79SHyon Kim 		RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
3426*9e86db79SHyon Kim 		    HBA_STATUS_ERROR_INCOMPATIBLE);
3427*9e86db79SHyon Kim 		}
3428*9e86db79SHyon Kim 
3429*9e86db79SHyon Kim 		registeredfunc = adapt_infop->library->
3430*9e86db79SHyon Kim 		    ftable.functionTable.GetVendorLibraryAttributesHandler;
3431*9e86db79SHyon Kim 		if (registeredfunc != NULL) {
3432*9e86db79SHyon Kim 		ret = (registeredfunc)(attributes);
3433*9e86db79SHyon Kim 		} else {
3434*9e86db79SHyon Kim 		/* Version 1 libary? */
3435*9e86db79SHyon Kim 		HBAGetVersionFunc	GetVersionFunc;
3436*9e86db79SHyon Kim 		GetVersionFunc = adapt_infop->library->
3437*9e86db79SHyon Kim 		    ftable.functionTable.GetVersionHandler;
3438*9e86db79SHyon Kim 		if (GetVersionFunc != NULL) {
3439*9e86db79SHyon Kim 			ret = ((GetVersionFunc)());
3440*9e86db79SHyon Kim 		}
3441*9e86db79SHyon Kim #ifdef NOTDEF
3442*9e86db79SHyon Kim 		else {
3443*9e86db79SHyon Kim 		    /* This should not happen, dont think its going to */
3444*9e86db79SHyon Kim 		}
3445*9e86db79SHyon Kim #endif
3446*9e86db79SHyon Kim 		}
3447*9e86db79SHyon Kim 		if (attributes->LibPath[0] == '\0') {
3448*9e86db79SHyon Kim 		if (strlen(adapt_infop->library->LibraryPath) < 256) {
3449*9e86db79SHyon Kim 			(void) strcpy(attributes->LibPath,
3450*9e86db79SHyon Kim 			    adapt_infop->library->LibraryPath);
3451*9e86db79SHyon Kim 		}
3452*9e86db79SHyon Kim 		}
3453*9e86db79SHyon Kim 		break;
3454*9e86db79SHyon Kim 	}
3455*9e86db79SHyon Kim 	}
3456*9e86db79SHyon Kim 	RELEASE_MUTEX(&_hbaapi_AL_mutex);
3457*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, ret);
3458*9e86db79SHyon Kim }
3459*9e86db79SHyon Kim 
3460*9e86db79SHyon Kim 
3461*9e86db79SHyon Kim /*
3462*9e86db79SHyon Kim  * This function returns SM-HBA version that the warpper library implemented.
3463*9e86db79SHyon Kim  */
3464*9e86db79SHyon Kim HBA_UINT32
3465*9e86db79SHyon Kim SMHBA_GetVersion() {
3466*9e86db79SHyon Kim     DEBUG(2, "SMHBA_GetVersion", 0, 0, 0);
3467*9e86db79SHyon Kim     return (SMHBA_LIBVERSION);
3468*9e86db79SHyon Kim }
3469*9e86db79SHyon Kim 
3470*9e86db79SHyon Kim /*
3471*9e86db79SHyon Kim  * This function returns the attributes for the warpper library.
3472*9e86db79SHyon Kim  */
3473*9e86db79SHyon Kim HBA_UINT32
3474*9e86db79SHyon Kim SMHBA_GetWrapperLibraryAttributes(
3475*9e86db79SHyon Kim     SMHBA_LIBRARYATTRIBUTES *attributes)
3476*9e86db79SHyon Kim {
3477*9e86db79SHyon Kim 
3478*9e86db79SHyon Kim 	struct timeval tv;
3479*9e86db79SHyon Kim 	struct tm tp;
3480*9e86db79SHyon Kim 
3481*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetWrapperLibraryAttributes", 0, 0, 0);
3482*9e86db79SHyon Kim 
3483*9e86db79SHyon Kim 	if (attributes == NULL) {
3484*9e86db79SHyon Kim 		DEBUG(1, "SMHBA_GetWrapperLibraryAttributes: "
3485*9e86db79SHyon Kim 		    "NULL pointer attributes",
3486*9e86db79SHyon Kim 		    0, 0, 0);
3487*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR_ARG);
3488*9e86db79SHyon Kim 	}
3489*9e86db79SHyon Kim 
3490*9e86db79SHyon Kim 	(void) memset(attributes, 0, sizeof (SMHBA_LIBRARYATTRIBUTES));
3491*9e86db79SHyon Kim 
3492*9e86db79SHyon Kim #if defined(SOLARIS)
3493*9e86db79SHyon Kim 	if ((handle = dlopen("libSMHBAAPI.so", RTLD_NOW)) != NULL) {
3494*9e86db79SHyon Kim 	if (dlinfo(handle, RTLD_DI_LINKMAP, &map) >= 0) {
3495*9e86db79SHyon Kim 		for (mp = map; mp != NULL; mp = mp->l_next) {
3496*9e86db79SHyon Kim 		if (strlen(map->l_name) < 256) {
3497*9e86db79SHyon Kim 			(void) strcpy(attributes->LibPath, map->l_name);
3498*9e86db79SHyon Kim 		}
3499*9e86db79SHyon Kim 		}
3500*9e86db79SHyon Kim 	}
3501*9e86db79SHyon Kim 	}
3502*9e86db79SHyon Kim 
3503*9e86db79SHyon Kim #endif
3504*9e86db79SHyon Kim 
3505*9e86db79SHyon Kim #if defined(VENDOR)
3506*9e86db79SHyon Kim 	(void) strcpy(attributes->VName, VENDOR);
3507*9e86db79SHyon Kim #else
3508*9e86db79SHyon Kim 	attributes->VName[0] = '\0';
3509*9e86db79SHyon Kim #endif
3510*9e86db79SHyon Kim #if	defined(VERSION)
3511*9e86db79SHyon Kim 	(void) strcpy(attributes->VVersion, VERSION);
3512*9e86db79SHyon Kim #else
3513*9e86db79SHyon Kim 	attributes->VVersion[0] = '\0';
3514*9e86db79SHyon Kim #endif
3515*9e86db79SHyon Kim 
3516*9e86db79SHyon Kim 	if (gettimeofday(&tv, (void *)0) == 0) {
3517*9e86db79SHyon Kim 	if (localtime_r(&tv.tv_sec, &tp) != NULL) {
3518*9e86db79SHyon Kim 		attributes->build_date.tm_mday = tp.tm_mday;
3519*9e86db79SHyon Kim 		attributes->build_date.tm_mon = tp.tm_mon;
3520*9e86db79SHyon Kim 		attributes->build_date.tm_year = tp.tm_year;
3521*9e86db79SHyon Kim 	} else {
3522*9e86db79SHyon Kim 		(void) memset(&attributes->build_date, 0,
3523*9e86db79SHyon Kim 		    sizeof (attributes->build_date));
3524*9e86db79SHyon Kim 	}
3525*9e86db79SHyon Kim 	(void) memset(&attributes->build_date, 0,
3526*9e86db79SHyon Kim 	    sizeof (attributes->build_date));
3527*9e86db79SHyon Kim 	}
3528*9e86db79SHyon Kim 
3529*9e86db79SHyon Kim 	return (1);
3530*9e86db79SHyon Kim }
3531*9e86db79SHyon Kim 
3532*9e86db79SHyon Kim /*
3533*9e86db79SHyon Kim  * This function returns the attributes for the warpper library.
3534*9e86db79SHyon Kim  */
3535*9e86db79SHyon Kim HBA_UINT32
3536*9e86db79SHyon Kim SMHBA_GetVendorLibraryAttributes(
3537*9e86db79SHyon Kim     HBA_UINT32 adapter_index,
3538*9e86db79SHyon Kim     SMHBA_LIBRARYATTRIBUTES *attributes)
3539*9e86db79SHyon Kim {
3540*9e86db79SHyon Kim 	HBA_ADAPTER_INFO	*adapt_infop;
3541*9e86db79SHyon Kim 	SMHBAGetVendorLibraryAttributesFunc
3542*9e86db79SHyon Kim 	    registeredfunc;
3543*9e86db79SHyon Kim 	HBA_UINT32		ret = 0;
3544*9e86db79SHyon Kim 
3545*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetVendorLibraryAttributes adapterindex:%d",
3546*9e86db79SHyon Kim 	    adapter_index, 0, 0);
3547*9e86db79SHyon Kim 	if (_hbaapi_librarylist == NULL) {
3548*9e86db79SHyon Kim 	DEBUG(1, "SMHBAAPI not loaded yet.", 0, 0, 0);
3549*9e86db79SHyon Kim 	return (0);
3550*9e86db79SHyon Kim 	}
3551*9e86db79SHyon Kim 
3552*9e86db79SHyon Kim 	if (attributes == NULL) {
3553*9e86db79SHyon Kim 		DEBUG(1, "SMHBA_GetVendorLibraryAttributes: "
3554*9e86db79SHyon Kim 		    "NULL pointer attributes",
3555*9e86db79SHyon Kim 		    0, 0, 0);
3556*9e86db79SHyon Kim 		return (HBA_STATUS_ERROR_ARG);
3557*9e86db79SHyon Kim 	}
3558*9e86db79SHyon Kim 
3559*9e86db79SHyon Kim 	(void) memset(attributes, 0, sizeof (SMHBA_LIBRARYATTRIBUTES));
3560*9e86db79SHyon Kim 
3561*9e86db79SHyon Kim 	GRAB_MUTEX(&_hbaapi_LL_mutex);
3562*9e86db79SHyon Kim 	GRAB_MUTEX(&_hbaapi_AL_mutex);
3563*9e86db79SHyon Kim 	for (adapt_infop = _hbaapi_adapterlist;
3564*9e86db79SHyon Kim 	    adapt_infop != NULL;
3565*9e86db79SHyon Kim 	    adapt_infop = adapt_infop->next) {
3566*9e86db79SHyon Kim 
3567*9e86db79SHyon Kim 	if (adapt_infop->index == adapter_index) {
3568*9e86db79SHyon Kim 
3569*9e86db79SHyon Kim 		if (adapt_infop->library->version != SMHBA) {
3570*9e86db79SHyon Kim 		RELEASE_MUTEX(&_hbaapi_AL_mutex);
3571*9e86db79SHyon Kim 		RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
3572*9e86db79SHyon Kim 		    HBA_STATUS_ERROR_INCOMPATIBLE);
3573*9e86db79SHyon Kim 		}
3574*9e86db79SHyon Kim 
3575*9e86db79SHyon Kim 		registeredfunc = adapt_infop->library->
3576*9e86db79SHyon Kim 		    ftable.smhbafunctionTable.GetVendorLibraryAttributesHandler;
3577*9e86db79SHyon Kim 		if (registeredfunc != NULL) {
3578*9e86db79SHyon Kim 		ret = (registeredfunc)(attributes);
3579*9e86db79SHyon Kim #ifdef NOTDEF
3580*9e86db79SHyon Kim 		} else {
3581*9e86db79SHyon Kim 		/* This should not happen since the VSL is already loaded. */
3582*9e86db79SHyon Kim #endif
3583*9e86db79SHyon Kim 		}
3584*9e86db79SHyon Kim 		if (attributes->LibPath[0] == '\0') {
3585*9e86db79SHyon Kim 		if (strlen(adapt_infop->library->LibraryPath) < 256) {
3586*9e86db79SHyon Kim 			(void) strcpy(attributes->LibPath,
3587*9e86db79SHyon Kim 			    adapt_infop->library->LibraryPath);
3588*9e86db79SHyon Kim 		}
3589*9e86db79SHyon Kim 		}
3590*9e86db79SHyon Kim 		break;
3591*9e86db79SHyon Kim 	}
3592*9e86db79SHyon Kim 	}
3593*9e86db79SHyon Kim 	RELEASE_MUTEX(&_hbaapi_AL_mutex);
3594*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, ret);
3595*9e86db79SHyon Kim }
3596*9e86db79SHyon Kim 
3597*9e86db79SHyon Kim HBA_STATUS
3598*9e86db79SHyon Kim SMHBA_GetAdapterAttributes(
3599*9e86db79SHyon Kim     HBA_HANDLE		handle,
3600*9e86db79SHyon Kim     SMHBA_ADAPTERATTRIBUTES *hbaattributes)
3601*9e86db79SHyon Kim {
3602*9e86db79SHyon Kim 	HBA_STATUS		status;
3603*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3604*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3605*9e86db79SHyon Kim 	SMHBAGetAdapterAttributesFunc GetAdapterAttributesFunc;
3606*9e86db79SHyon Kim 
3607*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0);
3608*9e86db79SHyon Kim 
3609*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3610*9e86db79SHyon Kim 
3611*9e86db79SHyon Kim 	GetAdapterAttributesFunc =
3612*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetAdapterAttributesHandler;
3613*9e86db79SHyon Kim 	if (GetAdapterAttributesFunc != NULL) {
3614*9e86db79SHyon Kim 	status = ((GetAdapterAttributesFunc)(vendorHandle, hbaattributes));
3615*9e86db79SHyon Kim 	} else {
3616*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3617*9e86db79SHyon Kim 	}
3618*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3619*9e86db79SHyon Kim }
3620*9e86db79SHyon Kim 
3621*9e86db79SHyon Kim HBA_STATUS
3622*9e86db79SHyon Kim SMHBA_GetNumberOfPorts(
3623*9e86db79SHyon Kim     HBA_HANDLE		handle,
3624*9e86db79SHyon Kim     HBA_UINT32		*numberofports)
3625*9e86db79SHyon Kim {
3626*9e86db79SHyon Kim 	HBA_STATUS		status;
3627*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3628*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3629*9e86db79SHyon Kim 	SMHBAGetNumberOfPortsFunc GetNumberOfPortsFunc;
3630*9e86db79SHyon Kim 
3631*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0);
3632*9e86db79SHyon Kim 
3633*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3634*9e86db79SHyon Kim 
3635*9e86db79SHyon Kim 	GetNumberOfPortsFunc =
3636*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetNumberOfPortsHandler;
3637*9e86db79SHyon Kim 	if (GetNumberOfPortsFunc != NULL) {
3638*9e86db79SHyon Kim 	status = ((GetNumberOfPortsFunc)(vendorHandle, numberofports));
3639*9e86db79SHyon Kim 	} else {
3640*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3641*9e86db79SHyon Kim 	}
3642*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3643*9e86db79SHyon Kim }
3644*9e86db79SHyon Kim 
3645*9e86db79SHyon Kim HBA_STATUS
3646*9e86db79SHyon Kim SMHBA_GetPortType(
3647*9e86db79SHyon Kim     HBA_HANDLE		handle,
3648*9e86db79SHyon Kim     HBA_UINT32		portindex,
3649*9e86db79SHyon Kim     HBA_PORTTYPE	*porttype)
3650*9e86db79SHyon Kim {
3651*9e86db79SHyon Kim 	HBA_STATUS		status;
3652*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3653*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3654*9e86db79SHyon Kim 	SMHBAGetPortTypeFunc GetPortTypeFunc;
3655*9e86db79SHyon Kim 
3656*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0);
3657*9e86db79SHyon Kim 
3658*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3659*9e86db79SHyon Kim 
3660*9e86db79SHyon Kim 	GetPortTypeFunc =
3661*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetPortTypeHandler;
3662*9e86db79SHyon Kim 	if (GetPortTypeFunc != NULL) {
3663*9e86db79SHyon Kim 	status = ((GetPortTypeFunc)(vendorHandle, portindex, porttype));
3664*9e86db79SHyon Kim 	} else {
3665*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3666*9e86db79SHyon Kim 	}
3667*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3668*9e86db79SHyon Kim }
3669*9e86db79SHyon Kim 
3670*9e86db79SHyon Kim HBA_STATUS
3671*9e86db79SHyon Kim SMHBA_GetAdapterPortAttributes(
3672*9e86db79SHyon Kim     HBA_HANDLE		handle,
3673*9e86db79SHyon Kim     HBA_UINT32		portindex,
3674*9e86db79SHyon Kim     SMHBA_PORTATTRIBUTES	*portattributes)
3675*9e86db79SHyon Kim {
3676*9e86db79SHyon Kim 	HBA_STATUS		status;
3677*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3678*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3679*9e86db79SHyon Kim 	SMHBAGetAdapterPortAttributesFunc
3680*9e86db79SHyon Kim 	    GetAdapterPortAttributesFunc;
3681*9e86db79SHyon Kim 
3682*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetAdapterPortAttributes", 0, 0, 0);
3683*9e86db79SHyon Kim 
3684*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3685*9e86db79SHyon Kim 
3686*9e86db79SHyon Kim 	GetAdapterPortAttributesFunc =
3687*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.\
3688*9e86db79SHyon Kim 	    GetAdapterPortAttributesHandler;
3689*9e86db79SHyon Kim 	if (GetAdapterPortAttributesFunc != NULL) {
3690*9e86db79SHyon Kim 	status = ((GetAdapterPortAttributesFunc)
3691*9e86db79SHyon Kim 	    (vendorHandle, portindex, portattributes));
3692*9e86db79SHyon Kim 	} else {
3693*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3694*9e86db79SHyon Kim 	}
3695*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3696*9e86db79SHyon Kim }
3697*9e86db79SHyon Kim 
3698*9e86db79SHyon Kim HBA_STATUS
3699*9e86db79SHyon Kim SMHBA_GetDiscoveredPortAttributes(
3700*9e86db79SHyon Kim     HBA_HANDLE		handle,
3701*9e86db79SHyon Kim     HBA_UINT32		portindex,
3702*9e86db79SHyon Kim     HBA_UINT32		discoveredportindex,
3703*9e86db79SHyon Kim     SMHBA_PORTATTRIBUTES	*portattributes)
3704*9e86db79SHyon Kim {
3705*9e86db79SHyon Kim 	HBA_STATUS		status;
3706*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3707*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3708*9e86db79SHyon Kim 	SMHBAGetDiscoveredPortAttributesFunc
3709*9e86db79SHyon Kim 	    GetDiscoveredPortAttributesFunc;
3710*9e86db79SHyon Kim 
3711*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetDiscoveredPortAttributes", 0, 0, 0);
3712*9e86db79SHyon Kim 
3713*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3714*9e86db79SHyon Kim 
3715*9e86db79SHyon Kim 	GetDiscoveredPortAttributesFunc =
3716*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.\
3717*9e86db79SHyon Kim 	    GetDiscoveredPortAttributesHandler;
3718*9e86db79SHyon Kim 	if (GetDiscoveredPortAttributesFunc != NULL)  {
3719*9e86db79SHyon Kim 	status = ((GetDiscoveredPortAttributesFunc)
3720*9e86db79SHyon Kim 	    (vendorHandle, portindex, discoveredportindex,
3721*9e86db79SHyon Kim 	    portattributes));
3722*9e86db79SHyon Kim 	} else {
3723*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3724*9e86db79SHyon Kim 	}
3725*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3726*9e86db79SHyon Kim }
3727*9e86db79SHyon Kim 
3728*9e86db79SHyon Kim HBA_STATUS
3729*9e86db79SHyon Kim SMHBA_GetPortAttributesByWWN(
3730*9e86db79SHyon Kim     HBA_HANDLE		handle,
3731*9e86db79SHyon Kim     HBA_WWN		portWWN,
3732*9e86db79SHyon Kim     HBA_WWN		domainPortWWN,
3733*9e86db79SHyon Kim     SMHBA_PORTATTRIBUTES	*portattributes)
3734*9e86db79SHyon Kim {
3735*9e86db79SHyon Kim 	HBA_STATUS		status;
3736*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3737*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3738*9e86db79SHyon Kim 	SMHBAGetPortAttributesByWWNFunc
3739*9e86db79SHyon Kim 	    GetPortAttributesByWWNFunc;
3740*9e86db79SHyon Kim 
3741*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetPortAttributesByWWN: %s", WWN2STR1(&portWWN), 0, 0);
3742*9e86db79SHyon Kim 
3743*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3744*9e86db79SHyon Kim 
3745*9e86db79SHyon Kim 	GetPortAttributesByWWNFunc =
3746*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetPortAttributesByWWNHandler;
3747*9e86db79SHyon Kim 	if (GetPortAttributesByWWNFunc != NULL) {
3748*9e86db79SHyon Kim 	status = ((GetPortAttributesByWWNFunc)
3749*9e86db79SHyon Kim 	    (vendorHandle, portWWN, domainPortWWN, portattributes));
3750*9e86db79SHyon Kim 	} else {
3751*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3752*9e86db79SHyon Kim 	}
3753*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3754*9e86db79SHyon Kim }
3755*9e86db79SHyon Kim 
3756*9e86db79SHyon Kim HBA_STATUS
3757*9e86db79SHyon Kim SMHBA_GetFCPhyAttributes(
3758*9e86db79SHyon Kim     HBA_HANDLE		handle,
3759*9e86db79SHyon Kim     HBA_UINT32		portindex,
3760*9e86db79SHyon Kim     HBA_UINT32		phyindex,
3761*9e86db79SHyon Kim     SMHBA_FC_PHY	*phytype)
3762*9e86db79SHyon Kim {
3763*9e86db79SHyon Kim 	HBA_STATUS		status;
3764*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3765*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3766*9e86db79SHyon Kim 	SMHBAGetFCPhyAttributesFunc GetFCPhyAttributesFunc;
3767*9e86db79SHyon Kim 
3768*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetFCPhyAttributesByWWN", 0, 0, 0);
3769*9e86db79SHyon Kim 
3770*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3771*9e86db79SHyon Kim 
3772*9e86db79SHyon Kim 	GetFCPhyAttributesFunc =
3773*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetFCPhyAttributesHandler;
3774*9e86db79SHyon Kim 	if (GetFCPhyAttributesFunc != NULL) {
3775*9e86db79SHyon Kim 	status = ((GetFCPhyAttributesFunc)
3776*9e86db79SHyon Kim 	    (vendorHandle, portindex, phyindex, phytype));
3777*9e86db79SHyon Kim 	} else {
3778*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3779*9e86db79SHyon Kim 	}
3780*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3781*9e86db79SHyon Kim }
3782*9e86db79SHyon Kim 
3783*9e86db79SHyon Kim HBA_STATUS
3784*9e86db79SHyon Kim SMHBA_GetSASPhyAttributes(
3785*9e86db79SHyon Kim     HBA_HANDLE		handle,
3786*9e86db79SHyon Kim     HBA_UINT32		portindex,
3787*9e86db79SHyon Kim     HBA_UINT32		phyindex,
3788*9e86db79SHyon Kim     SMHBA_SAS_PHY	*phytype)
3789*9e86db79SHyon Kim {
3790*9e86db79SHyon Kim 	HBA_STATUS		status;
3791*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3792*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3793*9e86db79SHyon Kim 	SMHBAGetSASPhyAttributesFunc GetSASPhyAttributesFunc;
3794*9e86db79SHyon Kim 
3795*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetFCPhyAttributesByWWN", 0, 0, 0);
3796*9e86db79SHyon Kim 
3797*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3798*9e86db79SHyon Kim 
3799*9e86db79SHyon Kim 	GetSASPhyAttributesFunc =
3800*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetSASPhyAttributesHandler;
3801*9e86db79SHyon Kim 	if (GetSASPhyAttributesFunc != NULL) {
3802*9e86db79SHyon Kim 	status = ((GetSASPhyAttributesFunc)
3803*9e86db79SHyon Kim 	    (vendorHandle, portindex, phyindex, phytype));
3804*9e86db79SHyon Kim 	} else {
3805*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3806*9e86db79SHyon Kim 	}
3807*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3808*9e86db79SHyon Kim }
3809*9e86db79SHyon Kim 
3810*9e86db79SHyon Kim HBA_STATUS
3811*9e86db79SHyon Kim SMHBA_GetProtocolStatistics(
3812*9e86db79SHyon Kim     HBA_HANDLE		handle,
3813*9e86db79SHyon Kim     HBA_UINT32		portindex,
3814*9e86db79SHyon Kim     HBA_UINT32		protocoltype,
3815*9e86db79SHyon Kim     SMHBA_PROTOCOLSTATISTICS *pProtocolStatistics)
3816*9e86db79SHyon Kim {
3817*9e86db79SHyon Kim 	HBA_STATUS		status;
3818*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3819*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3820*9e86db79SHyon Kim 	SMHBAGetProtocolStatisticsFunc
3821*9e86db79SHyon Kim 	    GetProtocolStatisticsFunc;
3822*9e86db79SHyon Kim 
3823*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetProtocolStatistics port index: %d protocol type: %d",
3824*9e86db79SHyon Kim 	    portindex, protocoltype, 0);
3825*9e86db79SHyon Kim 
3826*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3827*9e86db79SHyon Kim 
3828*9e86db79SHyon Kim 	GetProtocolStatisticsFunc =
3829*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetProtocolStatisticsHandler;
3830*9e86db79SHyon Kim 	if (GetProtocolStatisticsFunc != NULL) {
3831*9e86db79SHyon Kim 	status = (GetProtocolStatisticsFunc)
3832*9e86db79SHyon Kim 	    (vendorHandle, portindex, protocoltype, pProtocolStatistics);
3833*9e86db79SHyon Kim 	} else {
3834*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3835*9e86db79SHyon Kim 	}
3836*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3837*9e86db79SHyon Kim }
3838*9e86db79SHyon Kim 
3839*9e86db79SHyon Kim HBA_STATUS
3840*9e86db79SHyon Kim SMHBA_GetPhyStatistics(
3841*9e86db79SHyon Kim     HBA_HANDLE		handle,
3842*9e86db79SHyon Kim     HBA_UINT32		portindex,
3843*9e86db79SHyon Kim     HBA_UINT32		phyindex,
3844*9e86db79SHyon Kim     SMHBA_PHYSTATISTICS *pPhyStatistics)
3845*9e86db79SHyon Kim {
3846*9e86db79SHyon Kim 	HBA_STATUS		status;
3847*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3848*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3849*9e86db79SHyon Kim 	SMHBAGetPhyStatisticsFunc
3850*9e86db79SHyon Kim 	    GetPhyStatisticsFunc;
3851*9e86db79SHyon Kim 
3852*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetPhyStatistics port index: %d phy idex: %d",
3853*9e86db79SHyon Kim 	    portindex, phyindex, 0);
3854*9e86db79SHyon Kim 
3855*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3856*9e86db79SHyon Kim 
3857*9e86db79SHyon Kim 	GetPhyStatisticsFunc =
3858*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetPhyStatisticsHandler;
3859*9e86db79SHyon Kim 	if (GetPhyStatisticsFunc != NULL) {
3860*9e86db79SHyon Kim 	status = (GetPhyStatisticsFunc)
3861*9e86db79SHyon Kim 	    (vendorHandle, portindex, phyindex, pPhyStatistics);
3862*9e86db79SHyon Kim 	} else {
3863*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3864*9e86db79SHyon Kim 	}
3865*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3866*9e86db79SHyon Kim }
3867*9e86db79SHyon Kim 
3868*9e86db79SHyon Kim HBA_STATUS
3869*9e86db79SHyon Kim SMHBA_GetBindingCapability(
3870*9e86db79SHyon Kim     HBA_HANDLE		handle,
3871*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3872*9e86db79SHyon Kim     HBA_WWN		domainPortWWN,
3873*9e86db79SHyon Kim     SMHBA_BIND_CAPABILITY *pFlags)
3874*9e86db79SHyon Kim {
3875*9e86db79SHyon Kim 	HBA_STATUS		status;
3876*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3877*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3878*9e86db79SHyon Kim 	SMHBAGetBindingCapabilityFunc GetBindingCapabilityFunc;
3879*9e86db79SHyon Kim 
3880*9e86db79SHyon Kim 	DEBUG(2, "HBA_GetBindingCapability", 0, 0, 0);
3881*9e86db79SHyon Kim 
3882*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3883*9e86db79SHyon Kim 
3884*9e86db79SHyon Kim 	GetBindingCapabilityFunc =
3885*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetBindingCapabilityHandler;
3886*9e86db79SHyon Kim 	if (GetBindingCapabilityFunc != NULL) {
3887*9e86db79SHyon Kim 	status = (GetBindingCapabilityFunc)(vendorHandle, hbaPortWWN,
3888*9e86db79SHyon Kim 	    domainPortWWN, pFlags);
3889*9e86db79SHyon Kim 	} else {
3890*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3891*9e86db79SHyon Kim 	}
3892*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3893*9e86db79SHyon Kim }
3894*9e86db79SHyon Kim 
3895*9e86db79SHyon Kim HBA_STATUS
3896*9e86db79SHyon Kim SMHBA_GetBindingSupport(
3897*9e86db79SHyon Kim     HBA_HANDLE		handle,
3898*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3899*9e86db79SHyon Kim     HBA_WWN		domainPortWWN,
3900*9e86db79SHyon Kim     SMHBA_BIND_CAPABILITY *pFlags)
3901*9e86db79SHyon Kim {
3902*9e86db79SHyon Kim 	HBA_STATUS		status;
3903*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3904*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3905*9e86db79SHyon Kim 	SMHBAGetBindingSupportFunc
3906*9e86db79SHyon Kim 	    GetBindingSupporFunc;
3907*9e86db79SHyon Kim 
3908*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetBindingSupport port: %s",
3909*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), 0, 0);
3910*9e86db79SHyon Kim 
3911*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3912*9e86db79SHyon Kim 
3913*9e86db79SHyon Kim 	GetBindingSupporFunc =
3914*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetBindingSupportHandler;
3915*9e86db79SHyon Kim 	if (GetBindingSupporFunc != NULL) {
3916*9e86db79SHyon Kim 	status = (GetBindingSupporFunc)(vendorHandle,
3917*9e86db79SHyon Kim 	    hbaPortWWN, domainPortWWN, pFlags);
3918*9e86db79SHyon Kim 	} else {
3919*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3920*9e86db79SHyon Kim 	}
3921*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3922*9e86db79SHyon Kim }
3923*9e86db79SHyon Kim 
3924*9e86db79SHyon Kim HBA_STATUS
3925*9e86db79SHyon Kim SMHBA_SetBindingSupport(
3926*9e86db79SHyon Kim     HBA_HANDLE		handle,
3927*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3928*9e86db79SHyon Kim     HBA_WWN		domainPortWWN,
3929*9e86db79SHyon Kim     SMHBA_BIND_CAPABILITY flags)
3930*9e86db79SHyon Kim {
3931*9e86db79SHyon Kim 	HBA_STATUS		status;
3932*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3933*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3934*9e86db79SHyon Kim 	SMHBASetBindingSupportFunc
3935*9e86db79SHyon Kim 	    SetBindingSupporFunc;
3936*9e86db79SHyon Kim 
3937*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetBindingSupport port: %s",
3938*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), 0, 0);
3939*9e86db79SHyon Kim 
3940*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(HBAAPIV2);
3941*9e86db79SHyon Kim 
3942*9e86db79SHyon Kim 	SetBindingSupporFunc =
3943*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.SetBindingSupportHandler;
3944*9e86db79SHyon Kim 	if (SetBindingSupporFunc != NULL) {
3945*9e86db79SHyon Kim 	status = (SetBindingSupporFunc)
3946*9e86db79SHyon Kim 	    (vendorHandle, hbaPortWWN, domainPortWWN, flags);
3947*9e86db79SHyon Kim 	} else {
3948*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3949*9e86db79SHyon Kim 	}
3950*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3951*9e86db79SHyon Kim }
3952*9e86db79SHyon Kim 
3953*9e86db79SHyon Kim HBA_STATUS
3954*9e86db79SHyon Kim SMHBA_GetTargetMapping(
3955*9e86db79SHyon Kim     HBA_HANDLE		handle,
3956*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
3957*9e86db79SHyon Kim     HBA_WWN		domainPortWWN,
3958*9e86db79SHyon Kim     SMHBA_TARGETMAPPING *pMapping)
3959*9e86db79SHyon Kim {
3960*9e86db79SHyon Kim 	HBA_STATUS		status;
3961*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3962*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3963*9e86db79SHyon Kim 	SMHBAGetTargetMappingFunc GetTargetMappingFunc;
3964*9e86db79SHyon Kim 
3965*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetTargetMapping port WWN: %s",
3966*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), 0, 0);
3967*9e86db79SHyon Kim 
3968*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3969*9e86db79SHyon Kim 
3970*9e86db79SHyon Kim 	GetTargetMappingFunc =
3971*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetTargetMappingHandler;
3972*9e86db79SHyon Kim 	if (GetTargetMappingFunc != NULL) {
3973*9e86db79SHyon Kim 	status = ((GetTargetMappingFunc)(vendorHandle,
3974*9e86db79SHyon Kim 	    hbaPortWWN, domainPortWWN, pMapping));
3975*9e86db79SHyon Kim 	} else {
3976*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3977*9e86db79SHyon Kim 	}
3978*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3979*9e86db79SHyon Kim }
3980*9e86db79SHyon Kim 
3981*9e86db79SHyon Kim HBA_STATUS
3982*9e86db79SHyon Kim SMHBA_GetPersistentBinding(
3983*9e86db79SHyon Kim     HBA_HANDLE handle,
3984*9e86db79SHyon Kim     HBA_WWN	hbaPortWWN,
3985*9e86db79SHyon Kim     HBA_WWN	domainPortWWN,
3986*9e86db79SHyon Kim     SMHBA_BINDING *binding)
3987*9e86db79SHyon Kim {
3988*9e86db79SHyon Kim 	HBA_STATUS		status;
3989*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
3990*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
3991*9e86db79SHyon Kim 	SMHBAGetPersistentBindingFunc
3992*9e86db79SHyon Kim 	    GetPersistentBindingFunc;
3993*9e86db79SHyon Kim 
3994*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetPersistentBinding port WWN: %s",
3995*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), 0, 0);
3996*9e86db79SHyon Kim 
3997*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
3998*9e86db79SHyon Kim 
3999*9e86db79SHyon Kim 	GetPersistentBindingFunc =
4000*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetPersistentBindingHandler;
4001*9e86db79SHyon Kim 	if (GetPersistentBindingFunc != NULL) {
4002*9e86db79SHyon Kim 	status = ((GetPersistentBindingFunc)(vendorHandle,
4003*9e86db79SHyon Kim 	    hbaPortWWN, domainPortWWN, binding));
4004*9e86db79SHyon Kim 	} else {
4005*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4006*9e86db79SHyon Kim 	}
4007*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4008*9e86db79SHyon Kim }
4009*9e86db79SHyon Kim 
4010*9e86db79SHyon Kim HBA_STATUS
4011*9e86db79SHyon Kim SMHBA_SetPersistentBinding(
4012*9e86db79SHyon Kim     HBA_HANDLE handle,
4013*9e86db79SHyon Kim     HBA_WWN	hbaPortWWN,
4014*9e86db79SHyon Kim     HBA_WWN	domainPortWWN,
4015*9e86db79SHyon Kim     const SMHBA_BINDING *binding)
4016*9e86db79SHyon Kim {
4017*9e86db79SHyon Kim 	HBA_STATUS		status;
4018*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
4019*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
4020*9e86db79SHyon Kim 	SMHBASetPersistentBindingFunc
4021*9e86db79SHyon Kim 	    SetPersistentBindingFunc;
4022*9e86db79SHyon Kim 
4023*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_SetPersistentBinding port WWN: %s",
4024*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), 0, 0);
4025*9e86db79SHyon Kim 
4026*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4027*9e86db79SHyon Kim 
4028*9e86db79SHyon Kim 	SetPersistentBindingFunc =
4029*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.SetPersistentBindingHandler;
4030*9e86db79SHyon Kim 	if (SetPersistentBindingFunc != NULL) {
4031*9e86db79SHyon Kim 	status = ((SetPersistentBindingFunc)(vendorHandle,
4032*9e86db79SHyon Kim 	    hbaPortWWN, domainPortWWN, binding));
4033*9e86db79SHyon Kim 	} else {
4034*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4035*9e86db79SHyon Kim 	}
4036*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4037*9e86db79SHyon Kim }
4038*9e86db79SHyon Kim 
4039*9e86db79SHyon Kim HBA_STATUS
4040*9e86db79SHyon Kim SMHBA_RemovePersistentBinding(
4041*9e86db79SHyon Kim     HBA_HANDLE handle,
4042*9e86db79SHyon Kim     HBA_WWN	hbaPortWWN,
4043*9e86db79SHyon Kim     HBA_WWN	domainPortWWN,
4044*9e86db79SHyon Kim     const SMHBA_BINDING *binding)
4045*9e86db79SHyon Kim {
4046*9e86db79SHyon Kim 	HBA_STATUS		status;
4047*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
4048*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
4049*9e86db79SHyon Kim 	SMHBARemovePersistentBindingFunc
4050*9e86db79SHyon Kim 	    RemovePersistentBindingFunc;
4051*9e86db79SHyon Kim 
4052*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_RemovePersistentBinding port WWN: %s",
4053*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), 0, 0);
4054*9e86db79SHyon Kim 
4055*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4056*9e86db79SHyon Kim 
4057*9e86db79SHyon Kim 	RemovePersistentBindingFunc =
4058*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.RemovePersistentBindingHandler;
4059*9e86db79SHyon Kim 	if (RemovePersistentBindingFunc != NULL) {
4060*9e86db79SHyon Kim 	status = ((RemovePersistentBindingFunc)(vendorHandle,
4061*9e86db79SHyon Kim 	    hbaPortWWN, domainPortWWN, binding));
4062*9e86db79SHyon Kim 	} else {
4063*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4064*9e86db79SHyon Kim 	}
4065*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4066*9e86db79SHyon Kim }
4067*9e86db79SHyon Kim 
4068*9e86db79SHyon Kim HBA_STATUS
4069*9e86db79SHyon Kim SMHBA_RemoveAllPersistentBindings(
4070*9e86db79SHyon Kim     HBA_HANDLE handle,
4071*9e86db79SHyon Kim     HBA_WWN	hbaPortWWN,
4072*9e86db79SHyon Kim     HBA_WWN	domainPortWWN)
4073*9e86db79SHyon Kim {
4074*9e86db79SHyon Kim 	HBA_STATUS		status;
4075*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
4076*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
4077*9e86db79SHyon Kim 	SMHBARemoveAllPersistentBindingsFunc
4078*9e86db79SHyon Kim 	    RemoveAllPersistentBindingsFunc;
4079*9e86db79SHyon Kim 
4080*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_RemoveAllPersistentBinding port WWN: %s",
4081*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), 0, 0);
4082*9e86db79SHyon Kim 
4083*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4084*9e86db79SHyon Kim 
4085*9e86db79SHyon Kim 	RemoveAllPersistentBindingsFunc =
4086*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.\
4087*9e86db79SHyon Kim 	    RemoveAllPersistentBindingsHandler;
4088*9e86db79SHyon Kim 	if (RemoveAllPersistentBindingsFunc != NULL) {
4089*9e86db79SHyon Kim 	status = ((RemoveAllPersistentBindingsFunc)(vendorHandle,
4090*9e86db79SHyon Kim 	    hbaPortWWN, domainPortWWN));
4091*9e86db79SHyon Kim 	} else {
4092*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4093*9e86db79SHyon Kim 	}
4094*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4095*9e86db79SHyon Kim }
4096*9e86db79SHyon Kim 
4097*9e86db79SHyon Kim HBA_STATUS
4098*9e86db79SHyon Kim SMHBA_GetLUNStatistics(
4099*9e86db79SHyon Kim     HBA_HANDLE handle,
4100*9e86db79SHyon Kim     const HBA_SCSIID *lunit,
4101*9e86db79SHyon Kim     SMHBA_PROTOCOLSTATISTICS *statistics)
4102*9e86db79SHyon Kim {
4103*9e86db79SHyon Kim 	HBA_STATUS		status;
4104*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
4105*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
4106*9e86db79SHyon Kim 	SMHBAGetLUNStatisticsFunc GetLUNStatisticsFunc;
4107*9e86db79SHyon Kim 
4108*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_GetLUNStatistics", 0, 0, 0);
4109*9e86db79SHyon Kim 
4110*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4111*9e86db79SHyon Kim 
4112*9e86db79SHyon Kim 	GetLUNStatisticsFunc =
4113*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.GetLUNStatisticsHandler;
4114*9e86db79SHyon Kim 	if (GetLUNStatisticsFunc != NULL) {
4115*9e86db79SHyon Kim 	status = ((GetLUNStatisticsFunc)(vendorHandle, lunit, statistics));
4116*9e86db79SHyon Kim 	} else {
4117*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4118*9e86db79SHyon Kim 	}
4119*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4120*9e86db79SHyon Kim }
4121*9e86db79SHyon Kim 
4122*9e86db79SHyon Kim HBA_STATUS
4123*9e86db79SHyon Kim SMHBA_ScsiInquiry(
4124*9e86db79SHyon Kim     HBA_HANDLE	handle,
4125*9e86db79SHyon Kim     HBA_WWN	hbaPortWWN,
4126*9e86db79SHyon Kim     HBA_WWN	discoveredPortWWN,
4127*9e86db79SHyon Kim     HBA_WWN	domainPortWWN,
4128*9e86db79SHyon Kim     SMHBA_SCSILUN	smhbaLUN,
4129*9e86db79SHyon Kim     HBA_UINT8	CDB_Byte1,
4130*9e86db79SHyon Kim     HBA_UINT8	CDB_Byte2,
4131*9e86db79SHyon Kim     void	*pRspBuffer,
4132*9e86db79SHyon Kim     HBA_UINT32	*pRspBufferSize,
4133*9e86db79SHyon Kim     HBA_UINT8	*pScsiStatus,
4134*9e86db79SHyon Kim     void	*pSenseBuffer,
4135*9e86db79SHyon Kim     HBA_UINT32	*pSenseBufferSize)
4136*9e86db79SHyon Kim {
4137*9e86db79SHyon Kim 	HBA_STATUS		status;
4138*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
4139*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
4140*9e86db79SHyon Kim 	SMHBAScsiInquiryFunc ScsiInquiryFunc;
4141*9e86db79SHyon Kim 
4142*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_ScsiInquiry to hba port: %s discoveredPortWWN: %s",
4143*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0);
4144*9e86db79SHyon Kim 
4145*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4146*9e86db79SHyon Kim 
4147*9e86db79SHyon Kim 	ScsiInquiryFunc =
4148*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.ScsiInquiryHandler;
4149*9e86db79SHyon Kim 	if (ScsiInquiryFunc != NULL) {
4150*9e86db79SHyon Kim 	status = ((ScsiInquiryFunc)(
4151*9e86db79SHyon Kim 	    vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN,
4152*9e86db79SHyon Kim 	    smhbaLUN, CDB_Byte1, CDB_Byte2, pRspBuffer, pRspBufferSize,
4153*9e86db79SHyon Kim 	    pScsiStatus, pSenseBuffer, pSenseBufferSize));
4154*9e86db79SHyon Kim 	} else {
4155*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4156*9e86db79SHyon Kim 	}
4157*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4158*9e86db79SHyon Kim }
4159*9e86db79SHyon Kim 
4160*9e86db79SHyon Kim HBA_STATUS
4161*9e86db79SHyon Kim SMHBA_ScsiReportLUNs(
4162*9e86db79SHyon Kim     HBA_HANDLE	handle,
4163*9e86db79SHyon Kim     HBA_WWN	hbaPortWWN,
4164*9e86db79SHyon Kim     HBA_WWN	discoveredPortWWN,
4165*9e86db79SHyon Kim     HBA_WWN	domainPortWWN,
4166*9e86db79SHyon Kim     void	*pRspBuffer,
4167*9e86db79SHyon Kim     HBA_UINT32	*pRspBufferSize,
4168*9e86db79SHyon Kim     HBA_UINT8	*pScsiStatus,
4169*9e86db79SHyon Kim     void	*pSenseBuffer,
4170*9e86db79SHyon Kim     HBA_UINT32	*pSenseBufferSize)
4171*9e86db79SHyon Kim {
4172*9e86db79SHyon Kim 	HBA_STATUS		status;
4173*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
4174*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
4175*9e86db79SHyon Kim 	SMHBAScsiReportLUNsFunc ScsiReportLUNsFunc;
4176*9e86db79SHyon Kim 
4177*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_ScsiReportLuns to hba port: %s discoveredPortWWN: %s",
4178*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0);
4179*9e86db79SHyon Kim 
4180*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4181*9e86db79SHyon Kim 
4182*9e86db79SHyon Kim 	ScsiReportLUNsFunc =
4183*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.ScsiReportLUNsHandler;
4184*9e86db79SHyon Kim 	if (ScsiReportLUNsFunc != NULL) {
4185*9e86db79SHyon Kim 	status = ((ScsiReportLUNsFunc)(
4186*9e86db79SHyon Kim 	    vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN,
4187*9e86db79SHyon Kim 	    pRspBuffer, pRspBufferSize, pScsiStatus, pSenseBuffer,
4188*9e86db79SHyon Kim 	    pSenseBufferSize));
4189*9e86db79SHyon Kim 	} else {
4190*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4191*9e86db79SHyon Kim 	}
4192*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4193*9e86db79SHyon Kim }
4194*9e86db79SHyon Kim 
4195*9e86db79SHyon Kim HBA_STATUS
4196*9e86db79SHyon Kim SMHBA_ScsiReadCapacity(
4197*9e86db79SHyon Kim     HBA_HANDLE	handle,
4198*9e86db79SHyon Kim     HBA_WWN	hbaPortWWN,
4199*9e86db79SHyon Kim     HBA_WWN	discoveredPortWWN,
4200*9e86db79SHyon Kim     HBA_WWN	domainPortWWN,
4201*9e86db79SHyon Kim     SMHBA_SCSILUN	smhbaLUN,
4202*9e86db79SHyon Kim     void	*pRspBuffer,
4203*9e86db79SHyon Kim     HBA_UINT32	*pRspBufferSize,
4204*9e86db79SHyon Kim     HBA_UINT8	*pScsiStatus,
4205*9e86db79SHyon Kim     void	*pSenseBuffer,
4206*9e86db79SHyon Kim     HBA_UINT32	*pSenseBufferSize)
4207*9e86db79SHyon Kim {
4208*9e86db79SHyon Kim 	HBA_STATUS		status;
4209*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
4210*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
4211*9e86db79SHyon Kim 	SMHBAScsiReadCapacityFunc ScsiReadCapacityFunc;
4212*9e86db79SHyon Kim 
4213*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_ScsiReadCapacity to hba port: %s discoveredPortWWN: %s",
4214*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0);
4215*9e86db79SHyon Kim 
4216*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4217*9e86db79SHyon Kim 
4218*9e86db79SHyon Kim 	ScsiReadCapacityFunc =
4219*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.ScsiReadCapacityHandler;
4220*9e86db79SHyon Kim 	if (ScsiReadCapacityFunc != NULL) {
4221*9e86db79SHyon Kim 	status = ((ScsiReadCapacityFunc)(
4222*9e86db79SHyon Kim 	    vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN,
4223*9e86db79SHyon Kim 	    smhbaLUN, pRspBuffer, pRspBufferSize, pScsiStatus, pSenseBuffer,
4224*9e86db79SHyon Kim 	    pSenseBufferSize));
4225*9e86db79SHyon Kim 	} else {
4226*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4227*9e86db79SHyon Kim 	}
4228*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4229*9e86db79SHyon Kim }
4230*9e86db79SHyon Kim 
4231*9e86db79SHyon Kim HBA_STATUS
4232*9e86db79SHyon Kim SMHBA_SendTEST(
4233*9e86db79SHyon Kim     HBA_HANDLE		handle,
4234*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
4235*9e86db79SHyon Kim     HBA_WWN		destWWN,
4236*9e86db79SHyon Kim     HBA_UINT32		destFCID,
4237*9e86db79SHyon Kim     void		*pRspBuffer,
4238*9e86db79SHyon Kim     HBA_UINT32		pRspBufferSize)
4239*9e86db79SHyon Kim {
4240*9e86db79SHyon Kim 	HBA_STATUS		status;
4241*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
4242*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
4243*9e86db79SHyon Kim 	SMHBASendTESTFunc	SendTESTFunc;
4244*9e86db79SHyon Kim 
4245*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_SendTEST, hbaPortWWN: %s destWWN",
4246*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN),
4247*9e86db79SHyon Kim 	    WWN2STR1(&destWWN), 0);
4248*9e86db79SHyon Kim 
4249*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4250*9e86db79SHyon Kim 
4251*9e86db79SHyon Kim 	SendTESTFunc = lib_infop->ftable.smhbafunctionTable.SendTESTHandler;
4252*9e86db79SHyon Kim 	if (SendTESTFunc != NULL) {
4253*9e86db79SHyon Kim 	status = (SendTESTFunc)
4254*9e86db79SHyon Kim 	    (vendorHandle, hbaPortWWN, destWWN, destFCID,
4255*9e86db79SHyon Kim 	    pRspBuffer, pRspBufferSize);
4256*9e86db79SHyon Kim 	} else {
4257*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4258*9e86db79SHyon Kim 	}
4259*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4260*9e86db79SHyon Kim }
4261*9e86db79SHyon Kim 
4262*9e86db79SHyon Kim HBA_STATUS
4263*9e86db79SHyon Kim SMHBA_SendECHO(
4264*9e86db79SHyon Kim     HBA_HANDLE		handle,
4265*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
4266*9e86db79SHyon Kim     HBA_WWN		destWWN,
4267*9e86db79SHyon Kim     HBA_UINT32		destFCID,
4268*9e86db79SHyon Kim     void		*pReqBuffer,
4269*9e86db79SHyon Kim     HBA_UINT32		ReqBufferSize,
4270*9e86db79SHyon Kim     void		*pRspBuffer,
4271*9e86db79SHyon Kim     HBA_UINT32		*pRspBufferSize)
4272*9e86db79SHyon Kim {
4273*9e86db79SHyon Kim 	HBA_STATUS		status;
4274*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
4275*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
4276*9e86db79SHyon Kim 	SMHBASendECHOFunc	SendECHOFunc;
4277*9e86db79SHyon Kim 
4278*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_SendECHO, hbaPortWWN: %s destWWN",
4279*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), WWN2STR1(&destWWN), 0);
4280*9e86db79SHyon Kim 
4281*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4282*9e86db79SHyon Kim 
4283*9e86db79SHyon Kim 	SendECHOFunc = lib_infop->ftable.smhbafunctionTable.SendECHOHandler;
4284*9e86db79SHyon Kim 	if (SendECHOFunc != NULL) {
4285*9e86db79SHyon Kim 	status = (SendECHOFunc)
4286*9e86db79SHyon Kim 	    (vendorHandle, hbaPortWWN, destWWN, destFCID,
4287*9e86db79SHyon Kim 	    pReqBuffer, ReqBufferSize, pRspBuffer, pRspBufferSize);
4288*9e86db79SHyon Kim 	} else {
4289*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4290*9e86db79SHyon Kim 	}
4291*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4292*9e86db79SHyon Kim }
4293*9e86db79SHyon Kim 
4294*9e86db79SHyon Kim HBA_STATUS
4295*9e86db79SHyon Kim SMHBA_SendSMPPassThru(
4296*9e86db79SHyon Kim     HBA_HANDLE		handle,
4297*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
4298*9e86db79SHyon Kim     HBA_WWN		destWWN,
4299*9e86db79SHyon Kim     HBA_WWN		domainPortWWN,
4300*9e86db79SHyon Kim     void		*pReqBuffer,
4301*9e86db79SHyon Kim     HBA_UINT32		ReqBufferSize,
4302*9e86db79SHyon Kim     void		*pRspBuffer,
4303*9e86db79SHyon Kim     HBA_UINT32		*pRspBufferSize)
4304*9e86db79SHyon Kim {
4305*9e86db79SHyon Kim 	HBA_STATUS		status;
4306*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
4307*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
4308*9e86db79SHyon Kim 	SMHBASendSMPPassThruFunc	SendSMPPassThruFunc;
4309*9e86db79SHyon Kim 
4310*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_SendSMPPassThru, hbaPortWWN: %s destWWN: %s",
4311*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), WWN2STR1(&destWWN), 0);
4312*9e86db79SHyon Kim 
4313*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4314*9e86db79SHyon Kim 
4315*9e86db79SHyon Kim 	SendSMPPassThruFunc = lib_infop->ftable.\
4316*9e86db79SHyon Kim 	    smhbafunctionTable.SendSMPPassThruHandler;
4317*9e86db79SHyon Kim 
4318*9e86db79SHyon Kim 	if (SendSMPPassThruFunc != NULL) {
4319*9e86db79SHyon Kim 	status = (SendSMPPassThruFunc)
4320*9e86db79SHyon Kim 	    (vendorHandle, hbaPortWWN, destWWN, domainPortWWN,
4321*9e86db79SHyon Kim 	    pReqBuffer, ReqBufferSize, pRspBuffer, pRspBufferSize);
4322*9e86db79SHyon Kim 	} else {
4323*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4324*9e86db79SHyon Kim 	}
4325*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4326*9e86db79SHyon Kim }
4327*9e86db79SHyon Kim 
4328*9e86db79SHyon Kim /*
4329*9e86db79SHyon Kim  * Following the similar logic of HBAAPI addaspterevents_callback.
4330*9e86db79SHyon Kim  *
4331*9e86db79SHyon Kim  * Unlike other events Adapter Add Event is not limited to a specific
4332*9e86db79SHyon Kim  * adpater(i.e. no adatper handle is passed for registration) so
4333*9e86db79SHyon Kim  * the event should be passed to all registrants.  The routine below
4334*9e86db79SHyon Kim  * is passed to the VSLs as a callback and when Adapter Add event is detected
4335*9e86db79SHyon Kim  * by VSL it will call smhba_adapteraddevents_callback() which in turn check
4336*9e86db79SHyon Kim  * if the passed userdata ptr matches with the one stored in the callback list
4337*9e86db79SHyon Kim  * and calls the stored callback.
4338*9e86db79SHyon Kim  *
4339*9e86db79SHyon Kim  * For the situation that multiple clients are registered for Adapter Add event
4340*9e86db79SHyon Kim  * each registration is passed to VSLs so VSL may call
4341*9e86db79SHyon Kim  * smhba_adapteraddevents_callback() multiple times or it may call only once
4342*9e86db79SHyon Kim  * since the callback function is same.  For this implemneation, the userdata
4343*9e86db79SHyon Kim  * is stored in HBA_ALLADAPTERSCALLBACK_ELEM so it is expected that VSL call
4344*9e86db79SHyon Kim  * smhba_adapteraddevents_callback() only once and
4345*9e86db79SHyon Kim  * smhba_adapteraddevents_callback() will call the client callback with proper
4346*9e86db79SHyon Kim  * userdata.
4347*9e86db79SHyon Kim  */
4348*9e86db79SHyon Kim static void
4349*9e86db79SHyon Kim smhba_adapteraddevents_callback(
4350*9e86db79SHyon Kim /* LINTED E_FUNC_ARG_UNUSED */
4351*9e86db79SHyon Kim     void *data,
4352*9e86db79SHyon Kim     HBA_WWN PortWWN,
4353*9e86db79SHyon Kim /* LINTED E_FUNC_ARG_UNUSED */
4354*9e86db79SHyon Kim     HBA_UINT32 eventType)
4355*9e86db79SHyon Kim {
4356*9e86db79SHyon Kim 	HBA_ALLADAPTERSCALLBACK_ELEM	*cbp;
4357*9e86db79SHyon Kim 
4358*9e86db79SHyon Kim 	DEBUG(3, "AddAdapterEvent, port:%s", WWN2STR1(&PortWWN), 0, 0);
4359*9e86db79SHyon Kim 
4360*9e86db79SHyon Kim 	GRAB_MUTEX(&_smhba_AAE_mutex);
4361*9e86db79SHyon Kim 	for (cbp = _smhba_adapteraddevents_callback_list;
4362*9e86db79SHyon Kim 	    cbp != NULL;
4363*9e86db79SHyon Kim 	    cbp = cbp->next) {
4364*9e86db79SHyon Kim 	(*cbp->callback)(cbp->userdata, PortWWN, HBA_EVENT_ADAPTER_ADD);
4365*9e86db79SHyon Kim 	}
4366*9e86db79SHyon Kim 	RELEASE_MUTEX(&_smhba_AAE_mutex);
4367*9e86db79SHyon Kim 
4368*9e86db79SHyon Kim }
4369*9e86db79SHyon Kim 
4370*9e86db79SHyon Kim HBA_STATUS
4371*9e86db79SHyon Kim SMHBA_RegisterForAdapterAddEvents(
4372*9e86db79SHyon Kim     void		(*pCallback) (
4373*9e86db79SHyon Kim 	void		*data,
4374*9e86db79SHyon Kim 	HBA_WWN		PortWWN,
4375*9e86db79SHyon Kim 	HBA_UINT32	eventType),
4376*9e86db79SHyon Kim     void		*pUserData,
4377*9e86db79SHyon Kim     HBA_CALLBACKHANDLE  *pCallbackHandle) {
4378*9e86db79SHyon Kim 
4379*9e86db79SHyon Kim     HBA_ALLADAPTERSCALLBACK_ELEM	*cbp;
4380*9e86db79SHyon Kim     HBA_VENDORCALLBACK_ELEM		*vcbp;
4381*9e86db79SHyon Kim     HBA_VENDORCALLBACK_ELEM		*vendorhandlelist;
4382*9e86db79SHyon Kim     SMHBARegisterForAdapterAddEventsFunc	registeredfunc;
4383*9e86db79SHyon Kim     HBA_STATUS				status = HBA_STATUS_OK;
4384*9e86db79SHyon Kim     HBA_STATUS				failure = HBA_STATUS_OK;
4385*9e86db79SHyon Kim     HBA_LIBRARY_INFO			*lib_infop;
4386*9e86db79SHyon Kim     int					registered_cnt = 0;
4387*9e86db79SHyon Kim     int					vendor_cnt = 0;
4388*9e86db79SHyon Kim     int					not_supported_cnt = 0;
4389*9e86db79SHyon Kim     int					status_OK_bar_cnt = 0;
4390*9e86db79SHyon Kim     int					status_OK_cnt = 0;
4391*9e86db79SHyon Kim 
4392*9e86db79SHyon Kim     DEBUG(2, "SMHBA_RegisterForAdapterAddEvents", 0, 0, 0);
4393*9e86db79SHyon Kim     ARE_WE_INITED();
4394*9e86db79SHyon Kim 
4395*9e86db79SHyon Kim     cbp = (HBA_ALLADAPTERSCALLBACK_ELEM *)
4396*9e86db79SHyon Kim 	    calloc(1, sizeof (HBA_ALLADAPTERSCALLBACK_ELEM));
4397*9e86db79SHyon Kim 	*pCallbackHandle = (HBA_CALLBACKHANDLE) cbp;
4398*9e86db79SHyon Kim     if (cbp == NULL) {
4399*9e86db79SHyon Kim 	return (HBA_STATUS_ERROR);
4400*9e86db79SHyon Kim 	}
4401*9e86db79SHyon Kim 
4402*9e86db79SHyon Kim     GRAB_MUTEX(&_hbaapi_LL_mutex);
4403*9e86db79SHyon Kim     GRAB_MUTEX(&_smhba_AAE_mutex);
4404*9e86db79SHyon Kim     cbp->callback = pCallback;
4405*9e86db79SHyon Kim     cbp->userdata = pUserData;
4406*9e86db79SHyon Kim     cbp->next = _smhba_adapteraddevents_callback_list;
4407*9e86db79SHyon Kim     _smhba_adapteraddevents_callback_list = cbp;
4408*9e86db79SHyon Kim 
4409*9e86db79SHyon Kim 	/*
4410*9e86db79SHyon Kim 	 * Need to release the mutex now incase the vendor function invokes the
4411*9e86db79SHyon Kim 	 * callback.  We will grap the mutex later to attach the vendor handle
4412*9e86db79SHyon Kim 	 * list to the callback structure
4413*9e86db79SHyon Kim 	 */
4414*9e86db79SHyon Kim 	RELEASE_MUTEX(&_smhba_AAE_mutex);
4415*9e86db79SHyon Kim 
4416*9e86db79SHyon Kim 
4417*9e86db79SHyon Kim 	/*
4418*9e86db79SHyon Kim 	 * now create a list of vendors (vendor libraryies, NOT ADAPTERS)
4419*9e86db79SHyon Kim 	 * that have successfully registerred
4420*9e86db79SHyon Kim 	 */
4421*9e86db79SHyon Kim     vendorhandlelist = NULL;
4422*9e86db79SHyon Kim     for (lib_infop = _hbaapi_librarylist;
4423*9e86db79SHyon Kim 	lib_infop != NULL;
4424*9e86db79SHyon Kim 	lib_infop = lib_infop->next) {
4425*9e86db79SHyon Kim 
4426*9e86db79SHyon Kim 	/* only for HBAAPI V2 */
4427*9e86db79SHyon Kim 	if (lib_infop->version != SMHBA) {
4428*9e86db79SHyon Kim 	    continue;
4429*9e86db79SHyon Kim 	} else {
4430*9e86db79SHyon Kim 	    vendor_cnt++;
4431*9e86db79SHyon Kim 	}
4432*9e86db79SHyon Kim 
4433*9e86db79SHyon Kim 	registeredfunc =
4434*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.\
4435*9e86db79SHyon Kim 	    RegisterForAdapterAddEventsHandler;
4436*9e86db79SHyon Kim 	if (registeredfunc == NULL) {
4437*9e86db79SHyon Kim 	    continue;
4438*9e86db79SHyon Kim 	}
4439*9e86db79SHyon Kim 
4440*9e86db79SHyon Kim 	vcbp = (HBA_VENDORCALLBACK_ELEM *)
4441*9e86db79SHyon Kim 	    calloc(1, sizeof (HBA_VENDORCALLBACK_ELEM));
4442*9e86db79SHyon Kim 	if (vcbp == NULL) {
4443*9e86db79SHyon Kim 	    freevendorhandlelist(vendorhandlelist);
4444*9e86db79SHyon Kim 	    status = HBA_STATUS_ERROR;
4445*9e86db79SHyon Kim 	    break;
4446*9e86db79SHyon Kim 	}
4447*9e86db79SHyon Kim 
4448*9e86db79SHyon Kim 	registered_cnt++;
4449*9e86db79SHyon Kim 	status = (registeredfunc)(smhba_adapteraddevents_callback,
4450*9e86db79SHyon Kim 	    pUserData, &vcbp->vendorcbhandle);
4451*9e86db79SHyon Kim 	if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
4452*9e86db79SHyon Kim 	    not_supported_cnt++;
4453*9e86db79SHyon Kim 	    free(vcbp);
4454*9e86db79SHyon Kim 	    continue;
4455*9e86db79SHyon Kim 	} else if (status != HBA_STATUS_OK) {
4456*9e86db79SHyon Kim 	    status_OK_bar_cnt++;
4457*9e86db79SHyon Kim 	    DEBUG(1,
4458*9e86db79SHyon Kim 		    "SMHBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
4459*9e86db79SHyon Kim 		    lib_infop->LibraryPath, status, 0);
4460*9e86db79SHyon Kim 	    failure = status;
4461*9e86db79SHyon Kim 	    free(vcbp);
4462*9e86db79SHyon Kim 	    continue;
4463*9e86db79SHyon Kim 	} else {
4464*9e86db79SHyon Kim 	    status_OK_cnt++;
4465*9e86db79SHyon Kim 	}
4466*9e86db79SHyon Kim 	vcbp->lib_info = lib_infop;
4467*9e86db79SHyon Kim 	vcbp->next = vendorhandlelist;
4468*9e86db79SHyon Kim 	vendorhandlelist = vcbp;
4469*9e86db79SHyon Kim 	}
4470*9e86db79SHyon Kim 
4471*9e86db79SHyon Kim     if (vendor_cnt == 0) {
4472*9e86db79SHyon Kim 	/* no SMHBA VSL found.  Should be okay?? */
4473*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR;
4474*9e86db79SHyon Kim 	} else if (registered_cnt == 0) {
4475*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4476*9e86db79SHyon Kim 	freevendorhandlelist(vendorhandlelist);
4477*9e86db79SHyon Kim 	(void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
4478*9e86db79SHyon Kim 	} else if (status_OK_cnt == 0 && not_supported_cnt != 0) {
4479*9e86db79SHyon Kim 	status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4480*9e86db79SHyon Kim 	} else if (status_OK_cnt == 0) {
4481*9e86db79SHyon Kim 	/*
4482*9e86db79SHyon Kim 	 * At least one vendor library registered this function, but no
4483*9e86db79SHyon Kim 	 * vendor call succeeded
4484*9e86db79SHyon Kim 	 */
4485*9e86db79SHyon Kim 	(void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
4486*9e86db79SHyon Kim 	status = failure;
4487*9e86db79SHyon Kim 	} else {
4488*9e86db79SHyon Kim 	/* we have had atleast some success, now finish up */
4489*9e86db79SHyon Kim 	GRAB_MUTEX(&_smhba_AAE_mutex);
4490*9e86db79SHyon Kim 	/*
4491*9e86db79SHyon Kim 	 * this seems silly, but what if another thread called
4492*9e86db79SHyon Kim 	 * the callback remove
4493*9e86db79SHyon Kim 	 */
4494*9e86db79SHyon Kim 	for (cbp = _smhba_adapteraddevents_callback_list;
4495*9e86db79SHyon Kim 	    cbp != NULL; cbp = cbp->next) {
4496*9e86db79SHyon Kim 	    if ((HBA_CALLBACKHANDLE)cbp == *pCallbackHandle) {
4497*9e86db79SHyon Kim 		/* yup, its still there, hooray */
4498*9e86db79SHyon Kim 		cbp->vendorhandlelist = vendorhandlelist;
4499*9e86db79SHyon Kim 		vendorhandlelist = NULL;
4500*9e86db79SHyon Kim 		break;
4501*9e86db79SHyon Kim 	    }
4502*9e86db79SHyon Kim 	}
4503*9e86db79SHyon Kim 	RELEASE_MUTEX(&_smhba_AAE_mutex);
4504*9e86db79SHyon Kim 	if (vendorhandlelist != NULL) {
4505*9e86db79SHyon Kim 		/*
4506*9e86db79SHyon Kim 		 * bummer, somebody removed the callback before we finished
4507*9e86db79SHyon Kim 		 * registration, probably will never happen
4508*9e86db79SHyon Kim 		 */
4509*9e86db79SHyon Kim 	    freevendorhandlelist(vendorhandlelist);
4510*9e86db79SHyon Kim 	    DEBUG(1,
4511*9e86db79SHyon Kim 		    "HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was "
4512*9e86db79SHyon Kim 		    "called for a handle before registration was finished.",
4513*9e86db79SHyon Kim 		    0, 0, 0);
4514*9e86db79SHyon Kim 	    status = HBA_STATUS_ERROR;
4515*9e86db79SHyon Kim 	} else {
4516*9e86db79SHyon Kim 	    status = HBA_STATUS_OK;
4517*9e86db79SHyon Kim 	}
4518*9e86db79SHyon Kim 	}
4519*9e86db79SHyon Kim     RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4520*9e86db79SHyon Kim }
4521*9e86db79SHyon Kim 
4522*9e86db79SHyon Kim /* SMHBA Adapter Events (other than add) ******************************** */
4523*9e86db79SHyon Kim static void
4524*9e86db79SHyon Kim smhba_adapterevents_callback(void *data,
4525*9e86db79SHyon Kim 			HBA_WWN PortWWN,
4526*9e86db79SHyon Kim 			HBA_UINT32 eventType)
4527*9e86db79SHyon Kim {
4528*9e86db79SHyon Kim 	HBA_ADAPTERCALLBACK_ELEM	*acbp;
4529*9e86db79SHyon Kim 
4530*9e86db79SHyon Kim 	DEBUG(3, "AdapterEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN),
4531*9e86db79SHyon Kim 	    eventType, 0);
4532*9e86db79SHyon Kim 
4533*9e86db79SHyon Kim 	GRAB_MUTEX(&_hbaapi_AE_mutex);
4534*9e86db79SHyon Kim 	for (acbp = _smhba_adapterevents_callback_list;
4535*9e86db79SHyon Kim 	    acbp != NULL;
4536*9e86db79SHyon Kim 	    acbp = acbp->next) {
4537*9e86db79SHyon Kim 	if (data == (void *)acbp) {
4538*9e86db79SHyon Kim 		(*acbp->callback)(acbp->userdata, PortWWN, eventType);
4539*9e86db79SHyon Kim 		break;
4540*9e86db79SHyon Kim 	}
4541*9e86db79SHyon Kim 	}
4542*9e86db79SHyon Kim 	RELEASE_MUTEX(&_hbaapi_AE_mutex);
4543*9e86db79SHyon Kim }
4544*9e86db79SHyon Kim 
4545*9e86db79SHyon Kim HBA_STATUS
4546*9e86db79SHyon Kim SMHBA_RegisterForAdapterEvents(
4547*9e86db79SHyon Kim     void		(*pCallback) (
4548*9e86db79SHyon Kim 	void		*data,
4549*9e86db79SHyon Kim 	HBA_WWN		PortWWN,
4550*9e86db79SHyon Kim 	HBA_UINT32	eventType),
4551*9e86db79SHyon Kim     void		*pUserData,
4552*9e86db79SHyon Kim     HBA_HANDLE		handle,
4553*9e86db79SHyon Kim     HBA_CALLBACKHANDLE	*pCallbackHandle) {
4554*9e86db79SHyon Kim 
4555*9e86db79SHyon Kim 	HBA_ADAPTERCALLBACK_ELEM		*acbp;
4556*9e86db79SHyon Kim 	SMHBARegisterForAdapterEventsFunc	registeredfunc;
4557*9e86db79SHyon Kim 	HBA_STATUS				status;
4558*9e86db79SHyon Kim 	HBA_LIBRARY_INFO			*lib_infop;
4559*9e86db79SHyon Kim 	HBA_HANDLE				vendorHandle;
4560*9e86db79SHyon Kim 
4561*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_RegisterForAdapterEvents", 0, 0, 0);
4562*9e86db79SHyon Kim 
4563*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4564*9e86db79SHyon Kim 
4565*9e86db79SHyon Kim 	/* we now have the _hbaapi_LL_mutex */
4566*9e86db79SHyon Kim 
4567*9e86db79SHyon Kim 	registeredfunc = lib_infop->ftable.smhbafunctionTable.\
4568*9e86db79SHyon Kim 	    RegisterForAdapterEventsHandler;
4569*9e86db79SHyon Kim     if (registeredfunc == NULL) {
4570*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
4571*9e86db79SHyon Kim 	}
4572*9e86db79SHyon Kim 
4573*9e86db79SHyon Kim 	/*
4574*9e86db79SHyon Kim 	 * that allocated memory is used both as the handle for the
4575*9e86db79SHyon Kim 	 * caller, and as userdata to the vendor call so that on
4576*9e86db79SHyon Kim 	 * callback the specific registration may be recalled
4577*9e86db79SHyon Kim 	 */
4578*9e86db79SHyon Kim 	acbp = (HBA_ADAPTERCALLBACK_ELEM *)
4579*9e86db79SHyon Kim 	    calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
4580*9e86db79SHyon Kim 	if (acbp == NULL) {
4581*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
4582*9e86db79SHyon Kim 	}
4583*9e86db79SHyon Kim 	*pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
4584*9e86db79SHyon Kim 	acbp->callback = pCallback;
4585*9e86db79SHyon Kim 	acbp->userdata = pUserData;
4586*9e86db79SHyon Kim 	acbp->lib_info = lib_infop;
4587*9e86db79SHyon Kim 
4588*9e86db79SHyon Kim 	status = (registeredfunc)(smhba_adapterevents_callback,
4589*9e86db79SHyon Kim 	    (void *)acbp,
4590*9e86db79SHyon Kim 	    vendorHandle,
4591*9e86db79SHyon Kim 	    &acbp->vendorcbhandle);
4592*9e86db79SHyon Kim     if (status != HBA_STATUS_OK) {
4593*9e86db79SHyon Kim 	free(acbp);
4594*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4595*9e86db79SHyon Kim 	}
4596*9e86db79SHyon Kim 
4597*9e86db79SHyon Kim 	GRAB_MUTEX(&_smhba_AE_mutex);
4598*9e86db79SHyon Kim 	acbp->next = _smhba_adapterevents_callback_list;
4599*9e86db79SHyon Kim 	    _hbaapi_adapterevents_callback_list = acbp;
4600*9e86db79SHyon Kim 
4601*9e86db79SHyon Kim 	RELEASE_MUTEX(&_smhba_AE_mutex);
4602*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
4603*9e86db79SHyon Kim }
4604*9e86db79SHyon Kim 
4605*9e86db79SHyon Kim /* Adapter Port Events *********************************************** */
4606*9e86db79SHyon Kim static void
4607*9e86db79SHyon Kim smhba_adapterportevents_callback(void *data,
4608*9e86db79SHyon Kim 			    HBA_WWN PortWWN,
4609*9e86db79SHyon Kim 			    HBA_UINT32 eventType,
4610*9e86db79SHyon Kim 			    HBA_UINT32 fabricPortID)
4611*9e86db79SHyon Kim {
4612*9e86db79SHyon Kim 	HBA_ADAPTERCALLBACK_ELEM	*acbp;
4613*9e86db79SHyon Kim 
4614*9e86db79SHyon Kim 	DEBUG(3,
4615*9e86db79SHyon Kim 	    "SMHBA_AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x",
4616*9e86db79SHyon Kim 	    WWN2STR1(&PortWWN), eventType, fabricPortID);
4617*9e86db79SHyon Kim 
4618*9e86db79SHyon Kim 	GRAB_MUTEX(&_smhba_APE_mutex);
4619*9e86db79SHyon Kim 
4620*9e86db79SHyon Kim 	for (acbp = _smhba_adapterportevents_callback_list;
4621*9e86db79SHyon Kim 	    acbp != NULL;
4622*9e86db79SHyon Kim 	    acbp = acbp->next) {
4623*9e86db79SHyon Kim 	if (data == (void *)acbp) {
4624*9e86db79SHyon Kim 		(*acbp->callback)(acbp->userdata, PortWWN,
4625*9e86db79SHyon Kim 		    eventType, fabricPortID);
4626*9e86db79SHyon Kim 		break;
4627*9e86db79SHyon Kim 	}
4628*9e86db79SHyon Kim 	}
4629*9e86db79SHyon Kim 	RELEASE_MUTEX(&_smhba_APE_mutex);
4630*9e86db79SHyon Kim }
4631*9e86db79SHyon Kim 
4632*9e86db79SHyon Kim HBA_STATUS
4633*9e86db79SHyon Kim SMHBA_RegisterForAdapterPortEvents(
4634*9e86db79SHyon Kim     void		(*pCallback) (
4635*9e86db79SHyon Kim 	void		*pData,
4636*9e86db79SHyon Kim 	HBA_WWN		PortWWN,
4637*9e86db79SHyon Kim 	HBA_UINT32	eventType,
4638*9e86db79SHyon Kim 	HBA_UINT32	fabricPortID),
4639*9e86db79SHyon Kim     void		*pUserData,
4640*9e86db79SHyon Kim     HBA_HANDLE		handle,
4641*9e86db79SHyon Kim     HBA_WWN		portWWN,
4642*9e86db79SHyon Kim     HBA_UINT32		specificEventType,
4643*9e86db79SHyon Kim     HBA_CALLBACKHANDLE	*pCallbackHandle) {
4644*9e86db79SHyon Kim 
4645*9e86db79SHyon Kim 	HBA_ADAPTERCALLBACK_ELEM		*acbp;
4646*9e86db79SHyon Kim 	SMHBARegisterForAdapterPortEventsFunc	registeredfunc;
4647*9e86db79SHyon Kim 	HBA_STATUS				status;
4648*9e86db79SHyon Kim 	HBA_LIBRARY_INFO			*lib_infop;
4649*9e86db79SHyon Kim 	HBA_HANDLE				vendorHandle;
4650*9e86db79SHyon Kim 
4651*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_RegisterForAdapterPortEvents for port: %s",
4652*9e86db79SHyon Kim 	    WWN2STR1(&portWWN), 0, 0);
4653*9e86db79SHyon Kim 
4654*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4655*9e86db79SHyon Kim 	/* we now have the _hbaapi_LL_mutex */
4656*9e86db79SHyon Kim 
4657*9e86db79SHyon Kim 	registeredfunc =
4658*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.\
4659*9e86db79SHyon Kim 	    RegisterForAdapterPortEventsHandler;
4660*9e86db79SHyon Kim 	if (registeredfunc == NULL) {
4661*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
4662*9e86db79SHyon Kim 	}
4663*9e86db79SHyon Kim 
4664*9e86db79SHyon Kim 	/*
4665*9e86db79SHyon Kim 	 * that allocated memory is used both as the handle for the
4666*9e86db79SHyon Kim 	 * caller, and as userdata to the vendor call so that on
4667*9e86db79SHyon Kim 	 * callback the specific registration may be recalled
4668*9e86db79SHyon Kim 	 */
4669*9e86db79SHyon Kim 	acbp = (HBA_ADAPTERCALLBACK_ELEM *)
4670*9e86db79SHyon Kim 	    calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
4671*9e86db79SHyon Kim 	if (acbp == NULL) {
4672*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
4673*9e86db79SHyon Kim 	}
4674*9e86db79SHyon Kim 	*pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
4675*9e86db79SHyon Kim 	acbp->callback = pCallback;
4676*9e86db79SHyon Kim 	acbp->userdata = pUserData;
4677*9e86db79SHyon Kim 	acbp->lib_info = lib_infop;
4678*9e86db79SHyon Kim 
4679*9e86db79SHyon Kim 	status = (registeredfunc)(smhba_adapterportevents_callback,
4680*9e86db79SHyon Kim 	    (void *)acbp,
4681*9e86db79SHyon Kim 	    vendorHandle,
4682*9e86db79SHyon Kim 	    portWWN,
4683*9e86db79SHyon Kim 	    specificEventType,
4684*9e86db79SHyon Kim 	    &acbp->vendorcbhandle);
4685*9e86db79SHyon Kim 	if (status != HBA_STATUS_OK) {
4686*9e86db79SHyon Kim 	free(acbp);
4687*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4688*9e86db79SHyon Kim 	}
4689*9e86db79SHyon Kim 
4690*9e86db79SHyon Kim 	GRAB_MUTEX(&_smhba_APE_mutex);
4691*9e86db79SHyon Kim 	acbp->next = _smhba_adapterportevents_callback_list;
4692*9e86db79SHyon Kim 	_smhba_adapterportevents_callback_list = acbp;
4693*9e86db79SHyon Kim 
4694*9e86db79SHyon Kim 	RELEASE_MUTEX(&_smhba_APE_mutex);
4695*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
4696*9e86db79SHyon Kim }
4697*9e86db79SHyon Kim 
4698*9e86db79SHyon Kim /* SMHBA Adapter Port Stat Events ******************************** */
4699*9e86db79SHyon Kim static void
4700*9e86db79SHyon Kim smhba_adapterportstatevents_callback(void *data,
4701*9e86db79SHyon Kim 				HBA_WWN portWWN,
4702*9e86db79SHyon Kim 				HBA_UINT32 protocolType,
4703*9e86db79SHyon Kim 				HBA_UINT32 eventType)
4704*9e86db79SHyon Kim {
4705*9e86db79SHyon Kim 	HBA_ADAPTERCALLBACK_ELEM	*acbp;
4706*9e86db79SHyon Kim 
4707*9e86db79SHyon Kim 	DEBUG(3,
4708*9e86db79SHyon Kim 	    "SMBA_AdapterPortStateEvent, port:%s, eventType:%d",
4709*9e86db79SHyon Kim 	    WWN2STR1(&portWWN), eventType, 0);
4710*9e86db79SHyon Kim 
4711*9e86db79SHyon Kim 	GRAB_MUTEX(&_smhba_APSE_mutex);
4712*9e86db79SHyon Kim 	for (acbp = _smhba_adapterportstatevents_callback_list;
4713*9e86db79SHyon Kim 	    acbp != NULL;
4714*9e86db79SHyon Kim 	    acbp = acbp->next) {
4715*9e86db79SHyon Kim 	if (data == (void *)acbp) {
4716*9e86db79SHyon Kim 		(*acbp->callback)(acbp->userdata, portWWN,
4717*9e86db79SHyon Kim 		    protocolType, eventType);
4718*9e86db79SHyon Kim 		return;
4719*9e86db79SHyon Kim 	}
4720*9e86db79SHyon Kim 	}
4721*9e86db79SHyon Kim 	RELEASE_MUTEX(&_smhba_APSE_mutex);
4722*9e86db79SHyon Kim }
4723*9e86db79SHyon Kim 
4724*9e86db79SHyon Kim HBA_STATUS
4725*9e86db79SHyon Kim SMHBA_RegisterForAdapterPortStatEvents(
4726*9e86db79SHyon Kim     void		(*pCallback) (
4727*9e86db79SHyon Kim 	void		*pData,
4728*9e86db79SHyon Kim 	HBA_WWN		portWWN,
4729*9e86db79SHyon Kim 	HBA_UINT32	protocolType,
4730*9e86db79SHyon Kim 	HBA_UINT32	eventType),
4731*9e86db79SHyon Kim     void		*pUserData,
4732*9e86db79SHyon Kim     HBA_HANDLE		handle,
4733*9e86db79SHyon Kim     HBA_WWN		portWWN,
4734*9e86db79SHyon Kim     HBA_UINT32		protocolType,
4735*9e86db79SHyon Kim     SMHBA_PROTOCOLSTATISTICS	stats,
4736*9e86db79SHyon Kim     HBA_UINT32		statType,
4737*9e86db79SHyon Kim     HBA_CALLBACKHANDLE	*pCallbackHandle) {
4738*9e86db79SHyon Kim 
4739*9e86db79SHyon Kim 	HBA_ADAPTERCALLBACK_ELEM	*acbp;
4740*9e86db79SHyon Kim 	SMHBARegisterForAdapterPortStatEventsFunc
4741*9e86db79SHyon Kim 	    registeredfunc;
4742*9e86db79SHyon Kim 	HBA_STATUS			status;
4743*9e86db79SHyon Kim 	HBA_LIBRARY_INFO		*lib_infop;
4744*9e86db79SHyon Kim 	HBA_HANDLE			vendorHandle;
4745*9e86db79SHyon Kim 
4746*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_RegisterForAdapterPortStatEvents for port: %s",
4747*9e86db79SHyon Kim 	    WWN2STR1(&portWWN), 0, 0);
4748*9e86db79SHyon Kim 
4749*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4750*9e86db79SHyon Kim 	/* we now have the _hbaapi_LL_mutex */
4751*9e86db79SHyon Kim 
4752*9e86db79SHyon Kim 	registeredfunc =
4753*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.\
4754*9e86db79SHyon Kim 	    RegisterForAdapterPortStatEventsHandler;
4755*9e86db79SHyon Kim 	if (registeredfunc == NULL) {
4756*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
4757*9e86db79SHyon Kim 	}
4758*9e86db79SHyon Kim 
4759*9e86db79SHyon Kim 	/*
4760*9e86db79SHyon Kim 	 * that allocated memory is used both as the handle for the
4761*9e86db79SHyon Kim 	 * caller, and as userdata to the vendor call so that on
4762*9e86db79SHyon Kim 	 * callback the specific registration may be recalled
4763*9e86db79SHyon Kim 	 */
4764*9e86db79SHyon Kim 	acbp = (HBA_ADAPTERCALLBACK_ELEM *)
4765*9e86db79SHyon Kim 	    calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
4766*9e86db79SHyon Kim 	if (acbp == NULL) {
4767*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
4768*9e86db79SHyon Kim 	}
4769*9e86db79SHyon Kim 	*pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
4770*9e86db79SHyon Kim 	acbp->callback = pCallback;
4771*9e86db79SHyon Kim 	acbp->userdata = pUserData;
4772*9e86db79SHyon Kim 	acbp->lib_info = lib_infop;
4773*9e86db79SHyon Kim 
4774*9e86db79SHyon Kim 	status = (registeredfunc)(smhba_adapterportstatevents_callback,
4775*9e86db79SHyon Kim 	    (void *)acbp,
4776*9e86db79SHyon Kim 	    vendorHandle,
4777*9e86db79SHyon Kim 	    portWWN,
4778*9e86db79SHyon Kim 	    protocolType,
4779*9e86db79SHyon Kim 	    stats,
4780*9e86db79SHyon Kim 	    statType,
4781*9e86db79SHyon Kim 	    &acbp->vendorcbhandle);
4782*9e86db79SHyon Kim 	if (status != HBA_STATUS_OK) {
4783*9e86db79SHyon Kim 	free(acbp);
4784*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4785*9e86db79SHyon Kim 	}
4786*9e86db79SHyon Kim 
4787*9e86db79SHyon Kim 	GRAB_MUTEX(&_smhba_APSE_mutex);
4788*9e86db79SHyon Kim 	acbp->next = _smhba_adapterportstatevents_callback_list;
4789*9e86db79SHyon Kim 	_smhba_adapterportstatevents_callback_list = acbp;
4790*9e86db79SHyon Kim 
4791*9e86db79SHyon Kim 	RELEASE_MUTEX(&_smhba_APSE_mutex);
4792*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
4793*9e86db79SHyon Kim }
4794*9e86db79SHyon Kim 
4795*9e86db79SHyon Kim /* SMHBA Adapter Port Phy Stat Events ************************************ */
4796*9e86db79SHyon Kim static void
4797*9e86db79SHyon Kim smhba_adapterphystatevents_callback(void *data,
4798*9e86db79SHyon Kim 				HBA_WWN portWWN,
4799*9e86db79SHyon Kim 				HBA_UINT32 phyIndex,
4800*9e86db79SHyon Kim 				HBA_UINT32 eventType)
4801*9e86db79SHyon Kim {
4802*9e86db79SHyon Kim 	HBA_ADAPTERCALLBACK_ELEM	*acbp;
4803*9e86db79SHyon Kim 
4804*9e86db79SHyon Kim 	DEBUG(3,
4805*9e86db79SHyon Kim 	    "SMBA_AdapterPortStateEvent, port:%s, eventType:%d",
4806*9e86db79SHyon Kim 	    WWN2STR1(&portWWN), eventType, 0);
4807*9e86db79SHyon Kim 
4808*9e86db79SHyon Kim 	GRAB_MUTEX(&_smhba_APHYSE_mutex);
4809*9e86db79SHyon Kim 	for (acbp = _smhba_adapterphystatevents_callback_list;
4810*9e86db79SHyon Kim 	    acbp != NULL;
4811*9e86db79SHyon Kim 	    acbp = acbp->next) {
4812*9e86db79SHyon Kim 	if (data == (void *)acbp) {
4813*9e86db79SHyon Kim 		(*acbp->callback)(acbp->userdata, portWWN, phyIndex, eventType);
4814*9e86db79SHyon Kim 		return;
4815*9e86db79SHyon Kim 	}
4816*9e86db79SHyon Kim 	}
4817*9e86db79SHyon Kim 	RELEASE_MUTEX(&_smhba_APHYSE_mutex);
4818*9e86db79SHyon Kim }
4819*9e86db79SHyon Kim 
4820*9e86db79SHyon Kim HBA_STATUS
4821*9e86db79SHyon Kim SMHBA_RegisterForAdapterPhyStatEvents(
4822*9e86db79SHyon Kim     void		(*pCallback) (
4823*9e86db79SHyon Kim 	void		*pData,
4824*9e86db79SHyon Kim 	HBA_WWN		portWWN,
4825*9e86db79SHyon Kim 	HBA_UINT32	phyIndex,
4826*9e86db79SHyon Kim 	HBA_UINT32	eventType),
4827*9e86db79SHyon Kim     void		*pUserData,
4828*9e86db79SHyon Kim     HBA_HANDLE		handle,
4829*9e86db79SHyon Kim     HBA_WWN		portWWN,
4830*9e86db79SHyon Kim     HBA_UINT32		phyIndex,
4831*9e86db79SHyon Kim     SMHBA_PHYSTATISTICS	stats,
4832*9e86db79SHyon Kim     HBA_UINT32		statType,
4833*9e86db79SHyon Kim     HBA_CALLBACKHANDLE	*pCallbackHandle) {
4834*9e86db79SHyon Kim 
4835*9e86db79SHyon Kim 	HBA_ADAPTERCALLBACK_ELEM	*acbp;
4836*9e86db79SHyon Kim 	SMHBARegisterForAdapterPhyStatEventsFunc
4837*9e86db79SHyon Kim 	    registeredfunc;
4838*9e86db79SHyon Kim 	HBA_STATUS			status;
4839*9e86db79SHyon Kim 	HBA_LIBRARY_INFO		*lib_infop;
4840*9e86db79SHyon Kim 	HBA_HANDLE			vendorHandle;
4841*9e86db79SHyon Kim 
4842*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_RegisterForAdapterPhyStatEvents for port: %s",
4843*9e86db79SHyon Kim 	    WWN2STR1(&portWWN), 0, 0);
4844*9e86db79SHyon Kim 
4845*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4846*9e86db79SHyon Kim 	/* we now have the _hbaapi_LL_mutex */
4847*9e86db79SHyon Kim 
4848*9e86db79SHyon Kim 	registeredfunc =
4849*9e86db79SHyon Kim 	    lib_infop->ftable.smhbafunctionTable.\
4850*9e86db79SHyon Kim 	    RegisterForAdapterPhyStatEventsHandler;
4851*9e86db79SHyon Kim 	if (registeredfunc == NULL) {
4852*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
4853*9e86db79SHyon Kim 	}
4854*9e86db79SHyon Kim 
4855*9e86db79SHyon Kim 	/*
4856*9e86db79SHyon Kim 	 * that allocated memory is used both as the handle for the
4857*9e86db79SHyon Kim 	 * caller, and as userdata to the vendor call so that on
4858*9e86db79SHyon Kim 	 * callback the specific registration may be recalled
4859*9e86db79SHyon Kim 	 */
4860*9e86db79SHyon Kim 	acbp = (HBA_ADAPTERCALLBACK_ELEM *)
4861*9e86db79SHyon Kim 	    calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
4862*9e86db79SHyon Kim 	if (acbp == NULL) {
4863*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
4864*9e86db79SHyon Kim 	}
4865*9e86db79SHyon Kim 	*pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
4866*9e86db79SHyon Kim 	acbp->callback = pCallback;
4867*9e86db79SHyon Kim 	acbp->userdata = pUserData;
4868*9e86db79SHyon Kim 	acbp->lib_info = lib_infop;
4869*9e86db79SHyon Kim 
4870*9e86db79SHyon Kim 	status = (registeredfunc)(smhba_adapterphystatevents_callback,
4871*9e86db79SHyon Kim 	    (void *)acbp,
4872*9e86db79SHyon Kim 	    vendorHandle,
4873*9e86db79SHyon Kim 	    portWWN,
4874*9e86db79SHyon Kim 	    phyIndex,
4875*9e86db79SHyon Kim 	    stats,
4876*9e86db79SHyon Kim 	    statType,
4877*9e86db79SHyon Kim 	    &acbp->vendorcbhandle);
4878*9e86db79SHyon Kim 	if (status != HBA_STATUS_OK) {
4879*9e86db79SHyon Kim 	free(acbp);
4880*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4881*9e86db79SHyon Kim 	}
4882*9e86db79SHyon Kim 
4883*9e86db79SHyon Kim 	GRAB_MUTEX(&_smhba_APHYSE_mutex);
4884*9e86db79SHyon Kim 	acbp->next = _smhba_adapterphystatevents_callback_list;
4885*9e86db79SHyon Kim 	_smhba_adapterphystatevents_callback_list = acbp;
4886*9e86db79SHyon Kim 
4887*9e86db79SHyon Kim 	RELEASE_MUTEX(&_smhba_APHYSE_mutex);
4888*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
4889*9e86db79SHyon Kim }
4890*9e86db79SHyon Kim 
4891*9e86db79SHyon Kim /* SMHBA Target Events ********************************************* */
4892*9e86db79SHyon Kim static void
4893*9e86db79SHyon Kim smhba_targetevents_callback(void *data,
4894*9e86db79SHyon Kim 	HBA_WWN hbaPortWWN,
4895*9e86db79SHyon Kim 	HBA_WWN discoveredPortWWN,
4896*9e86db79SHyon Kim 	HBA_WWN domainPortWWN,
4897*9e86db79SHyon Kim 	HBA_UINT32 eventType)
4898*9e86db79SHyon Kim {
4899*9e86db79SHyon Kim 	HBA_ADAPTERCALLBACK_ELEM	*acbp;
4900*9e86db79SHyon Kim 
4901*9e86db79SHyon Kim 	DEBUG(3, "TargetEvent, hbaPort:%s, discoveredPort:%s eventType:%d",
4902*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), eventType);
4903*9e86db79SHyon Kim 
4904*9e86db79SHyon Kim 	GRAB_MUTEX(&_smhba_TE_mutex);
4905*9e86db79SHyon Kim 	for (acbp = _smhba_targetevents_callback_list;
4906*9e86db79SHyon Kim 	    acbp != NULL;
4907*9e86db79SHyon Kim 	    acbp = acbp->next) {
4908*9e86db79SHyon Kim 	if (data == (void *)acbp) {
4909*9e86db79SHyon Kim 		(*acbp->callback)(acbp->userdata, hbaPortWWN,
4910*9e86db79SHyon Kim 		    discoveredPortWWN, domainPortWWN, eventType);
4911*9e86db79SHyon Kim 		break;
4912*9e86db79SHyon Kim 	}
4913*9e86db79SHyon Kim 	}
4914*9e86db79SHyon Kim 	RELEASE_MUTEX(&_smhba_TE_mutex);
4915*9e86db79SHyon Kim }
4916*9e86db79SHyon Kim 
4917*9e86db79SHyon Kim HBA_STATUS
4918*9e86db79SHyon Kim SMHBA_RegisterForTargetEvents(
4919*9e86db79SHyon Kim     void		(*pCallback) (
4920*9e86db79SHyon Kim 	void		*pData,
4921*9e86db79SHyon Kim 	HBA_WWN		hbaPortWWN,
4922*9e86db79SHyon Kim 	HBA_WWN		discoveredPortWWN,
4923*9e86db79SHyon Kim 	HBA_WWN		domainPortWWN,
4924*9e86db79SHyon Kim 	HBA_UINT32	eventType),
4925*9e86db79SHyon Kim     void		*pUserData,
4926*9e86db79SHyon Kim     HBA_HANDLE		handle,
4927*9e86db79SHyon Kim     HBA_WWN		hbaPortWWN,
4928*9e86db79SHyon Kim     HBA_WWN		discoveredPortWWN,
4929*9e86db79SHyon Kim     HBA_WWN		domainPortWWN,
4930*9e86db79SHyon Kim     HBA_CALLBACKHANDLE	*pCallbackHandle,
4931*9e86db79SHyon Kim     HBA_UINT32		allTargets) {
4932*9e86db79SHyon Kim 
4933*9e86db79SHyon Kim 	HBA_ADAPTERCALLBACK_ELEM *acbp;
4934*9e86db79SHyon Kim 	SMHBARegisterForTargetEventsFunc
4935*9e86db79SHyon Kim 	    registeredfunc;
4936*9e86db79SHyon Kim 	HBA_STATUS		status;
4937*9e86db79SHyon Kim 	HBA_LIBRARY_INFO	*lib_infop;
4938*9e86db79SHyon Kim 	HBA_HANDLE		vendorHandle;
4939*9e86db79SHyon Kim 
4940*9e86db79SHyon Kim 	DEBUG(2, "SMHBA_RegisterForTargetEvents, hbaPort:"
4941*9e86db79SHyon Kim 	    "%s, discoveredPort: %s",
4942*9e86db79SHyon Kim 	    WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), 0);
4943*9e86db79SHyon Kim 
4944*9e86db79SHyon Kim 	CHECKLIBRARYANDVERSION(SMHBA);
4945*9e86db79SHyon Kim 	/* we now have the _hbaapi_LL_mutex */
4946*9e86db79SHyon Kim 
4947*9e86db79SHyon Kim 	registeredfunc = lib_infop->ftable.smhbafunctionTable.\
4948*9e86db79SHyon Kim 	    RegisterForTargetEventsHandler;
4949*9e86db79SHyon Kim 
4950*9e86db79SHyon Kim 	if (registeredfunc == NULL) {
4951*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
4952*9e86db79SHyon Kim 	}
4953*9e86db79SHyon Kim 
4954*9e86db79SHyon Kim 	/*
4955*9e86db79SHyon Kim 	 * that allocated memory is used both as the handle for the
4956*9e86db79SHyon Kim 	 * caller, and as userdata to the vendor call so that on
4957*9e86db79SHyon Kim 	 * callback the specific registration may be recalled
4958*9e86db79SHyon Kim 	 */
4959*9e86db79SHyon Kim 	acbp = (HBA_ADAPTERCALLBACK_ELEM *)
4960*9e86db79SHyon Kim 	    calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
4961*9e86db79SHyon Kim 	if (acbp == NULL) {
4962*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
4963*9e86db79SHyon Kim 	}
4964*9e86db79SHyon Kim 	*pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
4965*9e86db79SHyon Kim 	acbp->callback = pCallback;
4966*9e86db79SHyon Kim 	acbp->userdata = pUserData;
4967*9e86db79SHyon Kim 	acbp->lib_info = lib_infop;
4968*9e86db79SHyon Kim 
4969*9e86db79SHyon Kim 	status = (registeredfunc)(smhba_targetevents_callback,
4970*9e86db79SHyon Kim 	    (void *)acbp,
4971*9e86db79SHyon Kim 	    vendorHandle,
4972*9e86db79SHyon Kim 	    hbaPortWWN,
4973*9e86db79SHyon Kim 	    discoveredPortWWN,
4974*9e86db79SHyon Kim 	    domainPortWWN,
4975*9e86db79SHyon Kim 	    &acbp->vendorcbhandle,
4976*9e86db79SHyon Kim 	    allTargets);
4977*9e86db79SHyon Kim 	if (status != HBA_STATUS_OK) {
4978*9e86db79SHyon Kim 	free(acbp);
4979*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4980*9e86db79SHyon Kim 	}
4981*9e86db79SHyon Kim 
4982*9e86db79SHyon Kim 	GRAB_MUTEX(&_smhba_TE_mutex);
4983*9e86db79SHyon Kim 	acbp->next = _smhba_targetevents_callback_list;
4984*9e86db79SHyon Kim 	_smhba_targetevents_callback_list = acbp;
4985*9e86db79SHyon Kim 
4986*9e86db79SHyon Kim 	RELEASE_MUTEX(&_smhba_TE_mutex);
4987*9e86db79SHyon Kim 	RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
4988*9e86db79SHyon Kim }
4989