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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <unistd.h>
30 #include <netdb.h>
31 #include <errno.h>
32 
33 #include "util.h"
34 #include "cimKeys.h"
35 #include "providerNames.h"
36 #include "messageStrings.h"
37 #include "drive_descriptors.h"
38 #include "ctrl_descriptors.h"
39 #include "Solaris_SCSIInterface.h"
40 
41 #define	SCSI_GETINSTANCE	"SCSI_INTERFACE,GET_INSTANCE"
42 #define	SCSI_ENUMINSTANCES	"SCSI_INTERFACE,ENUM_INSTANCES"
43 #define	SCSI_ENUMINSTANCENAMES	"SCSI_INTERFACE,ENUM_INSTANCENAMES"
44 #define	SCSI_CREATEINSTANCE	"SCSI_INTERFACE,CREATE_INSTANCE"
45 #define	SCSI_DELETEINSTANCE	"SCSI_INTERFACE,DELETE_INSTANCE"
46 #define	SCSI_SETINSTANCE	"SCSI_INTERFACE,SET_INSTANCE"
47 #define	SCSI_GETPROPERTY	"SCSI_INTERFACE,GET_PROPERTY"
48 #define	SCSI_SETPROPERTY	"SCSI_INTERFACE,SET_PROPERTY"
49 #define	SCSI_INVOKEMETHOD	"SCSI_INTERFACE,INVOKE_METHOD"
50 #define	SCSI_EXECQUERY		"SCSI_INTERFACE,EXEC_QUERY"
51 #define	SCSI_ASSOCIATORS	"SCSI_INTERFACE,ASSOCIATORS"
52 #define	SCSI_ASSOCIATORNAMES	"SCSI_INTERFACE,ASSOCIATOR_NAMES"
53 #define	SCSI_REFERENCES		"SCSI_INTERFACE,REFERENCES"
54 #define	SCSI_REFERENCENAMES	"SCSI_INTERFACE,REFERENCE_NAMES"
55 
56 static
57 CCIMInstanceList *
58 scsiIntAssocToInstList(CCIMObjectPath *pObjectName, cimchar *pObjectNameRole,
59 	CCIMObjectPathList *objList, cimchar *objRole, int *error);
60 
61 static
62 CCIMInstance  *
63 scsiIntAssocToInst(CCIMObjectPath *obj1, cimchar *obj1Role,
64 	CCIMObjectPath *obj2, cimchar *obj2Role, int *error);
65 
66 /*
67  * Solaris_SCSIInterface provider
68  *
69  * It is important to note that all memory allocated by these functions
70  * and passed to the CIMOM, is freed by the door process prior to
71  * sending a copy of the data to the CIMOM.
72  */
73 
74 /*
75  * Name: cp_getInstance_Solaris_SCSIInterface
76  *
77  * Description: Returns an instance which matches the passed in object path
78  * if found.
79  *
80  * Parameters:
81  *	pOP - An CCIMObjectPath * which contains the information on
82  *	the class for which to find the instance.
83  * Returns:
84  *	CCIMInstance * if matched instance is found. Otherwise, NULL.
85  */
86 
87 CCIMInstance*
cp_getInstance_Solaris_SCSIInterface(CCIMObjectPath * pOP)88 cp_getInstance_Solaris_SCSIInterface(CCIMObjectPath* pOP)
89 {
90 	CCIMInstance* 		inst = NULL;
91 	CCIMPropertyList* 	pCurPropList;
92 	CCIMObjectPath		*antOp = NULL;
93 	CCIMObjectPath		*depOp = NULL;
94 	dm_descriptor_t		d_descriptor;
95 	dm_descriptor_t		c_descriptor;
96 	char			*name;
97 	int			error;
98 
99 
100 	if (pOP == NULL ||
101 	    pOP->mKeyProperties == NULL) {
102 	    util_handleError(SCSI_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
103 		NULL, &error);
104 	    return ((CCIMInstance *)NULL);
105 	}
106 
107 
108 	pCurPropList = pOP->mKeyProperties;
109 	antOp = (CCIMObjectPath *)util_getKeyValue(pCurPropList, reference,
110 	    ANTECEDENT, &error);
111 
112 	if (error == 0) {
113 	    depOp = (CCIMObjectPath *)util_getKeyValue(pCurPropList, reference,
114 		DEPENDENT, &error);
115 	}
116 
117 	if (error != 0) {
118 	    util_handleError(SCSI_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
119 		NULL, &error);
120 	    return ((CCIMInstance *)NULL);
121 	}
122 
123 	/*
124 	 * Now, get the name of the antecedent from the object path.
125 	 */
126 
127 	if ((antOp->mKeyProperties) == NULL ||
128 	    (depOp->mKeyProperties) == NULL) {
129 	    util_handleError(SCSI_GETINSTANCE, CIM_ERR_INVALID_PARAMETER,
130 		NULL, NULL, &error);
131 	    return ((CCIMInstance *)NULL);
132 	}
133 
134 	pCurPropList = antOp->mKeyProperties;
135 	name = (char *)util_getKeyValue(pCurPropList, string, DEVICEID,
136 	    &error);
137 
138 	if (error != 0) {
139 	    util_handleError(SCSI_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
140 		NULL, &error);
141 	    return ((CCIMInstance *)NULL);
142 	}
143 
144 	/*
145 	 * The only reason it is needed to get the descriptor for these
146 	 * two devices is to verify that they still exist and are valid.
147 	 * If they are not found, then getting the instance for this
148 	 * association as passed in by the client is not possible.
149 	 */
150 	c_descriptor = dm_get_descriptor_by_name(DM_CONTROLLER, name,
151 	    &error);
152 	/*
153 	 * Not found. Return a null instance.
154 	 */
155 
156 	if (error == ENODEV || c_descriptor == NULL) {
157 	    return ((CCIMInstance *)NULL);
158 	}
159 	if (error != 0) {
160 	    util_handleError(SCSI_GETINSTANCE, CIM_ERR_FAILED,
161 		DM_GET_DESC_BYNAME_FAILURE, NULL, &error);
162 	    return ((CCIMInstance*)NULL);
163 	}
164 	dm_free_descriptor(c_descriptor);
165 
166 	/*
167 	 * Now, get the name of the dependent from the object path.
168 	 */
169 
170 	pCurPropList = depOp->mKeyProperties;
171 	name = (cimchar *)util_getKeyValue(pCurPropList, string, DEVICEID,
172 	    &error);
173 
174 	if (error != 0) {
175 	    util_handleError(SCSI_GETINSTANCE, CIM_ERR_INVALID_PARAMETER, NULL,
176 		NULL, &error);
177 	    return ((CCIMInstance *)NULL);
178 	}
179 	d_descriptor = dm_get_descriptor_by_name(DM_DRIVE, name, &error);
180 
181 	/*
182 	 * Not found. Return a null instance.
183 	 */
184 
185 	if (error == ENODEV || d_descriptor == NULL) {
186 	    return ((CCIMInstance *)NULL);
187 	}
188 
189 	if (error != 0) {
190 	    util_handleError(SCSI_GETINSTANCE, CIM_ERR_FAILED,
191 		DM_GET_DESC_BYNAME_FAILURE, NULL, &error);
192 	    return ((CCIMInstance*)NULL);
193 	}
194 
195 	dm_free_descriptor(d_descriptor);
196 
197 	/*
198 	 * At this point I have verified I have the two devices that
199 	 * are part of this association. Use the object paths I got
200 	 * earlier to create the scsiinterface instance.
201 	 */
202 	inst = scsiIntAssocToInst(antOp, ANTECEDENT, depOp, DEPENDENT, &error);
203 
204 	if (error != 0) {
205 	    util_handleError(SCSI_GETINSTANCE, CIM_ERR_FAILED,
206 		SCSIINT_ASSOC_TO_INSTANCE_FAILURE, NULL, &error);
207 	    return ((CCIMInstance *)NULL);
208 	}
209 
210 	return (inst);
211 }
212 
213 /*
214  * Name: cp_enumInstances_Solaris_SCSIInterface
215  *
216  * Description: Returns a linked list of instances of
217  *      Solaris_SCSIInterface if found.
218  *
219  * Parameters:
220  *	pOP - An CCIMObjectPath * which contains the information on
221  *	the class for which to find the instances.
222  * Returns:
223  *	CCIMInstanceList * if instances are found. NULL otherwise.
224  */
225 
226 /* ARGSUSED */
227 CCIMInstanceList*
cp_enumInstances_Solaris_SCSIInterface(CCIMObjectPath * pOP)228 cp_enumInstances_Solaris_SCSIInterface(CCIMObjectPath* pOP)
229 {
230 	CCIMInstanceList	*instList = NULL;
231 	CCIMObjectPathList	*cObjList;
232 	CCIMObjectPathList	*tmpObjList;
233 	CCIMObjectPath		*objPath;
234 	CCIMInstance		*inst;
235 	CCIMException		*ex;
236 	dm_descriptor_t		*d_descriptorp = NULL;
237 	int			error = 0;
238 
239 
240 	/*
241 	 * Get the list of SCSI Controllers. Then get the associated drives
242 	 * via the device api.
243 	 */
244 
245 	objPath = cim_createEmptyObjectPath(SCSI_CONTROLLER);
246 	if (objPath == NULL) {
247 	    ex = cim_getLastError();
248 	    util_handleError(SCSI_ENUMINSTANCES, CIM_ERR_FAILED,
249 		CREATE_OBJECT_PATH, ex, &error);
250 	    return ((CCIMInstanceList *)NULL);
251 	}
252 
253 	cObjList = cimom_enumerateInstanceNames(objPath, cim_false);
254 	cim_freeObjectPath(objPath);
255 
256 	if (cObjList == NULL) {
257 	    ex = cim_getLastError();
258 	    util_handleError(SCSI_ENUMINSTANCES, CIM_ERR_FAILED,
259 		ENUM_INSTANCENAMES_FAILURE, ex, &error);
260 	    return ((CCIMInstanceList *)NULL);
261 	}
262 
263 	/*
264 	 * If no controllers of this type, then no interfaces.
265 	 */
266 
267 	if (cObjList->mDataObject == NULL) {
268 	    return ((CCIMInstanceList *)NULL);
269 	}
270 
271 	instList = cim_createInstanceList();
272 	if (instList == NULL) {
273 	    ex = cim_getLastError();
274 	    util_handleError(SCSI_ENUMINSTANCES, CIM_ERR_FAILED,
275 		CREATE_INSTANCE_LIST_FAILURE, ex, &error);
276 	    return ((CCIMInstanceList *)NULL);
277 	}
278 	/*
279 	 * Loop through all of these controller objects and get the associated
280 	 * disks.
281 	 */
282 
283 	for (tmpObjList = cObjList; tmpObjList != NULL;
284 	    tmpObjList = tmpObjList->mNext) {
285 
286 	    char 		*name = NULL;
287 	    CCIMObjectPath 	*cOp;
288 	    CCIMInstanceList	*tmpList;
289 	    CCIMInstanceList	*tmpList1;
290 	    CCIMPropertyList	*pCurPropList;
291 	    CCIMObjectPathList	*dObjList;
292 	    CCIMInstanceList	*tL;
293 	    dm_descriptor_t	c_descriptor;
294 
295 	    cOp = tmpObjList->mDataObject;
296 	    if ((pCurPropList = cOp->mKeyProperties) == NULL) {
297 		util_handleError(SCSI_ENUMINSTANCES,
298 		    CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
299 		cim_freeObjectPathList(cObjList);
300 		cim_freeInstanceList(instList);
301 		return ((CCIMInstanceList *)NULL);
302 	    }
303 
304 	    name = (cimchar *)util_getKeyValue(pCurPropList, string,
305 		DEVICEID, &error);
306 	    if (error != 0 || name == NULL) {
307 		util_handleError(SCSI_ENUMINSTANCES,
308 		    CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
309 		cim_freeInstanceList(instList);
310 		cim_freeObjectPathList(cObjList);
311 		return ((CCIMInstanceList *)NULL);
312 	    }
313 
314 	    c_descriptor = dm_get_descriptor_by_name(DM_CONTROLLER, name,
315 		&error);
316 
317 	    if (error == ENODEV || c_descriptor == NULL) {
318 		continue;
319 	    }
320 
321 	    if (error != 0) {
322 		util_handleError(SCSI_ENUMINSTANCES, CIM_ERR_FAILED,
323 		    DM_GET_DESC_BYNAME_FAILURE, NULL, &error);
324 		cim_freeInstanceList(instList);
325 		cim_freeObjectPathList(cObjList);
326 		return ((CCIMInstanceList *)NULL);
327 	    }
328 
329 	    d_descriptorp = dm_get_associated_descriptors(c_descriptor,
330 		DM_DRIVE, &error);
331 	    dm_free_descriptor(c_descriptor);
332 		/*
333 		 * If there are no drives associated with this controller,
334 		 * continue on to the next controller.
335 		 */
336 
337 	    if (d_descriptorp == NULL) {
338 		continue;
339 	    }
340 
341 	    if (d_descriptorp[0] == NULL) {
342 		dm_free_descriptors(d_descriptorp);
343 		continue;
344 	    }
345 
346 	    if (error != 0) {
347 		util_handleError(SCSI_ENUMINSTANCES, CIM_ERR_FAILED,
348 		    DM_GET_ASSOC_FAILURE, NULL, &error);
349 		cim_freeInstanceList(instList);
350 		cim_freeObjectPathList(cObjList);
351 		return ((CCIMInstanceList *)NULL);
352 	    }
353 
354 	    tmpList = drive_descriptors_toCCIMObjPathInstList(
355 		DISK_DRIVE, d_descriptorp, &error);
356 	    dm_free_descriptors(d_descriptorp);
357 
358 	    if (error != 0) {
359 		util_handleError(SCSI_ENUMINSTANCES, CIM_ERR_FAILED,
360 		    DRIVE_DESC_TO_INSTANCE_FAILURE, NULL, &error);
361 		cim_freeInstanceList(instList);
362 		cim_freeObjectPathList(cObjList);
363 		return ((CCIMInstanceList *)NULL);
364 	    }
365 
366 	    if (tmpList == NULL) {
367 		continue;
368 	    }
369 
370 	    dObjList = cim_createObjectPathList(tmpList);
371 	    cim_freeInstanceList(tmpList);
372 
373 	    if (dObjList == NULL) {
374 		ex = cim_getLastError();
375 		util_handleError(SCSI_ENUMINSTANCES, CIM_ERR_FAILED,
376 		    CREATE_OBJECT_PATH_FAILURE, ex, &error);
377 		cim_freeInstanceList(instList);
378 		cim_freeObjectPathList(cObjList);
379 		return ((CCIMInstanceList *)NULL);
380 	    }
381 
382 	    tmpList1 = scsiIntAssocToInstList(
383 		cOp, ANTECEDENT, dObjList, DEPENDENT, &error);
384 	    cim_freeObjectPathList(dObjList);
385 
386 	    if (error != 0) {
387 		util_handleError(SCSI_ENUMINSTANCES, CIM_ERR_FAILED,
388 		    DRIVE_DESC_TO_INSTANCE_FAILURE, NULL, &error);
389 		cim_freeInstanceList(instList);
390 		cim_freeObjectPathList(cObjList);
391 		return ((CCIMInstanceList *)NULL);
392 	    }
393 
394 	    tL = tmpList1;
395 	    do {
396 		inst = cim_copyInstance(tL->mDataObject);
397 		instList = cim_addInstance(instList, inst);
398 		if (instList == NULL) {
399 		    util_handleError(SCSI_ENUMINSTANCES, CIM_ERR_FAILED,
400 			ADD_INSTANCE_FAILURE, NULL, &error);
401 		    cim_freeObjectPathList(cObjList);
402 		    cim_freeObjectPathList(tmpList1);
403 		    return ((CCIMInstanceList *)NULL);
404 		}
405 		tL = tL->mNext;
406 	    } while (tL);
407 
408 	    cim_freeInstanceList(tmpList1);
409 	} /* end for */
410 
411 	/*
412 	 * It is possible I will have an empty instance list at
413 	 * this point. So, I must check and NULL this out if
414 	 * there are no entries.
415 	 */
416 
417 	cim_freeObjectPathList(cObjList);
418 
419 	if (instList->mDataObject == NULL) {
420 	    cim_freeInstanceList(instList);
421 	    instList = NULL;
422 	}
423 
424 	return (instList);
425 }
426 
427 /*
428  * Name: cp_enumInstanceNames_Solaris_SCSIInterface
429  *
430  * Description: Returns a linked list of CCIMObjectPath *
431  *      of Solaris_SCSIInterface if found.
432  *
433  * Parameters:
434  *	pOP - An CCIMObjectPath * which contains the information on
435  *	the class for which to find the instances.
436  * Returns:
437  *	CCIMObjectPathList * if objects are found. NULL otherwise.
438  */
439 
440 /* ARGSUSED */
441 CCIMObjectPathList*
cp_enumInstanceNames_Solaris_SCSIInterface(CCIMObjectPath * pOP)442 cp_enumInstanceNames_Solaris_SCSIInterface(CCIMObjectPath * pOP) {
443 
444 	CCIMInstanceList	*instList;
445 	CCIMObjectPathList	*objList = NULL;
446 	int			error;
447 
448 
449 	if (pOP == NULL) {
450 	    util_handleError(SCSI_ENUMINSTANCENAMES,
451 		CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
452 	    return ((CCIMObjectPathList *)NULL);
453 	}
454 
455 	/*
456 	 * Call in to enumInstances and then convert the instance list in
457 	 * to an object list.
458 	 */
459 
460 	instList = cp_enumInstances_Solaris_SCSIInterface(pOP);
461 
462 	if (instList != NULL) {
463 	    objList = cim_createObjectPathList(instList);
464 	    cim_freeInstanceList(instList);
465 	}
466 
467 	return (objList);
468 }
469 
470 /*
471  * Creating an instance of a Solaris_SCSIInterface is not supported.
472  */
473 
474 /* ARGSUSED */
475 CCIMObjectPath*
cp_createInstance_Solaris_SCSIInterface(CCIMObjectPath * pOP,CCIMInstance * pInst)476 cp_createInstance_Solaris_SCSIInterface(CCIMObjectPath* pOP,
477     CCIMInstance* pInst)
478 {
479 	int	error;
480 
481 	util_handleError(SCSI_CREATEINSTANCE, CIM_ERR_NOT_SUPPORTED, NULL,
482 	    NULL, &error);
483 	return ((CCIMObjectPath *)NULL);
484 }
485 
486 
487 /*
488  * Deleting an instance of a Solaris_SCSIInterface is not supported.
489  */
490 
491 /* ARGSUSED */
492 CIMBool
cp_deleteInstance_Solaris_SCSIInterface(CCIMObjectPath * pInst)493 cp_deleteInstance_Solaris_SCSIInterface(CCIMObjectPath* pInst)
494 {
495 	int	error;
496 
497 	util_handleError(SCSI_DELETEINSTANCE, CIM_ERR_NOT_SUPPORTED, NULL,
498 	    NULL, &error);
499 	return (cim_false);
500 }
501 
502 /*
503  * Name: cp_getProperty_Solaris_SCSIInterface
504  *
505  * Description: Returns the property requested, if found.
506  *
507  * Parameters:
508  *	pOP - An CCIMObjectPath * which contains the information on
509  *	the class for which to find the instances.
510  * Returns:
511  *	CCIMProperty * if found.
512  */
513 
514 /* ARGSUSED */
515 CCIMProperty	*
cp_getProperty_Solaris_SCSIInterface(CCIMObjectPath * pOP,char * pPropName)516 cp_getProperty_Solaris_SCSIInterface(CCIMObjectPath *pOP,
517     char *pPropName)
518 {
519 
520 	CCIMProperty	*prop = NULL;
521 	CCIMInstance	*inst = NULL;
522 	int		error = 0;
523 
524 
525 	if (pOP == NULL) {
526 	    util_handleError(SCSI_GETPROPERTY, CIM_ERR_INVALID_PARAMETER, NULL,
527 		NULL, &error);
528 	    return ((CCIMProperty *)NULL);
529 	}
530 
531 	inst = cp_getInstance_Solaris_SCSIInterface(pOP);
532 	if (inst == NULL) {
533 	    return ((CCIMProperty *)NULL);
534 	}
535 
536 	prop = cim_getProperty(inst, pPropName);
537 	cim_freeInstance(inst);
538 	return (prop);
539 }
540 
541 /*
542  * Setting an instance of a Solaris_SCSIInterface is not supported.
543  */
544 
545 /* ARGSUSED */
546 CIMBool
cp_setInstance_Solaris_SCSIInterface(CCIMObjectPath * pOP,CCIMInstance * pInst)547 cp_setInstance_Solaris_SCSIInterface(CCIMObjectPath* pOP, CCIMInstance* pInst)
548 {
549 	int	error;
550 
551 	util_handleError(SCSI_SETINSTANCE, CIM_ERR_NOT_SUPPORTED, NULL,
552 	    NULL, &error);
553 	return (cim_false);
554 }
555 
556 
557 /*
558  * Setting a property on a Solaris_SCSIInterface is not supported.
559  */
560 
561 /* ARGSUSED */
562 CIMBool
cp_setProperty_Solaris_SCSIInterface(CCIMObjectPath * pOP,CCIMProperty * pProp)563 cp_setProperty_Solaris_SCSIInterface(CCIMObjectPath* pOP, CCIMProperty* pProp)
564 {
565 	int	error;
566 
567 	util_handleError(SCSI_SETPROPERTY, CIM_ERR_NOT_SUPPORTED, NULL,
568 	    NULL, &error);
569 	return (cim_false);
570 }
571 
572 /*
573  * No Methods for Solaris_SCSIInterface.
574  */
575 
576 /* ARGSUSED */
577 CCIMProperty*
cp_invokeMethod_Solaris_SCSIInterface(CCIMObjectPath * op,cimchar * methodName,CCIMPropertyList * inParams,CCIMPropertyList * outParams)578 cp_invokeMethod_Solaris_SCSIInterface(
579     CCIMObjectPath* op, cimchar* methodName,
580 	CCIMPropertyList* inParams, CCIMPropertyList* outParams)
581 {
582 	CCIMProperty	*retVal = (CCIMProperty	*)NULL;
583 	return (retVal);
584 }
585 
586 /*
587  * Name: cp_execQuery_Solaris_SCSIInterface
588  *
589  * Description:
590  * Returns an instance list which matches the query if any are found.
591  *
592  * Parameters:
593  *	CCIMObjectPath *op - An CCIMObjectPath * which contains the
594  *	information on the class for which to find the instances.
595  *
596  * 	selectList - Not used
597  *	nonJoinExp - Not used
598  *
599  * Returns:
600  *	CCIMInstance * if matched instance is found. Otherwise, NULL.
601  */
602 /*
603  * Currently, there is no WQL parser for the C providers. As a result,
604  * what is returned to the CIMOM is a list of instances with
605  * a NULL value at the beginning of the list. This NULL value indicates
606  * to the CIMOM that it must do the filtering for the client.
607  */
608 
609 /* ARGSUSED */
610 CCIMInstanceList*
cp_execQuery_Solaris_SCSIInterface(CCIMObjectPath * op,cimchar * selectList,cimchar * nonJoinExp,cimchar * queryExp,int queryType)611 cp_execQuery_Solaris_SCSIInterface(CCIMObjectPath *op,
612     cimchar *selectList, cimchar *nonJoinExp, cimchar *queryExp, int queryType)
613 {
614 	CCIMInstanceList	*instList = NULL;
615 	CCIMInstanceList	*result;
616 	CCIMInstance		*emptyInst;
617 	CCIMException		*ex;
618 	int			error;
619 
620 
621 	if (op == NULL) {
622 	    util_handleError(SCSI_EXECQUERY, CIM_ERR_INVALID_PARAMETER,
623 		NULL, NULL, &error);
624 	    return ((CCIMInstanceList *)NULL);
625 	}
626 
627 	instList = cp_enumInstances_Solaris_SCSIInterface(op);
628 
629 	if (instList == NULL) {
630 	    return (instList);
631 	}
632 
633 	/*
634 	 * Create a null instance and add it to the beginning
635 	 * of the list to indicate to the CIMOM that no filtering
636 	 * was done.
637 	 */
638 
639 	emptyInst = cim_createInstance("");
640 	if (emptyInst == NULL) {
641 	    ex = cim_getLastError();
642 	    util_handleError(SCSI_EXECQUERY, CIM_ERR_FAILED,
643 		CREATE_INSTANCE_FAILURE, ex, &error);
644 	    return ((CCIMInstanceList *)NULL);
645 	}
646 
647 	result = cim_createInstanceList();
648 	if (result == NULL) {
649 	    ex = cim_getLastError();
650 	    util_handleError(SCSI_EXECQUERY, CIM_ERR_FAILED,
651 		CREATE_INSTANCE_LIST_FAILURE, ex, &error);
652 	    cim_freeInstance(emptyInst);
653 	    cim_freeInstanceList(instList);
654 	    return ((CCIMInstanceList *)NULL);
655 	}
656 
657 	result = cim_addInstance(result, emptyInst);
658 	if (result == NULL) {
659 	    ex = cim_getLastError();
660 	    util_handleError(SCSI_EXECQUERY, CIM_ERR_FAILED,
661 		ADD_INSTANCE_FAILURE, ex, &error);
662 	    cim_freeInstance(emptyInst);
663 	    cim_freeInstanceList(instList);
664 	    return ((CCIMInstanceList *)NULL);
665 	}
666 
667 	/*
668 	 * Since copying the original list to the new list will
669 	 * leave no way to free the original list, manually
670 	 * concatenate the original list to the new one.
671 	 */
672 
673 	result->mNext = instList;
674 	return (result);
675 }
676 
677 /*
678  * Name: cp_associators_Solaris_SCSIInterface
679  *
680  * Description:
681  * Returns a instances of objects associated with the passed in
682  * object if there are any.
683  *
684  * Parameters:
685  *
686  *	CCIMObjectPath *pAssocName - The name of the association that
687  *	the client wants information about.
688  *
689  *	CCIMObjectPath *pObjectName - An CCIMObjectPath * which contains the
690  *	information on the class for which to find the associated instances.
691  *
692  *	cimchar *pResultClass - If specified, only return instances that
693  *	are of this class type.
694  *
695  *      cimchar *pRole - If specified, must be valid for the object path
696  *	passed in requesting the associated instances.
697  *
698  *	cimchar *pResultRole - If specified, only return instances that
699  *	are playing this role in the association.
700  *
701  *
702  * Returns:
703  *	CCIMInstanceList * if associated objects are found.
704  *	NULL is returned on error as well as for an empty list.
705  */
706 
707 /* ARGSUSED */
708 CCIMInstanceList *
cp_associators_Solaris_SCSIInterface(CCIMObjectPath * pAssocName,CCIMObjectPath * pObjectName,cimchar * pResultClass,cimchar * pRole,cimchar * pResultRole)709 cp_associators_Solaris_SCSIInterface(CCIMObjectPath *pAssocName,
710     CCIMObjectPath *pObjectName, cimchar *pResultClass, cimchar *pRole,
711 	cimchar *pResultRole)
712 {
713 	CCIMPropertyList	*pCurPropList;
714 	CCIMInstanceList	*instList = NULL;
715 	CCIMException		*ex;
716 	dm_descriptor_t		*assoc_descriptors;
717 	dm_descriptor_t		obj_desc;
718 	char			*name;
719 	int			error = 0;
720 	int			isAntecedent = 0;
721 
722 
723 	if (pObjectName == NULL ||
724 	    pObjectName->mName == NULL ||
725 		pObjectName->mKeyProperties == NULL) {
726 	    util_handleError(SCSI_ASSOCIATORS, CIM_ERR_INVALID_PARAMETER,
727 		NULL, NULL, &error);
728 	    return ((CCIMInstanceList *)NULL);
729 	}
730 
731 	if (strcasecmp(pObjectName->mName, SCSI_CONTROLLER) == 0) {
732 	    isAntecedent = 1;
733 	}
734 
735 	if (pRole != NULL) {
736 	    if (strcasecmp(pRole, ANTECEDENT) == 0) {
737 		if (isAntecedent != 1) {
738 		    util_handleError(SCSI_ASSOCIATORS,
739 			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
740 		    return ((CCIMInstanceList *)NULL);
741 		}
742 	    } else if (strcasecmp(pRole, DEPENDENT) == 0) {
743 		if (isAntecedent == 1) {
744 		    util_handleError(SCSI_ASSOCIATORS,
745 			CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
746 		    return ((CCIMInstanceList *)NULL);
747 		}
748 	    }
749 	}
750 
751 	/*
752 	 * Both scsi controller and disk drive have deviceid as the
753 	 * key.
754 	 */
755 
756 	pCurPropList = pObjectName->mKeyProperties;
757 	name = (cimchar *)util_getKeyValue(pCurPropList, string, DEVICEID,
758 	    &error);
759 
760 	/*
761 	 * We went through the whole list and didn't find the necessary
762 	 * key value.
763 	 */
764 	if (error != 0 || name == NULL) {
765 	    util_handleError(SCSI_ASSOCIATORS, CIM_ERR_INVALID_PARAMETER, NULL,
766 		NULL, &error);
767 	    return ((CCIMInstanceList *)NULL);
768 	}
769 
770 	if (isAntecedent) {
771 	    obj_desc = dm_get_descriptor_by_name(DM_CONTROLLER, name, &error);
772 	} else {
773 	    obj_desc = dm_get_descriptor_by_name(DM_DRIVE, name, &error);
774 	}
775 
776 	/*
777 	 * Device not found, return NULL list.
778 	 */
779 	if (error == ENODEV || obj_desc == NULL) {
780 	    return ((CCIMInstanceList *)NULL);
781 	}
782 
783 	if (error != 0) {
784 	    util_handleError(SCSI_ASSOCIATORS, CIM_ERR_FAILED,
785 		DM_GET_DESC_BYNAME_FAILURE, NULL, &error);
786 	    return ((CCIMInstanceList *)NULL);
787 	}
788 
789 	if (isAntecedent) {
790 
791 		/*
792 		 * Controller calling this method, return instances of the
793 		 * disk drives associated with this controller.
794 		 */
795 
796 	    assoc_descriptors = dm_get_associated_descriptors(obj_desc,
797 		DM_DRIVE, &error);
798 	    dm_free_descriptor(obj_desc);
799 
800 	    if (assoc_descriptors == NULL) {
801 		return ((CCIMInstanceList *)NULL);
802 	    }
803 
804 	    if (assoc_descriptors[0] == NULL) {
805 		dm_free_descriptors(assoc_descriptors);
806 		return ((CCIMInstanceList *)NULL);
807 	    }
808 
809 	    if (error != 0) {
810 		util_handleError(SCSI_ASSOCIATORS,  CIM_ERR_FAILED,
811 		    DM_GET_ASSOC_FAILURE, NULL, &error);
812 		return ((CCIMInstanceList *)NULL);
813 	    }
814 		/*
815 		 * Generate the inst list of the associated disk drives.
816 		 */
817 
818 	    instList = drive_descriptors_toCCIMObjPathInstList(DISK_DRIVE,
819 		assoc_descriptors, &error);
820 	    dm_free_descriptors(assoc_descriptors);
821 
822 	    if (error != 0) {
823 		ex = cim_getLastError();
824 		util_handleError(SCSI_ASSOCIATORS, CIM_ERR_FAILED,
825 		    DRIVE_DESC_TO_INSTANCE_FAILURE, ex, &error);
826 		return ((CCIMInstanceList *)NULL);
827 	    }
828 	} else {
829 		/*
830 		 * This is the disk drive calling this function. Return the
831 		 * controllers that are associated with this disk.
832 		 */
833 
834 	    assoc_descriptors = dm_get_associated_descriptors(obj_desc,
835 		DM_CONTROLLER, &error);
836 	    dm_free_descriptor(obj_desc);
837 
838 	    if (assoc_descriptors ==  NULL) {
839 		return (instList);
840 	    }
841 
842 	    if (assoc_descriptors[0] == NULL) {
843 		dm_free_descriptors(assoc_descriptors);
844 		return (instList);
845 	    }
846 
847 	    if (error != 0) {
848 		util_handleError(SCSI_ASSOCIATORS,  CIM_ERR_FAILED,
849 		    DM_GET_ASSOC_FAILURE, NULL, &error);
850 		return ((CCIMInstanceList *)NULL);
851 	    }
852 
853 	    instList = ctrl_descriptors_toCCIMInstanceList(SCSI_CONTROLLER,
854 		assoc_descriptors, &error, 1, "scsi");
855 	    dm_free_descriptors(assoc_descriptors);
856 
857 	    if (error != 0) {
858 		util_handleError(SCSI_ASSOCIATORS, CIM_ERR_FAILED,
859 		    SCSICTRL_DESC_TO_INSTANCE_FAILURE, NULL, &error);
860 		return ((CCIMInstanceList *)NULL);
861 	    }
862 	}
863 
864 	return (instList);
865 }
866 
867 /*
868  * Name: cp_associatorNames_Solaris_SCSIInterface
869  *
870  * Description:
871  * Returns a list of objects associated with the passed in
872  * object if there are any via the object CCIMObjectPath.
873  *
874  * Parameters:
875  *
876  *	CCIMObjectPath *pAssocName - The name of the association that
877  *	the client wants information about.
878  *
879  *	CCIMObjectPath *pObjectName - An CCIMObjectPath * which contains the
880  *	information on the class for which to find the associated instances.
881  *
882  *	cimchar *pResultClass - If specified, only return instances that
883  *	are of this class type.
884  *
885  *      cimchar *pRole - If specified, must be valid for the object path
886  *	passed in requesting the associated instances.
887  *
888  *	cimchar *pResultRole - If specified, only return instances that
889  *	are playing this role in the association.
890  *
891  *
892  * Returns:
893  *	CCIMObjectPathList * if associated objects are found. NULL otherwise.
894  */
895 
896 /* ARGSUSED */
897 CCIMObjectPathList *
cp_associatorNames_Solaris_SCSIInterface(CCIMObjectPath * pAssocName,CCIMObjectPath * pObjectName,cimchar * pResultClass,cimchar * pRole,cimchar * pResultRole)898 cp_associatorNames_Solaris_SCSIInterface(CCIMObjectPath *pAssocName,
899     CCIMObjectPath *pObjectName, cimchar *pResultClass, cimchar *pRole,
900 	cimchar *pResultRole)
901 {
902 
903 	CCIMInstanceList	*instList = NULL;
904 	CCIMObjectPathList	*objList = NULL;
905 	int			error;
906 
907 
908 	if (pObjectName == NULL) {
909 	    util_handleError(SCSI_ASSOCIATORNAMES,
910 		CIM_ERR_INVALID_PARAMETER, NULL, NULL, &error);
911 	    return ((CCIMObjectPathList *)NULL);
912 	}
913 
914 	instList =
915 	    cp_associators_Solaris_SCSIInterface(
916 		pAssocName, pObjectName, pResultClass, pRole, pResultRole);
917 
918 	if (instList != NULL) {
919 	    objList = cim_createObjectPathList(instList);
920 	    cim_freeInstanceList(instList);
921 	}
922 
923 	return (objList);
924 }
925 
926 /*
927  * Name: cp_references_Solaris_SCSIInterface
928  *
929  * Description:
930  * Returns a instances of objects that have references to the passed in
931  * object if there are any.
932  *
933  * Parameters:
934  *
935  *	CCIMObjectPath *pAssocName - The name of the association that
936  *	the client wants information about.
937  *
938  *	CCIMObjectPath *pObjectName - An CCIMObjectPath * which contains the
939  *	information on the class for which to find the associated instances.
940  *
941  *      cimchar *pRole - If specified, must be valid for the object path
942  *	passed in requesting the associated instances.
943  *
944  * Returns:
945  *	CCIMObjectPathList * if associated objects are found. This list
946  *	may be empty. NULL is returned on error. If empty list, NULL
947  *	is returned also. An error is set for CIMOM if an error occurs
948  *	to notify CIMOM that the NULL means error.
949  */
950 
951 /* ARGSUSED */
952 CCIMInstanceList *
cp_references_Solaris_SCSIInterface(CCIMObjectPath * pAssocName,CCIMObjectPath * pObjectName,char * pRole)953 cp_references_Solaris_SCSIInterface(CCIMObjectPath *pAssocName,
954 CCIMObjectPath *pObjectName, char *pRole)
955 {
956 
957 	CCIMInstanceList	*instList = NULL;
958 	CCIMObjectPathList	*objList = NULL;
959 	int			error;
960 
961 
962 	if (pObjectName == NULL) {
963 	    util_handleError(SCSI_REFERENCES, CIM_ERR_INVALID_PARAMETER,
964 		NULL, NULL, &error);
965 	    return ((CCIMInstanceList *)NULL);
966 	}
967 
968 	/*
969 	 * Get the list of those objects that are referred to by
970 	 * the calling object.
971 	 */
972 
973 	objList =
974 	    cp_associatorNames_Solaris_SCSIInterface(
975 		pAssocName, pObjectName, NULL, NULL, NULL);
976 
977 	if (objList == NULL) {
978 	    return ((CCIMInstanceList *)NULL);
979 	}
980 
981 	/*
982 	 * Now generate the list of instances to return.
983 	 */
984 
985 	if ((strcasecmp(pObjectName->mName, SCSI_CONTROLLER)) == 0) {
986 	    instList = scsiIntAssocToInstList(pObjectName,
987 		ANTECEDENT, objList, DEPENDENT, &error);
988 	} else {
989 	    instList = scsiIntAssocToInstList(pObjectName,
990 		DEPENDENT, objList, ANTECEDENT, &error);
991 	}
992 
993 	cim_freeObjectPathList(objList);
994 	return (instList);
995 }
996 
997 /*
998  * Name: cp_referenceNames_Solaris_SCSIInterface
999  *
1000  * Description:
1001  * Returns a instances of objects that have references to the passed in
1002  * object if there are any.
1003  *
1004  * Parameters:
1005  *
1006  *	CCIMObjectPath *pAssocName - The name of the association that
1007  *	the client wants information about.
1008  *
1009  *	CCIMObjectPath *pObjectName - An CCIMObjectPath * which contains the
1010  *	information on the class for which to find the associated instances.
1011  *
1012  *      cimchar *pRole - If specified, must be valid for the object path
1013  *	passed in requesting the associated instances.
1014  *
1015  *
1016  * Returns:
1017  *	CCIMObjectPathList * if associated objects are found. This list
1018  *	may be empty. NULL is returned on error and for an empty list.
1019  *      An error is set for CIMOM to determine if NULL means error.
1020  *
1021  */
1022 
1023 /* ARGSUSED */
1024 CCIMObjectPathList *
cp_referenceNames_Solaris_SCSIInterface(CCIMObjectPath * pAssocName,CCIMObjectPath * pObjectName,cimchar * pRole)1025 cp_referenceNames_Solaris_SCSIInterface(CCIMObjectPath *pAssocName,
1026     CCIMObjectPath *pObjectName, cimchar *pRole)
1027 {
1028 
1029 	CCIMInstanceList	*instList;
1030 	CCIMObjectPathList	*objList = NULL;
1031 	int			error;
1032 
1033 	if (pObjectName == NULL) {
1034 	    util_handleError(SCSI_REFERENCENAMES, CIM_ERR_INVALID_PARAMETER,
1035 		NULL, NULL, &error);
1036 	    return ((CCIMObjectPathList *)NULL);
1037 	}
1038 
1039 	instList =
1040 	    cp_references_Solaris_SCSIInterface(pAssocName, pObjectName, pRole);
1041 
1042 	if (instList != NULL) {
1043 	    objList = cim_createObjectPathList(instList);
1044 	    cim_freeInstanceList(instList);
1045 	}
1046 
1047 	return (objList);
1048 }
1049 
1050 /*
1051  * Create the association class with the passed in attributes.
1052  */
1053 static
1054 CCIMInstanceList  *
scsiIntAssocToInstList(CCIMObjectPath * pObjectName,cimchar * pObjectNameRole,CCIMObjectPathList * objList,cimchar * objRole,int * error)1055 scsiIntAssocToInstList(CCIMObjectPath *pObjectName, cimchar *pObjectNameRole,
1056 	CCIMObjectPathList *objList, cimchar *objRole, int *error)
1057 {
1058 
1059 	CCIMObjectPathList	*tmpList;
1060 	CCIMInstanceList	*instList = NULL;
1061 	CCIMInstance		*inst;
1062 	CCIMObjectPath		*obj1;
1063 	CCIMObjectPath		*obj2;
1064 	CCIMException		*ex;
1065 
1066 	*error = 0;
1067 
1068 	if (objList == NULL) {
1069 	    return ((CCIMInstanceList *)NULL);
1070 	}
1071 
1072 	instList = cim_createInstanceList();
1073 	if (instList == NULL) {
1074 	    ex = cim_getLastError();
1075 	    util_handleError(SCSI_INTERFACE, CIM_ERR_FAILED,
1076 		CREATE_INSTANCE_FAILURE, ex, error);
1077 	    return ((CCIMInstanceList *)NULL);
1078 	}
1079 	tmpList = objList;
1080 	while (tmpList != NULL) {
1081 	    obj1 = tmpList->mDataObject;
1082 	    obj2 = cim_copyObjectPath(pObjectName);
1083 	    if (obj2 == NULL) {
1084 		ex = cim_getLastError();
1085 		util_handleError(SCSI_INTERFACE, CIM_ERR_FAILED,
1086 		    COPY_OBJPATH_FAILURE, ex, error);
1087 		return ((CCIMInstanceList *)NULL);
1088 	    }
1089 
1090 	    inst = scsiIntAssocToInst(obj1, objRole, obj2, pObjectNameRole,
1091 		error);
1092 	    cim_freeObjectPath(obj2);
1093 
1094 	    if (*error != 0) {
1095 		util_handleError(SCSI_INTERFACE, CIM_ERR_FAILED,
1096 		    SCSIINT_ASSOC_TO_INSTANCE_FAILURE, NULL, error);
1097 		cim_freeInstanceList(instList);
1098 		return ((CCIMInstanceList *)NULL);
1099 	    }
1100 
1101 	    instList = cim_addInstance(instList, inst);
1102 	    if (instList == NULL) {
1103 		ex = cim_getLastError();
1104 		util_handleError(SCSI_INTERFACE, CIM_ERR_FAILED,
1105 		    ADD_INSTANCE_FAILURE, ex, error);
1106 		cim_freeInstance(inst);
1107 		return ((CCIMInstanceList *)NULL);
1108 	    }
1109 	    tmpList = tmpList->mNext;
1110 	}
1111 	return (instList);
1112 }
1113 
1114 static
1115 CCIMInstance  *
scsiIntAssocToInst(CCIMObjectPath * obj1,cimchar * obj1Role,CCIMObjectPath * obj2,cimchar * obj2Role,int * error)1116 scsiIntAssocToInst(CCIMObjectPath *obj1, cimchar *obj1Role,
1117 	CCIMObjectPath *obj2, cimchar *obj2Role, int *error)
1118 {
1119 
1120 	CCIMInstance	*inst = NULL;
1121 	CCIMException	*ex;
1122 
1123 	*error = 0;
1124 
1125 	inst = cim_createInstance(SCSI_INTERFACE);
1126 	if (inst == NULL) {
1127 	    ex = cim_getLastError();
1128 	    util_handleError(SCSI_INTERFACE, CIM_ERR_FAILED,
1129 		SCSIINT_ASSOC_TO_INSTANCE_FAILURE, ex, error);
1130 	    return ((CCIMInstance *)NULL);
1131 	}
1132 
1133 	util_doReferenceProperty(obj2Role, obj2, cim_true, inst, error);
1134 	if (*error != 0) {
1135 	    ex = cim_getLastError();
1136 	    util_handleError(SCSI_INTERFACE, CIM_ERR_FAILED,
1137 		CREATE_REFPROP_FAILURE, ex, error);
1138 	    cim_freeInstance(inst);
1139 	    return ((CCIMInstance *)NULL);
1140 	}
1141 
1142 	util_doReferenceProperty(obj1Role, obj1, cim_true, inst, error);
1143 	if (*error != 0) {
1144 	    ex = cim_getLastError();
1145 	    util_handleError(SCSI_INTERFACE, CIM_ERR_FAILED,
1146 		CREATE_REFPROP_FAILURE, ex, error);
1147 	    cim_freeInstance(inst);
1148 	    return ((CCIMInstance *)NULL);
1149 	}
1150 
1151 	return (inst);
1152 }
1153