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 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 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