Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / lib / hbaapi / common / HBAAPILIB.c
blobd0e3e31b0e60ecdb1546a2bd7e384d090a70fc1b
1 /*************************************************************************
2 * Description
3 * HBAAPILIB.c - Implements a sample common (wrapper) HBA API library
5 * License:
6 * The contents of this file are subject to the SNIA Public License
7 * Version 1.0 (the "License"); you may not use this file except in
8 * compliance with the License. You may obtain a copy of the License at
10 * /http://www.snia.org/English/Resources/Code/OpenSource.html
12 * Software distributed under the License is distributed on an "AS IS"
13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14 * the License for the specific language governing rights and limitations
15 * under the License.
17 * The Original Code is SNIA HBA API Wrapper Library
19 * The Initial Developer of the Original Code is:
20 * Benjamin F. Kuo, Troika Networks, Inc. (benk@troikanetworks.com)
22 * Contributor(s):
23 * Tuan Lam, QLogic Corp. (t_lam@qlc.com)
24 * Dan Willie, Emulex Corp. (Dan.Willie@emulex.com)
25 * Dixon Hutchinson, Legato Systems, Inc. (dhutchin@legato.com)
26 * David Dillard, VERITAS Software Corp. (david.dillard@veritas.com)
28 *************************************************************************
31 #ifdef WIN32
32 #include <windows.h>
33 #include <string.h>
35 * Next define forces entry points in the dll to be exported
36 * See hbaapi.h to see what it does.
38 #define HBAAPI_EXPORTS
39 #else
40 #include <dlfcn.h>
41 #include <strings.h>
42 #endif
43 #include <stdio.h>
44 #include <time.h>
45 #include "hbaapi.h"
46 #include "vendorhbaapi.h"
47 #include <stdlib.h>
48 #ifdef USESYSLOG
49 #include <syslog.h>
50 #endif
53 * LIBRARY_NUM is a shortcut to figure out which library we need to call.
54 * The top 16 bits of handle are the library index
56 #define LIBRARY_NUM(handle) ((handle)>>16)
59 * VENDOR_HANDLE turns a global library handle into a vendor specific handle,
60 * with all upper 16 bits set to 0
62 #define VENDOR_HANDLE(handle) ((handle)&0xFFFF)
64 #define HBA_HANDLE_FROM_LOCAL(library, vendor) \
65 (((library)<<16) | ((vendor)&0x0000FFFF))
67 int _hbaapi_debuglevel = 0;
68 #define DEBUG(L, STR, A1, A2, A3)
70 #if defined(USESYSLOG) && defined(USELOGFILE)
71 FILE *_hbaapi_debug_fd = NULL;
72 int _hbaapi_sysloginit = 0;
73 #undef DEBUG
74 #ifdef WIN32
75 #define DEBUG(L, STR, A1, A2, A3)\
76 if ((L) <= _hbaapi_debuglevel) {\
77 if(_hbaapi_sysloginit == 0) {\
78 openlog("HBAAPI", LOG_PID|LOG_ODELAY ,LOG_USER);\
79 _hbaapi_sysloginit = 1;\
81 syslog (LOG_INFO, (STR), (A1), (A2), (A3));\
82 if(_hbaapi_debug_fd == NULL) {\
83 char _logFile[MAX_PATH]; \
84 GetTempPath(MAX_PATH, _logFile); \
85 strcat(_logFile, "HBAAPI.log"); \
86 _hbaapi_debug_fd = fopen(_logFile, "a");\
88 if(_hbaapi_debug_fd != NULL) {\
89 fprintf(_hbaapi_debug_fd, (STR ## "\n"), (A1), (A2), (A3));\
92 #else /* WIN32*/
93 #define DEBUG(L, STR, A1, A2, A3)\
94 if ((L) <= _hbaapi_debuglevel) {\
95 if(_hbaapi_sysloginit == 0) {\
96 openlog("HBAAPI", LOG_PID|LOG_ODELAY ,LOG_USER);\
97 _hbaapi_sysloginit = 1;\
99 syslog (LOG_INFO, (STR), (A1), (A2), (A3));\
100 if(_hbaapi_debug_fd == NULL) {\
101 _hbaapi_debug_fd = fopen("/tmp/HBAAPI.log", "a");\
103 if(_hbaapi_debug_fd != NULL) {\
104 fprintf(_hbaapi_debug_fd, (STR ## "\n"), (A1), (A2), (A3));\
107 #endif /* WIN32*/
109 #else /* Not both USESYSLOG and USELOGFILE */
110 #if defined(USESYSLOG)
111 int _hbaapi_sysloginit = 0;
112 #undef DEBUG
113 #define DEBUG(L, STR, A1, A2, A3) \
114 if ((L) <= _hbaapi_debuglevel) {\
115 if(_hbaapi_sysloginit == 0) {\
116 openlog("HBAAPI", LOG_PID|LOG_ODELAY ,LOG_USER);\
117 _hbaapi_sysloginit = 1;\
119 syslog (LOG_INFO, (STR), (A1), (A2), (A3));\
121 #endif /* USESYSLOG */
122 #if defined(USELOGFILE)
123 FILE *_hbaapi_debug_fd = NULL;
124 #undef DEBUG
125 #ifdef WIN32
126 #define DEBUG(L, STR, A1, A2, A3) \
127 if((L) <= _hbaapi_debuglevel) {\
128 if(_hbaapi_debug_fd == NULL) {\
129 char _logFile[MAX_PATH]; \
130 GetTempPath(MAX_PATH, _logFile); \
131 strcat(_logFile, "HBAAPI.log"); \
132 _hbaapi_debug_fd = fopen(_logFile, "a");\
135 #else /* WIN32 */
136 #define DEBUG(L, STR, A1, A2, A3) \
137 if((L) <= _hbaapi_debuglevel) {\
138 if(_hbaapi_debug_fd == NULL) {\
139 _hbaapi_debug_fd = fopen("/tmp/HBAAPI.log", "a");\
141 if(_hbaapi_debug_fd != NULL) { \
142 fprintf(_hbaapi_debug_fd, (STR) ## "\n", (A1), (A2), (A3));\
145 #endif /* WIN32 */
146 #endif /* USELOGFILE */
147 #endif /* Not both USELOGFILE and USESYSLOG */
149 #ifdef POSIX_THREADS
150 #include <pthread.h>
152 * When multiple mutex's are grabed, they must be always be grabbed in
153 * the same order, or deadlock can result. There are three levels
154 * of mutex's involved in this API. If LL_mutex is grabbed, always grap
155 * it first. If AL_mutex is grabbed, it may not be grabbed before
156 * LL_mutex. If grabbed in a multi grab sequence, the mutex's protecting
157 * the callback lists must always be grabbed last and release before calling
158 * a vendor specific library function that might invoke a callback function
159 * on the same thread.
161 #define GRAB_MUTEX(M) grab_mutex(M)
162 #define RELEASE_MUTEX(M) release_mutex(M)
163 #define RELEASE_MUTEX_RETURN(M,RET) release_mutex(M); return(RET)
164 #elif defined (WIN32)
165 #define GRAB_MUTEX(m) EnterCriticalSection(m)
166 #define RELEASE_MUTEX(m) LeaveCriticalSection(m)
167 #define RELEASE_MUTEX_RETURN(m, RET) LeaveCriticalSection(m); return(RET)
168 #else
169 #define GRAB_MUTEX(M)
170 #define RELEASE_MUTEX(M)
171 #define RELEASE_MUTEX_RETURN(M,RET) return(RET)
172 #endif
175 * Vendor library information
177 typedef enum {
178 HBA_LIBRARY_UNKNOWN,
179 HBA_LIBRARY_LOADED,
180 HBA_LIBRARY_NOT_LOADED
181 } HBA_LIBRARY_STATUS;
183 typedef struct hba_library_info {
184 struct hba_library_info
185 *next;
186 #ifdef WIN32
187 HINSTANCE hLibrary; /* Handle to a loaded DLL */
188 #else
189 char *LibraryName;
190 void* hLibrary; /* Handle to a loaded DLL */
191 #endif
192 char *LibraryPath;
193 HBA_ENTRYPOINTSV2 functionTable; /* Function pointers */
194 HBA_LIBRARY_STATUS status; /* info on this library */
195 HBA_UINT32 index;
196 } HBA_LIBRARY_INFO, *PHBA_LIBRARY_INFO;
198 #define ARE_WE_INITED() \
199 if (_hbaapi_librarylist == NULL) { \
200 return(HBA_STATUS_ERROR); \
202 HBA_LIBRARY_INFO *_hbaapi_librarylist = NULL;
203 HBA_UINT32 _hbaapi_total_library_count = 0;
204 #ifdef POSIX_THREADS
205 pthread_mutex_t _hbaapi_LL_mutex = PTHREAD_MUTEX_INITIALIZER;
206 #elif defined(WIN32)
207 CRITICAL_SECTION _hbaapi_LL_mutex;
208 #endif
211 * Individual adapter (hba) information
213 typedef struct hba_adapter_info {
214 struct hba_adapter_info
215 *next;
216 HBA_STATUS GNstatus; /* status from GetAdapterNameFunc */
217 char *name;
218 HBA_WWN nodeWWN;
219 HBA_LIBRARY_INFO *library;
220 HBA_UINT32 index;
221 } HBA_ADAPTER_INFO;
223 HBA_ADAPTER_INFO *_hbaapi_adapterlist = NULL;
224 HBA_UINT32 _hbaapi_total_adapter_count = 0;
225 #ifdef POSIX_THREADS
226 pthread_mutex_t _hbaapi_AL_mutex = PTHREAD_MUTEX_INITIALIZER;
227 #elif defined(WIN32)
228 CRITICAL_SECTION _hbaapi_AL_mutex;
229 #endif
232 * Call back registration
234 typedef struct hba_vendorcallback_elem {
235 struct hba_vendorcallback_elem
236 *next;
237 HBA_CALLBACKHANDLE vendorcbhandle;
238 HBA_LIBRARY_INFO *lib_info;
239 } HBA_VENDORCALLBACK_ELEM;
242 * Each instance of HBA_ADAPTERCALLBACK_ELEM represents a call to one of
243 * "register" functions that apply to a particular adapter.
244 * HBA_ALLADAPTERSCALLBACK_ELEM is used just for HBA_RegisterForAdapterAddEvents
246 typedef struct hba_adaptercallback_elem {
247 struct hba_adaptercallback_elem
248 *next;
249 HBA_LIBRARY_INFO *lib_info;
250 void *userdata;
251 HBA_CALLBACKHANDLE vendorcbhandle;
252 void (*callback)();
253 } HBA_ADAPTERCALLBACK_ELEM;
255 typedef struct hba_alladapterscallback_elem {
256 struct hba_alladapterscallback_elem
257 *next;
258 void *userdata;
259 HBA_VENDORCALLBACK_ELEM *vendorhandlelist;
260 void (*callback)();
261 } HBA_ALLADAPTERSCALLBACK_ELEM;
263 HBA_ALLADAPTERSCALLBACK_ELEM *_hbaapi_adapteraddevents_callback_list = NULL;
264 HBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterevents_callback_list = NULL;
265 HBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterportevents_callback_list = NULL;
266 HBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterportstatevents_callback_list = NULL;
267 HBA_ADAPTERCALLBACK_ELEM *_hbaapi_targetevents_callback_list = NULL;
268 HBA_ADAPTERCALLBACK_ELEM *_hbaapi_linkevents_callback_list = NULL;
269 HBA_ADAPTERCALLBACK_ELEM *_hbaapi_adapterdeviceevents_callback_list = NULL;
270 #ifdef POSIX_THREADS
271 /* mutex's to protect each list */
272 pthread_mutex_t _hbaapi_AAE_mutex = PTHREAD_MUTEX_INITIALIZER;
273 pthread_mutex_t _hbaapi_AE_mutex = PTHREAD_MUTEX_INITIALIZER;
274 pthread_mutex_t _hbaapi_APE_mutex = PTHREAD_MUTEX_INITIALIZER;
275 pthread_mutex_t _hbaapi_APSE_mutex = PTHREAD_MUTEX_INITIALIZER;
276 pthread_mutex_t _hbaapi_TE_mutex = PTHREAD_MUTEX_INITIALIZER;
277 pthread_mutex_t _hbaapi_LE_mutex = PTHREAD_MUTEX_INITIALIZER;
278 #elif defined(WIN32)
279 CRITICAL_SECTION _hbaapi_AAE_mutex;
280 CRITICAL_SECTION _hbaapi_AE_mutex;
281 CRITICAL_SECTION _hbaapi_APE_mutex;
282 CRITICAL_SECTION _hbaapi_APSE_mutex;
283 CRITICAL_SECTION _hbaapi_TE_mutex;
284 CRITICAL_SECTION _hbaapi_LE_mutex;
285 #endif
287 HBA_ADAPTERCALLBACK_ELEM **cb_lists_array[] = {
288 &_hbaapi_adapterevents_callback_list,
289 &_hbaapi_adapterportevents_callback_list,
290 &_hbaapi_adapterportstatevents_callback_list,
291 &_hbaapi_targetevents_callback_list,
292 &_hbaapi_linkevents_callback_list,
293 &_hbaapi_adapterdeviceevents_callback_list,
294 NULL};
297 * Common library internal. Mutex handling
299 #ifdef POSIX_THREADS
300 static void
301 grab_mutex(pthread_mutex_t *mp) {
302 int ret;
303 if((ret = pthread_mutex_lock(mp)) != 0) {
304 perror("pthread_mutex_lock - HBAAPI:");
305 DEBUG(0, "pthread_mutex_lock returned %d", ret, 0, 0);
309 static void
310 release_mutex(pthread_mutex_t *mp) {
311 int ret;
312 if((ret = pthread_mutex_unlock(mp)) != 0) {
313 perror("pthread_mutex_unlock - HBAAPI:");
314 DEBUG(0, "pthread_mutex_unlock returned %d", ret, 0, 0);
317 #endif
320 * Common library internal. Check library and return vendorhandle
322 static HBA_STATUS
323 HBA_CheckLibrary(HBA_HANDLE handle,
324 HBA_LIBRARY_INFO **lib_infopp,
325 HBA_HANDLE *vendorhandle) {
327 HBA_UINT32 libraryIndex;
328 HBA_LIBRARY_INFO *lib_infop;
330 if (vendorhandle == NULL) {
331 return(HBA_STATUS_ERROR_ARG);
333 if(_hbaapi_librarylist == NULL) {
334 return(HBA_STATUS_ERROR);
336 libraryIndex = LIBRARY_NUM(handle);
338 GRAB_MUTEX(&_hbaapi_LL_mutex);
339 for(lib_infop = _hbaapi_librarylist;
340 lib_infop != NULL;
341 lib_infop = lib_infop->next) {
342 if(lib_infop->index == libraryIndex) {
343 if(lib_infop->status != HBA_LIBRARY_LOADED) {
344 return HBA_STATUS_ERROR;
346 *lib_infopp = lib_infop;
347 *vendorhandle = VENDOR_HANDLE(handle);
348 /* caller will release the mutex */
349 return HBA_STATUS_OK;
352 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INVALID_HANDLE);
354 #define CHECKLIBRARY() \
355 status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);\
356 if(status != HBA_STATUS_OK) { \
357 return(status); \
361 *freevendorhandlelist is called with _hbaapi_LL_mutex already held
363 static void
364 freevendorhandlelist(HBA_VENDORCALLBACK_ELEM *vhlist) {
365 HBA_VENDORCALLBACK_ELEM *vhlp;
366 HBA_VENDORCALLBACK_ELEM *vnext;
367 HBARemoveCallbackFunc registeredfunc;
369 for(vhlp = vhlist; vhlp != NULL; vhlp = vnext) {
370 vnext = vhlp->next;
371 registeredfunc =
372 vhlp->lib_info->functionTable.RemoveCallbackHandler;
373 if(registeredfunc == NULL) {
374 continue;
376 (registeredfunc)(vhlp->vendorcbhandle);
377 free(vhlp);
381 static
382 HBA_STATUS
383 local_remove_callback(HBA_CALLBACKHANDLE cbhandle) {
384 HBA_ADAPTERCALLBACK_ELEM ***listp;
385 HBA_ADAPTERCALLBACK_ELEM **lastp;
386 HBA_ALLADAPTERSCALLBACK_ELEM **lap;
387 HBA_ALLADAPTERSCALLBACK_ELEM *allcbp;
388 HBA_ADAPTERCALLBACK_ELEM *cbp;
389 HBARemoveCallbackFunc registeredfunc;
390 HBA_VENDORCALLBACK_ELEM *vhlp;
391 HBA_VENDORCALLBACK_ELEM *vnext;
392 int found;
393 HBA_STATUS status = HBA_STATUS_ERROR_INVALID_HANDLE;
396 /* search through the simple lists first */
397 GRAB_MUTEX(&_hbaapi_AAE_mutex);
398 GRAB_MUTEX(&_hbaapi_AE_mutex);
399 GRAB_MUTEX(&_hbaapi_APE_mutex);
400 GRAB_MUTEX(&_hbaapi_APSE_mutex);
401 GRAB_MUTEX(&_hbaapi_TE_mutex);
402 GRAB_MUTEX(&_hbaapi_LE_mutex);
403 for(listp = cb_lists_array, found = 0; found == 0, *listp != NULL; listp++) {
404 lastp = *listp;
405 for(cbp=**listp; cbp != NULL; cbp = cbp->next) {
406 if(cbhandle != (HBA_CALLBACKHANDLE)cbp) {
407 lastp = &(cbp->next);
408 continue;
410 found = 1;
411 registeredfunc = cbp->lib_info->functionTable.RemoveCallbackHandler;
412 if(registeredfunc == NULL) {
413 break;
415 (registeredfunc)(cbp->vendorcbhandle);
416 *lastp = cbp->next;
417 free(cbp);
418 break;
421 RELEASE_MUTEX(&_hbaapi_LE_mutex);
422 RELEASE_MUTEX(&_hbaapi_TE_mutex);
423 RELEASE_MUTEX(&_hbaapi_APSE_mutex);
424 RELEASE_MUTEX(&_hbaapi_APE_mutex);
425 RELEASE_MUTEX(&_hbaapi_AE_mutex);
426 RELEASE_MUTEX(&_hbaapi_AAE_mutex);
427 if(found != 0) {
428 if(registeredfunc == NULL) {
429 return HBA_STATUS_ERROR_NOT_SUPPORTED;
431 return HBA_STATUS_OK;
434 GRAB_MUTEX(&_hbaapi_AAE_mutex);
435 /* if it wasnt in the simple lists, look in the list for adapteraddevents */
436 lap = &_hbaapi_adapteraddevents_callback_list;
437 for(allcbp = _hbaapi_adapteraddevents_callback_list;
438 allcbp != NULL;
439 allcbp = allcbp->next) {
440 if(cbhandle != (HBA_CALLBACKHANDLE)allcbp) {
441 lap = &allcbp->next;
442 continue;
444 for(vhlp = allcbp->vendorhandlelist; vhlp != NULL; vhlp = vnext) {
445 vnext = vhlp->next;
446 registeredfunc =
447 vhlp->lib_info->functionTable.RemoveCallbackHandler;
448 if(registeredfunc == NULL) {
449 continue;
451 (registeredfunc)(vhlp->vendorcbhandle);
452 free(vhlp);
454 *lap = allcbp->next;
455 free(allcbp);
456 status = HBA_STATUS_OK;
457 break;
459 RELEASE_MUTEX(&_hbaapi_AAE_mutex);
460 return(status);
463 static char wwn_str1[17];
464 static char wwn_str2[17];
465 static char wwn_str3[17];
466 #define WWN2STR1(wwn) WWN2str(wwn_str1, (wwn))
467 #define WWN2STR2(wwn) WWN2str(wwn_str2, (wwn))
468 #define WWN2STR3(wwn) WWN2str(wwn_str3, (wwn))
469 static char *
470 WWN2str(char *buf, HBA_WWN *wwn) {
471 int j;
472 unsigned char *pc = (unsigned char *)&(wwn->wwn[0]);
473 buf[0] = '\0';
474 for (j=0; j<16; j+=2) {
475 sprintf(&buf[j], "%02X", (int)*pc++);
477 return(buf);
481 #ifdef WIN32
482 BOOL APIENTRY
483 DllMain( HANDLE hModule,
484 DWORD ul_reason_for_call,
485 LPVOID lpReserved
488 switch (ul_reason_for_call)
490 case DLL_PROCESS_ATTACH:
491 break;
492 case DLL_PROCESS_DETACH:
493 break;
494 case DLL_THREAD_ATTACH:
495 case DLL_THREAD_DETACH:
496 break;
498 return TRUE;
500 #endif
503 * Read in the config file and load all the specified vendor specific
504 * libraries and perform the function registration exercise
506 HBA_STATUS
507 HBA_LoadLibrary(void) {
508 HBARegisterLibraryFunc
509 RegisterFunc;
510 HBARegisterLibraryV2Func
511 RegisterV2Func;
512 HBALoadLibraryFunc LoadLibraryFunc;
513 HBAGetVersionFunc GetVersionFunc;
514 #ifdef POSIX_THREADS
515 int ret;
516 #endif
517 HBA_STATUS status;
518 #ifdef NOTDEF
519 HBA_UINT32 libversion;
520 #endif
522 /* Open configuration file from known location */
523 #ifdef WIN32
524 LONG lStatus;
525 HKEY hkSniaHba, hkVendorLib;
526 FILETIME ftLastWriteTime;
527 TCHAR cSubKeyName[256];
528 DWORD i, dwSize, dwType;
529 BYTE byFileName[MAX_PATH];
530 HBA_LIBRARY_INFO *lib_infop;
532 if(_hbaapi_librarylist != NULL) {
533 /* this is an app programming error */
534 return HBA_STATUS_ERROR;
537 lStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\SNIA\\HBA",
538 0, KEY_READ, &hkSniaHba);
539 if (lStatus != ERROR_SUCCESS) {
540 /* ???Opportunity to send error msg, configuration error */
541 return HBA_STATUS_ERROR;
544 * Enumerate all the subkeys. These have the form:
545 * HKLM\Software\SNIA\HBA\<Vendor id> - note that we don't care
546 * what the vendor id is
548 for (i = 0; ; i++) {
549 dwSize = 255; /* how big the buffer is */
550 lStatus = RegEnumKeyEx(hkSniaHba, i,
551 (char *)&cSubKeyName, &dwSize, NULL,
552 NULL, NULL, &ftLastWriteTime);
553 if (lStatus == ERROR_NO_MORE_ITEMS) {
554 break; /* we're done */
555 } else if (lStatus == ERROR_MORE_DATA) { /* buffer not big enough */
556 /* do whatever */
559 /* Now open the subkey that pertains to this vendor's library */
560 lStatus = RegOpenKeyEx(hkSniaHba, cSubKeyName, 0, KEY_READ,
561 &hkVendorLib);
562 if (lStatus != ERROR_SUCCESS) {
563 RegCloseKey(hkSniaHba);
564 /* ???Opportunity to send error msg, installation error */
565 return HBA_STATUS_ERROR; /* you may want to return something
566 * else or keep trying */
568 /* The name of the library is contained in a REG_SZ Value
569 * keyed to "LibraryFile" */
570 dwSize = MAX_PATH;
571 lStatus = RegQueryValueEx(hkVendorLib, "LibraryFile", NULL, &dwType,
572 byFileName, &dwSize);
573 if (lStatus != ERROR_SUCCESS) {
574 RegCloseKey(hkVendorLib);
575 /* ???Opportunity to send error msg, installation error */
576 continue;
578 lib_infop = (HBA_LIBRARY_INFO *)calloc(1, sizeof(HBA_LIBRARY_INFO));
579 if(lib_infop == NULL) {
580 /* what is the right thing to do in MS land??? */
581 RegCloseKey(hkVendorLib);
582 /* ???Opportunity to send error msg, installation error */
583 return(HBA_STATUS_ERROR);
585 lib_infop->status = HBA_LIBRARY_NOT_LOADED;
586 lib_infop->next = _hbaapi_librarylist;
587 lib_infop->index = _hbaapi_total_library_count;
588 _hbaapi_total_library_count++;
589 _hbaapi_librarylist = lib_infop;
591 /* Now I can try to load the library */
592 lib_infop->hLibrary = LoadLibrary(byFileName);
593 if (lib_infop->hLibrary == NULL){
594 /* printf("unable to load library %s\n", librarypath); */
595 /* ???Opportunity to send error msg, installation error */
596 goto dud_library;
598 lib_infop->LibraryPath = strdup(byFileName);
599 DEBUG(1, "HBAAPI loading: %s\n", byFileName, 0, 0);
601 /* Call the registration function to get the list of pointers */
602 RegisterV2Func = (HBARegisterLibraryV2Func)
603 GetProcAddress(lib_infop->hLibrary, "HBA_RegisterLibraryV2");
604 if (RegisterV2Func != NULL) {
605 /* Load the function pointers directly into
606 * the table of functions */
607 status = ((RegisterV2Func)(&lib_infop->functionTable));
608 if (status != HBA_STATUS_OK) {
609 /* library not loaded */
610 /* ???Opportunity to send error msg, library error? */
611 goto dud_library;
613 } else {
614 /* Maybe the vendor library is only Rev1 */
615 RegisterFunc = (HBARegisterLibraryFunc)
616 GetProcAddress(lib_infop->hLibrary, "HBA_RegisterLibrary");
617 if(RegisterFunc == NULL) {
618 /* ???Opportunity to send error msg, library error? */
619 goto dud_library;
621 /* Load the function points directly into
622 * the Rev 2 table of functions */
623 status = ((RegisterFunc)(
624 (HBA_ENTRYPOINTS *)(&lib_infop->functionTable)));
625 if (status != HBA_STATUS_OK) {
626 /* library not loaded */
627 /* ???Opportunity to send error msg, library error? */
628 goto dud_library;
632 /* successfully loaded library */
633 GetVersionFunc = lib_infop->functionTable.GetVersionHandler;
634 if (GetVersionFunc == NULL) {
635 /* ???Opportunity to send error msg, library error? */
636 goto dud_library;
638 #ifdef NOTDEF /* save for a later time... when it matters */
639 /* Check the version of this library before loading */
640 /* Actually... This wrapper is compatible with version 1 */
641 libversion = ((GetVersionFunc)());
642 if (libversion < HBA_LIBVERSION) {
643 goto dud_library;
645 #endif
646 LoadLibraryFunc = lib_infop->functionTable.LoadLibraryHandler;
647 if (LoadLibraryFunc == NULL) {
648 /* Hmmm, dont we need to flag this in a realy big way??? */
649 /* How about messages to the system event logger ??? */
650 /* ???Opportunity to send error msg, library error? */
651 goto dud_library;
653 /* Initialize this library */
654 status = ((LoadLibraryFunc)());
655 if (status != HBA_STATUS_OK) {
656 /* ???Opportunity to send error msg, library error? */
657 continue;
659 /* successfully loaded library */
660 lib_infop->status = HBA_LIBRARY_LOADED;
662 dud_library: /* its also just the end of the loop */
663 RegCloseKey(hkVendorLib);
665 RegCloseKey(hkSniaHba);
667 #else /* Unix as opposed to Win32 */
668 FILE *hbaconf;
669 char fullline[512]; /* line read from HBA.conf */
670 char *libraryname; /* Read in from file HBA.conf */
671 char *librarypath; /* Read in from file HBA.conf */
672 char hbaConfFilePath[256];
673 char *charPtr;
674 HBA_LIBRARY_INFO *lib_infop;
676 if(_hbaapi_librarylist != NULL) {
677 fprintf(stderr,
678 "HBA_LoadLibrary: previously unfreed "
679 "libraries exist, call HBA_FreeLibrary().\n");
680 return HBA_STATUS_ERROR;
683 strcpy(hbaConfFilePath, "/etc/hba.conf");
685 if ((hbaconf = fopen(hbaConfFilePath, "r")) == NULL) {
686 printf("Cannot open %s\n", hbaConfFilePath);
687 return HBA_STATUS_ERROR;
690 /* Read in each line and load library */
691 while ((hbaconf != NULL) && (fgets(fullline, sizeof(fullline), hbaconf))) {
692 /* Skip the comments... */
693 if ((fullline[0] == '#') || (fullline[0] == '\n')) {
694 continue;
697 /* grab first 'thing' in line (if its there)*/
698 if((libraryname = strtok(fullline, " \t\n")) != NULL) {
699 if(strlen(libraryname) >= 64) {
700 fprintf(stderr, "Library name(%s) in %s is > 64 characters\n",
701 libraryname, hbaConfFilePath);
704 /* grab second 'thing' in line (if its there)*/
705 if((librarypath = strtok(NULL, " \t\n")) != NULL) {
706 if(strlen(librarypath) >= 256) {
707 fprintf(stderr, "Library path(%s) in %s is > 256 characters\n",
708 librarypath, hbaConfFilePath);
712 /* there should be no more 'things' in the line */
713 if((charPtr = strtok(NULL, " \n\t")) != NULL) {
714 fprintf(stderr, "Extraneous characters (\"%s\") in %s\n",
715 charPtr, hbaConfFilePath);
718 /* Continue to the next line if library name or path is invalid */
719 if (libraryname == NULL ||
720 strlen(libraryname) == 0 ||
721 librarypath == NULL ||
722 (strlen(librarypath) == 0)) {
723 continue;
726 * Special case....
727 * Look for loglevel
729 if(strcmp(libraryname, "debuglevel") == 0) {
730 _hbaapi_debuglevel = strtol(librarypath, NULL, 10);
731 /* error handling does the right thing automagically */
732 continue;
735 lib_infop = (HBA_LIBRARY_INFO *)calloc(1, sizeof(HBA_LIBRARY_INFO));
736 if(lib_infop == NULL) {
737 fprintf(stderr, "HBA_LoadLibrary: out of memeory\n");
738 return(HBA_STATUS_ERROR);
740 lib_infop->status = HBA_LIBRARY_NOT_LOADED;
741 lib_infop->LibraryName = strdup(libraryname);
742 lib_infop->LibraryPath = strdup(librarypath);
743 lib_infop->index = _hbaapi_total_library_count;
744 _hbaapi_total_library_count++;
745 lib_infop->next = _hbaapi_librarylist;
746 _hbaapi_librarylist = lib_infop;
748 /* Load the DLL now */
749 if((lib_infop->hLibrary = dlopen(librarypath,RTLD_LAZY)) == NULL) {
750 /*printf("unable to load library %s\n", librarypath); */
751 continue;
753 /* Call the registration function to get the list of pointers */
754 RegisterV2Func = (HBARegisterLibraryV2Func)
755 dlsym(lib_infop->hLibrary, "HBA_RegisterLibraryV2");
756 if (RegisterV2Func != NULL) {
757 /* Load the function points directly into
758 * the table of functions */
759 status = ((RegisterV2Func)(&lib_infop->functionTable));
760 if (status != HBA_STATUS_OK) {
761 /* library not loaded */
762 continue;
764 } else {
765 /* Maybe the vendor library is only Rev1 */
766 RegisterFunc = (HBARegisterLibraryFunc)
767 dlsym(lib_infop->hLibrary, "HBA_RegisterLibrary");
768 if(RegisterFunc == NULL) {
769 /* This function is required */
770 fprintf(stderr,
771 "HBA_LoadLibrary: vendor specific RegisterLibrary "
772 "function not found. lib: %s\n", librarypath);
773 DEBUG(0, "HBA_LoadLibrary: vendor specific RegisterLibrary "
774 "function not found. lib: %s\n", librarypath, 0, 0);
775 continue;
777 /* Load the function points directly into
778 * the table of functions */
779 status = ((RegisterFunc)
780 ((HBA_ENTRYPOINTS *)(&lib_infop->functionTable)));
781 if (status != HBA_STATUS_OK) {
782 /* library not loaded */
783 fprintf(stderr,
784 "HBA_LoadLibrary: vendor specific RegisterLibrary "
785 "function encountered an error. lib: %s\n", librarypath);
786 DEBUG(0, "HBA_LoadLibrary: vendor specific RegisterLibrary "
787 "function encountered an error. lib: %s\n", librarypath, 0, 0);
788 continue;
792 /* successfully loaded library */
793 if((GetVersionFunc = lib_infop->functionTable.GetVersionHandler)
794 == NULL) {
795 continue;
797 #ifdef NOTDEF /* save for a later time... when it matters */
798 libversion = ((GetVersionFunc)());
799 /* Check the version of this library before loading */
800 /* Actually... This wrapper is compatible with version 1 */
801 if(libversion < HBA_LIBVERSION) {
802 printf("Library version mismatch. Got %d expected %d.\n",
803 libversion, HBA_LIBVERSION);
804 continue;
806 DEBUG(1, "%s libversion = %d", librarypath, libversion, 0);
807 #endif
808 LoadLibraryFunc = lib_infop->functionTable.LoadLibraryHandler;
809 if (LoadLibraryFunc == NULL) {
810 /* this function is required */
811 fprintf(stderr,
812 "HBA_LoadLibrary: vendor specific LoadLibrary "
813 "function not found. lib: %s\n", librarypath);
814 DEBUG(0, "HBA_LoadLibrary: vendor specific LoadLibrary "
815 "function not found. lib: %s\n", librarypath, 0, 0);
816 continue;
818 /* Initialize this library */
819 if((status = ((LoadLibraryFunc)())) != HBA_STATUS_OK) {
820 /* maybe this should be a printf so that we CANNOT miss it */
821 fprintf(stderr,
822 "HBA_LoadLibrary: Encounterd and error loading: %s",
823 librarypath);
824 DEBUG(0, "Encounterd and error loading: %s", librarypath, 0, 0);
825 DEBUG(0, " HBA_STATUS: %d", status, 0, 0);
826 continue;
828 /* successfully loaded library */
829 lib_infop->status = HBA_LIBRARY_LOADED;
832 fclose(hbaconf);
833 #endif /* WIN32 or UNIX */
834 #ifdef POSIX_THREADS
835 ret = pthread_mutex_init(&_hbaapi_LL_mutex, NULL);
836 if(ret == 0) {
837 ret = pthread_mutex_init(&_hbaapi_AL_mutex, NULL);
839 if(ret == 0) {
840 ret = pthread_mutex_init(&_hbaapi_AAE_mutex, NULL);
842 if(ret == 0) {
843 ret = pthread_mutex_init(&_hbaapi_AE_mutex, NULL);
845 if(ret == 0) {
846 ret = pthread_mutex_init(&_hbaapi_APE_mutex, NULL);
848 if(ret == 0) {
849 ret = pthread_mutex_init(&_hbaapi_APSE_mutex, NULL);
851 if(ret == 0) {
852 ret = pthread_mutex_init(&_hbaapi_TE_mutex, NULL);
854 if(ret == 0) {
855 ret = pthread_mutex_init(&_hbaapi_LE_mutex, NULL);
857 if(ret != 0) {
858 perror("pthread_mutec_init - HBA_LoadLibrary");
859 return(HBA_STATUS_ERROR);
861 #elif defined(WIN32)
862 InitializeCriticalSection(&_hbaapi_LL_mutex);
863 InitializeCriticalSection(&_hbaapi_AL_mutex);
864 InitializeCriticalSection(&_hbaapi_AAE_mutex);
865 InitializeCriticalSection(&_hbaapi_AE_mutex);
866 InitializeCriticalSection(&_hbaapi_APE_mutex);
867 InitializeCriticalSection(&_hbaapi_APSE_mutex);
868 InitializeCriticalSection(&_hbaapi_TE_mutex);
869 InitializeCriticalSection(&_hbaapi_LE_mutex);
870 #endif
873 return HBA_STATUS_OK;
876 HBA_STATUS
877 HBA_FreeLibrary(void) {
878 HBAFreeLibraryFunc FreeLibraryFunc;
879 HBA_LIBRARY_INFO *lib_infop;
880 HBA_LIBRARY_INFO *lib_next;
881 HBA_ADAPTERCALLBACK_ELEM
882 ***listp;
883 HBA_ADAPTER_INFO *adapt_infop;
884 HBA_ADAPTER_INFO *adapt_next;
886 ARE_WE_INITED();
887 GRAB_MUTEX(&_hbaapi_LL_mutex);
888 GRAB_MUTEX(&_hbaapi_AL_mutex);
890 DEBUG(1, "HBA_FreeLibrary()", 0, 0, 0);
891 for(lib_infop = _hbaapi_librarylist; lib_infop != NULL; lib_infop = lib_next) {
892 lib_next = lib_infop->next;
893 if (lib_infop->status == HBA_LIBRARY_LOADED) {
894 FreeLibraryFunc = lib_infop->functionTable.FreeLibraryHandler;
895 if (FreeLibraryFunc != NULL) {
896 /* Free this library */
897 (void)((FreeLibraryFunc)());
899 #ifdef WIN32
900 FreeLibrary(lib_infop->hLibrary); /* Unload DLL from memory */
901 #else
902 dlclose(lib_infop->hLibrary); /* Unload DLL from memory */
903 #endif
905 #ifndef WIN32
906 free(lib_infop->LibraryName);
907 #endif
908 free(lib_infop->LibraryPath);
909 free(lib_infop);
912 _hbaapi_librarylist = NULL;
913 /* OK, now all functions are disabled except for LoadLibrary,
914 * Hope no other thread calls it before we have returned */
915 _hbaapi_total_library_count = 0;
917 for(adapt_infop = _hbaapi_adapterlist;
918 adapt_infop != NULL;
919 adapt_infop = adapt_next) {
920 adapt_next = adapt_infop->next;
921 free(adapt_infop->name);
922 free(adapt_infop);
924 _hbaapi_adapterlist = NULL;
925 _hbaapi_total_adapter_count = 0;
927 /* Free up the callbacks, this is not the most efficient, but it works */
928 while((volatile HBA_ADAPTERCALLBACK_ELEM *)
929 _hbaapi_adapteraddevents_callback_list
930 != NULL) {
931 local_remove_callback((HBA_CALLBACKHANDLE)
932 _hbaapi_adapteraddevents_callback_list);
934 for(listp = cb_lists_array; *listp != NULL; listp++) {
935 while((volatile HBA_ADAPTERCALLBACK_ELEM ***)**listp != NULL) {
936 local_remove_callback((HBA_CALLBACKHANDLE)**listp);
940 RELEASE_MUTEX(&_hbaapi_AL_mutex);
941 RELEASE_MUTEX(&_hbaapi_LL_mutex);
943 #ifdef USESYSLOG
944 closelog();
945 #endif
946 #ifdef USELOGFILE
947 if(_hbaapi_debug_fd != NULL) {
948 fclose(_hbaapi_debug_fd);
950 _hbaapi_debug_fd = NULL;
951 #endif
952 #ifdef POSIX_THREADS
953 /* this will unlock them as well, but who cares */
954 pthread_mutex_destroy(&_hbaapi_LE_mutex);
955 pthread_mutex_destroy(&_hbaapi_TE_mutex);
956 pthread_mutex_destroy(&_hbaapi_APSE_mutex);
957 pthread_mutex_destroy(&_hbaapi_APE_mutex);
958 pthread_mutex_destroy(&_hbaapi_AE_mutex);
959 pthread_mutex_destroy(&_hbaapi_AAE_mutex);
960 pthread_mutex_destroy(&_hbaapi_AL_mutex);
961 pthread_mutex_destroy(&_hbaapi_LL_mutex);
962 #elif defined(WIN32)
963 DeleteCriticalSection(&_hbaapi_LL_mutex);
964 DeleteCriticalSection(&_hbaapi_AL_mutex);
965 DeleteCriticalSection(&_hbaapi_AAE_mutex);
966 DeleteCriticalSection(&_hbaapi_AE_mutex);
967 DeleteCriticalSection(&_hbaapi_APE_mutex);
968 DeleteCriticalSection(&_hbaapi_APSE_mutex);
969 DeleteCriticalSection(&_hbaapi_TE_mutex);
970 DeleteCriticalSection(&_hbaapi_LE_mutex);
971 #endif
973 return HBA_STATUS_OK;
977 * The API used to use fixed size tables as its primary data structure.
978 * Indexing from 1 to N identified each adapters. Now the adapters are
979 * on a linked list. There is a unique "index" foreach each adapter.
980 * Adapters always keep their index, even if they are removed from the
981 * hardware. The only time the indexing is reset is on HBA_FreeLibrary
983 HBA_UINT32
984 HBA_GetNumberOfAdapters(void) {
985 int j=0;
986 HBA_LIBRARY_INFO *lib_infop;
987 HBAGetNumberOfAdaptersFunc
988 GetNumberOfAdaptersFunc;
989 HBAGetAdapterNameFunc
990 GetAdapterNameFunc;
991 HBA_BOOLEAN found_name;
992 HBA_ADAPTER_INFO *adapt_infop;
993 HBA_STATUS status;
995 char adaptername[256];
996 int num_adapters; /* local */
998 if(_hbaapi_librarylist == NULL) {
999 return (0);
1001 GRAB_MUTEX(&_hbaapi_LL_mutex); /* pay attention to order */
1002 GRAB_MUTEX(&_hbaapi_AL_mutex);
1004 for (lib_infop = _hbaapi_librarylist;
1005 lib_infop != NULL;
1006 lib_infop = lib_infop->next) {
1008 if (lib_infop->status != HBA_LIBRARY_LOADED) {
1009 continue;
1012 GetNumberOfAdaptersFunc =
1013 lib_infop->functionTable.GetNumberOfAdaptersHandler;
1014 if (GetNumberOfAdaptersFunc == NULL) {
1015 continue;
1017 num_adapters = ((GetNumberOfAdaptersFunc)());
1018 #ifndef WIN32
1019 DEBUG(1, "HBAAPI: num_adapters for %s = %d\n",
1020 lib_infop->LibraryName, num_adapters, 0);
1021 #else
1022 DEBUG(1, "HBAAPI: num_adapters for %s = %d\n",
1023 lib_infop->LibraryPath, num_adapters, 0);
1024 #endif
1026 /* Also get the names of all the adapters here and cache */
1027 GetAdapterNameFunc = lib_infop->functionTable.GetAdapterNameHandler;
1028 if(GetAdapterNameFunc == NULL) {
1029 continue;
1032 for (j = 0; j < num_adapters; j++) {
1033 found_name = 0;
1034 status = (GetAdapterNameFunc)(j, (char *)&adaptername);
1035 if(status == HBA_STATUS_OK) {
1036 for(adapt_infop = _hbaapi_adapterlist;
1037 adapt_infop != NULL;
1038 adapt_infop = adapt_infop->next) {
1040 * check for duplicates, really, this may just be a second
1041 * call to this function
1042 * ??? how do we know when a name becomes stale?
1044 if(strcmp(adaptername, adapt_infop->name) == 0) {
1045 /* already got this one */
1046 found_name++;
1047 break;
1050 if(found_name != 0) {
1051 continue;
1055 adapt_infop = (HBA_ADAPTER_INFO *)
1056 calloc(1, sizeof(HBA_ADAPTER_INFO));
1057 if(adapt_infop == NULL) {
1058 #ifndef WIN32
1059 fprintf(stderr,
1060 "HBA_GetNumberOfAdapters: calloc failed on sizeof:%d\n",
1061 sizeof(HBA_ADAPTER_INFO));
1062 #endif
1063 RELEASE_MUTEX(&_hbaapi_AL_mutex);
1064 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex,
1065 _hbaapi_total_adapter_count);
1067 if((adapt_infop->GNstatus = status) == HBA_STATUS_OK) {
1068 adapt_infop->name = strdup(adaptername);
1069 } else {
1070 char dummyname[512];
1071 sprintf(dummyname, "NULLADAPTER-%s-%03d",
1072 lib_infop->LibraryPath, _hbaapi_total_adapter_count);
1073 dummyname[255] = '\0';
1074 adapt_infop->name = strdup(dummyname);
1076 adapt_infop->library = lib_infop;
1077 adapt_infop->next = _hbaapi_adapterlist;
1078 adapt_infop->index = _hbaapi_total_adapter_count;
1079 _hbaapi_adapterlist = adapt_infop;
1080 _hbaapi_total_adapter_count++;
1083 RELEASE_MUTEX(&_hbaapi_AL_mutex);
1084 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, _hbaapi_total_adapter_count);
1087 HBA_STATUS
1088 HBA_GetAdapterName(
1089 HBA_UINT32 adapterindex,
1090 char *adaptername)
1092 HBA_ADAPTER_INFO *adapt_infop;
1093 HBA_STATUS ret = HBA_STATUS_ERROR_ILLEGAL_INDEX;
1095 if (adaptername == NULL) {
1096 return(HBA_STATUS_ERROR_ARG);
1099 * The adapter index is from old code, but we have
1100 * to support it. Go down the list looking for
1101 * the adapter
1103 ARE_WE_INITED();
1104 GRAB_MUTEX(&_hbaapi_AL_mutex);
1105 *adaptername = '\0';
1106 for(adapt_infop = _hbaapi_adapterlist;
1107 adapt_infop != NULL;
1108 adapt_infop = adapt_infop->next) {
1110 if(adapt_infop->index == adapterindex) {
1111 if(adapt_infop->name != NULL &&
1112 adapt_infop->GNstatus == HBA_STATUS_OK) {
1113 strcpy(adaptername, adapt_infop->name);
1114 } else {
1115 *adaptername = '\0';
1117 ret = adapt_infop->GNstatus;
1118 break;
1121 DEBUG(2, "GetAdapterName for index:%d ->%s", adapterindex, adaptername, 0);
1122 RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, ret);
1125 HBA_HANDLE
1126 HBA_OpenAdapter(char* adaptername) {
1127 HBA_HANDLE handle;
1128 HBAOpenAdapterFunc OpenAdapterFunc;
1129 HBA_ADAPTER_INFO *adapt_infop;
1130 HBA_LIBRARY_INFO *lib_infop;
1132 DEBUG(2, "OpenAdapter: %s", adaptername, 0, 0);
1134 if(_hbaapi_librarylist == NULL) {
1135 return(HBA_HANDLE_INVALID);
1137 if (adaptername == NULL) {
1138 return(HBA_STATUS_ERROR_ARG);
1140 handle = HBA_HANDLE_INVALID;
1141 GRAB_MUTEX(&_hbaapi_AL_mutex);
1142 for(adapt_infop = _hbaapi_adapterlist;
1143 adapt_infop != NULL;
1144 adapt_infop = adapt_infop->next) {
1145 if (strcmp(adaptername, adapt_infop->name) != 0) {
1146 continue;
1148 lib_infop = adapt_infop->library;
1149 OpenAdapterFunc =
1150 lib_infop->functionTable.OpenAdapterHandler;
1151 if (OpenAdapterFunc != NULL) {
1152 /* retrieve the vendor handle */
1153 handle = (OpenAdapterFunc)(adaptername);
1154 if(handle != 0) {
1155 /* or this with the library index to get the common handle */
1156 handle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle);
1159 break;
1161 RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, handle);
1164 * This function ignores the list of known adapters and instead tries
1165 * each vendors open function to see if one of them
1166 * can open an adapter when referenced with a particular WWN
1168 HBA_STATUS
1169 HBA_OpenAdapterByWWN(HBA_HANDLE *phandle, HBA_WWN nodeWWN) {
1170 HBA_HANDLE handle;
1171 HBA_LIBRARY_INFO *lib_infop;
1172 HBAGetNumberOfAdaptersFunc
1173 GetNumberOfAdaptersFunc;
1174 HBAOpenAdapterByWWNFunc
1175 OpenAdapterFunc;
1176 HBA_STATUS status;
1178 DEBUG(2, "OpenAdapterByWWN: %s", WWN2STR1(&nodeWWN), 0, 0);
1180 if (phandle == NULL) {
1181 return(HBA_STATUS_ERROR_ARG);
1184 ARE_WE_INITED();
1186 *phandle = HBA_HANDLE_INVALID;
1188 GRAB_MUTEX(&_hbaapi_LL_mutex);
1189 for (lib_infop = _hbaapi_librarylist;
1190 lib_infop != NULL;
1191 lib_infop = lib_infop->next) {
1193 status = HBA_STATUS_ERROR_ILLEGAL_WWN;
1195 if (lib_infop->status != HBA_LIBRARY_LOADED) {
1196 continue;
1199 GetNumberOfAdaptersFunc =
1200 lib_infop->functionTable.GetNumberOfAdaptersHandler;
1201 if (GetNumberOfAdaptersFunc == NULL) {
1202 continue;
1205 /* look for new hardware */
1206 (void) ((GetNumberOfAdaptersFunc)());
1208 OpenAdapterFunc = lib_infop->functionTable.OpenAdapterByWWNHandler;
1209 if (OpenAdapterFunc == NULL) {
1210 continue;
1213 * We do not know if the WWN is known by this vendor,
1214 * just try it
1216 if((status = (OpenAdapterFunc)(&handle, nodeWWN)) != HBA_STATUS_OK) {
1217 continue;
1219 /* OK, make a vendor non-specific handle */
1220 *phandle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle);
1221 status = HBA_STATUS_OK;
1222 break;
1224 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1227 void
1228 HBA_RefreshAdapterConfiguration() {
1229 DEBUG(2, "HBA_RefreshAdapterConfiguration", 0, 0, 0);
1230 (void)HBA_GetNumberOfAdapters();
1231 return;
1234 HBA_UINT32
1235 HBA_GetVersion() {
1236 DEBUG(2, "HBA_GetVersion", 0, 0, 0);
1237 return HBA_LIBVERSION;
1241 * This function is VERY OS dependent. Wing it as best you can.
1243 HBA_UINT32
1244 HBA_GetWrapperLibraryAttributes (
1245 HBA_LIBRARYATTRIBUTES *attributes)
1248 DEBUG(2, "HBA_GetWrapperLibraryAttributes", 0, 0, 0);
1250 if (attributes == NULL) {
1251 return(HBA_STATUS_ERROR_ARG);
1254 memset(attributes, 0, sizeof(HBA_LIBRARYATTRIBUTES));
1256 #if defined(SOLARIS)
1257 if((handle = dlopen("libHBAAPI.so", RTLD_NOW)) != NULL) {
1258 if(dlinfo(handle, RTLD_DI_LINKMAP, &map) >= 0) {
1259 for(mp = map; mp != NULL; mp = mp->l_next) {
1260 if(strlen(map->l_name) < 256) {
1261 strcpy(attributes->LibPath, map->l_lname);
1266 #elif defined(WIN32)
1268 HMODULE module;
1270 /* No need to do anything with the module handle */
1271 /* It wasn't alloocated so it doesn't need to be freed */
1272 module = GetModuleHandle("HBAAPI");
1273 if ( module != NULL ) {
1274 if ( GetModuleFileName(module, attributes->LibPath,
1275 sizeof(attributes->LibPath)) == 0 ) {
1276 attributes->LibPath[0] = '\0';
1280 #endif
1281 #if defined(VENDOR)
1282 strcpy(attributes->VName, VENDOR);
1283 #else
1284 attributes->VName[0] = '\0';
1285 #endif
1286 #if defined(VERSION)
1287 strcpy(attributes->VVersion, VERSION);
1288 #else
1289 attributes->VVersion[0] = '\0';
1290 #endif
1291 #if defined(BUILD_DATE)
1292 #if defined(WIN32)
1294 int matchCount;
1295 matchCount = sscanf(BUILD_DATE, "%u/%u/%u %u:%u:%u",
1296 &attributes->build_date.tm_year,
1297 &attributes->build_date.tm_mon,
1298 &attributes->build_date.tm_mday,
1299 &attributes->build_date.tm_hour,
1300 &attributes->build_date.tm_min,
1301 &attributes->build_date.tm_sec
1304 if ( matchCount != 6 ) {
1305 memset(&attributes->build_date, 0, sizeof(struct tm));
1306 } else {
1307 attributes->build_date.tm_year -= 1900;
1308 attributes->build_date.tm_isdst = -1;
1312 #else
1313 if(strptime(BUILD_DATE, "%Y/%m/%d %T %Z", &(attributes->build_date)) == NULL) {
1314 memset(&attributes->build_date, 0, sizeof(struct tm));
1316 #endif
1317 #else
1318 memset(&attributes->build_date, 0, sizeof(struct tm));
1319 #endif
1320 return 2;
1324 * Callback registation and handling
1326 HBA_STATUS
1327 HBA_RemoveCallback (HBA_CALLBACKHANDLE cbhandle) {
1328 HBA_STATUS status;
1330 DEBUG(2, "HBA_RemoveCallback", 0, 0, 0);
1331 ARE_WE_INITED();
1333 GRAB_MUTEX(&_hbaapi_LL_mutex);
1334 status = local_remove_callback(cbhandle);
1335 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1338 /* Adapter Add Events *********************************************************/
1339 static void
1340 adapteraddevents_callback (void *data, HBA_WWN PortWWN, HBA_UINT32 eventType) {
1341 HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
1343 DEBUG(3, "AddAdapterEvent, port:%s", WWN2STR1(&PortWWN), 0, 0);
1345 GRAB_MUTEX(&_hbaapi_AAE_mutex);
1346 for(cbp = _hbaapi_adapteraddevents_callback_list;
1347 cbp != NULL;
1348 cbp = cbp->next) {
1349 (*cbp->callback)(data, PortWWN, HBA_EVENT_ADAPTER_ADD);
1351 RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1354 HBA_STATUS
1355 HBA_RegisterForAdapterAddEvents (
1356 void (*callback) (
1357 void *data,
1358 HBA_WWN PortWWN,
1359 HBA_UINT32 eventType
1361 void *userData,
1362 HBA_CALLBACKHANDLE *callbackHandle) {
1364 HBA_ALLADAPTERSCALLBACK_ELEM *cbp;
1365 HBA_VENDORCALLBACK_ELEM *vcbp;
1366 HBA_VENDORCALLBACK_ELEM *vendorhandlelist;
1367 HBARegisterForAdapterAddEventsFunc registeredfunc;
1368 HBA_STATUS status = HBA_STATUS_OK;
1369 HBA_STATUS failure = HBA_STATUS_OK;
1370 HBA_LIBRARY_INFO *lib_infop;
1371 int registered_cnt = 0;
1372 int vendor_cnt = 0;
1373 int not_supported_cnt = 0;
1374 int status_OK_bar_cnt = 0;
1375 int status_OK_cnt = 0;
1377 DEBUG(2, "HBA_RegisterForAdapterAddEvents", 0, 0, 0);
1379 if (callbackHandle == NULL) {
1380 return(HBA_STATUS_ERROR_ARG);
1382 ARE_WE_INITED();
1384 cbp = (HBA_ALLADAPTERSCALLBACK_ELEM *)
1385 calloc(1, sizeof(HBA_ALLADAPTERSCALLBACK_ELEM));
1386 *callbackHandle = (HBA_CALLBACKHANDLE) cbp;
1387 if(cbp == NULL) {
1388 #ifndef WIN32
1389 fprintf(stderr,
1390 "HBA_RegisterForAdapterAddEvents: calloc failed for %d bytes\n",
1391 sizeof(HBA_ALLADAPTERSCALLBACK_ELEM));
1392 #endif
1393 return HBA_STATUS_ERROR;
1396 GRAB_MUTEX(&_hbaapi_LL_mutex);
1397 GRAB_MUTEX(&_hbaapi_AAE_mutex);
1398 cbp->callback = callback;
1399 cbp->next = _hbaapi_adapteraddevents_callback_list;
1400 _hbaapi_adapteraddevents_callback_list = cbp;
1401 /* Need to release the mutex now incase the vendor function invokes the
1402 * callback. We will grap the mutex later to attach the vendor handle list
1403 * to the callback structure */
1404 RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1408 * now create a list of vendors (vendor libraryies, NOT ADAPTERS) that have
1409 * successfully registerred
1411 vendorhandlelist = NULL;
1412 for(lib_infop = _hbaapi_librarylist;
1413 lib_infop != NULL;
1414 lib_infop = lib_infop->next) {
1416 vendor_cnt++;
1418 registeredfunc =
1419 lib_infop->functionTable.RegisterForAdapterAddEventsHandler;
1420 if(registeredfunc == NULL) {
1421 continue;
1424 vcbp = (HBA_VENDORCALLBACK_ELEM *)
1425 calloc(1, sizeof(HBA_VENDORCALLBACK_ELEM));
1426 if(vcbp == NULL) {
1427 #ifndef WIN32
1428 fprintf(stderr,
1429 "HBA_RegisterForAdapterAddEvents: "
1430 "calloc failed for %d bytes\n",
1431 sizeof(HBA_VENDORCALLBACK_ELEM));
1432 #endif
1433 freevendorhandlelist(vendorhandlelist);
1434 status = HBA_STATUS_ERROR;
1435 break;
1438 registered_cnt++;
1439 status = (registeredfunc)(adapteraddevents_callback,
1440 userData, &vcbp->vendorcbhandle);
1441 if(status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
1442 not_supported_cnt++;
1443 free(vcbp);
1444 continue;
1445 } else if (status != HBA_STATUS_OK) {
1446 status_OK_bar_cnt++;
1447 DEBUG(0,
1448 "HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
1449 lib_infop->LibraryPath, status, 0);
1450 #ifndef WIN32
1451 fprintf(stderr,
1452 "HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d",
1453 lib_infop->LibraryPath, status);
1454 #endif
1455 failure = status;
1456 free(vcbp);
1457 continue;
1458 } else {
1459 status_OK_cnt++;
1461 vcbp->lib_info = lib_infop;
1462 vcbp->next = vendorhandlelist;
1463 vendorhandlelist = vcbp;
1465 if(registered_cnt == 0) {
1466 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1467 freevendorhandlelist(vendorhandlelist);
1468 local_remove_callback((HBA_CALLBACKHANDLE) cbp);
1469 } else if (status_OK_cnt == 0 && not_supported_cnt != 0) {
1470 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
1471 } else if (status_OK_cnt == 0) {
1472 /* At least one vendor library registered this function, but no
1473 * vendor call succeeded */
1474 local_remove_callback((HBA_CALLBACKHANDLE) cbp);
1475 status = failure;
1476 } else {
1477 /* we have had atleast some success, now finish up */
1478 GRAB_MUTEX(&_hbaapi_AAE_mutex);
1479 /* this seems silly, but what if another thread called
1480 * the callback remove */
1481 for(cbp = _hbaapi_adapteraddevents_callback_list;
1482 cbp != NULL; cbp = cbp->next) {
1483 if((HBA_CALLBACKHANDLE)cbp == *callbackHandle) {
1484 /* yup, its still there, hooray */
1485 cbp->vendorhandlelist = vendorhandlelist;
1486 vendorhandlelist = NULL;
1487 break;
1490 RELEASE_MUTEX(&_hbaapi_AAE_mutex);
1491 if(vendorhandlelist != NULL) {
1492 /* bummer, somebody removed the callback before we finished
1493 * registration, probably will never happen */
1494 freevendorhandlelist(vendorhandlelist);
1495 DEBUG(0,
1496 "HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was "
1497 "called for a handle before registration was finished.",
1498 0, 0, 0);
1499 status = HBA_STATUS_ERROR;
1500 } else {
1501 status = HBA_STATUS_OK;
1504 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1507 /* Adapter Events (other than add) ********************************************/
1508 static void
1509 adapterevents_callback (void *data,
1510 HBA_WWN PortWWN,
1511 HBA_UINT32 eventType) {
1512 HBA_ADAPTERCALLBACK_ELEM *acbp;
1514 DEBUG(3, "AdapterEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN),
1515 eventType, 0);
1517 GRAB_MUTEX(&_hbaapi_AE_mutex);
1518 for(acbp = _hbaapi_adapterevents_callback_list;
1519 acbp != NULL;
1520 acbp = acbp->next) {
1521 if(data == (void *)acbp) {
1522 (*acbp->callback)(acbp->userdata, PortWWN, eventType);
1523 break;
1526 RELEASE_MUTEX(&_hbaapi_AE_mutex);
1528 HBA_STATUS
1529 HBA_RegisterForAdapterEvents (
1530 void (*callback) (
1531 void *data,
1532 HBA_WWN PortWWN,
1533 HBA_UINT32 eventType
1535 void *userData,
1536 HBA_HANDLE handle,
1537 HBA_CALLBACKHANDLE *callbackHandle) {
1539 HBA_ADAPTERCALLBACK_ELEM *acbp;
1540 HBARegisterForAdapterEventsFunc registeredfunc;
1541 HBA_STATUS status;
1542 HBA_LIBRARY_INFO *lib_infop;
1543 HBA_HANDLE vendorHandle;
1545 DEBUG(2, "HBA_RegisterForAdapterEvents", 0, 0, 0);
1547 if (callbackHandle == NULL) {
1548 return(HBA_STATUS_ERROR_ARG);
1551 CHECKLIBRARY();
1553 /* we now have the _hbaapi_LL_mutex */
1555 registeredfunc = lib_infop->functionTable.RegisterForAdapterEventsHandler;
1556 if(registeredfunc == NULL) {
1557 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1561 * that allocated memory is used both as the handle for the
1562 * caller, and as userdata to the vendor call so that on
1563 * callback the specific registration may be recalled
1565 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1566 calloc(1, sizeof(HBA_ADAPTERCALLBACK_ELEM));
1567 if(acbp == NULL) {
1568 #ifndef WIN32
1569 fprintf(stderr,
1570 "HBA_RegisterForAdapterEvents: calloc failed for %d bytes\n",
1571 sizeof(HBA_ADAPTERCALLBACK_ELEM));
1572 #endif
1573 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1575 *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1576 acbp->callback = callback;
1577 acbp->userdata = userData;
1578 acbp->lib_info = lib_infop;
1580 status = (registeredfunc)(adapterevents_callback,
1581 (void *)acbp,
1582 vendorHandle,
1583 &acbp->vendorcbhandle);
1584 if(status != HBA_STATUS_OK) {
1585 free(acbp);
1586 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1589 GRAB_MUTEX(&_hbaapi_AE_mutex);
1590 acbp->next = _hbaapi_adapterevents_callback_list;
1591 _hbaapi_adapterevents_callback_list = acbp;
1592 RELEASE_MUTEX(&_hbaapi_AE_mutex);
1594 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1597 /* Adapter Port Events ********************************************************/
1598 static void
1599 adapterportevents_callback (void *data,
1600 HBA_WWN PortWWN,
1601 HBA_UINT32 eventType,
1602 HBA_UINT32 fabricPortID) {
1603 HBA_ADAPTERCALLBACK_ELEM *acbp;
1605 DEBUG(3, "AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x",
1606 WWN2STR1(&PortWWN), eventType, fabricPortID);
1608 GRAB_MUTEX(&_hbaapi_APE_mutex);
1610 for(acbp = _hbaapi_adapterportevents_callback_list;
1611 acbp != NULL;
1612 acbp = acbp->next) {
1613 if(data == (void *)acbp) {
1614 (*acbp->callback)(acbp->userdata, PortWWN, eventType, fabricPortID);
1615 break;
1618 RELEASE_MUTEX(&_hbaapi_APE_mutex);
1620 HBA_STATUS
1621 HBA_RegisterForAdapterPortEvents (
1622 void (*callback) (
1623 void *data,
1624 HBA_WWN PortWWN,
1625 HBA_UINT32 eventType,
1626 HBA_UINT32 fabricPortID
1628 void *userData,
1629 HBA_HANDLE handle,
1630 HBA_WWN PortWWN,
1631 HBA_CALLBACKHANDLE *callbackHandle) {
1633 HBA_ADAPTERCALLBACK_ELEM *acbp;
1634 HBARegisterForAdapterPortEventsFunc registeredfunc;
1635 HBA_STATUS status;
1636 HBA_LIBRARY_INFO *lib_infop;
1637 HBA_HANDLE vendorHandle;
1639 DEBUG(2, "HBA_RegisterForAdapterPortEvents for port: %s",
1640 WWN2STR1(&PortWWN), 0, 0);
1642 if (callbackHandle == NULL) {
1643 return(HBA_STATUS_ERROR_ARG);
1646 CHECKLIBRARY();
1647 /* we now have the _hbaapi_LL_mutex */
1649 registeredfunc =
1650 lib_infop->functionTable.RegisterForAdapterPortEventsHandler;
1651 if(registeredfunc == NULL) {
1652 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1656 * that allocated memory is used both as the handle for the
1657 * caller, and as userdata to the vendor call so that on
1658 * callback the specific registration may be recalled
1660 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1661 calloc(1, sizeof(HBA_ADAPTERCALLBACK_ELEM));
1662 if(acbp == NULL) {
1663 #ifndef WIN32
1664 fprintf(stderr,
1665 "HBA_RegisterForAdapterPortEvents: "
1666 "calloc failed for %d bytes\n",
1667 sizeof(HBA_ADAPTERCALLBACK_ELEM));
1668 #endif
1669 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1672 *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1673 acbp->callback = callback;
1674 acbp->userdata = userData;
1675 acbp->lib_info = lib_infop;
1677 status = (registeredfunc)(adapterportevents_callback,
1678 (void *)acbp,
1679 vendorHandle,
1680 PortWWN,
1681 &acbp->vendorcbhandle);
1682 if(status != HBA_STATUS_OK) {
1683 free(acbp);
1684 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1687 GRAB_MUTEX(&_hbaapi_APE_mutex);
1688 acbp->next = _hbaapi_adapterportevents_callback_list;
1689 _hbaapi_adapterportevents_callback_list = acbp;
1690 RELEASE_MUTEX(&_hbaapi_APE_mutex);
1692 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1695 /* Adapter State Events *******************************************************/
1696 static void
1697 adapterportstatevents_callback (void *data,
1698 HBA_WWN PortWWN,
1699 HBA_UINT32 eventType) {
1700 HBA_ADAPTERCALLBACK_ELEM *acbp;
1702 DEBUG(3, "AdapterPortStateEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN),
1703 eventType, 0);
1705 GRAB_MUTEX(&_hbaapi_APSE_mutex);
1706 for(acbp = _hbaapi_adapterportstatevents_callback_list;
1707 acbp != NULL;
1708 acbp = acbp->next) {
1709 if(data == (void *)acbp) {
1710 (*acbp->callback)(acbp->userdata, PortWWN, eventType);
1711 return;
1715 HBA_STATUS
1716 HBA_RegisterForAdapterPortStatEvents (
1717 void (*callback) (
1718 void *data,
1719 HBA_WWN PortWWN,
1720 HBA_UINT32 eventType
1722 void *userData,
1723 HBA_HANDLE handle,
1724 HBA_WWN PortWWN,
1725 HBA_PORTSTATISTICS stats,
1726 HBA_UINT32 statType,
1727 HBA_CALLBACKHANDLE *callbackHandle) {
1729 HBA_ADAPTERCALLBACK_ELEM *acbp;
1730 HBARegisterForAdapterPortStatEventsFunc
1731 registeredfunc;
1732 HBA_STATUS status;
1733 HBA_LIBRARY_INFO *lib_infop;
1734 HBA_HANDLE vendorHandle;
1736 DEBUG(2, "HBA_RegisterForAdapterPortStatEvents for port: %s",
1737 WWN2STR1(&PortWWN), 0, 0);
1739 if (callbackHandle == NULL) {
1740 return(HBA_STATUS_ERROR_ARG);
1743 CHECKLIBRARY();
1744 /* we now have the _hbaapi_LL_mutex */
1746 registeredfunc =
1747 lib_infop->functionTable.RegisterForAdapterPortStatEventsHandler;
1748 if(registeredfunc == NULL) {
1749 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1753 * that allocated memory is used both as the handle for the
1754 * caller, and as userdata to the vendor call so that on
1755 * callback the specific registration may be recalled
1757 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1758 calloc(1, sizeof(HBA_ADAPTERCALLBACK_ELEM));
1759 if(acbp == NULL) {
1760 #ifndef WIN32
1761 fprintf(stderr,
1762 "HBA_RegisterForAdapterPortStatEvents: "
1763 "calloc failed for %d bytes\n",
1764 sizeof(HBA_ADAPTERCALLBACK_ELEM));
1765 #endif
1766 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1768 *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1769 acbp->callback = callback;
1770 acbp->userdata = userData;
1771 acbp->lib_info = lib_infop;
1773 status = (registeredfunc)(adapterportstatevents_callback,
1774 (void *)acbp,
1775 vendorHandle,
1776 PortWWN,
1777 stats,
1778 statType,
1779 &acbp->vendorcbhandle);
1780 if(status != HBA_STATUS_OK) {
1781 free(acbp);
1782 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1785 GRAB_MUTEX(&_hbaapi_APSE_mutex);
1786 acbp->next = _hbaapi_adapterportstatevents_callback_list;
1787 _hbaapi_adapterportstatevents_callback_list = acbp;
1788 RELEASE_MUTEX(&_hbaapi_APSE_mutex);
1790 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1793 /* Target Events **************************************************************/
1794 static void
1795 targetevents_callback (void *data,
1796 HBA_WWN hbaPortWWN,
1797 HBA_WWN discoveredPortWWN,
1798 HBA_UINT32 eventType) {
1799 HBA_ADAPTERCALLBACK_ELEM *acbp;
1801 DEBUG(3, "TargetEvent, hbaPort:%s, discoveredPort:%s eventType:%d",
1802 WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), eventType);
1804 GRAB_MUTEX(&_hbaapi_TE_mutex);
1805 for(acbp = _hbaapi_targetevents_callback_list;
1806 acbp != NULL;
1807 acbp = acbp->next) {
1808 if(data == (void *)acbp) {
1809 (*acbp->callback)(acbp->userdata, hbaPortWWN,
1810 discoveredPortWWN, eventType);
1811 break;
1814 RELEASE_MUTEX(&_hbaapi_TE_mutex);
1816 HBA_STATUS
1817 HBA_RegisterForTargetEvents (
1818 void (*callback) (
1819 void *data,
1820 HBA_WWN hbaPortWWN,
1821 HBA_WWN discoveredPortWWN,
1822 HBA_UINT32 eventType
1824 void *userData,
1825 HBA_HANDLE handle,
1826 HBA_WWN hbaPortWWN,
1827 HBA_WWN discoveredPortWWN,
1828 HBA_CALLBACKHANDLE *callbackHandle,
1829 HBA_UINT32 allTargets) {
1831 HBA_ADAPTERCALLBACK_ELEM
1832 *acbp;
1833 HBARegisterForTargetEventsFunc
1834 registeredfunc;
1835 HBA_STATUS status;
1836 HBA_LIBRARY_INFO *lib_infop;
1837 HBA_HANDLE vendorHandle;
1839 DEBUG(2, "HBA_RegisterForTargetEvents, hbaPort: %s, discoveredPort: %s",
1840 WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), 0);
1842 if (callbackHandle == NULL) {
1843 return(HBA_STATUS_ERROR_ARG);
1846 CHECKLIBRARY();
1847 /* we now have the _hbaapi_LL_mutex */
1849 registeredfunc = lib_infop->functionTable.RegisterForTargetEventsHandler;
1850 if(registeredfunc == NULL) {
1851 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1855 * that allocated memory is used both as the handle for the
1856 * caller, and as userdata to the vendor call so that on
1857 * callback the specific registration may be recalled
1859 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1860 calloc(1, sizeof(HBA_ADAPTERCALLBACK_ELEM));
1861 if(acbp == NULL) {
1862 #ifndef WIN32
1863 fprintf(stderr,
1864 "HBA_RegisterForTargetEvents: calloc failed for %d bytes\n",
1865 sizeof(HBA_ADAPTERCALLBACK_ELEM));
1866 #endif
1867 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1869 *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1870 acbp->callback = callback;
1871 acbp->userdata = userData;
1872 acbp->lib_info = lib_infop;
1874 status = (registeredfunc)(targetevents_callback,
1875 (void *)acbp,
1876 vendorHandle,
1877 hbaPortWWN,
1878 discoveredPortWWN,
1879 &acbp->vendorcbhandle,
1880 allTargets);
1881 if(status != HBA_STATUS_OK) {
1882 free(acbp);
1883 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1886 GRAB_MUTEX(&_hbaapi_TE_mutex);
1887 acbp->next = _hbaapi_targetevents_callback_list;
1888 _hbaapi_targetevents_callback_list = acbp;
1889 RELEASE_MUTEX(&_hbaapi_TE_mutex);
1891 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1894 /* Link Events ****************************************************************/
1895 static void
1896 linkevents_callback (void *data,
1897 HBA_WWN adapterWWN,
1898 HBA_UINT32 eventType,
1899 void *pRLIRBuffer,
1900 HBA_UINT32 RLIRBufferSize) {
1901 HBA_ADAPTERCALLBACK_ELEM *acbp;
1903 DEBUG(3, "LinkEvent, hbaWWN:%s, eventType:%d",
1904 WWN2STR1(&adapterWWN), eventType, 0);
1906 GRAB_MUTEX(&_hbaapi_LE_mutex);
1907 for(acbp = _hbaapi_linkevents_callback_list;
1908 acbp != NULL;
1909 acbp = acbp->next) {
1910 if(data == (void *)acbp) {
1911 (*acbp->callback)(acbp->userdata, adapterWWN,
1912 eventType, pRLIRBuffer, RLIRBufferSize);
1913 break;
1916 RELEASE_MUTEX(&_hbaapi_LE_mutex);
1918 HBA_STATUS
1919 HBA_RegisterForLinkEvents (
1920 void (*callback) (
1921 void *data,
1922 HBA_WWN adapterWWN,
1923 HBA_UINT32 eventType,
1924 void *pRLIRBuffer,
1925 HBA_UINT32 RLIRBufferSize),
1926 void *userData,
1927 void *pRLIRBuffer,
1928 HBA_UINT32 RLIRBufferSize,
1929 HBA_HANDLE handle,
1930 HBA_CALLBACKHANDLE *callbackHandle) {
1932 HBA_ADAPTERCALLBACK_ELEM *acbp;
1933 HBARegisterForLinkEventsFunc
1934 registeredfunc;
1935 HBA_STATUS status;
1936 HBA_LIBRARY_INFO *lib_infop;
1937 HBA_HANDLE vendorHandle;
1939 DEBUG(2, "HBA_RegisterForLinkEvents", 0, 0, 0);
1941 if (callbackHandle == NULL) {
1942 return(HBA_STATUS_ERROR_ARG);
1945 CHECKLIBRARY();
1946 /* we now have the _hbaapi_LL_mutex */
1948 registeredfunc = lib_infop->functionTable.RegisterForLinkEventsHandler;
1949 if(registeredfunc == NULL) {
1950 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED);
1954 * that allocated memory is used both as the handle for the
1955 * caller, and as userdata to the vendor call so that on
1956 * callback the specific registration may be recalled
1958 acbp = (HBA_ADAPTERCALLBACK_ELEM *)
1959 calloc(1, sizeof(HBA_ADAPTERCALLBACK_ELEM));
1960 if(acbp == NULL) {
1961 #ifndef WIN32
1962 fprintf(stderr,
1963 "HBA_RegisterForLinkEvents: calloc failed for %d bytes\n",
1964 sizeof(HBA_ADAPTERCALLBACK_ELEM));
1965 #endif
1966 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR);
1968 *callbackHandle = (HBA_CALLBACKHANDLE) acbp;
1969 acbp->callback = callback;
1970 acbp->userdata = userData;
1971 acbp->lib_info = lib_infop;
1973 status = (registeredfunc)(linkevents_callback,
1974 (void *)acbp,
1975 pRLIRBuffer,
1976 RLIRBufferSize,
1977 vendorHandle,
1978 &acbp->vendorcbhandle);
1979 if(status != HBA_STATUS_OK) {
1980 free(acbp);
1981 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
1984 GRAB_MUTEX(&_hbaapi_LE_mutex);
1985 acbp->next = _hbaapi_linkevents_callback_list;
1986 _hbaapi_linkevents_callback_list = acbp;
1987 RELEASE_MUTEX(&_hbaapi_LE_mutex);
1989 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK);
1994 * All of the functions below are almost passthru functions to the
1995 * vendor specific function
1998 void
1999 HBA_CloseAdapter(HBA_HANDLE handle) {
2000 HBA_STATUS status;
2001 HBA_LIBRARY_INFO *lib_infop;
2002 HBA_HANDLE vendorHandle;
2003 HBACloseAdapterFunc CloseAdapterFunc;
2005 DEBUG(2, "HBA_CloseAdapter", 0, 0, 0);
2007 status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
2008 if (status == HBA_STATUS_OK) {
2009 CloseAdapterFunc = lib_infop->functionTable.CloseAdapterHandler;
2010 if (CloseAdapterFunc != NULL) {
2011 ((CloseAdapterFunc)(vendorHandle));
2013 RELEASE_MUTEX(&_hbaapi_LL_mutex);
2017 HBA_STATUS
2018 HBA_GetAdapterAttributes (
2019 HBA_HANDLE handle,
2020 HBA_ADAPTERATTRIBUTES
2021 *hbaattributes)
2023 HBA_STATUS status;
2024 HBA_LIBRARY_INFO *lib_infop;
2025 HBA_HANDLE vendorHandle;
2026 HBAGetAdapterAttributesFunc GetAdapterAttributesFunc;
2028 DEBUG(2, "HBA_GetAdapterAttributes", 0, 0, 0);
2030 CHECKLIBRARY();
2031 GetAdapterAttributesFunc =
2032 lib_infop->functionTable.GetAdapterAttributesHandler;
2033 if (GetAdapterAttributesFunc != NULL) {
2034 status = ((GetAdapterAttributesFunc)(vendorHandle, hbaattributes));
2035 } else {
2036 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2038 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2041 HBA_STATUS
2042 HBA_GetAdapterPortAttributes (
2043 HBA_HANDLE handle,
2044 HBA_UINT32 portindex,
2045 HBA_PORTATTRIBUTES *portattributes)
2047 HBA_STATUS status;
2048 HBA_LIBRARY_INFO *lib_infop;
2049 HBA_HANDLE vendorHandle;
2050 HBAGetAdapterPortAttributesFunc
2051 GetAdapterPortAttributesFunc;
2053 DEBUG(2, "HBA_GetAdapterPortAttributes", 0, 0, 0);
2055 CHECKLIBRARY();
2056 GetAdapterPortAttributesFunc =
2057 lib_infop->functionTable.GetAdapterPortAttributesHandler;
2058 if (GetAdapterPortAttributesFunc != NULL) {
2059 status = ((GetAdapterPortAttributesFunc)
2060 (vendorHandle, portindex, portattributes));
2061 } else {
2062 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2064 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2067 HBA_STATUS
2068 HBA_GetPortStatistics (
2069 HBA_HANDLE handle,
2070 HBA_UINT32 portindex,
2071 HBA_PORTSTATISTICS *portstatistics)
2073 HBA_STATUS status;
2074 HBA_LIBRARY_INFO *lib_infop;
2075 HBA_HANDLE vendorHandle;
2076 HBAGetPortStatisticsFunc
2077 GetPortStatisticsFunc;
2079 DEBUG(2, "HBA_GetPortStatistics", 0, 0, 0);
2081 CHECKLIBRARY();
2082 GetPortStatisticsFunc =
2083 lib_infop->functionTable.GetPortStatisticsHandler;
2084 if (GetPortStatisticsFunc != NULL) {
2085 status = ((GetPortStatisticsFunc)
2086 (vendorHandle, portindex, portstatistics));
2087 } else {
2088 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2090 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2093 HBA_STATUS
2094 HBA_GetDiscoveredPortAttributes (
2095 HBA_HANDLE handle,
2096 HBA_UINT32 portindex,
2097 HBA_UINT32 discoveredportindex,
2098 HBA_PORTATTRIBUTES *portattributes)
2100 HBA_STATUS status;
2101 HBA_LIBRARY_INFO *lib_infop;
2102 HBA_HANDLE vendorHandle;
2103 HBAGetDiscoveredPortAttributesFunc
2104 GetDiscoveredPortAttributesFunc;
2106 DEBUG(2, "HBA_GetDiscoveredPortAttributes", 0, 0, 0);
2108 CHECKLIBRARY();
2109 GetDiscoveredPortAttributesFunc =
2110 lib_infop->functionTable.GetDiscoveredPortAttributesHandler;
2111 if (GetDiscoveredPortAttributesFunc != NULL) {
2112 status = ((GetDiscoveredPortAttributesFunc)
2113 (vendorHandle, portindex, discoveredportindex,
2114 portattributes));
2115 } else {
2116 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2118 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2121 HBA_STATUS
2122 HBA_GetPortAttributesByWWN (
2123 HBA_HANDLE handle,
2124 HBA_WWN PortWWN,
2125 HBA_PORTATTRIBUTES *portattributes)
2127 HBA_STATUS status;
2128 HBA_LIBRARY_INFO *lib_infop;
2129 HBA_HANDLE vendorHandle;
2130 HBAGetPortAttributesByWWNFunc
2131 GetPortAttributesByWWNFunc;
2133 DEBUG(2, "HBA_GetPortAttributesByWWN: %s", WWN2STR1(&PortWWN), 0, 0);
2135 CHECKLIBRARY();
2136 GetPortAttributesByWWNFunc =
2137 lib_infop->functionTable.GetPortAttributesByWWNHandler;
2138 if (GetPortAttributesByWWNFunc != NULL) {
2139 status = ((GetPortAttributesByWWNFunc)
2140 (vendorHandle, PortWWN, portattributes));
2141 } else {
2142 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2144 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2147 HBA_STATUS
2148 HBA_SendCTPassThru (
2149 HBA_HANDLE handle,
2150 void *pReqBuffer,
2151 HBA_UINT32 ReqBufferSize,
2152 void *pRspBuffer,
2153 HBA_UINT32 RspBufferSize)
2155 HBA_STATUS status;
2156 HBA_LIBRARY_INFO *lib_infop;
2157 HBA_HANDLE vendorHandle;
2158 HBASendCTPassThruFunc
2159 SendCTPassThruFunc;
2161 DEBUG(2, "HBA_SendCTPassThru", 0, 0, 0);
2163 CHECKLIBRARY();
2164 SendCTPassThruFunc = lib_infop->functionTable.SendCTPassThruHandler;
2165 if (SendCTPassThruFunc != NULL) {
2166 status = (SendCTPassThruFunc)
2167 (vendorHandle,
2168 pReqBuffer, ReqBufferSize,
2169 pRspBuffer, RspBufferSize);
2170 } else {
2171 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2173 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2176 HBA_STATUS
2177 HBA_SendCTPassThruV2 (
2178 HBA_HANDLE handle,
2179 HBA_WWN hbaPortWWN,
2180 void *pReqBuffer,
2181 HBA_UINT32 ReqBufferSize,
2182 void *pRspBuffer,
2183 HBA_UINT32 *pRspBufferSize)
2185 HBA_STATUS status;
2186 HBA_LIBRARY_INFO *lib_infop;
2187 HBA_HANDLE vendorHandle;
2188 HBASendCTPassThruV2Func
2189 registeredfunc;
2191 DEBUG(2, "HBA_SendCTPassThruV2m hbaPortWWN: %s", WWN2STR1(&hbaPortWWN), 0, 0);
2193 CHECKLIBRARY();
2194 registeredfunc = lib_infop->functionTable.SendCTPassThruV2Handler;
2195 if (registeredfunc != NULL) {
2196 status = (registeredfunc)
2197 (vendorHandle, hbaPortWWN,
2198 pReqBuffer, ReqBufferSize,
2199 pRspBuffer, pRspBufferSize);
2200 } else {
2201 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2203 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2206 HBA_STATUS
2207 HBA_GetEventBuffer (
2208 HBA_HANDLE handle,
2209 PHBA_EVENTINFO EventBuffer,
2210 HBA_UINT32 *EventBufferCount)
2212 HBA_STATUS status;
2213 HBA_LIBRARY_INFO *lib_infop;
2214 HBA_HANDLE vendorHandle;
2215 HBAGetEventBufferFunc
2216 GetEventBufferFunc;
2218 DEBUG(2, "HBA_GetEventBuffer", 0, 0, 0);
2220 CHECKLIBRARY();
2221 GetEventBufferFunc = lib_infop->functionTable.GetEventBufferHandler;
2222 if (GetEventBufferFunc != NULL) {
2223 status = (GetEventBufferFunc)
2224 (vendorHandle, EventBuffer, EventBufferCount);
2225 } else {
2226 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2228 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2231 HBA_STATUS
2232 HBA_SetRNIDMgmtInfo (HBA_HANDLE handle, HBA_MGMTINFO Info) {
2233 HBA_STATUS status;
2234 HBA_LIBRARY_INFO *lib_infop;
2235 HBA_HANDLE vendorHandle;
2236 HBASetRNIDMgmtInfoFunc
2237 SetRNIDMgmtInfoFunc;
2239 DEBUG(2, "HBA_SetRNIDMgmtInfo", 0, 0, 0);
2241 CHECKLIBRARY();
2242 SetRNIDMgmtInfoFunc = lib_infop->functionTable.SetRNIDMgmtInfoHandler;
2243 if (SetRNIDMgmtInfoFunc != NULL) {
2244 status = (SetRNIDMgmtInfoFunc)(vendorHandle, Info);
2245 } else {
2246 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2248 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2251 HBA_STATUS
2252 HBA_GetRNIDMgmtInfo (HBA_HANDLE handle, HBA_MGMTINFO *pInfo) {
2253 HBA_STATUS status;
2254 HBA_LIBRARY_INFO *lib_infop;
2255 HBA_HANDLE vendorHandle;
2256 HBAGetRNIDMgmtInfoFunc
2257 GetRNIDMgmtInfoFunc;
2259 DEBUG(2, "HBA_GetRNIDMgmtInfo", 0, 0, 0);
2261 CHECKLIBRARY();
2262 GetRNIDMgmtInfoFunc = lib_infop->functionTable.GetRNIDMgmtInfoHandler;
2263 if (GetRNIDMgmtInfoFunc != NULL) {
2264 status = (GetRNIDMgmtInfoFunc)(vendorHandle, pInfo);
2265 } else {
2266 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2268 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2271 HBA_STATUS
2272 HBA_SendRNID (
2273 HBA_HANDLE handle,
2274 HBA_WWN wwn,
2275 HBA_WWNTYPE wwntype,
2276 void *pRspBuffer,
2277 HBA_UINT32 *pRspBufferSize)
2279 HBA_STATUS status;
2280 HBA_LIBRARY_INFO *lib_infop;
2281 HBA_HANDLE vendorHandle;
2282 HBASendRNIDFunc SendRNIDFunc;
2284 DEBUG(2, "HBA_SendRNID for wwn: %s", WWN2STR1(&wwn), 0, 0);
2286 CHECKLIBRARY();
2287 SendRNIDFunc = lib_infop->functionTable.SendRNIDHandler;
2288 if (SendRNIDFunc != NULL) {
2289 status = ((SendRNIDFunc)(vendorHandle, wwn, wwntype,
2290 pRspBuffer, pRspBufferSize));
2291 } else {
2292 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2294 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2297 HBA_STATUS
2298 HBA_SendRNIDV2(
2299 HBA_HANDLE handle,
2300 HBA_WWN hbaPortWWN,
2301 HBA_WWN destWWN,
2302 HBA_UINT32 destFCID,
2303 HBA_UINT32 NodeIdDataFormat,
2304 void *pRspBuffer,
2305 HBA_UINT32 *pRspBufferSize)
2307 HBA_STATUS status;
2308 HBA_LIBRARY_INFO *lib_infop;
2309 HBA_HANDLE vendorHandle;
2310 HBASendRNIDV2Func registeredfunc;
2312 DEBUG(2, "HBA_SendRNIDV2, hbaPortWWN: %s", WWN2STR1(&hbaPortWWN), 0, 0);
2314 CHECKLIBRARY();
2315 registeredfunc = lib_infop->functionTable.SendRNIDV2Handler;
2316 if (registeredfunc != NULL) {
2317 status = (registeredfunc)
2318 (vendorHandle, hbaPortWWN, destWWN, destFCID, NodeIdDataFormat,
2319 pRspBuffer, pRspBufferSize);
2320 } else {
2321 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2323 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2326 void
2327 HBA_RefreshInformation (HBA_HANDLE handle) {
2328 HBA_STATUS status;
2329 HBA_LIBRARY_INFO *lib_infop;
2330 HBA_HANDLE vendorHandle;
2331 HBARefreshInformationFunc
2332 RefreshInformationFunc;
2334 DEBUG(2, "HBA_RefreshInformation", 0, 0, 0);
2336 status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
2337 if(status == HBA_STATUS_OK) {
2338 RefreshInformationFunc =
2339 lib_infop->functionTable.RefreshInformationHandler;
2340 if (RefreshInformationFunc != NULL) {
2341 ((RefreshInformationFunc)(vendorHandle));
2343 RELEASE_MUTEX(&_hbaapi_LL_mutex);
2347 void
2348 HBA_ResetStatistics (HBA_HANDLE handle, HBA_UINT32 portindex) {
2349 HBA_STATUS status;
2350 HBA_LIBRARY_INFO *lib_infop;
2351 HBA_HANDLE vendorHandle;
2352 HBAResetStatisticsFunc
2353 ResetStatisticsFunc;
2355 DEBUG(2, "HBA_ResetStatistics", 0, 0, 0);
2357 status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);
2358 if(status == HBA_STATUS_OK) {
2359 ResetStatisticsFunc = lib_infop->functionTable.ResetStatisticsHandler;
2360 if (ResetStatisticsFunc != NULL) {
2361 ((ResetStatisticsFunc)(vendorHandle, portindex));
2363 RELEASE_MUTEX(&_hbaapi_LL_mutex);
2367 HBA_STATUS
2368 HBA_GetFcpTargetMapping (HBA_HANDLE handle, PHBA_FCPTARGETMAPPING mapping) {
2369 HBA_STATUS status;
2370 HBA_LIBRARY_INFO *lib_infop;
2371 HBA_HANDLE vendorHandle;
2372 HBAGetFcpTargetMappingFunc GetFcpTargetMappingFunc;
2374 DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0);
2376 CHECKLIBRARY();
2377 GetFcpTargetMappingFunc =
2378 lib_infop->functionTable.GetFcpTargetMappingHandler;
2379 if (GetFcpTargetMappingFunc != NULL) {
2380 status = ((GetFcpTargetMappingFunc)(vendorHandle, mapping));
2381 } else {
2382 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2384 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2387 HBA_STATUS
2388 HBA_GetFcpTargetMappingV2 (
2389 HBA_HANDLE handle,
2390 HBA_WWN hbaPortWWN,
2391 HBA_FCPTARGETMAPPINGV2
2392 *pmapping)
2394 HBA_STATUS status;
2395 HBA_LIBRARY_INFO *lib_infop;
2396 HBA_HANDLE vendorHandle;
2397 HBAGetFcpTargetMappingV2Func
2398 registeredfunc;
2400 DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0);
2402 CHECKLIBRARY();
2403 registeredfunc =
2404 lib_infop->functionTable.GetFcpTargetMappingV2Handler;
2405 if (registeredfunc != NULL) {
2406 status = ((registeredfunc)(vendorHandle, hbaPortWWN, pmapping));
2407 } else {
2408 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2410 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2413 HBA_STATUS
2414 HBA_GetFcpPersistentBinding (HBA_HANDLE handle, PHBA_FCPBINDING binding) {
2415 HBA_STATUS status;
2416 HBA_LIBRARY_INFO *lib_infop;
2417 HBA_HANDLE vendorHandle;
2418 HBAGetFcpPersistentBindingFunc
2419 GetFcpPersistentBindingFunc;
2421 DEBUG(2, "HBA_GetFcpPersistentBinding", 0, 0, 0);
2423 CHECKLIBRARY();
2424 GetFcpPersistentBindingFunc =
2425 lib_infop->functionTable.GetFcpPersistentBindingHandler;
2426 if (GetFcpPersistentBindingFunc != NULL) {
2427 status = ((GetFcpPersistentBindingFunc)(vendorHandle, binding));
2428 } else {
2429 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2431 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2434 HBA_STATUS
2435 HBA_ScsiInquiryV2 (
2436 HBA_HANDLE handle,
2437 HBA_WWN hbaPortWWN,
2438 HBA_WWN discoveredPortWWN,
2439 HBA_UINT64 fcLUN,
2440 HBA_UINT8 CDB_Byte1,
2441 HBA_UINT8 CDB_Byte2,
2442 void *pRspBuffer,
2443 HBA_UINT32 *pRspBufferSize,
2444 HBA_UINT8 *pScsiStatus,
2445 void *pSenseBuffer,
2446 HBA_UINT32 *pSenseBufferSize)
2448 HBA_STATUS status;
2449 HBA_LIBRARY_INFO *lib_infop;
2450 HBA_HANDLE vendorHandle;
2451 HBAScsiInquiryV2Func ScsiInquiryV2Func;
2453 DEBUG(2, "HBA_ScsiInquiryV2 to discoveredPortWWN: %s",
2454 WWN2STR1(&discoveredPortWWN), 0, 0);
2456 CHECKLIBRARY();
2457 ScsiInquiryV2Func =
2458 lib_infop->functionTable.ScsiInquiryV2Handler;
2459 if (ScsiInquiryV2Func != NULL) {
2460 status =((ScsiInquiryV2Func)(
2461 vendorHandle, hbaPortWWN, discoveredPortWWN, fcLUN, CDB_Byte1,
2462 CDB_Byte2, pRspBuffer, pRspBufferSize, pScsiStatus,
2463 pSenseBuffer, pSenseBufferSize));
2464 } else {
2465 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2467 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2470 HBA_STATUS
2471 HBA_SendScsiInquiry (
2472 HBA_HANDLE handle,
2473 HBA_WWN PortWWN,
2474 HBA_UINT64 fcLUN,
2475 HBA_UINT8 EVPD,
2476 HBA_UINT32 PageCode,
2477 void *pRspBuffer,
2478 HBA_UINT32 RspBufferSize,
2479 void *pSenseBuffer,
2480 HBA_UINT32 SenseBufferSize)
2482 HBA_STATUS status;
2483 HBA_LIBRARY_INFO *lib_infop;
2484 HBA_HANDLE vendorHandle;
2485 HBASendScsiInquiryFunc SendScsiInquiryFunc;
2487 DEBUG(2, "HBA_SendScsiInquiry to PortWWN: %s", WWN2STR1(&PortWWN), 0, 0);
2489 CHECKLIBRARY();
2490 SendScsiInquiryFunc = lib_infop->functionTable.ScsiInquiryHandler;
2491 if (SendScsiInquiryFunc != NULL) {
2492 status =((SendScsiInquiryFunc)(
2493 vendorHandle, PortWWN, fcLUN, EVPD, PageCode, pRspBuffer,
2494 RspBufferSize, pSenseBuffer, SenseBufferSize));
2495 } else {
2496 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2498 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2501 HBA_STATUS
2502 HBA_ScsiReportLUNsV2 (
2503 HBA_HANDLE handle,
2504 HBA_WWN hbaPortWWN,
2505 HBA_WWN discoveredPortWWN,
2506 void *pRespBuffer,
2507 HBA_UINT32 *pRespBufferSize,
2508 HBA_UINT8 *pScsiStatus,
2509 void *pSenseBuffer,
2510 HBA_UINT32 *pSenseBufferSize)
2512 HBA_STATUS status;
2513 HBA_LIBRARY_INFO *lib_infop;
2514 HBA_HANDLE vendorHandle;
2515 HBAScsiReportLUNsV2Func ScsiReportLUNsV2Func;
2517 DEBUG(2, "HBA_ScsiReportLUNsV2 to discoveredPortWWN: %s",
2518 WWN2STR1(&discoveredPortWWN), 0, 0);
2520 CHECKLIBRARY();
2521 ScsiReportLUNsV2Func = lib_infop->functionTable.ScsiReportLUNsV2Handler;
2522 if (ScsiReportLUNsV2Func != NULL) {
2523 status = ((ScsiReportLUNsV2Func)(
2524 vendorHandle, hbaPortWWN, discoveredPortWWN,
2525 pRespBuffer, pRespBufferSize,
2526 pScsiStatus,
2527 pSenseBuffer, pSenseBufferSize));
2528 } else {
2529 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2531 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2534 HBA_STATUS
2535 HBA_SendReportLUNs (
2536 HBA_HANDLE handle,
2537 HBA_WWN portWWN,
2538 void *pRspBuffer,
2539 HBA_UINT32 RspBufferSize,
2540 void *pSenseBuffer,
2541 HBA_UINT32 SenseBufferSize)
2543 HBA_STATUS status;
2544 HBA_LIBRARY_INFO *lib_infop;
2545 HBA_HANDLE vendorHandle;
2546 HBASendReportLUNsFunc SendReportLUNsFunc;
2548 DEBUG(2, "HBA_SendReportLUNs to PortWWN: %s", WWN2STR1(&portWWN), 0, 0);
2550 CHECKLIBRARY();
2551 SendReportLUNsFunc = lib_infop->functionTable.ReportLUNsHandler;
2552 if (SendReportLUNsFunc != NULL) {
2553 status = ((SendReportLUNsFunc)(
2554 vendorHandle, portWWN, pRspBuffer,
2555 RspBufferSize, pSenseBuffer, SenseBufferSize));
2556 } else {
2557 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2559 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2562 HBA_STATUS
2563 HBA_ScsiReadCapacityV2 (
2564 HBA_HANDLE handle,
2565 HBA_WWN hbaPortWWN,
2566 HBA_WWN discoveredPortWWN,
2567 HBA_UINT64 fcLUN,
2568 void *pRspBuffer,
2569 HBA_UINT32 *pRspBufferSize,
2570 HBA_UINT8 *pScsiStatus,
2571 void *pSenseBuffer,
2572 HBA_UINT32 *SenseBufferSize)
2574 HBA_STATUS status;
2575 HBA_LIBRARY_INFO *lib_infop;
2576 HBA_HANDLE vendorHandle;
2577 HBAScsiReadCapacityV2Func ScsiReadCapacityV2Func;
2579 DEBUG(2, "HBA_ScsiReadCapacityV2 to discoveredPortWWN: %s",
2580 WWN2STR1(&discoveredPortWWN), 0, 0);
2582 CHECKLIBRARY();
2583 ScsiReadCapacityV2Func =
2584 lib_infop->functionTable.ScsiReadCapacityV2Handler;
2585 if (ScsiReadCapacityV2Func != NULL) {
2586 status =((ScsiReadCapacityV2Func)(
2587 vendorHandle, hbaPortWWN, discoveredPortWWN, fcLUN,
2588 pRspBuffer, pRspBufferSize,
2589 pScsiStatus,
2590 pSenseBuffer, SenseBufferSize));
2591 } else {
2592 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2594 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2597 HBA_STATUS
2598 HBA_SendReadCapacity (
2599 HBA_HANDLE handle,
2600 HBA_WWN portWWN,
2601 HBA_UINT64 fcLUN,
2602 void *pRspBuffer,
2603 HBA_UINT32 RspBufferSize,
2604 void *pSenseBuffer,
2605 HBA_UINT32 SenseBufferSize)
2607 HBA_STATUS status;
2608 HBA_LIBRARY_INFO *lib_infop;
2609 HBA_HANDLE vendorHandle;
2610 HBASendReadCapacityFunc SendReadCapacityFunc;
2612 DEBUG(2, "HBA_SendReadCapacity to portWWN: %s", WWN2STR1(&portWWN), 0, 0);
2614 CHECKLIBRARY();
2615 SendReadCapacityFunc = lib_infop->functionTable.ReadCapacityHandler;
2616 if (SendReadCapacityFunc != NULL) {
2617 status =((SendReadCapacityFunc)
2618 (vendorHandle, portWWN, fcLUN, pRspBuffer,
2619 RspBufferSize, pSenseBuffer, SenseBufferSize));
2620 } else {
2621 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2623 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2626 HBA_STATUS
2627 HBA_SendRLS (
2628 HBA_HANDLE handle,
2629 HBA_WWN hbaPortWWN,
2630 HBA_WWN destWWN,
2631 void *pRspBuffer,
2632 HBA_UINT32 *pRspBufferSize)
2634 HBA_STATUS status;
2635 HBA_LIBRARY_INFO *lib_infop;
2636 HBA_HANDLE vendorHandle;
2637 HBASendRLSFunc registeredfunc;
2639 DEBUG(2, "HBA_SendRLS to agent_wwn: %s:%d",
2640 WWN2STR1(&agent_wwn), agent_domain, 0);
2642 CHECKLIBRARY();
2643 registeredfunc = lib_infop->functionTable.SendRLSHandler;
2644 if (registeredfunc != NULL) {
2645 status =(registeredfunc)(
2646 vendorHandle, hbaPortWWN, destWWN, pRspBuffer, pRspBufferSize);
2647 } else {
2648 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2650 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2653 HBA_STATUS
2654 HBA_SendRPL (
2655 HBA_HANDLE handle,
2656 HBA_WWN hbaPortWWN,
2657 HBA_WWN agent_wwn,
2658 HBA_UINT32 agent_domain,
2659 HBA_UINT32 portindex,
2660 void *pRspBuffer,
2661 HBA_UINT32 *pRspBufferSize)
2663 HBA_STATUS status;
2664 HBA_LIBRARY_INFO *lib_infop;
2665 HBA_HANDLE vendorHandle;
2666 HBASendRPLFunc registeredfunc;
2668 DEBUG(2, "HBA_SendRPL to agent_wwn: %s:%d",
2669 WWN2STR1(&agent_wwn), agent_domain, 0);
2671 CHECKLIBRARY();
2672 registeredfunc = lib_infop->functionTable.SendRPLHandler;
2673 if (registeredfunc != NULL) {
2674 status =(registeredfunc)(
2675 vendorHandle, hbaPortWWN, agent_wwn, agent_domain, portindex,
2676 pRspBuffer, pRspBufferSize);
2677 } else {
2678 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2680 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2683 HBA_STATUS
2684 HBA_SendRPS (
2685 HBA_HANDLE handle,
2686 HBA_WWN hbaPortWWN,
2687 HBA_WWN agent_wwn,
2688 HBA_UINT32 agent_domain,
2689 HBA_WWN object_wwn,
2690 HBA_UINT32 object_port_number,
2691 void *pRspBuffer,
2692 HBA_UINT32 *pRspBufferSize)
2694 HBA_STATUS status;
2695 HBA_LIBRARY_INFO *lib_infop;
2696 HBA_HANDLE vendorHandle;
2697 HBASendRPSFunc registeredfunc;
2699 DEBUG(2, "HBA_SendRPS to agent_wwn: %s:%d",
2700 WWN2STR1(&agent_wwn), agent_domain, 0);
2702 CHECKLIBRARY();
2703 registeredfunc = lib_infop->functionTable.SendRPSHandler;
2704 if (registeredfunc != NULL) {
2705 status =(registeredfunc)(
2706 vendorHandle, hbaPortWWN, agent_wwn, agent_domain,
2707 object_wwn, object_port_number,
2708 pRspBuffer, pRspBufferSize);
2709 } else {
2710 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2712 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2715 HBA_STATUS
2716 HBA_SendSRL (
2717 HBA_HANDLE handle,
2718 HBA_WWN hbaPortWWN,
2719 HBA_WWN wwn,
2720 HBA_UINT32 domain,
2721 void *pRspBuffer,
2722 HBA_UINT32 *pRspBufferSize)
2724 HBA_STATUS status;
2725 HBA_LIBRARY_INFO *lib_infop;
2726 HBA_HANDLE vendorHandle;
2727 HBASendSRLFunc registeredfunc;
2729 DEBUG(2, "HBA_SendSRL to wwn:%s domain:%d", WWN2STR1(&wwn), domain, 0);
2731 CHECKLIBRARY();
2732 registeredfunc = lib_infop->functionTable.SendSRLHandler;
2733 if (registeredfunc != NULL) {
2734 status =(registeredfunc)(
2735 vendorHandle, hbaPortWWN, wwn, domain,
2736 pRspBuffer, pRspBufferSize);
2737 } else {
2738 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2740 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2743 HBA_STATUS
2744 HBA_SendLIRR (
2745 HBA_HANDLE handle,
2746 HBA_WWN sourceWWN,
2747 HBA_WWN destWWN,
2748 HBA_UINT8 function,
2749 HBA_UINT8 type,
2750 void *pRspBuffer,
2751 HBA_UINT32 *pRspBufferSize)
2753 HBA_STATUS status;
2754 HBA_LIBRARY_INFO *lib_infop;
2755 HBA_HANDLE vendorHandle;
2756 HBASendLIRRFunc registeredfunc;
2758 DEBUG(2, "HBA_SendLIRR destWWN:%s", WWN2STR1(&destWWN), 0, 0);
2760 CHECKLIBRARY();
2761 registeredfunc = lib_infop->functionTable.SendLIRRHandler;
2762 if (registeredfunc != NULL) {
2763 status =(registeredfunc)(
2764 vendorHandle, sourceWWN, destWWN, function, type,
2765 pRspBuffer, pRspBufferSize);
2766 } else {
2767 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2769 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2772 HBA_STATUS
2773 HBA_GetBindingCapability(
2774 HBA_HANDLE handle,
2775 HBA_WWN hbaPortWWN,
2776 HBA_BIND_CAPABILITY *pcapability)
2778 HBA_STATUS status;
2779 HBA_LIBRARY_INFO *lib_infop;
2780 HBA_HANDLE vendorHandle;
2781 HBAGetBindingCapabilityFunc
2782 registeredfunc;
2784 DEBUG(2, "HBA_GetBindingCapability", 0, 0, 0);
2786 CHECKLIBRARY();
2787 registeredfunc = lib_infop->functionTable.GetBindingCapabilityHandler;
2788 if (registeredfunc != NULL) {
2789 status =(registeredfunc)(vendorHandle, hbaPortWWN, pcapability);
2790 } else {
2791 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2793 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2796 HBA_STATUS
2797 HBA_GetBindingSupport (
2798 HBA_HANDLE handle,
2799 HBA_WWN hbaPortWWN,
2800 HBA_BIND_CAPABILITY *pcapability)
2802 HBA_STATUS status;
2803 HBA_LIBRARY_INFO *lib_infop;
2804 HBA_HANDLE vendorHandle;
2805 HBAGetBindingSupportFunc
2806 registeredfunc;
2808 DEBUG(2, "HBA_GetBindingSupport", 0, 0, 0);
2810 CHECKLIBRARY();
2811 registeredfunc = lib_infop->functionTable.GetBindingSupportHandler;
2812 if (registeredfunc != NULL) {
2813 status =(registeredfunc)(vendorHandle, hbaPortWWN, pcapability);
2814 } else {
2815 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2817 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2820 HBA_STATUS
2821 HBA_SetBindingSupport(
2822 HBA_HANDLE handle,
2823 HBA_WWN hbaPortWWN,
2824 HBA_BIND_CAPABILITY capability)
2826 HBA_STATUS status;
2827 HBA_LIBRARY_INFO *lib_infop;
2828 HBA_HANDLE vendorHandle;
2829 HBASetBindingSupportFunc
2830 registeredfunc;
2832 DEBUG(2, "HBA_SetBindingSupport", 0, 0, 0);
2834 CHECKLIBRARY();
2835 registeredfunc = lib_infop->functionTable.SetBindingSupportHandler;
2836 if (registeredfunc != NULL) {
2837 status =(registeredfunc)(vendorHandle, hbaPortWWN, capability);
2838 } else {
2839 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2841 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2844 HBA_STATUS
2845 HBA_SetPersistentBindingV2 (
2846 HBA_HANDLE handle,
2847 HBA_WWN hbaPortWWN,
2848 const HBA_FCPBINDING2
2849 *pbinding)
2851 HBA_STATUS status;
2852 HBA_LIBRARY_INFO *lib_infop;
2853 HBA_HANDLE vendorHandle;
2854 HBASetPersistentBindingV2Func
2855 registeredfunc;
2857 DEBUG(2, "HBA_SetPersistentBindingV2 port: %s", WWN2STR1(&hbaPortWWN), 0, 0);
2859 CHECKLIBRARY();
2860 registeredfunc = lib_infop->functionTable.SetPersistentBindingV2Handler;
2861 if (registeredfunc != NULL) {
2862 status =(registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
2863 } else {
2864 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2866 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2869 HBA_STATUS
2870 HBA_GetPersistentBindingV2 (
2871 HBA_HANDLE handle,
2872 HBA_WWN hbaPortWWN,
2873 HBA_FCPBINDING2 *pbinding)
2875 HBA_STATUS status;
2876 HBA_LIBRARY_INFO *lib_infop;
2877 HBA_HANDLE vendorHandle;
2878 HBAGetPersistentBindingV2Func
2879 registeredfunc;
2881 DEBUG(2, "HBA_GetPersistentBindingV2 port: %s", WWN2STR1(&hbaPortWWN), 0, 0);
2883 CHECKLIBRARY();
2884 registeredfunc = lib_infop->functionTable.GetPersistentBindingV2Handler;
2885 if (registeredfunc != NULL) {
2886 status =(registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
2887 } else {
2888 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2890 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2893 HBA_STATUS
2894 HBA_RemovePersistentBinding (
2895 HBA_HANDLE handle,
2896 HBA_WWN hbaPortWWN,
2897 const HBA_FCPBINDING2
2898 *pbinding)
2900 HBA_STATUS status;
2901 HBA_LIBRARY_INFO *lib_infop;
2902 HBA_HANDLE vendorHandle;
2903 HBARemovePersistentBindingFunc
2904 registeredfunc;
2906 DEBUG(2, "HBA_RemovePersistentBinding", 0, 0, 0);
2908 CHECKLIBRARY();
2909 registeredfunc =
2910 lib_infop->functionTable.RemovePersistentBindingHandler;
2911 if (registeredfunc != NULL) {
2912 status =(registeredfunc)(vendorHandle, hbaPortWWN, pbinding);
2913 } else {
2914 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2916 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2919 HBA_STATUS
2920 HBA_RemoveAllPersistentBindings (
2921 HBA_HANDLE handle,
2922 HBA_WWN hbaPortWWN)
2924 HBA_STATUS status;
2925 HBA_LIBRARY_INFO *lib_infop;
2926 HBA_HANDLE vendorHandle;
2927 HBARemoveAllPersistentBindingsFunc
2928 registeredfunc;
2930 DEBUG(2, "HBA_RemoveAllPersistentBindings", 0, 0, 0);
2932 CHECKLIBRARY();
2933 registeredfunc =
2934 lib_infop->functionTable.RemoveAllPersistentBindingsHandler;
2935 if (registeredfunc != NULL) {
2936 status =(registeredfunc)(vendorHandle, hbaPortWWN);
2937 } else {
2938 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2940 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2943 HBA_STATUS
2944 HBA_GetFC4Statistics (
2945 HBA_HANDLE handle,
2946 HBA_WWN portWWN,
2947 HBA_UINT8 FC4type,
2948 HBA_FC4STATISTICS *pstatistics)
2950 HBA_STATUS status;
2951 HBA_LIBRARY_INFO *lib_infop;
2952 HBA_HANDLE vendorHandle;
2953 HBAGetFC4StatisticsFunc
2954 registeredfunc;
2956 DEBUG(2, "HBA_GetFC4Statistics port: %s", WWN2STR1(&portWWN), 0, 0);
2958 CHECKLIBRARY();
2959 registeredfunc =
2960 lib_infop->functionTable.GetFC4StatisticsHandler;
2961 if (registeredfunc != NULL) {
2962 status =(registeredfunc)
2963 (vendorHandle, portWWN, FC4type, pstatistics);
2964 } else {
2965 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2967 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2970 HBA_STATUS
2971 HBA_GetFCPStatistics (
2972 HBA_HANDLE handle,
2973 const HBA_SCSIID *lunit,
2974 HBA_FC4STATISTICS *pstatistics)
2976 HBA_STATUS status;
2977 HBA_LIBRARY_INFO *lib_infop;
2978 HBA_HANDLE vendorHandle;
2979 HBAGetFCPStatisticsFunc
2980 registeredfunc;
2982 DEBUG(2, "HBA_GetFCPStatistics", 0, 0, 0);
2984 CHECKLIBRARY();
2985 registeredfunc =
2986 lib_infop->functionTable.GetFCPStatisticsHandler;
2987 if (registeredfunc != NULL) {
2988 status =(registeredfunc)(vendorHandle, lunit, pstatistics);
2989 } else {
2990 status = HBA_STATUS_ERROR_NOT_SUPPORTED;
2992 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status);
2995 HBA_UINT32
2996 HBA_GetVendorLibraryAttributes (
2997 HBA_UINT32 adapter_index,
2998 HBA_LIBRARYATTRIBUTES *attributes)
3000 HBA_ADAPTER_INFO *adapt_infop;
3001 HBAGetVendorLibraryAttributesFunc
3002 registeredfunc;
3003 HBA_UINT32 ret = 0;
3005 DEBUG(2, "HBA_GetVendorLibraryAttributes adapterindex:%d",
3006 adapter_index, 0, 0);
3007 if(_hbaapi_librarylist == NULL) {
3008 DEBUG(1, "HBAAPI not loaded yet.", 0, 0, 0);
3009 return(0);
3012 if (attributes == NULL) {
3013 return(HBA_STATUS_ERROR_ARG);
3016 memset(attributes, 0, sizeof(HBA_LIBRARYATTRIBUTES));
3018 GRAB_MUTEX(&_hbaapi_LL_mutex);
3019 GRAB_MUTEX(&_hbaapi_AL_mutex);
3020 for(adapt_infop = _hbaapi_adapterlist;
3021 adapt_infop != NULL;
3022 adapt_infop = adapt_infop->next) {
3024 if(adapt_infop->index == adapter_index) {
3025 registeredfunc = adapt_infop->library->
3026 functionTable.GetVendorLibraryAttributesHandler;
3027 if(registeredfunc != NULL) {
3028 ret = (registeredfunc)(attributes);
3029 } else {
3030 /* Version 1 libary? */
3031 HBAGetVersionFunc GetVersionFunc;
3032 GetVersionFunc = adapt_infop->library->
3033 functionTable.GetVersionHandler;
3034 if(GetVersionFunc != NULL) {
3035 ret = ((GetVersionFunc)());
3037 #ifdef NOTDEF
3038 else {
3039 /* This should not happen, dont think its going to */
3041 #endif
3043 if (attributes->LibPath[0] == '\0') {
3044 if(strlen(adapt_infop->library->LibraryPath) < 256) {
3045 strcpy(attributes->LibPath,
3046 adapt_infop->library->LibraryPath);
3049 break;
3052 RELEASE_MUTEX(&_hbaapi_AL_mutex);
3053 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, ret);