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
34MP_STATUS
35MP_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