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 2009 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 typedef HBA_STATUS (* Sun_HBADoForceLipFunc)(HBA_HANDLE, int *); 236 237 /* 238 * Individual adapter (hba) information 239 * Same as hbaadapter with different structure name. 240 */ 241 typedef struct hba_tgtadapter_info { 242 struct hba_tgtadapter_info 243 *next; 244 HBA_STATUS GNstatus; /* status from GetTgtAdapterNameFunc */ 245 char *name; 246 HBA_WWN nodeWWN; 247 HBA_LIBRARY_INFO *library; 248 HBA_UINT32 index; 249 } HBA_TGTADAPTER_INFO; 250 251 /* 252 * Make the list as an array with max size 16 253 */ 254 HBA_TGTADAPTER_INFO *_hbaapi_tgtadapterlist; 255 HBA_UINT32 _hbaapi_total_tgtadapter_count = 0; 256 #ifdef POSIX_THREADS 257 pthread_mutex_t _hbaapi_tgtAL_mutex = PTHREAD_MUTEX_INITIALIZER; 258 #elif defined(WIN32) 259 CRITICAL_SECTION _hbaapi_tgtAL_mutex; 260 #endif 261 262 /* 263 * Common library internal. Mutex handling 264 */ 265 #ifdef POSIX_THREADS 266 static void 267 grab_mutex(pthread_mutex_t *mp) { 268 int ret; 269 if((ret = pthread_mutex_lock(mp)) != 0) { 270 perror("pthread_mutex_lock - HBAAPI:"); 271 DEBUG(0, "pthread_mutex_lock returned %d", ret, 0, 0); 272 } 273 } 274 275 static void 276 release_mutex(pthread_mutex_t *mp) { 277 int ret; 278 if((ret = pthread_mutex_unlock(mp)) != 0) { 279 perror("pthread_mutex_unlock - HBAAPI:"); 280 DEBUG(0, "pthread_mutex_unlock returned %d", ret, 0, 0); 281 } 282 } 283 #endif 284 285 /* 286 * The API used to use fixed size tables as its primary data structure. 287 * Indexing from 1 to N identified each adapters. Now the adapters are 288 * on a linked list. There is a unique "index" foreach each adapter. 289 * Adapters always keep their index, even if they are removed from the 290 * hardware. The only time the indexing is reset is on HBA_FreeLibrary 291 */ 292 HBA_UINT32 293 Sun_HBA_GetNumberOfTgtAdapters() 294 { 295 int j=0; 296 HBA_LIBRARY_INFO *lib_infop; 297 Sun_HBAGetNumberOfTgtAdaptersFunc 298 GetNumberOfTgtAdaptersFunc = NULL; 299 Sun_HBAGetTgtAdapterNameFunc 300 GetTgtAdapterNameFunc = NULL; 301 HBA_BOOLEAN found_name; 302 HBA_TGTADAPTER_INFO *adapt_infop; 303 HBA_STATUS status; 304 305 char adaptername[256]; 306 int num_adapters; /* local */ 307 308 if(_hbaapi_librarylist == NULL) { 309 return (0); 310 } 311 GRAB_MUTEX(&_hbaapi_LL_mutex); /* pay attention to order */ 312 GRAB_MUTEX(&_hbaapi_tgtAL_mutex); 313 314 for (lib_infop = _hbaapi_librarylist; 315 lib_infop != NULL; 316 lib_infop = lib_infop->next) { 317 318 if (lib_infop->status != HBA_LIBRARY_LOADED) { 319 continue; 320 } 321 322 if (lib_infop->hLibrary != NULL) { 323 GetNumberOfTgtAdaptersFunc = (Sun_HBAGetNumberOfTgtAdaptersFunc) 324 dlsym(lib_infop->hLibrary, "Sun_fcGetNumberOfTgtAdapters"); 325 GetTgtAdapterNameFunc = (Sun_HBAGetTgtAdapterNameFunc) 326 dlsym(lib_infop->hLibrary, "Sun_fcGetTgtAdapterName"); 327 if (GetNumberOfTgtAdaptersFunc == NULL || 328 GetTgtAdapterNameFunc == NULL) { 329 GetNumberOfTgtAdaptersFunc = GetTgtAdapterNameFunc = NULL; 330 continue; 331 } 332 } else { 333 continue; 334 } 335 336 num_adapters = ((GetNumberOfTgtAdaptersFunc)()); 337 #ifndef WIN32 338 DEBUG(1, "HBAAPI: number of target mode adapters for %s = %d\n", 339 lib_infop->LibraryName, num_adapters, 0); 340 #else 341 DEBUG(1, "HBAAPI: number of target mode_adapters for %s = %d\n", 342 lib_infop->LibraryPath, num_adapters, 0); 343 #endif 344 345 for (j = 0; j < num_adapters; j++) { 346 found_name = 0; 347 status = (GetTgtAdapterNameFunc)(j, (char *)&adaptername); 348 if(status == HBA_STATUS_OK) { 349 for(adapt_infop = _hbaapi_tgtadapterlist; 350 adapt_infop != NULL; 351 adapt_infop = adapt_infop->next) { 352 /* 353 * check for duplicates, really, this may just be a second 354 * call to this function 355 * ??? how do we know when a name becomes stale? 356 */ 357 if(strcmp(adaptername, adapt_infop->name) == 0) { 358 /* already got this one */ 359 found_name++; 360 break; 361 } 362 } 363 if(found_name != 0) { 364 continue; 365 } 366 } 367 368 adapt_infop = (HBA_TGTADAPTER_INFO *) 369 calloc(1, sizeof(HBA_TGTADAPTER_INFO)); 370 if(adapt_infop == NULL) { 371 #ifndef WIN32 372 fprintf(stderr, 373 "HBA_GetNumberOfAdapters: calloc failed on sizeof:%d\n", 374 sizeof(HBA_TGTADAPTER_INFO)); 375 #endif 376 RELEASE_MUTEX(&_hbaapi_tgtAL_mutex); 377 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, 378 _hbaapi_total_tgtadapter_count); 379 } 380 if((adapt_infop->GNstatus = status) == HBA_STATUS_OK) { 381 adapt_infop->name = strdup(adaptername); 382 } else { 383 char dummyname[512]; 384 sprintf(dummyname, "NULLADAPTER-%s-%03d", 385 lib_infop->LibraryPath, _hbaapi_total_tgtadapter_count); 386 dummyname[255] = '\0'; 387 adapt_infop->name = strdup(dummyname); 388 } 389 adapt_infop->library = lib_infop; 390 adapt_infop->next = _hbaapi_tgtadapterlist; 391 adapt_infop->index = _hbaapi_total_tgtadapter_count; 392 _hbaapi_tgtadapterlist = adapt_infop; 393 _hbaapi_total_tgtadapter_count++; 394 } 395 GetNumberOfTgtAdaptersFunc = GetTgtAdapterNameFunc = NULL; 396 } 397 RELEASE_MUTEX(&_hbaapi_tgtAL_mutex); 398 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, _hbaapi_total_tgtadapter_count); 399 } 400 401 HBA_STATUS 402 Sun_HBA_GetTgtAdapterName( 403 HBA_UINT32 adapterindex, 404 char *adaptername) 405 { 406 HBA_TGTADAPTER_INFO *adapt_infop; 407 HBA_STATUS ret = HBA_STATUS_ERROR_ILLEGAL_INDEX; 408 409 if (adaptername == NULL) { 410 return(HBA_STATUS_ERROR_ARG); 411 } 412 /* 413 * The adapter index is from old code, but we have 414 * to support it. Go down the list looking for 415 * the adapter 416 */ 417 ARE_WE_INITED(); 418 GRAB_MUTEX(&_hbaapi_tgtAL_mutex); 419 *adaptername = '\0'; 420 for(adapt_infop = _hbaapi_tgtadapterlist; 421 adapt_infop != NULL; 422 adapt_infop = adapt_infop->next) { 423 424 if(adapt_infop->index == adapterindex) { 425 if(adapt_infop->name != NULL && 426 adapt_infop->GNstatus == HBA_STATUS_OK) { 427 strcpy(adaptername, adapt_infop->name); 428 } else { 429 *adaptername = '\0'; 430 } 431 ret = adapt_infop->GNstatus; 432 break; 433 } 434 } 435 DEBUG(2, "GetAdapterName for index:%d ->%s", adapterindex, adaptername, 0); 436 RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, ret); 437 } 438 439 HBA_HANDLE 440 Sun_HBA_OpenTgtAdapter(char* adaptername) 441 { 442 HBA_HANDLE handle; 443 Sun_HBAOpenTgtAdapterFunc OpenTgtAdapterFunc; 444 HBA_TGTADAPTER_INFO *adapt_infop; 445 HBA_LIBRARY_INFO *lib_infop; 446 447 DEBUG(2, "OpenAdapter: %s", adaptername, 0, 0); 448 449 if(_hbaapi_librarylist == NULL) { 450 return(HBA_HANDLE_INVALID); 451 } 452 if (adaptername == NULL) { 453 return(HBA_STATUS_ERROR_ARG); 454 } 455 handle = HBA_HANDLE_INVALID; 456 GRAB_MUTEX(&_hbaapi_AL_mutex); 457 for(adapt_infop = _hbaapi_tgtadapterlist; 458 adapt_infop != NULL; 459 adapt_infop = adapt_infop->next) { 460 if (strcmp(adaptername, adapt_infop->name) != 0) { 461 continue; 462 } 463 lib_infop = adapt_infop->library; 464 OpenTgtAdapterFunc = (Sun_HBAOpenTgtAdapterFunc) 465 dlsym(lib_infop->hLibrary, "Sun_fcOpenTgtAdapter"); 466 if (OpenTgtAdapterFunc != NULL) { 467 /* retrieve the vendor handle */ 468 handle = (OpenTgtAdapterFunc)(adaptername); 469 if(handle != 0) { 470 /* or this with the library index to get the common handle */ 471 handle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle); 472 } 473 } 474 break; 475 } 476 RELEASE_MUTEX_RETURN(&_hbaapi_AL_mutex, handle); 477 } 478 479 /* 480 * This function ignores the list of known adapters and instead tries 481 * each vendors open function to see if one of them 482 * can open an adapter when referenced with a particular WWN 483 */ 484 HBA_STATUS 485 Sun_HBA_OpenTgtAdapterByWWN(HBA_HANDLE *phandle, HBA_WWN nodeWWN) 486 { 487 HBA_HANDLE handle; 488 HBA_LIBRARY_INFO *lib_infop; 489 Sun_HBAGetNumberOfTgtAdaptersFunc 490 GetNumberOfTgtAdaptersFunc; 491 Sun_HBAOpenTgtAdapterByWWNFunc 492 OpenTgtAdapterByWWNFunc; 493 HBA_STATUS status; 494 495 DEBUG(2, "OpenAdapterByWWN: %s", WWN2STR1(&nodeWWN), 0, 0); 496 497 if (phandle == NULL) { 498 return(HBA_STATUS_ERROR_ARG); 499 } 500 501 ARE_WE_INITED(); 502 503 *phandle = HBA_HANDLE_INVALID; 504 505 GRAB_MUTEX(&_hbaapi_LL_mutex); 506 for (lib_infop = _hbaapi_librarylist; 507 lib_infop != NULL; 508 lib_infop = lib_infop->next) { 509 510 status = HBA_STATUS_ERROR_ILLEGAL_WWN; 511 512 if (lib_infop->status != HBA_LIBRARY_LOADED) { 513 continue; 514 } 515 516 GetNumberOfTgtAdaptersFunc = (Sun_HBAGetNumberOfTgtAdaptersFunc) 517 dlsym(lib_infop->hLibrary, "Sun_fcGetNumberOfTgtAdapters"); 518 OpenTgtAdapterByWWNFunc = (Sun_HBAOpenTgtAdapterByWWNFunc) 519 dlsym(lib_infop->hLibrary, "Sun_fcOpenTgtAdapterByWWN"); 520 if (GetNumberOfTgtAdaptersFunc == NULL || 521 OpenTgtAdapterByWWNFunc == NULL) { 522 GetNumberOfTgtAdaptersFunc = OpenTgtAdapterByWWNFunc = NULL; 523 continue; 524 } 525 526 (void) ((GetNumberOfTgtAdaptersFunc)()); 527 528 if((status = (OpenTgtAdapterByWWNFunc)(&handle, nodeWWN)) 529 != HBA_STATUS_OK) { 530 GetNumberOfTgtAdaptersFunc = OpenTgtAdapterByWWNFunc = NULL; 531 continue; 532 } 533 /* OK, make a vendor non-specific handle */ 534 *phandle = HBA_HANDLE_FROM_LOCAL(lib_infop->index, handle); 535 status = HBA_STATUS_OK; 536 break; 537 538 GetNumberOfTgtAdaptersFunc = OpenTgtAdapterByWWNFunc = NULL; 539 } 540 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 541 } 542 543 static HBA_STATUS 544 HBA_NPIV_CheckLibrary(HBA_HANDLE handle, 545 HBA_LIBRARY_INFO **lib_infopp, 546 HBA_HANDLE *vendorhandle) { 547 HBA_UINT32 libraryIndex; 548 HBA_LIBRARY_INFO *lib_infop; 549 550 if (vendorhandle == NULL) { 551 return(HBA_STATUS_ERROR_ARG); 552 } 553 if(_hbaapi_librarylist == NULL) { 554 return(HBA_STATUS_ERROR); 555 } 556 libraryIndex = LIBRARY_NUM(handle); 557 558 GRAB_MUTEX(&_hbaapi_LL_mutex); 559 for(lib_infop = _hbaapi_librarylist; 560 lib_infop != NULL; 561 lib_infop = lib_infop->next) { 562 if(lib_infop->index == libraryIndex) { 563 if(lib_infop->status != HBA_LIBRARY_LOADED) { 564 return HBA_STATUS_ERROR; 565 } 566 *lib_infopp = lib_infop; 567 *vendorhandle = VENDOR_HANDLE(handle); 568 /* caller will release the mutex */ 569 return HBA_STATUS_OK; 570 } 571 } 572 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_INVALID_HANDLE); 573 } 574 #define NPIVCHECKLIBRARY() \ 575 status = HBA_NPIV_CheckLibrary(handle, &lib_infop, &vendorHandle); \ 576 if(status != HBA_STATUS_OK) { \ 577 return(status); \ 578 } 579 580 HBA_STATUS 581 Sun_HBA_NPIVGetAdapterAttributes ( 582 HBA_HANDLE handle, 583 HBA_ADAPTERATTRIBUTES 584 *hbaattributes) 585 { 586 HBA_STATUS status; 587 HBA_LIBRARY_INFO *lib_infop; 588 HBA_HANDLE vendorHandle; 589 Sun_HBANPIVGetAdapterAttributesFunc NPIVGetAdapterAttributesFunc; 590 591 DEBUG(2, "HBA_NPIVGetAdapterAttributes", 0, 0, 0); 592 593 NPIVCHECKLIBRARY(); 594 NPIVGetAdapterAttributesFunc = (Sun_HBANPIVGetAdapterAttributesFunc) 595 dlsym(lib_infop->hLibrary, "Sun_fcNPIVGetAdapterAttributes"); 596 if (NPIVGetAdapterAttributesFunc != NULL) { 597 status = ((NPIVGetAdapterAttributesFunc)(vendorHandle, 598 hbaattributes)); 599 } else { 600 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 601 } 602 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 603 } 604 605 HBA_STATUS 606 Sun_HBA_GetNPIVPortInfo ( 607 HBA_HANDLE handle, 608 HBA_UINT32 portindex, 609 HBA_UINT32 vportindex, 610 HBA_NPIVATTRIBUTES *attributes) 611 { 612 HBA_STATUS status; 613 HBA_LIBRARY_INFO *lib_infop; 614 HBA_HANDLE vendorHandle; 615 Sun_HBAGetNPIVPortInfoFunc GetNPIVPortInfoFunc; 616 617 NPIVCHECKLIBRARY(); 618 GetNPIVPortInfoFunc = (Sun_HBAGetNPIVPortInfoFunc) 619 dlsym(lib_infop->hLibrary, "Sun_fcGetNPIVPortInfo"); 620 if (GetNPIVPortInfoFunc != NULL) { 621 status = ((GetNPIVPortInfoFunc)(vendorHandle, portindex, 622 vportindex, attributes)); 623 } else { 624 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 625 } 626 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 627 } 628 629 HBA_STATUS 630 Sun_HBA_DeleteNPIVPort ( 631 HBA_HANDLE handle, 632 HBA_UINT32 portindex, 633 HBA_WWN vportWWN) 634 { 635 HBA_STATUS status; 636 HBA_LIBRARY_INFO *lib_infop; 637 HBA_HANDLE vendorHandle; 638 Sun_HBADeleteNPIVPortFunc DeleteNPIVPortFunc; 639 640 NPIVCHECKLIBRARY(); 641 DeleteNPIVPortFunc = (Sun_HBADeleteNPIVPortFunc) 642 dlsym(lib_infop->hLibrary, "Sun_fcDeleteNPIVPort"); 643 if (DeleteNPIVPortFunc != NULL) { 644 status = ((DeleteNPIVPortFunc)(vendorHandle, 645 portindex, vportWWN)); 646 } else { 647 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 648 } 649 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 650 } 651 652 HBA_STATUS 653 Sun_HBA_CreateNPIVPort ( 654 HBA_HANDLE handle, 655 HBA_UINT32 portindex, 656 HBA_WWN vnodeWWN, 657 HBA_WWN vportWWN, 658 HBA_UINT32 *vportindex) 659 { 660 HBA_STATUS status; 661 HBA_LIBRARY_INFO *lib_infop; 662 HBA_HANDLE vendorHandle; 663 Sun_HBACreateNPIVPortFunc CreateNPIVPortFunc; 664 665 NPIVCHECKLIBRARY(); 666 CreateNPIVPortFunc = (Sun_HBACreateNPIVPortFunc) 667 dlsym(lib_infop->hLibrary, "Sun_fcCreateNPIVPort"); 668 if (CreateNPIVPortFunc != NULL) { 669 status = ((CreateNPIVPortFunc)(vendorHandle, 670 portindex, vnodeWWN, vportWWN, vportindex)); 671 } else { 672 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 673 } 674 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 675 } 676 677 HBA_STATUS 678 Sun_HBA_GetPortNPIVAttributes ( 679 HBA_HANDLE handle, 680 HBA_UINT32 portindex, 681 HBA_PORTNPIVATTRIBUTES *portnpivattributes) 682 { 683 HBA_STATUS status; 684 HBA_LIBRARY_INFO *lib_infop; 685 HBA_HANDLE vendorHandle; 686 Sun_HBAGetPortNPIVAttributesFunc GetPortNPIVAttributesFunc; 687 688 NPIVCHECKLIBRARY(); 689 GetPortNPIVAttributesFunc = (Sun_HBAGetPortNPIVAttributesFunc) 690 dlsym(lib_infop->hLibrary, "Sun_fcGetPortNPIVAttributes"); 691 if (GetPortNPIVAttributesFunc != NULL) { 692 status = ((GetPortNPIVAttributesFunc)( 693 vendorHandle, portindex, portnpivattributes)); 694 } else { 695 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 696 } 697 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 698 } 699 700 HBA_STATUS 701 Sun_HBA_AdapterCreateWWN ( 702 HBA_HANDLE handle, 703 HBA_UINT32 portindex, 704 HBA_WWN *nwwn, 705 HBA_WWN *pwwn, 706 HBA_WWN *OUI, 707 HBA_INT32 method) 708 { 709 HBA_STATUS status; 710 HBA_LIBRARY_INFO *lib_infop; 711 HBA_HANDLE vendorHandle; 712 Sun_HBAAdapterCreateWWNFunc AdapterCreateWWNFunc; 713 714 NPIVCHECKLIBRARY(); 715 AdapterCreateWWNFunc = (Sun_HBAAdapterCreateWWNFunc) 716 dlsym(lib_infop->hLibrary, "Sun_fcAdapterCreateWWN"); 717 if (AdapterCreateWWNFunc != NULL) { 718 status = ((AdapterCreateWWNFunc)(vendorHandle, 719 portindex, nwwn, pwwn, OUI, method)); 720 } else { 721 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 722 } 723 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 724 } 725 726 HBA_STATUS 727 Sun_HBA_AdapterReturnWWN ( 728 HBA_HANDLE handle, 729 HBA_UINT32 portindex, 730 HBA_WWN *nwwn, 731 HBA_WWN *pwwn) 732 { 733 HBA_STATUS status; 734 HBA_LIBRARY_INFO *lib_infop; 735 HBA_HANDLE vendorHandle; 736 Sun_HBAAdapterReturnWWNFunc AdapterReturnWWNFunc; 737 738 NPIVCHECKLIBRARY(); 739 AdapterReturnWWNFunc = (Sun_HBAAdapterReturnWWNFunc) 740 dlsym(lib_infop->hLibrary, "Sun_fcAdapterReturnWWN"); 741 if (AdapterReturnWWNFunc != NULL) { 742 status = ((AdapterReturnWWNFunc)(vendorHandle, 743 portindex, nwwn, pwwn)); 744 } else { 745 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 746 } 747 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 748 } 749 750 typedef struct hba_npivadaptercallback_elem { 751 struct hba_npivadaptercallback_elem 752 *next; 753 HBA_LIBRARY_INFO *lib_info; 754 void *userdata; 755 HBA_CALLBACKHANDLE vendorcbhandle; 756 void (*callback)(); 757 } HBA_NPIVADAPTERCALLBACK_ELEM; 758 extern HBA_NPIVADAPTERCALLBACK_ELEM *_hbaapi_adapterdeviceevents_callback_list; 759 760 /* Adapter Device Events ********************************************************/ 761 static void 762 adapterdeviceevents_callback (void *data, 763 HBA_WWN PortWWN, 764 HBA_UINT32 eventType, 765 HBA_UINT32 fabricPortID) 766 { 767 HBA_NPIVADAPTERCALLBACK_ELEM *acbp; 768 769 DEBUG(3, "AdapterDeviceEvent, port:%s, eventType:%d fabricPortID:0X%06x", 770 WWN2STR1(&PortWWN), eventType, fabricPortID); 771 772 GRAB_MUTEX(&_hbaapi_APE_mutex); 773 774 for(acbp = _hbaapi_adapterdeviceevents_callback_list; 775 acbp != NULL; 776 acbp = acbp->next) { 777 if(data == (void *)acbp) { 778 (*acbp->callback)(acbp->userdata, PortWWN, eventType, fabricPortID); 779 break; 780 } 781 } 782 RELEASE_MUTEX(&_hbaapi_APE_mutex); 783 } 784 785 HBA_STATUS 786 Sun_HBA_RegisterForAdapterDeviceEvents ( 787 void (*callback) ( 788 void *data, 789 HBA_WWN PortWWN, 790 HBA_UINT32 eventType, 791 HBA_UINT32 fabricPortID 792 ), 793 void *userData, 794 HBA_HANDLE handle, 795 HBA_WWN PortWWN, 796 HBA_CALLBACKHANDLE *callbackHandle) 797 { 798 HBA_NPIVADAPTERCALLBACK_ELEM *acbp; 799 HBA_STATUS status; 800 HBA_LIBRARY_INFO *lib_infop; 801 HBA_HANDLE vendorHandle; 802 Sun_HBARegisterForAdapterDeviceEventsFunc 803 registeredfunc; 804 805 if (callbackHandle == NULL) { 806 return(HBA_STATUS_ERROR_ARG); 807 } 808 809 NPIVCHECKLIBRARY(); 810 registeredfunc = (Sun_HBARegisterForAdapterDeviceEventsFunc) 811 dlsym(lib_infop->hLibrary, 812 "Sun_fcRegisterForAdapterDeviceEvents"); 813 if (registeredfunc == NULL) { 814 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); 815 } 816 817 acbp = (HBA_NPIVADAPTERCALLBACK_ELEM *) 818 calloc(1, sizeof(HBA_NPIVADAPTERCALLBACK_ELEM)); 819 820 if(acbp == NULL) { 821 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); 822 } 823 824 *callbackHandle = (HBA_CALLBACKHANDLE) acbp; 825 acbp->callback = callback; 826 acbp->userdata = userData; 827 acbp->lib_info = lib_infop; 828 829 status = (registeredfunc)(adapterdeviceevents_callback, 830 (void *)acbp, 831 vendorHandle, 832 PortWWN, 833 &acbp->vendorcbhandle); 834 if(status != HBA_STATUS_OK) { 835 free(acbp); 836 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 837 } 838 839 GRAB_MUTEX(&_hbaapi_APE_mutex); 840 acbp->next = _hbaapi_adapterdeviceevents_callback_list; 841 _hbaapi_adapterdeviceevents_callback_list = acbp; 842 RELEASE_MUTEX(&_hbaapi_APE_mutex); 843 844 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); 845 } 846 847 HBA_STATUS 848 Sun_HBA_ForceLip(HBA_HANDLE handle, int *rval) 849 { 850 HBA_STATUS status; 851 HBA_LIBRARY_INFO *lib_infop; 852 HBA_HANDLE vendorHandle; 853 854 Sun_HBADoForceLipFunc DoForceLipFunc; 855 856 DEBUG(2, "Sun_HBA_DoForceLip", 0, 0, 0); 857 858 NPIVCHECKLIBRARY(); 859 DoForceLipFunc = (Sun_HBADoForceLipFunc) 860 dlsym(lib_infop->hLibrary, "Sun_fcDoForceLip"); 861 if (DoForceLipFunc != NULL) { 862 status = ((DoForceLipFunc)(vendorHandle, rval)); 863 } else { 864 status = HBA_STATUS_ERROR_NOT_SUPPORTED; 865 } 866 RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); 867 } 868