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
MP_GetAssociatedTPGOidList(MP_OID oid,MP_OID_LIST ** ppList)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
getAssociatedTPGOidList(MP_OID oid,MP_OID_LIST ** ppList)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