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