1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27
28 #include <sun_sas.h>
29
30 /*
31 * Loads the HBA Library. Must be called before calling any HBA library
32 * functions
33 *
34 * Return values:
35 * HBA_STATUS_OK library properly loaded
36 * HBA_STATUS_ERROR library loaded incorrectly
37 */
38 int loadCount = 0;
Sun_sasLoadLibrary()39 HBA_STATUS Sun_sasLoadLibrary() {
40 const char ROUTINE[] = "Sun_sasLoadLibrary";
41 di_node_t root;
42 boolean_t atLeastOneHBA = B_FALSE;
43 boolean_t atLeastOneFailure = B_FALSE;
44 hrtime_t start = 0;
45 hrtime_t end = 0;
46 double duration = 0;
47
48 /* Make sure that library has not been already loaded */
49 if (loadCount++ > 0) {
50 log(LOG_DEBUG, ROUTINE, "Library already loaded %d time."
51 " Ignoring.", loadCount);
52 return (HBA_STATUS_ERROR);
53 }
54 hba_count = 0;
55 open_handle_index = 1;
56 /* Initialize the read-write lock */
57 if (mutex_init(&all_hbas_lock, USYNC_THREAD, NULL)) {
58 log(LOG_DEBUG, ROUTINE,
59 "Unable to initialize lock in LoadLibrary for reason \"%s\"",
60 strerror(errno));
61 return (HBA_STATUS_ERROR);
62 }
63 /* grab write lock */
64 lock(&all_hbas_lock);
65
66 start = gethrtime();
67 if ((root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) {
68 log(LOG_DEBUG, ROUTINE,
69 "Unable to load device tree for reason \"%s\"",
70 strerror(errno));
71 unlock(&all_hbas_lock);
72 return (HBA_STATUS_ERROR);
73 }
74 end = gethrtime();
75 duration = end - start;
76 duration /= HR_SECOND;
77 log(LOG_DEBUG, ROUTINE, "Loading device tree init took "
78 "%.6f seconds", duration);
79
80 /* At load time, we only gather libdevinfo information */
81 if (devtree_get_all_hbas(root) == HBA_STATUS_OK) {
82 atLeastOneHBA = B_TRUE;
83 } else {
84 atLeastOneFailure = B_TRUE;
85 }
86
87 di_fini(root);
88
89 unlock(&all_hbas_lock);
90
91 /* Now determine what status code to return */
92 if (atLeastOneHBA) {
93 /* We've got at least one HBA and possibly some failures */
94 return (HBA_STATUS_OK);
95 } else if (atLeastOneFailure) {
96 /* We have no HBAs but have failures */
97 return (HBA_STATUS_ERROR);
98 } else {
99 /* We have no HBAs and no failures */
100 return (HBA_STATUS_OK);
101 }
102 }
103