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.
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.
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]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 * Copyright 2019 Joyent, Inc.
33 * Retrieves the attributes for a specific discovered port by WWN
36 Sun_sasGetPortAttributesByWWN(HBA_HANDLE handle
, HBA_WWN portWWN
,
37 HBA_WWN domainPortWWN
, PSMHBA_PORTATTRIBUTES attributes
)
39 const char ROUTINE
[] = "Sun_sasGetPortAttributesByWWN";
41 struct sun_sas_hba
*hba_ptr
;
42 struct sun_sas_port
*hba_port_ptr
, *hba_disco_port
;
43 int index
, chkDomainPort
= 0, domainFound
= 0;
45 /* Validate the arguments */
46 if (attributes
== NULL
) {
47 log(LOG_DEBUG
, ROUTINE
, "NULL port attributes");
48 return (HBA_STATUS_ERROR_ARG
);
51 if (wwnConversion(domainPortWWN
.wwn
) != 0) {
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
);
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
);
75 if (hba_ptr
->first_port
== NULL
) {
76 /* This is probably an internal failure of the library */
77 if (hba_ptr
->device_path
[0] != '\0') {
78 log(LOG_DEBUG
, ROUTINE
,
79 "Internal failure: Adapter %s contains "
80 "no port data", hba_ptr
->device_path
);
82 log(LOG_DEBUG
, ROUTINE
,
83 "Internal failure: Adapter at index %d contains "
84 "no port data", hba_ptr
->index
);
86 unlock(&open_handles_lock
);
87 unlock(&all_hbas_lock
);
88 return (HBA_STATUS_ERROR
);
91 /* Loop over all Adapter ports */
92 for (hba_port_ptr
= hba_ptr
->first_port
;
94 hba_port_ptr
= hba_port_ptr
->next
) {
96 if (validateDomainAddress(hba_port_ptr
,
97 domainPortWWN
) != HBA_STATUS_OK
) {
103 if (wwnConversion(hba_port_ptr
->port_attributes
.
104 PortSpecificAttribute
.SASPort
->LocalSASAddress
.wwn
) ==
105 wwnConversion(portWWN
.wwn
)) {
107 * We should indicate an error if we enter here
108 * without domainPortWWN set.
110 if (chkDomainPort
== 0) {
111 log(LOG_DEBUG
, ROUTINE
,
112 "Domain Port WWN should be set when "
113 "querying HBA port %016llx for "
115 wwnConversion(portWWN
.wwn
), handle
);
116 unlock(&open_handles_lock
);
117 unlock(&all_hbas_lock
);
118 return (HBA_STATUS_ERROR_ARG
);
120 attributes
->PortType
=
121 hba_port_ptr
->port_attributes
.PortType
;
122 attributes
->PortState
=
123 hba_port_ptr
->port_attributes
.PortState
;
124 (void) strlcpy(attributes
->OSDeviceName
,
125 hba_port_ptr
->port_attributes
.OSDeviceName
,
126 sizeof (attributes
->OSDeviceName
));
127 (void) memcpy(attributes
->PortSpecificAttribute
.SASPort
,
128 hba_port_ptr
->port_attributes
.PortSpecificAttribute
.
129 SASPort
, sizeof (struct SMHBA_SAS_Port
));
131 unlock(&open_handles_lock
);
132 unlock(&all_hbas_lock
);
133 return (HBA_STATUS_OK
);
136 /* check to make sure there are devices attached to this port */
137 if (hba_port_ptr
->first_attached_port
!= NULL
) {
139 /* Loop over all discovered ports */
140 for (hba_disco_port
= hba_port_ptr
->first_attached_port
;
141 hba_disco_port
!= NULL
;
142 hba_disco_port
= hba_disco_port
->next
) {
143 if (wwnConversion(hba_disco_port
->
144 port_attributes
.PortSpecificAttribute
.
145 SASPort
->LocalSASAddress
.wwn
) ==
146 wwnConversion(portWWN
.wwn
)) {
147 attributes
->PortType
=
148 hba_disco_port
->port_attributes
.
150 attributes
->PortState
=
151 hba_disco_port
->port_attributes
.
153 (void) strlcpy(attributes
->OSDeviceName
,
154 hba_disco_port
->port_attributes
.
156 sizeof (attributes
->OSDeviceName
));
157 (void) memcpy(attributes
->
158 PortSpecificAttribute
.SASPort
,
159 hba_disco_port
->port_attributes
.
160 PortSpecificAttribute
.SASPort
,
161 sizeof (struct SMHBA_SAS_Port
));
162 unlock(&open_handles_lock
);
163 unlock(&all_hbas_lock
);
164 return (HBA_STATUS_OK
);
169 log(LOG_DEBUG
, ROUTINE
,
170 "Invalid Port WWN %016llx for handle %08lx",
171 wwnConversion(portWWN
.wwn
), handle
);
172 unlock(&open_handles_lock
);
173 unlock(&all_hbas_lock
);
174 return (HBA_STATUS_ERROR_ILLEGAL_WWN
);
177 if (chkDomainPort
&& domainFound
== 0) {
178 log(LOG_DEBUG
, ROUTINE
, "No Matching domain port"
179 " (%16llx) for port (%16llx) for handle %08lx",
180 wwnConversion(domainPortWWN
.wwn
),
181 wwnConversion(portWWN
.wwn
),
184 /* We enter here only when chkDomainPort == 0 */
185 log(LOG_DEBUG
, ROUTINE
,
186 "Invalid Port WWN %016llx for handle %08lx",
187 wwnConversion(portWWN
.wwn
), handle
);
189 unlock(&open_handles_lock
);
190 unlock(&all_hbas_lock
);
191 return (HBA_STATUS_ERROR_ILLEGAL_WWN
);