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 mutex_t all_hbas_lock = DEFAULTMUTEX;
31 mutex_t open_handles_lock = DEFAULTMUTEX;
32 HBA_UINT16 open_handle_index;
33 HBA_UINT32 hba_count;
34 
35 /*
36  * Loads the HBA Library.  Must be called before calling any HBA library
37  * functions
38  *
39  * Return values:
40  *	HBA_STATUS_OK	    library properly loaded
41  *	HBA_STATUS_ERROR    library loaded incorrectly
42  */
43 int	loadCount = 0;
Sun_sasLoadLibrary()44 HBA_STATUS Sun_sasLoadLibrary() {
45 	const char	ROUTINE[] = "Sun_sasLoadLibrary";
46 	di_node_t	root;
47 	boolean_t	atLeastOneHBA = B_FALSE;
48 	boolean_t	atLeastOneFailure = B_FALSE;
49 	hrtime_t	    start = 0;
50 	hrtime_t	    end = 0;
51 	double		    duration = 0;
52 
53 	/* Make sure that library has not been already loaded */
54 	if (loadCount++ > 0) {
55 		log(LOG_DEBUG, ROUTINE, "Library already loaded %d time."
56 		    " Ignoring.", loadCount);
57 		return (HBA_STATUS_ERROR);
58 	}
59 	hba_count = 0;
60 	open_handle_index = 1;
61 
62 	/* grab write lock */
63 	lock(&all_hbas_lock);
64 
65 	start = gethrtime();
66 	if ((root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) {
67 		log(LOG_DEBUG, ROUTINE,
68 		    "Unable to load device tree: \"%s\"",
69 		    strerror(errno));
70 		unlock(&all_hbas_lock);
71 		return (HBA_STATUS_ERROR);
72 	}
73 	end = gethrtime();
74 	duration = end - start;
75 	duration /= HR_SECOND;
76 	log(LOG_DEBUG, ROUTINE, "Loading device tree init took "
77 	    "%.6f seconds", duration);
78 
79 	/* At load time, we only gather libdevinfo information */
80 	if (devtree_get_all_hbas(root) == HBA_STATUS_OK) {
81 		atLeastOneHBA = B_TRUE;
82 	} else {
83 		atLeastOneFailure = B_TRUE;
84 	}
85 
86 	di_fini(root);
87 
88 	unlock(&all_hbas_lock);
89 
90 	/* Now determine what status code to return */
91 	if (atLeastOneHBA) {
92 		/* We've got at least one HBA and possibly some failures */
93 		return (HBA_STATUS_OK);
94 	}
95 	if (atLeastOneFailure) {
96 		/* We have no HBAs but have failures */
97 		return (HBA_STATUS_ERROR);
98 	}
99 
100 	/* We have no HBAs and no failures */
101 	return (HBA_STATUS_OK);
102 }
103