19e86db79SHyon Kim /*
29e86db79SHyon Kim  * CDDL HEADER START
39e86db79SHyon Kim  *
49e86db79SHyon Kim  * The contents of this file are subject to the terms of the
59e86db79SHyon Kim  * Common Development and Distribution License (the "License").
69e86db79SHyon Kim  * You may not use this file except in compliance with the License.
79e86db79SHyon Kim  *
89e86db79SHyon Kim  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99e86db79SHyon Kim  * or http://www.opensolaris.org/os/licensing.
109e86db79SHyon Kim  * See the License for the specific language governing permissions
119e86db79SHyon Kim  * and limitations under the License.
129e86db79SHyon Kim  *
139e86db79SHyon Kim  * When distributing Covered Code, include this CDDL HEADER in each
149e86db79SHyon Kim  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159e86db79SHyon Kim  * If applicable, add the following below this CDDL HEADER, with the
169e86db79SHyon Kim  * fields enclosed by brackets "[]" replaced with your own identifying
179e86db79SHyon Kim  * information: Portions Copyright [yyyy] [name of copyright owner]
189e86db79SHyon Kim  *
199e86db79SHyon Kim  * CDDL HEADER END
209e86db79SHyon Kim  */
219e86db79SHyon Kim 
229e86db79SHyon Kim /*
239e86db79SHyon Kim  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
249e86db79SHyon Kim  * Use is subject to license terms.
259e86db79SHyon Kim  */
26*00f453f4SRob Johnston /*
27*00f453f4SRob Johnston  * Copyright 2019 Joyent, Inc.
28*00f453f4SRob Johnston  */
299e86db79SHyon Kim 
309e86db79SHyon Kim #include    <sun_sas.h>
319e86db79SHyon Kim 
329e86db79SHyon Kim /*
339e86db79SHyon Kim  * Retrieves the attributes for a specified port discovered in the network
349e86db79SHyon Kim  */
359e86db79SHyon Kim HBA_STATUS
Sun_sasGetDiscoveredPortAttributes(HBA_HANDLE handle,HBA_UINT32 port,HBA_UINT32 discoveredport,SMHBA_PORTATTRIBUTES * attributes)369e86db79SHyon Kim Sun_sasGetDiscoveredPortAttributes(HBA_HANDLE handle,
37*00f453f4SRob Johnston     HBA_UINT32 port, HBA_UINT32 discoveredport,
38*00f453f4SRob Johnston     SMHBA_PORTATTRIBUTES *attributes)
39*00f453f4SRob Johnston {
409e86db79SHyon Kim 	const char		ROUTINE[] =
419e86db79SHyon Kim 	    "Sun_sasGetDiscoveredPortAttributes";
429e86db79SHyon Kim 	HBA_STATUS		status;
439e86db79SHyon Kim 	HBA_STATUS		ret = HBA_STATUS_OK;
449e86db79SHyon Kim 	struct sun_sas_hba	*hba_ptr;
459e86db79SHyon Kim 	struct sun_sas_port	*hba_port_ptr, *hba_disco_port;
469e86db79SHyon Kim 	int			index;
479e86db79SHyon Kim 
489e86db79SHyon Kim 	if (attributes == NULL) {
49*00f453f4SRob Johnston 		log(LOG_DEBUG, ROUTINE,
50*00f453f4SRob Johnston 		    "NULL attributes argument. Handle %08lx, port %d, "
51*00f453f4SRob Johnston 		    "discovered port %d", handle, port, discoveredport);
52*00f453f4SRob Johnston 		return (HBA_STATUS_ERROR_ARG);
539e86db79SHyon Kim 	}
549e86db79SHyon Kim 
559e86db79SHyon Kim 	lock(&all_hbas_lock);
569e86db79SHyon Kim 	index = RetrieveIndex(handle);
579e86db79SHyon Kim 	lock(&open_handles_lock);
589e86db79SHyon Kim 	hba_ptr = RetrieveHandle(index);
599e86db79SHyon Kim 	if (hba_ptr == NULL) {
60*00f453f4SRob Johnston 		log(LOG_DEBUG, ROUTINE, "Invalid handle %08lx.", handle);
61*00f453f4SRob Johnston 		unlock(&open_handles_lock);
62*00f453f4SRob Johnston 		unlock(&all_hbas_lock);
63*00f453f4SRob Johnston 		return (HBA_STATUS_ERROR_INVALID_HANDLE);
649e86db79SHyon Kim 	}
659e86db79SHyon Kim 
669e86db79SHyon Kim 	/* Check for stale data */
679e86db79SHyon Kim 	status = verifyAdapter(hba_ptr);
689e86db79SHyon Kim 	if (status != HBA_STATUS_OK) {
69*00f453f4SRob Johnston 		log(LOG_DEBUG, ROUTINE, "Verify Adapter failed");
70*00f453f4SRob Johnston 		unlock(&open_handles_lock);
71*00f453f4SRob Johnston 		unlock(&all_hbas_lock);
72*00f453f4SRob Johnston 		return (status);
739e86db79SHyon Kim 	}
749e86db79SHyon Kim 
759e86db79SHyon Kim 
769e86db79SHyon Kim 	if (hba_ptr->first_port == NULL) {
77*00f453f4SRob Johnston 		/* This is probably an internal failure of the library */
78*00f453f4SRob Johnston 		if (hba_ptr->device_path[0] != '\0') {
79*00f453f4SRob Johnston 			log(LOG_DEBUG, ROUTINE, "Internal failure:  Adapter %s"
80*00f453f4SRob Johnston 			    " contains no port data", hba_ptr->device_path);
81*00f453f4SRob Johnston 		} else {
82*00f453f4SRob Johnston 			log(LOG_DEBUG, ROUTINE, "Internal failure:  Adapter at"
83*00f453f4SRob Johnston 			    " index %d contains no port data", hba_ptr->index);
84*00f453f4SRob Johnston 		}
85*00f453f4SRob Johnston 		unlock(&open_handles_lock);
86*00f453f4SRob Johnston 		unlock(&all_hbas_lock);
87*00f453f4SRob Johnston 		return (HBA_STATUS_ERROR);
889e86db79SHyon Kim 	}
899e86db79SHyon Kim 
909e86db79SHyon Kim 	for (hba_port_ptr = hba_ptr->first_port;
919e86db79SHyon Kim 	    hba_port_ptr != NULL; hba_port_ptr = hba_port_ptr->next) {
929e86db79SHyon Kim 		if (hba_port_ptr->index == port) {
939e86db79SHyon Kim 			break;
949e86db79SHyon Kim 		}
959e86db79SHyon Kim 	}
969e86db79SHyon Kim 
979e86db79SHyon Kim 	if (hba_port_ptr == NULL) {
989e86db79SHyon Kim 		log(LOG_DEBUG, ROUTINE,
999e86db79SHyon Kim 		    "Invalid port index %d for handle %08lx",
1009e86db79SHyon Kim 		    port, handle);
1019e86db79SHyon Kim 		unlock(&open_handles_lock);
1029e86db79SHyon Kim 		unlock(&all_hbas_lock);
1039e86db79SHyon Kim 		return (HBA_STATUS_ERROR_ILLEGAL_INDEX);
1049e86db79SHyon Kim 	}
1059e86db79SHyon Kim 
1069e86db79SHyon Kim 	/* check to make sure there are devices attached to this port */
1079e86db79SHyon Kim 	if (hba_port_ptr->first_attached_port != NULL) {
1089e86db79SHyon Kim 		for (hba_disco_port = hba_port_ptr->first_attached_port;
109*00f453f4SRob Johnston 		    hba_disco_port != NULL;
110*00f453f4SRob Johnston 		    hba_disco_port = hba_disco_port->next) {
111*00f453f4SRob Johnston 			if (hba_disco_port->index == discoveredport) {
112*00f453f4SRob Johnston 				break;
113*00f453f4SRob Johnston 			}
1149e86db79SHyon Kim 		}
1159e86db79SHyon Kim 		if (hba_disco_port == NULL) {
1169e86db79SHyon Kim 			log(LOG_DEBUG, ROUTINE,
1179e86db79SHyon Kim 			    "Invalid discovered port index %d for hba port "
1189e86db79SHyon Kim 			    "index %d on handle %08lx.",
1199e86db79SHyon Kim 			    discoveredport, port, handle);
1209e86db79SHyon Kim 			ret = HBA_STATUS_ERROR_ILLEGAL_INDEX;
1219e86db79SHyon Kim 		} else {
122*00f453f4SRob Johnston 			attributes->PortType =
123*00f453f4SRob Johnston 			    hba_disco_port->port_attributes.PortType;
124*00f453f4SRob Johnston 			attributes->PortState =
125*00f453f4SRob Johnston 			    hba_disco_port->port_attributes.PortState;
126*00f453f4SRob Johnston 			(void) strlcpy(attributes->OSDeviceName,
127*00f453f4SRob Johnston 			    hba_disco_port->port_attributes.OSDeviceName,
128*00f453f4SRob Johnston 			    sizeof (attributes->OSDeviceName));
129*00f453f4SRob Johnston 			(void) memcpy(attributes->PortSpecificAttribute.SASPort,
130*00f453f4SRob Johnston 			    hba_disco_port->port_attributes.\
131*00f453f4SRob Johnston 			    PortSpecificAttribute.SASPort,
132*00f453f4SRob Johnston 			    sizeof (struct SMHBA_SAS_Port));
1339e86db79SHyon Kim 		}
1349e86db79SHyon Kim 	} else {
1359e86db79SHyon Kim 		/* No ports, so we can't possibly return anything */
1369e86db79SHyon Kim 		log(LOG_DEBUG, ROUTINE,
1379e86db79SHyon Kim 		    "No discovered port on HBA port index %d for handle %08lx",
1389e86db79SHyon Kim 		    port, handle);
1399e86db79SHyon Kim 		ret = HBA_STATUS_ERROR;
1409e86db79SHyon Kim 	}
1419e86db79SHyon Kim 	unlock(&open_handles_lock);
1429e86db79SHyon Kim 	unlock(&all_hbas_lock);
1439e86db79SHyon Kim 
1449e86db79SHyon Kim 	return (ret);
1459e86db79SHyon Kim }
146