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 mapping between targets and OS SCSI information
33 Sun_sasGetTargetMapping(HBA_HANDLE handle
, HBA_WWN hbaPortWWN
,
34 HBA_WWN domainPortWWN
, SMHBA_TARGETMAPPING
*mapping
)
36 const char ROUTINE
[] = "Sun_sasGetTargetMapping";
39 int domainPortFound
= 0;
40 uint_t total_entries
= 0;
41 struct sun_sas_hba
*hba_ptr
;
42 struct sun_sas_port
*hba_port_ptr
, *hba_disco_port
;
43 struct ScsiEntryList
*mapping_ptr
;
45 if (mapping
== NULL
) {
46 log(LOG_DEBUG
, ROUTINE
, "NULL mapping buffer");
47 return (HBA_STATUS_ERROR_ARG
);
51 index
= RetrieveIndex(handle
);
52 lock(&open_handles_lock
);
53 hba_ptr
= RetrieveHandle(index
);
54 if (hba_ptr
== NULL
) {
55 log(LOG_DEBUG
, ROUTINE
, "Invalid handle %08lx.", handle
);
56 /* on error, need to set NumberOfEntries to 0 */
57 mapping
->NumberOfEntries
= 0;
58 unlock(&open_handles_lock
);
59 unlock(&all_hbas_lock
);
60 return (HBA_STATUS_ERROR_INVALID_HANDLE
);
64 * We should indicate an error if no domainPortWWN passed in.
66 if (wwnConversion(domainPortWWN
.wwn
) == 0) {
67 log(LOG_DEBUG
, ROUTINE
, "domainPortWWN must be provided");
68 mapping
->NumberOfEntries
= 0;
69 unlock(&open_handles_lock
);
70 unlock(&all_hbas_lock
);
71 return (HBA_STATUS_ERROR_ARG
);
74 * walk through the list of ports for this hba and count up the number
75 * of discovered ports on each hba port
78 for (hba_port_ptr
= hba_ptr
->first_port
; hba_port_ptr
!= NULL
;
79 hba_port_ptr
= hba_port_ptr
->next
) {
80 if (hbaPortFound
== 0) {
81 if (wwnConversion(hba_port_ptr
->port_attributes
.
82 PortSpecificAttribute
.SASPort
->LocalSASAddress
.wwn
)
83 != wwnConversion(hbaPortWWN
.wwn
)) {
85 * Since all the ports under the same HBA have
86 * the same LocalSASAddress, we should break
87 * the loop once we find it dosn't match.
96 * Check whether the domainPortWWN matches.
98 if ((validateDomainAddress(hba_port_ptr
, domainPortWWN
))
104 for (hba_disco_port
= hba_port_ptr
->first_attached_port
;
105 hba_disco_port
!= NULL
;
106 hba_disco_port
= hba_disco_port
->next
) {
107 for (mapping_ptr
= hba_disco_port
->scsiInfo
;
109 mapping_ptr
= mapping_ptr
->next
) {
111 * Add the information as much as mapping
114 if (wwnConversion(domainPortWWN
.wwn
) !=
115 wwnConversion(mapping_ptr
->entry
.
116 PortLun
.domainPortWWN
.wwn
)) {
120 if (total_entries
< mapping
->NumberOfEntries
) {
121 (void) memcpy(&mapping
->entry
[i
].ScsiId
,
122 &mapping_ptr
->entry
.ScsiId
,
123 sizeof (SMHBA_SCSIID
));
124 (void) memcpy(&mapping
->entry
[i
].
125 PortLun
, &mapping_ptr
->entry
.
126 PortLun
, sizeof (SMHBA_PORTLUN
));
127 (void) memcpy(&mapping
->entry
[i
].LUID
,
128 &mapping_ptr
->entry
.LUID
,
129 sizeof (SMHBA_LUID
));
138 * check to make sure user has passed in an acceptable PortWWN for
141 if (hbaPortFound
== 0) {
142 log(LOG_DEBUG
, ROUTINE
, "Unable to locate requested "
143 "HBA Port WWN %016llx on handle %08lx",
144 wwnConversion(hbaPortWWN
.wwn
), handle
);
145 unlock(&open_handles_lock
);
146 unlock(&all_hbas_lock
);
147 return (HBA_STATUS_ERROR_ILLEGAL_WWN
);
150 if (domainPortFound
== 0) {
151 log(LOG_DEBUG
, ROUTINE
, "No matching domain "
152 "port %016llx for port %016llx on handle "
153 "%08lx", wwnConversion(domainPortWWN
.wwn
),
154 wwnConversion(hbaPortWWN
.wwn
), handle
);
155 unlock(&open_handles_lock
);
156 unlock(&all_hbas_lock
);
157 return (HBA_STATUS_ERROR_ILLEGAL_WWN
);
160 if (total_entries
> mapping
->NumberOfEntries
) {
161 log(LOG_DEBUG
, ROUTINE
,
162 "total entries: %d: mapping->NumberofEntries: %d.",
163 total_entries
, mapping
->NumberOfEntries
);
164 mapping
->NumberOfEntries
= total_entries
;
165 unlock(&open_handles_lock
);
166 unlock(&all_hbas_lock
);
167 return (HBA_STATUS_ERROR_MORE_DATA
);
170 mapping
->NumberOfEntries
= total_entries
;
172 /* convert devpath to dev link */
173 convertDevpathToDevlink(mapping
);
175 unlock(&open_handles_lock
);
176 unlock(&all_hbas_lock
);
178 return (HBA_STATUS_OK
);