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
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
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
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
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
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 */
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
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
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 fclose(hbaconf);
1089 #endif /* WIN32 or UNIX */
1090 #ifdef POSIX_THREADS
1091 /*
1092 * The _hbaapi_LL_mutex is already grabbed to proctect the caller of
1093 * HBA_FreeLibrary() during loading.
1094 * The mutexes are already initialized
1095 * with PTHREAD_MUTEX_INITIALIZER. Do we need to init again?
1096 * Keeping the code from HBAAPI source...
1097 */
1098 ret = pthread_mutex_init(&_hbaapi_AL_mutex, NULL);
1099 if (ret == 0) {
1100 ret = pthread_mutex_init(&_hbaapi_AAE_mutex, NULL);
1101 }
1102 if (ret == 0) {
1103 ret = pthread_mutex_init(&_hbaapi_AE_mutex, NULL);
1104 }
1105 if (ret == 0) {
1106 ret = pthread_mutex_init(&_hbaapi_APE_mutex, NULL);
1107 }
1108 if (ret == 0) {
1109 ret = pthread_mutex_init(&_hbaapi_APSE_mutex, NULL);
1110 }
1111 if (ret == 0) {
1112 ret = pthread_mutex_init(&_hbaapi_TE_mutex, NULL);
1113 }
1114 if (ret == 0) {
1115 ret = pthread_mutex_init(&_smhba_AAE_mutex, NULL);
1116 }
1117 if (ret == 0) {
1118 ret = pthread_mutex_init(&_smhba_AE_mutex, NULL);
1119 }
1120 if (ret == 0) {
1121 ret = pthread_mutex_init(&_smhba_APE_mutex, NULL);
1122 }
1123 if (ret == 0) {
1124 ret = pthread_mutex_init(&_smhba_APSE_mutex, NULL);
1125 }
1126 if (ret == 0) {
1127 ret = pthread_mutex_init(&_smhba_TE_mutex, NULL);
1128 }
1129 if (ret == 0) {
1130 ret = pthread_mutex_init(&_hbaapi_LE_mutex, NULL);
1131 }
1132 if (ret != 0) {
1133 perror("pthread_mutex_init - HBA_LoadLibrary");
1134 RELEASE_MUTEX(&_hbaapi_LL_mutex);
1135 return (HBA_STATUS_ERROR);
1136 }
1137 RELEASE_MUTEX(&_hbaapi_LL_mutex);
1138 #elif defined(WIN32)
1139 InitializeCriticalSection(&_hbaapi_LL_mutex);
1140 InitializeCriticalSection(&_hbaapi_AL_mutex);
1141 InitializeCriticalSection(&_hbaapi_AAE_mutex);
1142 InitializeCriticalSection(&_hbaapi_AE_mutex);
1143 InitializeCriticalSection(&_hbaapi_APE_mutex);
1144 InitializeCriticalSection(&_hbaapi_APSE_mutex);
1145 InitializeCriticalSection(&_hbaapi_TE_mutex);
1146 InitializeCriticalSection(&_hbaapi_LE_mutex);
1147 InitializeCriticalSection(&_smhba_AAE_mutex);
1148 InitializeCriticalSection(&_smhba_AE_mutex);
1149 InitializeCriticalSection(&_smhba_APE_mutex);
1150 InitializeCriticalSection(&_smhba_APSE_mutex);
1151 InitializeCriticalSection(&_smhba_TE_mutex);
1152 #endif
1153
1154 return (HBA_STATUS_OK);
1155 }
1156
1157 HBA_STATUS
1158 HBA_FreeLibrary() {
1159 HBAFreeLibraryFunc FreeLibraryFunc;
1160 /* LINTED E_FUNC_SET_NOT_USED */
1161 HBA_STATUS status __unused;
1162 HBA_LIBRARY_INFO *lib_infop;
1163 HBA_LIBRARY_INFO *lib_next;
1164 HBA_ADAPTERCALLBACK_ELEM
1165 ***listp;
1166 HBA_ADAPTER_INFO *adapt_infop;
1167 HBA_ADAPTER_INFO *adapt_next;
1168
1169 GRAB_MUTEX(&_hbaapi_LL_mutex);
1170 if (_hbaapi_librarylist == NULL) {
1171 RELEASE_MUTEX(&_hbaapi_LL_mutex);
1172 return (HBA_STATUS_ERROR_NOT_LOADED);
1173 }
1174
1175 GRAB_MUTEX(&_hbaapi_AL_mutex);
1176
1177 DEBUG(1, "HBA_FreeLibrary()", 0, 0, 0);
1178 for (lib_infop = _hbaapi_librarylist; lib_infop != NULL;
1179 lib_infop = lib_next) {
1180 lib_next = lib_infop->next;
1181 if (lib_infop->status == HBA_LIBRARY_LOADED) {
1182 FreeLibraryFunc = FUNCCOMMON(lib_infop, FreeLibraryHandler);
1183 if (FreeLibraryFunc != NULL) {
1184 /* Free this library */
1185 status = ((FreeLibraryFunc)());
1186 DEBUG(1, "HBA_FreeLibrary() Failed %d", status, 0, 0);
1187 }
1188 #ifdef WIN32
1189 FreeLibrary(lib_infop->hLibrary); /* Unload DLL from memory */
1190 #else
1191 (void) dlclose(lib_infop->hLibrary); /* Unload DLL from memory */
1192 #endif
1193 }
1194 #ifndef WIN32
1195 free(lib_infop->LibraryName);
1196 #endif
1197 free(lib_infop->LibraryPath);
1198 free(lib_infop);
1199
1200 }
1201 _hbaapi_librarylist = NULL;
1202 /*
1203 * OK, now all functions are disabled except for LoadLibrary,
1204 * Hope no other thread calls it before we have returned
1205 */
1206 _hbaapi_total_library_count = 0;
1207
1208 for (adapt_infop = _hbaapi_adapterlist;
1209 adapt_infop != NULL;
1210 adapt_infop = adapt_next) {
1211 adapt_next = adapt_infop->next;
1212 free(adapt_infop->name);
1213 free(adapt_infop);
1214 }
1215 _hbaapi_adapterlist = NULL;
1216 _hbaapi_total_adapter_count = 0;
1217
1218 /*
1219 * Free up the callbacks, this is not the most efficient, but it works
1220 */
1221 while ((volatile HBA_ADAPTERCALLBACK_ELEM *)
1222 _hbaapi_adapteraddevents_callback_list
1223 != NULL) {
1224 (void) local_remove_callback((HBA_CALLBACKHANDLE)
1225 _hbaapi_adapteraddevents_callback_list);
1226 }
1227 while ((volatile HBA_ADAPTERCALLBACK_ELEM *)
1228 _smhba_adapteraddevents_callback_list
1229 != NULL) {
1230 (void) local_remove_callback((HBA_CALLBACKHANDLE)
1231 _smhba_adapteraddevents_callback_list);
1232 }
1233 for (listp = cb_lists_array; *listp != NULL; listp++) {
1234 while ((volatile HBA_ADAPTERCALLBACK_ELEM ***)**listp != NULL) {
1235 (void) local_remove_callback((HBA_CALLBACKHANDLE)**listp);
1236 }
1237 }
1238
1239 RELEASE_MUTEX(&_hbaapi_AL_mutex);
1240 RELEASE_MUTEX(&_hbaapi_LL_mutex);
1241
1242 #ifdef USESYSLOG
1243 closelog();
1244 #endif
1245 #ifdef USELOGFILE
1246 if (_hbaapi_debug_fd != NULL) {
1247 fclose(_hbaapi_debug_fd);
1248 }
1249 _hbaapi_debug_fd = NULL;
1250 #endif
1251 #ifdef POSIX_THREADS
1252 /* this will unlock them as well, but who cares */
1253 (void) pthread_mutex_destroy(&_hbaapi_LE_mutex);
1254 (void) pthread_mutex_destroy(&_hbaapi_TE_mutex);
1255 (void) pthread_mutex_destroy(&_hbaapi_APSE_mutex);
1256 (void) pthread_mutex_destroy(&_hbaapi_APE_mutex);
1257 (void) pthread_mutex_destroy(&_hbaapi_AE_mutex);
1258 (void) pthread_mutex_destroy(&_hbaapi_AAE_mutex);
1259 (void) pthread_mutex_destroy(&_smhba_TE_mutex);
1260 (void) pthread_mutex_destroy(&_smhba_APSE_mutex);
1261 (void) pthread_mutex_destroy(&_smhba_APE_mutex);
1262 (void) pthread_mutex_destroy(&_smhba_AE_mutex);
1263 (void) pthread_mutex_destroy(&_smhba_AAE_mutex);
1264 (void) pthread_mutex_destroy(&_hbaapi_AL_mutex);
1265 (void) pthread_mutex_destroy(&_hbaapi_LL_mutex);
1266 #elif defined(WIN32)
1267 DeleteCriticalSection(&_hbaapi_LL_mutex);
1268 DeleteCriticalSection(&_hbaapi_AL_mutex);
1269 DeleteCriticalSection(&_hbaapi_AAE_mutex);
1270 DeleteCriticalSection(&_hbaapi_AE_mutex);
1271 DeleteCriticalSection(&_hbaapi_APE_mutex);
1272 DeleteCriticalSection(&_hbaapi_APSE_mutex);
1273 DeleteCriticalSection(&_hbaapi_TE_mutex);
1274 DeleteCriticalSection(&_hbaapi_LE_mutex);
1275 DeleteCriticalSection(&_smhba_TE_mutex);
1276 DeleteCriticalSection(&_smhba_APSE_mutex);
1277 DeleteCriticalSection(&_smhba_APE_mutex);
1278 DeleteCriticalSection(&_smhba_AE_mutex);
1279 DeleteCriticalSection(&_smhba_AAE_mutex);
1280 #endif
1281
1282 return (HBA_STATUS_OK);
1283 }
1284
1285 /*
1286 * The API used to use fixed size tables as its primary data structure.
1287 * Indexing from 1 to N identified each adapters. Now the adapters are
1288 * on a linked list. There is a unique "index" foreach each adapter.
1289 * Adapters always keep their index, even if they are removed from the
1290 * hardware. The only time the indexing is reset is on HBA_FreeLibrary
1291 */
1292 HBA_UINT32
1293 HBA_GetNumberOfAdapters()
1294 {
1295 int j = 0;
1296 HBA_LIBRARY_INFO *lib_infop;
1297 HBAGetNumberOfAdaptersFunc GetNumberOfAdaptersFunc;
1298 HBAGetAdapterNameFunc GetAdapterNameFunc;
1299 HBA_BOOLEAN found_name;
1300 HBA_ADAPTER_INFO *adapt_infop;
1301 HBA_STATUS status;
1302
1303 char adaptername[256];
1304 int num_adapters; /* local */
1305
1306 if (_hbaapi_librarylist == NULL) {
1307 return (0);
1308 }
1309 GRAB_MUTEX(&_hbaapi_LL_mutex); /* pay attention to order */
1310 GRAB_MUTEX(&_hbaapi_AL_mutex);
1311
1312 for (lib_infop = _hbaapi_librarylist;
1313 lib_infop != NULL;
1314 lib_infop = lib_infop->next) {
1315
1316 if (lib_infop->status != HBA_LIBRARY_LOADED) {
1317 continue;
1318 }
1319
1320 GetNumberOfAdaptersFunc =
1321 FUNCCOMMON(lib_infop, GetNumberOfAdaptersHandler);
1322 if (GetNumberOfAdaptersFunc == NULL) {
1323 continue;
1324 }
1325 num_adapters = ((GetNumberOfAdaptersFunc)());
1326 #ifndef WIN32
1327 DEBUG(1, "HBAAPI: num_adapters for %s = %d\n",
1328 lib_infop->LibraryName, num_adapters, 0);
1329 #else
1330 DEBUG(1, "HBAAPI: num_adapters for %s = %d\n",
1331 lib_infop->LibraryPath, num_adapters, 0);
1332 #endif
1333
1334 /* Also get the names of all the adapters here and cache */
1335 GetAdapterNameFunc = FUNCCOMMON(lib_infop, GetAdapterNameHandler);
1336 if (GetAdapterNameFunc == NULL) {
1337 continue;
1338 }
1339
1340 for (j = 0; j < num_adapters; j++) {
1341 found_name = 0;
1342 status = (GetAdapterNameFunc)(j, (char *)&adaptername);
1343 if (status == HBA_STATUS_OK) {
1344 for (adapt_infop = _hbaapi_adapterlist;
1345 adapt_infop != NULL;
1346 adapt_infop = adapt_infop->next) {
1347 /*
1348 * check for duplicates, really,
1349 * this may just be a second
1350 * call to this function
1351 * ??? how do we know when a name becomes stale?
1352 */
1353 if (strcmp(adaptername, adapt_infop->name) == 0) {
1354 /* already got this one */
1355 found_name++;
1356 break;
1357 }
1358 }
1359 if (found_name != 0) {
1360 continue;
1361 }
1362 }
1363
1364 adapt_infop = (HBA_ADAPTER_INFO *)
1365 calloc(1, sizeof (HBA_ADAPTER_INFO));
1366 if (adapt_infop == NULL) {
1367 #ifndef WIN32
1368 (void) fprintf(stderr,
1369 "HBA_GetNumberOfAdapters: calloc failed"
1370 " on sizeof:%lu\n",
1371 (unsigned long)(sizeof (HBA_ADAPTER_INFO)));
1372 #endif
1373 RELEASE_MUTEX(&_hbaapi_AL_mutex);
1374 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
1375 _hbaapi_total_adapter_count);
1376 }
1377 if ((adapt_infop->GNstatus = status) == HBA_STATUS_OK) {
1378 adapt_infop->name = strdup(adaptername);
1379 } else {
1380 char dummyname[512];
1381 (void) sprintf(dummyname, "NULLADAPTER-%255s-%03d",
1382 lib_infop->LibraryPath, _hbaapi_total_adapter_count);
1383 dummyname[511] = '\0';
1384 adapt_infop->name = strdup(dummyname);
1385 }
1386 lib_infop->numOfAdapters++;
1387 adapt_infop->library = lib_infop;
1388 adapt_infop->next = _hbaapi_adapterlist;
1389 adapt_infop->index = _hbaapi_total_adapter_count;
1390 _hbaapi_adapterlist = adapt_infop;
1391 _hbaapi_total_adapter_count++;
1392 }
1393 }
1394 RELEASE_MUTEX(&_hbaapi_AL_mutex);
1395 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, _hbaapi_total_adapter_count);
1396 }
1397
1398 HBA_STATUS
1399 HBA_GetAdapterName(
1400 HBA_UINT32 adapterindex,
1401 char *adaptername)
1402 {
1403 HBA_ADAPTER_INFO *adapt_infop;
1404 HBA_STATUS ret = HBA_STATUS_ERROR_ILLEGAL_INDEX;
1405
1406 if (adaptername == NULL) {
1407 DEBUG(1, "HBA_GetAdapterName: NULL pointer adaptername",
1408 0, 0, 0);
1409 return (HBA_STATUS_ERROR_ARG);
1410 }
1411
1412 /*
1413 * The adapter index is from old code, but we have
1414 * to support it. Go down the list looking for
1415 * the adapter
1416 */
1417 ARE_WE_INITED();
1418 GRAB_MUTEX(&_hbaapi_AL_mutex);
1419 *adaptername = '\0';
1420 for (adapt_infop = _hbaapi_adapterlist;
1421 adapt_infop != NULL;
1422 adapt_infop = adapt_infop->next) {
1423
1424 if (adapt_infop->index == adapterindex) {
1425 if (adapt_infop->name != NULL &&
1426 adapt_infop->GNstatus == HBA_STATUS_OK) {
1427 (void) strcpy(adaptername, adapt_infop->name);
1428 } else {
1429 *adaptername = '\0';
1430 }
1431 ret = adapt_infop->GNstatus;
1432 break;
1433 }
1434 }
1435 DEBUG(2, "GetAdapterName for index:%d ->%s",
1436 adapterindex, adaptername, 0);
1437 RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, ret);
1438 }
1439
1440 HBA_HANDLE
1441 HBA_OpenAdapter(char *adaptername)
1442 {
1443 HBA_HANDLE handle;
1444 HBAOpenAdapterFunc OpenAdapterFunc;
1445 HBA_ADAPTER_INFO *adapt_infop;
1446 HBA_LIBRARY_INFO *lib_infop;
1447
1448 DEBUG(2, "OpenAdapter: %s", adaptername, 0, 0);
1449
1450 handle = HBA_HANDLE_INVALID;
1451 if (_hbaapi_librarylist == NULL) {
1452 return (handle);
1453 }
1454 if (adaptername == NULL) {
1455 DEBUG(1, "HBA_OpenAdapter: NULL pointer adaptername",
1456 0, 0, 0);
1457 return (handle);
1458 }
1459 GRAB_MUTEX(&_hbaapi_AL_mutex);
1460 for (adapt_infop = _hbaapi_adapterlist;
1461 adapt_infop != NULL;
1462 adapt_infop = adapt_infop->next) {
1463 if (strcmp(adaptername, adapt_infop->name) != 0) {
1464 continue;
1465 }
1466 lib_infop = adapt_infop->library;
1467 OpenAdapterFunc = FUNCCOMMON(lib_infop, OpenAdapterHandler);
1468
1469 if (OpenAdapterFunc != NULL) {
1470 /* retrieve the vendor handle */
1471 handle = (OpenAdapterFunc)(adaptername);
1472 if (handle != 0) {
1473 /* or this with the library index to get the common handle */
1474 handle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle);
1475 }
1476 }
1477 break;
1478 }
1479 RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, handle);
1480 }
1481
1482 /*
1483 * Finding an adapter with matching WWN.
1484 */
1485 HBA_STATUS
1486 HBA_OpenAdapterByWWN(HBA_HANDLE *phandle, HBA_WWN nodeWWN) {
1487 HBA_HANDLE handle;
1488 HBA_LIBRARY_INFO *lib_infop;
1489 HBAGetNumberOfAdaptersFunc
1490 GetNumberOfAdaptersFunc;
1491 HBAOpenAdapterByWWNFunc
1492 OpenAdapterFunc;
1493 HBA_STATUS status;
1494
1495 DEBUG(2, "OpenAdapterByWWN: %s", WWN2STR1(&nodeWWN), 0, 0);
1496 ARE_WE_INITED();
1497
1498 *phandle = HBA_HANDLE_INVALID;
1499
1500 GRAB_MUTEX(&_hbaapi_LL_mutex);
1501 for (lib_infop = _hbaapi_librarylist;
1502 lib_infop != NULL;
1503 lib_infop = lib_infop->next) {
1504
1505 status = HBA_STATUS_ERROR_ILLEGAL_WWN;
1506
1507 if (lib_infop->status != HBA_LIBRARY_LOADED) {
1508 continue;
1509 }
1510
1511 /* only for HBAAPIV2 */
1512 if (lib_infop->version != HBAAPIV2) {
1513 continue;
1514 }
1515
1516 GetNumberOfAdaptersFunc =
1517 FUNCCOMMON(lib_infop, GetNumberOfAdaptersHandler);
1518 if (GetNumberOfAdaptersFunc == NULL) {
1519 continue;
1520 }
1521
1522 /* look for new hardware */
1523 (void) ((GetNumberOfAdaptersFunc)());
1524
1525 OpenAdapterFunc =
1526 lib_infop->ftable.functionTable.OpenAdapterByWWNHandler;
1527 if (OpenAdapterFunc == NULL) {
1528 continue;
1529 }
1530 /*
1531 * We do not know if the WWN is known by this vendor,
1532 * just try it
1533 */
1534 if ((status = (OpenAdapterFunc)(&handle, nodeWWN)) != HBA_STATUS_OK) {
1535 continue;
1536 }
1537 /* OK, make a vendor non-specific handle */
1538 *phandle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle);
1539 status = HBA_STATUS_OK;
1540 break;
1541 }
1542 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1543 }
1544
1545 void
1546 HBA_RefreshAdapterConfiguration() {
1547 DEBUG(2, "HBA_RefreshAdapterConfiguration", 0, 0, 0);
1548 (void) HBA_GetNumberOfAdapters();
1549 }
1550
1551 HBA_UINT32
1552 HBA_GetVersion() {
1553 DEBUG(2, "HBA_GetVersion", 0, 0, 0);
1554 return (HBA_LIBVERSION);
1555 }
1556
1557 /*
1558 * This function is VERY OS dependent. Wing it as best you can.
1559 */
1560 HBA_UINT32
1561 HBA_GetWrapperLibraryAttributes(
1562 HBA_LIBRARYATTRIBUTES *attributes)
1563 {
1564
1565 DEBUG(2, "HBA_GetWrapperLibraryAttributes", 0, 0, 0);
1566
1567 if (attributes == NULL) {
1568 DEBUG(1, "HBA_GetWrapperLibraryAttributes:"
1569 "NULL pointer attributes",
1570 0, 0, 0);
1571 return (HBA_STATUS_ERROR_ARG);
1572 }
1573
1574 (void) memset(attributes, 0, sizeof (HBA_LIBRARYATTRIBUTES));
1575
1576 #if defined(SOLARIS)
1577 if ((handle = dlopen("libHBAAPI.so", RTLD_NOW)) != NULL) {
1578 if (dlinfo(handle, RTLD_DI_LINKMAP, &map) >= 0) {
1579 for (mp = map; mp != NULL; mp = mp->l_next) {
1580 if (strlen(map->l_name) < 256) {
1581 (void) strcpy(attributes->LibPath, map->l_name);
1582 }
1583 }
1584 }
1585 }
1586 #elif defined(WIN32)
1587 HMODULE module;
1588
1589 /* No need to do anything with the module handle */
1590 /* It wasn't alloocated so it doesn't need to be freed */
1591 module = GetModuleHandle("HBAAPI");
1592 if (module != NULL) {
1593 if (GetModuleFileName(module, attributes->LibPath,
1594 sizeof (attributes->LibPath)) == 0) {
1595 attributes->LibPath[0] = '\0';
1596 }
1597 }
1598 #endif
1599 #if defined(VENDOR)
1600 (void) strcpy(attributes->VName, VENDOR);
1601 #else
1602 attributes->VName[0] = '\0';
1603 #endif
1604 #if defined(VERSION)
1605 (void) strcpy(attributes->VVersion, VERSION);
1606 #else
1607 attributes->VVersion[0] = '\0';
1608 #endif
1609 #if defined(BUILD_DATE)
1610 #if defined(WIN32)
1611 int matchCount;
1612 matchCount = sscanf(BUILD_DATE, "%u/%u/%u %u:%u:%u",
1613 &attributes->build_date.tm_year,
1614 &attributes->build_date.tm_mon,
1615 &attributes->build_date.tm_mday,
1616 &attributes->build_date.tm_hour,
1617 &attributes->build_date.tm_min,
1618 &attributes->build_date.tm_sec);
1619
1620 if (matchCount != 6) {
1621 memset(&attributes->build_date, 0, sizeof (struct tm));
1622 } else {
1623 attributes->build_date.tm_year -= 1900;
1624 attributes->build_date.tm_isdst = -1;
1625 }
1626 #else
1627 if (strptime(BUILD_DATE,
1628 "%Y/%m/%d %T %Z", &(attributes->build_date)) == NULL) {
1629 (void) memset(&attributes->build_date, 0, sizeof (struct tm));
1630 }
1631 #endif
1632 #else
1633 (void) memset(&attributes->build_date, 0, sizeof (struct tm));
1634 #endif
1635 return (2);
1636 }
1637
1638 /*
1639 * Callback registation and handling
1640 */
1641 HBA_STATUS
1642 HBA_RemoveCallback(HBA_CALLBACKHANDLE cbhandle) {
1643 HBA_STATUS status;
1644
1645 DEBUG(2, "HBA_RemoveCallback", 0, 0, 0);
1646 ARE_WE_INITED();
1647
1648 GRAB_MUTEX(&_hbaapi_LL_mutex);
1649 status = local_remove_callback(cbhandle);
1650 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1651 }
1652
1653 /* Adapter Add Events ************************************************* */
1654 static void
1655 /* LINTED E_FUNC_ARG_UNUSED */
1656 adapteraddevents_callback(void *data, HBA_WWN PortWWN, HBA_UINT32 eventType) {
1657 HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
1658
1659 DEBUG(3, "AddAdapterEvent, port: %s", WWN2STR1(&PortWWN), 0, 0);
1660
1661 GRAB_MUTEX(&_hbaapi_AAE_mutex);
1662 for (cbp = _hbaapi_adapteraddevents_callback_list;
1663 cbp != NULL;
1664 cbp = cbp->next) {
1665 (*cbp->callback)(data, PortWWN, HBA_EVENT_ADAPTER_ADD);
1666 }
1667 RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1668
1669 }
1670
1671 HBA_STATUS
1672 HBA_RegisterForAdapterAddEvents(
1673 void (*callback)(
1674 void *data,
1675 HBA_WWN PortWWN,
1676 HBA_UINT32 eventType),
1677 void *userData,
1678 HBA_CALLBACKHANDLE *callbackHandle) {
1679
1680 HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
1681 HBA_VENDORCALLBACK_ELEM *vcbp;
1682 HBA_VENDORCALLBACK_ELEM *vendorhandlelist;
1683 HBARegisterForAdapterAddEventsFunc registeredfunc;
1684 HBA_STATUS status = HBA_STATUS_OK;
1685 HBA_STATUS failure = HBA_STATUS_OK;
1686 HBA_LIBRARY_INFO *lib_infop;
1687 int registered_cnt = 0;
1688 int vendor_cnt = 0;
1689 int not_supported_cnt = 0;
1690 int status_OK_bar_cnt = 0;
1691 int status_OK_cnt = 0;
1692
1693 DEBUG(2, "HBA_RegisterForAdapterAddEvents", 0, 0, 0);
1694 ARE_WE_INITED();
1695
1696 cbp = (HBA_ALLADAPTERSCALLBACK_ELEM *)
1697 calloc(1, sizeof (HBA_ALLADAPTERSCALLBACK_ELEM));
1698 *callbackHandle = (HBA_CALLBACKHANDLE) cbp;
1699 if (cbp == NULL) {
1700 #ifndef WIN32
1701 (void) fprintf(stderr,
1702 "HBA_RegisterForAdapterAddEvents: calloc failed "
1703 "for %lu bytes\n",
1704 (unsigned long)(sizeof (HBA_ALLADAPTERSCALLBACK_ELEM)));
1705 #endif
1706 return (HBA_STATUS_ERROR);
1707 }
1708
1709 GRAB_MUTEX(&_hbaapi_LL_mutex);
1710 GRAB_MUTEX(&_hbaapi_AAE_mutex);
1711 cbp->callback = callback;
1712 cbp->next = _hbaapi_adapteraddevents_callback_list;
1713 _hbaapi_adapteraddevents_callback_list = cbp;
1714 /*
1715 * Need to release the mutex now incase the vendor function invokes the
1716 * callback. We will grap the mutex later to attach the vendor handle
1717 * list to the callback structure
1718 */
1719 RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1720
1721 /*
1722 * now create a list of vendors (vendor libraryies, NOT ADAPTERS)
1723 * that have successfully registerred
1724 */
1725 vendorhandlelist = NULL;
1726 for (lib_infop = _hbaapi_librarylist;
1727 lib_infop != NULL;
1728 lib_infop = lib_infop->next) {
1729
1730 /* only for HBAAPI V2 */
1731 if ((lib_infop->version != HBAAPIV2)) {
1732 continue;
1733 } else {
1734 vendor_cnt++;
1735 }
1736
1737 registeredfunc =
1738 lib_infop->ftable.functionTable.RegisterForAdapterAddEventsHandler;
1739 if (registeredfunc == NULL) {
1740 continue;
1741 }
1742
1743 vcbp = (HBA_VENDORCALLBACK_ELEM *)
1744 calloc(1, sizeof (HBA_VENDORCALLBACK_ELEM));
1745 if (vcbp == NULL) {
1746 #ifndef WIN32
1747 (void) fprintf(stderr,
1748 "HBA_RegisterForAdapterAddEvents: "
1749 "calloc failed for %lu bytes\n",
1750 (unsigned long)(sizeof (HBA_VENDORCALLBACK_ELEM)));
1751 #endif
1752 freevendorhandlelist(vendorhandlelist);
1753 status = HBA_STATUS_ERROR;
1754 break;
1755 }
1756
1757 registered_cnt++;
1758 status = (registeredfunc)(adapteraddevents_callback,
1759 userData, &vcbp->vendorcbhandle);
1760 if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
1761 not_supported_cnt++;
1762 free(vcbp);
1763 continue;
1764 } else if (status != HBA_STATUS_OK) {
1765 status_OK_bar_cnt++;
1766 DEBUG(1,
1767 "HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
1768 lib_infop->LibraryPath, status, 0);
1769 #ifndef WIN32
1770 (void) fprintf(stderr,
1771 "HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
1772 lib_infop->LibraryPath, status);
1773 #endif
1774 failure = status;
1775 free(vcbp);
1776 continue;
1777 } else {
1778 status_OK_cnt++;
1779 }
1780 vcbp->lib_info = lib_infop;
1781 vcbp->next = vendorhandlelist;
1782 vendorhandlelist = vcbp;
1783 }
1784 if (vendor_cnt == 0) {
1785 /* no HBAAPIV2 is deteced. should be okay? */
1786 status = HBA_STATUS_ERROR;
1787 } else if (registered_cnt == 0) {
1788 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1789 freevendorhandlelist(vendorhandlelist);
1790 (void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
1791 } else if (status_OK_cnt == 0 && not_supported_cnt != 0) {
1792 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1793 } else if (status_OK_cnt == 0) {
1794 /*
1795 * At least one vendor library registered this function, but no
1796 * vendor call succeeded
1797 */
1798 (void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
1799 status = failure;
1800 } else {
1801 /* we have had atleast some success, now finish up */
1802 GRAB_MUTEX(&_hbaapi_AAE_mutex);
1803 /*
1804 * this seems silly, but what if another thread called
1805 * the callback remove
1806 */
1807 for (cbp = _hbaapi_adapteraddevents_callback_list;
1808 cbp != NULL; cbp = cbp->next) {
1809 if ((HBA_CALLBACKHANDLE)cbp == *callbackHandle) {
1810 /* yup, its still there, hooray */
1811 cbp->vendorhandlelist = vendorhandlelist;
1812 vendorhandlelist = NULL;
1813 break;
1814 }
1815 }
1816 RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1817 if (vendorhandlelist != NULL) {
1818 /*
1819 * bummer, somebody removed the callback before we finished
1820 * registration, probably will never happen
1821 */
1822 freevendorhandlelist(vendorhandlelist);
1823 DEBUG(1,
1824 "HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was "
1825 "called for a handle before registration was finished.",
1826 0, 0, 0);
1827 status = HBA_STATUS_ERROR;
1828 } else {
1829 status = HBA_STATUS_OK;
1830 }
1831 }
1832 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1833 }
1834
1835 /* Adapter Events (other than add) ************************************** */
1836 static void
1837 adapterevents_callback(void *data,
1838 HBA_WWN PortWWN,
1839 HBA_UINT32 eventType) {
1840 HBA_ADAPTERCALLBACK_ELEM *acbp;
1841
1842 DEBUG(3, "AdapterEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN),
1843 eventType, 0);
1844
1845 GRAB_MUTEX(&_hbaapi_AE_mutex);
1846 for (acbp = _hbaapi_adapterevents_callback_list;
1847 acbp != NULL;
1848 acbp = acbp->next) {
1849 if (data == (void *)acbp) {
1850 (*acbp->callback)(acbp->userdata, PortWWN, eventType);
1851 break;
1852 }
1853 }
1854 RELEASE_MUTEX(&_hbaapi_AE_mutex);
1855 }
1856 HBA_STATUS
1857 HBA_RegisterForAdapterEvents(
1858 void (*callback) (
1859 void *data,
1860 HBA_WWN PortWWN,
1861 HBA_UINT32 eventType),
1862 void *userData,
1863 HBA_HANDLE handle,
1864 HBA_CALLBACKHANDLE *callbackHandle) {
1865
1866 HBA_ADAPTERCALLBACK_ELEM *acbp;
1867 HBARegisterForAdapterEventsFunc registeredfunc;
1868 HBA_STATUS status;
1869 HBA_LIBRARY_INFO *lib_infop;
1870 HBA_HANDLE vendorHandle;
1871
1872 DEBUG(2, "HBA_RegisterForAdapterEvents", 0, 0, 0);
1873
1874 CHECKLIBRARYANDVERSION(HBAAPIV2);
1875
1876 /* we now have the _hbaapi_LL_mutex */
1877
1878 registeredfunc =
1879 lib_infop->ftable.functionTable.RegisterForAdapterEventsHandler;
1880 if (registeredfunc == NULL) {
1881 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1882 }
1883
1884 /*
1885 * that allocated memory is used both as the handle for the
1886 * caller, and as userdata to the vendor call so that on
1887 * callback the specific registration may be recalled
1888 */
1889 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1890 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1891 if (acbp == NULL) {
1892 #ifndef WIN32
1893 (void) fprintf(stderr,
1894 "HBA_RegisterForAdapterEvents: calloc failed for %lu bytes\n",
1895 (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
1896 #endif
1897 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1898 }
1899 *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1900 acbp->callback = callback;
1901 acbp->userdata = userData;
1902 acbp->lib_info = lib_infop;
1903
1904 status = (registeredfunc)(adapterevents_callback,
1905 (void *)acbp,
1906 vendorHandle,
1907 &acbp->vendorcbhandle);
1908 if (status != HBA_STATUS_OK) {
1909 free(acbp);
1910 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1911 }
1912
1913 GRAB_MUTEX(&_hbaapi_AE_mutex);
1914 acbp->next = _hbaapi_adapterevents_callback_list;
1915 _hbaapi_adapterevents_callback_list = acbp;
1916 RELEASE_MUTEX(&_hbaapi_AE_mutex);
1917
1918 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1919 }
1920
1921 /* Adapter Port Events ************************************************** */
1922 static void
1923 adapterportevents_callback(void *data,
1924 HBA_WWN PortWWN,
1925 HBA_UINT32 eventType,
1926 HBA_UINT32 fabricPortID) {
1927 HBA_ADAPTERCALLBACK_ELEM *acbp;
1928
1929 DEBUG(3, "AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x",
1930 WWN2STR1(&PortWWN), eventType, fabricPortID);
1931
1932 GRAB_MUTEX(&_hbaapi_APE_mutex);
1933
1934 for (acbp = _hbaapi_adapterportevents_callback_list;
1935 acbp != NULL;
1936 acbp = acbp->next) {
1937 if (data == (void *)acbp) {
1938 (*acbp->callback)(acbp->userdata, PortWWN, eventType, fabricPortID);
1939 break;
1940 }
1941 }
1942 RELEASE_MUTEX(&_hbaapi_APE_mutex);
1943 }
1944
1945 HBA_STATUS
1946 HBA_RegisterForAdapterPortEvents(
1947 void (*callback) (
1948 void *data,
1949 HBA_WWN PortWWN,
1950 HBA_UINT32 eventType,
1951 HBA_UINT32 fabricPortID),
1952 void *userData,
1953 HBA_HANDLE handle,
1954 HBA_WWN PortWWN,
1955 HBA_CALLBACKHANDLE *callbackHandle) {
1956
1957 HBA_ADAPTERCALLBACK_ELEM *acbp;
1958 HBARegisterForAdapterPortEventsFunc registeredfunc;
1959 HBA_STATUS status;
1960 HBA_LIBRARY_INFO *lib_infop;
1961 HBA_HANDLE vendorHandle;
1962
1963 DEBUG(2, "HBA_RegisterForAdapterPortEvents for port: %s",
1964 WWN2STR1(&PortWWN), 0, 0);
1965
1966 CHECKLIBRARYANDVERSION(HBAAPIV2);
1967 /* we now have the _hbaapi_LL_mutex */
1968
1969 registeredfunc =
1970 lib_infop->ftable.functionTable.RegisterForAdapterPortEventsHandler;
1971 if (registeredfunc == NULL) {
1972 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1973 }
1974
1975 /*
1976 * that allocated memory is used both as the handle for the
1977 * caller, and as userdata to the vendor call so that on
1978 * callback the specific registration may be recalled
1979 */
1980 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1981 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
1982 if (acbp == NULL) {
1983 #ifndef WIN32
1984 (void) fprintf(stderr,
1985 "HBA_RegisterForAdapterPortEvents: "
1986 "calloc failed for %lu bytes\n",
1987 (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
1988 #endif
1989 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1990
1991 }
1992 *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1993 acbp->callback = callback;
1994 acbp->userdata = userData;
1995 acbp->lib_info = lib_infop;
1996
1997 status = (registeredfunc)(adapterportevents_callback,
1998 (void *)acbp,
1999 vendorHandle,
2000 PortWWN,
2001 &acbp->vendorcbhandle);
2002 if (status != HBA_STATUS_OK) {
2003 free(acbp);
2004 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2005 }
2006
2007 GRAB_MUTEX(&_hbaapi_APE_mutex);
2008 acbp->next = _hbaapi_adapterportevents_callback_list;
2009 _hbaapi_adapterportevents_callback_list = acbp;
2010 RELEASE_MUTEX(&_hbaapi_APE_mutex);
2011
2012 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
2013 }
2014
2015 /* Adapter State Events ************************************************ */
2016 static void
2017 adapterportstatevents_callback(void *data,
2018 HBA_WWN PortWWN,
2019 HBA_UINT32 eventType) {
2020 HBA_ADAPTERCALLBACK_ELEM *acbp;
2021
2022 DEBUG(3, "AdapterPortStatEvent, port:%s, eventType:%d",
2023 WWN2STR1(&PortWWN),
2024 eventType, 0);
2025
2026 GRAB_MUTEX(&_hbaapi_APSE_mutex);
2027 for (acbp = _hbaapi_adapterportstatevents_callback_list;
2028 acbp != NULL;
2029 acbp = acbp->next) {
2030 if (data == (void *)acbp) {
2031 (*acbp->callback)(acbp->userdata, PortWWN, eventType);
2032 return;
2033 }
2034 }
2035 RELEASE_MUTEX(&_hbaapi_APSE_mutex);
2036 }
2037 HBA_STATUS
2038 HBA_RegisterForAdapterPortStatEvents(
2039 void (*callback) (
2040 void *data,
2041 HBA_WWN PortWWN,
2042 HBA_UINT32 eventType),
2043 void *userData,
2044 HBA_HANDLE handle,
2045 HBA_WWN PortWWN,
2046 HBA_PORTSTATISTICS stats,
2047 HBA_UINT32 statType,
2048 HBA_CALLBACKHANDLE *callbackHandle) {
2049
2050 HBA_ADAPTERCALLBACK_ELEM *acbp;
2051 HBARegisterForAdapterPortStatEventsFunc
2052 registeredfunc;
2053 HBA_STATUS status;
2054 HBA_LIBRARY_INFO *lib_infop;
2055 HBA_HANDLE vendorHandle;
2056
2057 DEBUG(2, "HBA_RegisterForAdapterPortStatEvents for port: %s",
2058 WWN2STR1(&PortWWN), 0, 0);
2059
2060 CHECKLIBRARYANDVERSION(HBAAPIV2);
2061 /* we now have the _hbaapi_LL_mutex */
2062
2063 registeredfunc =
2064 lib_infop->ftable.functionTable.RegisterForAdapterPortStatEventsHandler;
2065 if (registeredfunc == NULL) {
2066 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
2067 }
2068
2069 /*
2070 * that allocated memory is used both as the handle for the
2071 * caller, and as userdata to the vendor call so that on
2072 * callback the specific registration may be recalled
2073 */
2074 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
2075 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
2076 if (acbp == NULL) {
2077 #ifndef WIN32
2078 (void) fprintf(stderr,
2079 "HBA_RegisterForAdapterPortStatEvents: "
2080 "calloc failed for %lu bytes\n",
2081 (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
2082 #endif
2083 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
2084 }
2085 *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
2086 acbp->callback = callback;
2087 acbp->userdata = userData;
2088 acbp->lib_info = lib_infop;
2089
2090 status = (registeredfunc)(adapterportstatevents_callback,
2091 (void *)acbp,
2092 vendorHandle,
2093 PortWWN,
2094 stats,
2095 statType,
2096 &acbp->vendorcbhandle);
2097 if (status != HBA_STATUS_OK) {
2098 free(acbp);
2099 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2100 }
2101
2102 GRAB_MUTEX(&_hbaapi_APSE_mutex);
2103 acbp->next = _hbaapi_adapterportstatevents_callback_list;
2104 _hbaapi_adapterportstatevents_callback_list = acbp;
2105 RELEASE_MUTEX(&_hbaapi_APSE_mutex);
2106
2107 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
2108 }
2109
2110 /* Target Events ******************************************************* */
2111 static void
2112 targetevents_callback(void *data,
2113 HBA_WWN hbaPortWWN,
2114 HBA_WWN discoveredPortWWN,
2115 HBA_UINT32 eventType) {
2116
2117 HBA_ADAPTERCALLBACK_ELEM *acbp;
2118
2119 DEBUG(3, "TargetEvent, hbaPort:%s, discoveredPort:%s eventType:%d",
2120 WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), eventType);
2121
2122 GRAB_MUTEX(&_hbaapi_TE_mutex);
2123 for (acbp = _hbaapi_targetevents_callback_list;
2124 acbp != NULL;
2125 acbp = acbp->next) {
2126 if (data == (void *)acbp) {
2127 (*acbp->callback)(acbp->userdata, hbaPortWWN,
2128 discoveredPortWWN, eventType);
2129 break;
2130 }
2131 }
2132 RELEASE_MUTEX(&_hbaapi_TE_mutex);
2133 }
2134
2135 HBA_STATUS
2136 HBA_RegisterForTargetEvents(
2137 void (*callback) (
2138 void *data,
2139 HBA_WWN hbaPortWWN,
2140 HBA_WWN discoveredPortWWN,
2141 HBA_UINT32 eventType),
2142 void *userData,
2143 HBA_HANDLE handle,
2144 HBA_WWN hbaPortWWN,
2145 HBA_WWN discoveredPortWWN,
2146 HBA_CALLBACKHANDLE *callbackHandle,
2147 HBA_UINT32 allTargets) {
2148
2149 HBA_ADAPTERCALLBACK_ELEM
2150 *acbp;
2151 HBARegisterForTargetEventsFunc
2152 registeredfunc;
2153 HBA_STATUS status;
2154 HBA_LIBRARY_INFO *lib_infop;
2155 HBA_HANDLE vendorHandle;
2156
2157 DEBUG(2, "HBA_RegisterForTargetEvents, hbaPort: %s, discoveredPort: %s",
2158 WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), 0);
2159
2160 CHECKLIBRARYANDVERSION(HBAAPIV2);
2161 /* we now have the _hbaapi_LL_mutex */
2162
2163 registeredfunc =
2164 lib_infop->ftable.functionTable.RegisterForTargetEventsHandler;
2165 if (registeredfunc == NULL) {
2166 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
2167 }
2168
2169 /*
2170 * that allocated memory is used both as the handle for the
2171 * caller, and as userdata to the vendor call so that on
2172 * callback the specific registration may be recalled
2173 */
2174 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
2175 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
2176 if (acbp == NULL) {
2177 #ifndef WIN32
2178 (void) fprintf(stderr,
2179 "HBA_RegisterForTargetEvents: calloc failed for %lu bytes\n",
2180 (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
2181 #endif
2182 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
2183 }
2184 *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
2185 acbp->callback = callback;
2186 acbp->userdata = userData;
2187 acbp->lib_info = lib_infop;
2188
2189 status = (registeredfunc)(targetevents_callback,
2190 (void *)acbp,
2191 vendorHandle,
2192 hbaPortWWN,
2193 discoveredPortWWN,
2194 &acbp->vendorcbhandle,
2195 allTargets);
2196 if (status != HBA_STATUS_OK) {
2197 free(acbp);
2198 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2199 }
2200
2201 GRAB_MUTEX(&_hbaapi_TE_mutex);
2202 acbp->next = _hbaapi_targetevents_callback_list;
2203 _hbaapi_targetevents_callback_list = acbp;
2204 RELEASE_MUTEX(&_hbaapi_TE_mutex);
2205
2206 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
2207 }
2208
2209 /* Link Events ********************************************************* */
2210 static void
2211 linkevents_callback(void *data,
2212 HBA_WWN adapterWWN,
2213 HBA_UINT32 eventType,
2214 void *pRLIRBuffer,
2215 HBA_UINT32 RLIRBufferSize) {
2216 HBA_ADAPTERCALLBACK_ELEM *acbp;
2217
2218 DEBUG(3, "LinkEvent, hbaWWN:%s, eventType:%d",
2219 WWN2STR1(&adapterWWN), eventType, 0);
2220
2221 GRAB_MUTEX(&_hbaapi_LE_mutex);
2222 for (acbp = _hbaapi_linkevents_callback_list;
2223 acbp != NULL;
2224 acbp = acbp->next) {
2225 if (data == (void *)acbp) {
2226 (*acbp->callback)(acbp->userdata, adapterWWN,
2227 eventType, pRLIRBuffer, RLIRBufferSize);
2228 break;
2229 }
2230 }
2231 RELEASE_MUTEX(&_hbaapi_LE_mutex);
2232 }
2233 HBA_STATUS
2234 HBA_RegisterForLinkEvents(
2235 void (*callback) (
2236 void *data,
2237 HBA_WWN adapterWWN,
2238 HBA_UINT32 eventType,
2239 void *pRLIRBuffer,
2240 HBA_UINT32 RLIRBufferSize),
2241 void *userData,
2242 void *pRLIRBuffer,
2243 HBA_UINT32 RLIRBufferSize,
2244 HBA_HANDLE handle,
2245 HBA_CALLBACKHANDLE *callbackHandle) {
2246
2247 HBA_ADAPTERCALLBACK_ELEM *acbp;
2248 HBARegisterForLinkEventsFunc
2249 registeredfunc;
2250 HBA_STATUS status;
2251 HBA_LIBRARY_INFO *lib_infop;
2252 HBA_HANDLE vendorHandle;
2253
2254 DEBUG(2, "HBA_RegisterForLinkEvents", 0, 0, 0);
2255
2256 CHECKLIBRARY();
2257 /* we now have the _hbaapi_LL_mutex */
2258
2259 registeredfunc = FUNCCOMMON(lib_infop, RegisterForLinkEventsHandler);
2260
2261 if (registeredfunc == NULL) {
2262 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
2263 }
2264
2265 /*
2266 * that allocated memory is used both as the handle for the
2267 * caller, and as userdata to the vendor call so that on
2268 * callback the specific registration may be recalled
2269 */
2270 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
2271 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
2272 if (acbp == NULL) {
2273 #ifndef WIN32
2274 (void) fprintf(stderr,
2275 "HBA_RegisterForLinkEvents: calloc failed for %lu bytes\n",
2276 (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM)));
2277 #endif
2278 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
2279 }
2280 *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
2281 acbp->callback = callback;
2282 acbp->userdata = userData;
2283 acbp->lib_info = lib_infop;
2284
2285 status = (registeredfunc)(linkevents_callback,
2286 (void *)acbp,
2287 pRLIRBuffer,
2288 RLIRBufferSize,
2289 vendorHandle,
2290 &acbp->vendorcbhandle);
2291 if (status != HBA_STATUS_OK) {
2292 free(acbp);
2293 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2294 }
2295
2296 GRAB_MUTEX(&_hbaapi_LE_mutex);
2297 acbp->next = _hbaapi_linkevents_callback_list;
2298 _hbaapi_linkevents_callback_list = acbp;
2299 RELEASE_MUTEX(&_hbaapi_LE_mutex);
2300
2301 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
2302 }
2303
2304 /*
2305 * All of the functions below are almost passthru functions to the
2306 * vendor specific function
2307 */
2308
2309 void
2310 HBA_CloseAdapter(HBA_HANDLE handle) {
2311 HBA_STATUS status;
2312 HBA_LIBRARY_INFO *lib_infop;
2313 HBA_HANDLE vendorHandle;
2314 HBACloseAdapterFunc CloseAdapterFunc;
2315
2316 DEBUG(2, "HBA_CloseAdapter", 0, 0, 0);
2317
2318 status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
2319 if (status == HBA_STATUS_OK) {
2320 CloseAdapterFunc = FUNCCOMMON(lib_infop, CloseAdapterHandler);
2321 if (CloseAdapterFunc != NULL) {
2322 ((CloseAdapterFunc)(vendorHandle));
2323 }
2324 RELEASE_MUTEX(&_hbaapi_LL_mutex);
2325 }
2326 }
2327
2328 HBA_STATUS
2329 HBA_GetAdapterAttributes(
2330 HBA_HANDLE handle,
2331 HBA_ADAPTERATTRIBUTES
2332 *hbaattributes)
2333 {
2334 HBA_STATUS status;
2335 HBA_LIBRARY_INFO *lib_infop;
2336 HBA_HANDLE vendorHandle;
2337 HBAGetAdapterAttributesFunc GetAdapterAttributesFunc;
2338
2339 DEBUG(2, "HBA_GetAdapterAttributes", 0, 0, 0);
2340
2341 CHECKLIBRARY();
2342
2343 if (lib_infop->version == SMHBA) {
2344 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2345 }
2346
2347 GetAdapterAttributesFunc =
2348 lib_infop->ftable.functionTable.GetAdapterAttributesHandler;
2349 if (GetAdapterAttributesFunc != NULL) {
2350 status = ((GetAdapterAttributesFunc)(vendorHandle, hbaattributes));
2351 } else {
2352 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2353 }
2354 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2355 }
2356
2357 HBA_STATUS
2358 HBA_GetAdapterPortAttributes(
2359 HBA_HANDLE handle,
2360 HBA_UINT32 portindex,
2361 HBA_PORTATTRIBUTES *portattributes)
2362 {
2363 HBA_STATUS status;
2364 HBA_LIBRARY_INFO *lib_infop;
2365 HBA_HANDLE vendorHandle;
2366 HBAGetAdapterPortAttributesFunc
2367 GetAdapterPortAttributesFunc;
2368
2369 DEBUG(2, "HBA_GetAdapterPortAttributes", 0, 0, 0);
2370
2371 CHECKLIBRARY();
2372 if (lib_infop->version == SMHBA) {
2373 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2374 }
2375
2376 GetAdapterPortAttributesFunc =
2377 lib_infop->ftable.functionTable.GetAdapterPortAttributesHandler;
2378 if (GetAdapterPortAttributesFunc != NULL) {
2379 status = ((GetAdapterPortAttributesFunc)
2380 (vendorHandle, portindex, portattributes));
2381 } else {
2382 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2383 }
2384 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2385 }
2386
2387 HBA_STATUS
2388 HBA_GetPortStatistics(
2389 HBA_HANDLE handle,
2390 HBA_UINT32 portindex,
2391 HBA_PORTSTATISTICS *portstatistics)
2392 {
2393 HBA_STATUS status;
2394 HBA_LIBRARY_INFO *lib_infop;
2395 HBA_HANDLE vendorHandle;
2396 HBAGetPortStatisticsFunc
2397 GetPortStatisticsFunc;
2398
2399 DEBUG(2, "HBA_GetPortStatistics", 0, 0, 0);
2400
2401 CHECKLIBRARY();
2402 if (lib_infop->version == SMHBA) {
2403 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2404 }
2405
2406 GetPortStatisticsFunc =
2407 lib_infop->ftable.functionTable.GetPortStatisticsHandler;
2408 if (GetPortStatisticsFunc != NULL) {
2409 status = ((GetPortStatisticsFunc)
2410 (vendorHandle, portindex, portstatistics));
2411 } else {
2412 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2413 }
2414 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2415 }
2416
2417 HBA_STATUS
2418 HBA_GetDiscoveredPortAttributes(
2419 HBA_HANDLE handle,
2420 HBA_UINT32 portindex,
2421 HBA_UINT32 discoveredportindex,
2422 HBA_PORTATTRIBUTES *portattributes)
2423 {
2424 HBA_STATUS status;
2425 HBA_LIBRARY_INFO *lib_infop;
2426 HBA_HANDLE vendorHandle;
2427 HBAGetDiscoveredPortAttributesFunc
2428 GetDiscoveredPortAttributesFunc;
2429
2430 DEBUG(2, "HBA_GetDiscoveredPortAttributes", 0, 0, 0);
2431
2432 CHECKLIBRARY();
2433 if (lib_infop->version == SMHBA) {
2434 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2435 }
2436
2437 GetDiscoveredPortAttributesFunc =
2438 lib_infop->ftable.functionTable.GetDiscoveredPortAttributesHandler;
2439 if (GetDiscoveredPortAttributesFunc != NULL) {
2440 status = ((GetDiscoveredPortAttributesFunc)
2441 (vendorHandle, portindex, discoveredportindex,
2442 portattributes));
2443 } else {
2444 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2445 }
2446 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2447 }
2448
2449 HBA_STATUS
2450 HBA_GetPortAttributesByWWN(
2451 HBA_HANDLE handle,
2452 HBA_WWN PortWWN,
2453 HBA_PORTATTRIBUTES *portattributes)
2454 {
2455 HBA_STATUS status;
2456 HBA_LIBRARY_INFO *lib_infop;
2457 HBA_HANDLE vendorHandle;
2458 HBAGetPortAttributesByWWNFunc
2459 GetPortAttributesByWWNFunc;
2460
2461 DEBUG(2, "HBA_GetPortAttributesByWWN: %s", WWN2STR1(&PortWWN), 0, 0);
2462
2463 CHECKLIBRARY();
2464 if (lib_infop->version == SMHBA) {
2465 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2466 }
2467
2468 GetPortAttributesByWWNFunc =
2469 lib_infop->ftable.functionTable.GetPortAttributesByWWNHandler;
2470 if (GetPortAttributesByWWNFunc != NULL) {
2471 status = ((GetPortAttributesByWWNFunc)
2472 (vendorHandle, PortWWN, portattributes));
2473 } else {
2474 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2475 }
2476 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2477 }
2478
2479 HBA_STATUS
2480 HBA_SendCTPassThru(
2481 HBA_HANDLE handle,
2482 void *pReqBuffer,
2483 HBA_UINT32 ReqBufferSize,
2484 void *pRspBuffer,
2485 HBA_UINT32 RspBufferSize)
2486 {
2487 HBA_STATUS status;
2488 HBA_LIBRARY_INFO *lib_infop;
2489 HBA_HANDLE vendorHandle;
2490 HBASendCTPassThruFunc
2491 SendCTPassThruFunc;
2492
2493 DEBUG(2, "HBA_SendCTPassThru", 0, 0, 0);
2494
2495 CHECKLIBRARY();
2496 if (lib_infop->version == SMHBA) {
2497 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2498 }
2499
2500 SendCTPassThruFunc =
2501 lib_infop->ftable.functionTable.SendCTPassThruHandler;
2502 if (SendCTPassThruFunc != NULL) {
2503 status = (SendCTPassThruFunc)
2504 (vendorHandle,
2505 pReqBuffer, ReqBufferSize,
2506 pRspBuffer, RspBufferSize);
2507 } else {
2508 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2509 }
2510 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2511 }
2512
2513 HBA_STATUS
2514 HBA_SendCTPassThruV2(
2515 HBA_HANDLE handle,
2516 HBA_WWN hbaPortWWN,
2517 void *pReqBuffer,
2518 HBA_UINT32 ReqBufferSize,
2519 void *pRspBuffer,
2520 HBA_UINT32 *pRspBufferSize)
2521 {
2522 HBA_STATUS status;
2523 HBA_LIBRARY_INFO *lib_infop;
2524 HBA_HANDLE vendorHandle;
2525 HBASendCTPassThruV2Func
2526 registeredfunc;
2527
2528 DEBUG(2, "HBA_SendCTPassThruV2m hbaPortWWN: %s",
2529 WWN2STR1(&hbaPortWWN), 0, 0);
2530
2531 CHECKLIBRARYANDVERSION(HBAAPIV2);
2532 registeredfunc = FUNCCOMMON(lib_infop, SendCTPassThruV2Handler);
2533 if (registeredfunc != NULL) {
2534 status = (registeredfunc)
2535 (vendorHandle, hbaPortWWN,
2536 pReqBuffer, ReqBufferSize,
2537 pRspBuffer, pRspBufferSize);
2538 } else {
2539 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2540 }
2541 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2542 }
2543
2544 HBA_STATUS
2545 HBA_GetEventBuffer(
2546 HBA_HANDLE handle,
2547 PHBA_EVENTINFO EventBuffer,
2548 HBA_UINT32 *EventBufferCount)
2549 {
2550 HBA_STATUS status;
2551 HBA_LIBRARY_INFO *lib_infop;
2552 HBA_HANDLE vendorHandle;
2553 HBAGetEventBufferFunc
2554 GetEventBufferFunc;
2555
2556 DEBUG(2, "HBA_GetEventBuffer", 0, 0, 0);
2557
2558 CHECKLIBRARY();
2559 if (lib_infop->version == SMHBA) {
2560 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2561 }
2562
2563 GetEventBufferFunc =
2564 lib_infop->ftable.functionTable.GetEventBufferHandler;
2565 if (GetEventBufferFunc != NULL) {
2566 status = (GetEventBufferFunc)
2567 (vendorHandle, EventBuffer, EventBufferCount);
2568 } else {
2569 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2570 }
2571 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2572 }
2573
2574 HBA_STATUS
2575 HBA_SetRNIDMgmtInfo(HBA_HANDLE handle, HBA_MGMTINFO Info) {
2576 HBA_STATUS status;
2577 HBA_LIBRARY_INFO *lib_infop;
2578 HBA_HANDLE vendorHandle;
2579 HBASetRNIDMgmtInfoFunc
2580 SetRNIDMgmtInfoFunc;
2581
2582 DEBUG(2, "HBA_SetRNIDMgmtInfo", 0, 0, 0);
2583
2584 CHECKLIBRARY();
2585 SetRNIDMgmtInfoFunc = FUNCCOMMON(lib_infop, SetRNIDMgmtInfoHandler);
2586 if (SetRNIDMgmtInfoFunc != NULL) {
2587 status = (SetRNIDMgmtInfoFunc)(vendorHandle, Info);
2588 } else {
2589 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2590 }
2591 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2592 }
2593
2594 HBA_STATUS
2595 HBA_GetRNIDMgmtInfo(HBA_HANDLE handle, HBA_MGMTINFO *pInfo) {
2596 HBA_STATUS status;
2597 HBA_LIBRARY_INFO *lib_infop;
2598 HBA_HANDLE vendorHandle;
2599 HBAGetRNIDMgmtInfoFunc
2600 GetRNIDMgmtInfoFunc;
2601
2602 DEBUG(2, "HBA_GetRNIDMgmtInfo", 0, 0, 0);
2603
2604 CHECKLIBRARY();
2605 GetRNIDMgmtInfoFunc = FUNCCOMMON(lib_infop, GetRNIDMgmtInfoHandler);
2606 if (GetRNIDMgmtInfoFunc != NULL) {
2607 status = (GetRNIDMgmtInfoFunc)(vendorHandle, pInfo);
2608 } else {
2609 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2610 }
2611 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2612 }
2613
2614 HBA_STATUS
2615 HBA_SendRNID(
2616 HBA_HANDLE handle,
2617 HBA_WWN wwn,
2618 HBA_WWNTYPE wwntype,
2619 void *pRspBuffer,
2620 HBA_UINT32 *pRspBufferSize)
2621 {
2622 HBA_STATUS status;
2623 HBA_LIBRARY_INFO *lib_infop;
2624 HBA_HANDLE vendorHandle;
2625 HBASendRNIDFunc SendRNIDFunc;
2626
2627 DEBUG(2, "HBA_SendRNID for wwn: %s", WWN2STR1(&wwn), 0, 0);
2628
2629 CHECKLIBRARY();
2630 if (lib_infop->version == SMHBA) {
2631 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2632 }
2633
2634 SendRNIDFunc = lib_infop->ftable.functionTable.SendRNIDHandler;
2635 if (SendRNIDFunc != NULL) {
2636 status = ((SendRNIDFunc)(vendorHandle, wwn, wwntype,
2637 pRspBuffer, pRspBufferSize));
2638 } else {
2639 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2640 }
2641 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2642 }
2643
2644 HBA_STATUS
2645 HBA_SendRNIDV2(
2646 HBA_HANDLE handle,
2647 HBA_WWN hbaPortWWN,
2648 HBA_WWN destWWN,
2649 HBA_UINT32 destFCID,
2650 HBA_UINT32 NodeIdDataFormat,
2651 void *pRspBuffer,
2652 HBA_UINT32 *pRspBufferSize)
2653 {
2654 HBA_STATUS status;
2655 HBA_LIBRARY_INFO *lib_infop;
2656 HBA_HANDLE vendorHandle;
2657 HBASendRNIDV2Func registeredfunc;
2658
2659 DEBUG(2, "HBA_SendRNIDV2, hbaPortWWN: %s", WWN2STR1(&hbaPortWWN), 0, 0);
2660
2661 CHECKLIBRARY();
2662 registeredfunc = FUNCCOMMON(lib_infop, SendRNIDV2Handler);
2663 if (registeredfunc != NULL) {
2664 status = (registeredfunc)
2665 (vendorHandle, hbaPortWWN, destWWN, destFCID, NodeIdDataFormat,
2666 pRspBuffer, pRspBufferSize);
2667 } else {
2668 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2669 }
2670 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2671 }
2672
2673 void
2674 HBA_RefreshInformation(HBA_HANDLE handle) {
2675 HBA_STATUS status;
2676 HBA_LIBRARY_INFO *lib_infop;
2677 HBA_HANDLE vendorHandle;
2678 HBARefreshInformationFunc
2679 RefreshInformationFunc;
2680
2681 DEBUG(2, "HBA_RefreshInformation", 0, 0, 0);
2682
2683 status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
2684 if (status == HBA_STATUS_OK) {
2685 RefreshInformationFunc =
2686 FUNCCOMMON(lib_infop, RefreshInformationHandler);
2687 if (RefreshInformationFunc != NULL) {
2688 ((RefreshInformationFunc)(vendorHandle));
2689 }
2690 RELEASE_MUTEX(&_hbaapi_LL_mutex);
2691 }
2692 }
2693
2694 void
2695 HBA_ResetStatistics(HBA_HANDLE handle, HBA_UINT32 portindex) {
2696 HBA_STATUS status;
2697 HBA_LIBRARY_INFO *lib_infop;
2698 HBA_HANDLE vendorHandle;
2699 HBAResetStatisticsFunc
2700 ResetStatisticsFunc;
2701
2702 DEBUG(2, "HBA_ResetStatistics", 0, 0, 0);
2703
2704 status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
2705 if (status == HBA_STATUS_OK) {
2706 if (lib_infop->version == SMHBA) {
2707 RELEASE_MUTEX(&_hbaapi_LL_mutex);
2708 }
2709
2710 ResetStatisticsFunc =
2711 lib_infop->ftable.functionTable.ResetStatisticsHandler;
2712 if (ResetStatisticsFunc != NULL) {
2713 ((ResetStatisticsFunc)(vendorHandle, portindex));
2714 }
2715 RELEASE_MUTEX(&_hbaapi_LL_mutex);
2716 }
2717 }
2718
2719 HBA_STATUS
2720 HBA_GetFcpTargetMapping(HBA_HANDLE handle, PHBA_FCPTARGETMAPPING mapping) {
2721 HBA_STATUS status;
2722 HBA_LIBRARY_INFO *lib_infop;
2723 HBA_HANDLE vendorHandle;
2724 HBAGetFcpTargetMappingFunc GetFcpTargetMappingFunc;
2725
2726 DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0);
2727
2728 CHECKLIBRARY();
2729 if (lib_infop->version == SMHBA) {
2730 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2731 }
2732
2733 GetFcpTargetMappingFunc =
2734 lib_infop->ftable.functionTable.GetFcpTargetMappingHandler;
2735 if (GetFcpTargetMappingFunc != NULL) {
2736 status = ((GetFcpTargetMappingFunc)(vendorHandle, mapping));
2737 } else {
2738 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2739 }
2740 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2741 }
2742
2743 HBA_STATUS
2744 HBA_GetFcpTargetMappingV2(
2745 HBA_HANDLE handle,
2746 HBA_WWN hbaPortWWN,
2747 HBA_FCPTARGETMAPPINGV2 *pmapping)
2748 {
2749 HBA_STATUS status;
2750 HBA_LIBRARY_INFO *lib_infop;
2751 HBA_HANDLE vendorHandle;
2752 HBAGetFcpTargetMappingV2Func
2753 registeredfunc;
2754
2755 DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0);
2756
2757 CHECKLIBRARYANDVERSION(HBAAPIV2);
2758
2759 registeredfunc =
2760 lib_infop->ftable.functionTable.GetFcpTargetMappingV2Handler;
2761 if (registeredfunc != NULL) {
2762 status = ((registeredfunc)(vendorHandle, hbaPortWWN, pmapping));
2763 } else {
2764 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2765 }
2766 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2767 }
2768
2769 HBA_STATUS
2770 HBA_GetFcpPersistentBinding(HBA_HANDLE handle, PHBA_FCPBINDING binding) {
2771 HBA_STATUS status;
2772 HBA_LIBRARY_INFO *lib_infop;
2773 HBA_HANDLE vendorHandle;
2774 HBAGetFcpPersistentBindingFunc
2775 GetFcpPersistentBindingFunc;
2776
2777 DEBUG(2, "HBA_GetFcpPersistentBinding", 0, 0, 0);
2778
2779 CHECKLIBRARY();
2780 if (lib_infop->version == SMHBA) {
2781 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2782 }
2783
2784 GetFcpPersistentBindingFunc =
2785 lib_infop->ftable.functionTable.GetFcpPersistentBindingHandler;
2786 if (GetFcpPersistentBindingFunc != NULL) {
2787 status = ((GetFcpPersistentBindingFunc)(vendorHandle, binding));
2788 } else {
2789 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2790 }
2791 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2792 }
2793
2794 HBA_STATUS
2795 HBA_ScsiInquiryV2(
2796 HBA_HANDLE handle,
2797 HBA_WWN hbaPortWWN,
2798 HBA_WWN discoveredPortWWN,
2799 HBA_UINT64 fcLUN,
2800 HBA_UINT8 CDB_Byte1,
2801 HBA_UINT8 CDB_Byte2,
2802 void *pRspBuffer,
2803 HBA_UINT32 *pRspBufferSize,
2804 HBA_UINT8 *pScsiStatus,
2805 void *pSenseBuffer,
2806 HBA_UINT32 *pSenseBufferSize)
2807 {
2808 HBA_STATUS status;
2809 HBA_LIBRARY_INFO *lib_infop;
2810 HBA_HANDLE vendorHandle;
2811 HBAScsiInquiryV2Func ScsiInquiryV2Func;
2812
2813 DEBUG(2, "HBA_ScsiInquiryV2 to discoveredPortWWN: %s",
2814 WWN2STR1(&discoveredPortWWN), 0, 0);
2815
2816 CHECKLIBRARYANDVERSION(HBAAPIV2);
2817
2818 ScsiInquiryV2Func =
2819 lib_infop->ftable.functionTable.ScsiInquiryV2Handler;
2820 if (ScsiInquiryV2Func != NULL) {
2821 status = ((ScsiInquiryV2Func)(
2822 vendorHandle, hbaPortWWN, discoveredPortWWN, fcLUN, CDB_Byte1,
2823 CDB_Byte2, pRspBuffer, pRspBufferSize, pScsiStatus,
2824 pSenseBuffer, pSenseBufferSize));
2825 } else {
2826 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2827 }
2828 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2829 }
2830
2831 HBA_STATUS
2832 HBA_SendScsiInquiry(
2833 HBA_HANDLE handle,
2834 HBA_WWN PortWWN,
2835 HBA_UINT64 fcLUN,
2836 HBA_UINT8 EVPD,
2837 HBA_UINT32 PageCode,
2838 void *pRspBuffer,
2839 HBA_UINT32 RspBufferSize,
2840 void *pSenseBuffer,
2841 HBA_UINT32 SenseBufferSize)
2842 {
2843 HBA_STATUS status;
2844 HBA_LIBRARY_INFO *lib_infop;
2845 HBA_HANDLE vendorHandle;
2846 HBASendScsiInquiryFunc SendScsiInquiryFunc;
2847
2848 DEBUG(2, "HBA_SendScsiInquiry to PortWWN: %s",
2849 WWN2STR1(&PortWWN), 0, 0);
2850
2851 CHECKLIBRARY();
2852 if (lib_infop->version == SMHBA) {
2853 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2854 }
2855
2856 SendScsiInquiryFunc =
2857 lib_infop->ftable.functionTable.ScsiInquiryHandler;
2858 if (SendScsiInquiryFunc != NULL) {
2859 status = ((SendScsiInquiryFunc)(
2860 vendorHandle, PortWWN, fcLUN, EVPD, PageCode, pRspBuffer,
2861 RspBufferSize, pSenseBuffer, SenseBufferSize));
2862 } else {
2863 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2864 }
2865 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2866 }
2867
2868 HBA_STATUS
2869 HBA_ScsiReportLUNsV2(
2870 HBA_HANDLE handle,
2871 HBA_WWN hbaPortWWN,
2872 HBA_WWN discoveredPortWWN,
2873 void *pRespBuffer,
2874 HBA_UINT32 *pRespBufferSize,
2875 HBA_UINT8 *pScsiStatus,
2876 void *pSenseBuffer,
2877 HBA_UINT32 *pSenseBufferSize)
2878 {
2879 HBA_STATUS status;
2880 HBA_LIBRARY_INFO *lib_infop;
2881 HBA_HANDLE vendorHandle;
2882 HBAScsiReportLUNsV2Func ScsiReportLUNsV2Func;
2883
2884 DEBUG(2, "HBA_ScsiReportLUNsV2 to discoveredPortWWN: %s",
2885 WWN2STR1(&discoveredPortWWN), 0, 0);
2886
2887 CHECKLIBRARYANDVERSION(HBAAPIV2);
2888
2889 ScsiReportLUNsV2Func =
2890 lib_infop->ftable.functionTable.ScsiReportLUNsV2Handler;
2891 if (ScsiReportLUNsV2Func != NULL) {
2892 status = ((ScsiReportLUNsV2Func)(
2893 vendorHandle, hbaPortWWN, discoveredPortWWN,
2894 pRespBuffer, pRespBufferSize,
2895 pScsiStatus,
2896 pSenseBuffer, pSenseBufferSize));
2897 } else {
2898 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2899 }
2900 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2901 }
2902
2903 HBA_STATUS
2904 HBA_SendReportLUNs(
2905 HBA_HANDLE handle,
2906 HBA_WWN portWWN,
2907 void *pRspBuffer,
2908 HBA_UINT32 RspBufferSize,
2909 void *pSenseBuffer,
2910 HBA_UINT32 SenseBufferSize)
2911 {
2912 HBA_STATUS status;
2913 HBA_LIBRARY_INFO *lib_infop;
2914 HBA_HANDLE vendorHandle;
2915 HBASendReportLUNsFunc SendReportLUNsFunc;
2916
2917 DEBUG(2, "HBA_SendReportLUNs to PortWWN: %s", WWN2STR1(&portWWN), 0, 0);
2918
2919 CHECKLIBRARY();
2920 if (lib_infop->version == SMHBA) {
2921 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2922 }
2923
2924 SendReportLUNsFunc = lib_infop->ftable.functionTable.ReportLUNsHandler;
2925 if (SendReportLUNsFunc != NULL) {
2926 status = ((SendReportLUNsFunc)(
2927 vendorHandle, portWWN, pRspBuffer,
2928 RspBufferSize, pSenseBuffer, SenseBufferSize));
2929 } else {
2930 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2931 }
2932 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2933 }
2934
2935 HBA_STATUS
2936 HBA_ScsiReadCapacityV2(
2937 HBA_HANDLE handle,
2938 HBA_WWN hbaPortWWN,
2939 HBA_WWN discoveredPortWWN,
2940 HBA_UINT64 fcLUN,
2941 void *pRspBuffer,
2942 HBA_UINT32 *pRspBufferSize,
2943 HBA_UINT8 *pScsiStatus,
2944 void *pSenseBuffer,
2945 HBA_UINT32 *SenseBufferSize)
2946 {
2947 HBA_STATUS status;
2948 HBA_LIBRARY_INFO *lib_infop;
2949 HBA_HANDLE vendorHandle;
2950 HBAScsiReadCapacityV2Func ScsiReadCapacityV2Func;
2951
2952 DEBUG(2, "HBA_ScsiReadCapacityV2 to discoveredPortWWN: %s",
2953 WWN2STR1(&discoveredPortWWN), 0, 0);
2954
2955 CHECKLIBRARYANDVERSION(HBAAPIV2);
2956
2957 ScsiReadCapacityV2Func =
2958 lib_infop->ftable.functionTable.ScsiReadCapacityV2Handler;
2959 if (ScsiReadCapacityV2Func != NULL) {
2960 status = ((ScsiReadCapacityV2Func)(
2961 vendorHandle, hbaPortWWN, discoveredPortWWN, fcLUN,
2962 pRspBuffer, pRspBufferSize,
2963 pScsiStatus,
2964 pSenseBuffer, SenseBufferSize));
2965 } else {
2966 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2967 }
2968 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2969 }
2970
2971 HBA_STATUS
2972 HBA_SendReadCapacity(
2973 HBA_HANDLE handle,
2974 HBA_WWN portWWN,
2975 HBA_UINT64 fcLUN,
2976 void *pRspBuffer,
2977 HBA_UINT32 RspBufferSize,
2978 void *pSenseBuffer,
2979 HBA_UINT32 SenseBufferSize)
2980 {
2981 HBA_STATUS status;
2982 HBA_LIBRARY_INFO *lib_infop;
2983 HBA_HANDLE vendorHandle;
2984 HBASendReadCapacityFunc SendReadCapacityFunc;
2985
2986 DEBUG(2, "HBA_SendReadCapacity to portWWN: %s",
2987 WWN2STR1(&portWWN), 0, 0);
2988
2989 CHECKLIBRARY();
2990 if (lib_infop->version == SMHBA) {
2991 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE);
2992 }
2993
2994 SendReadCapacityFunc =
2995 lib_infop->ftable.functionTable.ReadCapacityHandler;
2996 if (SendReadCapacityFunc != NULL) {
2997 status = ((SendReadCapacityFunc)
2998 (vendorHandle, portWWN, fcLUN, pRspBuffer,
2999 RspBufferSize, pSenseBuffer, SenseBufferSize));
3000 } else {
3001 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3002 }
3003 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3004 }
3005
3006 HBA_STATUS
3007 HBA_SendRPL(
3008 HBA_HANDLE handle,
3009 HBA_WWN hbaPortWWN,
3010 HBA_WWN agent_wwn,
3011 HBA_UINT32 agent_domain,
3012 HBA_UINT32 portindex,
3013 void *pRspBuffer,
3014 HBA_UINT32 *pRspBufferSize)
3015 {
3016 HBA_STATUS status;
3017 HBA_LIBRARY_INFO *lib_infop;
3018 HBA_HANDLE vendorHandle;
3019 HBASendRPLFunc registeredfunc;
3020
3021 DEBUG(2, "HBA_SendRPL to agent_wwn: %s:%d",
3022 WWN2STR1(&agent_wwn), agent_domain, 0);
3023
3024 CHECKLIBRARY();
3025 registeredfunc = FUNCCOMMON(lib_infop, SendRPLHandler);
3026 if (registeredfunc != NULL) {
3027 status = (registeredfunc)(
3028 vendorHandle, hbaPortWWN, agent_wwn, agent_domain, portindex,
3029 pRspBuffer, pRspBufferSize);
3030 } else {
3031 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3032 }
3033 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3034 }
3035
3036 HBA_STATUS
3037 HBA_SendRPS(
3038 HBA_HANDLE handle,
3039 HBA_WWN hbaPortWWN,
3040 HBA_WWN agent_wwn,
3041 HBA_UINT32 agent_domain,
3042 HBA_WWN object_wwn,
3043 HBA_UINT32 object_port_number,
3044 void *pRspBuffer,
3045 HBA_UINT32 *pRspBufferSize)
3046 {
3047 HBA_STATUS status;
3048 HBA_LIBRARY_INFO *lib_infop;
3049 HBA_HANDLE vendorHandle;
3050 HBASendRPSFunc registeredfunc;
3051
3052 DEBUG(2, "HBA_SendRPS to agent_wwn: %s:%d",
3053 WWN2STR1(&agent_wwn), agent_domain, 0);
3054
3055 CHECKLIBRARY();
3056 registeredfunc = FUNCCOMMON(lib_infop, SendRPSHandler);
3057 if (registeredfunc != NULL) {
3058 status = (registeredfunc)(
3059 vendorHandle, hbaPortWWN, agent_wwn, agent_domain,
3060 object_wwn, object_port_number,
3061 pRspBuffer, pRspBufferSize);
3062 } else {
3063 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3064 }
3065 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3066 }
3067
3068 HBA_STATUS
3069 HBA_SendSRL(
3070 HBA_HANDLE handle,
3071 HBA_WWN hbaPortWWN,
3072 HBA_WWN wwn,
3073 HBA_UINT32 domain,
3074 void *pRspBuffer,
3075 HBA_UINT32 *pRspBufferSize)
3076 {
3077 HBA_STATUS status;
3078 HBA_LIBRARY_INFO *lib_infop;
3079 HBA_HANDLE vendorHandle;
3080 HBASendSRLFunc registeredfunc;
3081
3082 DEBUG(2, "HBA_SendSRL to wwn:%s domain:%d", WWN2STR1(&wwn), domain, 0);
3083
3084 CHECKLIBRARY();
3085 registeredfunc = FUNCCOMMON(lib_infop, SendSRLHandler);
3086 if (registeredfunc != NULL) {
3087 status = (registeredfunc)(
3088 vendorHandle, hbaPortWWN, wwn, domain,
3089 pRspBuffer, pRspBufferSize);
3090 } else {
3091 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3092 }
3093 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3094 }
3095 HBA_STATUS
3096 HBA_SendRLS(
3097 HBA_HANDLE handle,
3098 HBA_WWN hbaPortWWN,
3099 HBA_WWN destWWN,
3100 void *pRspBuffer,
3101 HBA_UINT32 *pRspBufferSize)
3102 {
3103 HBA_STATUS status;
3104 HBA_LIBRARY_INFO *lib_infop;
3105 HBA_HANDLE vendorHandle;
3106 HBASendRLSFunc registeredfunc;
3107
3108 DEBUG(2, "HBA_SendRLS dest_wwn: %s",
3109 WWN2STR1(&destWWN), 0, 0);
3110
3111 CHECKLIBRARY();
3112 registeredfunc = FUNCCOMMON(lib_infop, SendRLSHandler);
3113 if (registeredfunc != NULL) {
3114 status = (registeredfunc)(
3115 vendorHandle, hbaPortWWN, destWWN,
3116 pRspBuffer, pRspBufferSize);
3117 } else {
3118 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3119 }
3120 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3121 }
3122
3123 HBA_STATUS
3124 HBA_SendLIRR(
3125 HBA_HANDLE handle,
3126 HBA_WWN sourceWWN,
3127 HBA_WWN destWWN,
3128 HBA_UINT8 function,
3129 HBA_UINT8 type,
3130 void *pRspBuffer,
3131 HBA_UINT32 *pRspBufferSize)
3132 {
3133 HBA_STATUS status;
3134 HBA_LIBRARY_INFO *lib_infop;
3135 HBA_HANDLE vendorHandle;
3136 HBASendLIRRFunc registeredfunc;
3137
3138 DEBUG(2, "HBA_SendLIRR destWWN:%s", WWN2STR1(&destWWN), 0, 0);
3139
3140 CHECKLIBRARY();
3141 registeredfunc = FUNCCOMMON(lib_infop, SendLIRRHandler);
3142 if (registeredfunc != NULL) {
3143 status = (registeredfunc)(
3144 vendorHandle, sourceWWN, destWWN, function, type,
3145 pRspBuffer, pRspBufferSize);
3146 } else {
3147 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3148 }
3149 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3150 }
3151
3152 HBA_STATUS
3153 HBA_GetBindingCapability(
3154 HBA_HANDLE handle,
3155 HBA_WWN hbaPortWWN,
3156 HBA_BIND_CAPABILITY *pcapability)
3157 {
3158 HBA_STATUS status;
3159 HBA_LIBRARY_INFO *lib_infop;
3160 HBA_HANDLE vendorHandle;
3161 HBAGetBindingCapabilityFunc
3162 registeredfunc;
3163
3164 DEBUG(2, "HBA_GetBindingCapability", 0, 0, 0);
3165
3166 CHECKLIBRARYANDVERSION(HBAAPIV2);
3167
3168 registeredfunc =
3169 lib_infop->ftable.functionTable.GetBindingCapabilityHandler;
3170 if (registeredfunc != NULL) {
3171 status = (registeredfunc)(vendorHandle, hbaPortWWN, pcapability);
3172 } else {
3173 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3174 }
3175 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3176 }
3177
3178 HBA_STATUS
3179 HBA_GetBindingSupport(
3180 HBA_HANDLE handle,
3181 HBA_WWN hbaPortWWN,
3182 HBA_BIND_CAPABILITY *pcapability)
3183 {
3184 HBA_STATUS status;
3185 HBA_LIBRARY_INFO *lib_infop;
3186 HBA_HANDLE vendorHandle;
3187 HBAGetBindingSupportFunc
3188 registeredfunc;
3189
3190 DEBUG(2, "HBA_GetBindingSupport", 0, 0, 0);
3191
3192 CHECKLIBRARYANDVERSION(HBAAPIV2);
3193
3194 registeredfunc =
3195 lib_infop->ftable.functionTable.GetBindingSupportHandler;
3196 if (registeredfunc != NULL) {
3197 status = (registeredfunc)(vendorHandle, hbaPortWWN, pcapability);
3198 } else {
3199 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3200 }
3201 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3202 }
3203
3204 HBA_STATUS
3205 HBA_SetBindingSupport(
3206 HBA_HANDLE handle,
3207 HBA_WWN hbaPortWWN,
3208 HBA_BIND_CAPABILITY capability)
3209 {
3210 HBA_STATUS status;
3211 HBA_LIBRARY_INFO *lib_infop;
3212 HBA_HANDLE vendorHandle;
3213 HBASetBindingSupportFunc
3214 registeredfunc;
3215
3216 DEBUG(2, "HBA_SetBindingSupport", 0, 0, 0);
3217
3218 CHECKLIBRARYANDVERSION(HBAAPIV2);
3219
3220 registeredfunc =
3221 lib_infop->ftable.functionTable.SetBindingSupportHandler;
3222 if (registeredfunc != NULL) {
3223 status = (registeredfunc)(vendorHandle, hbaPortWWN, capability);
3224 } else {
3225 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3226 }
3227 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3228 }
3229
3230 HBA_STATUS
3231 HBA_SetPersistentBindingV2(
3232 HBA_HANDLE handle,
3233 HBA_WWN hbaPortWWN,
3234 const HBA_FCPBINDING2 *pbinding)
3235 {
3236 HBA_STATUS status;
3237 HBA_LIBRARY_INFO *lib_infop;
3238 HBA_HANDLE vendorHandle;
3239 HBASetPersistentBindingV2Func
3240 registeredfunc;
3241
3242 DEBUG(2, "HBA_SetPersistentBindingV2 port: %s",
3243 WWN2STR1(&hbaPortWWN), 0, 0);
3244
3245 CHECKLIBRARYANDVERSION(HBAAPIV2);
3246
3247 registeredfunc =
3248 lib_infop->ftable.functionTable.SetPersistentBindingV2Handler;
3249 if (registeredfunc != NULL) {
3250 status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
3251 } else {
3252 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3253 }
3254 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3255 }
3256
3257 HBA_STATUS
3258 HBA_GetPersistentBindingV2(
3259 HBA_HANDLE handle,
3260 HBA_WWN hbaPortWWN,
3261 HBA_FCPBINDING2 *pbinding)
3262 {
3263 HBA_STATUS status;
3264 HBA_LIBRARY_INFO *lib_infop;
3265 HBA_HANDLE vendorHandle;
3266 HBAGetPersistentBindingV2Func
3267 registeredfunc;
3268
3269 DEBUG(2, "HBA_GetPersistentBindingV2 port: %s",
3270 WWN2STR1(&hbaPortWWN), 0, 0);
3271
3272 CHECKLIBRARYANDVERSION(HBAAPIV2);
3273
3274 registeredfunc =
3275 lib_infop->ftable.functionTable.GetPersistentBindingV2Handler;
3276 if (registeredfunc != NULL) {
3277 status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
3278 } else {
3279 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3280 }
3281 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3282 }
3283
3284 HBA_STATUS
3285 HBA_RemovePersistentBinding(
3286 HBA_HANDLE handle,
3287 HBA_WWN hbaPortWWN,
3288 const HBA_FCPBINDING2
3289 *pbinding)
3290 {
3291 HBA_STATUS status;
3292 HBA_LIBRARY_INFO *lib_infop;
3293 HBA_HANDLE vendorHandle;
3294 HBARemovePersistentBindingFunc
3295 registeredfunc;
3296
3297 DEBUG(2, "HBA_RemovePersistentBinding", 0, 0, 0);
3298
3299 CHECKLIBRARYANDVERSION(HBAAPIV2);
3300
3301 registeredfunc =
3302 lib_infop->ftable.functionTable.RemovePersistentBindingHandler;
3303 if (registeredfunc != NULL) {
3304 status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
3305 } else {
3306 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3307 }
3308 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3309 }
3310
3311 HBA_STATUS
3312 HBA_RemoveAllPersistentBindings(
3313 HBA_HANDLE handle,
3314 HBA_WWN hbaPortWWN)
3315 {
3316 HBA_STATUS status;
3317 HBA_LIBRARY_INFO *lib_infop;
3318 HBA_HANDLE vendorHandle;
3319 HBARemoveAllPersistentBindingsFunc
3320 registeredfunc;
3321
3322 DEBUG(2, "HBA_RemoveAllPersistentBindings", 0, 0, 0);
3323
3324 CHECKLIBRARYANDVERSION(HBAAPIV2);
3325
3326 registeredfunc =
3327 lib_infop->ftable.functionTable.RemoveAllPersistentBindingsHandler;
3328 if (registeredfunc != NULL) {
3329 status = (registeredfunc)(vendorHandle, hbaPortWWN);
3330 } else {
3331 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3332 }
3333 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3334 }
3335
3336 HBA_STATUS
3337 HBA_GetFC4Statistics(
3338 HBA_HANDLE handle,
3339 HBA_WWN portWWN,
3340 HBA_UINT8 FC4type,
3341 HBA_FC4STATISTICS *pstatistics)
3342 {
3343 HBA_STATUS status;
3344 HBA_LIBRARY_INFO *lib_infop;
3345 HBA_HANDLE vendorHandle;
3346 HBAGetFC4StatisticsFunc
3347 registeredfunc;
3348
3349 DEBUG(2, "HBA_GetFC4Statistics port: %s", WWN2STR1(&portWWN), 0, 0);
3350
3351 CHECKLIBRARYANDVERSION(HBAAPIV2);
3352
3353 registeredfunc =
3354 lib_infop->ftable.functionTable.GetFC4StatisticsHandler;
3355 if (registeredfunc != NULL) {
3356 status = (registeredfunc)
3357 (vendorHandle, portWWN, FC4type, pstatistics);
3358 } else {
3359 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3360 }
3361 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3362 }
3363
3364 HBA_STATUS
3365 HBA_GetFCPStatistics(
3366 HBA_HANDLE handle,
3367 const HBA_SCSIID *lunit,
3368 HBA_FC4STATISTICS *pstatistics)
3369 {
3370 HBA_STATUS status;
3371 HBA_LIBRARY_INFO *lib_infop;
3372 HBA_HANDLE vendorHandle;
3373 HBAGetFCPStatisticsFunc
3374 registeredfunc;
3375
3376 DEBUG(2, "HBA_GetFCPStatistics", 0, 0, 0);
3377
3378 CHECKLIBRARYANDVERSION(HBAAPIV2);
3379
3380 registeredfunc =
3381 lib_infop->ftable.functionTable.GetFCPStatisticsHandler;
3382 if (registeredfunc != NULL) {
3383 status = (registeredfunc)(vendorHandle, lunit, pstatistics);
3384 } else {
3385 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3386 }
3387 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3388 }
3389
3390 HBA_UINT32
3391 HBA_GetVendorLibraryAttributes(
3392 HBA_UINT32 adapter_index,
3393 HBA_LIBRARYATTRIBUTES *attributes)
3394 {
3395 HBA_ADAPTER_INFO *adapt_infop;
3396 HBAGetVendorLibraryAttributesFunc
3397 registeredfunc;
3398 HBA_UINT32 ret = 0;
3399
3400 DEBUG(2, "HBA_GetVendorLibraryAttributes adapterindex:%d",
3401 adapter_index, 0, 0);
3402 if (_hbaapi_librarylist == NULL) {
3403 DEBUG(1, "HBAAPI not loaded yet.", 0, 0, 0);
3404 return (0);
3405 }
3406
3407 if (attributes == NULL) {
3408 DEBUG(1,
3409 "HBA_GetVendorLibraryAttributes: NULL pointer attributes",
3410 0, 0, 0);
3411 return (HBA_STATUS_ERROR_ARG);
3412 }
3413
3414 (void) memset(attributes, 0, sizeof (HBA_LIBRARYATTRIBUTES));
3415
3416 GRAB_MUTEX(&_hbaapi_LL_mutex);
3417 GRAB_MUTEX(&_hbaapi_AL_mutex);
3418 for (adapt_infop = _hbaapi_adapterlist;
3419 adapt_infop != NULL;
3420 adapt_infop = adapt_infop->next) {
3421
3422 if (adapt_infop->index == adapter_index) {
3423
3424 if (adapt_infop->library->version == SMHBA) {
3425 RELEASE_MUTEX(&_hbaapi_AL_mutex);
3426 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
3427 HBA_STATUS_ERROR_INCOMPATIBLE);
3428 }
3429
3430 registeredfunc = adapt_infop->library->
3431 ftable.functionTable.GetVendorLibraryAttributesHandler;
3432 if (registeredfunc != NULL) {
3433 ret = (registeredfunc)(attributes);
3434 } else {
3435 /* Version 1 libary? */
3436 HBAGetVersionFunc GetVersionFunc;
3437 GetVersionFunc = adapt_infop->library->
3438 ftable.functionTable.GetVersionHandler;
3439 if (GetVersionFunc != NULL) {
3440 ret = ((GetVersionFunc)());
3441 }
3442 #ifdef NOTDEF
3443 else {
3444 /* This should not happen, dont think its going to */
3445 }
3446 #endif
3447 }
3448 if (attributes->LibPath[0] == '\0') {
3449 if (strlen(adapt_infop->library->LibraryPath) < 256) {
3450 (void) strcpy(attributes->LibPath,
3451 adapt_infop->library->LibraryPath);
3452 }
3453 }
3454 break;
3455 }
3456 }
3457 RELEASE_MUTEX(&_hbaapi_AL_mutex);
3458 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, ret);
3459 }
3460
3461
3462 /*
3463 * This function returns SM-HBA version that the warpper library implemented.
3464 */
3465 HBA_UINT32
3466 SMHBA_GetVersion() {
3467 DEBUG(2, "SMHBA_GetVersion", 0, 0, 0);
3468 return (SMHBA_LIBVERSION);
3469 }
3470
3471 /*
3472 * This function returns the attributes for the warpper library.
3473 */
3474 HBA_UINT32
3475 SMHBA_GetWrapperLibraryAttributes(
3476 SMHBA_LIBRARYATTRIBUTES *attributes)
3477 {
3478
3479 struct timeval tv;
3480 struct tm tp;
3481
3482 DEBUG(2, "SMHBA_GetWrapperLibraryAttributes", 0, 0, 0);
3483
3484 if (attributes == NULL) {
3485 DEBUG(1, "SMHBA_GetWrapperLibraryAttributes: "
3486 "NULL pointer attributes",
3487 0, 0, 0);
3488 return (HBA_STATUS_ERROR_ARG);
3489 }
3490
3491 (void) memset(attributes, 0, sizeof (SMHBA_LIBRARYATTRIBUTES));
3492
3493 #if defined(SOLARIS)
3494 if ((handle = dlopen("libSMHBAAPI.so", RTLD_NOW)) != NULL) {
3495 if (dlinfo(handle, RTLD_DI_LINKMAP, &map) >= 0) {
3496 for (mp = map; mp != NULL; mp = mp->l_next) {
3497 if (strlen(map->l_name) < 256) {
3498 (void) strcpy(attributes->LibPath, map->l_name);
3499 }
3500 }
3501 }
3502 }
3503
3504 #endif
3505
3506 #if defined(VENDOR)
3507 (void) strcpy(attributes->VName, VENDOR);
3508 #else
3509 attributes->VName[0] = '\0';
3510 #endif
3511 #if defined(VERSION)
3512 (void) strcpy(attributes->VVersion, VERSION);
3513 #else
3514 attributes->VVersion[0] = '\0';
3515 #endif
3516
3517 if (gettimeofday(&tv, (void *)0) == 0) {
3518 if (localtime_r(&tv.tv_sec, &tp) != NULL) {
3519 attributes->build_date.tm_mday = tp.tm_mday;
3520 attributes->build_date.tm_mon = tp.tm_mon;
3521 attributes->build_date.tm_year = tp.tm_year;
3522 } else {
3523 (void) memset(&attributes->build_date, 0,
3524 sizeof (attributes->build_date));
3525 }
3526 (void) memset(&attributes->build_date, 0,
3527 sizeof (attributes->build_date));
3528 }
3529
3530 return (1);
3531 }
3532
3533 /*
3534 * This function returns the attributes for the warpper library.
3535 */
3536 HBA_UINT32
3537 SMHBA_GetVendorLibraryAttributes(
3538 HBA_UINT32 adapter_index,
3539 SMHBA_LIBRARYATTRIBUTES *attributes)
3540 {
3541 HBA_ADAPTER_INFO *adapt_infop;
3542 SMHBAGetVendorLibraryAttributesFunc
3543 registeredfunc;
3544 HBA_UINT32 ret = 0;
3545
3546 DEBUG(2, "SMHBA_GetVendorLibraryAttributes adapterindex:%d",
3547 adapter_index, 0, 0);
3548 if (_hbaapi_librarylist == NULL) {
3549 DEBUG(1, "SMHBAAPI not loaded yet.", 0, 0, 0);
3550 return (0);
3551 }
3552
3553 if (attributes == NULL) {
3554 DEBUG(1, "SMHBA_GetVendorLibraryAttributes: "
3555 "NULL pointer attributes",
3556 0, 0, 0);
3557 return (HBA_STATUS_ERROR_ARG);
3558 }
3559
3560 (void) memset(attributes, 0, sizeof (SMHBA_LIBRARYATTRIBUTES));
3561
3562 GRAB_MUTEX(&_hbaapi_LL_mutex);
3563 GRAB_MUTEX(&_hbaapi_AL_mutex);
3564 for (adapt_infop = _hbaapi_adapterlist;
3565 adapt_infop != NULL;
3566 adapt_infop = adapt_infop->next) {
3567
3568 if (adapt_infop->index == adapter_index) {
3569
3570 if (adapt_infop->library->version != SMHBA) {
3571 RELEASE_MUTEX(&_hbaapi_AL_mutex);
3572 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
3573 HBA_STATUS_ERROR_INCOMPATIBLE);
3574 }
3575
3576 registeredfunc = adapt_infop->library->
3577 ftable.smhbafunctionTable.GetVendorLibraryAttributesHandler;
3578 if (registeredfunc != NULL) {
3579 ret = (registeredfunc)(attributes);
3580 #ifdef NOTDEF
3581 } else {
3582 /* This should not happen since the VSL is already loaded. */
3583 #endif
3584 }
3585 if (attributes->LibPath[0] == '\0') {
3586 if (strlen(adapt_infop->library->LibraryPath) < 256) {
3587 (void) strcpy(attributes->LibPath,
3588 adapt_infop->library->LibraryPath);
3589 }
3590 }
3591 break;
3592 }
3593 }
3594 RELEASE_MUTEX(&_hbaapi_AL_mutex);
3595 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, ret);
3596 }
3597
3598 HBA_STATUS
3599 SMHBA_GetAdapterAttributes(
3600 HBA_HANDLE handle,
3601 SMHBA_ADAPTERATTRIBUTES *hbaattributes)
3602 {
3603 HBA_STATUS status;
3604 HBA_LIBRARY_INFO *lib_infop;
3605 HBA_HANDLE vendorHandle;
3606 SMHBAGetAdapterAttributesFunc GetAdapterAttributesFunc;
3607
3608 DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0);
3609
3610 CHECKLIBRARYANDVERSION(SMHBA);
3611
3612 GetAdapterAttributesFunc =
3613 lib_infop->ftable.smhbafunctionTable.GetAdapterAttributesHandler;
3614 if (GetAdapterAttributesFunc != NULL) {
3615 status = ((GetAdapterAttributesFunc)(vendorHandle, hbaattributes));
3616 } else {
3617 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3618 }
3619 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3620 }
3621
3622 HBA_STATUS
3623 SMHBA_GetNumberOfPorts(
3624 HBA_HANDLE handle,
3625 HBA_UINT32 *numberofports)
3626 {
3627 HBA_STATUS status;
3628 HBA_LIBRARY_INFO *lib_infop;
3629 HBA_HANDLE vendorHandle;
3630 SMHBAGetNumberOfPortsFunc GetNumberOfPortsFunc;
3631
3632 DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0);
3633
3634 CHECKLIBRARYANDVERSION(SMHBA);
3635
3636 GetNumberOfPortsFunc =
3637 lib_infop->ftable.smhbafunctionTable.GetNumberOfPortsHandler;
3638 if (GetNumberOfPortsFunc != NULL) {
3639 status = ((GetNumberOfPortsFunc)(vendorHandle, numberofports));
3640 } else {
3641 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3642 }
3643 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3644 }
3645
3646 HBA_STATUS
3647 SMHBA_GetPortType(
3648 HBA_HANDLE handle,
3649 HBA_UINT32 portindex,
3650 HBA_PORTTYPE *porttype)
3651 {
3652 HBA_STATUS status;
3653 HBA_LIBRARY_INFO *lib_infop;
3654 HBA_HANDLE vendorHandle;
3655 SMHBAGetPortTypeFunc GetPortTypeFunc;
3656
3657 DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0);
3658
3659 CHECKLIBRARYANDVERSION(SMHBA);
3660
3661 GetPortTypeFunc =
3662 lib_infop->ftable.smhbafunctionTable.GetPortTypeHandler;
3663 if (GetPortTypeFunc != NULL) {
3664 status = ((GetPortTypeFunc)(vendorHandle, portindex, porttype));
3665 } else {
3666 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3667 }
3668 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3669 }
3670
3671 HBA_STATUS
3672 SMHBA_GetAdapterPortAttributes(
3673 HBA_HANDLE handle,
3674 HBA_UINT32 portindex,
3675 SMHBA_PORTATTRIBUTES *portattributes)
3676 {
3677 HBA_STATUS status;
3678 HBA_LIBRARY_INFO *lib_infop;
3679 HBA_HANDLE vendorHandle;
3680 SMHBAGetAdapterPortAttributesFunc
3681 GetAdapterPortAttributesFunc;
3682
3683 DEBUG(2, "SMHBA_GetAdapterPortAttributes", 0, 0, 0);
3684
3685 CHECKLIBRARYANDVERSION(SMHBA);
3686
3687 GetAdapterPortAttributesFunc =
3688 lib_infop->ftable.smhbafunctionTable.\
3689 GetAdapterPortAttributesHandler;
3690 if (GetAdapterPortAttributesFunc != NULL) {
3691 status = ((GetAdapterPortAttributesFunc)
3692 (vendorHandle, portindex, portattributes));
3693 } else {
3694 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3695 }
3696 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3697 }
3698
3699 HBA_STATUS
3700 SMHBA_GetDiscoveredPortAttributes(
3701 HBA_HANDLE handle,
3702 HBA_UINT32 portindex,
3703 HBA_UINT32 discoveredportindex,
3704 SMHBA_PORTATTRIBUTES *portattributes)
3705 {
3706 HBA_STATUS status;
3707 HBA_LIBRARY_INFO *lib_infop;
3708 HBA_HANDLE vendorHandle;
3709 SMHBAGetDiscoveredPortAttributesFunc
3710 GetDiscoveredPortAttributesFunc;
3711
3712 DEBUG(2, "SMHBA_GetDiscoveredPortAttributes", 0, 0, 0);
3713
3714 CHECKLIBRARYANDVERSION(SMHBA);
3715
3716 GetDiscoveredPortAttributesFunc =
3717 lib_infop->ftable.smhbafunctionTable.\
3718 GetDiscoveredPortAttributesHandler;
3719 if (GetDiscoveredPortAttributesFunc != NULL) {
3720 status = ((GetDiscoveredPortAttributesFunc)
3721 (vendorHandle, portindex, discoveredportindex,
3722 portattributes));
3723 } else {
3724 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3725 }
3726 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3727 }
3728
3729 HBA_STATUS
3730 SMHBA_GetPortAttributesByWWN(
3731 HBA_HANDLE handle,
3732 HBA_WWN portWWN,
3733 HBA_WWN domainPortWWN,
3734 SMHBA_PORTATTRIBUTES *portattributes)
3735 {
3736 HBA_STATUS status;
3737 HBA_LIBRARY_INFO *lib_infop;
3738 HBA_HANDLE vendorHandle;
3739 SMHBAGetPortAttributesByWWNFunc
3740 GetPortAttributesByWWNFunc;
3741
3742 DEBUG(2, "SMHBA_GetPortAttributesByWWN: %s", WWN2STR1(&portWWN), 0, 0);
3743
3744 CHECKLIBRARYANDVERSION(SMHBA);
3745
3746 GetPortAttributesByWWNFunc =
3747 lib_infop->ftable.smhbafunctionTable.GetPortAttributesByWWNHandler;
3748 if (GetPortAttributesByWWNFunc != NULL) {
3749 status = ((GetPortAttributesByWWNFunc)
3750 (vendorHandle, portWWN, domainPortWWN, portattributes));
3751 } else {
3752 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3753 }
3754 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3755 }
3756
3757 HBA_STATUS
3758 SMHBA_GetFCPhyAttributes(
3759 HBA_HANDLE handle,
3760 HBA_UINT32 portindex,
3761 HBA_UINT32 phyindex,
3762 SMHBA_FC_PHY *phytype)
3763 {
3764 HBA_STATUS status;
3765 HBA_LIBRARY_INFO *lib_infop;
3766 HBA_HANDLE vendorHandle;
3767 SMHBAGetFCPhyAttributesFunc GetFCPhyAttributesFunc;
3768
3769 DEBUG(2, "SMHBA_GetFCPhyAttributesByWWN", 0, 0, 0);
3770
3771 CHECKLIBRARYANDVERSION(SMHBA);
3772
3773 GetFCPhyAttributesFunc =
3774 lib_infop->ftable.smhbafunctionTable.GetFCPhyAttributesHandler;
3775 if (GetFCPhyAttributesFunc != NULL) {
3776 status = ((GetFCPhyAttributesFunc)
3777 (vendorHandle, portindex, phyindex, phytype));
3778 } else {
3779 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3780 }
3781 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3782 }
3783
3784 HBA_STATUS
3785 SMHBA_GetSASPhyAttributes(
3786 HBA_HANDLE handle,
3787 HBA_UINT32 portindex,
3788 HBA_UINT32 phyindex,
3789 SMHBA_SAS_PHY *phytype)
3790 {
3791 HBA_STATUS status;
3792 HBA_LIBRARY_INFO *lib_infop;
3793 HBA_HANDLE vendorHandle;
3794 SMHBAGetSASPhyAttributesFunc GetSASPhyAttributesFunc;
3795
3796 DEBUG(2, "SMHBA_GetFCPhyAttributesByWWN", 0, 0, 0);
3797
3798 CHECKLIBRARYANDVERSION(SMHBA);
3799
3800 GetSASPhyAttributesFunc =
3801 lib_infop->ftable.smhbafunctionTable.GetSASPhyAttributesHandler;
3802 if (GetSASPhyAttributesFunc != NULL) {
3803 status = ((GetSASPhyAttributesFunc)
3804 (vendorHandle, portindex, phyindex, phytype));
3805 } else {
3806 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3807 }
3808 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3809 }
3810
3811 HBA_STATUS
3812 SMHBA_GetProtocolStatistics(
3813 HBA_HANDLE handle,
3814 HBA_UINT32 portindex,
3815 HBA_UINT32 protocoltype,
3816 SMHBA_PROTOCOLSTATISTICS *pProtocolStatistics)
3817 {
3818 HBA_STATUS status;
3819 HBA_LIBRARY_INFO *lib_infop;
3820 HBA_HANDLE vendorHandle;
3821 SMHBAGetProtocolStatisticsFunc
3822 GetProtocolStatisticsFunc;
3823
3824 DEBUG(2, "SMHBA_GetProtocolStatistics port index: %d protocol type: %d",
3825 portindex, protocoltype, 0);
3826
3827 CHECKLIBRARYANDVERSION(SMHBA);
3828
3829 GetProtocolStatisticsFunc =
3830 lib_infop->ftable.smhbafunctionTable.GetProtocolStatisticsHandler;
3831 if (GetProtocolStatisticsFunc != NULL) {
3832 status = (GetProtocolStatisticsFunc)
3833 (vendorHandle, portindex, protocoltype, pProtocolStatistics);
3834 } else {
3835 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3836 }
3837 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3838 }
3839
3840 HBA_STATUS
3841 SMHBA_GetPhyStatistics(
3842 HBA_HANDLE handle,
3843 HBA_UINT32 portindex,
3844 HBA_UINT32 phyindex,
3845 SMHBA_PHYSTATISTICS *pPhyStatistics)
3846 {
3847 HBA_STATUS status;
3848 HBA_LIBRARY_INFO *lib_infop;
3849 HBA_HANDLE vendorHandle;
3850 SMHBAGetPhyStatisticsFunc
3851 GetPhyStatisticsFunc;
3852
3853 DEBUG(2, "SMHBA_GetPhyStatistics port index: %d phy idex: %d",
3854 portindex, phyindex, 0);
3855
3856 CHECKLIBRARYANDVERSION(SMHBA);
3857
3858 GetPhyStatisticsFunc =
3859 lib_infop->ftable.smhbafunctionTable.GetPhyStatisticsHandler;
3860 if (GetPhyStatisticsFunc != NULL) {
3861 status = (GetPhyStatisticsFunc)
3862 (vendorHandle, portindex, phyindex, pPhyStatistics);
3863 } else {
3864 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3865 }
3866 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3867 }
3868
3869 HBA_STATUS
3870 SMHBA_GetBindingCapability(
3871 HBA_HANDLE handle,
3872 HBA_WWN hbaPortWWN,
3873 HBA_WWN domainPortWWN,
3874 SMHBA_BIND_CAPABILITY *pFlags)
3875 {
3876 HBA_STATUS status;
3877 HBA_LIBRARY_INFO *lib_infop;
3878 HBA_HANDLE vendorHandle;
3879 SMHBAGetBindingCapabilityFunc GetBindingCapabilityFunc;
3880
3881 DEBUG(2, "HBA_GetBindingCapability", 0, 0, 0);
3882
3883 CHECKLIBRARYANDVERSION(SMHBA);
3884
3885 GetBindingCapabilityFunc =
3886 lib_infop->ftable.smhbafunctionTable.GetBindingCapabilityHandler;
3887 if (GetBindingCapabilityFunc != NULL) {
3888 status = (GetBindingCapabilityFunc)(vendorHandle, hbaPortWWN,
3889 domainPortWWN, pFlags);
3890 } else {
3891 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3892 }
3893 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3894 }
3895
3896 HBA_STATUS
3897 SMHBA_GetBindingSupport(
3898 HBA_HANDLE handle,
3899 HBA_WWN hbaPortWWN,
3900 HBA_WWN domainPortWWN,
3901 SMHBA_BIND_CAPABILITY *pFlags)
3902 {
3903 HBA_STATUS status;
3904 HBA_LIBRARY_INFO *lib_infop;
3905 HBA_HANDLE vendorHandle;
3906 SMHBAGetBindingSupportFunc
3907 GetBindingSupporFunc;
3908
3909 DEBUG(2, "SMHBA_GetBindingSupport port: %s",
3910 WWN2STR1(&hbaPortWWN), 0, 0);
3911
3912 CHECKLIBRARYANDVERSION(SMHBA);
3913
3914 GetBindingSupporFunc =
3915 lib_infop->ftable.smhbafunctionTable.GetBindingSupportHandler;
3916 if (GetBindingSupporFunc != NULL) {
3917 status = (GetBindingSupporFunc)(vendorHandle,
3918 hbaPortWWN, domainPortWWN, pFlags);
3919 } else {
3920 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3921 }
3922 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3923 }
3924
3925 HBA_STATUS
3926 SMHBA_SetBindingSupport(
3927 HBA_HANDLE handle,
3928 HBA_WWN hbaPortWWN,
3929 HBA_WWN domainPortWWN,
3930 SMHBA_BIND_CAPABILITY flags)
3931 {
3932 HBA_STATUS status;
3933 HBA_LIBRARY_INFO *lib_infop;
3934 HBA_HANDLE vendorHandle;
3935 SMHBASetBindingSupportFunc
3936 SetBindingSupporFunc;
3937
3938 DEBUG(2, "SMHBA_GetBindingSupport port: %s",
3939 WWN2STR1(&hbaPortWWN), 0, 0);
3940
3941 CHECKLIBRARYANDVERSION(HBAAPIV2);
3942
3943 SetBindingSupporFunc =
3944 lib_infop->ftable.smhbafunctionTable.SetBindingSupportHandler;
3945 if (SetBindingSupporFunc != NULL) {
3946 status = (SetBindingSupporFunc)
3947 (vendorHandle, hbaPortWWN, domainPortWWN, flags);
3948 } else {
3949 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3950 }
3951 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3952 }
3953
3954 HBA_STATUS
3955 SMHBA_GetTargetMapping(
3956 HBA_HANDLE handle,
3957 HBA_WWN hbaPortWWN,
3958 HBA_WWN domainPortWWN,
3959 SMHBA_TARGETMAPPING *pMapping)
3960 {
3961 HBA_STATUS status;
3962 HBA_LIBRARY_INFO *lib_infop;
3963 HBA_HANDLE vendorHandle;
3964 SMHBAGetTargetMappingFunc GetTargetMappingFunc;
3965
3966 DEBUG(2, "SMHBA_GetTargetMapping port WWN: %s",
3967 WWN2STR1(&hbaPortWWN), 0, 0);
3968
3969 CHECKLIBRARYANDVERSION(SMHBA);
3970
3971 GetTargetMappingFunc =
3972 lib_infop->ftable.smhbafunctionTable.GetTargetMappingHandler;
3973 if (GetTargetMappingFunc != NULL) {
3974 status = ((GetTargetMappingFunc)(vendorHandle,
3975 hbaPortWWN, domainPortWWN, pMapping));
3976 } else {
3977 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
3978 }
3979 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
3980 }
3981
3982 HBA_STATUS
3983 SMHBA_GetPersistentBinding(
3984 HBA_HANDLE handle,
3985 HBA_WWN hbaPortWWN,
3986 HBA_WWN domainPortWWN,
3987 SMHBA_BINDING *binding)
3988 {
3989 HBA_STATUS status;
3990 HBA_LIBRARY_INFO *lib_infop;
3991 HBA_HANDLE vendorHandle;
3992 SMHBAGetPersistentBindingFunc
3993 GetPersistentBindingFunc;
3994
3995 DEBUG(2, "SMHBA_GetPersistentBinding port WWN: %s",
3996 WWN2STR1(&hbaPortWWN), 0, 0);
3997
3998 CHECKLIBRARYANDVERSION(SMHBA);
3999
4000 GetPersistentBindingFunc =
4001 lib_infop->ftable.smhbafunctionTable.GetPersistentBindingHandler;
4002 if (GetPersistentBindingFunc != NULL) {
4003 status = ((GetPersistentBindingFunc)(vendorHandle,
4004 hbaPortWWN, domainPortWWN, binding));
4005 } else {
4006 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4007 }
4008 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4009 }
4010
4011 HBA_STATUS
4012 SMHBA_SetPersistentBinding(
4013 HBA_HANDLE handle,
4014 HBA_WWN hbaPortWWN,
4015 HBA_WWN domainPortWWN,
4016 const SMHBA_BINDING *binding)
4017 {
4018 HBA_STATUS status;
4019 HBA_LIBRARY_INFO *lib_infop;
4020 HBA_HANDLE vendorHandle;
4021 SMHBASetPersistentBindingFunc
4022 SetPersistentBindingFunc;
4023
4024 DEBUG(2, "SMHBA_SetPersistentBinding port WWN: %s",
4025 WWN2STR1(&hbaPortWWN), 0, 0);
4026
4027 CHECKLIBRARYANDVERSION(SMHBA);
4028
4029 SetPersistentBindingFunc =
4030 lib_infop->ftable.smhbafunctionTable.SetPersistentBindingHandler;
4031 if (SetPersistentBindingFunc != NULL) {
4032 status = ((SetPersistentBindingFunc)(vendorHandle,
4033 hbaPortWWN, domainPortWWN, binding));
4034 } else {
4035 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4036 }
4037 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4038 }
4039
4040 HBA_STATUS
4041 SMHBA_RemovePersistentBinding(
4042 HBA_HANDLE handle,
4043 HBA_WWN hbaPortWWN,
4044 HBA_WWN domainPortWWN,
4045 const SMHBA_BINDING *binding)
4046 {
4047 HBA_STATUS status;
4048 HBA_LIBRARY_INFO *lib_infop;
4049 HBA_HANDLE vendorHandle;
4050 SMHBARemovePersistentBindingFunc
4051 RemovePersistentBindingFunc;
4052
4053 DEBUG(2, "SMHBA_RemovePersistentBinding port WWN: %s",
4054 WWN2STR1(&hbaPortWWN), 0, 0);
4055
4056 CHECKLIBRARYANDVERSION(SMHBA);
4057
4058 RemovePersistentBindingFunc =
4059 lib_infop->ftable.smhbafunctionTable.RemovePersistentBindingHandler;
4060 if (RemovePersistentBindingFunc != NULL) {
4061 status = ((RemovePersistentBindingFunc)(vendorHandle,
4062 hbaPortWWN, domainPortWWN, binding));
4063 } else {
4064 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4065 }
4066 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4067 }
4068
4069 HBA_STATUS
4070 SMHBA_RemoveAllPersistentBindings(
4071 HBA_HANDLE handle,
4072 HBA_WWN hbaPortWWN,
4073 HBA_WWN domainPortWWN)
4074 {
4075 HBA_STATUS status;
4076 HBA_LIBRARY_INFO *lib_infop;
4077 HBA_HANDLE vendorHandle;
4078 SMHBARemoveAllPersistentBindingsFunc
4079 RemoveAllPersistentBindingsFunc;
4080
4081 DEBUG(2, "SMHBA_RemoveAllPersistentBinding port WWN: %s",
4082 WWN2STR1(&hbaPortWWN), 0, 0);
4083
4084 CHECKLIBRARYANDVERSION(SMHBA);
4085
4086 RemoveAllPersistentBindingsFunc =
4087 lib_infop->ftable.smhbafunctionTable.\
4088 RemoveAllPersistentBindingsHandler;
4089 if (RemoveAllPersistentBindingsFunc != NULL) {
4090 status = ((RemoveAllPersistentBindingsFunc)(vendorHandle,
4091 hbaPortWWN, domainPortWWN));
4092 } else {
4093 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4094 }
4095 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4096 }
4097
4098 HBA_STATUS
4099 SMHBA_GetLUNStatistics(
4100 HBA_HANDLE handle,
4101 const HBA_SCSIID *lunit,
4102 SMHBA_PROTOCOLSTATISTICS *statistics)
4103 {
4104 HBA_STATUS status;
4105 HBA_LIBRARY_INFO *lib_infop;
4106 HBA_HANDLE vendorHandle;
4107 SMHBAGetLUNStatisticsFunc GetLUNStatisticsFunc;
4108
4109 DEBUG(2, "SMHBA_GetLUNStatistics", 0, 0, 0);
4110
4111 CHECKLIBRARYANDVERSION(SMHBA);
4112
4113 GetLUNStatisticsFunc =
4114 lib_infop->ftable.smhbafunctionTable.GetLUNStatisticsHandler;
4115 if (GetLUNStatisticsFunc != NULL) {
4116 status = ((GetLUNStatisticsFunc)(vendorHandle, lunit, statistics));
4117 } else {
4118 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4119 }
4120 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4121 }
4122
4123 HBA_STATUS
4124 SMHBA_ScsiInquiry(
4125 HBA_HANDLE handle,
4126 HBA_WWN hbaPortWWN,
4127 HBA_WWN discoveredPortWWN,
4128 HBA_WWN domainPortWWN,
4129 SMHBA_SCSILUN smhbaLUN,
4130 HBA_UINT8 CDB_Byte1,
4131 HBA_UINT8 CDB_Byte2,
4132 void *pRspBuffer,
4133 HBA_UINT32 *pRspBufferSize,
4134 HBA_UINT8 *pScsiStatus,
4135 void *pSenseBuffer,
4136 HBA_UINT32 *pSenseBufferSize)
4137 {
4138 HBA_STATUS status;
4139 HBA_LIBRARY_INFO *lib_infop;
4140 HBA_HANDLE vendorHandle;
4141 SMHBAScsiInquiryFunc ScsiInquiryFunc;
4142
4143 DEBUG(2, "SMHBA_ScsiInquiry to hba port: %s discoveredPortWWN: %s",
4144 WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0);
4145
4146 CHECKLIBRARYANDVERSION(SMHBA);
4147
4148 ScsiInquiryFunc =
4149 lib_infop->ftable.smhbafunctionTable.ScsiInquiryHandler;
4150 if (ScsiInquiryFunc != NULL) {
4151 status = ((ScsiInquiryFunc)(
4152 vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN,
4153 smhbaLUN, CDB_Byte1, CDB_Byte2, pRspBuffer, pRspBufferSize,
4154 pScsiStatus, pSenseBuffer, pSenseBufferSize));
4155 } else {
4156 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4157 }
4158 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4159 }
4160
4161 HBA_STATUS
4162 SMHBA_ScsiReportLUNs(
4163 HBA_HANDLE handle,
4164 HBA_WWN hbaPortWWN,
4165 HBA_WWN discoveredPortWWN,
4166 HBA_WWN domainPortWWN,
4167 void *pRspBuffer,
4168 HBA_UINT32 *pRspBufferSize,
4169 HBA_UINT8 *pScsiStatus,
4170 void *pSenseBuffer,
4171 HBA_UINT32 *pSenseBufferSize)
4172 {
4173 HBA_STATUS status;
4174 HBA_LIBRARY_INFO *lib_infop;
4175 HBA_HANDLE vendorHandle;
4176 SMHBAScsiReportLUNsFunc ScsiReportLUNsFunc;
4177
4178 DEBUG(2, "SMHBA_ScsiReportLuns to hba port: %s discoveredPortWWN: %s",
4179 WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0);
4180
4181 CHECKLIBRARYANDVERSION(SMHBA);
4182
4183 ScsiReportLUNsFunc =
4184 lib_infop->ftable.smhbafunctionTable.ScsiReportLUNsHandler;
4185 if (ScsiReportLUNsFunc != NULL) {
4186 status = ((ScsiReportLUNsFunc)(
4187 vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN,
4188 pRspBuffer, pRspBufferSize, pScsiStatus, pSenseBuffer,
4189 pSenseBufferSize));
4190 } else {
4191 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4192 }
4193 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4194 }
4195
4196 HBA_STATUS
4197 SMHBA_ScsiReadCapacity(
4198 HBA_HANDLE handle,
4199 HBA_WWN hbaPortWWN,
4200 HBA_WWN discoveredPortWWN,
4201 HBA_WWN domainPortWWN,
4202 SMHBA_SCSILUN smhbaLUN,
4203 void *pRspBuffer,
4204 HBA_UINT32 *pRspBufferSize,
4205 HBA_UINT8 *pScsiStatus,
4206 void *pSenseBuffer,
4207 HBA_UINT32 *pSenseBufferSize)
4208 {
4209 HBA_STATUS status;
4210 HBA_LIBRARY_INFO *lib_infop;
4211 HBA_HANDLE vendorHandle;
4212 SMHBAScsiReadCapacityFunc ScsiReadCapacityFunc;
4213
4214 DEBUG(2, "SMHBA_ScsiReadCapacity to hba port: %s discoveredPortWWN: %s",
4215 WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0);
4216
4217 CHECKLIBRARYANDVERSION(SMHBA);
4218
4219 ScsiReadCapacityFunc =
4220 lib_infop->ftable.smhbafunctionTable.ScsiReadCapacityHandler;
4221 if (ScsiReadCapacityFunc != NULL) {
4222 status = ((ScsiReadCapacityFunc)(
4223 vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN,
4224 smhbaLUN, pRspBuffer, pRspBufferSize, pScsiStatus, pSenseBuffer,
4225 pSenseBufferSize));
4226 } else {
4227 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4228 }
4229 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4230 }
4231
4232 HBA_STATUS
4233 SMHBA_SendTEST(
4234 HBA_HANDLE handle,
4235 HBA_WWN hbaPortWWN,
4236 HBA_WWN destWWN,
4237 HBA_UINT32 destFCID,
4238 void *pRspBuffer,
4239 HBA_UINT32 pRspBufferSize)
4240 {
4241 HBA_STATUS status;
4242 HBA_LIBRARY_INFO *lib_infop;
4243 HBA_HANDLE vendorHandle;
4244 SMHBASendTESTFunc SendTESTFunc;
4245
4246 DEBUG(2, "SMHBA_SendTEST, hbaPortWWN: %s destWWN",
4247 WWN2STR1(&hbaPortWWN),
4248 WWN2STR1(&destWWN), 0);
4249
4250 CHECKLIBRARYANDVERSION(SMHBA);
4251
4252 SendTESTFunc = lib_infop->ftable.smhbafunctionTable.SendTESTHandler;
4253 if (SendTESTFunc != NULL) {
4254 status = (SendTESTFunc)
4255 (vendorHandle, hbaPortWWN, destWWN, destFCID,
4256 pRspBuffer, pRspBufferSize);
4257 } else {
4258 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4259 }
4260 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4261 }
4262
4263 HBA_STATUS
4264 SMHBA_SendECHO(
4265 HBA_HANDLE handle,
4266 HBA_WWN hbaPortWWN,
4267 HBA_WWN destWWN,
4268 HBA_UINT32 destFCID,
4269 void *pReqBuffer,
4270 HBA_UINT32 ReqBufferSize,
4271 void *pRspBuffer,
4272 HBA_UINT32 *pRspBufferSize)
4273 {
4274 HBA_STATUS status;
4275 HBA_LIBRARY_INFO *lib_infop;
4276 HBA_HANDLE vendorHandle;
4277 SMHBASendECHOFunc SendECHOFunc;
4278
4279 DEBUG(2, "SMHBA_SendECHO, hbaPortWWN: %s destWWN",
4280 WWN2STR1(&hbaPortWWN), WWN2STR1(&destWWN), 0);
4281
4282 CHECKLIBRARYANDVERSION(SMHBA);
4283
4284 SendECHOFunc = lib_infop->ftable.smhbafunctionTable.SendECHOHandler;
4285 if (SendECHOFunc != NULL) {
4286 status = (SendECHOFunc)
4287 (vendorHandle, hbaPortWWN, destWWN, destFCID,
4288 pReqBuffer, ReqBufferSize, pRspBuffer, pRspBufferSize);
4289 } else {
4290 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4291 }
4292 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4293 }
4294
4295 HBA_STATUS
4296 SMHBA_SendSMPPassThru(
4297 HBA_HANDLE handle,
4298 HBA_WWN hbaPortWWN,
4299 HBA_WWN destWWN,
4300 HBA_WWN domainPortWWN,
4301 void *pReqBuffer,
4302 HBA_UINT32 ReqBufferSize,
4303 void *pRspBuffer,
4304 HBA_UINT32 *pRspBufferSize)
4305 {
4306 HBA_STATUS status;
4307 HBA_LIBRARY_INFO *lib_infop;
4308 HBA_HANDLE vendorHandle;
4309 SMHBASendSMPPassThruFunc SendSMPPassThruFunc;
4310
4311 DEBUG(2, "SMHBA_SendSMPPassThru, hbaPortWWN: %s destWWN: %s",
4312 WWN2STR1(&hbaPortWWN), WWN2STR1(&destWWN), 0);
4313
4314 CHECKLIBRARYANDVERSION(SMHBA);
4315
4316 SendSMPPassThruFunc = lib_infop->ftable.\
4317 smhbafunctionTable.SendSMPPassThruHandler;
4318
4319 if (SendSMPPassThruFunc != NULL) {
4320 status = (SendSMPPassThruFunc)
4321 (vendorHandle, hbaPortWWN, destWWN, domainPortWWN,
4322 pReqBuffer, ReqBufferSize, pRspBuffer, pRspBufferSize);
4323 } else {
4324 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4325 }
4326 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4327 }
4328
4329 /*
4330 * Following the similar logic of HBAAPI addaspterevents_callback.
4331 *
4332 * Unlike other events Adapter Add Event is not limited to a specific
4333 * adapter(i.e. no adapter handle is passed for registration) so
4334 * the event should be passed to all registrants. The routine below
4335 * is passed to the VSLs as a callback and when Adapter Add event is detected
4336 * by VSL it will call smhba_adapteraddevents_callback() which in turn check
4337 * if the passed userdata ptr matches with the one stored in the callback list
4338 * and calls the stored callback.
4339 *
4340 * For the situation that multiple clients are registered for Adapter Add event
4341 * each registration is passed to VSLs so VSL may call
4342 * smhba_adapteraddevents_callback() multiple times or it may call only once
4343 * since the callback function is same. For this implemneation, the userdata
4344 * is stored in HBA_ALLADAPTERSCALLBACK_ELEM so it is expected that VSL call
4345 * smhba_adapteraddevents_callback() only once and
4346 * smhba_adapteraddevents_callback() will call the client callback with proper
4347 * userdata.
4348 */
4349 static void
4350 smhba_adapteraddevents_callback(
4351 /* LINTED E_FUNC_ARG_UNUSED */
4352 void *data,
4353 HBA_WWN PortWWN,
4354 /* LINTED E_FUNC_ARG_UNUSED */
4355 HBA_UINT32 eventType)
4356 {
4357 HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
4358
4359 DEBUG(3, "AddAdapterEvent, port:%s", WWN2STR1(&PortWWN), 0, 0);
4360
4361 GRAB_MUTEX(&_smhba_AAE_mutex);
4362 for (cbp = _smhba_adapteraddevents_callback_list;
4363 cbp != NULL;
4364 cbp = cbp->next) {
4365 (*cbp->callback)(cbp->userdata, PortWWN, HBA_EVENT_ADAPTER_ADD);
4366 }
4367 RELEASE_MUTEX(&_smhba_AAE_mutex);
4368
4369 }
4370
4371 HBA_STATUS
4372 SMHBA_RegisterForAdapterAddEvents(
4373 void (*pCallback) (
4374 void *data,
4375 HBA_WWN PortWWN,
4376 HBA_UINT32 eventType),
4377 void *pUserData,
4378 HBA_CALLBACKHANDLE *pCallbackHandle) {
4379
4380 HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
4381 HBA_VENDORCALLBACK_ELEM *vcbp;
4382 HBA_VENDORCALLBACK_ELEM *vendorhandlelist;
4383 SMHBARegisterForAdapterAddEventsFunc registeredfunc;
4384 HBA_STATUS status = HBA_STATUS_OK;
4385 HBA_STATUS failure = HBA_STATUS_OK;
4386 HBA_LIBRARY_INFO *lib_infop;
4387 int registered_cnt = 0;
4388 int vendor_cnt = 0;
4389 int not_supported_cnt = 0;
4390 int status_OK_bar_cnt = 0;
4391 int status_OK_cnt = 0;
4392
4393 DEBUG(2, "SMHBA_RegisterForAdapterAddEvents", 0, 0, 0);
4394 ARE_WE_INITED();
4395
4396 cbp = (HBA_ALLADAPTERSCALLBACK_ELEM *)
4397 calloc(1, sizeof (HBA_ALLADAPTERSCALLBACK_ELEM));
4398 *pCallbackHandle = (HBA_CALLBACKHANDLE) cbp;
4399 if (cbp == NULL) {
4400 return (HBA_STATUS_ERROR);
4401 }
4402
4403 GRAB_MUTEX(&_hbaapi_LL_mutex);
4404 GRAB_MUTEX(&_smhba_AAE_mutex);
4405 cbp->callback = pCallback;
4406 cbp->userdata = pUserData;
4407 cbp->next = _smhba_adapteraddevents_callback_list;
4408 _smhba_adapteraddevents_callback_list = cbp;
4409
4410 /*
4411 * Need to release the mutex now incase the vendor function invokes the
4412 * callback. We will grap the mutex later to attach the vendor handle
4413 * list to the callback structure
4414 */
4415 RELEASE_MUTEX(&_smhba_AAE_mutex);
4416
4417
4418 /*
4419 * now create a list of vendors (vendor libraryies, NOT ADAPTERS)
4420 * that have successfully registerred
4421 */
4422 vendorhandlelist = NULL;
4423 for (lib_infop = _hbaapi_librarylist;
4424 lib_infop != NULL;
4425 lib_infop = lib_infop->next) {
4426
4427 /* only for HBAAPI V2 */
4428 if (lib_infop->version != SMHBA) {
4429 continue;
4430 } else {
4431 vendor_cnt++;
4432 }
4433
4434 registeredfunc =
4435 lib_infop->ftable.smhbafunctionTable.\
4436 RegisterForAdapterAddEventsHandler;
4437 if (registeredfunc == NULL) {
4438 continue;
4439 }
4440
4441 vcbp = (HBA_VENDORCALLBACK_ELEM *)
4442 calloc(1, sizeof (HBA_VENDORCALLBACK_ELEM));
4443 if (vcbp == NULL) {
4444 freevendorhandlelist(vendorhandlelist);
4445 status = HBA_STATUS_ERROR;
4446 break;
4447 }
4448
4449 registered_cnt++;
4450 status = (registeredfunc)(smhba_adapteraddevents_callback,
4451 pUserData, &vcbp->vendorcbhandle);
4452 if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
4453 not_supported_cnt++;
4454 free(vcbp);
4455 continue;
4456 } else if (status != HBA_STATUS_OK) {
4457 status_OK_bar_cnt++;
4458 DEBUG(1,
4459 "SMHBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
4460 lib_infop->LibraryPath, status, 0);
4461 failure = status;
4462 free(vcbp);
4463 continue;
4464 } else {
4465 status_OK_cnt++;
4466 }
4467 vcbp->lib_info = lib_infop;
4468 vcbp->next = vendorhandlelist;
4469 vendorhandlelist = vcbp;
4470 }
4471
4472 if (vendor_cnt == 0) {
4473 /* no SMHBA VSL found. Should be okay?? */
4474 status = HBA_STATUS_ERROR;
4475 } else if (registered_cnt == 0) {
4476 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4477 freevendorhandlelist(vendorhandlelist);
4478 (void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
4479 } else if (status_OK_cnt == 0 && not_supported_cnt != 0) {
4480 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
4481 } else if (status_OK_cnt == 0) {
4482 /*
4483 * At least one vendor library registered this function, but no
4484 * vendor call succeeded
4485 */
4486 (void) local_remove_callback((HBA_CALLBACKHANDLE) cbp);
4487 status = failure;
4488 } else {
4489 /* we have had atleast some success, now finish up */
4490 GRAB_MUTEX(&_smhba_AAE_mutex);
4491 /*
4492 * this seems silly, but what if another thread called
4493 * the callback remove
4494 */
4495 for (cbp = _smhba_adapteraddevents_callback_list;
4496 cbp != NULL; cbp = cbp->next) {
4497 if ((HBA_CALLBACKHANDLE)cbp == *pCallbackHandle) {
4498 /* yup, its still there, hooray */
4499 cbp->vendorhandlelist = vendorhandlelist;
4500 vendorhandlelist = NULL;
4501 break;
4502 }
4503 }
4504 RELEASE_MUTEX(&_smhba_AAE_mutex);
4505 if (vendorhandlelist != NULL) {
4506 /*
4507 * bummer, somebody removed the callback before we finished
4508 * registration, probably will never happen
4509 */
4510 freevendorhandlelist(vendorhandlelist);
4511 DEBUG(1,
4512 "HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was "
4513 "called for a handle before registration was finished.",
4514 0, 0, 0);
4515 status = HBA_STATUS_ERROR;
4516 } else {
4517 status = HBA_STATUS_OK;
4518 }
4519 }
4520 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4521 }
4522
4523 /* SMHBA Adapter Events (other than add) ******************************** */
4524 static void
4525 smhba_adapterevents_callback(void *data,
4526 HBA_WWN PortWWN,
4527 HBA_UINT32 eventType)
4528 {
4529 HBA_ADAPTERCALLBACK_ELEM *acbp;
4530
4531 DEBUG(3, "AdapterEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN),
4532 eventType, 0);
4533
4534 GRAB_MUTEX(&_hbaapi_AE_mutex);
4535 for (acbp = _smhba_adapterevents_callback_list;
4536 acbp != NULL;
4537 acbp = acbp->next) {
4538 if (data == (void *)acbp) {
4539 (*acbp->callback)(acbp->userdata, PortWWN, eventType);
4540 break;
4541 }
4542 }
4543 RELEASE_MUTEX(&_hbaapi_AE_mutex);
4544 }
4545
4546 HBA_STATUS
4547 SMHBA_RegisterForAdapterEvents(
4548 void (*pCallback) (
4549 void *data,
4550 HBA_WWN PortWWN,
4551 HBA_UINT32 eventType),
4552 void *pUserData,
4553 HBA_HANDLE handle,
4554 HBA_CALLBACKHANDLE *pCallbackHandle) {
4555
4556 HBA_ADAPTERCALLBACK_ELEM *acbp;
4557 SMHBARegisterForAdapterEventsFunc registeredfunc;
4558 HBA_STATUS status;
4559 HBA_LIBRARY_INFO *lib_infop;
4560 HBA_HANDLE vendorHandle;
4561
4562 DEBUG(2, "SMHBA_RegisterForAdapterEvents", 0, 0, 0);
4563
4564 CHECKLIBRARYANDVERSION(SMHBA);
4565
4566 /* we now have the _hbaapi_LL_mutex */
4567
4568 registeredfunc = lib_infop->ftable.smhbafunctionTable.\
4569 RegisterForAdapterEventsHandler;
4570 if (registeredfunc == NULL) {
4571 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
4572 }
4573
4574 /*
4575 * that allocated memory is used both as the handle for the
4576 * caller, and as userdata to the vendor call so that on
4577 * callback the specific registration may be recalled
4578 */
4579 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
4580 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
4581 if (acbp == NULL) {
4582 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
4583 }
4584 *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
4585 acbp->callback = pCallback;
4586 acbp->userdata = pUserData;
4587 acbp->lib_info = lib_infop;
4588
4589 status = (registeredfunc)(smhba_adapterevents_callback,
4590 (void *)acbp,
4591 vendorHandle,
4592 &acbp->vendorcbhandle);
4593 if (status != HBA_STATUS_OK) {
4594 free(acbp);
4595 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4596 }
4597
4598 GRAB_MUTEX(&_smhba_AE_mutex);
4599 acbp->next = _smhba_adapterevents_callback_list;
4600 _hbaapi_adapterevents_callback_list = acbp;
4601
4602 RELEASE_MUTEX(&_smhba_AE_mutex);
4603 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
4604 }
4605
4606 /* Adapter Port Events *********************************************** */
4607 static void
4608 smhba_adapterportevents_callback(void *data,
4609 HBA_WWN PortWWN,
4610 HBA_UINT32 eventType,
4611 HBA_UINT32 fabricPortID)
4612 {
4613 HBA_ADAPTERCALLBACK_ELEM *acbp;
4614
4615 DEBUG(3,
4616 "SMHBA_AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x",
4617 WWN2STR1(&PortWWN), eventType, fabricPortID);
4618
4619 GRAB_MUTEX(&_smhba_APE_mutex);
4620
4621 for (acbp = _smhba_adapterportevents_callback_list;
4622 acbp != NULL;
4623 acbp = acbp->next) {
4624 if (data == (void *)acbp) {
4625 (*acbp->callback)(acbp->userdata, PortWWN,
4626 eventType, fabricPortID);
4627 break;
4628 }
4629 }
4630 RELEASE_MUTEX(&_smhba_APE_mutex);
4631 }
4632
4633 HBA_STATUS
4634 SMHBA_RegisterForAdapterPortEvents(
4635 void (*pCallback) (
4636 void *pData,
4637 HBA_WWN PortWWN,
4638 HBA_UINT32 eventType,
4639 HBA_UINT32 fabricPortID),
4640 void *pUserData,
4641 HBA_HANDLE handle,
4642 HBA_WWN portWWN,
4643 HBA_UINT32 specificEventType,
4644 HBA_CALLBACKHANDLE *pCallbackHandle) {
4645
4646 HBA_ADAPTERCALLBACK_ELEM *acbp;
4647 SMHBARegisterForAdapterPortEventsFunc registeredfunc;
4648 HBA_STATUS status;
4649 HBA_LIBRARY_INFO *lib_infop;
4650 HBA_HANDLE vendorHandle;
4651
4652 DEBUG(2, "SMHBA_RegisterForAdapterPortEvents for port: %s",
4653 WWN2STR1(&portWWN), 0, 0);
4654
4655 CHECKLIBRARYANDVERSION(SMHBA);
4656 /* we now have the _hbaapi_LL_mutex */
4657
4658 registeredfunc =
4659 lib_infop->ftable.smhbafunctionTable.\
4660 RegisterForAdapterPortEventsHandler;
4661 if (registeredfunc == NULL) {
4662 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
4663 }
4664
4665 /*
4666 * that allocated memory is used both as the handle for the
4667 * caller, and as userdata to the vendor call so that on
4668 * callback the specific registration may be recalled
4669 */
4670 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
4671 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
4672 if (acbp == NULL) {
4673 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
4674 }
4675 *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
4676 acbp->callback = pCallback;
4677 acbp->userdata = pUserData;
4678 acbp->lib_info = lib_infop;
4679
4680 status = (registeredfunc)(smhba_adapterportevents_callback,
4681 (void *)acbp,
4682 vendorHandle,
4683 portWWN,
4684 specificEventType,
4685 &acbp->vendorcbhandle);
4686 if (status != HBA_STATUS_OK) {
4687 free(acbp);
4688 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4689 }
4690
4691 GRAB_MUTEX(&_smhba_APE_mutex);
4692 acbp->next = _smhba_adapterportevents_callback_list;
4693 _smhba_adapterportevents_callback_list = acbp;
4694
4695 RELEASE_MUTEX(&_smhba_APE_mutex);
4696 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
4697 }
4698
4699 /* SMHBA Adapter Port Stat Events ******************************** */
4700 static void
4701 smhba_adapterportstatevents_callback(void *data,
4702 HBA_WWN portWWN,
4703 HBA_UINT32 protocolType,
4704 HBA_UINT32 eventType)
4705 {
4706 HBA_ADAPTERCALLBACK_ELEM *acbp;
4707
4708 DEBUG(3,
4709 "SMBA_AdapterPortStateEvent, port:%s, eventType:%d",
4710 WWN2STR1(&portWWN), eventType, 0);
4711
4712 GRAB_MUTEX(&_smhba_APSE_mutex);
4713 for (acbp = _smhba_adapterportstatevents_callback_list;
4714 acbp != NULL;
4715 acbp = acbp->next) {
4716 if (data == (void *)acbp) {
4717 (*acbp->callback)(acbp->userdata, portWWN,
4718 protocolType, eventType);
4719 return;
4720 }
4721 }
4722 RELEASE_MUTEX(&_smhba_APSE_mutex);
4723 }
4724
4725 HBA_STATUS
4726 SMHBA_RegisterForAdapterPortStatEvents(
4727 void (*pCallback) (
4728 void *pData,
4729 HBA_WWN portWWN,
4730 HBA_UINT32 protocolType,
4731 HBA_UINT32 eventType),
4732 void *pUserData,
4733 HBA_HANDLE handle,
4734 HBA_WWN portWWN,
4735 HBA_UINT32 protocolType,
4736 SMHBA_PROTOCOLSTATISTICS stats,
4737 HBA_UINT32 statType,
4738 HBA_CALLBACKHANDLE *pCallbackHandle) {
4739
4740 HBA_ADAPTERCALLBACK_ELEM *acbp;
4741 SMHBARegisterForAdapterPortStatEventsFunc
4742 registeredfunc;
4743 HBA_STATUS status;
4744 HBA_LIBRARY_INFO *lib_infop;
4745 HBA_HANDLE vendorHandle;
4746
4747 DEBUG(2, "SMHBA_RegisterForAdapterPortStatEvents for port: %s",
4748 WWN2STR1(&portWWN), 0, 0);
4749
4750 CHECKLIBRARYANDVERSION(SMHBA);
4751 /* we now have the _hbaapi_LL_mutex */
4752
4753 registeredfunc =
4754 lib_infop->ftable.smhbafunctionTable.\
4755 RegisterForAdapterPortStatEventsHandler;
4756 if (registeredfunc == NULL) {
4757 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
4758 }
4759
4760 /*
4761 * that allocated memory is used both as the handle for the
4762 * caller, and as userdata to the vendor call so that on
4763 * callback the specific registration may be recalled
4764 */
4765 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
4766 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
4767 if (acbp == NULL) {
4768 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
4769 }
4770 *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
4771 acbp->callback = pCallback;
4772 acbp->userdata = pUserData;
4773 acbp->lib_info = lib_infop;
4774
4775 status = (registeredfunc)(smhba_adapterportstatevents_callback,
4776 (void *)acbp,
4777 vendorHandle,
4778 portWWN,
4779 protocolType,
4780 stats,
4781 statType,
4782 &acbp->vendorcbhandle);
4783 if (status != HBA_STATUS_OK) {
4784 free(acbp);
4785 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4786 }
4787
4788 GRAB_MUTEX(&_smhba_APSE_mutex);
4789 acbp->next = _smhba_adapterportstatevents_callback_list;
4790 _smhba_adapterportstatevents_callback_list = acbp;
4791
4792 RELEASE_MUTEX(&_smhba_APSE_mutex);
4793 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
4794 }
4795
4796 /* SMHBA Adapter Port Phy Stat Events ************************************ */
4797 static void
4798 smhba_adapterphystatevents_callback(void *data,
4799 HBA_WWN portWWN,
4800 HBA_UINT32 phyIndex,
4801 HBA_UINT32 eventType)
4802 {
4803 HBA_ADAPTERCALLBACK_ELEM *acbp;
4804
4805 DEBUG(3,
4806 "SMBA_AdapterPortStateEvent, port:%s, eventType:%d",
4807 WWN2STR1(&portWWN), eventType, 0);
4808
4809 GRAB_MUTEX(&_smhba_APHYSE_mutex);
4810 for (acbp = _smhba_adapterphystatevents_callback_list;
4811 acbp != NULL;
4812 acbp = acbp->next) {
4813 if (data == (void *)acbp) {
4814 (*acbp->callback)(acbp->userdata, portWWN, phyIndex, eventType);
4815 return;
4816 }
4817 }
4818 RELEASE_MUTEX(&_smhba_APHYSE_mutex);
4819 }
4820
4821 HBA_STATUS
4822 SMHBA_RegisterForAdapterPhyStatEvents(
4823 void (*pCallback) (
4824 void *pData,
4825 HBA_WWN portWWN,
4826 HBA_UINT32 phyIndex,
4827 HBA_UINT32 eventType),
4828 void *pUserData,
4829 HBA_HANDLE handle,
4830 HBA_WWN portWWN,
4831 HBA_UINT32 phyIndex,
4832 SMHBA_PHYSTATISTICS stats,
4833 HBA_UINT32 statType,
4834 HBA_CALLBACKHANDLE *pCallbackHandle) {
4835
4836 HBA_ADAPTERCALLBACK_ELEM *acbp;
4837 SMHBARegisterForAdapterPhyStatEventsFunc
4838 registeredfunc;
4839 HBA_STATUS status;
4840 HBA_LIBRARY_INFO *lib_infop;
4841 HBA_HANDLE vendorHandle;
4842
4843 DEBUG(2, "SMHBA_RegisterForAdapterPhyStatEvents for port: %s",
4844 WWN2STR1(&portWWN), 0, 0);
4845
4846 CHECKLIBRARYANDVERSION(SMHBA);
4847 /* we now have the _hbaapi_LL_mutex */
4848
4849 registeredfunc =
4850 lib_infop->ftable.smhbafunctionTable.\
4851 RegisterForAdapterPhyStatEventsHandler;
4852 if (registeredfunc == NULL) {
4853 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
4854 }
4855
4856 /*
4857 * that allocated memory is used both as the handle for the
4858 * caller, and as userdata to the vendor call so that on
4859 * callback the specific registration may be recalled
4860 */
4861 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
4862 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
4863 if (acbp == NULL) {
4864 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
4865 }
4866 *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
4867 acbp->callback = pCallback;
4868 acbp->userdata = pUserData;
4869 acbp->lib_info = lib_infop;
4870
4871 status = (registeredfunc)(smhba_adapterphystatevents_callback,
4872 (void *)acbp,
4873 vendorHandle,
4874 portWWN,
4875 phyIndex,
4876 stats,
4877 statType,
4878 &acbp->vendorcbhandle);
4879 if (status != HBA_STATUS_OK) {
4880 free(acbp);
4881 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4882 }
4883
4884 GRAB_MUTEX(&_smhba_APHYSE_mutex);
4885 acbp->next = _smhba_adapterphystatevents_callback_list;
4886 _smhba_adapterphystatevents_callback_list = acbp;
4887
4888 RELEASE_MUTEX(&_smhba_APHYSE_mutex);
4889 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
4890 }
4891
4892 /* SMHBA Target Events ********************************************* */
4893 static void
4894 smhba_targetevents_callback(void *data,
4895 HBA_WWN hbaPortWWN,
4896 HBA_WWN discoveredPortWWN,
4897 HBA_WWN domainPortWWN,
4898 HBA_UINT32 eventType)
4899 {
4900 HBA_ADAPTERCALLBACK_ELEM *acbp;
4901
4902 DEBUG(3, "TargetEvent, hbaPort:%s, discoveredPort:%s eventType:%d",
4903 WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), eventType);
4904
4905 GRAB_MUTEX(&_smhba_TE_mutex);
4906 for (acbp = _smhba_targetevents_callback_list;
4907 acbp != NULL;
4908 acbp = acbp->next) {
4909 if (data == (void *)acbp) {
4910 (*acbp->callback)(acbp->userdata, hbaPortWWN,
4911 discoveredPortWWN, domainPortWWN, eventType);
4912 break;
4913 }
4914 }
4915 RELEASE_MUTEX(&_smhba_TE_mutex);
4916 }
4917
4918 HBA_STATUS
4919 SMHBA_RegisterForTargetEvents(
4920 void (*pCallback) (
4921 void *pData,
4922 HBA_WWN hbaPortWWN,
4923 HBA_WWN discoveredPortWWN,
4924 HBA_WWN domainPortWWN,
4925 HBA_UINT32 eventType),
4926 void *pUserData,
4927 HBA_HANDLE handle,
4928 HBA_WWN hbaPortWWN,
4929 HBA_WWN discoveredPortWWN,
4930 HBA_WWN domainPortWWN,
4931 HBA_CALLBACKHANDLE *pCallbackHandle,
4932 HBA_UINT32 allTargets) {
4933
4934 HBA_ADAPTERCALLBACK_ELEM *acbp;
4935 SMHBARegisterForTargetEventsFunc
4936 registeredfunc;
4937 HBA_STATUS status;
4938 HBA_LIBRARY_INFO *lib_infop;
4939 HBA_HANDLE vendorHandle;
4940
4941 DEBUG(2, "SMHBA_RegisterForTargetEvents, hbaPort:"
4942 "%s, discoveredPort: %s",
4943 WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), 0);
4944
4945 CHECKLIBRARYANDVERSION(SMHBA);
4946 /* we now have the _hbaapi_LL_mutex */
4947
4948 registeredfunc = lib_infop->ftable.smhbafunctionTable.\
4949 RegisterForTargetEventsHandler;
4950
4951 if (registeredfunc == NULL) {
4952 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
4953 }
4954
4955 /*
4956 * that allocated memory is used both as the handle for the
4957 * caller, and as userdata to the vendor call so that on
4958 * callback the specific registration may be recalled
4959 */
4960 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
4961 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM));
4962 if (acbp == NULL) {
4963 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
4964 }
4965 *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp;
4966 acbp->callback = pCallback;
4967 acbp->userdata = pUserData;
4968 acbp->lib_info = lib_infop;
4969
4970 status = (registeredfunc)(smhba_targetevents_callback,
4971 (void *)acbp,
4972 vendorHandle,
4973 hbaPortWWN,
4974 discoveredPortWWN,
4975 domainPortWWN,
4976 &acbp->vendorcbhandle,
4977 allTargets);
4978 if (status != HBA_STATUS_OK) {
4979 free(acbp);
4980 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
4981 }
4982
4983 GRAB_MUTEX(&_smhba_TE_mutex);
4984 acbp->next = _smhba_targetevents_callback_list;
4985 _smhba_targetevents_callback_list = acbp;
4986
4987 RELEASE_MUTEX(&_smhba_TE_mutex);
4988 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
4989 }