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