xref: /illumos-gate/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetAssociatedTPGOidList.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <syslog.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <stropts.h>
30 
31 #include "mp_utils.h"
32 MP_STATUS
33 MP_GetAssociatedTPGOidList(MP_OID oid, MP_OID_LIST **ppList)
34 {
35 	MP_STATUS mpStatus = MP_STATUS_SUCCESS;
36 
37 
38 	log(LOG_INFO, "MP_GetAssociatedTPGOidList()", " - enter");
39 
40 
41 	mpStatus = getAssociatedTPGOidList(oid, ppList);
42 
43 
44 	log(LOG_INFO, "MP_GetAssociatedTPGOidList()", " - exit");
45 
46 	return (mpStatus);
47 }
48 
49 
50 MP_STATUS
51 getAssociatedTPGOidList(MP_OID oid, MP_OID_LIST **ppList)
52 {
53 	mp_iocdata_t mp_ioctl;
54 
55 	uint64_t *objList = NULL;
56 
57 	int numOBJ = 0;
58 	int i = 0;
59 	int ioctlStatus = 0;
60 
61 	MP_STATUS mpStatus = MP_STATUS_SUCCESS;
62 
63 
64 	log(LOG_INFO, "getAssociatedTPGOidList()", " - enter");
65 
66 
67 	log(LOG_INFO, "getAssociatedTPGOidList()",
68 		"oid.objectSequenceNumber = %llx",
69 		oid.objectSequenceNumber);
70 
71 	if (g_scsi_vhci_fd < 0) {
72 		log(LOG_INFO, "getAssociatedTPGOidList()",
73 		    "invalid driver file handle");
74 		log(LOG_INFO, "getAssociatedTPGOidList()", " - error exit");
75 		return (MP_STATUS_FAILED);
76 	}
77 
78 	objList = (uint64_t *)calloc(1, DEFAULT_BUFFER_SIZE_TPG);
79 	if (NULL == objList) {
80 		log(LOG_INFO, "getAssociatedTPGOidList()",
81 			"no memory for objList(1)");
82 		log(LOG_INFO, "getAssociatedTPGOidList()",
83 			" - error exit");
84 		return (MP_STATUS_INSUFFICIENT_MEMORY);
85 	}
86 
87 	(void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t));
88 
89 	mp_ioctl.mp_cmd  = MP_GET_TPG_LIST;
90 	mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber;
91 	mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber);
92 	mp_ioctl.mp_obuf = (caddr_t)objList;
93 	mp_ioctl.mp_olen = DEFAULT_BUFFER_SIZE_TPG;
94 	mp_ioctl.mp_xfer = MP_XFER_READ;
95 
96 	log(LOG_INFO, "getAssociatedTPGOidList()",
97 		"mp_ioctl.mp_cmd (MP_GET_TPG_LIST) : %d",
98 		mp_ioctl.mp_cmd);
99 	log(LOG_INFO, "getAssociatedTPGOidList()",
100 		"mp_ioctl.mp_obuf: %x", mp_ioctl.mp_obuf);
101 	log(LOG_INFO, "getAssociatedTPGOidList()",
102 		"mp_ioctl.mp_olen: %d", mp_ioctl.mp_olen);
103 	log(LOG_INFO, "getAssociatedTPGOidList()",
104 		"mp_ioctl.mp_xfer: %d (MP_XFER_READ)",
105 		mp_ioctl.mp_xfer);
106 
107 	ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl);
108 	log(LOG_INFO, "getAssociatedTPGOidList()",
109 		"ioctl call returned ioctlStatus: %d",
110 		ioctlStatus);
111 
112 	if (ioctlStatus < 0) {
113 		ioctlStatus = errno;
114 	}
115 
116 	if ((ioctlStatus != 0) && (MP_MORE_DATA != mp_ioctl.mp_errno)) {
117 
118 		log(LOG_INFO, "getAssociatedTPGOidList()",
119 		    "IOCTL call failed.  IOCTL error is: %d",
120 			ioctlStatus);
121 		log(LOG_INFO, "getAssociatedTPGOidList()",
122 		    "IOCTL call failed.  IOCTL error is: %s",
123 			strerror(ioctlStatus));
124 		log(LOG_INFO, "getAssociatedTPGOidList()",
125 		    "IOCTL call failed.  mp_ioctl.mp_errno: %x",
126 			mp_ioctl.mp_errno);
127 
128 
129 		free(objList);
130 
131 		if (ENOTSUP == ioctlStatus) {
132 			mpStatus = MP_STATUS_UNSUPPORTED;
133 		} else if (0 == mp_ioctl.mp_errno) {
134 			mpStatus = MP_STATUS_FAILED;
135 		} else {
136 			mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno);
137 		}
138 
139 		log(LOG_INFO, "getAssociatedTPGOidList()",
140 			" - error exit, returning %d to caller.", mpStatus);
141 
142 		return (mpStatus);
143 	}
144 
145 	log(LOG_INFO, "getAssociatedTPGOidList()",
146 		" - mp_ioctl.mp_alen : %d",
147 		mp_ioctl.mp_alen);
148 	log(LOG_INFO, "getAssociatedTPGOidList()",
149 		" - sizeof (uint64_t): %d",
150 		sizeof (uint64_t));
151 
152 	numOBJ = mp_ioctl.mp_alen / sizeof (uint64_t);
153 	log(LOG_INFO, "getAssociatedTPGOidList()",
154 	    "Length of list: %d", numOBJ);
155 
156 	if (numOBJ < 1) {
157 		log(LOG_INFO, "getAssociatedTPGOidList()",
158 			"driver returned empty list.");
159 
160 		free(objList);
161 
162 		*ppList = createOidList(1);
163 		if (NULL == *ppList) {
164 			log(LOG_INFO,
165 				"getAssociatedTPGOidList()",
166 				"no memory for MP_OID_LIST");
167 			log(LOG_INFO,
168 				"getAssociatedTPGOidList()",
169 				" - error exit");
170 			return (MP_STATUS_INSUFFICIENT_MEMORY);
171 		}
172 
173 		return (MP_STATUS_SUCCESS);
174 	}
175 
176 	if (mp_ioctl.mp_alen > DEFAULT_BUFFER_SIZE_TPG) {
177 
178 		log(LOG_INFO, "getAssociatedTPGOidList()",
179 			"buffer size too small, need : %d",
180 			mp_ioctl.mp_alen);
181 
182 		free(objList);
183 
184 		objList = (uint64_t *)calloc(1, numOBJ * sizeof (uint64_t));
185 		if (NULL == objList) {
186 			log(LOG_INFO, "getAssociatedTPGOidList()",
187 				"no memory for objList(2)");
188 			log(LOG_INFO, "getAssociatedTPGOidList()",
189 				" - error exit");
190 			return (MP_STATUS_INSUFFICIENT_MEMORY);
191 		}
192 
193 		(void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t));
194 
195 		mp_ioctl.mp_cmd  = MP_GET_TPG_LIST;
196 		mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber;
197 		mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber);
198 		mp_ioctl.mp_obuf = (caddr_t)objList;
199 		mp_ioctl.mp_olen = numOBJ * sizeof (uint64_t);
200 		mp_ioctl.mp_xfer = MP_XFER_READ;
201 
202 		log(LOG_INFO, "getAssociatedTPGOidList()",
203 			"mp_ioctl.mp_cmd (MP_GET_TPG_LIST) : %d",
204 			mp_ioctl.mp_cmd);
205 		log(LOG_INFO, "getAssociatedTPGOidList()",
206 			"mp_ioctl.mp_obuf: %x", mp_ioctl.mp_obuf);
207 		log(LOG_INFO, "getAssociatedTPGOidList()",
208 			"mp_ioctl.mp_olen: %d", mp_ioctl.mp_olen);
209 		log(LOG_INFO, "getAssociatedTPGOidList()",
210 			"mp_ioctl.mp_xfer: %d (MP_XFER_READ)",
211 			mp_ioctl.mp_xfer);
212 
213 
214 		ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl);
215 		log(LOG_INFO, "getAssociatedTPGOidList()",
216 			"ioctl call returned ioctlStatus: %d",
217 			ioctlStatus);
218 
219 		if (ioctlStatus < 0) {
220 			ioctlStatus = errno;
221 		}
222 
223 		if (ioctlStatus != 0) {
224 
225 			log(LOG_INFO, "getAssociatedTPGOidList()",
226 				"IOCTL call failed.  IOCTL error is: %d",
227 				ioctlStatus);
228 			log(LOG_INFO, "getAssociatedTPGOidList()",
229 				"IOCTL call failed.  IOCTL error is: %s",
230 				strerror(ioctlStatus));
231 			log(LOG_INFO, "getAssociatedTPGOidList()",
232 				"IOCTL call failed.  mp_ioctl.mp_errno: %x",
233 				mp_ioctl.mp_errno);
234 
235 
236 			free(objList);
237 
238 			if (ENOTSUP == ioctlStatus) {
239 				mpStatus = MP_STATUS_UNSUPPORTED;
240 			} else if (0 == mp_ioctl.mp_errno) {
241 				mpStatus = MP_STATUS_FAILED;
242 			} else {
243 				mpStatus =
244 					getStatus4ErrorCode(mp_ioctl.mp_errno);
245 			}
246 
247 			log(LOG_INFO, "getAssociatedTPGOidList()",
248 				" - error exit");
249 
250 			return (mpStatus);
251 		}
252 	}
253 
254 
255 	*ppList = createOidList(numOBJ);
256 	if (NULL == *ppList) {
257 		log(LOG_INFO, "getAssociatedTPGOidList()",
258 			"no memory for *ppList");
259 		free(objList);
260 		log(LOG_INFO, "getAssociatedTPGOidList()",
261 			" - error exit");
262 		return (MP_STATUS_INSUFFICIENT_MEMORY);
263 	}
264 
265 	(*ppList)->oidCount = numOBJ;
266 
267 	log(LOG_INFO, "getAssociatedTPGOidList()",
268 		"(*ppList)->oidCount = %d",
269 		(*ppList)->oidCount);
270 
271 	for (i = 0; i < numOBJ; i++) {
272 		(*ppList)->oids[i].objectType =
273 			MP_OBJECT_TYPE_TARGET_PORT_GROUP;
274 		(*ppList)->oids[i].ownerId = g_pluginOwnerID;
275 		(*ppList)->oids[i].objectSequenceNumber = objList[i];
276 
277 		log(LOG_INFO, "getAssociatedTPGOidList()",
278 			"(*ppList)->oids[%d].objectType           = %d",
279 			i, (*ppList)->oids[i].objectType);
280 		log(LOG_INFO, "getAssociatedTPGOidList()",
281 			"(*ppList)->oids[%d].ownerId              = %d",
282 			i, (*ppList)->oids[i].ownerId);
283 		log(LOG_INFO, "getAssociatedTPGOidList()",
284 			"(*ppList)->oids[%d].objectSequenceNumber = %llx",
285 			i, (*ppList)->oids[i].objectSequenceNumber);
286 	}
287 
288 	free(objList);
289 
290 
291 	log(LOG_INFO, "getAssociatedTPGOidList()",
292 		" - exit");
293 
294 	return (MP_STATUS_SUCCESS);
295 }
296