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 fclose(hbaconf); 950 return (HBA_STATUS_ERROR); 951 } 952 lib_infop->status = HBA_LIBRARY_NOT_LOADED; 953 lib_infop->LibraryName = strdup(libraryname); 954 lib_infop->LibraryPath = strdup(librarypath); 955 lib_infop->numOfAdapters = 0; 956 lib_infop->version = UNKNOWN; 957 lib_infop->index = _hbaapi_total_library_count; 958 _hbaapi_total_library_count++; 959 lib_infop->next = _hbaapi_librarylist; 960 _hbaapi_librarylist = lib_infop; 961 962 /* Load the DLL now */ 963 if ((lib_infop->hLibrary = dlopen(librarypath, RTLD_LAZY)) == NULL) { 964 /* printf("unable to load library %s\n", librarypath); */ 965 continue; 966 } 967 /* Call the registration function to get the list of pointers */ 968 RegisterSMHBAFunc = (SMHBARegisterLibraryFunc) 969 dlsym(lib_infop->hLibrary, "SMHBA_RegisterLibrary"); 970 if (RegisterSMHBAFunc != NULL) { 971 /* 972 * Load the function points directly into 973 * the table of functions 974 */ 975 status = ((RegisterSMHBAFunc) 976 (&lib_infop->ftable.smhbafunctionTable)); 977 if (status != HBA_STATUS_OK) { 978 /* library not loaded */ 979 continue; 980 } else { 981 lib_infop->version = SMHBA; 982 } 983 } else { 984 RegisterV2Func = (HBARegisterLibraryV2Func) 985 dlsym(lib_infop->hLibrary, "HBA_RegisterLibraryV2"); 986 if (RegisterV2Func != NULL) { 987 /* 988 * Load the function points directly into 989 * the table of functions 990 */ 991 status = ((RegisterV2Func)((HBA_ENTRYPOINTSV2 *) 992 (&lib_infop->ftable.functionTable))); 993 if (status != HBA_STATUS_OK) { 994 /* library not loaded */ 995 continue; 996 } else { 997 lib_infop->version = HBAAPIV2; 998 } 999 } else { 1000 /* Maybe the vendor library is only Rev1 */ 1001 RegisterFunc = (HBARegisterLibraryFunc) 1002 dlsym(lib_infop->hLibrary, "HBA_RegisterLibrary"); 1003 if (RegisterFunc == NULL) { 1004 /* This function is required */ 1005 (void) fprintf(stderr, 1006 "HBA_LoadLibrary: vendor specific RegisterLibrary " 1007 "function not found. lib: %s\n", librarypath); 1008 DEBUG(1, "HBA_LoadLibrary: vendor specific " 1009 "RegisterLibrary function not found. lib: %s\n", 1010 librarypath, 0, 0); 1011 continue; 1012 } 1013 /* 1014 * Load the function points directly into 1015 * the table of functions 1016 */ 1017 status = ((RegisterFunc) 1018 ((HBA_ENTRYPOINTS *)(&lib_infop->ftable.functionTable))); 1019 if (status != HBA_STATUS_OK) { 1020 /* library not loaded */ 1021 (void) fprintf(stderr, 1022 "HBA_LoadLibrary: vendor specific RegisterLibrary " 1023 "function encountered an error. lib: %s\n", 1024 librarypath); 1025 DEBUG(1, 1026 "HBA_LoadLibrary: vendor specific RegisterLibrary " 1027 "function encountered an error. lib: %s\n", 1028 librarypath, 0, 0); 1029 continue; 1030 } else { 1031 lib_infop->version = HBAAPI; 1032 } 1033 } 1034 } 1035 1036 /* successfully loaded library */ 1037 /* 1038 * SM-HBA and HBAAPI has a seperate handler for GetVersion but 1039 * they have the same function signature so use the same variable here. 1040 */ 1041 if ((GetVersionFunc = FUNCCOMMON(lib_infop, GetVersionHandler)) 1042 == NULL) { 1043 continue; 1044 } 1045 if (lib_infop->version == SMHBA) { 1046 libversion = ((GetVersionFunc)()); 1047 if (libversion < SMHBA_LIBVERSION) { 1048 (void) printf("Library version mismatch." 1049 "Got %d expected %d.\n", 1050 libversion, SMHBA_LIBVERSION); 1051 continue; 1052 } 1053 } else { 1054 libversion = ((GetVersionFunc)()); 1055 /* Check the version of this library before loading */ 1056 /* Actually... This wrapper is compatible with version 1 */ 1057 if (libversion < HBA_LIBVERSION) { 1058 (void) printf("Library version mismatch." 1059 "Got %d expected %d.\n", 1060 libversion, HBA_LIBVERSION); 1061 continue; 1062 } 1063 } 1064 1065 DEBUG(1, "%s libversion = %d", librarypath, libversion, 0); 1066 LoadLibraryFunc = FUNCCOMMON(lib_infop, LoadLibraryHandler); 1067 if (LoadLibraryFunc == NULL) { 1068 /* this function is required */ 1069 (void) fprintf(stderr, 1070 "HBA_LoadLibrary: vendor specific LoadLibrary " 1071 "function not found. lib: %s\n", librarypath); 1072 DEBUG(1, "HBA_LoadLibrary: vendor specific LoadLibrary " 1073 "function not found. lib: %s\n", librarypath, 0, 0); 1074 continue; 1075 } 1076 /* Initialize this library */ 1077 if ((status = ((LoadLibraryFunc)())) != HBA_STATUS_OK) { 1078 /* maybe this should be a printf so that we CANNOT miss it */ 1079 (void) fprintf(stderr, 1080 "HBA_LoadLibrary: Encounterd and error loading: %s", 1081 librarypath); 1082 DEBUG(1, "Encounterd and error loading: %s", librarypath, 0, 0); 1083 DEBUG(1, " HBA_STATUS: %d", status, 0, 0); 1084 continue; 1085 } 1086 /* successfully loaded library */ 1087 lib_infop->status = HBA_LIBRARY_LOADED; 1088 } 1089 fclose(hbaconf); 1090 #endif /* WIN32 or UNIX */ 1091 #ifdef POSIX_THREADS 1092 /* 1093 * The _hbaapi_LL_mutex is already grabbed to proctect the caller of 1094 * HBA_FreeLibrary() during loading. 1095 * The mutexes are already initialized 1096 * with PTHREAD_MUTEX_INITIALIZER. Do we need to init again? 1097 * Keeping the code from HBAAPI source... 1098 */ 1099 ret = pthread_mutex_init(&_hbaapi_AL_mutex, NULL); 1100 if (ret == 0) { 1101 ret = pthread_mutex_init(&_hbaapi_AAE_mutex, NULL); 1102 } 1103 if (ret == 0) { 1104 ret = pthread_mutex_init(&_hbaapi_AE_mutex, NULL); 1105 } 1106 if (ret == 0) { 1107 ret = pthread_mutex_init(&_hbaapi_APE_mutex, NULL); 1108 } 1109 if (ret == 0) { 1110 ret = pthread_mutex_init(&_hbaapi_APSE_mutex, NULL); 1111 } 1112 if (ret == 0) { 1113 ret = pthread_mutex_init(&_hbaapi_TE_mutex, NULL); 1114 } 1115 if (ret == 0) { 1116 ret = pthread_mutex_init(&_smhba_AAE_mutex, NULL); 1117 } 1118 if (ret == 0) { 1119 ret = pthread_mutex_init(&_smhba_AE_mutex, NULL); 1120 } 1121 if (ret == 0) { 1122 ret = pthread_mutex_init(&_smhba_APE_mutex, NULL); 1123 } 1124 if (ret == 0) { 1125 ret = pthread_mutex_init(&_smhba_APSE_mutex, NULL); 1126 } 1127 if (ret == 0) { 1128 ret = pthread_mutex_init(&_smhba_TE_mutex, NULL); 1129 } 1130 if (ret == 0) { 1131 ret = pthread_mutex_init(&_hbaapi_LE_mutex, NULL); 1132 } 1133 if (ret != 0) { 1134 perror("pthread_mutex_init - HBA_LoadLibrary"); 1135 RELEASE_MUTEX(&_hbaapi_LL_mutex); 1136 return (HBA_STATUS_ERROR); 1137 } 1138 RELEASE_MUTEX(&_hbaapi_LL_mutex); 1139 #elif defined(WIN32) 1140 InitializeCriticalSection(&_hbaapi_LL_mutex); 1141 InitializeCriticalSection(&_hbaapi_AL_mutex); 1142 InitializeCriticalSection(&_hbaapi_AAE_mutex); 1143 InitializeCriticalSection(&_hbaapi_AE_mutex); 1144 InitializeCriticalSection(&_hbaapi_APE_mutex); 1145 InitializeCriticalSection(&_hbaapi_APSE_mutex); 1146 InitializeCriticalSection(&_hbaapi_TE_mutex); 1147 InitializeCriticalSection(&_hbaapi_LE_mutex); 1148 InitializeCriticalSection(&_smhba_AAE_mutex); 1149 InitializeCriticalSection(&_smhba_AE_mutex); 1150 InitializeCriticalSection(&_smhba_APE_mutex); 1151 InitializeCriticalSection(&_smhba_APSE_mutex); 1152 InitializeCriticalSection(&_smhba_TE_mutex); 1153 #endif 1154 1155 return (HBA_STATUS_OK); 1156 } 1157 1158 HBA_STATUS 1159 HBA_FreeLibrary() { 1160 HBAFreeLibraryFunc FreeLibraryFunc; 1161 /* LINTED E_FUNC_SET_NOT_USED */ 1162 HBA_STATUS status __unused; 1163 HBA_LIBRARY_INFO *lib_infop; 1164 HBA_LIBRARY_INFO *lib_next; 1165 HBA_ADAPTERCALLBACK_ELEM 1166 ***listp; 1167 HBA_ADAPTER_INFO *adapt_infop; 1168 HBA_ADAPTER_INFO *adapt_next; 1169 1170 GRAB_MUTEX(&_hbaapi_LL_mutex); 1171 if (_hbaapi_librarylist == NULL) { 1172 RELEASE_MUTEX(&_hbaapi_LL_mutex); 1173 return (HBA_STATUS_ERROR_NOT_LOADED); 1174 } 1175 1176 GRAB_MUTEX(&_hbaapi_AL_mutex); 1177 1178 DEBUG(1, "HBA_FreeLibrary()", 0, 0, 0); 1179 for (lib_infop = _hbaapi_librarylist; lib_infop != NULL; 1180 lib_infop = lib_next) { 1181 lib_next = lib_infop->next; 1182 if (lib_infop->status == HBA_LIBRARY_LOADED) { 1183 FreeLibraryFunc = FUNCCOMMON(lib_infop, FreeLibraryHandler); 1184 if (FreeLibraryFunc != NULL) { 1185 /* Free this library */ 1186 status = ((FreeLibraryFunc)()); 1187 DEBUG(1, "HBA_FreeLibrary() Failed %d", status, 0, 0); 1188 } 1189 #ifdef WIN32 1190 FreeLibrary(lib_infop->hLibrary); /* Unload DLL from memory */ 1191 #else 1192 (void) dlclose(lib_infop->hLibrary); /* Unload DLL from memory */ 1193 #endif 1194 } 1195 #ifndef WIN32 1196 free(lib_infop->LibraryName); 1197 #endif 1198 free(lib_infop->LibraryPath); 1199 free(lib_infop); 1200 1201 } 1202 _hbaapi_librarylist = NULL; 1203 /* 1204 * OK, now all functions are disabled except for LoadLibrary, 1205 * Hope no other thread calls it before we have returned 1206 */ 1207 _hbaapi_total_library_count = 0; 1208 1209 for (adapt_infop = _hbaapi_adapterlist; 1210 adapt_infop != NULL; 1211 adapt_infop = adapt_next) { 1212 adapt_next = adapt_infop->next; 1213 free(adapt_infop->name); 1214 free(adapt_infop); 1215 } 1216 _hbaapi_adapterlist = NULL; 1217 _hbaapi_total_adapter_count = 0; 1218 1219 /* 1220 * Free up the callbacks, this is not the most efficient, but it works 1221 */ 1222 while ((volatile HBA_ADAPTERCALLBACK_ELEM *) 1223 _hbaapi_adapteraddevents_callback_list 1224 != NULL) { 1225 (void) local_remove_callback((HBA_CALLBACKHANDLE) 1226 _hbaapi_adapteraddevents_callback_list); 1227 } 1228 while ((volatile HBA_ADAPTERCALLBACK_ELEM *) 1229 _smhba_adapteraddevents_callback_list 1230 != NULL) { 1231 (void) local_remove_callback((HBA_CALLBACKHANDLE) 1232 _smhba_adapteraddevents_callback_list); 1233 } 1234 for (listp = cb_lists_array; *listp != NULL; listp++) { 1235 while ((volatile HBA_ADAPTERCALLBACK_ELEM ***)**listp != NULL) { 1236 (void) local_remove_callback((HBA_CALLBACKHANDLE)**listp); 1237 } 1238 } 1239 1240 RELEASE_MUTEX(&_hbaapi_AL_mutex); 1241 RELEASE_MUTEX(&_hbaapi_LL_mutex); 1242 1243 #ifdef USESYSLOG 1244 closelog(); 1245 #endif 1246 #ifdef USELOGFILE 1247 if (_hbaapi_debug_fd != NULL) { 1248 fclose(_hbaapi_debug_fd); 1249 } 1250 _hbaapi_debug_fd = NULL; 1251 #endif 1252 #ifdef POSIX_THREADS 1253 /* this will unlock them as well, but who cares */ 1254 (void) pthread_mutex_destroy(&_hbaapi_LE_mutex); 1255 (void) pthread_mutex_destroy(&_hbaapi_TE_mutex); 1256 (void) pthread_mutex_destroy(&_hbaapi_APSE_mutex); 1257 (void) pthread_mutex_destroy(&_hbaapi_APE_mutex); 1258 (void) pthread_mutex_destroy(&_hbaapi_AE_mutex); 1259 (void) pthread_mutex_destroy(&_hbaapi_AAE_mutex); 1260 (void) pthread_mutex_destroy(&_smhba_TE_mutex); 1261 (void) pthread_mutex_destroy(&_smhba_APSE_mutex); 1262 (void) pthread_mutex_destroy(&_smhba_APE_mutex); 1263 (void) pthread_mutex_destroy(&_smhba_AE_mutex); 1264 (void) pthread_mutex_destroy(&_smhba_AAE_mutex); 1265 (void) pthread_mutex_destroy(&_hbaapi_AL_mutex); 1266 (void) pthread_mutex_destroy(&_hbaapi_LL_mutex); 1267 #elif defined(WIN32) 1268 DeleteCriticalSection(&_hbaapi_LL_mutex); 1269 DeleteCriticalSection(&_hbaapi_AL_mutex); 1270 DeleteCriticalSection(&_hbaapi_AAE_mutex); 1271 DeleteCriticalSection(&_hbaapi_AE_mutex); 1272 DeleteCriticalSection(&_hbaapi_APE_mutex); 1273 DeleteCriticalSection(&_hbaapi_APSE_mutex); 1274 DeleteCriticalSection(&_hbaapi_TE_mutex); 1275 DeleteCriticalSection(&_hbaapi_LE_mutex); 1276 DeleteCriticalSection(&_smhba_TE_mutex); 1277 DeleteCriticalSection(&_smhba_APSE_mutex); 1278 DeleteCriticalSection(&_smhba_APE_mutex); 1279 DeleteCriticalSection(&_smhba_AE_mutex); 1280 DeleteCriticalSection(&_smhba_AAE_mutex); 1281 #endif 1282 1283 return (HBA_STATUS_OK); 1284 } 1285 1286 /* 1287 * The API used to use fixed size tables as its primary data structure. 1288 * Indexing from 1 to N identified each adapters. Now the adapters are 1289 * on a linked list. There is a unique "index" foreach each adapter. 1290 * Adapters always keep their index, even if they are removed from the 1291 * hardware. The only time the indexing is reset is on HBA_FreeLibrary 1292 */ 1293 HBA_UINT32 1294 HBA_GetNumberOfAdapters() 1295 { 1296 int j = 0; 1297 HBA_LIBRARY_INFO *lib_infop; 1298 HBAGetNumberOfAdaptersFunc GetNumberOfAdaptersFunc; 1299 HBAGetAdapterNameFunc GetAdapterNameFunc; 1300 HBA_BOOLEAN found_name; 1301 HBA_ADAPTER_INFO *adapt_infop; 1302 HBA_STATUS status; 1303 1304 char adaptername[256]; 1305 int num_adapters; /* local */ 1306 1307 if (_hbaapi_librarylist == NULL) { 1308 return (0); 1309 } 1310 GRAB_MUTEX(&_hbaapi_LL_mutex); /* pay attention to order */ 1311 GRAB_MUTEX(&_hbaapi_AL_mutex); 1312 1313 for (lib_infop = _hbaapi_librarylist; 1314 lib_infop != NULL; 1315 lib_infop = lib_infop->next) { 1316 1317 if (lib_infop->status != HBA_LIBRARY_LOADED) { 1318 continue; 1319 } 1320 1321 GetNumberOfAdaptersFunc = 1322 FUNCCOMMON(lib_infop, GetNumberOfAdaptersHandler); 1323 if (GetNumberOfAdaptersFunc == NULL) { 1324 continue; 1325 } 1326 num_adapters = ((GetNumberOfAdaptersFunc)()); 1327 #ifndef WIN32 1328 DEBUG(1, "HBAAPI: num_adapters for %s = %d\n", 1329 lib_infop->LibraryName, num_adapters, 0); 1330 #else 1331 DEBUG(1, "HBAAPI: num_adapters for %s = %d\n", 1332 lib_infop->LibraryPath, num_adapters, 0); 1333 #endif 1334 1335 /* Also get the names of all the adapters here and cache */ 1336 GetAdapterNameFunc = FUNCCOMMON(lib_infop, GetAdapterNameHandler); 1337 if (GetAdapterNameFunc == NULL) { 1338 continue; 1339 } 1340 1341 for (j = 0; j < num_adapters; j++) { 1342 found_name = 0; 1343 status = (GetAdapterNameFunc)(j, (char *)&adaptername); 1344 if (status == HBA_STATUS_OK) { 1345 for (adapt_infop = _hbaapi_adapterlist; 1346 adapt_infop != NULL; 1347 adapt_infop = adapt_infop->next) { 1348 /* 1349 * check for duplicates, really, 1350 * this may just be a second 1351 * call to this function 1352 * ??? how do we know when a name becomes stale? 1353 */ 1354 if (strcmp(adaptername, adapt_infop->name) == 0) { 1355 /* already got this one */ 1356 found_name++; 1357 break; 1358 } 1359 } 1360 if (found_name != 0) { 1361 continue; 1362 } 1363 } 1364 1365 adapt_infop = (HBA_ADAPTER_INFO *) 1366 calloc(1, sizeof (HBA_ADAPTER_INFO)); 1367 if (adapt_infop == NULL) { 1368 #ifndef WIN32 1369 (void) fprintf(stderr, 1370 "HBA_GetNumberOfAdapters: calloc failed" 1371 " on sizeof:%lu\n", 1372 (unsigned long)(sizeof (HBA_ADAPTER_INFO))); 1373 #endif 1374 RELEASE_MUTEX(&_hbaapi_AL_mutex); 1375 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, 1376 _hbaapi_total_adapter_count); 1377 } 1378 if ((adapt_infop->GNstatus = status) == HBA_STATUS_OK) { 1379 adapt_infop->name = strdup(adaptername); 1380 } else { 1381 char dummyname[512]; 1382 (void) sprintf(dummyname, "NULLADAPTER-%255s-%03d", 1383 lib_infop->LibraryPath, _hbaapi_total_adapter_count); 1384 dummyname[511] = '\0'; 1385 adapt_infop->name = strdup(dummyname); 1386 } 1387 lib_infop->numOfAdapters++; 1388 adapt_infop->library = lib_infop; 1389 adapt_infop->next = _hbaapi_adapterlist; 1390 adapt_infop->index = _hbaapi_total_adapter_count; 1391 _hbaapi_adapterlist = adapt_infop; 1392 _hbaapi_total_adapter_count++; 1393 } 1394 } 1395 RELEASE_MUTEX(&_hbaapi_AL_mutex); 1396 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, _hbaapi_total_adapter_count); 1397 } 1398 1399 HBA_STATUS 1400 HBA_GetAdapterName( 1401 HBA_UINT32 adapterindex, 1402 char *adaptername) 1403 { 1404 HBA_ADAPTER_INFO *adapt_infop; 1405 HBA_STATUS ret = HBA_STATUS_ERROR_ILLEGAL_INDEX; 1406 1407 if (adaptername == NULL) { 1408 DEBUG(1, "HBA_GetAdapterName: NULL pointer adaptername", 1409 0, 0, 0); 1410 return (HBA_STATUS_ERROR_ARG); 1411 } 1412 1413 /* 1414 * The adapter index is from old code, but we have 1415 * to support it. Go down the list looking for 1416 * the adapter 1417 */ 1418 ARE_WE_INITED(); 1419 GRAB_MUTEX(&_hbaapi_AL_mutex); 1420 *adaptername = '\0'; 1421 for (adapt_infop = _hbaapi_adapterlist; 1422 adapt_infop != NULL; 1423 adapt_infop = adapt_infop->next) { 1424 1425 if (adapt_infop->index == adapterindex) { 1426 if (adapt_infop->name != NULL && 1427 adapt_infop->GNstatus == HBA_STATUS_OK) { 1428 (void) strcpy(adaptername, adapt_infop->name); 1429 } else { 1430 *adaptername = '\0'; 1431 } 1432 ret = adapt_infop->GNstatus; 1433 break; 1434 } 1435 } 1436 DEBUG(2, "GetAdapterName for index:%d ->%s", 1437 adapterindex, adaptername, 0); 1438 RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, ret); 1439 } 1440 1441 HBA_HANDLE 1442 HBA_OpenAdapter(char *adaptername) 1443 { 1444 HBA_HANDLE handle; 1445 HBAOpenAdapterFunc OpenAdapterFunc; 1446 HBA_ADAPTER_INFO *adapt_infop; 1447 HBA_LIBRARY_INFO *lib_infop; 1448 1449 DEBUG(2, "OpenAdapter: %s", adaptername, 0, 0); 1450 1451 handle = HBA_HANDLE_INVALID; 1452 if (_hbaapi_librarylist == NULL) { 1453 return (handle); 1454 } 1455 if (adaptername == NULL) { 1456 DEBUG(1, "HBA_OpenAdapter: NULL pointer adaptername", 1457 0, 0, 0); 1458 return (handle); 1459 } 1460 GRAB_MUTEX(&_hbaapi_AL_mutex); 1461 for (adapt_infop = _hbaapi_adapterlist; 1462 adapt_infop != NULL; 1463 adapt_infop = adapt_infop->next) { 1464 if (strcmp(adaptername, adapt_infop->name) != 0) { 1465 continue; 1466 } 1467 lib_infop = adapt_infop->library; 1468 OpenAdapterFunc = FUNCCOMMON(lib_infop, OpenAdapterHandler); 1469 1470 if (OpenAdapterFunc != NULL) { 1471 /* retrieve the vendor handle */ 1472 handle = (OpenAdapterFunc)(adaptername); 1473 if (handle != 0) { 1474 /* or this with the library index to get the common handle */ 1475 handle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle); 1476 } 1477 } 1478 break; 1479 } 1480 RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, handle); 1481 } 1482 1483 /* 1484 * Finding an adapter with matching WWN. 1485 */ 1486 HBA_STATUS 1487 HBA_OpenAdapterByWWN(HBA_HANDLE *phandle, HBA_WWN nodeWWN) { 1488 HBA_HANDLE handle; 1489 HBA_LIBRARY_INFO *lib_infop; 1490 HBAGetNumberOfAdaptersFunc 1491 GetNumberOfAdaptersFunc; 1492 HBAOpenAdapterByWWNFunc 1493 OpenAdapterFunc; 1494 HBA_STATUS status; 1495 1496 DEBUG(2, "OpenAdapterByWWN: %s", WWN2STR1(&nodeWWN), 0, 0); 1497 ARE_WE_INITED(); 1498 1499 *phandle = HBA_HANDLE_INVALID; 1500 1501 GRAB_MUTEX(&_hbaapi_LL_mutex); 1502 for (lib_infop = _hbaapi_librarylist; 1503 lib_infop != NULL; 1504 lib_infop = lib_infop->next) { 1505 1506 status = HBA_STATUS_ERROR_ILLEGAL_WWN; 1507 1508 if (lib_infop->status != HBA_LIBRARY_LOADED) { 1509 continue; 1510 } 1511 1512 /* only for HBAAPIV2 */ 1513 if (lib_infop->version != HBAAPIV2) { 1514 continue; 1515 } 1516 1517 GetNumberOfAdaptersFunc = 1518 FUNCCOMMON(lib_infop, GetNumberOfAdaptersHandler); 1519 if (GetNumberOfAdaptersFunc == NULL) { 1520 continue; 1521 } 1522 1523 /* look for new hardware */ 1524 (void) ((GetNumberOfAdaptersFunc)()); 1525 1526 OpenAdapterFunc = 1527 lib_infop->ftable.functionTable.OpenAdapterByWWNHandler; 1528 if (OpenAdapterFunc == NULL) { 1529 continue; 1530 } 1531 /* 1532 * We do not know if the WWN is known by this vendor, 1533 * just try it 1534 */ 1535 if ((status = (OpenAdapterFunc)(&handle, nodeWWN)) != HBA_STATUS_OK) { 1536 continue; 1537 } 1538 /* OK, make a vendor non-specific handle */ 1539 *phandle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle); 1540 status = HBA_STATUS_OK; 1541 break; 1542 } 1543 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 1544 } 1545 1546 void 1547 HBA_RefreshAdapterConfiguration() { 1548 DEBUG(2, "HBA_RefreshAdapterConfiguration", 0, 0, 0); 1549 (void) HBA_GetNumberOfAdapters(); 1550 } 1551 1552 HBA_UINT32 1553 HBA_GetVersion() { 1554 DEBUG(2, "HBA_GetVersion", 0, 0, 0); 1555 return (HBA_LIBVERSION); 1556 } 1557 1558 /* 1559 * This function is VERY OS dependent. Wing it as best you can. 1560 */ 1561 HBA_UINT32 1562 HBA_GetWrapperLibraryAttributes( 1563 HBA_LIBRARYATTRIBUTES *attributes) 1564 { 1565 1566 DEBUG(2, "HBA_GetWrapperLibraryAttributes", 0, 0, 0); 1567 1568 if (attributes == NULL) { 1569 DEBUG(1, "HBA_GetWrapperLibraryAttributes:" 1570 "NULL pointer attributes", 1571 0, 0, 0); 1572 return (HBA_STATUS_ERROR_ARG); 1573 } 1574 1575 (void) memset(attributes, 0, sizeof (HBA_LIBRARYATTRIBUTES)); 1576 1577 #if defined(SOLARIS) 1578 if ((handle = dlopen("libHBAAPI.so", RTLD_NOW)) != NULL) { 1579 if (dlinfo(handle, RTLD_DI_LINKMAP, &map) >= 0) { 1580 for (mp = map; mp != NULL; mp = mp->l_next) { 1581 if (strlen(map->l_name) < 256) { 1582 (void) strcpy(attributes->LibPath, map->l_name); 1583 } 1584 } 1585 } 1586 } 1587 #elif defined(WIN32) 1588 HMODULE module; 1589 1590 /* No need to do anything with the module handle */ 1591 /* It wasn't alloocated so it doesn't need to be freed */ 1592 module = GetModuleHandle("HBAAPI"); 1593 if (module != NULL) { 1594 if (GetModuleFileName(module, attributes->LibPath, 1595 sizeof (attributes->LibPath)) == 0) { 1596 attributes->LibPath[0] = '\0'; 1597 } 1598 } 1599 #endif 1600 #if defined(VENDOR) 1601 (void) strcpy(attributes->VName, VENDOR); 1602 #else 1603 attributes->VName[0] = '\0'; 1604 #endif 1605 #if defined(VERSION) 1606 (void) strcpy(attributes->VVersion, VERSION); 1607 #else 1608 attributes->VVersion[0] = '\0'; 1609 #endif 1610 #if defined(BUILD_DATE) 1611 #if defined(WIN32) 1612 int matchCount; 1613 matchCount = sscanf(BUILD_DATE, "%u/%u/%u %u:%u:%u", 1614 &attributes->build_date.tm_year, 1615 &attributes->build_date.tm_mon, 1616 &attributes->build_date.tm_mday, 1617 &attributes->build_date.tm_hour, 1618 &attributes->build_date.tm_min, 1619 &attributes->build_date.tm_sec); 1620 1621 if (matchCount != 6) { 1622 memset(&attributes->build_date, 0, sizeof (struct tm)); 1623 } else { 1624 attributes->build_date.tm_year -= 1900; 1625 attributes->build_date.tm_isdst = -1; 1626 } 1627 #else 1628 if (strptime(BUILD_DATE, 1629 "%Y/%m/%d %T %Z", &(attributes->build_date)) == NULL) { 1630 (void) memset(&attributes->build_date, 0, sizeof (struct tm)); 1631 } 1632 #endif 1633 #else 1634 (void) memset(&attributes->build_date, 0, sizeof (struct tm)); 1635 #endif 1636 return (2); 1637 } 1638 1639 /* 1640 * Callback registation and handling 1641 */ 1642 HBA_STATUS 1643 HBA_RemoveCallback(HBA_CALLBACKHANDLE cbhandle) { 1644 HBA_STATUS status; 1645 1646 DEBUG(2, "HBA_RemoveCallback", 0, 0, 0); 1647 ARE_WE_INITED(); 1648 1649 GRAB_MUTEX(&_hbaapi_LL_mutex); 1650 status = local_remove_callback(cbhandle); 1651 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 1652 } 1653 1654 /* Adapter Add Events ************************************************* */ 1655 static void 1656 /* LINTED E_FUNC_ARG_UNUSED */ 1657 adapteraddevents_callback(void *data, HBA_WWN PortWWN, HBA_UINT32 eventType) { 1658 HBA_ALLADAPTERSCALLBACK_ELEM *cbp; 1659 1660 DEBUG(3, "AddAdapterEvent, port: %s", WWN2STR1(&PortWWN), 0, 0); 1661 1662 GRAB_MUTEX(&_hbaapi_AAE_mutex); 1663 for (cbp = _hbaapi_adapteraddevents_callback_list; 1664 cbp != NULL; 1665 cbp = cbp->next) { 1666 (*cbp->callback)(data, PortWWN, HBA_EVENT_ADAPTER_ADD); 1667 } 1668 RELEASE_MUTEX(&_hbaapi_AAE_mutex); 1669 1670 } 1671 1672 HBA_STATUS 1673 HBA_RegisterForAdapterAddEvents( 1674 void (*callback)( 1675 void *data, 1676 HBA_WWN PortWWN, 1677 HBA_UINT32 eventType), 1678 void *userData, 1679 HBA_CALLBACKHANDLE *callbackHandle) { 1680 1681 HBA_ALLADAPTERSCALLBACK_ELEM *cbp; 1682 HBA_VENDORCALLBACK_ELEM *vcbp; 1683 HBA_VENDORCALLBACK_ELEM *vendorhandlelist; 1684 HBARegisterForAdapterAddEventsFunc registeredfunc; 1685 HBA_STATUS status = HBA_STATUS_OK; 1686 HBA_STATUS failure = HBA_STATUS_OK; 1687 HBA_LIBRARY_INFO *lib_infop; 1688 int registered_cnt = 0; 1689 int vendor_cnt = 0; 1690 int not_supported_cnt = 0; 1691 int status_OK_bar_cnt = 0; 1692 int status_OK_cnt = 0; 1693 1694 DEBUG(2, "HBA_RegisterForAdapterAddEvents", 0, 0, 0); 1695 ARE_WE_INITED(); 1696 1697 cbp = (HBA_ALLADAPTERSCALLBACK_ELEM *) 1698 calloc(1, sizeof (HBA_ALLADAPTERSCALLBACK_ELEM)); 1699 *callbackHandle = (HBA_CALLBACKHANDLE) cbp; 1700 if (cbp == NULL) { 1701 #ifndef WIN32 1702 (void) fprintf(stderr, 1703 "HBA_RegisterForAdapterAddEvents: calloc failed " 1704 "for %lu bytes\n", 1705 (unsigned long)(sizeof (HBA_ALLADAPTERSCALLBACK_ELEM))); 1706 #endif 1707 return (HBA_STATUS_ERROR); 1708 } 1709 1710 GRAB_MUTEX(&_hbaapi_LL_mutex); 1711 GRAB_MUTEX(&_hbaapi_AAE_mutex); 1712 cbp->callback = callback; 1713 cbp->next = _hbaapi_adapteraddevents_callback_list; 1714 _hbaapi_adapteraddevents_callback_list = cbp; 1715 /* 1716 * Need to release the mutex now incase the vendor function invokes the 1717 * callback. We will grap the mutex later to attach the vendor handle 1718 * list to the callback structure 1719 */ 1720 RELEASE_MUTEX(&_hbaapi_AAE_mutex); 1721 1722 /* 1723 * now create a list of vendors (vendor libraryies, NOT ADAPTERS) 1724 * that have successfully registerred 1725 */ 1726 vendorhandlelist = NULL; 1727 for (lib_infop = _hbaapi_librarylist; 1728 lib_infop != NULL; 1729 lib_infop = lib_infop->next) { 1730 1731 /* only for HBAAPI V2 */ 1732 if ((lib_infop->version != HBAAPIV2)) { 1733 continue; 1734 } else { 1735 vendor_cnt++; 1736 } 1737 1738 registeredfunc = 1739 lib_infop->ftable.functionTable.RegisterForAdapterAddEventsHandler; 1740 if (registeredfunc == NULL) { 1741 continue; 1742 } 1743 1744 vcbp = (HBA_VENDORCALLBACK_ELEM *) 1745 calloc(1, sizeof (HBA_VENDORCALLBACK_ELEM)); 1746 if (vcbp == NULL) { 1747 #ifndef WIN32 1748 (void) fprintf(stderr, 1749 "HBA_RegisterForAdapterAddEvents: " 1750 "calloc failed for %lu bytes\n", 1751 (unsigned long)(sizeof (HBA_VENDORCALLBACK_ELEM))); 1752 #endif 1753 freevendorhandlelist(vendorhandlelist); 1754 status = HBA_STATUS_ERROR; 1755 break; 1756 } 1757 1758 registered_cnt++; 1759 status = (registeredfunc)(adapteraddevents_callback, 1760 userData, &vcbp->vendorcbhandle); 1761 if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) { 1762 not_supported_cnt++; 1763 free(vcbp); 1764 continue; 1765 } else if (status != HBA_STATUS_OK) { 1766 status_OK_bar_cnt++; 1767 DEBUG(1, 1768 "HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d", 1769 lib_infop->LibraryPath, status, 0); 1770 #ifndef WIN32 1771 (void) fprintf(stderr, 1772 "HBA_RegisterForAdapterAddEvents: Library->%s, Error->%d", 1773 lib_infop->LibraryPath, status); 1774 #endif 1775 failure = status; 1776 free(vcbp); 1777 continue; 1778 } else { 1779 status_OK_cnt++; 1780 } 1781 vcbp->lib_info = lib_infop; 1782 vcbp->next = vendorhandlelist; 1783 vendorhandlelist = vcbp; 1784 } 1785 if (vendor_cnt == 0) { 1786 /* no HBAAPIV2 is deteced. should be okay? */ 1787 status = HBA_STATUS_ERROR; 1788 } else if (registered_cnt == 0) { 1789 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 1790 freevendorhandlelist(vendorhandlelist); 1791 (void) local_remove_callback((HBA_CALLBACKHANDLE) cbp); 1792 } else if (status_OK_cnt == 0 && not_supported_cnt != 0) { 1793 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 1794 } else if (status_OK_cnt == 0) { 1795 /* 1796 * At least one vendor library registered this function, but no 1797 * vendor call succeeded 1798 */ 1799 (void) local_remove_callback((HBA_CALLBACKHANDLE) cbp); 1800 status = failure; 1801 } else { 1802 /* we have had atleast some success, now finish up */ 1803 GRAB_MUTEX(&_hbaapi_AAE_mutex); 1804 /* 1805 * this seems silly, but what if another thread called 1806 * the callback remove 1807 */ 1808 for (cbp = _hbaapi_adapteraddevents_callback_list; 1809 cbp != NULL; cbp = cbp->next) { 1810 if ((HBA_CALLBACKHANDLE)cbp == *callbackHandle) { 1811 /* yup, its still there, hooray */ 1812 cbp->vendorhandlelist = vendorhandlelist; 1813 vendorhandlelist = NULL; 1814 break; 1815 } 1816 } 1817 RELEASE_MUTEX(&_hbaapi_AAE_mutex); 1818 if (vendorhandlelist != NULL) { 1819 /* 1820 * bummer, somebody removed the callback before we finished 1821 * registration, probably will never happen 1822 */ 1823 freevendorhandlelist(vendorhandlelist); 1824 DEBUG(1, 1825 "HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was " 1826 "called for a handle before registration was finished.", 1827 0, 0, 0); 1828 status = HBA_STATUS_ERROR; 1829 } else { 1830 status = HBA_STATUS_OK; 1831 } 1832 } 1833 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 1834 } 1835 1836 /* Adapter Events (other than add) ************************************** */ 1837 static void 1838 adapterevents_callback(void *data, 1839 HBA_WWN PortWWN, 1840 HBA_UINT32 eventType) { 1841 HBA_ADAPTERCALLBACK_ELEM *acbp; 1842 1843 DEBUG(3, "AdapterEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN), 1844 eventType, 0); 1845 1846 GRAB_MUTEX(&_hbaapi_AE_mutex); 1847 for (acbp = _hbaapi_adapterevents_callback_list; 1848 acbp != NULL; 1849 acbp = acbp->next) { 1850 if (data == (void *)acbp) { 1851 (*acbp->callback)(acbp->userdata, PortWWN, eventType); 1852 break; 1853 } 1854 } 1855 RELEASE_MUTEX(&_hbaapi_AE_mutex); 1856 } 1857 HBA_STATUS 1858 HBA_RegisterForAdapterEvents( 1859 void (*callback) ( 1860 void *data, 1861 HBA_WWN PortWWN, 1862 HBA_UINT32 eventType), 1863 void *userData, 1864 HBA_HANDLE handle, 1865 HBA_CALLBACKHANDLE *callbackHandle) { 1866 1867 HBA_ADAPTERCALLBACK_ELEM *acbp; 1868 HBARegisterForAdapterEventsFunc registeredfunc; 1869 HBA_STATUS status; 1870 HBA_LIBRARY_INFO *lib_infop; 1871 HBA_HANDLE vendorHandle; 1872 1873 DEBUG(2, "HBA_RegisterForAdapterEvents", 0, 0, 0); 1874 1875 CHECKLIBRARYANDVERSION(HBAAPIV2); 1876 1877 /* we now have the _hbaapi_LL_mutex */ 1878 1879 registeredfunc = 1880 lib_infop->ftable.functionTable.RegisterForAdapterEventsHandler; 1881 if (registeredfunc == NULL) { 1882 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 1883 } 1884 1885 /* 1886 * that allocated memory is used both as the handle for the 1887 * caller, and as userdata to the vendor call so that on 1888 * callback the specific registration may be recalled 1889 */ 1890 acbp = (HBA_ADAPTERCALLBACK_ELEM *) 1891 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM)); 1892 if (acbp == NULL) { 1893 #ifndef WIN32 1894 (void) fprintf(stderr, 1895 "HBA_RegisterForAdapterEvents: calloc failed for %lu bytes\n", 1896 (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM))); 1897 #endif 1898 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); 1899 } 1900 *callbackHandle = (HBA_CALLBACKHANDLE) acbp; 1901 acbp->callback = callback; 1902 acbp->userdata = userData; 1903 acbp->lib_info = lib_infop; 1904 1905 status = (registeredfunc)(adapterevents_callback, 1906 (void *)acbp, 1907 vendorHandle, 1908 &acbp->vendorcbhandle); 1909 if (status != HBA_STATUS_OK) { 1910 free(acbp); 1911 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 1912 } 1913 1914 GRAB_MUTEX(&_hbaapi_AE_mutex); 1915 acbp->next = _hbaapi_adapterevents_callback_list; 1916 _hbaapi_adapterevents_callback_list = acbp; 1917 RELEASE_MUTEX(&_hbaapi_AE_mutex); 1918 1919 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 1920 } 1921 1922 /* Adapter Port Events ************************************************** */ 1923 static void 1924 adapterportevents_callback(void *data, 1925 HBA_WWN PortWWN, 1926 HBA_UINT32 eventType, 1927 HBA_UINT32 fabricPortID) { 1928 HBA_ADAPTERCALLBACK_ELEM *acbp; 1929 1930 DEBUG(3, "AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x", 1931 WWN2STR1(&PortWWN), eventType, fabricPortID); 1932 1933 GRAB_MUTEX(&_hbaapi_APE_mutex); 1934 1935 for (acbp = _hbaapi_adapterportevents_callback_list; 1936 acbp != NULL; 1937 acbp = acbp->next) { 1938 if (data == (void *)acbp) { 1939 (*acbp->callback)(acbp->userdata, PortWWN, eventType, fabricPortID); 1940 break; 1941 } 1942 } 1943 RELEASE_MUTEX(&_hbaapi_APE_mutex); 1944 } 1945 1946 HBA_STATUS 1947 HBA_RegisterForAdapterPortEvents( 1948 void (*callback) ( 1949 void *data, 1950 HBA_WWN PortWWN, 1951 HBA_UINT32 eventType, 1952 HBA_UINT32 fabricPortID), 1953 void *userData, 1954 HBA_HANDLE handle, 1955 HBA_WWN PortWWN, 1956 HBA_CALLBACKHANDLE *callbackHandle) { 1957 1958 HBA_ADAPTERCALLBACK_ELEM *acbp; 1959 HBARegisterForAdapterPortEventsFunc registeredfunc; 1960 HBA_STATUS status; 1961 HBA_LIBRARY_INFO *lib_infop; 1962 HBA_HANDLE vendorHandle; 1963 1964 DEBUG(2, "HBA_RegisterForAdapterPortEvents for port: %s", 1965 WWN2STR1(&PortWWN), 0, 0); 1966 1967 CHECKLIBRARYANDVERSION(HBAAPIV2); 1968 /* we now have the _hbaapi_LL_mutex */ 1969 1970 registeredfunc = 1971 lib_infop->ftable.functionTable.RegisterForAdapterPortEventsHandler; 1972 if (registeredfunc == NULL) { 1973 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 1974 } 1975 1976 /* 1977 * that allocated memory is used both as the handle for the 1978 * caller, and as userdata to the vendor call so that on 1979 * callback the specific registration may be recalled 1980 */ 1981 acbp = (HBA_ADAPTERCALLBACK_ELEM *) 1982 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM)); 1983 if (acbp == NULL) { 1984 #ifndef WIN32 1985 (void) fprintf(stderr, 1986 "HBA_RegisterForAdapterPortEvents: " 1987 "calloc failed for %lu bytes\n", 1988 (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM))); 1989 #endif 1990 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); 1991 1992 } 1993 *callbackHandle = (HBA_CALLBACKHANDLE) acbp; 1994 acbp->callback = callback; 1995 acbp->userdata = userData; 1996 acbp->lib_info = lib_infop; 1997 1998 status = (registeredfunc)(adapterportevents_callback, 1999 (void *)acbp, 2000 vendorHandle, 2001 PortWWN, 2002 &acbp->vendorcbhandle); 2003 if (status != HBA_STATUS_OK) { 2004 free(acbp); 2005 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2006 } 2007 2008 GRAB_MUTEX(&_hbaapi_APE_mutex); 2009 acbp->next = _hbaapi_adapterportevents_callback_list; 2010 _hbaapi_adapterportevents_callback_list = acbp; 2011 RELEASE_MUTEX(&_hbaapi_APE_mutex); 2012 2013 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 2014 } 2015 2016 /* Adapter State Events ************************************************ */ 2017 static void 2018 adapterportstatevents_callback(void *data, 2019 HBA_WWN PortWWN, 2020 HBA_UINT32 eventType) { 2021 HBA_ADAPTERCALLBACK_ELEM *acbp; 2022 2023 DEBUG(3, "AdapterPortStatEvent, port:%s, eventType:%d", 2024 WWN2STR1(&PortWWN), 2025 eventType, 0); 2026 2027 GRAB_MUTEX(&_hbaapi_APSE_mutex); 2028 for (acbp = _hbaapi_adapterportstatevents_callback_list; 2029 acbp != NULL; 2030 acbp = acbp->next) { 2031 if (data == (void *)acbp) { 2032 (*acbp->callback)(acbp->userdata, PortWWN, eventType); 2033 return; 2034 } 2035 } 2036 RELEASE_MUTEX(&_hbaapi_APSE_mutex); 2037 } 2038 HBA_STATUS 2039 HBA_RegisterForAdapterPortStatEvents( 2040 void (*callback) ( 2041 void *data, 2042 HBA_WWN PortWWN, 2043 HBA_UINT32 eventType), 2044 void *userData, 2045 HBA_HANDLE handle, 2046 HBA_WWN PortWWN, 2047 HBA_PORTSTATISTICS stats, 2048 HBA_UINT32 statType, 2049 HBA_CALLBACKHANDLE *callbackHandle) { 2050 2051 HBA_ADAPTERCALLBACK_ELEM *acbp; 2052 HBARegisterForAdapterPortStatEventsFunc 2053 registeredfunc; 2054 HBA_STATUS status; 2055 HBA_LIBRARY_INFO *lib_infop; 2056 HBA_HANDLE vendorHandle; 2057 2058 DEBUG(2, "HBA_RegisterForAdapterPortStatEvents for port: %s", 2059 WWN2STR1(&PortWWN), 0, 0); 2060 2061 CHECKLIBRARYANDVERSION(HBAAPIV2); 2062 /* we now have the _hbaapi_LL_mutex */ 2063 2064 registeredfunc = 2065 lib_infop->ftable.functionTable.RegisterForAdapterPortStatEventsHandler; 2066 if (registeredfunc == NULL) { 2067 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 2068 } 2069 2070 /* 2071 * that allocated memory is used both as the handle for the 2072 * caller, and as userdata to the vendor call so that on 2073 * callback the specific registration may be recalled 2074 */ 2075 acbp = (HBA_ADAPTERCALLBACK_ELEM *) 2076 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM)); 2077 if (acbp == NULL) { 2078 #ifndef WIN32 2079 (void) fprintf(stderr, 2080 "HBA_RegisterForAdapterPortStatEvents: " 2081 "calloc failed for %lu bytes\n", 2082 (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM))); 2083 #endif 2084 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); 2085 } 2086 *callbackHandle = (HBA_CALLBACKHANDLE) acbp; 2087 acbp->callback = callback; 2088 acbp->userdata = userData; 2089 acbp->lib_info = lib_infop; 2090 2091 status = (registeredfunc)(adapterportstatevents_callback, 2092 (void *)acbp, 2093 vendorHandle, 2094 PortWWN, 2095 stats, 2096 statType, 2097 &acbp->vendorcbhandle); 2098 if (status != HBA_STATUS_OK) { 2099 free(acbp); 2100 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2101 } 2102 2103 GRAB_MUTEX(&_hbaapi_APSE_mutex); 2104 acbp->next = _hbaapi_adapterportstatevents_callback_list; 2105 _hbaapi_adapterportstatevents_callback_list = acbp; 2106 RELEASE_MUTEX(&_hbaapi_APSE_mutex); 2107 2108 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 2109 } 2110 2111 /* Target Events ******************************************************* */ 2112 static void 2113 targetevents_callback(void *data, 2114 HBA_WWN hbaPortWWN, 2115 HBA_WWN discoveredPortWWN, 2116 HBA_UINT32 eventType) { 2117 2118 HBA_ADAPTERCALLBACK_ELEM *acbp; 2119 2120 DEBUG(3, "TargetEvent, hbaPort:%s, discoveredPort:%s eventType:%d", 2121 WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), eventType); 2122 2123 GRAB_MUTEX(&_hbaapi_TE_mutex); 2124 for (acbp = _hbaapi_targetevents_callback_list; 2125 acbp != NULL; 2126 acbp = acbp->next) { 2127 if (data == (void *)acbp) { 2128 (*acbp->callback)(acbp->userdata, hbaPortWWN, 2129 discoveredPortWWN, eventType); 2130 break; 2131 } 2132 } 2133 RELEASE_MUTEX(&_hbaapi_TE_mutex); 2134 } 2135 2136 HBA_STATUS 2137 HBA_RegisterForTargetEvents( 2138 void (*callback) ( 2139 void *data, 2140 HBA_WWN hbaPortWWN, 2141 HBA_WWN discoveredPortWWN, 2142 HBA_UINT32 eventType), 2143 void *userData, 2144 HBA_HANDLE handle, 2145 HBA_WWN hbaPortWWN, 2146 HBA_WWN discoveredPortWWN, 2147 HBA_CALLBACKHANDLE *callbackHandle, 2148 HBA_UINT32 allTargets) { 2149 2150 HBA_ADAPTERCALLBACK_ELEM 2151 *acbp; 2152 HBARegisterForTargetEventsFunc 2153 registeredfunc; 2154 HBA_STATUS status; 2155 HBA_LIBRARY_INFO *lib_infop; 2156 HBA_HANDLE vendorHandle; 2157 2158 DEBUG(2, "HBA_RegisterForTargetEvents, hbaPort: %s, discoveredPort: %s", 2159 WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), 0); 2160 2161 CHECKLIBRARYANDVERSION(HBAAPIV2); 2162 /* we now have the _hbaapi_LL_mutex */ 2163 2164 registeredfunc = 2165 lib_infop->ftable.functionTable.RegisterForTargetEventsHandler; 2166 if (registeredfunc == NULL) { 2167 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 2168 } 2169 2170 /* 2171 * that allocated memory is used both as the handle for the 2172 * caller, and as userdata to the vendor call so that on 2173 * callback the specific registration may be recalled 2174 */ 2175 acbp = (HBA_ADAPTERCALLBACK_ELEM *) 2176 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM)); 2177 if (acbp == NULL) { 2178 #ifndef WIN32 2179 (void) fprintf(stderr, 2180 "HBA_RegisterForTargetEvents: calloc failed for %lu bytes\n", 2181 (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM))); 2182 #endif 2183 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); 2184 } 2185 *callbackHandle = (HBA_CALLBACKHANDLE) acbp; 2186 acbp->callback = callback; 2187 acbp->userdata = userData; 2188 acbp->lib_info = lib_infop; 2189 2190 status = (registeredfunc)(targetevents_callback, 2191 (void *)acbp, 2192 vendorHandle, 2193 hbaPortWWN, 2194 discoveredPortWWN, 2195 &acbp->vendorcbhandle, 2196 allTargets); 2197 if (status != HBA_STATUS_OK) { 2198 free(acbp); 2199 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2200 } 2201 2202 GRAB_MUTEX(&_hbaapi_TE_mutex); 2203 acbp->next = _hbaapi_targetevents_callback_list; 2204 _hbaapi_targetevents_callback_list = acbp; 2205 RELEASE_MUTEX(&_hbaapi_TE_mutex); 2206 2207 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 2208 } 2209 2210 /* Link Events ********************************************************* */ 2211 static void 2212 linkevents_callback(void *data, 2213 HBA_WWN adapterWWN, 2214 HBA_UINT32 eventType, 2215 void *pRLIRBuffer, 2216 HBA_UINT32 RLIRBufferSize) { 2217 HBA_ADAPTERCALLBACK_ELEM *acbp; 2218 2219 DEBUG(3, "LinkEvent, hbaWWN:%s, eventType:%d", 2220 WWN2STR1(&adapterWWN), eventType, 0); 2221 2222 GRAB_MUTEX(&_hbaapi_LE_mutex); 2223 for (acbp = _hbaapi_linkevents_callback_list; 2224 acbp != NULL; 2225 acbp = acbp->next) { 2226 if (data == (void *)acbp) { 2227 (*acbp->callback)(acbp->userdata, adapterWWN, 2228 eventType, pRLIRBuffer, RLIRBufferSize); 2229 break; 2230 } 2231 } 2232 RELEASE_MUTEX(&_hbaapi_LE_mutex); 2233 } 2234 HBA_STATUS 2235 HBA_RegisterForLinkEvents( 2236 void (*callback) ( 2237 void *data, 2238 HBA_WWN adapterWWN, 2239 HBA_UINT32 eventType, 2240 void *pRLIRBuffer, 2241 HBA_UINT32 RLIRBufferSize), 2242 void *userData, 2243 void *pRLIRBuffer, 2244 HBA_UINT32 RLIRBufferSize, 2245 HBA_HANDLE handle, 2246 HBA_CALLBACKHANDLE *callbackHandle) { 2247 2248 HBA_ADAPTERCALLBACK_ELEM *acbp; 2249 HBARegisterForLinkEventsFunc 2250 registeredfunc; 2251 HBA_STATUS status; 2252 HBA_LIBRARY_INFO *lib_infop; 2253 HBA_HANDLE vendorHandle; 2254 2255 DEBUG(2, "HBA_RegisterForLinkEvents", 0, 0, 0); 2256 2257 CHECKLIBRARY(); 2258 /* we now have the _hbaapi_LL_mutex */ 2259 2260 registeredfunc = FUNCCOMMON(lib_infop, RegisterForLinkEventsHandler); 2261 2262 if (registeredfunc == NULL) { 2263 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 2264 } 2265 2266 /* 2267 * that allocated memory is used both as the handle for the 2268 * caller, and as userdata to the vendor call so that on 2269 * callback the specific registration may be recalled 2270 */ 2271 acbp = (HBA_ADAPTERCALLBACK_ELEM *) 2272 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM)); 2273 if (acbp == NULL) { 2274 #ifndef WIN32 2275 (void) fprintf(stderr, 2276 "HBA_RegisterForLinkEvents: calloc failed for %lu bytes\n", 2277 (unsigned long)(sizeof (HBA_ADAPTERCALLBACK_ELEM))); 2278 #endif 2279 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); 2280 } 2281 *callbackHandle = (HBA_CALLBACKHANDLE) acbp; 2282 acbp->callback = callback; 2283 acbp->userdata = userData; 2284 acbp->lib_info = lib_infop; 2285 2286 status = (registeredfunc)(linkevents_callback, 2287 (void *)acbp, 2288 pRLIRBuffer, 2289 RLIRBufferSize, 2290 vendorHandle, 2291 &acbp->vendorcbhandle); 2292 if (status != HBA_STATUS_OK) { 2293 free(acbp); 2294 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2295 } 2296 2297 GRAB_MUTEX(&_hbaapi_LE_mutex); 2298 acbp->next = _hbaapi_linkevents_callback_list; 2299 _hbaapi_linkevents_callback_list = acbp; 2300 RELEASE_MUTEX(&_hbaapi_LE_mutex); 2301 2302 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 2303 } 2304 2305 /* 2306 * All of the functions below are almost passthru functions to the 2307 * vendor specific function 2308 */ 2309 2310 void 2311 HBA_CloseAdapter(HBA_HANDLE handle) { 2312 HBA_STATUS status; 2313 HBA_LIBRARY_INFO *lib_infop; 2314 HBA_HANDLE vendorHandle; 2315 HBACloseAdapterFunc CloseAdapterFunc; 2316 2317 DEBUG(2, "HBA_CloseAdapter", 0, 0, 0); 2318 2319 status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle); 2320 if (status == HBA_STATUS_OK) { 2321 CloseAdapterFunc = FUNCCOMMON(lib_infop, CloseAdapterHandler); 2322 if (CloseAdapterFunc != NULL) { 2323 ((CloseAdapterFunc)(vendorHandle)); 2324 } 2325 RELEASE_MUTEX(&_hbaapi_LL_mutex); 2326 } 2327 } 2328 2329 HBA_STATUS 2330 HBA_GetAdapterAttributes( 2331 HBA_HANDLE handle, 2332 HBA_ADAPTERATTRIBUTES 2333 *hbaattributes) 2334 { 2335 HBA_STATUS status; 2336 HBA_LIBRARY_INFO *lib_infop; 2337 HBA_HANDLE vendorHandle; 2338 HBAGetAdapterAttributesFunc GetAdapterAttributesFunc; 2339 2340 DEBUG(2, "HBA_GetAdapterAttributes", 0, 0, 0); 2341 2342 CHECKLIBRARY(); 2343 2344 if (lib_infop->version == SMHBA) { 2345 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2346 } 2347 2348 GetAdapterAttributesFunc = 2349 lib_infop->ftable.functionTable.GetAdapterAttributesHandler; 2350 if (GetAdapterAttributesFunc != NULL) { 2351 status = ((GetAdapterAttributesFunc)(vendorHandle, hbaattributes)); 2352 } else { 2353 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2354 } 2355 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2356 } 2357 2358 HBA_STATUS 2359 HBA_GetAdapterPortAttributes( 2360 HBA_HANDLE handle, 2361 HBA_UINT32 portindex, 2362 HBA_PORTATTRIBUTES *portattributes) 2363 { 2364 HBA_STATUS status; 2365 HBA_LIBRARY_INFO *lib_infop; 2366 HBA_HANDLE vendorHandle; 2367 HBAGetAdapterPortAttributesFunc 2368 GetAdapterPortAttributesFunc; 2369 2370 DEBUG(2, "HBA_GetAdapterPortAttributes", 0, 0, 0); 2371 2372 CHECKLIBRARY(); 2373 if (lib_infop->version == SMHBA) { 2374 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2375 } 2376 2377 GetAdapterPortAttributesFunc = 2378 lib_infop->ftable.functionTable.GetAdapterPortAttributesHandler; 2379 if (GetAdapterPortAttributesFunc != NULL) { 2380 status = ((GetAdapterPortAttributesFunc) 2381 (vendorHandle, portindex, portattributes)); 2382 } else { 2383 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2384 } 2385 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2386 } 2387 2388 HBA_STATUS 2389 HBA_GetPortStatistics( 2390 HBA_HANDLE handle, 2391 HBA_UINT32 portindex, 2392 HBA_PORTSTATISTICS *portstatistics) 2393 { 2394 HBA_STATUS status; 2395 HBA_LIBRARY_INFO *lib_infop; 2396 HBA_HANDLE vendorHandle; 2397 HBAGetPortStatisticsFunc 2398 GetPortStatisticsFunc; 2399 2400 DEBUG(2, "HBA_GetPortStatistics", 0, 0, 0); 2401 2402 CHECKLIBRARY(); 2403 if (lib_infop->version == SMHBA) { 2404 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2405 } 2406 2407 GetPortStatisticsFunc = 2408 lib_infop->ftable.functionTable.GetPortStatisticsHandler; 2409 if (GetPortStatisticsFunc != NULL) { 2410 status = ((GetPortStatisticsFunc) 2411 (vendorHandle, portindex, portstatistics)); 2412 } else { 2413 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2414 } 2415 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2416 } 2417 2418 HBA_STATUS 2419 HBA_GetDiscoveredPortAttributes( 2420 HBA_HANDLE handle, 2421 HBA_UINT32 portindex, 2422 HBA_UINT32 discoveredportindex, 2423 HBA_PORTATTRIBUTES *portattributes) 2424 { 2425 HBA_STATUS status; 2426 HBA_LIBRARY_INFO *lib_infop; 2427 HBA_HANDLE vendorHandle; 2428 HBAGetDiscoveredPortAttributesFunc 2429 GetDiscoveredPortAttributesFunc; 2430 2431 DEBUG(2, "HBA_GetDiscoveredPortAttributes", 0, 0, 0); 2432 2433 CHECKLIBRARY(); 2434 if (lib_infop->version == SMHBA) { 2435 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2436 } 2437 2438 GetDiscoveredPortAttributesFunc = 2439 lib_infop->ftable.functionTable.GetDiscoveredPortAttributesHandler; 2440 if (GetDiscoveredPortAttributesFunc != NULL) { 2441 status = ((GetDiscoveredPortAttributesFunc) 2442 (vendorHandle, portindex, discoveredportindex, 2443 portattributes)); 2444 } else { 2445 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2446 } 2447 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2448 } 2449 2450 HBA_STATUS 2451 HBA_GetPortAttributesByWWN( 2452 HBA_HANDLE handle, 2453 HBA_WWN PortWWN, 2454 HBA_PORTATTRIBUTES *portattributes) 2455 { 2456 HBA_STATUS status; 2457 HBA_LIBRARY_INFO *lib_infop; 2458 HBA_HANDLE vendorHandle; 2459 HBAGetPortAttributesByWWNFunc 2460 GetPortAttributesByWWNFunc; 2461 2462 DEBUG(2, "HBA_GetPortAttributesByWWN: %s", WWN2STR1(&PortWWN), 0, 0); 2463 2464 CHECKLIBRARY(); 2465 if (lib_infop->version == SMHBA) { 2466 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2467 } 2468 2469 GetPortAttributesByWWNFunc = 2470 lib_infop->ftable.functionTable.GetPortAttributesByWWNHandler; 2471 if (GetPortAttributesByWWNFunc != NULL) { 2472 status = ((GetPortAttributesByWWNFunc) 2473 (vendorHandle, PortWWN, portattributes)); 2474 } else { 2475 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2476 } 2477 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2478 } 2479 2480 HBA_STATUS 2481 HBA_SendCTPassThru( 2482 HBA_HANDLE handle, 2483 void *pReqBuffer, 2484 HBA_UINT32 ReqBufferSize, 2485 void *pRspBuffer, 2486 HBA_UINT32 RspBufferSize) 2487 { 2488 HBA_STATUS status; 2489 HBA_LIBRARY_INFO *lib_infop; 2490 HBA_HANDLE vendorHandle; 2491 HBASendCTPassThruFunc 2492 SendCTPassThruFunc; 2493 2494 DEBUG(2, "HBA_SendCTPassThru", 0, 0, 0); 2495 2496 CHECKLIBRARY(); 2497 if (lib_infop->version == SMHBA) { 2498 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2499 } 2500 2501 SendCTPassThruFunc = 2502 lib_infop->ftable.functionTable.SendCTPassThruHandler; 2503 if (SendCTPassThruFunc != NULL) { 2504 status = (SendCTPassThruFunc) 2505 (vendorHandle, 2506 pReqBuffer, ReqBufferSize, 2507 pRspBuffer, RspBufferSize); 2508 } else { 2509 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2510 } 2511 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2512 } 2513 2514 HBA_STATUS 2515 HBA_SendCTPassThruV2( 2516 HBA_HANDLE handle, 2517 HBA_WWN hbaPortWWN, 2518 void *pReqBuffer, 2519 HBA_UINT32 ReqBufferSize, 2520 void *pRspBuffer, 2521 HBA_UINT32 *pRspBufferSize) 2522 { 2523 HBA_STATUS status; 2524 HBA_LIBRARY_INFO *lib_infop; 2525 HBA_HANDLE vendorHandle; 2526 HBASendCTPassThruV2Func 2527 registeredfunc; 2528 2529 DEBUG(2, "HBA_SendCTPassThruV2m hbaPortWWN: %s", 2530 WWN2STR1(&hbaPortWWN), 0, 0); 2531 2532 CHECKLIBRARYANDVERSION(HBAAPIV2); 2533 registeredfunc = FUNCCOMMON(lib_infop, SendCTPassThruV2Handler); 2534 if (registeredfunc != NULL) { 2535 status = (registeredfunc) 2536 (vendorHandle, hbaPortWWN, 2537 pReqBuffer, ReqBufferSize, 2538 pRspBuffer, pRspBufferSize); 2539 } else { 2540 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2541 } 2542 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2543 } 2544 2545 HBA_STATUS 2546 HBA_GetEventBuffer( 2547 HBA_HANDLE handle, 2548 PHBA_EVENTINFO EventBuffer, 2549 HBA_UINT32 *EventBufferCount) 2550 { 2551 HBA_STATUS status; 2552 HBA_LIBRARY_INFO *lib_infop; 2553 HBA_HANDLE vendorHandle; 2554 HBAGetEventBufferFunc 2555 GetEventBufferFunc; 2556 2557 DEBUG(2, "HBA_GetEventBuffer", 0, 0, 0); 2558 2559 CHECKLIBRARY(); 2560 if (lib_infop->version == SMHBA) { 2561 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2562 } 2563 2564 GetEventBufferFunc = 2565 lib_infop->ftable.functionTable.GetEventBufferHandler; 2566 if (GetEventBufferFunc != NULL) { 2567 status = (GetEventBufferFunc) 2568 (vendorHandle, EventBuffer, EventBufferCount); 2569 } else { 2570 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2571 } 2572 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2573 } 2574 2575 HBA_STATUS 2576 HBA_SetRNIDMgmtInfo(HBA_HANDLE handle, HBA_MGMTINFO Info) { 2577 HBA_STATUS status; 2578 HBA_LIBRARY_INFO *lib_infop; 2579 HBA_HANDLE vendorHandle; 2580 HBASetRNIDMgmtInfoFunc 2581 SetRNIDMgmtInfoFunc; 2582 2583 DEBUG(2, "HBA_SetRNIDMgmtInfo", 0, 0, 0); 2584 2585 CHECKLIBRARY(); 2586 SetRNIDMgmtInfoFunc = FUNCCOMMON(lib_infop, SetRNIDMgmtInfoHandler); 2587 if (SetRNIDMgmtInfoFunc != NULL) { 2588 status = (SetRNIDMgmtInfoFunc)(vendorHandle, Info); 2589 } else { 2590 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2591 } 2592 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2593 } 2594 2595 HBA_STATUS 2596 HBA_GetRNIDMgmtInfo(HBA_HANDLE handle, HBA_MGMTINFO *pInfo) { 2597 HBA_STATUS status; 2598 HBA_LIBRARY_INFO *lib_infop; 2599 HBA_HANDLE vendorHandle; 2600 HBAGetRNIDMgmtInfoFunc 2601 GetRNIDMgmtInfoFunc; 2602 2603 DEBUG(2, "HBA_GetRNIDMgmtInfo", 0, 0, 0); 2604 2605 CHECKLIBRARY(); 2606 GetRNIDMgmtInfoFunc = FUNCCOMMON(lib_infop, GetRNIDMgmtInfoHandler); 2607 if (GetRNIDMgmtInfoFunc != NULL) { 2608 status = (GetRNIDMgmtInfoFunc)(vendorHandle, pInfo); 2609 } else { 2610 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2611 } 2612 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2613 } 2614 2615 HBA_STATUS 2616 HBA_SendRNID( 2617 HBA_HANDLE handle, 2618 HBA_WWN wwn, 2619 HBA_WWNTYPE wwntype, 2620 void *pRspBuffer, 2621 HBA_UINT32 *pRspBufferSize) 2622 { 2623 HBA_STATUS status; 2624 HBA_LIBRARY_INFO *lib_infop; 2625 HBA_HANDLE vendorHandle; 2626 HBASendRNIDFunc SendRNIDFunc; 2627 2628 DEBUG(2, "HBA_SendRNID for wwn: %s", WWN2STR1(&wwn), 0, 0); 2629 2630 CHECKLIBRARY(); 2631 if (lib_infop->version == SMHBA) { 2632 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2633 } 2634 2635 SendRNIDFunc = lib_infop->ftable.functionTable.SendRNIDHandler; 2636 if (SendRNIDFunc != NULL) { 2637 status = ((SendRNIDFunc)(vendorHandle, wwn, wwntype, 2638 pRspBuffer, pRspBufferSize)); 2639 } else { 2640 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2641 } 2642 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2643 } 2644 2645 HBA_STATUS 2646 HBA_SendRNIDV2( 2647 HBA_HANDLE handle, 2648 HBA_WWN hbaPortWWN, 2649 HBA_WWN destWWN, 2650 HBA_UINT32 destFCID, 2651 HBA_UINT32 NodeIdDataFormat, 2652 void *pRspBuffer, 2653 HBA_UINT32 *pRspBufferSize) 2654 { 2655 HBA_STATUS status; 2656 HBA_LIBRARY_INFO *lib_infop; 2657 HBA_HANDLE vendorHandle; 2658 HBASendRNIDV2Func registeredfunc; 2659 2660 DEBUG(2, "HBA_SendRNIDV2, hbaPortWWN: %s", WWN2STR1(&hbaPortWWN), 0, 0); 2661 2662 CHECKLIBRARY(); 2663 registeredfunc = FUNCCOMMON(lib_infop, SendRNIDV2Handler); 2664 if (registeredfunc != NULL) { 2665 status = (registeredfunc) 2666 (vendorHandle, hbaPortWWN, destWWN, destFCID, NodeIdDataFormat, 2667 pRspBuffer, pRspBufferSize); 2668 } else { 2669 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2670 } 2671 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2672 } 2673 2674 void 2675 HBA_RefreshInformation(HBA_HANDLE handle) { 2676 HBA_STATUS status; 2677 HBA_LIBRARY_INFO *lib_infop; 2678 HBA_HANDLE vendorHandle; 2679 HBARefreshInformationFunc 2680 RefreshInformationFunc; 2681 2682 DEBUG(2, "HBA_RefreshInformation", 0, 0, 0); 2683 2684 status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle); 2685 if (status == HBA_STATUS_OK) { 2686 RefreshInformationFunc = 2687 FUNCCOMMON(lib_infop, RefreshInformationHandler); 2688 if (RefreshInformationFunc != NULL) { 2689 ((RefreshInformationFunc)(vendorHandle)); 2690 } 2691 RELEASE_MUTEX(&_hbaapi_LL_mutex); 2692 } 2693 } 2694 2695 void 2696 HBA_ResetStatistics(HBA_HANDLE handle, HBA_UINT32 portindex) { 2697 HBA_STATUS status; 2698 HBA_LIBRARY_INFO *lib_infop; 2699 HBA_HANDLE vendorHandle; 2700 HBAResetStatisticsFunc 2701 ResetStatisticsFunc; 2702 2703 DEBUG(2, "HBA_ResetStatistics", 0, 0, 0); 2704 2705 status = HBA_CheckLibrary(handle, &lib_infop, &vendorHandle); 2706 if (status == HBA_STATUS_OK) { 2707 if (lib_infop->version == SMHBA) { 2708 RELEASE_MUTEX(&_hbaapi_LL_mutex); 2709 } 2710 2711 ResetStatisticsFunc = 2712 lib_infop->ftable.functionTable.ResetStatisticsHandler; 2713 if (ResetStatisticsFunc != NULL) { 2714 ((ResetStatisticsFunc)(vendorHandle, portindex)); 2715 } 2716 RELEASE_MUTEX(&_hbaapi_LL_mutex); 2717 } 2718 } 2719 2720 HBA_STATUS 2721 HBA_GetFcpTargetMapping(HBA_HANDLE handle, PHBA_FCPTARGETMAPPING mapping) { 2722 HBA_STATUS status; 2723 HBA_LIBRARY_INFO *lib_infop; 2724 HBA_HANDLE vendorHandle; 2725 HBAGetFcpTargetMappingFunc GetFcpTargetMappingFunc; 2726 2727 DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0); 2728 2729 CHECKLIBRARY(); 2730 if (lib_infop->version == SMHBA) { 2731 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2732 } 2733 2734 GetFcpTargetMappingFunc = 2735 lib_infop->ftable.functionTable.GetFcpTargetMappingHandler; 2736 if (GetFcpTargetMappingFunc != NULL) { 2737 status = ((GetFcpTargetMappingFunc)(vendorHandle, mapping)); 2738 } else { 2739 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2740 } 2741 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2742 } 2743 2744 HBA_STATUS 2745 HBA_GetFcpTargetMappingV2( 2746 HBA_HANDLE handle, 2747 HBA_WWN hbaPortWWN, 2748 HBA_FCPTARGETMAPPINGV2 *pmapping) 2749 { 2750 HBA_STATUS status; 2751 HBA_LIBRARY_INFO *lib_infop; 2752 HBA_HANDLE vendorHandle; 2753 HBAGetFcpTargetMappingV2Func 2754 registeredfunc; 2755 2756 DEBUG(2, "HBA_GetFcpTargetMapping", 0, 0, 0); 2757 2758 CHECKLIBRARYANDVERSION(HBAAPIV2); 2759 2760 registeredfunc = 2761 lib_infop->ftable.functionTable.GetFcpTargetMappingV2Handler; 2762 if (registeredfunc != NULL) { 2763 status = ((registeredfunc)(vendorHandle, hbaPortWWN, pmapping)); 2764 } else { 2765 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2766 } 2767 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2768 } 2769 2770 HBA_STATUS 2771 HBA_GetFcpPersistentBinding(HBA_HANDLE handle, PHBA_FCPBINDING binding) { 2772 HBA_STATUS status; 2773 HBA_LIBRARY_INFO *lib_infop; 2774 HBA_HANDLE vendorHandle; 2775 HBAGetFcpPersistentBindingFunc 2776 GetFcpPersistentBindingFunc; 2777 2778 DEBUG(2, "HBA_GetFcpPersistentBinding", 0, 0, 0); 2779 2780 CHECKLIBRARY(); 2781 if (lib_infop->version == SMHBA) { 2782 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2783 } 2784 2785 GetFcpPersistentBindingFunc = 2786 lib_infop->ftable.functionTable.GetFcpPersistentBindingHandler; 2787 if (GetFcpPersistentBindingFunc != NULL) { 2788 status = ((GetFcpPersistentBindingFunc)(vendorHandle, binding)); 2789 } else { 2790 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2791 } 2792 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2793 } 2794 2795 HBA_STATUS 2796 HBA_ScsiInquiryV2( 2797 HBA_HANDLE handle, 2798 HBA_WWN hbaPortWWN, 2799 HBA_WWN discoveredPortWWN, 2800 HBA_UINT64 fcLUN, 2801 HBA_UINT8 CDB_Byte1, 2802 HBA_UINT8 CDB_Byte2, 2803 void *pRspBuffer, 2804 HBA_UINT32 *pRspBufferSize, 2805 HBA_UINT8 *pScsiStatus, 2806 void *pSenseBuffer, 2807 HBA_UINT32 *pSenseBufferSize) 2808 { 2809 HBA_STATUS status; 2810 HBA_LIBRARY_INFO *lib_infop; 2811 HBA_HANDLE vendorHandle; 2812 HBAScsiInquiryV2Func ScsiInquiryV2Func; 2813 2814 DEBUG(2, "HBA_ScsiInquiryV2 to discoveredPortWWN: %s", 2815 WWN2STR1(&discoveredPortWWN), 0, 0); 2816 2817 CHECKLIBRARYANDVERSION(HBAAPIV2); 2818 2819 ScsiInquiryV2Func = 2820 lib_infop->ftable.functionTable.ScsiInquiryV2Handler; 2821 if (ScsiInquiryV2Func != NULL) { 2822 status = ((ScsiInquiryV2Func)( 2823 vendorHandle, hbaPortWWN, discoveredPortWWN, fcLUN, CDB_Byte1, 2824 CDB_Byte2, pRspBuffer, pRspBufferSize, pScsiStatus, 2825 pSenseBuffer, pSenseBufferSize)); 2826 } else { 2827 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2828 } 2829 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2830 } 2831 2832 HBA_STATUS 2833 HBA_SendScsiInquiry( 2834 HBA_HANDLE handle, 2835 HBA_WWN PortWWN, 2836 HBA_UINT64 fcLUN, 2837 HBA_UINT8 EVPD, 2838 HBA_UINT32 PageCode, 2839 void *pRspBuffer, 2840 HBA_UINT32 RspBufferSize, 2841 void *pSenseBuffer, 2842 HBA_UINT32 SenseBufferSize) 2843 { 2844 HBA_STATUS status; 2845 HBA_LIBRARY_INFO *lib_infop; 2846 HBA_HANDLE vendorHandle; 2847 HBASendScsiInquiryFunc SendScsiInquiryFunc; 2848 2849 DEBUG(2, "HBA_SendScsiInquiry to PortWWN: %s", 2850 WWN2STR1(&PortWWN), 0, 0); 2851 2852 CHECKLIBRARY(); 2853 if (lib_infop->version == SMHBA) { 2854 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2855 } 2856 2857 SendScsiInquiryFunc = 2858 lib_infop->ftable.functionTable.ScsiInquiryHandler; 2859 if (SendScsiInquiryFunc != NULL) { 2860 status = ((SendScsiInquiryFunc)( 2861 vendorHandle, PortWWN, fcLUN, EVPD, PageCode, pRspBuffer, 2862 RspBufferSize, pSenseBuffer, SenseBufferSize)); 2863 } else { 2864 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2865 } 2866 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2867 } 2868 2869 HBA_STATUS 2870 HBA_ScsiReportLUNsV2( 2871 HBA_HANDLE handle, 2872 HBA_WWN hbaPortWWN, 2873 HBA_WWN discoveredPortWWN, 2874 void *pRespBuffer, 2875 HBA_UINT32 *pRespBufferSize, 2876 HBA_UINT8 *pScsiStatus, 2877 void *pSenseBuffer, 2878 HBA_UINT32 *pSenseBufferSize) 2879 { 2880 HBA_STATUS status; 2881 HBA_LIBRARY_INFO *lib_infop; 2882 HBA_HANDLE vendorHandle; 2883 HBAScsiReportLUNsV2Func ScsiReportLUNsV2Func; 2884 2885 DEBUG(2, "HBA_ScsiReportLUNsV2 to discoveredPortWWN: %s", 2886 WWN2STR1(&discoveredPortWWN), 0, 0); 2887 2888 CHECKLIBRARYANDVERSION(HBAAPIV2); 2889 2890 ScsiReportLUNsV2Func = 2891 lib_infop->ftable.functionTable.ScsiReportLUNsV2Handler; 2892 if (ScsiReportLUNsV2Func != NULL) { 2893 status = ((ScsiReportLUNsV2Func)( 2894 vendorHandle, hbaPortWWN, discoveredPortWWN, 2895 pRespBuffer, pRespBufferSize, 2896 pScsiStatus, 2897 pSenseBuffer, pSenseBufferSize)); 2898 } else { 2899 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2900 } 2901 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2902 } 2903 2904 HBA_STATUS 2905 HBA_SendReportLUNs( 2906 HBA_HANDLE handle, 2907 HBA_WWN portWWN, 2908 void *pRspBuffer, 2909 HBA_UINT32 RspBufferSize, 2910 void *pSenseBuffer, 2911 HBA_UINT32 SenseBufferSize) 2912 { 2913 HBA_STATUS status; 2914 HBA_LIBRARY_INFO *lib_infop; 2915 HBA_HANDLE vendorHandle; 2916 HBASendReportLUNsFunc SendReportLUNsFunc; 2917 2918 DEBUG(2, "HBA_SendReportLUNs to PortWWN: %s", WWN2STR1(&portWWN), 0, 0); 2919 2920 CHECKLIBRARY(); 2921 if (lib_infop->version == SMHBA) { 2922 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2923 } 2924 2925 SendReportLUNsFunc = lib_infop->ftable.functionTable.ReportLUNsHandler; 2926 if (SendReportLUNsFunc != NULL) { 2927 status = ((SendReportLUNsFunc)( 2928 vendorHandle, portWWN, pRspBuffer, 2929 RspBufferSize, pSenseBuffer, SenseBufferSize)); 2930 } else { 2931 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2932 } 2933 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2934 } 2935 2936 HBA_STATUS 2937 HBA_ScsiReadCapacityV2( 2938 HBA_HANDLE handle, 2939 HBA_WWN hbaPortWWN, 2940 HBA_WWN discoveredPortWWN, 2941 HBA_UINT64 fcLUN, 2942 void *pRspBuffer, 2943 HBA_UINT32 *pRspBufferSize, 2944 HBA_UINT8 *pScsiStatus, 2945 void *pSenseBuffer, 2946 HBA_UINT32 *SenseBufferSize) 2947 { 2948 HBA_STATUS status; 2949 HBA_LIBRARY_INFO *lib_infop; 2950 HBA_HANDLE vendorHandle; 2951 HBAScsiReadCapacityV2Func ScsiReadCapacityV2Func; 2952 2953 DEBUG(2, "HBA_ScsiReadCapacityV2 to discoveredPortWWN: %s", 2954 WWN2STR1(&discoveredPortWWN), 0, 0); 2955 2956 CHECKLIBRARYANDVERSION(HBAAPIV2); 2957 2958 ScsiReadCapacityV2Func = 2959 lib_infop->ftable.functionTable.ScsiReadCapacityV2Handler; 2960 if (ScsiReadCapacityV2Func != NULL) { 2961 status = ((ScsiReadCapacityV2Func)( 2962 vendorHandle, hbaPortWWN, discoveredPortWWN, fcLUN, 2963 pRspBuffer, pRspBufferSize, 2964 pScsiStatus, 2965 pSenseBuffer, SenseBufferSize)); 2966 } else { 2967 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 2968 } 2969 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 2970 } 2971 2972 HBA_STATUS 2973 HBA_SendReadCapacity( 2974 HBA_HANDLE handle, 2975 HBA_WWN portWWN, 2976 HBA_UINT64 fcLUN, 2977 void *pRspBuffer, 2978 HBA_UINT32 RspBufferSize, 2979 void *pSenseBuffer, 2980 HBA_UINT32 SenseBufferSize) 2981 { 2982 HBA_STATUS status; 2983 HBA_LIBRARY_INFO *lib_infop; 2984 HBA_HANDLE vendorHandle; 2985 HBASendReadCapacityFunc SendReadCapacityFunc; 2986 2987 DEBUG(2, "HBA_SendReadCapacity to portWWN: %s", 2988 WWN2STR1(&portWWN), 0, 0); 2989 2990 CHECKLIBRARY(); 2991 if (lib_infop->version == SMHBA) { 2992 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INCOMPATIBLE); 2993 } 2994 2995 SendReadCapacityFunc = 2996 lib_infop->ftable.functionTable.ReadCapacityHandler; 2997 if (SendReadCapacityFunc != NULL) { 2998 status = ((SendReadCapacityFunc) 2999 (vendorHandle, portWWN, fcLUN, pRspBuffer, 3000 RspBufferSize, pSenseBuffer, SenseBufferSize)); 3001 } else { 3002 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3003 } 3004 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3005 } 3006 3007 HBA_STATUS 3008 HBA_SendRPL( 3009 HBA_HANDLE handle, 3010 HBA_WWN hbaPortWWN, 3011 HBA_WWN agent_wwn, 3012 HBA_UINT32 agent_domain, 3013 HBA_UINT32 portindex, 3014 void *pRspBuffer, 3015 HBA_UINT32 *pRspBufferSize) 3016 { 3017 HBA_STATUS status; 3018 HBA_LIBRARY_INFO *lib_infop; 3019 HBA_HANDLE vendorHandle; 3020 HBASendRPLFunc registeredfunc; 3021 3022 DEBUG(2, "HBA_SendRPL to agent_wwn: %s:%d", 3023 WWN2STR1(&agent_wwn), agent_domain, 0); 3024 3025 CHECKLIBRARY(); 3026 registeredfunc = FUNCCOMMON(lib_infop, SendRPLHandler); 3027 if (registeredfunc != NULL) { 3028 status = (registeredfunc)( 3029 vendorHandle, hbaPortWWN, agent_wwn, agent_domain, portindex, 3030 pRspBuffer, pRspBufferSize); 3031 } else { 3032 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3033 } 3034 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3035 } 3036 3037 HBA_STATUS 3038 HBA_SendRPS( 3039 HBA_HANDLE handle, 3040 HBA_WWN hbaPortWWN, 3041 HBA_WWN agent_wwn, 3042 HBA_UINT32 agent_domain, 3043 HBA_WWN object_wwn, 3044 HBA_UINT32 object_port_number, 3045 void *pRspBuffer, 3046 HBA_UINT32 *pRspBufferSize) 3047 { 3048 HBA_STATUS status; 3049 HBA_LIBRARY_INFO *lib_infop; 3050 HBA_HANDLE vendorHandle; 3051 HBASendRPSFunc registeredfunc; 3052 3053 DEBUG(2, "HBA_SendRPS to agent_wwn: %s:%d", 3054 WWN2STR1(&agent_wwn), agent_domain, 0); 3055 3056 CHECKLIBRARY(); 3057 registeredfunc = FUNCCOMMON(lib_infop, SendRPSHandler); 3058 if (registeredfunc != NULL) { 3059 status = (registeredfunc)( 3060 vendorHandle, hbaPortWWN, agent_wwn, agent_domain, 3061 object_wwn, object_port_number, 3062 pRspBuffer, pRspBufferSize); 3063 } else { 3064 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3065 } 3066 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3067 } 3068 3069 HBA_STATUS 3070 HBA_SendSRL( 3071 HBA_HANDLE handle, 3072 HBA_WWN hbaPortWWN, 3073 HBA_WWN wwn, 3074 HBA_UINT32 domain, 3075 void *pRspBuffer, 3076 HBA_UINT32 *pRspBufferSize) 3077 { 3078 HBA_STATUS status; 3079 HBA_LIBRARY_INFO *lib_infop; 3080 HBA_HANDLE vendorHandle; 3081 HBASendSRLFunc registeredfunc; 3082 3083 DEBUG(2, "HBA_SendSRL to wwn:%s domain:%d", WWN2STR1(&wwn), domain, 0); 3084 3085 CHECKLIBRARY(); 3086 registeredfunc = FUNCCOMMON(lib_infop, SendSRLHandler); 3087 if (registeredfunc != NULL) { 3088 status = (registeredfunc)( 3089 vendorHandle, hbaPortWWN, wwn, domain, 3090 pRspBuffer, pRspBufferSize); 3091 } else { 3092 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3093 } 3094 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3095 } 3096 HBA_STATUS 3097 HBA_SendRLS( 3098 HBA_HANDLE handle, 3099 HBA_WWN hbaPortWWN, 3100 HBA_WWN destWWN, 3101 void *pRspBuffer, 3102 HBA_UINT32 *pRspBufferSize) 3103 { 3104 HBA_STATUS status; 3105 HBA_LIBRARY_INFO *lib_infop; 3106 HBA_HANDLE vendorHandle; 3107 HBASendRLSFunc registeredfunc; 3108 3109 DEBUG(2, "HBA_SendRLS dest_wwn: %s", 3110 WWN2STR1(&destWWN), 0, 0); 3111 3112 CHECKLIBRARY(); 3113 registeredfunc = FUNCCOMMON(lib_infop, SendRLSHandler); 3114 if (registeredfunc != NULL) { 3115 status = (registeredfunc)( 3116 vendorHandle, hbaPortWWN, destWWN, 3117 pRspBuffer, pRspBufferSize); 3118 } else { 3119 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3120 } 3121 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3122 } 3123 3124 HBA_STATUS 3125 HBA_SendLIRR( 3126 HBA_HANDLE handle, 3127 HBA_WWN sourceWWN, 3128 HBA_WWN destWWN, 3129 HBA_UINT8 function, 3130 HBA_UINT8 type, 3131 void *pRspBuffer, 3132 HBA_UINT32 *pRspBufferSize) 3133 { 3134 HBA_STATUS status; 3135 HBA_LIBRARY_INFO *lib_infop; 3136 HBA_HANDLE vendorHandle; 3137 HBASendLIRRFunc registeredfunc; 3138 3139 DEBUG(2, "HBA_SendLIRR destWWN:%s", WWN2STR1(&destWWN), 0, 0); 3140 3141 CHECKLIBRARY(); 3142 registeredfunc = FUNCCOMMON(lib_infop, SendLIRRHandler); 3143 if (registeredfunc != NULL) { 3144 status = (registeredfunc)( 3145 vendorHandle, sourceWWN, destWWN, function, type, 3146 pRspBuffer, pRspBufferSize); 3147 } else { 3148 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3149 } 3150 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3151 } 3152 3153 HBA_STATUS 3154 HBA_GetBindingCapability( 3155 HBA_HANDLE handle, 3156 HBA_WWN hbaPortWWN, 3157 HBA_BIND_CAPABILITY *pcapability) 3158 { 3159 HBA_STATUS status; 3160 HBA_LIBRARY_INFO *lib_infop; 3161 HBA_HANDLE vendorHandle; 3162 HBAGetBindingCapabilityFunc 3163 registeredfunc; 3164 3165 DEBUG(2, "HBA_GetBindingCapability", 0, 0, 0); 3166 3167 CHECKLIBRARYANDVERSION(HBAAPIV2); 3168 3169 registeredfunc = 3170 lib_infop->ftable.functionTable.GetBindingCapabilityHandler; 3171 if (registeredfunc != NULL) { 3172 status = (registeredfunc)(vendorHandle, hbaPortWWN, pcapability); 3173 } else { 3174 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3175 } 3176 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3177 } 3178 3179 HBA_STATUS 3180 HBA_GetBindingSupport( 3181 HBA_HANDLE handle, 3182 HBA_WWN hbaPortWWN, 3183 HBA_BIND_CAPABILITY *pcapability) 3184 { 3185 HBA_STATUS status; 3186 HBA_LIBRARY_INFO *lib_infop; 3187 HBA_HANDLE vendorHandle; 3188 HBAGetBindingSupportFunc 3189 registeredfunc; 3190 3191 DEBUG(2, "HBA_GetBindingSupport", 0, 0, 0); 3192 3193 CHECKLIBRARYANDVERSION(HBAAPIV2); 3194 3195 registeredfunc = 3196 lib_infop->ftable.functionTable.GetBindingSupportHandler; 3197 if (registeredfunc != NULL) { 3198 status = (registeredfunc)(vendorHandle, hbaPortWWN, pcapability); 3199 } else { 3200 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3201 } 3202 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3203 } 3204 3205 HBA_STATUS 3206 HBA_SetBindingSupport( 3207 HBA_HANDLE handle, 3208 HBA_WWN hbaPortWWN, 3209 HBA_BIND_CAPABILITY capability) 3210 { 3211 HBA_STATUS status; 3212 HBA_LIBRARY_INFO *lib_infop; 3213 HBA_HANDLE vendorHandle; 3214 HBASetBindingSupportFunc 3215 registeredfunc; 3216 3217 DEBUG(2, "HBA_SetBindingSupport", 0, 0, 0); 3218 3219 CHECKLIBRARYANDVERSION(HBAAPIV2); 3220 3221 registeredfunc = 3222 lib_infop->ftable.functionTable.SetBindingSupportHandler; 3223 if (registeredfunc != NULL) { 3224 status = (registeredfunc)(vendorHandle, hbaPortWWN, capability); 3225 } else { 3226 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3227 } 3228 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3229 } 3230 3231 HBA_STATUS 3232 HBA_SetPersistentBindingV2( 3233 HBA_HANDLE handle, 3234 HBA_WWN hbaPortWWN, 3235 const HBA_FCPBINDING2 *pbinding) 3236 { 3237 HBA_STATUS status; 3238 HBA_LIBRARY_INFO *lib_infop; 3239 HBA_HANDLE vendorHandle; 3240 HBASetPersistentBindingV2Func 3241 registeredfunc; 3242 3243 DEBUG(2, "HBA_SetPersistentBindingV2 port: %s", 3244 WWN2STR1(&hbaPortWWN), 0, 0); 3245 3246 CHECKLIBRARYANDVERSION(HBAAPIV2); 3247 3248 registeredfunc = 3249 lib_infop->ftable.functionTable.SetPersistentBindingV2Handler; 3250 if (registeredfunc != NULL) { 3251 status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding); 3252 } else { 3253 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3254 } 3255 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3256 } 3257 3258 HBA_STATUS 3259 HBA_GetPersistentBindingV2( 3260 HBA_HANDLE handle, 3261 HBA_WWN hbaPortWWN, 3262 HBA_FCPBINDING2 *pbinding) 3263 { 3264 HBA_STATUS status; 3265 HBA_LIBRARY_INFO *lib_infop; 3266 HBA_HANDLE vendorHandle; 3267 HBAGetPersistentBindingV2Func 3268 registeredfunc; 3269 3270 DEBUG(2, "HBA_GetPersistentBindingV2 port: %s", 3271 WWN2STR1(&hbaPortWWN), 0, 0); 3272 3273 CHECKLIBRARYANDVERSION(HBAAPIV2); 3274 3275 registeredfunc = 3276 lib_infop->ftable.functionTable.GetPersistentBindingV2Handler; 3277 if (registeredfunc != NULL) { 3278 status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding); 3279 } else { 3280 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3281 } 3282 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3283 } 3284 3285 HBA_STATUS 3286 HBA_RemovePersistentBinding( 3287 HBA_HANDLE handle, 3288 HBA_WWN hbaPortWWN, 3289 const HBA_FCPBINDING2 3290 *pbinding) 3291 { 3292 HBA_STATUS status; 3293 HBA_LIBRARY_INFO *lib_infop; 3294 HBA_HANDLE vendorHandle; 3295 HBARemovePersistentBindingFunc 3296 registeredfunc; 3297 3298 DEBUG(2, "HBA_RemovePersistentBinding", 0, 0, 0); 3299 3300 CHECKLIBRARYANDVERSION(HBAAPIV2); 3301 3302 registeredfunc = 3303 lib_infop->ftable.functionTable.RemovePersistentBindingHandler; 3304 if (registeredfunc != NULL) { 3305 status = (registeredfunc)(vendorHandle, hbaPortWWN, pbinding); 3306 } else { 3307 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3308 } 3309 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3310 } 3311 3312 HBA_STATUS 3313 HBA_RemoveAllPersistentBindings( 3314 HBA_HANDLE handle, 3315 HBA_WWN hbaPortWWN) 3316 { 3317 HBA_STATUS status; 3318 HBA_LIBRARY_INFO *lib_infop; 3319 HBA_HANDLE vendorHandle; 3320 HBARemoveAllPersistentBindingsFunc 3321 registeredfunc; 3322 3323 DEBUG(2, "HBA_RemoveAllPersistentBindings", 0, 0, 0); 3324 3325 CHECKLIBRARYANDVERSION(HBAAPIV2); 3326 3327 registeredfunc = 3328 lib_infop->ftable.functionTable.RemoveAllPersistentBindingsHandler; 3329 if (registeredfunc != NULL) { 3330 status = (registeredfunc)(vendorHandle, hbaPortWWN); 3331 } else { 3332 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3333 } 3334 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3335 } 3336 3337 HBA_STATUS 3338 HBA_GetFC4Statistics( 3339 HBA_HANDLE handle, 3340 HBA_WWN portWWN, 3341 HBA_UINT8 FC4type, 3342 HBA_FC4STATISTICS *pstatistics) 3343 { 3344 HBA_STATUS status; 3345 HBA_LIBRARY_INFO *lib_infop; 3346 HBA_HANDLE vendorHandle; 3347 HBAGetFC4StatisticsFunc 3348 registeredfunc; 3349 3350 DEBUG(2, "HBA_GetFC4Statistics port: %s", WWN2STR1(&portWWN), 0, 0); 3351 3352 CHECKLIBRARYANDVERSION(HBAAPIV2); 3353 3354 registeredfunc = 3355 lib_infop->ftable.functionTable.GetFC4StatisticsHandler; 3356 if (registeredfunc != NULL) { 3357 status = (registeredfunc) 3358 (vendorHandle, portWWN, FC4type, pstatistics); 3359 } else { 3360 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3361 } 3362 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3363 } 3364 3365 HBA_STATUS 3366 HBA_GetFCPStatistics( 3367 HBA_HANDLE handle, 3368 const HBA_SCSIID *lunit, 3369 HBA_FC4STATISTICS *pstatistics) 3370 { 3371 HBA_STATUS status; 3372 HBA_LIBRARY_INFO *lib_infop; 3373 HBA_HANDLE vendorHandle; 3374 HBAGetFCPStatisticsFunc 3375 registeredfunc; 3376 3377 DEBUG(2, "HBA_GetFCPStatistics", 0, 0, 0); 3378 3379 CHECKLIBRARYANDVERSION(HBAAPIV2); 3380 3381 registeredfunc = 3382 lib_infop->ftable.functionTable.GetFCPStatisticsHandler; 3383 if (registeredfunc != NULL) { 3384 status = (registeredfunc)(vendorHandle, lunit, pstatistics); 3385 } else { 3386 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3387 } 3388 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3389 } 3390 3391 HBA_UINT32 3392 HBA_GetVendorLibraryAttributes( 3393 HBA_UINT32 adapter_index, 3394 HBA_LIBRARYATTRIBUTES *attributes) 3395 { 3396 HBA_ADAPTER_INFO *adapt_infop; 3397 HBAGetVendorLibraryAttributesFunc 3398 registeredfunc; 3399 HBA_UINT32 ret = 0; 3400 3401 DEBUG(2, "HBA_GetVendorLibraryAttributes adapterindex:%d", 3402 adapter_index, 0, 0); 3403 if (_hbaapi_librarylist == NULL) { 3404 DEBUG(1, "HBAAPI not loaded yet.", 0, 0, 0); 3405 return (0); 3406 } 3407 3408 if (attributes == NULL) { 3409 DEBUG(1, 3410 "HBA_GetVendorLibraryAttributes: NULL pointer attributes", 3411 0, 0, 0); 3412 return (HBA_STATUS_ERROR_ARG); 3413 } 3414 3415 (void) memset(attributes, 0, sizeof (HBA_LIBRARYATTRIBUTES)); 3416 3417 GRAB_MUTEX(&_hbaapi_LL_mutex); 3418 GRAB_MUTEX(&_hbaapi_AL_mutex); 3419 for (adapt_infop = _hbaapi_adapterlist; 3420 adapt_infop != NULL; 3421 adapt_infop = adapt_infop->next) { 3422 3423 if (adapt_infop->index == adapter_index) { 3424 3425 if (adapt_infop->library->version == SMHBA) { 3426 RELEASE_MUTEX(&_hbaapi_AL_mutex); 3427 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, 3428 HBA_STATUS_ERROR_INCOMPATIBLE); 3429 } 3430 3431 registeredfunc = adapt_infop->library-> 3432 ftable.functionTable.GetVendorLibraryAttributesHandler; 3433 if (registeredfunc != NULL) { 3434 ret = (registeredfunc)(attributes); 3435 } else { 3436 /* Version 1 libary? */ 3437 HBAGetVersionFunc GetVersionFunc; 3438 GetVersionFunc = adapt_infop->library-> 3439 ftable.functionTable.GetVersionHandler; 3440 if (GetVersionFunc != NULL) { 3441 ret = ((GetVersionFunc)()); 3442 } 3443 #ifdef NOTDEF 3444 else { 3445 /* This should not happen, dont think its going to */ 3446 } 3447 #endif 3448 } 3449 if (attributes->LibPath[0] == '\0') { 3450 if (strlen(adapt_infop->library->LibraryPath) < 256) { 3451 (void) strcpy(attributes->LibPath, 3452 adapt_infop->library->LibraryPath); 3453 } 3454 } 3455 break; 3456 } 3457 } 3458 RELEASE_MUTEX(&_hbaapi_AL_mutex); 3459 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, ret); 3460 } 3461 3462 3463 /* 3464 * This function returns SM-HBA version that the warpper library implemented. 3465 */ 3466 HBA_UINT32 3467 SMHBA_GetVersion() { 3468 DEBUG(2, "SMHBA_GetVersion", 0, 0, 0); 3469 return (SMHBA_LIBVERSION); 3470 } 3471 3472 /* 3473 * This function returns the attributes for the warpper library. 3474 */ 3475 HBA_UINT32 3476 SMHBA_GetWrapperLibraryAttributes( 3477 SMHBA_LIBRARYATTRIBUTES *attributes) 3478 { 3479 3480 struct timeval tv; 3481 struct tm tp; 3482 3483 DEBUG(2, "SMHBA_GetWrapperLibraryAttributes", 0, 0, 0); 3484 3485 if (attributes == NULL) { 3486 DEBUG(1, "SMHBA_GetWrapperLibraryAttributes: " 3487 "NULL pointer attributes", 3488 0, 0, 0); 3489 return (HBA_STATUS_ERROR_ARG); 3490 } 3491 3492 (void) memset(attributes, 0, sizeof (SMHBA_LIBRARYATTRIBUTES)); 3493 3494 #if defined(SOLARIS) 3495 if ((handle = dlopen("libSMHBAAPI.so", RTLD_NOW)) != NULL) { 3496 if (dlinfo(handle, RTLD_DI_LINKMAP, &map) >= 0) { 3497 for (mp = map; mp != NULL; mp = mp->l_next) { 3498 if (strlen(map->l_name) < 256) { 3499 (void) strcpy(attributes->LibPath, map->l_name); 3500 } 3501 } 3502 } 3503 } 3504 3505 #endif 3506 3507 #if defined(VENDOR) 3508 (void) strcpy(attributes->VName, VENDOR); 3509 #else 3510 attributes->VName[0] = '\0'; 3511 #endif 3512 #if defined(VERSION) 3513 (void) strcpy(attributes->VVersion, VERSION); 3514 #else 3515 attributes->VVersion[0] = '\0'; 3516 #endif 3517 3518 if (gettimeofday(&tv, (void *)0) == 0) { 3519 if (localtime_r(&tv.tv_sec, &tp) != NULL) { 3520 attributes->build_date.tm_mday = tp.tm_mday; 3521 attributes->build_date.tm_mon = tp.tm_mon; 3522 attributes->build_date.tm_year = tp.tm_year; 3523 } else { 3524 (void) memset(&attributes->build_date, 0, 3525 sizeof (attributes->build_date)); 3526 } 3527 (void) memset(&attributes->build_date, 0, 3528 sizeof (attributes->build_date)); 3529 } 3530 3531 return (1); 3532 } 3533 3534 /* 3535 * This function returns the attributes for the warpper library. 3536 */ 3537 HBA_UINT32 3538 SMHBA_GetVendorLibraryAttributes( 3539 HBA_UINT32 adapter_index, 3540 SMHBA_LIBRARYATTRIBUTES *attributes) 3541 { 3542 HBA_ADAPTER_INFO *adapt_infop; 3543 SMHBAGetVendorLibraryAttributesFunc 3544 registeredfunc; 3545 HBA_UINT32 ret = 0; 3546 3547 DEBUG(2, "SMHBA_GetVendorLibraryAttributes adapterindex:%d", 3548 adapter_index, 0, 0); 3549 if (_hbaapi_librarylist == NULL) { 3550 DEBUG(1, "SMHBAAPI not loaded yet.", 0, 0, 0); 3551 return (0); 3552 } 3553 3554 if (attributes == NULL) { 3555 DEBUG(1, "SMHBA_GetVendorLibraryAttributes: " 3556 "NULL pointer attributes", 3557 0, 0, 0); 3558 return (HBA_STATUS_ERROR_ARG); 3559 } 3560 3561 (void) memset(attributes, 0, sizeof (SMHBA_LIBRARYATTRIBUTES)); 3562 3563 GRAB_MUTEX(&_hbaapi_LL_mutex); 3564 GRAB_MUTEX(&_hbaapi_AL_mutex); 3565 for (adapt_infop = _hbaapi_adapterlist; 3566 adapt_infop != NULL; 3567 adapt_infop = adapt_infop->next) { 3568 3569 if (adapt_infop->index == adapter_index) { 3570 3571 if (adapt_infop->library->version != SMHBA) { 3572 RELEASE_MUTEX(&_hbaapi_AL_mutex); 3573 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, 3574 HBA_STATUS_ERROR_INCOMPATIBLE); 3575 } 3576 3577 registeredfunc = adapt_infop->library-> 3578 ftable.smhbafunctionTable.GetVendorLibraryAttributesHandler; 3579 if (registeredfunc != NULL) { 3580 ret = (registeredfunc)(attributes); 3581 #ifdef NOTDEF 3582 } else { 3583 /* This should not happen since the VSL is already loaded. */ 3584 #endif 3585 } 3586 if (attributes->LibPath[0] == '\0') { 3587 if (strlen(adapt_infop->library->LibraryPath) < 256) { 3588 (void) strcpy(attributes->LibPath, 3589 adapt_infop->library->LibraryPath); 3590 } 3591 } 3592 break; 3593 } 3594 } 3595 RELEASE_MUTEX(&_hbaapi_AL_mutex); 3596 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, ret); 3597 } 3598 3599 HBA_STATUS 3600 SMHBA_GetAdapterAttributes( 3601 HBA_HANDLE handle, 3602 SMHBA_ADAPTERATTRIBUTES *hbaattributes) 3603 { 3604 HBA_STATUS status; 3605 HBA_LIBRARY_INFO *lib_infop; 3606 HBA_HANDLE vendorHandle; 3607 SMHBAGetAdapterAttributesFunc GetAdapterAttributesFunc; 3608 3609 DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0); 3610 3611 CHECKLIBRARYANDVERSION(SMHBA); 3612 3613 GetAdapterAttributesFunc = 3614 lib_infop->ftable.smhbafunctionTable.GetAdapterAttributesHandler; 3615 if (GetAdapterAttributesFunc != NULL) { 3616 status = ((GetAdapterAttributesFunc)(vendorHandle, hbaattributes)); 3617 } else { 3618 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3619 } 3620 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3621 } 3622 3623 HBA_STATUS 3624 SMHBA_GetNumberOfPorts( 3625 HBA_HANDLE handle, 3626 HBA_UINT32 *numberofports) 3627 { 3628 HBA_STATUS status; 3629 HBA_LIBRARY_INFO *lib_infop; 3630 HBA_HANDLE vendorHandle; 3631 SMHBAGetNumberOfPortsFunc GetNumberOfPortsFunc; 3632 3633 DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0); 3634 3635 CHECKLIBRARYANDVERSION(SMHBA); 3636 3637 GetNumberOfPortsFunc = 3638 lib_infop->ftable.smhbafunctionTable.GetNumberOfPortsHandler; 3639 if (GetNumberOfPortsFunc != NULL) { 3640 status = ((GetNumberOfPortsFunc)(vendorHandle, numberofports)); 3641 } else { 3642 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3643 } 3644 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3645 } 3646 3647 HBA_STATUS 3648 SMHBA_GetPortType( 3649 HBA_HANDLE handle, 3650 HBA_UINT32 portindex, 3651 HBA_PORTTYPE *porttype) 3652 { 3653 HBA_STATUS status; 3654 HBA_LIBRARY_INFO *lib_infop; 3655 HBA_HANDLE vendorHandle; 3656 SMHBAGetPortTypeFunc GetPortTypeFunc; 3657 3658 DEBUG(2, "SMHBA_GetAdapterAttributes", 0, 0, 0); 3659 3660 CHECKLIBRARYANDVERSION(SMHBA); 3661 3662 GetPortTypeFunc = 3663 lib_infop->ftable.smhbafunctionTable.GetPortTypeHandler; 3664 if (GetPortTypeFunc != NULL) { 3665 status = ((GetPortTypeFunc)(vendorHandle, portindex, porttype)); 3666 } else { 3667 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3668 } 3669 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3670 } 3671 3672 HBA_STATUS 3673 SMHBA_GetAdapterPortAttributes( 3674 HBA_HANDLE handle, 3675 HBA_UINT32 portindex, 3676 SMHBA_PORTATTRIBUTES *portattributes) 3677 { 3678 HBA_STATUS status; 3679 HBA_LIBRARY_INFO *lib_infop; 3680 HBA_HANDLE vendorHandle; 3681 SMHBAGetAdapterPortAttributesFunc 3682 GetAdapterPortAttributesFunc; 3683 3684 DEBUG(2, "SMHBA_GetAdapterPortAttributes", 0, 0, 0); 3685 3686 CHECKLIBRARYANDVERSION(SMHBA); 3687 3688 GetAdapterPortAttributesFunc = 3689 lib_infop->ftable.smhbafunctionTable.\ 3690 GetAdapterPortAttributesHandler; 3691 if (GetAdapterPortAttributesFunc != NULL) { 3692 status = ((GetAdapterPortAttributesFunc) 3693 (vendorHandle, portindex, portattributes)); 3694 } else { 3695 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3696 } 3697 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3698 } 3699 3700 HBA_STATUS 3701 SMHBA_GetDiscoveredPortAttributes( 3702 HBA_HANDLE handle, 3703 HBA_UINT32 portindex, 3704 HBA_UINT32 discoveredportindex, 3705 SMHBA_PORTATTRIBUTES *portattributes) 3706 { 3707 HBA_STATUS status; 3708 HBA_LIBRARY_INFO *lib_infop; 3709 HBA_HANDLE vendorHandle; 3710 SMHBAGetDiscoveredPortAttributesFunc 3711 GetDiscoveredPortAttributesFunc; 3712 3713 DEBUG(2, "SMHBA_GetDiscoveredPortAttributes", 0, 0, 0); 3714 3715 CHECKLIBRARYANDVERSION(SMHBA); 3716 3717 GetDiscoveredPortAttributesFunc = 3718 lib_infop->ftable.smhbafunctionTable.\ 3719 GetDiscoveredPortAttributesHandler; 3720 if (GetDiscoveredPortAttributesFunc != NULL) { 3721 status = ((GetDiscoveredPortAttributesFunc) 3722 (vendorHandle, portindex, discoveredportindex, 3723 portattributes)); 3724 } else { 3725 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3726 } 3727 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3728 } 3729 3730 HBA_STATUS 3731 SMHBA_GetPortAttributesByWWN( 3732 HBA_HANDLE handle, 3733 HBA_WWN portWWN, 3734 HBA_WWN domainPortWWN, 3735 SMHBA_PORTATTRIBUTES *portattributes) 3736 { 3737 HBA_STATUS status; 3738 HBA_LIBRARY_INFO *lib_infop; 3739 HBA_HANDLE vendorHandle; 3740 SMHBAGetPortAttributesByWWNFunc 3741 GetPortAttributesByWWNFunc; 3742 3743 DEBUG(2, "SMHBA_GetPortAttributesByWWN: %s", WWN2STR1(&portWWN), 0, 0); 3744 3745 CHECKLIBRARYANDVERSION(SMHBA); 3746 3747 GetPortAttributesByWWNFunc = 3748 lib_infop->ftable.smhbafunctionTable.GetPortAttributesByWWNHandler; 3749 if (GetPortAttributesByWWNFunc != NULL) { 3750 status = ((GetPortAttributesByWWNFunc) 3751 (vendorHandle, portWWN, domainPortWWN, portattributes)); 3752 } else { 3753 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3754 } 3755 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3756 } 3757 3758 HBA_STATUS 3759 SMHBA_GetFCPhyAttributes( 3760 HBA_HANDLE handle, 3761 HBA_UINT32 portindex, 3762 HBA_UINT32 phyindex, 3763 SMHBA_FC_PHY *phytype) 3764 { 3765 HBA_STATUS status; 3766 HBA_LIBRARY_INFO *lib_infop; 3767 HBA_HANDLE vendorHandle; 3768 SMHBAGetFCPhyAttributesFunc GetFCPhyAttributesFunc; 3769 3770 DEBUG(2, "SMHBA_GetFCPhyAttributesByWWN", 0, 0, 0); 3771 3772 CHECKLIBRARYANDVERSION(SMHBA); 3773 3774 GetFCPhyAttributesFunc = 3775 lib_infop->ftable.smhbafunctionTable.GetFCPhyAttributesHandler; 3776 if (GetFCPhyAttributesFunc != NULL) { 3777 status = ((GetFCPhyAttributesFunc) 3778 (vendorHandle, portindex, phyindex, phytype)); 3779 } else { 3780 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3781 } 3782 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3783 } 3784 3785 HBA_STATUS 3786 SMHBA_GetSASPhyAttributes( 3787 HBA_HANDLE handle, 3788 HBA_UINT32 portindex, 3789 HBA_UINT32 phyindex, 3790 SMHBA_SAS_PHY *phytype) 3791 { 3792 HBA_STATUS status; 3793 HBA_LIBRARY_INFO *lib_infop; 3794 HBA_HANDLE vendorHandle; 3795 SMHBAGetSASPhyAttributesFunc GetSASPhyAttributesFunc; 3796 3797 DEBUG(2, "SMHBA_GetFCPhyAttributesByWWN", 0, 0, 0); 3798 3799 CHECKLIBRARYANDVERSION(SMHBA); 3800 3801 GetSASPhyAttributesFunc = 3802 lib_infop->ftable.smhbafunctionTable.GetSASPhyAttributesHandler; 3803 if (GetSASPhyAttributesFunc != NULL) { 3804 status = ((GetSASPhyAttributesFunc) 3805 (vendorHandle, portindex, phyindex, phytype)); 3806 } else { 3807 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3808 } 3809 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3810 } 3811 3812 HBA_STATUS 3813 SMHBA_GetProtocolStatistics( 3814 HBA_HANDLE handle, 3815 HBA_UINT32 portindex, 3816 HBA_UINT32 protocoltype, 3817 SMHBA_PROTOCOLSTATISTICS *pProtocolStatistics) 3818 { 3819 HBA_STATUS status; 3820 HBA_LIBRARY_INFO *lib_infop; 3821 HBA_HANDLE vendorHandle; 3822 SMHBAGetProtocolStatisticsFunc 3823 GetProtocolStatisticsFunc; 3824 3825 DEBUG(2, "SMHBA_GetProtocolStatistics port index: %d protocol type: %d", 3826 portindex, protocoltype, 0); 3827 3828 CHECKLIBRARYANDVERSION(SMHBA); 3829 3830 GetProtocolStatisticsFunc = 3831 lib_infop->ftable.smhbafunctionTable.GetProtocolStatisticsHandler; 3832 if (GetProtocolStatisticsFunc != NULL) { 3833 status = (GetProtocolStatisticsFunc) 3834 (vendorHandle, portindex, protocoltype, pProtocolStatistics); 3835 } else { 3836 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3837 } 3838 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3839 } 3840 3841 HBA_STATUS 3842 SMHBA_GetPhyStatistics( 3843 HBA_HANDLE handle, 3844 HBA_UINT32 portindex, 3845 HBA_UINT32 phyindex, 3846 SMHBA_PHYSTATISTICS *pPhyStatistics) 3847 { 3848 HBA_STATUS status; 3849 HBA_LIBRARY_INFO *lib_infop; 3850 HBA_HANDLE vendorHandle; 3851 SMHBAGetPhyStatisticsFunc 3852 GetPhyStatisticsFunc; 3853 3854 DEBUG(2, "SMHBA_GetPhyStatistics port index: %d phy idex: %d", 3855 portindex, phyindex, 0); 3856 3857 CHECKLIBRARYANDVERSION(SMHBA); 3858 3859 GetPhyStatisticsFunc = 3860 lib_infop->ftable.smhbafunctionTable.GetPhyStatisticsHandler; 3861 if (GetPhyStatisticsFunc != NULL) { 3862 status = (GetPhyStatisticsFunc) 3863 (vendorHandle, portindex, phyindex, pPhyStatistics); 3864 } else { 3865 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3866 } 3867 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3868 } 3869 3870 HBA_STATUS 3871 SMHBA_GetBindingCapability( 3872 HBA_HANDLE handle, 3873 HBA_WWN hbaPortWWN, 3874 HBA_WWN domainPortWWN, 3875 SMHBA_BIND_CAPABILITY *pFlags) 3876 { 3877 HBA_STATUS status; 3878 HBA_LIBRARY_INFO *lib_infop; 3879 HBA_HANDLE vendorHandle; 3880 SMHBAGetBindingCapabilityFunc GetBindingCapabilityFunc; 3881 3882 DEBUG(2, "HBA_GetBindingCapability", 0, 0, 0); 3883 3884 CHECKLIBRARYANDVERSION(SMHBA); 3885 3886 GetBindingCapabilityFunc = 3887 lib_infop->ftable.smhbafunctionTable.GetBindingCapabilityHandler; 3888 if (GetBindingCapabilityFunc != NULL) { 3889 status = (GetBindingCapabilityFunc)(vendorHandle, hbaPortWWN, 3890 domainPortWWN, pFlags); 3891 } else { 3892 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3893 } 3894 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3895 } 3896 3897 HBA_STATUS 3898 SMHBA_GetBindingSupport( 3899 HBA_HANDLE handle, 3900 HBA_WWN hbaPortWWN, 3901 HBA_WWN domainPortWWN, 3902 SMHBA_BIND_CAPABILITY *pFlags) 3903 { 3904 HBA_STATUS status; 3905 HBA_LIBRARY_INFO *lib_infop; 3906 HBA_HANDLE vendorHandle; 3907 SMHBAGetBindingSupportFunc 3908 GetBindingSupporFunc; 3909 3910 DEBUG(2, "SMHBA_GetBindingSupport port: %s", 3911 WWN2STR1(&hbaPortWWN), 0, 0); 3912 3913 CHECKLIBRARYANDVERSION(SMHBA); 3914 3915 GetBindingSupporFunc = 3916 lib_infop->ftable.smhbafunctionTable.GetBindingSupportHandler; 3917 if (GetBindingSupporFunc != NULL) { 3918 status = (GetBindingSupporFunc)(vendorHandle, 3919 hbaPortWWN, domainPortWWN, pFlags); 3920 } else { 3921 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3922 } 3923 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3924 } 3925 3926 HBA_STATUS 3927 SMHBA_SetBindingSupport( 3928 HBA_HANDLE handle, 3929 HBA_WWN hbaPortWWN, 3930 HBA_WWN domainPortWWN, 3931 SMHBA_BIND_CAPABILITY flags) 3932 { 3933 HBA_STATUS status; 3934 HBA_LIBRARY_INFO *lib_infop; 3935 HBA_HANDLE vendorHandle; 3936 SMHBASetBindingSupportFunc 3937 SetBindingSupporFunc; 3938 3939 DEBUG(2, "SMHBA_GetBindingSupport port: %s", 3940 WWN2STR1(&hbaPortWWN), 0, 0); 3941 3942 CHECKLIBRARYANDVERSION(HBAAPIV2); 3943 3944 SetBindingSupporFunc = 3945 lib_infop->ftable.smhbafunctionTable.SetBindingSupportHandler; 3946 if (SetBindingSupporFunc != NULL) { 3947 status = (SetBindingSupporFunc) 3948 (vendorHandle, hbaPortWWN, domainPortWWN, flags); 3949 } else { 3950 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3951 } 3952 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3953 } 3954 3955 HBA_STATUS 3956 SMHBA_GetTargetMapping( 3957 HBA_HANDLE handle, 3958 HBA_WWN hbaPortWWN, 3959 HBA_WWN domainPortWWN, 3960 SMHBA_TARGETMAPPING *pMapping) 3961 { 3962 HBA_STATUS status; 3963 HBA_LIBRARY_INFO *lib_infop; 3964 HBA_HANDLE vendorHandle; 3965 SMHBAGetTargetMappingFunc GetTargetMappingFunc; 3966 3967 DEBUG(2, "SMHBA_GetTargetMapping port WWN: %s", 3968 WWN2STR1(&hbaPortWWN), 0, 0); 3969 3970 CHECKLIBRARYANDVERSION(SMHBA); 3971 3972 GetTargetMappingFunc = 3973 lib_infop->ftable.smhbafunctionTable.GetTargetMappingHandler; 3974 if (GetTargetMappingFunc != NULL) { 3975 status = ((GetTargetMappingFunc)(vendorHandle, 3976 hbaPortWWN, domainPortWWN, pMapping)); 3977 } else { 3978 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 3979 } 3980 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 3981 } 3982 3983 HBA_STATUS 3984 SMHBA_GetPersistentBinding( 3985 HBA_HANDLE handle, 3986 HBA_WWN hbaPortWWN, 3987 HBA_WWN domainPortWWN, 3988 SMHBA_BINDING *binding) 3989 { 3990 HBA_STATUS status; 3991 HBA_LIBRARY_INFO *lib_infop; 3992 HBA_HANDLE vendorHandle; 3993 SMHBAGetPersistentBindingFunc 3994 GetPersistentBindingFunc; 3995 3996 DEBUG(2, "SMHBA_GetPersistentBinding port WWN: %s", 3997 WWN2STR1(&hbaPortWWN), 0, 0); 3998 3999 CHECKLIBRARYANDVERSION(SMHBA); 4000 4001 GetPersistentBindingFunc = 4002 lib_infop->ftable.smhbafunctionTable.GetPersistentBindingHandler; 4003 if (GetPersistentBindingFunc != NULL) { 4004 status = ((GetPersistentBindingFunc)(vendorHandle, 4005 hbaPortWWN, domainPortWWN, binding)); 4006 } else { 4007 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4008 } 4009 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4010 } 4011 4012 HBA_STATUS 4013 SMHBA_SetPersistentBinding( 4014 HBA_HANDLE handle, 4015 HBA_WWN hbaPortWWN, 4016 HBA_WWN domainPortWWN, 4017 const SMHBA_BINDING *binding) 4018 { 4019 HBA_STATUS status; 4020 HBA_LIBRARY_INFO *lib_infop; 4021 HBA_HANDLE vendorHandle; 4022 SMHBASetPersistentBindingFunc 4023 SetPersistentBindingFunc; 4024 4025 DEBUG(2, "SMHBA_SetPersistentBinding port WWN: %s", 4026 WWN2STR1(&hbaPortWWN), 0, 0); 4027 4028 CHECKLIBRARYANDVERSION(SMHBA); 4029 4030 SetPersistentBindingFunc = 4031 lib_infop->ftable.smhbafunctionTable.SetPersistentBindingHandler; 4032 if (SetPersistentBindingFunc != NULL) { 4033 status = ((SetPersistentBindingFunc)(vendorHandle, 4034 hbaPortWWN, domainPortWWN, binding)); 4035 } else { 4036 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4037 } 4038 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4039 } 4040 4041 HBA_STATUS 4042 SMHBA_RemovePersistentBinding( 4043 HBA_HANDLE handle, 4044 HBA_WWN hbaPortWWN, 4045 HBA_WWN domainPortWWN, 4046 const SMHBA_BINDING *binding) 4047 { 4048 HBA_STATUS status; 4049 HBA_LIBRARY_INFO *lib_infop; 4050 HBA_HANDLE vendorHandle; 4051 SMHBARemovePersistentBindingFunc 4052 RemovePersistentBindingFunc; 4053 4054 DEBUG(2, "SMHBA_RemovePersistentBinding port WWN: %s", 4055 WWN2STR1(&hbaPortWWN), 0, 0); 4056 4057 CHECKLIBRARYANDVERSION(SMHBA); 4058 4059 RemovePersistentBindingFunc = 4060 lib_infop->ftable.smhbafunctionTable.RemovePersistentBindingHandler; 4061 if (RemovePersistentBindingFunc != NULL) { 4062 status = ((RemovePersistentBindingFunc)(vendorHandle, 4063 hbaPortWWN, domainPortWWN, binding)); 4064 } else { 4065 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4066 } 4067 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4068 } 4069 4070 HBA_STATUS 4071 SMHBA_RemoveAllPersistentBindings( 4072 HBA_HANDLE handle, 4073 HBA_WWN hbaPortWWN, 4074 HBA_WWN domainPortWWN) 4075 { 4076 HBA_STATUS status; 4077 HBA_LIBRARY_INFO *lib_infop; 4078 HBA_HANDLE vendorHandle; 4079 SMHBARemoveAllPersistentBindingsFunc 4080 RemoveAllPersistentBindingsFunc; 4081 4082 DEBUG(2, "SMHBA_RemoveAllPersistentBinding port WWN: %s", 4083 WWN2STR1(&hbaPortWWN), 0, 0); 4084 4085 CHECKLIBRARYANDVERSION(SMHBA); 4086 4087 RemoveAllPersistentBindingsFunc = 4088 lib_infop->ftable.smhbafunctionTable.\ 4089 RemoveAllPersistentBindingsHandler; 4090 if (RemoveAllPersistentBindingsFunc != NULL) { 4091 status = ((RemoveAllPersistentBindingsFunc)(vendorHandle, 4092 hbaPortWWN, domainPortWWN)); 4093 } else { 4094 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4095 } 4096 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4097 } 4098 4099 HBA_STATUS 4100 SMHBA_GetLUNStatistics( 4101 HBA_HANDLE handle, 4102 const HBA_SCSIID *lunit, 4103 SMHBA_PROTOCOLSTATISTICS *statistics) 4104 { 4105 HBA_STATUS status; 4106 HBA_LIBRARY_INFO *lib_infop; 4107 HBA_HANDLE vendorHandle; 4108 SMHBAGetLUNStatisticsFunc GetLUNStatisticsFunc; 4109 4110 DEBUG(2, "SMHBA_GetLUNStatistics", 0, 0, 0); 4111 4112 CHECKLIBRARYANDVERSION(SMHBA); 4113 4114 GetLUNStatisticsFunc = 4115 lib_infop->ftable.smhbafunctionTable.GetLUNStatisticsHandler; 4116 if (GetLUNStatisticsFunc != NULL) { 4117 status = ((GetLUNStatisticsFunc)(vendorHandle, lunit, statistics)); 4118 } else { 4119 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4120 } 4121 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4122 } 4123 4124 HBA_STATUS 4125 SMHBA_ScsiInquiry( 4126 HBA_HANDLE handle, 4127 HBA_WWN hbaPortWWN, 4128 HBA_WWN discoveredPortWWN, 4129 HBA_WWN domainPortWWN, 4130 SMHBA_SCSILUN smhbaLUN, 4131 HBA_UINT8 CDB_Byte1, 4132 HBA_UINT8 CDB_Byte2, 4133 void *pRspBuffer, 4134 HBA_UINT32 *pRspBufferSize, 4135 HBA_UINT8 *pScsiStatus, 4136 void *pSenseBuffer, 4137 HBA_UINT32 *pSenseBufferSize) 4138 { 4139 HBA_STATUS status; 4140 HBA_LIBRARY_INFO *lib_infop; 4141 HBA_HANDLE vendorHandle; 4142 SMHBAScsiInquiryFunc ScsiInquiryFunc; 4143 4144 DEBUG(2, "SMHBA_ScsiInquiry to hba port: %s discoveredPortWWN: %s", 4145 WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0); 4146 4147 CHECKLIBRARYANDVERSION(SMHBA); 4148 4149 ScsiInquiryFunc = 4150 lib_infop->ftable.smhbafunctionTable.ScsiInquiryHandler; 4151 if (ScsiInquiryFunc != NULL) { 4152 status = ((ScsiInquiryFunc)( 4153 vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN, 4154 smhbaLUN, CDB_Byte1, CDB_Byte2, pRspBuffer, pRspBufferSize, 4155 pScsiStatus, pSenseBuffer, pSenseBufferSize)); 4156 } else { 4157 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4158 } 4159 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4160 } 4161 4162 HBA_STATUS 4163 SMHBA_ScsiReportLUNs( 4164 HBA_HANDLE handle, 4165 HBA_WWN hbaPortWWN, 4166 HBA_WWN discoveredPortWWN, 4167 HBA_WWN domainPortWWN, 4168 void *pRspBuffer, 4169 HBA_UINT32 *pRspBufferSize, 4170 HBA_UINT8 *pScsiStatus, 4171 void *pSenseBuffer, 4172 HBA_UINT32 *pSenseBufferSize) 4173 { 4174 HBA_STATUS status; 4175 HBA_LIBRARY_INFO *lib_infop; 4176 HBA_HANDLE vendorHandle; 4177 SMHBAScsiReportLUNsFunc ScsiReportLUNsFunc; 4178 4179 DEBUG(2, "SMHBA_ScsiReportLuns to hba port: %s discoveredPortWWN: %s", 4180 WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0); 4181 4182 CHECKLIBRARYANDVERSION(SMHBA); 4183 4184 ScsiReportLUNsFunc = 4185 lib_infop->ftable.smhbafunctionTable.ScsiReportLUNsHandler; 4186 if (ScsiReportLUNsFunc != NULL) { 4187 status = ((ScsiReportLUNsFunc)( 4188 vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN, 4189 pRspBuffer, pRspBufferSize, pScsiStatus, pSenseBuffer, 4190 pSenseBufferSize)); 4191 } else { 4192 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4193 } 4194 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4195 } 4196 4197 HBA_STATUS 4198 SMHBA_ScsiReadCapacity( 4199 HBA_HANDLE handle, 4200 HBA_WWN hbaPortWWN, 4201 HBA_WWN discoveredPortWWN, 4202 HBA_WWN domainPortWWN, 4203 SMHBA_SCSILUN smhbaLUN, 4204 void *pRspBuffer, 4205 HBA_UINT32 *pRspBufferSize, 4206 HBA_UINT8 *pScsiStatus, 4207 void *pSenseBuffer, 4208 HBA_UINT32 *pSenseBufferSize) 4209 { 4210 HBA_STATUS status; 4211 HBA_LIBRARY_INFO *lib_infop; 4212 HBA_HANDLE vendorHandle; 4213 SMHBAScsiReadCapacityFunc ScsiReadCapacityFunc; 4214 4215 DEBUG(2, "SMHBA_ScsiReadCapacity to hba port: %s discoveredPortWWN: %s", 4216 WWN2STR1(&hbaPortWWN), WWN2STR1(&discoveredPortWWN), 0); 4217 4218 CHECKLIBRARYANDVERSION(SMHBA); 4219 4220 ScsiReadCapacityFunc = 4221 lib_infop->ftable.smhbafunctionTable.ScsiReadCapacityHandler; 4222 if (ScsiReadCapacityFunc != NULL) { 4223 status = ((ScsiReadCapacityFunc)( 4224 vendorHandle, hbaPortWWN, discoveredPortWWN, domainPortWWN, 4225 smhbaLUN, pRspBuffer, pRspBufferSize, pScsiStatus, pSenseBuffer, 4226 pSenseBufferSize)); 4227 } else { 4228 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4229 } 4230 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4231 } 4232 4233 HBA_STATUS 4234 SMHBA_SendTEST( 4235 HBA_HANDLE handle, 4236 HBA_WWN hbaPortWWN, 4237 HBA_WWN destWWN, 4238 HBA_UINT32 destFCID, 4239 void *pRspBuffer, 4240 HBA_UINT32 pRspBufferSize) 4241 { 4242 HBA_STATUS status; 4243 HBA_LIBRARY_INFO *lib_infop; 4244 HBA_HANDLE vendorHandle; 4245 SMHBASendTESTFunc SendTESTFunc; 4246 4247 DEBUG(2, "SMHBA_SendTEST, hbaPortWWN: %s destWWN", 4248 WWN2STR1(&hbaPortWWN), 4249 WWN2STR1(&destWWN), 0); 4250 4251 CHECKLIBRARYANDVERSION(SMHBA); 4252 4253 SendTESTFunc = lib_infop->ftable.smhbafunctionTable.SendTESTHandler; 4254 if (SendTESTFunc != NULL) { 4255 status = (SendTESTFunc) 4256 (vendorHandle, hbaPortWWN, destWWN, destFCID, 4257 pRspBuffer, pRspBufferSize); 4258 } else { 4259 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4260 } 4261 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4262 } 4263 4264 HBA_STATUS 4265 SMHBA_SendECHO( 4266 HBA_HANDLE handle, 4267 HBA_WWN hbaPortWWN, 4268 HBA_WWN destWWN, 4269 HBA_UINT32 destFCID, 4270 void *pReqBuffer, 4271 HBA_UINT32 ReqBufferSize, 4272 void *pRspBuffer, 4273 HBA_UINT32 *pRspBufferSize) 4274 { 4275 HBA_STATUS status; 4276 HBA_LIBRARY_INFO *lib_infop; 4277 HBA_HANDLE vendorHandle; 4278 SMHBASendECHOFunc SendECHOFunc; 4279 4280 DEBUG(2, "SMHBA_SendECHO, hbaPortWWN: %s destWWN", 4281 WWN2STR1(&hbaPortWWN), WWN2STR1(&destWWN), 0); 4282 4283 CHECKLIBRARYANDVERSION(SMHBA); 4284 4285 SendECHOFunc = lib_infop->ftable.smhbafunctionTable.SendECHOHandler; 4286 if (SendECHOFunc != NULL) { 4287 status = (SendECHOFunc) 4288 (vendorHandle, hbaPortWWN, destWWN, destFCID, 4289 pReqBuffer, ReqBufferSize, pRspBuffer, pRspBufferSize); 4290 } else { 4291 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4292 } 4293 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4294 } 4295 4296 HBA_STATUS 4297 SMHBA_SendSMPPassThru( 4298 HBA_HANDLE handle, 4299 HBA_WWN hbaPortWWN, 4300 HBA_WWN destWWN, 4301 HBA_WWN domainPortWWN, 4302 void *pReqBuffer, 4303 HBA_UINT32 ReqBufferSize, 4304 void *pRspBuffer, 4305 HBA_UINT32 *pRspBufferSize) 4306 { 4307 HBA_STATUS status; 4308 HBA_LIBRARY_INFO *lib_infop; 4309 HBA_HANDLE vendorHandle; 4310 SMHBASendSMPPassThruFunc SendSMPPassThruFunc; 4311 4312 DEBUG(2, "SMHBA_SendSMPPassThru, hbaPortWWN: %s destWWN: %s", 4313 WWN2STR1(&hbaPortWWN), WWN2STR1(&destWWN), 0); 4314 4315 CHECKLIBRARYANDVERSION(SMHBA); 4316 4317 SendSMPPassThruFunc = lib_infop->ftable.\ 4318 smhbafunctionTable.SendSMPPassThruHandler; 4319 4320 if (SendSMPPassThruFunc != NULL) { 4321 status = (SendSMPPassThruFunc) 4322 (vendorHandle, hbaPortWWN, destWWN, domainPortWWN, 4323 pReqBuffer, ReqBufferSize, pRspBuffer, pRspBufferSize); 4324 } else { 4325 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4326 } 4327 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4328 } 4329 4330 /* 4331 * Following the similar logic of HBAAPI addaspterevents_callback. 4332 * 4333 * Unlike other events Adapter Add Event is not limited to a specific 4334 * adapter(i.e. no adapter handle is passed for registration) so 4335 * the event should be passed to all registrants. The routine below 4336 * is passed to the VSLs as a callback and when Adapter Add event is detected 4337 * by VSL it will call smhba_adapteraddevents_callback() which in turn check 4338 * if the passed userdata ptr matches with the one stored in the callback list 4339 * and calls the stored callback. 4340 * 4341 * For the situation that multiple clients are registered for Adapter Add event 4342 * each registration is passed to VSLs so VSL may call 4343 * smhba_adapteraddevents_callback() multiple times or it may call only once 4344 * since the callback function is same. For this implemneation, the userdata 4345 * is stored in HBA_ALLADAPTERSCALLBACK_ELEM so it is expected that VSL call 4346 * smhba_adapteraddevents_callback() only once and 4347 * smhba_adapteraddevents_callback() will call the client callback with proper 4348 * userdata. 4349 */ 4350 static void 4351 smhba_adapteraddevents_callback( 4352 /* LINTED E_FUNC_ARG_UNUSED */ 4353 void *data, 4354 HBA_WWN PortWWN, 4355 /* LINTED E_FUNC_ARG_UNUSED */ 4356 HBA_UINT32 eventType) 4357 { 4358 HBA_ALLADAPTERSCALLBACK_ELEM *cbp; 4359 4360 DEBUG(3, "AddAdapterEvent, port:%s", WWN2STR1(&PortWWN), 0, 0); 4361 4362 GRAB_MUTEX(&_smhba_AAE_mutex); 4363 for (cbp = _smhba_adapteraddevents_callback_list; 4364 cbp != NULL; 4365 cbp = cbp->next) { 4366 (*cbp->callback)(cbp->userdata, PortWWN, HBA_EVENT_ADAPTER_ADD); 4367 } 4368 RELEASE_MUTEX(&_smhba_AAE_mutex); 4369 4370 } 4371 4372 HBA_STATUS 4373 SMHBA_RegisterForAdapterAddEvents( 4374 void (*pCallback) ( 4375 void *data, 4376 HBA_WWN PortWWN, 4377 HBA_UINT32 eventType), 4378 void *pUserData, 4379 HBA_CALLBACKHANDLE *pCallbackHandle) { 4380 4381 HBA_ALLADAPTERSCALLBACK_ELEM *cbp; 4382 HBA_VENDORCALLBACK_ELEM *vcbp; 4383 HBA_VENDORCALLBACK_ELEM *vendorhandlelist; 4384 SMHBARegisterForAdapterAddEventsFunc registeredfunc; 4385 HBA_STATUS status = HBA_STATUS_OK; 4386 HBA_STATUS failure = HBA_STATUS_OK; 4387 HBA_LIBRARY_INFO *lib_infop; 4388 int registered_cnt = 0; 4389 int vendor_cnt = 0; 4390 int not_supported_cnt = 0; 4391 int status_OK_bar_cnt = 0; 4392 int status_OK_cnt = 0; 4393 4394 DEBUG(2, "SMHBA_RegisterForAdapterAddEvents", 0, 0, 0); 4395 ARE_WE_INITED(); 4396 4397 cbp = (HBA_ALLADAPTERSCALLBACK_ELEM *) 4398 calloc(1, sizeof (HBA_ALLADAPTERSCALLBACK_ELEM)); 4399 *pCallbackHandle = (HBA_CALLBACKHANDLE) cbp; 4400 if (cbp == NULL) { 4401 return (HBA_STATUS_ERROR); 4402 } 4403 4404 GRAB_MUTEX(&_hbaapi_LL_mutex); 4405 GRAB_MUTEX(&_smhba_AAE_mutex); 4406 cbp->callback = pCallback; 4407 cbp->userdata = pUserData; 4408 cbp->next = _smhba_adapteraddevents_callback_list; 4409 _smhba_adapteraddevents_callback_list = cbp; 4410 4411 /* 4412 * Need to release the mutex now incase the vendor function invokes the 4413 * callback. We will grap the mutex later to attach the vendor handle 4414 * list to the callback structure 4415 */ 4416 RELEASE_MUTEX(&_smhba_AAE_mutex); 4417 4418 4419 /* 4420 * now create a list of vendors (vendor libraryies, NOT ADAPTERS) 4421 * that have successfully registerred 4422 */ 4423 vendorhandlelist = NULL; 4424 for (lib_infop = _hbaapi_librarylist; 4425 lib_infop != NULL; 4426 lib_infop = lib_infop->next) { 4427 4428 /* only for HBAAPI V2 */ 4429 if (lib_infop->version != SMHBA) { 4430 continue; 4431 } else { 4432 vendor_cnt++; 4433 } 4434 4435 registeredfunc = 4436 lib_infop->ftable.smhbafunctionTable.\ 4437 RegisterForAdapterAddEventsHandler; 4438 if (registeredfunc == NULL) { 4439 continue; 4440 } 4441 4442 vcbp = (HBA_VENDORCALLBACK_ELEM *) 4443 calloc(1, sizeof (HBA_VENDORCALLBACK_ELEM)); 4444 if (vcbp == NULL) { 4445 freevendorhandlelist(vendorhandlelist); 4446 status = HBA_STATUS_ERROR; 4447 break; 4448 } 4449 4450 registered_cnt++; 4451 status = (registeredfunc)(smhba_adapteraddevents_callback, 4452 pUserData, &vcbp->vendorcbhandle); 4453 if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) { 4454 not_supported_cnt++; 4455 free(vcbp); 4456 continue; 4457 } else if (status != HBA_STATUS_OK) { 4458 status_OK_bar_cnt++; 4459 DEBUG(1, 4460 "SMHBA_RegisterForAdapterAddEvents: Library->%s, Error->%d", 4461 lib_infop->LibraryPath, status, 0); 4462 failure = status; 4463 free(vcbp); 4464 continue; 4465 } else { 4466 status_OK_cnt++; 4467 } 4468 vcbp->lib_info = lib_infop; 4469 vcbp->next = vendorhandlelist; 4470 vendorhandlelist = vcbp; 4471 } 4472 4473 if (vendor_cnt == 0) { 4474 /* no SMHBA VSL found. Should be okay?? */ 4475 status = HBA_STATUS_ERROR; 4476 } else if (registered_cnt == 0) { 4477 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4478 freevendorhandlelist(vendorhandlelist); 4479 (void) local_remove_callback((HBA_CALLBACKHANDLE) cbp); 4480 } else if (status_OK_cnt == 0 && not_supported_cnt != 0) { 4481 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 4482 } else if (status_OK_cnt == 0) { 4483 /* 4484 * At least one vendor library registered this function, but no 4485 * vendor call succeeded 4486 */ 4487 (void) local_remove_callback((HBA_CALLBACKHANDLE) cbp); 4488 status = failure; 4489 } else { 4490 /* we have had atleast some success, now finish up */ 4491 GRAB_MUTEX(&_smhba_AAE_mutex); 4492 /* 4493 * this seems silly, but what if another thread called 4494 * the callback remove 4495 */ 4496 for (cbp = _smhba_adapteraddevents_callback_list; 4497 cbp != NULL; cbp = cbp->next) { 4498 if ((HBA_CALLBACKHANDLE)cbp == *pCallbackHandle) { 4499 /* yup, its still there, hooray */ 4500 cbp->vendorhandlelist = vendorhandlelist; 4501 vendorhandlelist = NULL; 4502 break; 4503 } 4504 } 4505 RELEASE_MUTEX(&_smhba_AAE_mutex); 4506 if (vendorhandlelist != NULL) { 4507 /* 4508 * bummer, somebody removed the callback before we finished 4509 * registration, probably will never happen 4510 */ 4511 freevendorhandlelist(vendorhandlelist); 4512 DEBUG(1, 4513 "HBA_RegisterForAdapterAddEvents: HBA_RemoveCallback was " 4514 "called for a handle before registration was finished.", 4515 0, 0, 0); 4516 status = HBA_STATUS_ERROR; 4517 } else { 4518 status = HBA_STATUS_OK; 4519 } 4520 } 4521 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4522 } 4523 4524 /* SMHBA Adapter Events (other than add) ******************************** */ 4525 static void 4526 smhba_adapterevents_callback(void *data, 4527 HBA_WWN PortWWN, 4528 HBA_UINT32 eventType) 4529 { 4530 HBA_ADAPTERCALLBACK_ELEM *acbp; 4531 4532 DEBUG(3, "AdapterEvent, port:%s, eventType:%d", WWN2STR1(&PortWWN), 4533 eventType, 0); 4534 4535 GRAB_MUTEX(&_hbaapi_AE_mutex); 4536 for (acbp = _smhba_adapterevents_callback_list; 4537 acbp != NULL; 4538 acbp = acbp->next) { 4539 if (data == (void *)acbp) { 4540 (*acbp->callback)(acbp->userdata, PortWWN, eventType); 4541 break; 4542 } 4543 } 4544 RELEASE_MUTEX(&_hbaapi_AE_mutex); 4545 } 4546 4547 HBA_STATUS 4548 SMHBA_RegisterForAdapterEvents( 4549 void (*pCallback) ( 4550 void *data, 4551 HBA_WWN PortWWN, 4552 HBA_UINT32 eventType), 4553 void *pUserData, 4554 HBA_HANDLE handle, 4555 HBA_CALLBACKHANDLE *pCallbackHandle) { 4556 4557 HBA_ADAPTERCALLBACK_ELEM *acbp; 4558 SMHBARegisterForAdapterEventsFunc registeredfunc; 4559 HBA_STATUS status; 4560 HBA_LIBRARY_INFO *lib_infop; 4561 HBA_HANDLE vendorHandle; 4562 4563 DEBUG(2, "SMHBA_RegisterForAdapterEvents", 0, 0, 0); 4564 4565 CHECKLIBRARYANDVERSION(SMHBA); 4566 4567 /* we now have the _hbaapi_LL_mutex */ 4568 4569 registeredfunc = lib_infop->ftable.smhbafunctionTable.\ 4570 RegisterForAdapterEventsHandler; 4571 if (registeredfunc == NULL) { 4572 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 4573 } 4574 4575 /* 4576 * that allocated memory is used both as the handle for the 4577 * caller, and as userdata to the vendor call so that on 4578 * callback the specific registration may be recalled 4579 */ 4580 acbp = (HBA_ADAPTERCALLBACK_ELEM *) 4581 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM)); 4582 if (acbp == NULL) { 4583 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); 4584 } 4585 *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp; 4586 acbp->callback = pCallback; 4587 acbp->userdata = pUserData; 4588 acbp->lib_info = lib_infop; 4589 4590 status = (registeredfunc)(smhba_adapterevents_callback, 4591 (void *)acbp, 4592 vendorHandle, 4593 &acbp->vendorcbhandle); 4594 if (status != HBA_STATUS_OK) { 4595 free(acbp); 4596 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4597 } 4598 4599 GRAB_MUTEX(&_smhba_AE_mutex); 4600 acbp->next = _smhba_adapterevents_callback_list; 4601 _hbaapi_adapterevents_callback_list = acbp; 4602 4603 RELEASE_MUTEX(&_smhba_AE_mutex); 4604 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 4605 } 4606 4607 /* Adapter Port Events *********************************************** */ 4608 static void 4609 smhba_adapterportevents_callback(void *data, 4610 HBA_WWN PortWWN, 4611 HBA_UINT32 eventType, 4612 HBA_UINT32 fabricPortID) 4613 { 4614 HBA_ADAPTERCALLBACK_ELEM *acbp; 4615 4616 DEBUG(3, 4617 "SMHBA_AdapterPortEvent, port:%s, eventType:%d fabricPortID:0X%06x", 4618 WWN2STR1(&PortWWN), eventType, fabricPortID); 4619 4620 GRAB_MUTEX(&_smhba_APE_mutex); 4621 4622 for (acbp = _smhba_adapterportevents_callback_list; 4623 acbp != NULL; 4624 acbp = acbp->next) { 4625 if (data == (void *)acbp) { 4626 (*acbp->callback)(acbp->userdata, PortWWN, 4627 eventType, fabricPortID); 4628 break; 4629 } 4630 } 4631 RELEASE_MUTEX(&_smhba_APE_mutex); 4632 } 4633 4634 HBA_STATUS 4635 SMHBA_RegisterForAdapterPortEvents( 4636 void (*pCallback) ( 4637 void *pData, 4638 HBA_WWN PortWWN, 4639 HBA_UINT32 eventType, 4640 HBA_UINT32 fabricPortID), 4641 void *pUserData, 4642 HBA_HANDLE handle, 4643 HBA_WWN portWWN, 4644 HBA_UINT32 specificEventType, 4645 HBA_CALLBACKHANDLE *pCallbackHandle) { 4646 4647 HBA_ADAPTERCALLBACK_ELEM *acbp; 4648 SMHBARegisterForAdapterPortEventsFunc registeredfunc; 4649 HBA_STATUS status; 4650 HBA_LIBRARY_INFO *lib_infop; 4651 HBA_HANDLE vendorHandle; 4652 4653 DEBUG(2, "SMHBA_RegisterForAdapterPortEvents for port: %s", 4654 WWN2STR1(&portWWN), 0, 0); 4655 4656 CHECKLIBRARYANDVERSION(SMHBA); 4657 /* we now have the _hbaapi_LL_mutex */ 4658 4659 registeredfunc = 4660 lib_infop->ftable.smhbafunctionTable.\ 4661 RegisterForAdapterPortEventsHandler; 4662 if (registeredfunc == NULL) { 4663 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 4664 } 4665 4666 /* 4667 * that allocated memory is used both as the handle for the 4668 * caller, and as userdata to the vendor call so that on 4669 * callback the specific registration may be recalled 4670 */ 4671 acbp = (HBA_ADAPTERCALLBACK_ELEM *) 4672 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM)); 4673 if (acbp == NULL) { 4674 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); 4675 } 4676 *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp; 4677 acbp->callback = pCallback; 4678 acbp->userdata = pUserData; 4679 acbp->lib_info = lib_infop; 4680 4681 status = (registeredfunc)(smhba_adapterportevents_callback, 4682 (void *)acbp, 4683 vendorHandle, 4684 portWWN, 4685 specificEventType, 4686 &acbp->vendorcbhandle); 4687 if (status != HBA_STATUS_OK) { 4688 free(acbp); 4689 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4690 } 4691 4692 GRAB_MUTEX(&_smhba_APE_mutex); 4693 acbp->next = _smhba_adapterportevents_callback_list; 4694 _smhba_adapterportevents_callback_list = acbp; 4695 4696 RELEASE_MUTEX(&_smhba_APE_mutex); 4697 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 4698 } 4699 4700 /* SMHBA Adapter Port Stat Events ******************************** */ 4701 static void 4702 smhba_adapterportstatevents_callback(void *data, 4703 HBA_WWN portWWN, 4704 HBA_UINT32 protocolType, 4705 HBA_UINT32 eventType) 4706 { 4707 HBA_ADAPTERCALLBACK_ELEM *acbp; 4708 4709 DEBUG(3, 4710 "SMBA_AdapterPortStateEvent, port:%s, eventType:%d", 4711 WWN2STR1(&portWWN), eventType, 0); 4712 4713 GRAB_MUTEX(&_smhba_APSE_mutex); 4714 for (acbp = _smhba_adapterportstatevents_callback_list; 4715 acbp != NULL; 4716 acbp = acbp->next) { 4717 if (data == (void *)acbp) { 4718 (*acbp->callback)(acbp->userdata, portWWN, 4719 protocolType, eventType); 4720 return; 4721 } 4722 } 4723 RELEASE_MUTEX(&_smhba_APSE_mutex); 4724 } 4725 4726 HBA_STATUS 4727 SMHBA_RegisterForAdapterPortStatEvents( 4728 void (*pCallback) ( 4729 void *pData, 4730 HBA_WWN portWWN, 4731 HBA_UINT32 protocolType, 4732 HBA_UINT32 eventType), 4733 void *pUserData, 4734 HBA_HANDLE handle, 4735 HBA_WWN portWWN, 4736 HBA_UINT32 protocolType, 4737 SMHBA_PROTOCOLSTATISTICS stats, 4738 HBA_UINT32 statType, 4739 HBA_CALLBACKHANDLE *pCallbackHandle) { 4740 4741 HBA_ADAPTERCALLBACK_ELEM *acbp; 4742 SMHBARegisterForAdapterPortStatEventsFunc 4743 registeredfunc; 4744 HBA_STATUS status; 4745 HBA_LIBRARY_INFO *lib_infop; 4746 HBA_HANDLE vendorHandle; 4747 4748 DEBUG(2, "SMHBA_RegisterForAdapterPortStatEvents for port: %s", 4749 WWN2STR1(&portWWN), 0, 0); 4750 4751 CHECKLIBRARYANDVERSION(SMHBA); 4752 /* we now have the _hbaapi_LL_mutex */ 4753 4754 registeredfunc = 4755 lib_infop->ftable.smhbafunctionTable.\ 4756 RegisterForAdapterPortStatEventsHandler; 4757 if (registeredfunc == NULL) { 4758 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 4759 } 4760 4761 /* 4762 * that allocated memory is used both as the handle for the 4763 * caller, and as userdata to the vendor call so that on 4764 * callback the specific registration may be recalled 4765 */ 4766 acbp = (HBA_ADAPTERCALLBACK_ELEM *) 4767 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM)); 4768 if (acbp == NULL) { 4769 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); 4770 } 4771 *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp; 4772 acbp->callback = pCallback; 4773 acbp->userdata = pUserData; 4774 acbp->lib_info = lib_infop; 4775 4776 status = (registeredfunc)(smhba_adapterportstatevents_callback, 4777 (void *)acbp, 4778 vendorHandle, 4779 portWWN, 4780 protocolType, 4781 stats, 4782 statType, 4783 &acbp->vendorcbhandle); 4784 if (status != HBA_STATUS_OK) { 4785 free(acbp); 4786 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4787 } 4788 4789 GRAB_MUTEX(&_smhba_APSE_mutex); 4790 acbp->next = _smhba_adapterportstatevents_callback_list; 4791 _smhba_adapterportstatevents_callback_list = acbp; 4792 4793 RELEASE_MUTEX(&_smhba_APSE_mutex); 4794 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 4795 } 4796 4797 /* SMHBA Adapter Port Phy Stat Events ************************************ */ 4798 static void 4799 smhba_adapterphystatevents_callback(void *data, 4800 HBA_WWN portWWN, 4801 HBA_UINT32 phyIndex, 4802 HBA_UINT32 eventType) 4803 { 4804 HBA_ADAPTERCALLBACK_ELEM *acbp; 4805 4806 DEBUG(3, 4807 "SMBA_AdapterPortStateEvent, port:%s, eventType:%d", 4808 WWN2STR1(&portWWN), eventType, 0); 4809 4810 GRAB_MUTEX(&_smhba_APHYSE_mutex); 4811 for (acbp = _smhba_adapterphystatevents_callback_list; 4812 acbp != NULL; 4813 acbp = acbp->next) { 4814 if (data == (void *)acbp) { 4815 (*acbp->callback)(acbp->userdata, portWWN, phyIndex, eventType); 4816 return; 4817 } 4818 } 4819 RELEASE_MUTEX(&_smhba_APHYSE_mutex); 4820 } 4821 4822 HBA_STATUS 4823 SMHBA_RegisterForAdapterPhyStatEvents( 4824 void (*pCallback) ( 4825 void *pData, 4826 HBA_WWN portWWN, 4827 HBA_UINT32 phyIndex, 4828 HBA_UINT32 eventType), 4829 void *pUserData, 4830 HBA_HANDLE handle, 4831 HBA_WWN portWWN, 4832 HBA_UINT32 phyIndex, 4833 SMHBA_PHYSTATISTICS stats, 4834 HBA_UINT32 statType, 4835 HBA_CALLBACKHANDLE *pCallbackHandle) { 4836 4837 HBA_ADAPTERCALLBACK_ELEM *acbp; 4838 SMHBARegisterForAdapterPhyStatEventsFunc 4839 registeredfunc; 4840 HBA_STATUS status; 4841 HBA_LIBRARY_INFO *lib_infop; 4842 HBA_HANDLE vendorHandle; 4843 4844 DEBUG(2, "SMHBA_RegisterForAdapterPhyStatEvents for port: %s", 4845 WWN2STR1(&portWWN), 0, 0); 4846 4847 CHECKLIBRARYANDVERSION(SMHBA); 4848 /* we now have the _hbaapi_LL_mutex */ 4849 4850 registeredfunc = 4851 lib_infop->ftable.smhbafunctionTable.\ 4852 RegisterForAdapterPhyStatEventsHandler; 4853 if (registeredfunc == NULL) { 4854 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 4855 } 4856 4857 /* 4858 * that allocated memory is used both as the handle for the 4859 * caller, and as userdata to the vendor call so that on 4860 * callback the specific registration may be recalled 4861 */ 4862 acbp = (HBA_ADAPTERCALLBACK_ELEM *) 4863 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM)); 4864 if (acbp == NULL) { 4865 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); 4866 } 4867 *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp; 4868 acbp->callback = pCallback; 4869 acbp->userdata = pUserData; 4870 acbp->lib_info = lib_infop; 4871 4872 status = (registeredfunc)(smhba_adapterphystatevents_callback, 4873 (void *)acbp, 4874 vendorHandle, 4875 portWWN, 4876 phyIndex, 4877 stats, 4878 statType, 4879 &acbp->vendorcbhandle); 4880 if (status != HBA_STATUS_OK) { 4881 free(acbp); 4882 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4883 } 4884 4885 GRAB_MUTEX(&_smhba_APHYSE_mutex); 4886 acbp->next = _smhba_adapterphystatevents_callback_list; 4887 _smhba_adapterphystatevents_callback_list = acbp; 4888 4889 RELEASE_MUTEX(&_smhba_APHYSE_mutex); 4890 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 4891 } 4892 4893 /* SMHBA Target Events ********************************************* */ 4894 static void 4895 smhba_targetevents_callback(void *data, 4896 HBA_WWN hbaPortWWN, 4897 HBA_WWN discoveredPortWWN, 4898 HBA_WWN domainPortWWN, 4899 HBA_UINT32 eventType) 4900 { 4901 HBA_ADAPTERCALLBACK_ELEM *acbp; 4902 4903 DEBUG(3, "TargetEvent, hbaPort:%s, discoveredPort:%s eventType:%d", 4904 WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), eventType); 4905 4906 GRAB_MUTEX(&_smhba_TE_mutex); 4907 for (acbp = _smhba_targetevents_callback_list; 4908 acbp != NULL; 4909 acbp = acbp->next) { 4910 if (data == (void *)acbp) { 4911 (*acbp->callback)(acbp->userdata, hbaPortWWN, 4912 discoveredPortWWN, domainPortWWN, eventType); 4913 break; 4914 } 4915 } 4916 RELEASE_MUTEX(&_smhba_TE_mutex); 4917 } 4918 4919 HBA_STATUS 4920 SMHBA_RegisterForTargetEvents( 4921 void (*pCallback) ( 4922 void *pData, 4923 HBA_WWN hbaPortWWN, 4924 HBA_WWN discoveredPortWWN, 4925 HBA_WWN domainPortWWN, 4926 HBA_UINT32 eventType), 4927 void *pUserData, 4928 HBA_HANDLE handle, 4929 HBA_WWN hbaPortWWN, 4930 HBA_WWN discoveredPortWWN, 4931 HBA_WWN domainPortWWN, 4932 HBA_CALLBACKHANDLE *pCallbackHandle, 4933 HBA_UINT32 allTargets) { 4934 4935 HBA_ADAPTERCALLBACK_ELEM *acbp; 4936 SMHBARegisterForTargetEventsFunc 4937 registeredfunc; 4938 HBA_STATUS status; 4939 HBA_LIBRARY_INFO *lib_infop; 4940 HBA_HANDLE vendorHandle; 4941 4942 DEBUG(2, "SMHBA_RegisterForTargetEvents, hbaPort:" 4943 "%s, discoveredPort: %s", 4944 WWN2STR1(&hbaPortWWN), WWN2STR2(&discoveredPortWWN), 0); 4945 4946 CHECKLIBRARYANDVERSION(SMHBA); 4947 /* we now have the _hbaapi_LL_mutex */ 4948 4949 registeredfunc = lib_infop->ftable.smhbafunctionTable.\ 4950 RegisterForTargetEventsHandler; 4951 4952 if (registeredfunc == NULL) { 4953 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 4954 } 4955 4956 /* 4957 * that allocated memory is used both as the handle for the 4958 * caller, and as userdata to the vendor call so that on 4959 * callback the specific registration may be recalled 4960 */ 4961 acbp = (HBA_ADAPTERCALLBACK_ELEM *) 4962 calloc(1, sizeof (HBA_ADAPTERCALLBACK_ELEM)); 4963 if (acbp == NULL) { 4964 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); 4965 } 4966 *pCallbackHandle = (HBA_CALLBACKHANDLE) acbp; 4967 acbp->callback = pCallback; 4968 acbp->userdata = pUserData; 4969 acbp->lib_info = lib_infop; 4970 4971 status = (registeredfunc)(smhba_targetevents_callback, 4972 (void *)acbp, 4973 vendorHandle, 4974 hbaPortWWN, 4975 discoveredPortWWN, 4976 domainPortWWN, 4977 &acbp->vendorcbhandle, 4978 allTargets); 4979 if (status != HBA_STATUS_OK) { 4980 free(acbp); 4981 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 4982 } 4983 4984 GRAB_MUTEX(&_smhba_TE_mutex); 4985 acbp->next = _smhba_targetevents_callback_list; 4986 _smhba_targetevents_callback_list = acbp; 4987 4988 RELEASE_MUTEX(&_smhba_TE_mutex); 4989 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 4990 } 4991