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