PageRenderTime 43ms CodeModel.GetById 1ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 0ms

/usr/src/cmd/wbem/provider/c/wbem_disk/assoc/Solaris_SCSIInterface.c

https://bitbucket.org/osunix/osunix-gate
C | 1152 lines | 651 code | 177 blank | 324 comment | 167 complexity | d88255a622afdd436bf125fed3abb297 MD5 | raw file
   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
  56static
  57CCIMInstanceList *
  58scsiIntAssocToInstList(CCIMObjectPath *pObjectName, cimchar *pObjectNameRole,
  59	CCIMObjectPathList *objList, cimchar *objRole, int *error);
  60
  61static
  62CCIMInstance  *
  63scsiIntAssocToInst(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
  87CCIMInstance*
  88cp_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 */
 227CCIMInstanceList*
 228cp_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 */
 441CCIMObjectPathList*
 442cp_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 */
 475CCIMObjectPath*
 476cp_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 */
 492CIMBool
 493cp_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 */
 515CCIMProperty	*
 516cp_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 */
 546CIMBool
 547cp_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 */
 562CIMBool
 563cp_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 */
 577CCIMProperty*
 578cp_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 */
 610CCIMInstanceList*
 611cp_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 */
 708CCIMInstanceList *
 709cp_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 */
 897CCIMObjectPathList *
 898cp_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 */
 952CCIMInstanceList *
 953cp_references_Solaris_SCSIInterface(CCIMObjectPath *pAssocName,
 954CCIMObjectPath *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 */
1024CCIMObjectPathList *
1025cp_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 */
1053static
1054CCIMInstanceList  *
1055scsiIntAssocToInstList(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
1114static
1115CCIMInstance  *
1116scsiIntAssocToInst(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}