1*10652SHyon.Kim@Sun.COM /*
2*10652SHyon.Kim@Sun.COM * CDDL HEADER START
3*10652SHyon.Kim@Sun.COM *
4*10652SHyon.Kim@Sun.COM * The contents of this file are subject to the terms of the
5*10652SHyon.Kim@Sun.COM * Common Development and Distribution License (the "License").
6*10652SHyon.Kim@Sun.COM * You may not use this file except in compliance with the License.
7*10652SHyon.Kim@Sun.COM *
8*10652SHyon.Kim@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10652SHyon.Kim@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*10652SHyon.Kim@Sun.COM * See the License for the specific language governing permissions
11*10652SHyon.Kim@Sun.COM * and limitations under the License.
12*10652SHyon.Kim@Sun.COM *
13*10652SHyon.Kim@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*10652SHyon.Kim@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10652SHyon.Kim@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*10652SHyon.Kim@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*10652SHyon.Kim@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*10652SHyon.Kim@Sun.COM *
19*10652SHyon.Kim@Sun.COM * CDDL HEADER END
20*10652SHyon.Kim@Sun.COM */
21*10652SHyon.Kim@Sun.COM
22*10652SHyon.Kim@Sun.COM /*
23*10652SHyon.Kim@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24*10652SHyon.Kim@Sun.COM * Use is subject to license terms.
25*10652SHyon.Kim@Sun.COM */
26*10652SHyon.Kim@Sun.COM
27*10652SHyon.Kim@Sun.COM #include <sun_sas.h>
28*10652SHyon.Kim@Sun.COM
29*10652SHyon.Kim@Sun.COM /*
30*10652SHyon.Kim@Sun.COM * Retrieves the mapping between targets and OS SCSI information
31*10652SHyon.Kim@Sun.COM */
32*10652SHyon.Kim@Sun.COM HBA_STATUS
Sun_sasGetTargetMapping(HBA_HANDLE handle,HBA_WWN hbaPortWWN,HBA_WWN domainPortWWN,SMHBA_TARGETMAPPING * mapping)33*10652SHyon.Kim@Sun.COM Sun_sasGetTargetMapping(HBA_HANDLE handle, HBA_WWN hbaPortWWN,
34*10652SHyon.Kim@Sun.COM HBA_WWN domainPortWWN, SMHBA_TARGETMAPPING *mapping)
35*10652SHyon.Kim@Sun.COM {
36*10652SHyon.Kim@Sun.COM const char ROUTINE[] = "Sun_sasGetTargetMapping";
37*10652SHyon.Kim@Sun.COM int i, index;
38*10652SHyon.Kim@Sun.COM int hbaPortFound = 0;
39*10652SHyon.Kim@Sun.COM int domainPortFound = 0;
40*10652SHyon.Kim@Sun.COM uint_t total_entries = 0;
41*10652SHyon.Kim@Sun.COM struct sun_sas_hba *hba_ptr;
42*10652SHyon.Kim@Sun.COM struct sun_sas_port *hba_port_ptr, *hba_disco_port;
43*10652SHyon.Kim@Sun.COM struct ScsiEntryList *mapping_ptr;
44*10652SHyon.Kim@Sun.COM
45*10652SHyon.Kim@Sun.COM if (mapping == NULL) {
46*10652SHyon.Kim@Sun.COM log(LOG_DEBUG, ROUTINE, "NULL mapping buffer");
47*10652SHyon.Kim@Sun.COM return (HBA_STATUS_ERROR_ARG);
48*10652SHyon.Kim@Sun.COM }
49*10652SHyon.Kim@Sun.COM
50*10652SHyon.Kim@Sun.COM lock(&all_hbas_lock);
51*10652SHyon.Kim@Sun.COM index = RetrieveIndex(handle);
52*10652SHyon.Kim@Sun.COM lock(&open_handles_lock);
53*10652SHyon.Kim@Sun.COM hba_ptr = RetrieveHandle(index);
54*10652SHyon.Kim@Sun.COM if (hba_ptr == NULL) {
55*10652SHyon.Kim@Sun.COM log(LOG_DEBUG, ROUTINE, "Invalid handle %08lx.", handle);
56*10652SHyon.Kim@Sun.COM /* on error, need to set NumberOfEntries to 0 */
57*10652SHyon.Kim@Sun.COM mapping->NumberOfEntries = 0;
58*10652SHyon.Kim@Sun.COM unlock(&open_handles_lock);
59*10652SHyon.Kim@Sun.COM unlock(&all_hbas_lock);
60*10652SHyon.Kim@Sun.COM return (HBA_STATUS_ERROR_INVALID_HANDLE);
61*10652SHyon.Kim@Sun.COM }
62*10652SHyon.Kim@Sun.COM
63*10652SHyon.Kim@Sun.COM /*
64*10652SHyon.Kim@Sun.COM * We should indicate an error if no domainPortWWN passed in.
65*10652SHyon.Kim@Sun.COM */
66*10652SHyon.Kim@Sun.COM if (wwnConversion(domainPortWWN.wwn) == 0) {
67*10652SHyon.Kim@Sun.COM log(LOG_DEBUG, ROUTINE, "domainPortWWN must be provided");
68*10652SHyon.Kim@Sun.COM mapping->NumberOfEntries = 0;
69*10652SHyon.Kim@Sun.COM unlock(&open_handles_lock);
70*10652SHyon.Kim@Sun.COM unlock(&all_hbas_lock);
71*10652SHyon.Kim@Sun.COM return (HBA_STATUS_ERROR_ARG);
72*10652SHyon.Kim@Sun.COM }
73*10652SHyon.Kim@Sun.COM /*
74*10652SHyon.Kim@Sun.COM * walk through the list of ports for this hba and count up the number
75*10652SHyon.Kim@Sun.COM * of discovered ports on each hba port
76*10652SHyon.Kim@Sun.COM */
77*10652SHyon.Kim@Sun.COM i = 0;
78*10652SHyon.Kim@Sun.COM for (hba_port_ptr = hba_ptr->first_port; hba_port_ptr != NULL;
79*10652SHyon.Kim@Sun.COM hba_port_ptr = hba_port_ptr->next) {
80*10652SHyon.Kim@Sun.COM if (hbaPortFound == 0) {
81*10652SHyon.Kim@Sun.COM if (wwnConversion(hba_port_ptr->port_attributes.
82*10652SHyon.Kim@Sun.COM PortSpecificAttribute.SASPort->LocalSASAddress.wwn)
83*10652SHyon.Kim@Sun.COM != wwnConversion(hbaPortWWN.wwn)) {
84*10652SHyon.Kim@Sun.COM /*
85*10652SHyon.Kim@Sun.COM * Since all the ports under the same HBA have
86*10652SHyon.Kim@Sun.COM * the same LocalSASAddress, we should break
87*10652SHyon.Kim@Sun.COM * the loop once we find it dosn't match.
88*10652SHyon.Kim@Sun.COM */
89*10652SHyon.Kim@Sun.COM break;
90*10652SHyon.Kim@Sun.COM } else {
91*10652SHyon.Kim@Sun.COM hbaPortFound = 1;
92*10652SHyon.Kim@Sun.COM }
93*10652SHyon.Kim@Sun.COM }
94*10652SHyon.Kim@Sun.COM
95*10652SHyon.Kim@Sun.COM /*
96*10652SHyon.Kim@Sun.COM * Check whether the domainPortWWN matches.
97*10652SHyon.Kim@Sun.COM */
98*10652SHyon.Kim@Sun.COM if ((validateDomainAddress(hba_port_ptr, domainPortWWN))
99*10652SHyon.Kim@Sun.COM != HBA_STATUS_OK) {
100*10652SHyon.Kim@Sun.COM continue;
101*10652SHyon.Kim@Sun.COM }
102*10652SHyon.Kim@Sun.COM domainPortFound = 1;
103*10652SHyon.Kim@Sun.COM
104*10652SHyon.Kim@Sun.COM for (hba_disco_port = hba_port_ptr->first_attached_port;
105*10652SHyon.Kim@Sun.COM hba_disco_port != NULL;
106*10652SHyon.Kim@Sun.COM hba_disco_port = hba_disco_port->next) {
107*10652SHyon.Kim@Sun.COM for (mapping_ptr = hba_disco_port->scsiInfo;
108*10652SHyon.Kim@Sun.COM mapping_ptr != NULL;
109*10652SHyon.Kim@Sun.COM mapping_ptr = mapping_ptr->next) {
110*10652SHyon.Kim@Sun.COM /*
111*10652SHyon.Kim@Sun.COM * Add the information as much as mapping
112*10652SHyon.Kim@Sun.COM * can hold.
113*10652SHyon.Kim@Sun.COM */
114*10652SHyon.Kim@Sun.COM if (wwnConversion(domainPortWWN.wwn) !=
115*10652SHyon.Kim@Sun.COM wwnConversion(mapping_ptr->entry.
116*10652SHyon.Kim@Sun.COM PortLun.domainPortWWN.wwn)) {
117*10652SHyon.Kim@Sun.COM continue;
118*10652SHyon.Kim@Sun.COM }
119*10652SHyon.Kim@Sun.COM
120*10652SHyon.Kim@Sun.COM if (total_entries < mapping->NumberOfEntries) {
121*10652SHyon.Kim@Sun.COM (void) memcpy(&mapping->entry[i].ScsiId,
122*10652SHyon.Kim@Sun.COM &mapping_ptr->entry.ScsiId,
123*10652SHyon.Kim@Sun.COM sizeof (SMHBA_SCSIID));
124*10652SHyon.Kim@Sun.COM (void) memcpy(&mapping->entry[i].
125*10652SHyon.Kim@Sun.COM PortLun, &mapping_ptr->entry.
126*10652SHyon.Kim@Sun.COM PortLun, sizeof (SMHBA_PORTLUN));
127*10652SHyon.Kim@Sun.COM (void) memcpy(&mapping->entry[i].LUID,
128*10652SHyon.Kim@Sun.COM &mapping_ptr->entry.LUID,
129*10652SHyon.Kim@Sun.COM sizeof (SMHBA_LUID));
130*10652SHyon.Kim@Sun.COM i++;
131*10652SHyon.Kim@Sun.COM }
132*10652SHyon.Kim@Sun.COM total_entries++;
133*10652SHyon.Kim@Sun.COM }
134*10652SHyon.Kim@Sun.COM }
135*10652SHyon.Kim@Sun.COM }
136*10652SHyon.Kim@Sun.COM
137*10652SHyon.Kim@Sun.COM /*
138*10652SHyon.Kim@Sun.COM * check to make sure user has passed in an acceptable PortWWN for
139*10652SHyon.Kim@Sun.COM * the given handle
140*10652SHyon.Kim@Sun.COM */
141*10652SHyon.Kim@Sun.COM if (hbaPortFound == 0) {
142*10652SHyon.Kim@Sun.COM log(LOG_DEBUG, ROUTINE, "Unable to locate requested "
143*10652SHyon.Kim@Sun.COM "HBA Port WWN %016llx on handle %08lx",
144*10652SHyon.Kim@Sun.COM wwnConversion(hbaPortWWN.wwn), handle);
145*10652SHyon.Kim@Sun.COM unlock(&open_handles_lock);
146*10652SHyon.Kim@Sun.COM unlock(&all_hbas_lock);
147*10652SHyon.Kim@Sun.COM return (HBA_STATUS_ERROR_ILLEGAL_WWN);
148*10652SHyon.Kim@Sun.COM }
149*10652SHyon.Kim@Sun.COM
150*10652SHyon.Kim@Sun.COM if (domainPortFound == 0) {
151*10652SHyon.Kim@Sun.COM log(LOG_DEBUG, ROUTINE, "No matching domain "
152*10652SHyon.Kim@Sun.COM "port %016llx for port %016llx on handle "
153*10652SHyon.Kim@Sun.COM "%08lx", wwnConversion(domainPortWWN.wwn),
154*10652SHyon.Kim@Sun.COM wwnConversion(hbaPortWWN.wwn), handle);
155*10652SHyon.Kim@Sun.COM unlock(&open_handles_lock);
156*10652SHyon.Kim@Sun.COM unlock(&all_hbas_lock);
157*10652SHyon.Kim@Sun.COM return (HBA_STATUS_ERROR_ILLEGAL_WWN);
158*10652SHyon.Kim@Sun.COM }
159*10652SHyon.Kim@Sun.COM
160*10652SHyon.Kim@Sun.COM if (total_entries > mapping->NumberOfEntries) {
161*10652SHyon.Kim@Sun.COM log(LOG_DEBUG, ROUTINE,
162*10652SHyon.Kim@Sun.COM "total entries: %d: mapping->NumberofEntries: %d.",
163*10652SHyon.Kim@Sun.COM total_entries, mapping->NumberOfEntries);
164*10652SHyon.Kim@Sun.COM mapping->NumberOfEntries = total_entries;
165*10652SHyon.Kim@Sun.COM unlock(&open_handles_lock);
166*10652SHyon.Kim@Sun.COM unlock(&all_hbas_lock);
167*10652SHyon.Kim@Sun.COM return (HBA_STATUS_ERROR_MORE_DATA);
168*10652SHyon.Kim@Sun.COM }
169*10652SHyon.Kim@Sun.COM
170*10652SHyon.Kim@Sun.COM mapping->NumberOfEntries = total_entries;
171*10652SHyon.Kim@Sun.COM
172*10652SHyon.Kim@Sun.COM /* convert devpath to dev link */
173*10652SHyon.Kim@Sun.COM convertDevpathToDevlink(mapping);
174*10652SHyon.Kim@Sun.COM
175*10652SHyon.Kim@Sun.COM unlock(&open_handles_lock);
176*10652SHyon.Kim@Sun.COM unlock(&all_hbas_lock);
177*10652SHyon.Kim@Sun.COM
178*10652SHyon.Kim@Sun.COM return (HBA_STATUS_OK);
179*10652SHyon.Kim@Sun.COM }
180