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