4b22b9337f359bfd063322244f5336cc7c6ffcfars/*
4b22b9337f359bfd063322244f5336cc7c6ffcfars * CDDL HEADER START
4b22b9337f359bfd063322244f5336cc7c6ffcfars *
4b22b9337f359bfd063322244f5336cc7c6ffcfars * The contents of this file are subject to the terms of the
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Common Development and Distribution License (the "License").
4b22b9337f359bfd063322244f5336cc7c6ffcfars * You may not use this file except in compliance with the License.
4b22b9337f359bfd063322244f5336cc7c6ffcfars *
4b22b9337f359bfd063322244f5336cc7c6ffcfars * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4b22b9337f359bfd063322244f5336cc7c6ffcfars * or http://www.opensolaris.org/os/licensing.
4b22b9337f359bfd063322244f5336cc7c6ffcfars * See the License for the specific language governing permissions
4b22b9337f359bfd063322244f5336cc7c6ffcfars * and limitations under the License.
4b22b9337f359bfd063322244f5336cc7c6ffcfars *
4b22b9337f359bfd063322244f5336cc7c6ffcfars * When distributing Covered Code, include this CDDL HEADER in each
4b22b9337f359bfd063322244f5336cc7c6ffcfars * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4b22b9337f359bfd063322244f5336cc7c6ffcfars * If applicable, add the following below this CDDL HEADER, with the
4b22b9337f359bfd063322244f5336cc7c6ffcfars * fields enclosed by brackets "[]" replaced with your own identifying
4b22b9337f359bfd063322244f5336cc7c6ffcfars * information: Portions Copyright [yyyy] [name of copyright owner]
4b22b9337f359bfd063322244f5336cc7c6ffcfars *
4b22b9337f359bfd063322244f5336cc7c6ffcfars * CDDL HEADER END
4b22b9337f359bfd063322244f5336cc7c6ffcfars */
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars/*
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Use is subject to license terms.
4b22b9337f359bfd063322244f5336cc7c6ffcfars */
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars#include <sun_sas.h>
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars/*
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Loads the HBA Library. Must be called before calling any HBA library
4b22b9337f359bfd063322244f5336cc7c6ffcfars * functions
4b22b9337f359bfd063322244f5336cc7c6ffcfars *
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Return values:
4b22b9337f359bfd063322244f5336cc7c6ffcfars * HBA_STATUS_OK library properly loaded
4b22b9337f359bfd063322244f5336cc7c6ffcfars * HBA_STATUS_ERROR library loaded incorrectly
4b22b9337f359bfd063322244f5336cc7c6ffcfars */
4b22b9337f359bfd063322244f5336cc7c6ffcfarsint loadCount = 0;
4b22b9337f359bfd063322244f5336cc7c6ffcfarsHBA_STATUS Sun_sasLoadLibrary() {
4b22b9337f359bfd063322244f5336cc7c6ffcfars const char ROUTINE[] = "Sun_sasLoadLibrary";
4b22b9337f359bfd063322244f5336cc7c6ffcfars di_node_t root;
b6805bf78d2bbbeeaea8909a05623587b42d58b3Gordon Ross boolean_t atLeastOneHBA = B_FALSE;
4b22b9337f359bfd063322244f5336cc7c6ffcfars boolean_t atLeastOneFailure = B_FALSE;
4b22b9337f359bfd063322244f5336cc7c6ffcfars hrtime_t start = 0;
4b22b9337f359bfd063322244f5336cc7c6ffcfars hrtime_t end = 0;
4b22b9337f359bfd063322244f5336cc7c6ffcfars double duration = 0;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /* Make sure that library has not been already loaded */
4b22b9337f359bfd063322244f5336cc7c6ffcfars if (loadCount++ > 0) {
4b22b9337f359bfd063322244f5336cc7c6ffcfars log(LOG_DEBUG, ROUTINE, "Library already loaded %d time."
4b22b9337f359bfd063322244f5336cc7c6ffcfars " Ignoring.", loadCount);
4b22b9337f359bfd063322244f5336cc7c6ffcfars return (HBA_STATUS_ERROR);
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars hba_count = 0;
4b22b9337f359bfd063322244f5336cc7c6ffcfars open_handle_index = 1;
4b22b9337f359bfd063322244f5336cc7c6ffcfars /* Initialize the read-write lock */
4b22b9337f359bfd063322244f5336cc7c6ffcfars if (mutex_init(&all_hbas_lock, USYNC_THREAD, NULL)) {
4b22b9337f359bfd063322244f5336cc7c6ffcfars log(LOG_DEBUG, ROUTINE,
"Unable to initialize lock in LoadLibrary for reason \"%s\"",
strerror(errno));
return (HBA_STATUS_ERROR);
}
/* grab write lock */
lock(&all_hbas_lock);
start = gethrtime();
if ((root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) {
log(LOG_DEBUG, ROUTINE,
"Unable to load device tree for reason \"%s\"",
strerror(errno));
unlock(&all_hbas_lock);
return (HBA_STATUS_ERROR);
}
end = gethrtime();
duration = end - start;
duration /= HR_SECOND;
log(LOG_DEBUG, ROUTINE, "Loading device tree init took "
"%.6f seconds", duration);
/* At load time, we only gather libdevinfo information */
if (devtree_get_all_hbas(root) == HBA_STATUS_OK) {
atLeastOneHBA = B_TRUE;
} else {
atLeastOneFailure = B_TRUE;
}
di_fini(root);
unlock(&all_hbas_lock);
/* Now determine what status code to return */
if (atLeastOneHBA) {
/* We've got at least one HBA and possibly some failures */
return (HBA_STATUS_OK);
} else if (atLeastOneFailure) {
/* We have no HBAs but have failures */
return (HBA_STATUS_ERROR);
} else {
/* We have no HBAs and no failures */
return (HBA_STATUS_OK);
}
}