9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * CDDL HEADER START
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 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * See the License for the specific language governing permissions
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * and limitations under the License.
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 * CDDL HEADER END
f2e8686e6101ad6ab3df43205537e610151b5434xun ni - Sun Microsystems - Beijing China * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim/* free hba port info for the given hba */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Free the nested structures (port and attached port) */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Free discovered port structure list. */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Free target mapping data list first. */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Internal routine for adding an HBA port
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kimadd_hba_port_info(di_node_t portNode, struct sun_sas_hba *hba_ptr, int protocol)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Sun_sas handle ptr set to NULL.");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((port_ptr->port_attributes.PortSpecificAttribute.SASPort =
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (struct SMHBA_SAS_Port *)calloc(1, sizeof (struct SMHBA_SAS_Port)))
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((portDevpath = di_devfs_path(portNode)) == NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Unable to get device path from HBA Port Node.");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
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 /* something is wrong here. */
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim "Unable to take devinfoi branch snapshot on HBA port \"%s\""
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (((state & DI_DRIVER_DETACHED) == DI_DRIVER_DETACHED) ||
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim ((state & DI_DEVICE_OFFLINE) == DI_DEVICE_OFFLINE)) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "HBA port node %s is either OFFLINE or DETACHED",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.PortState = HBA_PORTSTATE_OFFLINE;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.PortState = HBA_PORTSTATE_ONLINE;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim port_ptr->port_attributes.PortType = HBA_PORTTYPE_SASDEVICE;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(port_ptr->device_path, portDevpath, MAXPATHLEN + 1);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (lookupControllerLink(portDevpath, (char *)cntlLink) ==
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(port_ptr->port_attributes.OSDeviceName, cntlLink,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) snprintf(port_ptr->port_attributes.OSDeviceName,
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim rval = di_prop_lookup_strings(DDI_DEV_T_ANY, branchNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Unable to get initiator-port from HBA port node %s.",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim for (charptr = propStringData; *charptr != '\0'; charptr++) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim PortSpecificAttribute.SASPort->LocalSASAddress.wwn,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "No proper intiator-port prop value on HBA port %s",
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim rval = di_prop_lookup_strings(DDI_DEV_T_ANY, branchNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Unable to get attached-port from HBA port node %s.",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim for (charptr = propStringData; *charptr != '\0'; charptr++) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* continue even if the attached port is NULL. */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "No proper attached-port prop value: "
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "HBA port Local SAS Address(%016llx)",
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim rval = di_prop_lookup_ints(DDI_DEV_T_ANY, branchNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Unable to get NumberofPhys from HBA port %s.",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (port_ptr->port_attributes.PortSpecificAttribute.\
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim if (get_phy_info(branchNode, port_ptr) != HBA_STATUS_OK) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Failed to get phy info on HBA port %s.",
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim /* now done with prop checking. remove branchNode. */
f94d63efa5176901b7c714a65f345cf45d5b1370Hyon Kim /* Construct discovered target port. */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (devtree_attached_devices(portNode, port_ptr) != HBA_STATUS_OK) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Failed to get attached device info HBA port %s.",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim S_FREE(port_ptr->port_attributes.PortSpecificAttribute.SASPort);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* add new port onto hba handle list */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kimrefresh_hba(di_node_t hbaNode, struct sun_sas_hba *hba_ptr)
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * clean up existing hba port, discovered target, phy info.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * leave open handles intact.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "HBA node doesn't have iport child.");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Unable to get supported-protocol from HBA node.");
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);
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 * Without iport support, the devinfo node will represent one port hba.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * This routine assumes the locks have been taken.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "portNode has instance of -1");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((hbaDevpath = di_devfs_path(hbaNode)) == NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "device path from hbaNode");
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* check to see if this is a repeat HBA */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* this is a new hba */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) snprintf(new_hba->adapter_attributes.HBASymbolicName,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.HBASymbolicName),
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Manufacturer */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.Manufacturer,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.Manufacturer));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.Manufacturer,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.Manufacturer));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* SerialNumber */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim new_hba->adapter_attributes.SerialNumber[0] = '\0';
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.SerialNumber,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.SerialNumber));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Model */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* FirmwareVersion */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Property \"%s\" not found for device \"%s\"",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.FirmwareVersion,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.FirmwareVersion));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* HardwareVersion */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Property \"%s\" not found for device \"%s\"",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.HardwareVersion,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.HardwareVersion));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* DriverVersion */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, hbaNode,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Property \"%s\" not found for device \"%s\"",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.DriverVersion,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim sizeof (new_hba->adapter_attributes.DriverVersion));
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "Unable to get supported-protocol from HBA node.");
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 if ((hba_driver = di_driver_name(hbaNode)) != NULL) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim (void) strlcpy(new_hba->adapter_attributes.DriverName,
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "HBA driver name not found for device \"%s\"",
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 (void) snprintf(new_hba->handle_name, HANDLE_NAME_LENGTH, "%s-%s-%d",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "SUNW", new_hba->adapter_attributes.DriverName, hba_instance);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim "HBA driver doesn't have iport child. \"%s\"",
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* continue on with an hba without any port. */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * add newly created handle into global_hba_head list
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 /* Now bump the new one to the head of the list */
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);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * add newly created handle into global_hba_head list
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 new_hba->open_handles = global_hba_head->open_handles;
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Now bump the new one to the head of the list */
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 /* Skip stub(instance -1) nodes */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (rval >= 0) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* add the hba to the hba list */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* Found a node. No need to walk the child. */
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 rv = di_walk_node(root, DI_WALK_SIBFIRST, &wa, lookup_smhba_sas_hba);
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim if (rv == 0) {
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * Now determine what status code to return, taking
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * partial failure scenarios into consideration.
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 * We've got at least one HBA and possibly some
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim * failures.
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* We have no HBAs but have failures */
9e86db79b7d1bbc5f2f04e99954cbd5eae0e22bbHyon Kim /* We have no HBAs and no failures */