xref: /onnv-gate/usr/src/lib/sun_sas/common/Sun_sasGetTargetMapping.c (revision 10652:9d0aff74d6fd)
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