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