1 /************************************************************************* 2 * Description 3 * HBAAPILIB-sun.c - Implements the Sun Extention for Target mode 4 * FCHBA discovery 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 ************************************************************************* 19 */ 20 21 #ifdef WIN32 22 #include <windows.h> 23 #include <string.h> 24 /* 25 * Next define forces entry points in the dll to be exported 26 * See hbaapi.h to see what it does. 27 */ 28 #define HBAAPI_EXPORTS 29 #else 30 #include <dlfcn.h> 31 #include <strings.h> 32 #endif 33 #include <stdio.h> 34 #include <time.h> 35 #include <dlfcn.h> 36 #include "hbaapi.h" 37 #include "hbaapi-sun.h" 38 #include "vendorhbaapi.h" 39 #include <stdlib.h> 40 #ifdef USESYSLOG 41 #include <syslog.h> 42 #endif 43 44 45 /* 46 * LIBRARY_NUM is a shortcut to figure out which library we need to call. 47 * The top 16 bits of handle are the library index 48 */ 49 #define LIBRARY_NUM(handle) ((handle)>>16) 50 51 /* 52 * VENDOR_HANDLE turns a global library handle into a vendor specific handle, 53 * with all upper 16 bits set to 0 54 */ 55 #define VENDOR_HANDLE(handle) ((handle)&0xFFFF) 56 57 #define HBA_HANDLE_FROM_LOCAL(library, vendor) \ 58 (((library)<<16) | ((vendor)&0x0000FFFF)) 59 60 extern int _hbaapi_debuglevel; 61 #define DEBUG(L, STR, A1, A2, A3) 62 63 #if defined(USESYSLOG) && defined(USELOGFILE) 64 extern FILE *_hbaapi_debug_fd; 65 extern int _hbaapi_sysloginit; 66 #undef DEBUG 67 #ifdef WIN32 68 #define DEBUG(L, STR, A1, A2, A3)\ 69 if ((L) <= _hbaapi_debuglevel) {\ 70 if(_hbaapi_sysloginit == 0) {\ 71 openlog("HBAAPI", LOG_PID|LOG_ODELAY ,LOG_USER);\ 72 _hbaapi_sysloginit = 1;\ 73 }\ 74 syslog (LOG_INFO, (STR), (A1), (A2), (A3));\ 75 if(_hbaapi_debug_fd == NULL) {\ 76 char _logFile[MAX_PATH]; \ 77 GetTempPath(MAX_PATH, _logFile); \ 78 strcat(_logFile, "HBAAPI.log"); \ 79 _hbaapi_debug_fd = fopen(_logFile, "a");\ 80 }\ 81 if(_hbaapi_debug_fd != NULL) {\ 82 fprintf(_hbaapi_debug_fd, (STR ## "\n"), (A1), (A2), (A3));\ 83 }\ 84 } 85 #else /* WIN32*/ 86 #define DEBUG(L, STR, A1, A2, A3)\ 87 if ((L) <= _hbaapi_debuglevel) {\ 88 if(_hbaapi_sysloginit == 0) {\ 89 openlog("HBAAPI", LOG_PID|LOG_ODELAY ,LOG_USER);\ 90 _hbaapi_sysloginit = 1;\ 91 }\ 92 syslog (LOG_INFO, (STR), (A1), (A2), (A3));\ 93 if(_hbaapi_debug_fd == NULL) {\ 94 _hbaapi_debug_fd = fopen("/tmp/HBAAPI.log", "a");\ 95 }\ 96 if(_hbaapi_debug_fd != NULL) {\ 97 fprintf(_hbaapi_debug_fd, (STR ## "\n"), (A1), (A2), (A3));\ 98 }\ 99 } 100 #endif /* WIN32*/ 101 102 #else /* Not both USESYSLOG and USELOGFILE */ 103 #if defined(USESYSLOG) 104 int _hbaapi_sysloginit = 0; 105 #undef DEBUG 106 #define DEBUG(L, STR, A1, A2, A3) \ 107 if ((L) <= _hbaapi_debuglevel) {\ 108 if(_hbaapi_sysloginit == 0) {\ 109 openlog("HBAAPI", LOG_PID|LOG_ODELAY ,LOG_USER);\ 110 _hbaapi_sysloginit = 1;\ 111 }\ 112 syslog (LOG_INFO, (STR), (A1), (A2), (A3));\ 113 } 114 #endif /* USESYSLOG */ 115 #if defined(USELOGFILE) 116 FILE *_hbaapi_debug_fd = NULL; 117 #undef DEBUG 118 #ifdef WIN32 119 #define DEBUG(L, STR, A1, A2, A3) \ 120 if((L) <= _hbaapi_debuglevel) {\ 121 if(_hbaapi_debug_fd == NULL) {\ 122 char _logFile[MAX_PATH]; \ 123 GetTempPath(MAX_PATH, _logFile); \ 124 strcat(_logFile, "HBAAPI.log"); \ 125 _hbaapi_debug_fd = fopen(_logFile, "a");\ 126 }\ 127 } 128 #else /* WIN32 */ 129 #define DEBUG(L, STR, A1, A2, A3) \ 130 if((L) <= _hbaapi_debuglevel) {\ 131 if(_hbaapi_debug_fd == NULL) {\ 132 _hbaapi_debug_fd = fopen("/tmp/HBAAPI.log", "a");\ 133 }\ 134 if(_hbaapi_debug_fd != NULL) { \ 135 fprintf(_hbaapi_debug_fd, (STR) ## "\n", (A1), (A2), (A3));\ 136 }\ 137 } 138 #endif /* WIN32 */ 139 #endif /* USELOGFILE */ 140 #endif /* Not both USELOGFILE and USESYSLOG */ 141 142 #ifdef POSIX_THREADS 143 #include <pthread.h> 144 /* 145 * When multiple mutex's are grabed, they must be always be grabbed in 146 * the same order, or deadlock can result. There are three levels 147 * of mutex's involved in this API. If LL_mutex is grabbed, always grap 148 * it first. If AL_mutex is grabbed, it may not be grabbed before 149 * LL_mutex. If grabbed in a multi grab sequence, the mutex's protecting 150 * the callback lists must always be grabbed last and release before calling 151 * a vendor specific library function that might invoke a callback function 152 * on the same thread. 153 */ 154 #define GRAB_MUTEX(M) grab_mutex(M) 155 #define RELEASE_MUTEX(M) release_mutex(M) 156 #define RELEASE_MUTEX_RETURN(M,RET) release_mutex(M); return(RET) 157 #elif defined (WIN32) 158 #define GRAB_MUTEX(m) EnterCriticalSection(m) 159 #define RELEASE_MUTEX(m) LeaveCriticalSection(m) 160 #define RELEASE_MUTEX_RETURN(m, RET) LeaveCriticalSection(m); return(RET) 161 #else 162 #define GRAB_MUTEX(M) 163 #define RELEASE_MUTEX(M) 164 #define RELEASE_MUTEX_RETURN(M,RET) return(RET) 165 #endif 166 167 /* 168 * HBA_LIBRARY_STATUS and HBA_LIBRARY_INFO are redefined here. 169 * Avoid any change in the common code. 170 */ 171 typedef enum { 172 HBA_LIBRARY_UNKNOWN, 173 HBA_LIBRARY_LOADED, 174 HBA_LIBRARY_NOT_LOADED 175 } HBA_LIBRARY_STATUS; 176 177 typedef struct hba_library_info { 178 struct hba_library_info 179 *next; 180 #ifdef WIN32 181 HINSTANCE hLibrary; /* Handle to a loaded DLL */ 182 #else 183 char *LibraryName; 184 void* hLibrary; /* Handle to a loaded DLL */ 185 #endif 186 char *LibraryPath; 187 HBA_ENTRYPOINTSV2 functionTable; /* Function pointers */ 188 HBA_LIBRARY_STATUS status; /* info on this library */ 189 HBA_UINT32 index; 190 } HBA_LIBRARY_INFO, *PHBA_LIBRARY_INFO; 191 192 #define ARE_WE_INITED() \ 193 if (_hbaapi_librarylist == NULL) { \ 194 return(HBA_STATUS_ERROR); \ 195 } 196 197 extern HBA_LIBRARY_INFO *_hbaapi_librarylist; 198 extern HBA_UINT32 _hbaapi_total_library_count; 199 #ifdef POSIX_THREADS 200 extern pthread_mutex_t _hbaapi_LL_mutex; 201 #elif defined(WIN32) 202 extern CRITICAL_SECTION _hbaapi_LL_mutex; 203 #endif 204 205 /* 206 * Function type def fop Sun extentions. 207 */ 208 typedef HBA_UINT32 (* Sun_HBAGetNumberOfTgtAdaptersFunc)(); 209 typedef HBA_STATUS (* Sun_HBAGetTgtAdapterNameFunc)(HBA_UINT32, char *); 210 typedef HBA_HANDLE (* Sun_HBAOpenTgtAdapterFunc)(char *); 211 typedef HBA_STATUS (* Sun_HBAOpenTgtAdapterByWWNFunc) 212 (HBA_HANDLE *, HBA_WWN); 213 typedef HBA_STATUS (* Sun_HBANPIVGetAdapterAttributesFunc) 214 (HBA_HANDLE, HBA_ADAPTERATTRIBUTES *); 215 typedef HBA_STATUS (* Sun_HBAGetNPIVPortInfoFunc) 216 (HBA_HANDLE, HBA_UINT32, HBA_UINT32, HBA_NPIVATTRIBUTES *); 217 typedef HBA_STATUS (* Sun_HBADeleteNPIVPortFunc) 218 (HBA_HANDLE, HBA_UINT32, HBA_WWN); 219 typedef HBA_STATUS (* Sun_HBACreateNPIVPortFunc) 220 (HBA_HANDLE, HBA_UINT32, HBA_WWN, HBA_WWN, HBA_UINT32 *); 221 typedef HBA_STATUS (* Sun_HBAAdapterReturnWWNFunc) 222 (HBA_HANDLE, HBA_UINT32, HBA_WWN *, HBA_WWN *); 223 typedef HBA_STATUS (* Sun_HBAAdapterCreateWWNFunc) 224 (HBA_HANDLE, HBA_UINT32, HBA_WWN *, HBA_WWN *, HBA_WWN *, 225 HBA_INT32); 226 typedef HBA_STATUS (* Sun_HBAGetPortNPIVAttributesFunc) 227 (HBA_HANDLE, HBA_UINT32, HBA_PORTNPIVATTRIBUTES *); 228 typedef HBA_STATUS (* Sun_HBARegisterForAdapterDeviceEventsFunc) 229 (void (*)(void *, HBA_WWN, HBA_UINT32, HBA_UINT32), 230 void *, HBA_HANDLE, HBA_WWN, HBA_CALLBACKHANDLE *); 231 232 /* 233 * Individual adapter (hba) information 234 * Same as hbaadapter with different structure name. 235 */ 236 typedef struct hba_tgtadapter_info { 237 struct hba_tgtadapter_info 238 *next; 239 HBA_STATUS GNstatus; /* status from GetTgtAdapterNameFunc */ 240 char *name; 241 HBA_WWN nodeWWN; 242 HBA_LIBRARY_INFO *library; 243 HBA_UINT32 index; 244 } HBA_TGTADAPTER_INFO; 245 246 /* 247 * Make the list as an array with max size 16 248 */ 249 HBA_TGTADAPTER_INFO *_hbaapi_tgtadapterlist; 250 HBA_UINT32 _hbaapi_total_tgtadapter_count = 0; 251 #ifdef POSIX_THREADS 252 pthread_mutex_t _hbaapi_tgtAL_mutex = PTHREAD_MUTEX_INITIALIZER; 253 #elif defined(WIN32) 254 CRITICAL_SECTION _hbaapi_tgtAL_mutex; 255 #endif 256 257 /* 258 * Common library internal. Mutex handling 259 */ 260 #ifdef POSIX_THREADS 261 static void 262 grab_mutex(pthread_mutex_t *mp) { 263 int ret; 264 if((ret = pthread_mutex_lock(mp)) != 0) { 265 perror("pthread_mutex_lock - HBAAPI:"); 266 DEBUG(0, "pthread_mutex_lock returned %d", ret, 0, 0); 267 } 268 } 269 270 static void 271 release_mutex(pthread_mutex_t *mp) { 272 int ret; 273 if((ret = pthread_mutex_unlock(mp)) != 0) { 274 perror("pthread_mutex_unlock - HBAAPI:"); 275 DEBUG(0, "pthread_mutex_unlock returned %d", ret, 0, 0); 276 } 277 } 278 #endif 279 280 /* 281 * The API used to use fixed size tables as its primary data structure. 282 * Indexing from 1 to N identified each adapters. Now the adapters are 283 * on a linked list. There is a unique "index" foreach each adapter. 284 * Adapters always keep their index, even if they are removed from the 285 * hardware. The only time the indexing is reset is on HBA_FreeLibrary 286 */ 287 HBA_UINT32 288 Sun_HBA_GetNumberOfTgtAdapters() 289 { 290 int j=0; 291 HBA_LIBRARY_INFO *lib_infop; 292 Sun_HBAGetNumberOfTgtAdaptersFunc 293 GetNumberOfTgtAdaptersFunc = NULL; 294 Sun_HBAGetTgtAdapterNameFunc 295 GetTgtAdapterNameFunc = NULL; 296 HBA_BOOLEAN found_name; 297 HBA_TGTADAPTER_INFO *adapt_infop; 298 HBA_STATUS status; 299 300 char adaptername[256]; 301 int num_adapters; /* local */ 302 303 if(_hbaapi_librarylist == NULL) { 304 return (0); 305 } 306 GRAB_MUTEX(&_hbaapi_LL_mutex); /* pay attention to order */ 307 GRAB_MUTEX(&_hbaapi_tgtAL_mutex); 308 309 for (lib_infop = _hbaapi_librarylist; 310 lib_infop != NULL; 311 lib_infop = lib_infop->next) { 312 313 if (lib_infop->status != HBA_LIBRARY_LOADED) { 314 continue; 315 } 316 317 if (lib_infop->hLibrary != NULL) { 318 GetNumberOfTgtAdaptersFunc = (Sun_HBAGetNumberOfTgtAdaptersFunc) 319 dlsym(lib_infop->hLibrary, "Sun_fcGetNumberOfTgtAdapters"); 320 GetTgtAdapterNameFunc = (Sun_HBAGetTgtAdapterNameFunc) 321 dlsym(lib_infop->hLibrary, "Sun_fcGetTgtAdapterName"); 322 if (GetNumberOfTgtAdaptersFunc == NULL || 323 GetTgtAdapterNameFunc == NULL) { 324 GetNumberOfTgtAdaptersFunc = GetTgtAdapterNameFunc = NULL; 325 continue; 326 } 327 } else { 328 continue; 329 } 330 331 num_adapters = ((GetNumberOfTgtAdaptersFunc)()); 332 #ifndef WIN32 333 DEBUG(1, "HBAAPI: number of target mode adapters for %s = %d\n", 334 lib_infop->LibraryName, num_adapters, 0); 335 #else 336 DEBUG(1, "HBAAPI: number of target mode_adapters for %s = %d\n", 337 lib_infop->LibraryPath, num_adapters, 0); 338 #endif 339 340 for (j = 0; j < num_adapters; j++) { 341 found_name = 0; 342 status = (GetTgtAdapterNameFunc)(j, (char *)&adaptername); 343 if(status == HBA_STATUS_OK) { 344 for(adapt_infop = _hbaapi_tgtadapterlist; 345 adapt_infop != NULL; 346 adapt_infop = adapt_infop->next) { 347 /* 348 * check for duplicates, really, this may just be a second 349 * call to this function 350 * ??? how do we know when a name becomes stale? 351 */ 352 if(strcmp(adaptername, adapt_infop->name) == 0) { 353 /* already got this one */ 354 found_name++; 355 break; 356 } 357 } 358 if(found_name != 0) { 359 continue; 360 } 361 } 362 363 adapt_infop = (HBA_TGTADAPTER_INFO *) 364 calloc(1, sizeof(HBA_TGTADAPTER_INFO)); 365 if(adapt_infop == NULL) { 366 #ifndef WIN32 367 fprintf(stderr, 368 "HBA_GetNumberOfAdapters: calloc failed on sizeof:%d\n", 369 sizeof(HBA_TGTADAPTER_INFO)); 370 #endif 371 RELEASE_MUTEX(&_hbaapi_tgtAL_mutex); 372 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, 373 _hbaapi_total_tgtadapter_count); 374 } 375 if((adapt_infop->GNstatus = status) == HBA_STATUS_OK) { 376 adapt_infop->name = strdup(adaptername); 377 } else { 378 char dummyname[512]; 379 sprintf(dummyname, "NULLADAPTER-%s-%03d", 380 lib_infop->LibraryPath, _hbaapi_total_tgtadapter_count); 381 dummyname[255] = '\0'; 382 adapt_infop->name = strdup(dummyname); 383 } 384 adapt_infop->library = lib_infop; 385 adapt_infop->next = _hbaapi_tgtadapterlist; 386 adapt_infop->index = _hbaapi_total_tgtadapter_count; 387 _hbaapi_tgtadapterlist = adapt_infop; 388 _hbaapi_total_tgtadapter_count++; 389 } 390 GetNumberOfTgtAdaptersFunc = GetTgtAdapterNameFunc = NULL; 391 } 392 RELEASE_MUTEX(&_hbaapi_tgtAL_mutex); 393 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, _hbaapi_total_tgtadapter_count); 394 } 395 396 HBA_STATUS 397 Sun_HBA_GetTgtAdapterName( 398 HBA_UINT32 adapterindex, 399 char *adaptername) 400 { 401 HBA_TGTADAPTER_INFO *adapt_infop; 402 HBA_STATUS ret = HBA_STATUS_ERROR_ILLEGAL_INDEX; 403 404 if (adaptername == NULL) { 405 return(HBA_STATUS_ERROR_ARG); 406 } 407 /* 408 * The adapter index is from old code, but we have 409 * to support it. Go down the list looking for 410 * the adapter 411 */ 412 ARE_WE_INITED(); 413 GRAB_MUTEX(&_hbaapi_tgtAL_mutex); 414 *adaptername = '\0'; 415 for(adapt_infop = _hbaapi_tgtadapterlist; 416 adapt_infop != NULL; 417 adapt_infop = adapt_infop->next) { 418 419 if(adapt_infop->index == adapterindex) { 420 if(adapt_infop->name != NULL && 421 adapt_infop->GNstatus == HBA_STATUS_OK) { 422 strcpy(adaptername, adapt_infop->name); 423 } else { 424 *adaptername = '\0'; 425 } 426 ret = adapt_infop->GNstatus; 427 break; 428 } 429 } 430 DEBUG(2, "GetAdapterName for index:%d ->%s", adapterindex, adaptername, 0); 431 RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, ret); 432 } 433 434 HBA_HANDLE 435 Sun_HBA_OpenTgtAdapter(char* adaptername) 436 { 437 HBA_HANDLE handle; 438 Sun_HBAOpenTgtAdapterFunc OpenTgtAdapterFunc; 439 HBA_TGTADAPTER_INFO *adapt_infop; 440 HBA_LIBRARY_INFO *lib_infop; 441 442 DEBUG(2, "OpenAdapter: %s", adaptername, 0, 0); 443 444 if(_hbaapi_librarylist == NULL) { 445 return(HBA_HANDLE_INVALID); 446 } 447 if (adaptername == NULL) { 448 return(HBA_STATUS_ERROR_ARG); 449 } 450 handle = HBA_HANDLE_INVALID; 451 GRAB_MUTEX(&_hbaapi_AL_mutex); 452 for(adapt_infop = _hbaapi_tgtadapterlist; 453 adapt_infop != NULL; 454 adapt_infop = adapt_infop->next) { 455 if (strcmp(adaptername, adapt_infop->name) != 0) { 456 continue; 457 } 458 lib_infop = adapt_infop->library; 459 OpenTgtAdapterFunc = (Sun_HBAOpenTgtAdapterFunc) 460 dlsym(lib_infop->hLibrary, "Sun_fcOpenTgtAdapter"); 461 if (OpenTgtAdapterFunc != NULL) { 462 /* retrieve the vendor handle */ 463 handle = (OpenTgtAdapterFunc)(adaptername); 464 if(handle != 0) { 465 /* or this with the library index to get the common handle */ 466 handle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle); 467 } 468 } 469 break; 470 } 471 RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, handle); 472 } 473 474 /* 475 * This function ignores the list of known adapters and instead tries 476 * each vendors open function to see if one of them 477 * can open an adapter when referenced with a particular WWN 478 */ 479 HBA_STATUS 480 Sun_HBA_OpenTgtAdapterByWWN(HBA_HANDLE *phandle, HBA_WWN nodeWWN) 481 { 482 HBA_HANDLE handle; 483 HBA_LIBRARY_INFO *lib_infop; 484 Sun_HBAGetNumberOfTgtAdaptersFunc 485 GetNumberOfTgtAdaptersFunc; 486 Sun_HBAOpenTgtAdapterByWWNFunc 487 OpenTgtAdapterByWWNFunc; 488 HBA_STATUS status; 489 490 DEBUG(2, "OpenAdapterByWWN: %s", WWN2STR1(&nodeWWN), 0, 0); 491 492 if (phandle == NULL) { 493 return(HBA_STATUS_ERROR_ARG); 494 } 495 496 ARE_WE_INITED(); 497 498 *phandle = HBA_HANDLE_INVALID; 499 500 GRAB_MUTEX(&_hbaapi_LL_mutex); 501 for (lib_infop = _hbaapi_librarylist; 502 lib_infop != NULL; 503 lib_infop = lib_infop->next) { 504 505 status = HBA_STATUS_ERROR_ILLEGAL_WWN; 506 507 if (lib_infop->status != HBA_LIBRARY_LOADED) { 508 continue; 509 } 510 511 GetNumberOfTgtAdaptersFunc = (Sun_HBAGetNumberOfTgtAdaptersFunc) 512 dlsym(lib_infop->hLibrary, "Sun_fcGetNumberOfTgtAdapters"); 513 OpenTgtAdapterByWWNFunc = (Sun_HBAOpenTgtAdapterByWWNFunc) 514 dlsym(lib_infop->hLibrary, "Sun_fcOpenTgtAdapterByWWN"); 515 if (GetNumberOfTgtAdaptersFunc == NULL || 516 OpenTgtAdapterByWWNFunc == NULL) { 517 GetNumberOfTgtAdaptersFunc = OpenTgtAdapterByWWNFunc = NULL; 518 continue; 519 } 520 521 (void) ((GetNumberOfTgtAdaptersFunc)()); 522 523 if((status = (OpenTgtAdapterByWWNFunc)(&handle, nodeWWN)) 524 != HBA_STATUS_OK) { 525 GetNumberOfTgtAdaptersFunc = OpenTgtAdapterByWWNFunc = NULL; 526 continue; 527 } 528 /* OK, make a vendor non-specific handle */ 529 *phandle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle); 530 status = HBA_STATUS_OK; 531 break; 532 533 GetNumberOfTgtAdaptersFunc = OpenTgtAdapterByWWNFunc = NULL; 534 } 535 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 536 } 537 538 static HBA_STATUS 539 HBA_NPIV_CheckLibrary(HBA_HANDLE handle, 540 HBA_LIBRARY_INFO **lib_infopp, 541 HBA_HANDLE *vendorhandle) { 542 HBA_UINT32 libraryIndex; 543 HBA_LIBRARY_INFO *lib_infop; 544 545 if (vendorhandle == NULL) { 546 return(HBA_STATUS_ERROR_ARG); 547 } 548 if(_hbaapi_librarylist == NULL) { 549 return(HBA_STATUS_ERROR); 550 } 551 libraryIndex = LIBRARY_NUM(handle); 552 553 GRAB_MUTEX(&_hbaapi_LL_mutex); 554 for(lib_infop = _hbaapi_librarylist; 555 lib_infop != NULL; 556 lib_infop = lib_infop->next) { 557 if(lib_infop->index == libraryIndex) { 558 if(lib_infop->status != HBA_LIBRARY_LOADED) { 559 return HBA_STATUS_ERROR; 560 } 561 *lib_infopp = lib_infop; 562 *vendorhandle = VENDOR_HANDLE(handle); 563 /* caller will release the mutex */ 564 return HBA_STATUS_OK; 565 } 566 } 567 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INVALID_HANDLE); 568 } 569 #define NPIVCHECKLIBRARY() \ 570 status = HBA_NPIV_CheckLibrary(handle, &lib_infop, &vendorHandle); \ 571 if(status != HBA_STATUS_OK) { \ 572 return(status); \ 573 } 574 575 HBA_STATUS 576 Sun_HBA_NPIVGetAdapterAttributes ( 577 HBA_HANDLE handle, 578 HBA_ADAPTERATTRIBUTES 579 *hbaattributes) 580 { 581 HBA_STATUS status; 582 HBA_LIBRARY_INFO *lib_infop; 583 HBA_HANDLE vendorHandle; 584 Sun_HBANPIVGetAdapterAttributesFunc NPIVGetAdapterAttributesFunc; 585 586 DEBUG(2, "HBA_NPIVGetAdapterAttributes", 0, 0, 0); 587 588 NPIVCHECKLIBRARY(); 589 NPIVGetAdapterAttributesFunc = (Sun_HBANPIVGetAdapterAttributesFunc) 590 dlsym(lib_infop->hLibrary, "Sun_fcNPIVGetAdapterAttributes"); 591 if (NPIVGetAdapterAttributesFunc != NULL) { 592 status = ((NPIVGetAdapterAttributesFunc)(vendorHandle, 593 hbaattributes)); 594 } else { 595 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 596 } 597 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 598 } 599 600 HBA_STATUS 601 Sun_HBA_GetNPIVPortInfo ( 602 HBA_HANDLE handle, 603 HBA_UINT32 portindex, 604 HBA_UINT32 vportindex, 605 HBA_NPIVATTRIBUTES *attributes) 606 { 607 HBA_STATUS status; 608 HBA_LIBRARY_INFO *lib_infop; 609 HBA_HANDLE vendorHandle; 610 Sun_HBAGetNPIVPortInfoFunc GetNPIVPortInfoFunc; 611 612 NPIVCHECKLIBRARY(); 613 GetNPIVPortInfoFunc = (Sun_HBAGetNPIVPortInfoFunc) 614 dlsym(lib_infop->hLibrary, "Sun_fcGetNPIVPortInfo"); 615 if (GetNPIVPortInfoFunc != NULL) { 616 status = ((GetNPIVPortInfoFunc)(vendorHandle, portindex, 617 vportindex, attributes)); 618 } else { 619 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 620 } 621 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 622 } 623 624 HBA_STATUS 625 Sun_HBA_DeleteNPIVPort ( 626 HBA_HANDLE handle, 627 HBA_UINT32 portindex, 628 HBA_WWN vportWWN) 629 { 630 HBA_STATUS status; 631 HBA_LIBRARY_INFO *lib_infop; 632 HBA_HANDLE vendorHandle; 633 Sun_HBADeleteNPIVPortFunc DeleteNPIVPortFunc; 634 635 NPIVCHECKLIBRARY(); 636 DeleteNPIVPortFunc = (Sun_HBADeleteNPIVPortFunc) 637 dlsym(lib_infop->hLibrary, "Sun_fcDeleteNPIVPort"); 638 if (DeleteNPIVPortFunc != NULL) { 639 status = ((DeleteNPIVPortFunc)(vendorHandle, 640 portindex, vportWWN)); 641 } else { 642 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 643 } 644 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 645 } 646 647 HBA_STATUS 648 Sun_HBA_CreateNPIVPort ( 649 HBA_HANDLE handle, 650 HBA_UINT32 portindex, 651 HBA_WWN vnodeWWN, 652 HBA_WWN vportWWN, 653 HBA_UINT32 *vportindex) 654 { 655 HBA_STATUS status; 656 HBA_LIBRARY_INFO *lib_infop; 657 HBA_HANDLE vendorHandle; 658 Sun_HBACreateNPIVPortFunc CreateNPIVPortFunc; 659 660 NPIVCHECKLIBRARY(); 661 CreateNPIVPortFunc = (Sun_HBACreateNPIVPortFunc) 662 dlsym(lib_infop->hLibrary, "Sun_fcCreateNPIVPort"); 663 if (CreateNPIVPortFunc != NULL) { 664 status = ((CreateNPIVPortFunc)(vendorHandle, 665 portindex, vnodeWWN, vportWWN, vportindex)); 666 } else { 667 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 668 } 669 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 670 } 671 672 HBA_STATUS 673 Sun_HBA_GetPortNPIVAttributes ( 674 HBA_HANDLE handle, 675 HBA_UINT32 portindex, 676 HBA_PORTNPIVATTRIBUTES *portnpivattributes) 677 { 678 HBA_STATUS status; 679 HBA_LIBRARY_INFO *lib_infop; 680 HBA_HANDLE vendorHandle; 681 Sun_HBAGetPortNPIVAttributesFunc GetPortNPIVAttributesFunc; 682 683 NPIVCHECKLIBRARY(); 684 GetPortNPIVAttributesFunc = (Sun_HBAGetPortNPIVAttributesFunc) 685 dlsym(lib_infop->hLibrary, "Sun_fcGetPortNPIVAttributes"); 686 if (GetPortNPIVAttributesFunc != NULL) { 687 status = ((GetPortNPIVAttributesFunc)( 688 vendorHandle, portindex, portnpivattributes)); 689 } else { 690 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 691 } 692 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 693 } 694 695 HBA_STATUS 696 Sun_HBA_AdapterCreateWWN ( 697 HBA_HANDLE handle, 698 HBA_UINT32 portindex, 699 HBA_WWN *nwwn, 700 HBA_WWN *pwwn, 701 HBA_WWN *OUI, 702 HBA_INT32 method) 703 { 704 HBA_STATUS status; 705 HBA_LIBRARY_INFO *lib_infop; 706 HBA_HANDLE vendorHandle; 707 Sun_HBAAdapterCreateWWNFunc AdapterCreateWWNFunc; 708 709 NPIVCHECKLIBRARY(); 710 AdapterCreateWWNFunc = (Sun_HBAAdapterCreateWWNFunc) 711 dlsym(lib_infop->hLibrary, "Sun_fcAdapterCreateWWN"); 712 if (AdapterCreateWWNFunc != NULL) { 713 status = ((AdapterCreateWWNFunc)(vendorHandle, 714 portindex, nwwn, pwwn, OUI, method)); 715 } else { 716 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 717 } 718 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 719 } 720 721 HBA_STATUS 722 Sun_HBA_AdapterReturnWWN ( 723 HBA_HANDLE handle, 724 HBA_UINT32 portindex, 725 HBA_WWN *nwwn, 726 HBA_WWN *pwwn) 727 { 728 HBA_STATUS status; 729 HBA_LIBRARY_INFO *lib_infop; 730 HBA_HANDLE vendorHandle; 731 Sun_HBAAdapterReturnWWNFunc AdapterReturnWWNFunc; 732 733 NPIVCHECKLIBRARY(); 734 AdapterReturnWWNFunc = (Sun_HBAAdapterReturnWWNFunc) 735 dlsym(lib_infop->hLibrary, "Sun_fcAdapterReturnWWN"); 736 if (AdapterReturnWWNFunc != NULL) { 737 status = ((AdapterReturnWWNFunc)(vendorHandle, 738 portindex, nwwn, pwwn)); 739 } else { 740 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 741 } 742 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 743 } 744 745 typedef struct hba_npivadaptercallback_elem { 746 struct hba_npivadaptercallback_elem 747 *next; 748 HBA_LIBRARY_INFO *lib_info; 749 void *userdata; 750 HBA_CALLBACKHANDLE vendorcbhandle; 751 void (*callback)(); 752 } HBA_NPIVADAPTERCALLBACK_ELEM; 753 extern HBA_NPIVADAPTERCALLBACK_ELEM *_hbaapi_adapterdeviceevents_callback_list; 754 755 /* Adapter Device Events ********************************************************/ 756 static void 757 adapterdeviceevents_callback (void *data, 758 HBA_WWN PortWWN, 759 HBA_UINT32 eventType, 760 HBA_UINT32 fabricPortID) 761 { 762 HBA_NPIVADAPTERCALLBACK_ELEM *acbp; 763 764 DEBUG(3, "AdapterDeviceEvent, port:%s, eventType:%d fabricPortID:0X%06x", 765 WWN2STR1(&PortWWN), eventType, fabricPortID); 766 767 GRAB_MUTEX(&_hbaapi_APE_mutex); 768 769 for(acbp = _hbaapi_adapterdeviceevents_callback_list; 770 acbp != NULL; 771 acbp = acbp->next) { 772 if(data == (void *)acbp) { 773 (*acbp->callback)(acbp->userdata, PortWWN, eventType, fabricPortID); 774 break; 775 } 776 } 777 RELEASE_MUTEX(&_hbaapi_APE_mutex); 778 } 779 780 HBA_STATUS 781 Sun_HBA_RegisterForAdapterDeviceEvents ( 782 void (*callback) ( 783 void *data, 784 HBA_WWN PortWWN, 785 HBA_UINT32 eventType, 786 HBA_UINT32 fabricPortID 787 ), 788 void *userData, 789 HBA_HANDLE handle, 790 HBA_WWN PortWWN, 791 HBA_CALLBACKHANDLE *callbackHandle) 792 { 793 HBA_NPIVADAPTERCALLBACK_ELEM *acbp; 794 HBA_STATUS status; 795 HBA_LIBRARY_INFO *lib_infop; 796 HBA_HANDLE vendorHandle; 797 Sun_HBARegisterForAdapterDeviceEventsFunc 798 registeredfunc; 799 800 if (callbackHandle == NULL) { 801 return(HBA_STATUS_ERROR_ARG); 802 } 803 804 NPIVCHECKLIBRARY(); 805 registeredfunc = (Sun_HBARegisterForAdapterDeviceEventsFunc) 806 dlsym(lib_infop->hLibrary, 807 "Sun_fcRegisterForAdapterDeviceEvents"); 808 if (registeredfunc == NULL) { 809 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 810 } 811 812 acbp = (HBA_NPIVADAPTERCALLBACK_ELEM *) 813 calloc(1, sizeof(HBA_NPIVADAPTERCALLBACK_ELEM)); 814 815 if(acbp == NULL) { 816 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); 817 } 818 819 *callbackHandle = (HBA_CALLBACKHANDLE) acbp; 820 acbp->callback = callback; 821 acbp->userdata = userData; 822 acbp->lib_info = lib_infop; 823 824 status = (registeredfunc)(adapterdeviceevents_callback, 825 (void *)acbp, 826 vendorHandle, 827 PortWWN, 828 &acbp->vendorcbhandle); 829 if(status != HBA_STATUS_OK) { 830 free(acbp); 831 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 832 } 833 834 GRAB_MUTEX(&_hbaapi_APE_mutex); 835 acbp->next = _hbaapi_adapterdeviceevents_callback_list; 836 _hbaapi_adapterdeviceevents_callback_list = acbp; 837 RELEASE_MUTEX(&_hbaapi_APE_mutex); 838 839 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 840 } 841