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