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