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
grab_mutex(pthread_mutex_t * mp)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
release_mutex(pthread_mutex_t * mp)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
Sun_HBA_GetNumberOfTgtAdapters()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
Sun_HBA_GetTgtAdapterName(HBA_UINT32 adapterindex,char * adaptername)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
Sun_HBA_OpenTgtAdapter(char * adaptername)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
Sun_HBA_OpenTgtAdapterByWWN(HBA_HANDLE * phandle,HBA_WWN nodeWWN)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
HBA_NPIV_CheckLibrary(HBA_HANDLE handle,HBA_LIBRARY_INFO ** lib_infopp,HBA_HANDLE * vendorhandle)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
Sun_HBA_NPIVGetAdapterAttributes(HBA_HANDLE handle,HBA_ADAPTERATTRIBUTES * hbaattributes)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
Sun_HBA_GetNPIVPortInfo(HBA_HANDLE handle,HBA_UINT32 portindex,HBA_UINT32 vportindex,HBA_NPIVATTRIBUTES * attributes)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
Sun_HBA_DeleteNPIVPort(HBA_HANDLE handle,HBA_UINT32 portindex,HBA_WWN vportWWN)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
Sun_HBA_CreateNPIVPort(HBA_HANDLE handle,HBA_UINT32 portindex,HBA_WWN vnodeWWN,HBA_WWN vportWWN,HBA_UINT32 * vportindex)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
Sun_HBA_GetPortNPIVAttributes(HBA_HANDLE handle,HBA_UINT32 portindex,HBA_PORTNPIVATTRIBUTES * portnpivattributes)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
Sun_HBA_AdapterCreateWWN(HBA_HANDLE handle,HBA_UINT32 portindex,HBA_WWN * nwwn,HBA_WWN * pwwn,HBA_WWN * OUI,HBA_INT32 method)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
Sun_HBA_AdapterReturnWWN(HBA_HANDLE handle,HBA_UINT32 portindex,HBA_WWN * nwwn,HBA_WWN * pwwn)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
adapterdeviceevents_callback(void * data,HBA_WWN PortWWN,HBA_UINT32 eventType,HBA_UINT32 fabricPortID)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
Sun_HBA_RegisterForAdapterDeviceEvents(void (* callback)(void * data,HBA_WWN PortWWN,HBA_UINT32 eventType,HBA_UINT32 fabricPortID),void * userData,HBA_HANDLE handle,HBA_WWN PortWWN,HBA_CALLBACKHANDLE * callbackHandle)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
Sun_HBA_ForceLip(HBA_HANDLE handle,int * rval)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