9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim/*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * CDDL HEADER START
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim *
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * The contents of this file are subject to the terms of the
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Common Development and Distribution License (the "License").
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * You may not use this file except in compliance with the License.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim *
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * or http://www.opensolaris.org/os/licensing.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * See the License for the specific language governing permissions
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * and limitations under the License.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim *
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * When distributing Covered Code, include this CDDL HEADER in each
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * If applicable, add the following below this CDDL HEADER, with the
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * fields enclosed by brackets "[]" replaced with your own identifying
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * information: Portions Copyright [yyyy] [name of copyright owner]
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim *
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * CDDL HEADER END
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim/*
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim#include <sun_sas.h>
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim#include <sys/modctl.h>
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim#include <sys/types.h>
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim#include <netinet/in.h>
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim#include <inttypes.h>
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim#include <ctype.h>
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim/* free hba port info for the given hba */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kimstatic void
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kimfree_hba_port(struct sun_sas_hba *hba_ptr)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim{
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim struct sun_sas_port *hba_port = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim struct sun_sas_port *last_hba_port = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim struct sun_sas_port *tgt_port = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim struct sun_sas_port *last_tgt_port = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim struct ScsiEntryList *scsi_info = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim struct ScsiEntryList *last_scsi_info = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim struct phy_info *phy_ptr = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim struct phy_info *last_phy = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Free the nested structures (port and attached port) */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim hba_port = hba_ptr->first_port;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim while (hba_port != NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Free discovered port structure list. */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim tgt_port = hba_port->first_attached_port;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim while (tgt_port != NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Free target mapping data list first. */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim scsi_info = tgt_port->scsiInfo;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim while (scsi_info != NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim last_scsi_info = scsi_info;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim scsi_info = scsi_info->next;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim free(last_scsi_info);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim last_tgt_port = tgt_port;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim tgt_port = tgt_port->next;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim free(last_tgt_port->port_attributes.\
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim free(last_tgt_port);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim hba_port->first_attached_port = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim phy_ptr = hba_port->first_phy;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim while (phy_ptr != NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim last_phy = phy_ptr;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim phy_ptr = phy_ptr->next;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim free(last_phy);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim hba_port->first_phy = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim last_hba_port = hba_port;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim hba_port = hba_port->next;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim free(last_hba_port->port_attributes.\
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim free(last_hba_port);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim hba_ptr->first_port = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim}
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim/*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Internal routine for adding an HBA port
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kimstatic HBA_STATUS
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kimadd_hba_port_info(di_node_t portNode, struct sun_sas_hba *hba_ptr, int protocol)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim{
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim const char ROUTINE[] = "add_hba_port_info";
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim struct sun_sas_port *port_ptr;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim char *portDevpath;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim int *propIntData;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim char *propStringData;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim uint64_t tmpAddr;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim char *charptr, cntlLink[MAXPATHLEN] = {'\0'};
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim int rval;
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim di_node_t branchNode;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim uint_t state = HBA_PORTSTATE_UNKNOWN;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (hba_ptr == NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Sun_sas handle ptr set to NULL.");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR_ARG);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((port_ptr = (struct sun_sas_port *)calloc(1,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (struct sun_sas_port))) == NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim OUT_OF_MEMORY(ROUTINE);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((port_ptr->port_attributes.PortSpecificAttribute.SASPort =
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (struct SMHBA_SAS_Port *)calloc(1, sizeof (struct SMHBA_SAS_Port)))
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim == NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim OUT_OF_MEMORY(ROUTINE);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((portDevpath = di_devfs_path(portNode)) == NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Unable to get device path from HBA Port Node.");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim /*
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim * Let's take a branch snap shot for pulling attributes.
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim * The attribute change doesn't invalidate devinfo cache snapshot.
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim * Phy info prop and num-phys can be obsolate when the same hba
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim * connected to the same expander(SIM) thus phy numbers are increased.
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim * Also the phy number may get decreased when a connection is removed
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim * while the iport still exist through another connection.
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim */
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim branchNode = di_init(portDevpath, DINFOPROP);
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim if (branchNode == DI_NODE_NIL) {
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim /* something is wrong here. */
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim di_fini(branchNode);
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim log(LOG_DEBUG, ROUTINE,
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim "Unable to take devinfoi branch snapshot on HBA port \"%s\""
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim " due to %s", portDevpath, strerror(errno));
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim S_FREE(port_ptr);
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim return (HBA_STATUS_ERROR);
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim }
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim state = di_state(portNode);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (((state & DI_DRIVER_DETACHED) == DI_DRIVER_DETACHED) ||
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim ((state & DI_DEVICE_OFFLINE) == DI_DEVICE_OFFLINE)) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "HBA port node %s is either OFFLINE or DETACHED",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim portDevpath);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.PortState = HBA_PORTSTATE_OFFLINE;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.PortState = HBA_PORTSTATE_ONLINE;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.PortType = HBA_PORTTYPE_SASDEVICE;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(port_ptr->device_path, portDevpath, MAXPATHLEN + 1);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (lookupControllerLink(portDevpath, (char *)cntlLink) ==
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim HBA_STATUS_OK) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(port_ptr->port_attributes.OSDeviceName, cntlLink,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (port_ptr->port_attributes.OSDeviceName));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((charptr = strrchr(cntlLink, '/')) != NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim charptr++;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (charptr[0] == 'c') {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->cntlNumber = atoi(++charptr);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->cntlNumber = -1;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) snprintf(port_ptr->port_attributes.OSDeviceName,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (port_ptr->port_attributes.OSDeviceName),
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "%s%s%s", DEVICES_DIR, portDevpath, SCSI_SUFFIX);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim di_devfs_path_free(portDevpath);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.PortSpecificAttribute.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim SASPort->PortProtocol = protocol;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim rval = di_prop_lookup_strings(DDI_DEV_T_ANY, branchNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "initiator-port", &propStringData);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (rval < 0) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Unable to get initiator-port from HBA port node %s.",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.OSDeviceName);
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim di_fini(branchNode);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim for (charptr = propStringData; *charptr != '\0'; charptr++) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (isxdigit(*charptr)) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim break;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (*charptr != '\0') {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim tmpAddr = htonll(strtoll(charptr, NULL, 16));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) memcpy(port_ptr->port_attributes.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim PortSpecificAttribute.SASPort->LocalSASAddress.wwn,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim &tmpAddr, 8);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "No proper intiator-port prop value on HBA port %s",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.OSDeviceName);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim rval = di_prop_lookup_strings(DDI_DEV_T_ANY, branchNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "attached-port", &propStringData);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (rval < 0) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Unable to get attached-port from HBA port node %s.",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.OSDeviceName);
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim di_fini(branchNode);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim for (charptr = propStringData; *charptr != '\0'; charptr++) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (isxdigit(*charptr)) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim break;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (*charptr != '\0') {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim tmpAddr = htonll(strtoll(charptr, NULL, 16));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) memcpy(port_ptr->port_attributes.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim PortSpecificAttribute.SASPort->
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim AttachedSASAddress.wwn, &tmpAddr, 8);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* continue even if the attached port is NULL. */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "No proper attached-port prop value: "
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "HBA port Local SAS Address(%016llx)",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim wwnConversion(port_ptr->port_attributes.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim PortSpecificAttribute.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim SASPort->LocalSASAddress.wwn));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim rval = di_prop_lookup_ints(DDI_DEV_T_ANY, branchNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "num-phys", &propIntData);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (rval < 0) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Unable to get NumberofPhys from HBA port %s.",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.OSDeviceName);
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim di_fini(branchNode);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.PortSpecificAttribute.\
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim SASPort->NumberofPhys = *propIntData;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (port_ptr->port_attributes.PortSpecificAttribute.\
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim SASPort->NumberofPhys > 0) {
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim if (get_phy_info(branchNode, port_ptr) != HBA_STATUS_OK) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Failed to get phy info on HBA port %s.",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.OSDeviceName);
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim di_fini(branchNode);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr->port_attributes.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr);
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim /* now done with prop checking. remove branchNode. */
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim di_fini(branchNode);
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim /* Construct discovered target port. */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (devtree_attached_devices(portNode, port_ptr) != HBA_STATUS_OK) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Failed to get attached device info HBA port %s.",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.OSDeviceName);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr);
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim fillDomainPortWWN(port_ptr);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* add new port onto hba handle list */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (hba_ptr->first_port == NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->index = 0;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim hba_ptr->first_port = port_ptr;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->index = hba_ptr->first_port->index + 1;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->next = hba_ptr->first_port;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim hba_ptr->first_port = port_ptr;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_OK);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim}
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon KimHBA_STATUS
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kimrefresh_hba(di_node_t hbaNode, struct sun_sas_hba *hba_ptr)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim{
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim const char ROUTINE[] = "refresh_hba";
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim di_node_t portNode;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim int protocol = 0;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim int *propIntData;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * clean up existing hba port, discovered target, phy info.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * leave open handles intact.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim free_hba_port(hba_ptr);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((portNode = di_child_node(hbaNode)) == NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "HBA node doesn't have iport child.");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_ints(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "supported-protocol", &propIntData)) == -1) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Unable to get supported-protocol from HBA node.");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim protocol = *propIntData;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim while (portNode != DI_NODE_NIL) {
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China if (di_prop_lookup_ints(DDI_DEV_T_ANY, portNode,
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China "virtual-port", &propIntData) >= 0) {
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China if (*propIntData) {
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China /* ignore a virtual port. */
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China portNode = di_sibling_node(portNode);
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China continue;
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China }
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (add_hba_port_info(portNode, hba_ptr, protocol)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim == HBA_STATUS_ERROR) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(hba_ptr->first_port);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(hba_ptr);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim portNode = di_sibling_node(portNode);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_OK);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim}
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim/*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Discover information for one HBA in the device tree.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * The di_node_t argument should be a node with smhba-supported prop set
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * to true.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Without iport support, the devinfo node will represent one port hba.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * This routine assumes the locks have been taken.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon KimHBA_STATUS
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kimdevtree_get_one_hba(di_node_t hbaNode)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim{
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim const char ROUTINE[] = "devtree_get_one_hba";
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim char *propdata = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim int *propIntData = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim struct sun_sas_hba *new_hba, *hba_ptr;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim char *hbaDevpath, *hba_driver;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim int protocol = 0;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim di_node_t portNode;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim int hba_instance = -1;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim hba_instance = di_instance(hbaNode);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (hba_instance == -1) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "portNode has instance of -1");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (DI_WALK_CONTINUE);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((hbaDevpath = di_devfs_path(hbaNode)) == NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE, "Unable to get "
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "device path from hbaNode");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* check to see if this is a repeat HBA */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (global_hba_head) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim for (hba_ptr = global_hba_head;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim hba_ptr != NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim hba_ptr = hba_ptr->next) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((strncmp(hba_ptr->device_path, hbaDevpath,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim strlen(hbaDevpath))) == 0) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (refresh_hba(hbaNode, hba_ptr) !=
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim HBA_STATUS_OK) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE, "Refresh failed"
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim " on hbaNode %s", hbaDevpath);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim di_devfs_path_free(hbaDevpath);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_OK);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* this is a new hba */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((new_hba = (struct sun_sas_hba *)calloc(1,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (struct sun_sas_hba))) == NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim OUT_OF_MEMORY(ROUTINE);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim di_devfs_path_free(hbaDevpath);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->device_path, hbaDevpath,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->device_path));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim di_devfs_path_free(hbaDevpath);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) snprintf(new_hba->adapter_attributes.HBASymbolicName,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.HBASymbolicName),
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "%s%s", DEVICES_DIR, new_hba->device_path);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Manufacturer */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Manufacturer", (char **)&propdata)) == -1) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.Manufacturer,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim SUN_MICROSYSTEMS,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.Manufacturer));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.Manufacturer,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim propdata,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.Manufacturer));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* SerialNumber */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "SerialNumber", (char **)&propdata)) == -1) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->adapter_attributes.SerialNumber[0] = '\0';
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.SerialNumber,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim propdata,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.SerialNumber));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Model */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "ModelName", (char **)&propdata)) == -1) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->adapter_attributes.Model[0] = '\0';
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.Model,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim propdata,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.Model));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* FirmwareVersion */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "firmware-version", (char **)&propdata)) == -1) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Property \"%s\" not found for device \"%s\"",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "firmware-version", new_hba->device_path);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.FirmwareVersion,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim propdata,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.FirmwareVersion));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* HardwareVersion */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "hardware-version", (char **)&propdata)) == -1) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Property \"%s\" not found for device \"%s\"",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "hardware-version", new_hba->device_path);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.HardwareVersion,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim propdata,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.HardwareVersion));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* DriverVersion */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "driver-version", (char **)&propdata)) == -1) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Property \"%s\" not found for device \"%s\"",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "driver-version", new_hba->device_path);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.DriverVersion,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim propdata,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.DriverVersion));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_ints(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "supported-protocol", &propIntData)) == -1) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Unable to get supported-protocol from HBA node.");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim protocol = *propIntData;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* We don't use these */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->adapter_attributes.OptionROMVersion[0] = '\0';
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->adapter_attributes.RedundantOptionROMVersion[0] = '\0';
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->adapter_attributes.RedundantFirmwareVersion[0] = '\0';
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->adapter_attributes.VendorSpecificID = 0;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((hba_driver = di_driver_name(hbaNode)) != NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.DriverName,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim hba_driver,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.DriverName));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "HBA driver name not found for device \"%s\"",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->device_path);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Name the adapter: like SUNW-pmcs-1
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Using di_instance number as the suffix for the name for persistent
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * among rebooting.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) snprintf(new_hba->handle_name, HANDLE_NAME_LENGTH, "%s-%s-%d",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "SUNW", new_hba->adapter_attributes.DriverName, hba_instance);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((portNode = di_child_node(hbaNode)) == NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "HBA driver doesn't have iport child. \"%s\"",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->device_path);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* continue on with an hba without any port. */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->index = hba_count++;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * add newly created handle into global_hba_head list
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (global_hba_head != NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Make sure to move the open_handles list to back to
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * the head if it's there (for refresh scenario)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (global_hba_head->open_handles) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->open_handles =
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim global_hba_head->open_handles;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim global_hba_head->open_handles = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Now bump the new one to the head of the list */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->next = global_hba_head;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim global_hba_head = new_hba;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim global_hba_head = new_hba;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_OK);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim while (portNode != DI_NODE_NIL) {
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China if (di_prop_lookup_ints(DDI_DEV_T_ANY, portNode,
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China "virtual-port", &propIntData) >= 0) {
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China if (*propIntData) {
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China /* ignore a virtual port. */
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China portNode = di_sibling_node(portNode);
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China continue;
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China }
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (add_hba_port_info(portNode, new_hba, protocol)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim == HBA_STATUS_ERROR) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(new_hba->first_port);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(new_hba);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim portNode = di_sibling_node(portNode);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->index = hba_count++;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * add newly created handle into global_hba_head list
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (global_hba_head != NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Make sure to move the open_handles list to back to the
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * head if it's there (for refresh scenario)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (global_hba_head->open_handles) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->open_handles = global_hba_head->open_handles;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim global_hba_head->open_handles = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Now bump the new one to the head of the list */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->next = global_hba_head;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim global_hba_head = new_hba;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim global_hba_head = new_hba;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_OK);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim}
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim/*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Discover information for all HBAs found on the system.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * The di_node_t argument should be the root of the device tree.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * This routine assumes the locks have been taken
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kimstatic int
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kimlookup_smhba_sas_hba(di_node_t node, void *arg)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim{
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim const char ROUTINE[] = "lookup_smhba_sas_hba";
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim int *propData, rval;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim walkarg_t *wa = (walkarg_t *)arg;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Skip stub(instance -1) nodes */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (IS_STUB_NODE(node)) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE, "Walk continue");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (DI_WALK_CONTINUE);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim rval = di_prop_lookup_ints(DDI_DEV_T_ANY, node,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "sm-hba-supported", &propData);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (rval >= 0) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (*propData) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* add the hba to the hba list */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (devtree_get_one_hba(node) != HBA_STATUS_OK) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim *(wa->flag) = B_TRUE;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Found a node. No need to walk the child. */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim log(LOG_DEBUG, ROUTINE, "Walk prunechild");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (DI_WALK_PRUNECHILD);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (DI_WALK_CONTINUE);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim}
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim/*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Discover information for all HBAs found on the system.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * The di_node_t argument should be the root of the device tree.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * This routine assumes the locks have been taken
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon KimHBA_STATUS
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kimdevtree_get_all_hbas(di_node_t root)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim{
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim const char ROUTINE[] = "devtree_get_all_hbas";
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim int rv, ret = HBA_STATUS_ERROR;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim walkarg_t wa;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim wa.devpath = NULL;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((wa.flag = (boolean_t *)calloc(1,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (boolean_t))) == NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim OUT_OF_MEMORY(ROUTINE);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (HBA_STATUS_ERROR);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim *wa.flag = B_FALSE;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim rv = di_walk_node(root, DI_WALK_SIBFIRST, &wa, lookup_smhba_sas_hba);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (rv == 0) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Now determine what status code to return, taking
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * partial failure scenarios into consideration.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim *
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * If we have at least one working HBA, then we return an
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * OK status. If we have no good HBAs, but at least one
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * failed HBA, we return an ERROR status. If we have
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * no HBAs and no failures, we return OK.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (global_hba_head) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /*
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * We've got at least one HBA and possibly some
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * failures.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim ret = HBA_STATUS_OK;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else if (*(wa.flag)) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* We have no HBAs but have failures */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim ret = HBA_STATUS_ERROR;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim } else {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* We have no HBAs and no failures */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim ret = HBA_STATUS_OK;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim }
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(wa.flag);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (ret == HBA_STATUS_OK)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) registerSysevent();
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim return (ret);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim}