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