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.
30 * Retrieves the attributes for a specific discovered port by WWN
33 Sun_sasGetPortAttributesByWWN(HBA_HANDLE handle
, HBA_WWN portWWN
,
34 HBA_WWN domainPortWWN
, PSMHBA_PORTATTRIBUTES attributes
)
36 const char ROUTINE
[] = "Sun_sasGetPortAttributesByWWN";
38 struct sun_sas_hba
*hba_ptr
;
39 struct sun_sas_port
*hba_port_ptr
, *hba_disco_port
;
40 int index
, chkDomainPort
= 0, domainFound
= 0;
42 /* Validate the arguments */
43 if (attributes
== NULL
) {
44 log(LOG_DEBUG
, ROUTINE
, "NULL port attributes");
45 return (HBA_STATUS_ERROR_ARG
);
48 if (wwnConversion(domainPortWWN
.wwn
) != 0) {
53 index
= RetrieveIndex(handle
);
54 lock(&open_handles_lock
);
55 hba_ptr
= RetrieveHandle(index
);
56 if (hba_ptr
== NULL
) {
57 log(LOG_DEBUG
, ROUTINE
, "Invalid handle %08lx.", handle
);
58 unlock(&open_handles_lock
);
59 unlock(&all_hbas_lock
);
60 return (HBA_STATUS_ERROR_INVALID_HANDLE
);
63 /* Check for stale data */
64 status
= verifyAdapter(hba_ptr
);
65 if (status
!= HBA_STATUS_OK
) {
66 log(LOG_DEBUG
, ROUTINE
, "Verify adapter failed");
67 unlock(&open_handles_lock
);
68 unlock(&all_hbas_lock
);
72 if (hba_ptr
->first_port
== NULL
) {
73 /* This is probably an internal failure of the library */
74 if (hba_ptr
->device_path
) {
75 log(LOG_DEBUG
, ROUTINE
,
76 "Internal failure: Adapter %s contains "
77 "no port data", hba_ptr
->device_path
);
79 log(LOG_DEBUG
, ROUTINE
,
80 "Internal failure: Adapter at index %d contains "
81 "no port data", hba_ptr
->index
);
83 unlock(&open_handles_lock
);
84 unlock(&all_hbas_lock
);
85 return (HBA_STATUS_ERROR
);
88 /* Loop over all Adapter ports */
89 for (hba_port_ptr
= hba_ptr
->first_port
;
91 hba_port_ptr
= hba_port_ptr
->next
) {
93 if (validateDomainAddress(hba_port_ptr
,
94 domainPortWWN
) != HBA_STATUS_OK
) {
100 if (wwnConversion(hba_port_ptr
->port_attributes
.
101 PortSpecificAttribute
.SASPort
->LocalSASAddress
.wwn
) ==
102 wwnConversion(portWWN
.wwn
)) {
104 * We should indicate an error if we enter here
105 * without domainPortWWN set.
107 if (chkDomainPort
== 0) {
108 log(LOG_DEBUG
, ROUTINE
,
109 "Domain Port WWN should be set when "
110 "querying HBA port %016llx for "
112 wwnConversion(portWWN
.wwn
), handle
);
113 unlock(&open_handles_lock
);
114 unlock(&all_hbas_lock
);
115 return (HBA_STATUS_ERROR_ARG
);
117 attributes
->PortType
=
118 hba_port_ptr
->port_attributes
.PortType
;
119 attributes
->PortState
=
120 hba_port_ptr
->port_attributes
.PortState
;
121 (void) strlcpy(attributes
->OSDeviceName
,
122 hba_port_ptr
->port_attributes
.OSDeviceName
,
123 sizeof (attributes
->OSDeviceName
));
124 (void) memcpy(attributes
->PortSpecificAttribute
.SASPort
,
125 hba_port_ptr
->port_attributes
.PortSpecificAttribute
.
126 SASPort
, sizeof (struct SMHBA_SAS_Port
));
128 unlock(&open_handles_lock
);
129 unlock(&all_hbas_lock
);
130 return (HBA_STATUS_OK
);
133 /* check to make sure there are devices attached to this port */
134 if (hba_port_ptr
->first_attached_port
!= NULL
) {
136 /* Loop over all discovered ports */
137 for (hba_disco_port
= hba_port_ptr
->first_attached_port
;
138 hba_disco_port
!= NULL
;
139 hba_disco_port
= hba_disco_port
->next
) {
140 if (wwnConversion(hba_disco_port
->
141 port_attributes
.PortSpecificAttribute
.
142 SASPort
->LocalSASAddress
.wwn
) ==
143 wwnConversion(portWWN
.wwn
)) {
144 attributes
->PortType
=
145 hba_disco_port
->port_attributes
.
147 attributes
->PortState
=
148 hba_disco_port
->port_attributes
.
150 (void) strlcpy(attributes
->OSDeviceName
,
151 hba_disco_port
->port_attributes
.
153 sizeof (attributes
->OSDeviceName
));
154 (void) memcpy(attributes
->
155 PortSpecificAttribute
.SASPort
,
156 hba_disco_port
->port_attributes
.
157 PortSpecificAttribute
.SASPort
,
158 sizeof (struct SMHBA_SAS_Port
));
159 unlock(&open_handles_lock
);
160 unlock(&all_hbas_lock
);
161 return (HBA_STATUS_OK
);
166 log(LOG_DEBUG
, ROUTINE
,
167 "Invalid Port WWN %016llx for handle %08lx",
168 wwnConversion(portWWN
.wwn
), handle
);
169 unlock(&open_handles_lock
);
170 unlock(&all_hbas_lock
);
171 return (HBA_STATUS_ERROR_ILLEGAL_WWN
);
174 if (chkDomainPort
&& domainFound
== 0) {
175 log(LOG_DEBUG
, ROUTINE
, "No Matching domain port"
176 " (%16llx) for port (%16llx) for handle %08lx",
177 wwnConversion(domainPortWWN
.wwn
),
178 wwnConversion(portWWN
.wwn
),
181 /* We enter here only when chkDomainPort == 0 */
182 log(LOG_DEBUG
, ROUTINE
,
183 "Invalid Port WWN %016llx for handle %08lx",
184 wwnConversion(portWWN
.wwn
), handle
);
186 unlock(&open_handles_lock
);
187 unlock(&all_hbas_lock
);
188 return (HBA_STATUS_ERROR_ILLEGAL_WWN
);