1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright 2019 Joyent, Inc.
28 */
29
30 #include <sun_sas.h>
31
32 /*
33 * Retrieves the attributes for a specified port discovered in the network
34 */
35 HBA_STATUS
Sun_sasGetDiscoveredPortAttributes(HBA_HANDLE handle,HBA_UINT32 port,HBA_UINT32 discoveredport,SMHBA_PORTATTRIBUTES * attributes)36 Sun_sasGetDiscoveredPortAttributes(HBA_HANDLE handle,
37 HBA_UINT32 port, HBA_UINT32 discoveredport,
38 SMHBA_PORTATTRIBUTES *attributes)
39 {
40 const char ROUTINE[] =
41 "Sun_sasGetDiscoveredPortAttributes";
42 HBA_STATUS status;
43 HBA_STATUS ret = HBA_STATUS_OK;
44 struct sun_sas_hba *hba_ptr;
45 struct sun_sas_port *hba_port_ptr, *hba_disco_port;
46 int index;
47
48 if (attributes == NULL) {
49 log(LOG_DEBUG, ROUTINE,
50 "NULL attributes argument. Handle %08lx, port %d, "
51 "discovered port %d", handle, port, discoveredport);
52 return (HBA_STATUS_ERROR_ARG);
53 }
54
55 lock(&all_hbas_lock);
56 index = RetrieveIndex(handle);
57 lock(&open_handles_lock);
58 hba_ptr = RetrieveHandle(index);
59 if (hba_ptr == NULL) {
60 log(LOG_DEBUG, ROUTINE, "Invalid handle %08lx.", handle);
61 unlock(&open_handles_lock);
62 unlock(&all_hbas_lock);
63 return (HBA_STATUS_ERROR_INVALID_HANDLE);
64 }
65
66 /* Check for stale data */
67 status = verifyAdapter(hba_ptr);
68 if (status != HBA_STATUS_OK) {
69 log(LOG_DEBUG, ROUTINE, "Verify Adapter failed");
70 unlock(&open_handles_lock);
71 unlock(&all_hbas_lock);
72 return (status);
73 }
74
75
76 if (hba_ptr->first_port == NULL) {
77 /* This is probably an internal failure of the library */
78 if (hba_ptr->device_path[0] != '\0') {
79 log(LOG_DEBUG, ROUTINE, "Internal failure: Adapter %s"
80 " contains no port data", hba_ptr->device_path);
81 } else {
82 log(LOG_DEBUG, ROUTINE, "Internal failure: Adapter at"
83 " index %d contains no port data", hba_ptr->index);
84 }
85 unlock(&open_handles_lock);
86 unlock(&all_hbas_lock);
87 return (HBA_STATUS_ERROR);
88 }
89
90 for (hba_port_ptr = hba_ptr->first_port;
91 hba_port_ptr != NULL; hba_port_ptr = hba_port_ptr->next) {
92 if (hba_port_ptr->index == port) {
93 break;
94 }
95 }
96
97 if (hba_port_ptr == NULL) {
98 log(LOG_DEBUG, ROUTINE,
99 "Invalid port index %d for handle %08lx",
100 port, handle);
101 unlock(&open_handles_lock);
102 unlock(&all_hbas_lock);
103 return (HBA_STATUS_ERROR_ILLEGAL_INDEX);
104 }
105
106 /* check to make sure there are devices attached to this port */
107 if (hba_port_ptr->first_attached_port != NULL) {
108 for (hba_disco_port = hba_port_ptr->first_attached_port;
109 hba_disco_port != NULL;
110 hba_disco_port = hba_disco_port->next) {
111 if (hba_disco_port->index == discoveredport) {
112 break;
113 }
114 }
115 if (hba_disco_port == NULL) {
116 log(LOG_DEBUG, ROUTINE,
117 "Invalid discovered port index %d for hba port "
118 "index %d on handle %08lx.",
119 discoveredport, port, handle);
120 ret = HBA_STATUS_ERROR_ILLEGAL_INDEX;
121 } else {
122 attributes->PortType =
123 hba_disco_port->port_attributes.PortType;
124 attributes->PortState =
125 hba_disco_port->port_attributes.PortState;
126 (void) strlcpy(attributes->OSDeviceName,
127 hba_disco_port->port_attributes.OSDeviceName,
128 sizeof (attributes->OSDeviceName));
129 (void) memcpy(attributes->PortSpecificAttribute.SASPort,
130 hba_disco_port->port_attributes.\
131 PortSpecificAttribute.SASPort,
132 sizeof (struct SMHBA_SAS_Port));
133 }
134 } else {
135 /* No ports, so we can't possibly return anything */
136 log(LOG_DEBUG, ROUTINE,
137 "No discovered port on HBA port index %d for handle %08lx",
138 port, handle);
139 ret = HBA_STATUS_ERROR;
140 }
141 unlock(&open_handles_lock);
142 unlock(&all_hbas_lock);
143
144 return (ret);
145 }
146