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 <stdlib.h> 48 #ifdef USESYSLOG 49 #include <syslog.h> 50 #endif 51 52 /* 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 55 */ 56 #define LIBRARY_NUM(handle) ((handle)>>16) 57 58 /* 59 * VENDOR_HANDLE turns a global library handle into a vendor specific handle, 60 * with all upper 16 bits set to 0 61 */ 62 #define VENDOR_HANDLE(handle) ((handle)&0xFFFF) 63 64 #define HBA_HANDLE_FROM_LOCAL(library, vendor) \ 65 (((library)<<16) | ((vendor)&0x0000FFFF)) 66 67 int _hbaapi_debuglevel = 0; 68 #define DEBUG(L, STR, A1, A2, A3) 69 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;\ 80 }\ 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");\ 87 }\ 88 if(_hbaapi_debug_fd != NULL) {\ 89 fprintf(_hbaapi_debug_fd, (STR ## "\n"), (A1), (A2), (A3));\ 90 }\ 91 } 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;\ 98 }\ 99 syslog (LOG_INFO, (STR), (A1), (A2), (A3));\ 100 if(_hbaapi_debug_fd == NULL) {\ 101 _hbaapi_debug_fd = fopen("/tmp/HBAAPI.log", "a");\ 102 }\ 103 if(_hbaapi_debug_fd != NULL) {\ 104 fprintf(_hbaapi_debug_fd, (STR ## "\n"), (A1), (A2), (A3));\ 105 }\ 106 } 107 #endif /* WIN32*/ 108 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;\ 118 }\ 119 syslog (LOG_INFO, (STR), (A1), (A2), (A3));\ 120 } 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");\ 133 }\ 134 } 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");\ 140 }\ 141 if(_hbaapi_debug_fd != NULL) { \ 142 fprintf(_hbaapi_debug_fd, (STR) ## "\n", (A1), (A2), (A3));\ 143 }\ 144 } 145 #endif /* WIN32 */ 146 #endif /* USELOGFILE */ 147 #endif /* Not both USELOGFILE and USESYSLOG */ 148 149 #ifdef POSIX_THREADS 150 #include <pthread.h> 151 /* 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. 160 */ 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 173 174 /* 175 * Vendor library information 176 */ 177 typedef enum { 178 HBA_LIBRARY_UNKNOWN, 179 HBA_LIBRARY_LOADED, 180 HBA_LIBRARY_NOT_LOADED 181 } HBA_LIBRARY_STATUS; 182 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; 197 198 #define ARE_WE_INITED() \ 199 if (_hbaapi_librarylist == NULL) { \ 200 return(HBA_STATUS_ERROR); \ 201 } 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 209 210 /* 211 * Individual adapter (hba) information 212 */ 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; 222 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 230 231 /* 232 * Call back registration 233 */ 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; 240 241 /* 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 245 */ 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; 254 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; 262 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 286 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}; 295 296 /* 297 * Common library internal. Mutex handling 298 */ 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); 306 } 307 } 308 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); 315 } 316 } 317 #endif 318 319 /* 320 * Common library internal. Check library and return vendorhandle 321 */ 322 static HBA_STATUS 323 HBA_CheckLibrary(HBA_HANDLE handle, 324 HBA_LIBRARY_INFO **lib_infopp, 325 HBA_HANDLE *vendorhandle) { 326 327 HBA_UINT32 libraryIndex; 328 HBA_LIBRARY_INFO *lib_infop; 329 330 if (vendorhandle == NULL) { 331 return(HBA_STATUS_ERROR_ARG); 332 } 333 if(_hbaapi_librarylist == NULL) { 334 return(HBA_STATUS_ERROR); 335 } 336 libraryIndex = LIBRARY_NUM(handle); 337 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; 345 } 346 *lib_infopp = lib_infop; 347 *vendorhandle = VENDOR_HANDLE(handle); 348 /* caller will release the mutex */ 349 return HBA_STATUS_OK; 350 } 351 } 352 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INVALID_HANDLE); 353 } 354 #define CHECKLIBRARY() \ 355 status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle);\ 356 if(status != HBA_STATUS_OK) { \ 357 return(status); \ 358 } 359 360 /* 361 *freevendorhandlelist is called with _hbaapi_LL_mutex already held 362 */ 363 static void 364 freevendorhandlelist(HBA_VENDORCALLBACK_ELEM *vhlist) { 365 HBA_VENDORCALLBACK_ELEM *vhlp; 366 HBA_VENDORCALLBACK_ELEM *vnext; 367 HBARemoveCallbackFunc registeredfunc; 368 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; 375 } 376 (registeredfunc)(vhlp->vendorcbhandle); 377 free(vhlp); 378 } 379 } 380 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; 394 395 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; 409 } 410 found = 1; 411 registeredfunc = cbp->lib_info->functionTable.RemoveCallbackHandler; 412 if(registeredfunc == NULL) { 413 break; 414 } 415 (registeredfunc)(cbp->vendorcbhandle); 416 *lastp = cbp->next; 417 free(cbp); 418 break; 419 } 420 } 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; 430 } 431 return HBA_STATUS_OK; 432 } 433 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; 443 } 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; 450 } 451 (registeredfunc)(vhlp->vendorcbhandle); 452 free(vhlp); 453 } 454 *lap = allcbp->next; 455 free(allcbp); 456 status = HBA_STATUS_OK; 457 break; 458 } 459 RELEASE_MUTEX(&_hbaapi_AAE_mutex); 460 return(status); 461 } 462 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++); 476 } 477 return(buf); 478 } 479 480 481 #ifdef WIN32 482 BOOL APIENTRY 483 DllMain( HANDLE hModule, 484 DWORD ul_reason_for_call, 485 LPVOID lpReserved 486 ) 487 { 488 switch (ul_reason_for_call) 489 { 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; 497 } 498 return TRUE; 499 } 500 #endif 501 502 /* 503 * Read in the config file and load all the specified vendor specific 504 * libraries and perform the function registration exercise 505 */ 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 521 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; 531 532 if(_hbaapi_librarylist != NULL) { 533 /* this is an app programming error */ 534 return HBA_STATUS_ERROR; 535 } 536 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; 542 } 543 /* 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 547 */ 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 */ 557 ; 558 } 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 */ 567 } 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; 577 } 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); 584 } 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; 590 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; 597 } 598 lib_infop->LibraryPath = strdup(byFileName); 599 DEBUG(1, "HBAAPI loading: %s\n", byFileName, 0, 0); 600 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; 612 } 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; 620 } 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; 629 } 630 } 631 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; 637 } 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; 644 } 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; 652 } 653 /* Initialize this library */ 654 status = ((LoadLibraryFunc)()); 655 if (status != HBA_STATUS_OK) { 656 /* ???Opportunity to send error msg, library error? */ 657 continue; 658 } 659 /* successfully loaded library */ 660 lib_infop->status = HBA_LIBRARY_LOADED; 661 662 dud_library: /* its also just the end of the loop */ 663 RegCloseKey(hkVendorLib); 664 } 665 RegCloseKey(hkSniaHba); 666 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; 675 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; 681 } 682 683 strcpy(hbaConfFilePath, "/etc/hba.conf"); 684 685 if ((hbaconf = fopen(hbaConfFilePath, "r")) == NULL) { 686 printf("Cannot open %s\n", hbaConfFilePath); 687 return HBA_STATUS_ERROR; 688 } 689 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; 695 } 696 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); 702 } 703 } 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); 709 } 710 } 711 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); 716 } 717 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; 724 } 725 /* 726 * Special case.... 727 * Look for loglevel 728 */ 729 if(strcmp(libraryname, "debuglevel") == 0) { 730 _hbaapi_debuglevel = strtol(librarypath, NULL, 10); 731 /* error handling does the right thing automagically */ 732 continue; 733 } 734 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); 739 } 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; 747 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; 752 } 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; 763 } 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; 776 } 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; 789 } 790 } 791 792 /* successfully loaded library */ 793 if((GetVersionFunc = lib_infop->functionTable.GetVersionHandler) 794 == NULL) { 795 continue; 796 } 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; 805 } 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; 817 } 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; 827 } 828 /* successfully loaded library */ 829 lib_infop->status = HBA_LIBRARY_LOADED; 830 } 831 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); 838 } 839 if(ret == 0) { 840 ret = pthread_mutex_init(&_hbaapi_AAE_mutex, NULL); 841 } 842 if(ret == 0) { 843 ret = pthread_mutex_init(&_hbaapi_AE_mutex, NULL); 844 } 845 if(ret == 0) { 846 ret = pthread_mutex_init(&_hbaapi_APE_mutex, NULL); 847 } 848 if(ret == 0) { 849 ret = pthread_mutex_init(&_hbaapi_APSE_mutex, NULL); 850 } 851 if(ret == 0) { 852 ret = pthread_mutex_init(&_hbaapi_TE_mutex, NULL); 853 } 854 if(ret == 0) { 855 ret = pthread_mutex_init(&_hbaapi_LE_mutex, NULL); 856 } 857 if(ret != 0) { 858 perror("pthread_mutec_init - HBA_LoadLibrary"); 859 return(HBA_STATUS_ERROR); 860 } 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 871 872 873 return HBA_STATUS_OK; 874 } 875 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; 885 886 ARE_WE_INITED(); 887 GRAB_MUTEX(&_hbaapi_LL_mutex); 888 GRAB_MUTEX(&_hbaapi_AL_mutex); 889 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)()); 898 } 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 904 } 905 #ifndef WIN32 906 free(lib_infop->LibraryName); 907 #endif 908 free(lib_infop->LibraryPath); 909 free(lib_infop); 910 911 } 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; 916 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); 923 } 924 _hbaapi_adapterlist = NULL; 925 _hbaapi_total_adapter_count = 0; 926 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); 933 } 934 for(listp = cb_lists_array; *listp != NULL; listp++) { 935 while((volatile HBA_ADAPTERCALLBACK_ELEM ***)**listp != NULL) { 936 local_remove_callback((HBA_CALLBACKHANDLE)**listp); 937 } 938 } 939 940 RELEASE_MUTEX(&_hbaapi_AL_mutex); 941 RELEASE_MUTEX(&_hbaapi_LL_mutex); 942 943 #ifdef USESYSLOG 944 closelog(); 945 #endif 946 #ifdef USELOGFILE 947 if(_hbaapi_debug_fd != NULL) { 948 fclose(_hbaapi_debug_fd); 949 } 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 972 973 return HBA_STATUS_OK; 974 } 975 976 /* 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 982 */ 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; 994 995 char adaptername[256]; 996 int num_adapters; /* local */ 997 998 if(_hbaapi_librarylist == NULL) { 999 return (0); 1000 } 1001 GRAB_MUTEX(&_hbaapi_LL_mutex); /* pay attention to order */ 1002 GRAB_MUTEX(&_hbaapi_AL_mutex); 1003 1004 for (lib_infop = _hbaapi_librarylist; 1005 lib_infop != NULL; 1006 lib_infop = lib_infop->next) { 1007 1008 if (lib_infop->status != HBA_LIBRARY_LOADED) { 1009 continue; 1010 } 1011 1012 GetNumberOfAdaptersFunc = 1013 lib_infop->functionTable.GetNumberOfAdaptersHandler; 1014 if (GetNumberOfAdaptersFunc == NULL) { 1015 continue; 1016 } 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 1025 1026 /* Also get the names of all the adapters here and cache */ 1027 GetAdapterNameFunc = lib_infop->functionTable.GetAdapterNameHandler; 1028 if(GetAdapterNameFunc == NULL) { 1029 continue; 1030 } 1031 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) { 1039 /* 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? 1043 */ 1044 if(strcmp(adaptername, adapt_infop->name) == 0) { 1045 /* already got this one */ 1046 found_name++; 1047 break; 1048 } 1049 } 1050 if(found_name != 0) { 1051 continue; 1052 } 1053 } 1054 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); 1066 } 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); 1075 } 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++; 1081 } 1082 } 1083 RELEASE_MUTEX(&_hbaapi_AL_mutex); 1084 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, _hbaapi_total_adapter_count); 1085 } 1086 1087 HBA_STATUS 1088 HBA_GetAdapterName( 1089 HBA_UINT32 adapterindex, 1090 char *adaptername) 1091 { 1092 HBA_ADAPTER_INFO *adapt_infop; 1093 HBA_STATUS ret = HBA_STATUS_ERROR_ILLEGAL_INDEX; 1094 1095 if (adaptername == NULL) { 1096 return(HBA_STATUS_ERROR_ARG); 1097 } 1098 /* 1099 * The adapter index is from old code, but we have 1100 * to support it. Go down the list looking for 1101 * the adapter 1102 */ 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) { 1109 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'; 1116 } 1117 ret = adapt_infop->GNstatus; 1118 break; 1119 } 1120 } 1121 DEBUG(2, "GetAdapterName for index:%d ->%s", adapterindex, adaptername, 0); 1122 RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, ret); 1123 } 1124 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; 1131 1132 DEBUG(2, "OpenAdapter: %s", adaptername, 0, 0); 1133 1134 if(_hbaapi_librarylist == NULL) { 1135 return(HBA_HANDLE_INVALID); 1136 } 1137 if (adaptername == NULL) { 1138 return(HBA_STATUS_ERROR_ARG); 1139 } 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; 1147 } 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); 1157 } 1158 } 1159 break; 1160 } 1161 RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, handle); 1162 } 1163 /* 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 1167 */ 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; 1177 1178 DEBUG(2, "OpenAdapterByWWN: %s", WWN2STR1(&nodeWWN), 0, 0); 1179 1180 if (phandle == NULL) { 1181 return(HBA_STATUS_ERROR_ARG); 1182 } 1183 1184 ARE_WE_INITED(); 1185 1186 *phandle = HBA_HANDLE_INVALID; 1187 1188 GRAB_MUTEX(&_hbaapi_LL_mutex); 1189 for (lib_infop = _hbaapi_librarylist; 1190 lib_infop != NULL; 1191 lib_infop = lib_infop->next) { 1192 1193 status = HBA_STATUS_ERROR_ILLEGAL_WWN; 1194 1195 if (lib_infop->status != HBA_LIBRARY_LOADED) { 1196 continue; 1197 } 1198 1199 GetNumberOfAdaptersFunc = 1200 lib_infop->functionTable.GetNumberOfAdaptersHandler; 1201 if (GetNumberOfAdaptersFunc == NULL) { 1202 continue; 1203 } 1204 1205 /* look for new hardware */ 1206 (void) ((GetNumberOfAdaptersFunc)()); 1207 1208 OpenAdapterFunc = lib_infop->functionTable.OpenAdapterByWWNHandler; 1209 if (OpenAdapterFunc == NULL) { 1210 continue; 1211 } 1212 /* 1213 * We do not know if the WWN is known by this vendor, 1214 * just try it 1215 */ 1216 if((status = (OpenAdapterFunc)(&handle, nodeWWN)) != HBA_STATUS_OK) { 1217 continue; 1218 } 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; 1223 } 1224 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 1225 } 1226 1227 void 1228 HBA_RefreshAdapterConfiguration() { 1229 DEBUG(2, "HBA_RefreshAdapterConfiguration", 0, 0, 0); 1230 (void)HBA_GetNumberOfAdapters(); 1231 return; 1232 } 1233 1234 HBA_UINT32 1235 HBA_GetVersion() { 1236 DEBUG(2, "HBA_GetVersion", 0, 0, 0); 1237 return HBA_LIBVERSION; 1238 } 1239 1240 /* 1241 * This function is VERY OS dependent. Wing it as best you can. 1242 */ 1243 HBA_UINT32 1244 HBA_GetWrapperLibraryAttributes ( 1245 HBA_LIBRARYATTRIBUTES *attributes) 1246 { 1247 1248 DEBUG(2, "HBA_GetWrapperLibraryAttributes", 0, 0, 0); 1249 1250 if (attributes == NULL) { 1251 return(HBA_STATUS_ERROR_ARG); 1252 } 1253 1254 memset(attributes, 0, sizeof(HBA_LIBRARYATTRIBUTES)); 1255 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); 1262 } 1263 } 1264 } 1265 } 1266 #elif defined(WIN32) 1267 { 1268 HMODULE module; 1269 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'; 1277 } 1278 } 1279 } 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) 1293 { 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 1302 ); 1303 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; 1309 } 1310 1311 } 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)); 1315 } 1316 #endif 1317 #else 1318 memset(&attributes->build_date, 0, sizeof(struct tm)); 1319 #endif 1320 return 2; 1321 } 1322 1323 /* 1324 * Callback registation and handling 1325 */ 1326 HBA_STATUS 1327 HBA_RemoveCallback (HBA_CALLBACKHANDLE cbhandle) { 1328 HBA_STATUS status; 1329 1330 DEBUG(2, "HBA_RemoveCallback", 0, 0, 0); 1331 ARE_WE_INITED(); 1332 1333 GRAB_MUTEX(&_hbaapi_LL_mutex); 1334 status = local_remove_callback(cbhandle); 1335 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 1336 } 1337 1338 /* Adapter Add Events *********************************************************/ 1339 static void 1340 adapteraddevents_callback (void *data, HBA_WWN PortWWN, HBA_UINT32 eventType) { 1341 HBA_ALLADAPTERSCALLBACK_ELEM *cbp; 1342 1343 DEBUG(3, "AddAdapterEvent, port:%s", WWN2STR1(&PortWWN), 0, 0); 1344 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); 1350 } 1351 RELEASE_MUTEX(&_hbaapi_AAE_mutex); 1352 1353 } 1354 HBA_STATUS 1355 HBA_RegisterForAdapterAddEvents ( 1356 void (*callback) ( 1357 void *data, 1358 HBA_WWN PortWWN, 1359 HBA_UINT32 eventType 1360 ), 1361 void *userData, 1362 HBA_CALLBACKHANDLE *callbackHandle) { 1363 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; 1376 1377 DEBUG(2, "HBA_RegisterForAdapterAddEvents", 0, 0, 0); 1378 1379 if (callbackHandle == NULL) { 1380 return(HBA_STATUS_ERROR_ARG); 1381 } 1382 ARE_WE_INITED(); 1383 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; 1394 } 1395 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); 1405 1406 1407 /* 1408 * now create a list of vendors (vendor libraryies, NOT ADAPTERS) that have 1409 * successfully registerred 1410 */ 1411 vendorhandlelist = NULL; 1412 for(lib_infop = _hbaapi_librarylist; 1413 lib_infop != NULL; 1414 lib_infop = lib_infop->next) { 1415 1416 vendor_cnt++; 1417 1418 registeredfunc = 1419 lib_infop->functionTable.RegisterForAdapterAddEventsHandler; 1420 if(registeredfunc == NULL) { 1421 continue; 1422 } 1423 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; 1436 } 1437 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++; 1460 } 1461 vcbp->lib_info = lib_infop; 1462 vcbp->next = vendorhandlelist; 1463 vendorhandlelist = vcbp; 1464 } 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; 1488 } 1489 } 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; 1502 } 1503 } 1504 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 1505 } 1506 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; 1513 1514 DEBUG(3, "AdapterEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN), 1515 eventType, 0); 1516 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; 1524 } 1525 } 1526 RELEASE_MUTEX(&_hbaapi_AE_mutex); 1527 } 1528 HBA_STATUS 1529 HBA_RegisterForAdapterEvents ( 1530 void (*callback) ( 1531 void *data, 1532 HBA_WWN PortWWN, 1533 HBA_UINT32 eventType 1534 ), 1535 void *userData, 1536 HBA_HANDLE handle, 1537 HBA_CALLBACKHANDLE *callbackHandle) { 1538 1539 HBA_ADAPTERCALLBACK_ELEM *acbp; 1540 HBARegisterForAdapterEventsFunc registeredfunc; 1541 HBA_STATUS status; 1542 HBA_LIBRARY_INFO *lib_infop; 1543 HBA_HANDLE vendorHandle; 1544 1545 DEBUG(2, "HBA_RegisterForAdapterEvents", 0, 0, 0); 1546 1547 if (callbackHandle == NULL) { 1548 return(HBA_STATUS_ERROR_ARG); 1549 } 1550 1551 CHECKLIBRARY(); 1552 1553 /* we now have the _hbaapi_LL_mutex */ 1554 1555 registeredfunc = lib_infop->functionTable.RegisterForAdapterEventsHandler; 1556 if(registeredfunc == NULL) { 1557 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 1558 } 1559 1560 /* 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 1564 */ 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); 1574 } 1575 *callbackHandle = (HBA_CALLBACKHANDLE) acbp; 1576 acbp->callback = callback; 1577 acbp->userdata = userData; 1578 acbp->lib_info = lib_infop; 1579 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); 1587 } 1588 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); 1593 1594 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 1595 } 1596 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; 1604 1605 DEBUG(3, "AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x", 1606 WWN2STR1(&PortWWN), eventType, fabricPortID); 1607 1608 GRAB_MUTEX(&_hbaapi_APE_mutex); 1609 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; 1616 } 1617 } 1618 RELEASE_MUTEX(&_hbaapi_APE_mutex); 1619 } 1620 HBA_STATUS 1621 HBA_RegisterForAdapterPortEvents ( 1622 void (*callback) ( 1623 void *data, 1624 HBA_WWN PortWWN, 1625 HBA_UINT32 eventType, 1626 HBA_UINT32 fabricPortID 1627 ), 1628 void *userData, 1629 HBA_HANDLE handle, 1630 HBA_WWN PortWWN, 1631 HBA_CALLBACKHANDLE *callbackHandle) { 1632 1633 HBA_ADAPTERCALLBACK_ELEM *acbp; 1634 HBARegisterForAdapterPortEventsFunc registeredfunc; 1635 HBA_STATUS status; 1636 HBA_LIBRARY_INFO *lib_infop; 1637 HBA_HANDLE vendorHandle; 1638 1639 DEBUG(2, "HBA_RegisterForAdapterPortEvents for port: %s", 1640 WWN2STR1(&PortWWN), 0, 0); 1641 1642 if (callbackHandle == NULL) { 1643 return(HBA_STATUS_ERROR_ARG); 1644 } 1645 1646 CHECKLIBRARY(); 1647 /* we now have the _hbaapi_LL_mutex */ 1648 1649 registeredfunc = 1650 lib_infop->functionTable.RegisterForAdapterPortEventsHandler; 1651 if(registeredfunc == NULL) { 1652 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 1653 } 1654 1655 /* 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 1659 */ 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); 1670 1671 } 1672 *callbackHandle = (HBA_CALLBACKHANDLE) acbp; 1673 acbp->callback = callback; 1674 acbp->userdata = userData; 1675 acbp->lib_info = lib_infop; 1676 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); 1685 } 1686 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); 1691 1692 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 1693 } 1694 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; 1701 1702 DEBUG(3, "AdapterPortStateEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN), 1703 eventType, 0); 1704 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; 1712 } 1713 } 1714 } 1715 HBA_STATUS 1716 HBA_RegisterForAdapterPortStatEvents ( 1717 void (*callback) ( 1718 void *data, 1719 HBA_WWN PortWWN, 1720 HBA_UINT32 eventType 1721 ), 1722 void *userData, 1723 HBA_HANDLE handle, 1724 HBA_WWN PortWWN, 1725 HBA_PORTSTATISTICS stats, 1726 HBA_UINT32 statType, 1727 HBA_CALLBACKHANDLE *callbackHandle) { 1728 1729 HBA_ADAPTERCALLBACK_ELEM *acbp; 1730 HBARegisterForAdapterPortStatEventsFunc 1731 registeredfunc; 1732 HBA_STATUS status; 1733 HBA_LIBRARY_INFO *lib_infop; 1734 HBA_HANDLE vendorHandle; 1735 1736 DEBUG(2, "HBA_RegisterForAdapterPortStatEvents for port: %s", 1737 WWN2STR1(&PortWWN), 0, 0); 1738 1739 if (callbackHandle == NULL) { 1740 return(HBA_STATUS_ERROR_ARG); 1741 } 1742 1743 CHECKLIBRARY(); 1744 /* we now have the _hbaapi_LL_mutex */ 1745 1746 registeredfunc = 1747 lib_infop->functionTable.RegisterForAdapterPortStatEventsHandler; 1748 if(registeredfunc == NULL) { 1749 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 1750 } 1751 1752 /* 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 1756 */ 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); 1767 } 1768 *callbackHandle = (HBA_CALLBACKHANDLE) acbp; 1769 acbp->callback = callback; 1770 acbp->userdata = userData; 1771 acbp->lib_info = lib_infop; 1772 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); 1783 } 1784 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); 1789 1790 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 1791 } 1792 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; 1800 1801 DEBUG(3, "TargetEvent, hbaPort:%s, discoveredPort:%s eventType:%d", 1802 WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), eventType); 1803 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; 1812 } 1813 } 1814 RELEASE_MUTEX(&_hbaapi_TE_mutex); 1815 } 1816 HBA_STATUS 1817 HBA_RegisterForTargetEvents ( 1818 void (*callback) ( 1819 void *data, 1820 HBA_WWN hbaPortWWN, 1821 HBA_WWN discoveredPortWWN, 1822 HBA_UINT32 eventType 1823 ), 1824 void *userData, 1825 HBA_HANDLE handle, 1826 HBA_WWN hbaPortWWN, 1827 HBA_WWN discoveredPortWWN, 1828 HBA_CALLBACKHANDLE *callbackHandle, 1829 HBA_UINT32 allTargets) { 1830 1831 HBA_ADAPTERCALLBACK_ELEM 1832 *acbp; 1833 HBARegisterForTargetEventsFunc 1834 registeredfunc; 1835 HBA_STATUS status; 1836 HBA_LIBRARY_INFO *lib_infop; 1837 HBA_HANDLE vendorHandle; 1838 1839 DEBUG(2, "HBA_RegisterForTargetEvents, hbaPort: %s, discoveredPort: %s", 1840 WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), 0); 1841 1842 if (callbackHandle == NULL) { 1843 return(HBA_STATUS_ERROR_ARG); 1844 } 1845 1846 CHECKLIBRARY(); 1847 /* we now have the _hbaapi_LL_mutex */ 1848 1849 registeredfunc = lib_infop->functionTable.RegisterForTargetEventsHandler; 1850 if(registeredfunc == NULL) { 1851 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 1852 } 1853 1854 /* 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 1858 */ 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); 1868 } 1869 *callbackHandle = (HBA_CALLBACKHANDLE) acbp; 1870 acbp->callback = callback; 1871 acbp->userdata = userData; 1872 acbp->lib_info = lib_infop; 1873 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); 1884 } 1885 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); 1890 1891 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 1892 } 1893 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; 1902 1903 DEBUG(3, "LinkEvent, hbaWWN:%s, eventType:%d", 1904 WWN2STR1(&adapterWWN), eventType, 0); 1905 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; 1914 } 1915 } 1916 RELEASE_MUTEX(&_hbaapi_LE_mutex); 1917 } 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) { 1931 1932 HBA_ADAPTERCALLBACK_ELEM *acbp; 1933 HBARegisterForLinkEventsFunc 1934 registeredfunc; 1935 HBA_STATUS status; 1936 HBA_LIBRARY_INFO *lib_infop; 1937 HBA_HANDLE vendorHandle; 1938 1939 DEBUG(2, "HBA_RegisterForLinkEvents", 0, 0, 0); 1940 1941 if (callbackHandle == NULL) { 1942 return(HBA_STATUS_ERROR_ARG); 1943 } 1944 1945 CHECKLIBRARY(); 1946 /* we now have the _hbaapi_LL_mutex */ 1947 1948 registeredfunc = lib_infop->functionTable.RegisterForLinkEventsHandler; 1949 if(registeredfunc == NULL) { 1950 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 1951 } 1952 1953 /* 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 1957 */ 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); 1967 } 1968 *callbackHandle = (HBA_CALLBACKHANDLE) acbp; 1969 acbp->callback = callback; 1970 acbp->userdata = userData; 1971 acbp->lib_info = lib_infop; 1972 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); 1982 } 1983 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); 1988 1989 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 1990 } 1991 1992 1993 /* 1994 * All of the functions below are almost passthru functions to the 1995 * vendor specific function 1996 */ 1997 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; 2004 2005 DEBUG(2, "HBA_CloseAdapter", 0, 0, 0); 2006 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)); 2012 } 2013 RELEASE_MUTEX(&_hbaapi_LL_mutex); 2014 } 2015 } 2016 2017 HBA_STATUS 2018 HBA_GetAdapterAttributes ( 2019 HBA_HANDLE handle, 2020 HBA_ADAPTERATTRIBUTES 2021 *hbaattributes) 2022 { 2023 HBA_STATUS status; 2024 HBA_LIBRARY_INFO *lib_infop; 2025 HBA_HANDLE vendorHandle; 2026 HBAGetAdapterAttributesFunc GetAdapterAttributesFunc; 2027 2028 DEBUG(2, "HBA_GetAdapterAttributes", 0, 0, 0); 2029 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; 2037 } 2038 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2039 } 2040 2041 HBA_STATUS 2042 HBA_GetAdapterPortAttributes ( 2043 HBA_HANDLE handle, 2044 HBA_UINT32 portindex, 2045 HBA_PORTATTRIBUTES *portattributes) 2046 { 2047 HBA_STATUS status; 2048 HBA_LIBRARY_INFO *lib_infop; 2049 HBA_HANDLE vendorHandle; 2050 HBAGetAdapterPortAttributesFunc 2051 GetAdapterPortAttributesFunc; 2052 2053 DEBUG(2, "HBA_GetAdapterPortAttributes", 0, 0, 0); 2054 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; 2063 } 2064 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2065 } 2066 2067 HBA_STATUS 2068 HBA_GetPortStatistics ( 2069 HBA_HANDLE handle, 2070 HBA_UINT32 portindex, 2071 HBA_PORTSTATISTICS *portstatistics) 2072 { 2073 HBA_STATUS status; 2074 HBA_LIBRARY_INFO *lib_infop; 2075 HBA_HANDLE vendorHandle; 2076 HBAGetPortStatisticsFunc 2077 GetPortStatisticsFunc; 2078 2079 DEBUG(2, "HBA_GetPortStatistics", 0, 0, 0); 2080 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; 2089 } 2090 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2091 } 2092 2093 HBA_STATUS 2094 HBA_GetDiscoveredPortAttributes ( 2095 HBA_HANDLE handle, 2096 HBA_UINT32 portindex, 2097 HBA_UINT32 discoveredportindex, 2098 HBA_PORTATTRIBUTES *portattributes) 2099 { 2100 HBA_STATUS status; 2101 HBA_LIBRARY_INFO *lib_infop; 2102 HBA_HANDLE vendorHandle; 2103 HBAGetDiscoveredPortAttributesFunc 2104 GetDiscoveredPortAttributesFunc; 2105 2106 DEBUG(2, "HBA_GetDiscoveredPortAttributes", 0, 0, 0); 2107 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; 2117 } 2118 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2119 } 2120 2121 HBA_STATUS 2122 HBA_GetPortAttributesByWWN ( 2123 HBA_HANDLE handle, 2124 HBA_WWN PortWWN, 2125 HBA_PORTATTRIBUTES *portattributes) 2126 { 2127 HBA_STATUS status; 2128 HBA_LIBRARY_INFO *lib_infop; 2129 HBA_HANDLE vendorHandle; 2130 HBAGetPortAttributesByWWNFunc 2131 GetPortAttributesByWWNFunc; 2132 2133 DEBUG(2, "HBA_GetPortAttributesByWWN: %s", WWN2STR1(&PortWWN), 0, 0); 2134 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; 2143 } 2144 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2145 } 2146 2147 HBA_STATUS 2148 HBA_SendCTPassThru ( 2149 HBA_HANDLE handle, 2150 void *pReqBuffer, 2151 HBA_UINT32 ReqBufferSize, 2152 void *pRspBuffer, 2153 HBA_UINT32 RspBufferSize) 2154 { 2155 HBA_STATUS status; 2156 HBA_LIBRARY_INFO *lib_infop; 2157 HBA_HANDLE vendorHandle; 2158 HBASendCTPassThruFunc 2159 SendCTPassThruFunc; 2160 2161 DEBUG(2, "HBA_SendCTPassThru", 0, 0, 0); 2162 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; 2172 } 2173 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2174 } 2175 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) 2184 { 2185 HBA_STATUS status; 2186 HBA_LIBRARY_INFO *lib_infop; 2187 HBA_HANDLE vendorHandle; 2188 HBASendCTPassThruV2Func 2189 registeredfunc; 2190 2191 DEBUG(2, "HBA_SendCTPassThruV2m hbaPortWWN: %s", WWN2STR1(&hbaPortWWN), 0, 0); 2192 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; 2202 } 2203 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2204 } 2205 2206 HBA_STATUS 2207 HBA_GetEventBuffer ( 2208 HBA_HANDLE handle, 2209 PHBA_EVENTINFO EventBuffer, 2210 HBA_UINT32 *EventBufferCount) 2211 { 2212 HBA_STATUS status; 2213 HBA_LIBRARY_INFO *lib_infop; 2214 HBA_HANDLE vendorHandle; 2215 HBAGetEventBufferFunc 2216 GetEventBufferFunc; 2217 2218 DEBUG(2, "HBA_GetEventBuffer", 0, 0, 0); 2219 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; 2227 } 2228 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2229 } 2230 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; 2238 2239 DEBUG(2, "HBA_SetRNIDMgmtInfo", 0, 0, 0); 2240 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; 2247 } 2248 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2249 } 2250 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; 2258 2259 DEBUG(2, "HBA_GetRNIDMgmtInfo", 0, 0, 0); 2260 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; 2267 } 2268 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2269 } 2270 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) 2278 { 2279 HBA_STATUS status; 2280 HBA_LIBRARY_INFO *lib_infop; 2281 HBA_HANDLE vendorHandle; 2282 HBASendRNIDFunc SendRNIDFunc; 2283 2284 DEBUG(2, "HBA_SendRNID for wwn: %s", WWN2STR1(&wwn), 0, 0); 2285 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; 2293 } 2294 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2295 } 2296 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) 2306 { 2307 HBA_STATUS status; 2308 HBA_LIBRARY_INFO *lib_infop; 2309 HBA_HANDLE vendorHandle; 2310 HBASendRNIDV2Func registeredfunc; 2311 2312 DEBUG(2, "HBA_SendRNIDV2, hbaPortWWN: %s", WWN2STR1(&hbaPortWWN), 0, 0); 2313 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; 2322 } 2323 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2324 } 2325 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; 2333 2334 DEBUG(2, "HBA_RefreshInformation", 0, 0, 0); 2335 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)); 2342 } 2343 RELEASE_MUTEX(&_hbaapi_LL_mutex); 2344 } 2345 } 2346 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; 2354 2355 DEBUG(2, "HBA_ResetStatistics", 0, 0, 0); 2356 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)); 2362 } 2363 RELEASE_MUTEX(&_hbaapi_LL_mutex); 2364 } 2365 } 2366 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; 2373 2374 DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0); 2375 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; 2383 } 2384 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2385 } 2386 2387 HBA_STATUS 2388 HBA_GetFcpTargetMappingV2 ( 2389 HBA_HANDLE handle, 2390 HBA_WWN hbaPortWWN, 2391 HBA_FCPTARGETMAPPINGV2 2392 *pmapping) 2393 { 2394 HBA_STATUS status; 2395 HBA_LIBRARY_INFO *lib_infop; 2396 HBA_HANDLE vendorHandle; 2397 HBAGetFcpTargetMappingV2Func 2398 registeredfunc; 2399 2400 DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0); 2401 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; 2409 } 2410 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2411 } 2412 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; 2420 2421 DEBUG(2, "HBA_GetFcpPersistentBinding", 0, 0, 0); 2422 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; 2430 } 2431 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2432 } 2433 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) 2447 { 2448 HBA_STATUS status; 2449 HBA_LIBRARY_INFO *lib_infop; 2450 HBA_HANDLE vendorHandle; 2451 HBAScsiInquiryV2Func ScsiInquiryV2Func; 2452 2453 DEBUG(2, "HBA_ScsiInquiryV2 to discoveredPortWWN: %s", 2454 WWN2STR1(&discoveredPortWWN), 0, 0); 2455 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; 2466 } 2467 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2468 } 2469 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) 2481 { 2482 HBA_STATUS status; 2483 HBA_LIBRARY_INFO *lib_infop; 2484 HBA_HANDLE vendorHandle; 2485 HBASendScsiInquiryFunc SendScsiInquiryFunc; 2486 2487 DEBUG(2, "HBA_SendScsiInquiry to PortWWN: %s", WWN2STR1(&PortWWN), 0, 0); 2488 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; 2497 } 2498 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2499 } 2500 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) 2511 { 2512 HBA_STATUS status; 2513 HBA_LIBRARY_INFO *lib_infop; 2514 HBA_HANDLE vendorHandle; 2515 HBAScsiReportLUNsV2Func ScsiReportLUNsV2Func; 2516 2517 DEBUG(2, "HBA_ScsiReportLUNsV2 to discoveredPortWWN: %s", 2518 WWN2STR1(&discoveredPortWWN), 0, 0); 2519 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; 2530 } 2531 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2532 } 2533 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) 2542 { 2543 HBA_STATUS status; 2544 HBA_LIBRARY_INFO *lib_infop; 2545 HBA_HANDLE vendorHandle; 2546 HBASendReportLUNsFunc SendReportLUNsFunc; 2547 2548 DEBUG(2, "HBA_SendReportLUNs to PortWWN: %s", WWN2STR1(&portWWN), 0, 0); 2549 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; 2558 } 2559 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2560 } 2561 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) 2573 { 2574 HBA_STATUS status; 2575 HBA_LIBRARY_INFO *lib_infop; 2576 HBA_HANDLE vendorHandle; 2577 HBAScsiReadCapacityV2Func ScsiReadCapacityV2Func; 2578 2579 DEBUG(2, "HBA_ScsiReadCapacityV2 to discoveredPortWWN: %s", 2580 WWN2STR1(&discoveredPortWWN), 0, 0); 2581 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; 2593 } 2594 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2595 } 2596 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) 2606 { 2607 HBA_STATUS status; 2608 HBA_LIBRARY_INFO *lib_infop; 2609 HBA_HANDLE vendorHandle; 2610 HBASendReadCapacityFunc SendReadCapacityFunc; 2611 2612 DEBUG(2, "HBA_SendReadCapacity to portWWN: %s", WWN2STR1(&portWWN), 0, 0); 2613 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; 2622 } 2623 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2624 } 2625 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) 2633 { 2634 HBA_STATUS status; 2635 HBA_LIBRARY_INFO *lib_infop; 2636 HBA_HANDLE vendorHandle; 2637 HBASendRLSFunc registeredfunc; 2638 2639 DEBUG(2, "HBA_SendRLS to agent_wwn: %s:%d", 2640 WWN2STR1(&agent_wwn), agent_domain, 0); 2641 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; 2649 } 2650 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2651 } 2652 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) 2662 { 2663 HBA_STATUS status; 2664 HBA_LIBRARY_INFO *lib_infop; 2665 HBA_HANDLE vendorHandle; 2666 HBASendRPLFunc registeredfunc; 2667 2668 DEBUG(2, "HBA_SendRPL to agent_wwn: %s:%d", 2669 WWN2STR1(&agent_wwn), agent_domain, 0); 2670 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; 2679 } 2680 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2681 } 2682 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) 2693 { 2694 HBA_STATUS status; 2695 HBA_LIBRARY_INFO *lib_infop; 2696 HBA_HANDLE vendorHandle; 2697 HBASendRPSFunc registeredfunc; 2698 2699 DEBUG(2, "HBA_SendRPS to agent_wwn: %s:%d", 2700 WWN2STR1(&agent_wwn), agent_domain, 0); 2701 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; 2711 } 2712 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2713 } 2714 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) 2723 { 2724 HBA_STATUS status; 2725 HBA_LIBRARY_INFO *lib_infop; 2726 HBA_HANDLE vendorHandle; 2727 HBASendSRLFunc registeredfunc; 2728 2729 DEBUG(2, "HBA_SendSRL to wwn:%s domain:%d", WWN2STR1(&wwn), domain, 0); 2730 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; 2739 } 2740 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2741 } 2742 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) 2752 { 2753 HBA_STATUS status; 2754 HBA_LIBRARY_INFO *lib_infop; 2755 HBA_HANDLE vendorHandle; 2756 HBASendLIRRFunc registeredfunc; 2757 2758 DEBUG(2, "HBA_SendLIRR destWWN:%s", WWN2STR1(&destWWN), 0, 0); 2759 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; 2768 } 2769 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2770 } 2771 2772 HBA_STATUS 2773 HBA_GetBindingCapability( 2774 HBA_HANDLE handle, 2775 HBA_WWN hbaPortWWN, 2776 HBA_BIND_CAPABILITY *pcapability) 2777 { 2778 HBA_STATUS status; 2779 HBA_LIBRARY_INFO *lib_infop; 2780 HBA_HANDLE vendorHandle; 2781 HBAGetBindingCapabilityFunc 2782 registeredfunc; 2783 2784 DEBUG(2, "HBA_GetBindingCapability", 0, 0, 0); 2785 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; 2792 } 2793 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2794 } 2795 2796 HBA_STATUS 2797 HBA_GetBindingSupport ( 2798 HBA_HANDLE handle, 2799 HBA_WWN hbaPortWWN, 2800 HBA_BIND_CAPABILITY *pcapability) 2801 { 2802 HBA_STATUS status; 2803 HBA_LIBRARY_INFO *lib_infop; 2804 HBA_HANDLE vendorHandle; 2805 HBAGetBindingSupportFunc 2806 registeredfunc; 2807 2808 DEBUG(2, "HBA_GetBindingSupport", 0, 0, 0); 2809 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; 2816 } 2817 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2818 } 2819 2820 HBA_STATUS 2821 HBA_SetBindingSupport( 2822 HBA_HANDLE handle, 2823 HBA_WWN hbaPortWWN, 2824 HBA_BIND_CAPABILITY capability) 2825 { 2826 HBA_STATUS status; 2827 HBA_LIBRARY_INFO *lib_infop; 2828 HBA_HANDLE vendorHandle; 2829 HBASetBindingSupportFunc 2830 registeredfunc; 2831 2832 DEBUG(2, "HBA_SetBindingSupport", 0, 0, 0); 2833 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; 2840 } 2841 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2842 } 2843 2844 HBA_STATUS 2845 HBA_SetPersistentBindingV2 ( 2846 HBA_HANDLE handle, 2847 HBA_WWN hbaPortWWN, 2848 const HBA_FCPBINDING2 2849 *pbinding) 2850 { 2851 HBA_STATUS status; 2852 HBA_LIBRARY_INFO *lib_infop; 2853 HBA_HANDLE vendorHandle; 2854 HBASetPersistentBindingV2Func 2855 registeredfunc; 2856 2857 DEBUG(2, "HBA_SetPersistentBindingV2 port: %s", WWN2STR1(&hbaPortWWN), 0, 0); 2858 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; 2865 } 2866 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2867 } 2868 2869 HBA_STATUS 2870 HBA_GetPersistentBindingV2 ( 2871 HBA_HANDLE handle, 2872 HBA_WWN hbaPortWWN, 2873 HBA_FCPBINDING2 *pbinding) 2874 { 2875 HBA_STATUS status; 2876 HBA_LIBRARY_INFO *lib_infop; 2877 HBA_HANDLE vendorHandle; 2878 HBAGetPersistentBindingV2Func 2879 registeredfunc; 2880 2881 DEBUG(2, "HBA_GetPersistentBindingV2 port: %s", WWN2STR1(&hbaPortWWN), 0, 0); 2882 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; 2889 } 2890 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2891 } 2892 2893 HBA_STATUS 2894 HBA_RemovePersistentBinding ( 2895 HBA_HANDLE handle, 2896 HBA_WWN hbaPortWWN, 2897 const HBA_FCPBINDING2 2898 *pbinding) 2899 { 2900 HBA_STATUS status; 2901 HBA_LIBRARY_INFO *lib_infop; 2902 HBA_HANDLE vendorHandle; 2903 HBARemovePersistentBindingFunc 2904 registeredfunc; 2905 2906 DEBUG(2, "HBA_RemovePersistentBinding", 0, 0, 0); 2907 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; 2915 } 2916 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2917 } 2918 2919 HBA_STATUS 2920 HBA_RemoveAllPersistentBindings ( 2921 HBA_HANDLE handle, 2922 HBA_WWN hbaPortWWN) 2923 { 2924 HBA_STATUS status; 2925 HBA_LIBRARY_INFO *lib_infop; 2926 HBA_HANDLE vendorHandle; 2927 HBARemoveAllPersistentBindingsFunc 2928 registeredfunc; 2929 2930 DEBUG(2, "HBA_RemoveAllPersistentBindings", 0, 0, 0); 2931 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; 2939 } 2940 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2941 } 2942 2943 HBA_STATUS 2944 HBA_GetFC4Statistics ( 2945 HBA_HANDLE handle, 2946 HBA_WWN portWWN, 2947 HBA_UINT8 FC4type, 2948 HBA_FC4STATISTICS *pstatistics) 2949 { 2950 HBA_STATUS status; 2951 HBA_LIBRARY_INFO *lib_infop; 2952 HBA_HANDLE vendorHandle; 2953 HBAGetFC4StatisticsFunc 2954 registeredfunc; 2955 2956 DEBUG(2, "HBA_GetFC4Statistics port: %s", WWN2STR1(&portWWN), 0, 0); 2957 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; 2966 } 2967 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2968 } 2969 2970 HBA_STATUS 2971 HBA_GetFCPStatistics ( 2972 HBA_HANDLE handle, 2973 const HBA_SCSIID *lunit, 2974 HBA_FC4STATISTICS *pstatistics) 2975 { 2976 HBA_STATUS status; 2977 HBA_LIBRARY_INFO *lib_infop; 2978 HBA_HANDLE vendorHandle; 2979 HBAGetFCPStatisticsFunc 2980 registeredfunc; 2981 2982 DEBUG(2, "HBA_GetFCPStatistics", 0, 0, 0); 2983 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; 2991 } 2992 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2993 } 2994 2995 HBA_UINT32 2996 HBA_GetVendorLibraryAttributes ( 2997 HBA_UINT32 adapter_index, 2998 HBA_LIBRARYATTRIBUTES *attributes) 2999 { 3000 HBA_ADAPTER_INFO *adapt_infop; 3001 HBAGetVendorLibraryAttributesFunc 3002 registeredfunc; 3003 HBA_UINT32 ret = 0; 3004 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); 3010 } 3011 3012 if (attributes == NULL) { 3013 return(HBA_STATUS_ERROR_ARG); 3014 } 3015 3016 memset(attributes, 0, sizeof(HBA_LIBRARYATTRIBUTES)); 3017 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) { 3023 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)()); 3036 } 3037 #ifdef NOTDEF 3038 else { 3039 /* This should not happen, dont think its going to */ 3040 } 3041 #endif 3042 } 3043 if (attributes->LibPath[0] == '\0') { 3044 if(strlen(adapt_infop->library->LibraryPath) < 256) { 3045 strcpy(attributes->LibPath, 3046 adapt_infop->library->LibraryPath); 3047 } 3048 } 3049 break; 3050 } 3051 } 3052 RELEASE_MUTEX(&_hbaapi_AL_mutex); 3053 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, ret); 3054 } 3055