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