19e86db7Hyon Kim/*
29e86db7Hyon Kim * CDDL HEADER START
39e86db7Hyon Kim *
49e86db7Hyon Kim * The contents of this file are subject to the terms of the
59e86db7Hyon Kim * Common Development and Distribution License (the "License").
69e86db7Hyon Kim * You may not use this file except in compliance with the License.
79e86db7Hyon Kim *
89e86db7Hyon Kim * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99e86db7Hyon Kim * or http://www.opensolaris.org/os/licensing.
109e86db7Hyon Kim * See the License for the specific language governing permissions
119e86db7Hyon Kim * and limitations under the License.
129e86db7Hyon Kim *
139e86db7Hyon Kim * When distributing Covered Code, include this CDDL HEADER in each
149e86db7Hyon Kim * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159e86db7Hyon Kim * If applicable, add the following below this CDDL HEADER, with the
169e86db7Hyon Kim * fields enclosed by brackets "[]" replaced with your own identifying
179e86db7Hyon Kim * information: Portions Copyright [yyyy] [name of copyright owner]
189e86db7Hyon Kim *
199e86db7Hyon Kim * CDDL HEADER END
209e86db7Hyon Kim */
219e86db7Hyon Kim
229e86db7Hyon Kim/*
239e86db7Hyon Kim * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
249e86db7Hyon Kim * Use is subject to license terms.
259e86db7Hyon Kim */
2600f453fRob Johnston/*
2700f453fRob Johnston * Copyright 2019 Joyent, Inc.
2800f453fRob Johnston */
299e86db7Hyon Kim#include    <sun_sas.h>
309e86db7Hyon Kim
319e86db7Hyon Kim/*
329e86db7Hyon Kim * Retrieves the attributes for a specified port of an adapter
339e86db7Hyon Kim */
349e86db7Hyon KimHBA_STATUS
3500f453fRob JohnstonSun_sasGetAdapterPortAttributes(HBA_HANDLE handle, HBA_UINT32 port,
3600f453fRob Johnston    PSMHBA_PORTATTRIBUTES attributes)
3700f453fRob Johnston{
389e86db7Hyon Kim	const char		ROUTINE[] = "Sun_sasGetAdapterPortAttributes";
399e86db7Hyon Kim	HBA_STATUS		status;
409e86db7Hyon Kim	struct sun_sas_hba	*hba_ptr;
419e86db7Hyon Kim	struct sun_sas_port	*hba_port_ptr;
429e86db7Hyon Kim	int			index;
439e86db7Hyon Kim
449e86db7Hyon Kim	/* Validate the arguments */
459e86db7Hyon Kim	if ((attributes == NULL) ||
469e86db7Hyon Kim	    (attributes->PortSpecificAttribute.SASPort == NULL)) {
4700f453fRob Johnston		log(LOG_DEBUG, ROUTINE, "NULL attributes");
4800f453fRob Johnston		return (HBA_STATUS_ERROR_ARG);
499e86db7Hyon Kim	}
509e86db7Hyon Kim
519e86db7Hyon Kim	lock(&all_hbas_lock);
529e86db7Hyon Kim	index = RetrieveIndex(handle);
539e86db7Hyon Kim	lock(&open_handles_lock);
549e86db7Hyon Kim	hba_ptr = RetrieveHandle(index);
559e86db7Hyon Kim	if (hba_ptr == NULL) {
569e86db7Hyon Kim		log(LOG_DEBUG, ROUTINE, "Invalid handle %08lx", handle);
579e86db7Hyon Kim		unlock(&open_handles_lock);
589e86db7Hyon Kim		unlock(&all_hbas_lock);
599e86db7Hyon Kim		return (HBA_STATUS_ERROR_INVALID_HANDLE);
609e86db7Hyon Kim	}
619e86db7Hyon Kim
629e86db7Hyon Kim	/* Check for stale data */
639e86db7Hyon Kim	status = verifyAdapter(hba_ptr);
649e86db7Hyon Kim	if (status != HBA_STATUS_OK) {
659e86db7Hyon Kim		log(LOG_DEBUG, ROUTINE, "Verify Adapter failed");
669e86db7Hyon Kim		unlock(&open_handles_lock);
679e86db7Hyon Kim		unlock(&all_hbas_lock);
689e86db7Hyon Kim		return (status);
699e86db7Hyon Kim	}
709e86db7Hyon Kim
719e86db7Hyon Kim	if (hba_ptr->first_port == NULL) {
7200f453fRob Johnston		/* This is probably an internal failure of the library */
7300f453fRob Johnston		if (hba_ptr->device_path[0] != '\0') {
7400f453fRob Johnston			log(LOG_DEBUG, ROUTINE, "Internal failure:  Adapter "
7500f453fRob Johnston			    "%s contains no port data", hba_ptr->device_path);
7600f453fRob Johnston		} else {
7700f453fRob Johnston			log(LOG_DEBUG, ROUTINE, "Internal failure:  Adapter at"
7800f453fRob Johnston			    " index %d contains no port data", hba_ptr->index);
7900f453fRob Johnston		}
8000f453fRob Johnston		unlock(&open_handles_lock);
8100f453fRob Johnston		unlock(&all_hbas_lock);
8200f453fRob Johnston		return (HBA_STATUS_ERROR);
839e86db7Hyon Kim	}
849e86db7Hyon Kim	for (hba_port_ptr = hba_ptr->first_port;
859e86db7Hyon Kim	    hba_port_ptr != NULL; hba_port_ptr = hba_port_ptr->next) {
869e86db7Hyon Kim		if (hba_port_ptr->index == port) {
879e86db7Hyon Kim			break;
889e86db7Hyon Kim		}
899e86db7Hyon Kim	}
909e86db7Hyon Kim	if (hba_port_ptr == NULL || hba_port_ptr->index != port) {
919e86db7Hyon Kim		log(LOG_DEBUG, ROUTINE,
929e86db7Hyon Kim		    "Invalid port index %d for handle %08lx.",
939e86db7Hyon Kim		    port, handle);
949e86db7Hyon Kim		unlock(&open_handles_lock);
959e86db7Hyon Kim		unlock(&all_hbas_lock);
969e86db7Hyon Kim		return (HBA_STATUS_ERROR_ILLEGAL_INDEX);
979e86db7Hyon Kim	}
989e86db7Hyon Kim
999e86db7Hyon Kim	attributes->PortType =  hba_port_ptr->port_attributes.PortType;
1009e86db7Hyon Kim	attributes->PortState =  hba_port_ptr->port_attributes.PortState;
1019e86db7Hyon Kim	(void) strlcpy(attributes->OSDeviceName,
1029e86db7Hyon Kim	    hba_port_ptr->port_attributes.OSDeviceName,
1039e86db7Hyon Kim	    sizeof (attributes->OSDeviceName));
1049e86db7Hyon Kim	(void) memcpy(attributes->PortSpecificAttribute.SASPort,
1059e86db7Hyon Kim	    hba_port_ptr->port_attributes.PortSpecificAttribute.SASPort,
1069e86db7Hyon Kim	    sizeof (struct SMHBA_SAS_Port));
1079e86db7Hyon Kim
1089e86db7Hyon Kim	unlock(&open_handles_lock);
1099e86db7Hyon Kim	unlock(&all_hbas_lock);
1109e86db7Hyon Kim
1119e86db7Hyon Kim	return (HBA_STATUS_OK);
1129e86db7Hyon Kim}