Blame IbAccess/Common/SubnetDriver/sa.c

Packit 857059
/* BEGIN_ICS_COPYRIGHT4 ****************************************
Packit 857059
Packit 857059
Copyright (c) 2015-2017, Intel Corporation
Packit 857059
Packit 857059
Redistribution and use in source and binary forms, with or without
Packit 857059
modification, are permitted provided that the following conditions are met:
Packit 857059
Packit 857059
    * Redistributions of source code must retain the above copyright notice,
Packit 857059
      this list of conditions and the following disclaimer.
Packit 857059
    * Redistributions in binary form must reproduce the above copyright
Packit 857059
      notice, this list of conditions and the following disclaimer in the
Packit 857059
      documentation and/or other materials provided with the distribution.
Packit 857059
    * Neither the name of Intel Corporation nor the names of its contributors
Packit 857059
      may be used to endorse or promote products derived from this software
Packit 857059
      without specific prior written permission.
Packit 857059
Packit 857059
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 857059
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 857059
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit 857059
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
Packit 857059
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 857059
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit 857059
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit 857059
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit 857059
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 857059
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 857059
Packit 857059
** END_ICS_COPYRIGHT4   ****************************************/
Packit 857059
Packit 857059
#include <datatypes.h>
Packit 857059
#include <imemory.h>
Packit 857059
#include <ilist.h>
Packit 857059
#include <ievent.h>
Packit 857059
#include <imutex.h>
Packit 857059
#include <stl_sd.h>
Packit 857059
#include <sdi.h>
Packit 857059
#include <ib_generalServices.h>
Packit 857059
Packit 857059
Packit 857059
#if 0 // keep this around in case we need it for debugging again
Packit 857059
void SaShowPacket(char *msg, unsigned char *packet, int length) {
Packit 857059
	_DBG_DUMP_MEMORY(_DBG_LVL_? ("%s", msg), (void*)packet, length);
Packit 857059
}
Packit 857059
#endif
Packit 857059
Packit 857059
FSTATUS
Packit 857059
SubnetAdmInit(
Packit 857059
    void
Packit 857059
    )
Packit 857059
{
Packit 857059
	uint64 *pLocalPortGuidsList = NULL;
Packit 857059
	uint32 LocalPortGuidsCount;
Packit 857059
	FSTATUS Fstatus;
Packit 857059
	unsigned ii;
Packit 857059
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, SubnetAdmInit);
Packit 857059
Packit 857059
	Fstatus = iba_sd_get_local_port_guids_alloc(&pLocalPortGuidsList, &LocalPortGuidsCount);
Packit 857059
	if (Fstatus != FSUCCESS || LocalPortGuidsCount == 0)
Packit 857059
	{
Packit 857059
		if (Fstatus == FSUCCESS)
Packit 857059
			Fstatus = FNOT_DONE;
Packit 857059
		if (pLocalPortGuidsList != NULL)
Packit 857059
		{
Packit 857059
			MemoryDeallocate(pLocalPortGuidsList);
Packit 857059
			pLocalPortGuidsList = NULL;
Packit 857059
		}
Packit 857059
		_DBG_INFO(("No Active LocalPortGuids found\n"));
Packit 857059
		_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
Packit 857059
        return(Fstatus);
Packit 857059
	}
Packit 857059
Packit 857059
	for (ii = 0; ii < LocalPortGuidsCount; ii++)
Packit 857059
	{
Packit 857059
		MAD *mad;
Packit 857059
		PQueryDetails pQueryElement;
Packit 857059
Packit 857059
		pQueryElement = (QueryDetails*)MemoryAllocateAndClear(sizeof(QueryDetails),
Packit 857059
									FALSE, SUBNET_DRIVER_TAG);
Packit 857059
	
Packit 857059
		if (pQueryElement == NULL)  
Packit 857059
		{
Packit 857059
			_DBG_ERROR(("Cannot allocate memory for QueryElement in SubnetAdmInit\n"));
Packit 857059
			_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
Packit 857059
        	return(FINSUFFICIENT_MEMORY);
Packit 857059
    	}
Packit 857059
Packit 857059
		QListSetObj(&pQueryElement->QueryListItem, (void *)pQueryElement);
Packit 857059
		pQueryElement->IsSelfCommand = TRUE;
Packit 857059
		pQueryElement->SdSentCmd = GetClassportInfo;
Packit 857059
		pQueryElement->ControlParameters.RetryCount = g_SdParams.DefaultRetryCount;
Packit 857059
		pQueryElement->ControlParameters.Timeout = g_SdParams.DefaultRetryInterval;
Packit 857059
	
Packit 857059
    	pQueryElement->u.pSaMad = (SA_MAD*)MemoryAllocateAndClear(sizeof(SA_MAD),
Packit 857059
                                                FALSE,
Packit 857059
                                                SUBNET_DRIVER_TAG);
Packit 857059
    	if (pQueryElement->u.pSaMad == NULL)
Packit 857059
    	{
Packit 857059
			MemoryDeallocate(pQueryElement);
Packit 857059
        	_DBG_ERROR(("Cannot allocate memory for QueryElement->u.pSaMad in SubnetAdmInit\n"));
Packit 857059
        	_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
Packit 857059
        	return(FINSUFFICIENT_MEMORY);
Packit 857059
    	} 
Packit 857059
Packit 857059
		mad = (MAD *)pQueryElement->u.pSaMad;
Packit 857059
	
Packit 857059
		FillBaseGmpValues(pQueryElement);
Packit 857059
Packit 857059
		mad->common.mr.s.R = 0; //since this is not a response, set it to 0;
Packit 857059
		mad->common.mr.s.Method = MMTHD_GET; 
Packit 857059
Packit 857059
		MAD_SET_ATTRIB_ID(mad, MCLASS_ATTRIB_ID_CLASS_PORT_INFO);
Packit 857059
		MAD_SET_ATTRIB_MOD(mad, 0); 
Packit 857059
Packit 857059
		// fields were initialized to 0 above
Packit 857059
		// which is what we want for a single packet RMPP request in 1.0a or 1.1
Packit 857059
	pQueryElement->TotalBytesInGmp = (mad->common.BaseVersion == IB_BASE_VERSION)
Packit 857059
		? IB_MAD_BLOCK_SIZE
Packit 857059
		: (sizeof(SA_MAD) - STL_SUBN_ADM_DATASIZE) + sizeof(STL_CLASS_PORT_INFO);
Packit 857059
Packit 857059
		pQueryElement->PortGuid = pLocalPortGuidsList[ii];
Packit 857059
Packit 857059
#if defined( DBG) || defined(IB_DEBUG)
Packit 857059
		{
Packit 857059
			CA_PORT *pCaPort;
Packit 857059
Packit 857059
			SpinLockAcquire(pCaPortListLock);
Packit 857059
			pCaPort = GetCaPort(pLocalPortGuidsList[ii]);
Packit 857059
			ASSERT(pCaPort != NULL);
Packit 857059
			ASSERT(pQueryElement->PortGuid == pCaPort->PortGuid);
Packit 857059
			SpinLockRelease(pCaPortListLock);
Packit 857059
		}
Packit 857059
#endif
Packit 857059
Packit 857059
		SendQueryElement(pQueryElement, TRUE /*FirstAttempt*/);
Packit 857059
	}
Packit 857059
Packit 857059
	MemoryDeallocate(pLocalPortGuidsList);
Packit 857059
Packit 857059
	// Trigger the timer handler
Packit 857059
	StartTimerHandler(pTimerObject, g_SdParams.TimeInterval);
Packit 857059
Packit 857059
	_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
Packit 857059
	return(FSUCCESS);
Packit 857059
}
Packit 857059
Packit 857059
// for a given SA attribute, indicate the size of the actual
Packit 857059
// unpadded record returned
Packit 857059
uint32
Packit 857059
SubnetAdmAttrToRecordSize(uint8 attribute)
Packit 857059
{
Packit 857059
	switch (attribute)
Packit 857059
	{
Packit 857059
	case SA_ATTRIB_INFORM_INFO:
Packit 857059
			return(sizeof(IB_INFORM_INFO));
Packit 857059
	case SA_ATTRIB_NODE_RECORD:
Packit 857059
			return(sizeof(IB_NODE_RECORD));
Packit 857059
	case SA_ATTRIB_PORTINFO_RECORD:
Packit 857059
			return(sizeof(IB_PORTINFO_RECORD));
Packit 857059
	case SA_ATTRIB_SWITCHINFO_RECORD:
Packit 857059
			return(sizeof(IB_SWITCHINFO_RECORD));
Packit 857059
	case SA_ATTRIB_LINEAR_FWDTBL_RECORD:
Packit 857059
			return(sizeof(IB_LINEAR_FDB_RECORD));
Packit 857059
	case SA_ATTRIB_RANDOM_FWDTBL_RECORD:
Packit 857059
			return(sizeof(IB_RANDOM_FDB_RECORD));
Packit 857059
	case SA_ATTRIB_MCAST_FWDTBL_RECORD:
Packit 857059
			return(sizeof(IB_MCAST_FDB_RECORD));
Packit 857059
	case SA_ATTRIB_SMINFO_RECORD:
Packit 857059
			return(sizeof(IB_SMINFO_RECORD));
Packit 857059
	case SA_ATTRIB_INFORM_INFO_RECORD:
Packit 857059
			return(sizeof(IB_INFORM_INFO_RECORD));
Packit 857059
	case SA_ATTRIB_LINK_RECORD:
Packit 857059
			return(sizeof(IB_LINK_RECORD));
Packit 857059
	case SA_ATTRIB_SERVICE_RECORD:
Packit 857059
			return(sizeof(IB_SERVICE_RECORD));
Packit 857059
	case SA_ATTRIB_P_KEY_TABLE_RECORD:
Packit 857059
			return(sizeof(IB_P_KEY_TABLE_RECORD));
Packit 857059
	case SA_ATTRIB_PATH_RECORD:
Packit 857059
			return(sizeof(IB_PATH_RECORD));
Packit 857059
	case SA_ATTRIB_VLARBTABLE_RECORD:
Packit 857059
			return(sizeof(IB_VLARBTABLE_RECORD));
Packit 857059
	case SA_ATTRIB_MCMEMBER_RECORD:
Packit 857059
			return(sizeof(IB_MCMEMBER_RECORD));
Packit 857059
	case SA_ATTRIB_TRACE_RECORD:
Packit 857059
			return(sizeof(IB_TRACE_RECORD));
Packit 857059
	case SA_ATTRIB_MULTIPATH_RECORD:
Packit 857059
			return(sizeof(IB_MULTIPATH_RECORD));
Packit 857059
	case SA_ATTRIB_SERVICEASSOCIATION_RECORD:
Packit 857059
			return(sizeof(IB_SERVICEASSOCIATION_RECORD));
Packit 857059
	default:
Packit 857059
			return 0;
Packit 857059
	}
Packit 857059
}
Packit 857059
Packit 857059
// look at payload len in SA reponse and compute the size of
Packit 857059
// each record and the number of records
Packit 857059
// also validates payload does not indicate truncation of last record
Packit 857059
// if last was truncated, it reduces NumRecords with a warning
Packit 857059
FSTATUS
Packit 857059
SdComputeResponseSizes(
Packit 857059
	SA_MAD 				*pSaMad,
Packit 857059
	uint32				messageSize,	// Size of Coalesced message
Packit 857059
	uint32				*pNumRecords,
Packit 857059
	uint32				*pPaddedRecordSize,
Packit 857059
	uint32				*pRecordSize
Packit 857059
	)
Packit 857059
{
Packit 857059
	uint32				saPayload;
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, SdComputeResponseSizes);
Packit 857059
Packit 857059
	*pRecordSize = SubnetAdmAttrToRecordSize(pSaMad->common.AttributeID);
Packit 857059
	if (pSaMad->common.mr.AsReg8 == SUBN_ADM_GET_RESP)
Packit 857059
	{
Packit 857059
		// single record response
Packit 857059
		*pPaddedRecordSize = *pRecordSize;
Packit 857059
		*pNumRecords = 1;
Packit 857059
		return FSUCCESS;
Packit 857059
	}
Packit 857059
	// round up just in case SA omits pad bytes at end of last record
Packit 857059
	*pPaddedRecordSize = pSaMad->SaHdr.AttributeOffset*sizeof(uint64) ;
Packit 857059
	if (*pPaddedRecordSize == 0) {
Packit 857059
		_DBG_WARN(("Invalid AttributeOffset!\n"
Packit 857059
					"\tAttributeOffset........%d\n"
Packit 857059
					"\tPayloadLen.............%d\n"
Packit 857059
					"\tRecordSize.............%d\n",
Packit 857059
					pSaMad->SaHdr.AttributeOffset,
Packit 857059
					pSaMad->RmppHdr.u2.PayloadLen,
Packit 857059
					*pRecordSize));
Packit 857059
		*pNumRecords = 0;	// TBD ignore or fail request????
Packit 857059
		_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
Packit 857059
		return FSUCCESS;
Packit 857059
	}
Packit 857059
	// GsiCoalesceDgrm already removed extra SA_HDRs and adjusted
Packit 857059
	// messageSize to account for their removal
Packit 857059
	saPayload = messageSize - (sizeof(MAD_COMMON) + sizeof(RMPP_HEADER) + sizeof(SA_HDR));
Packit 857059
	*pNumRecords = (saPayload + (*pPaddedRecordSize)-1) / (*pPaddedRecordSize);
Packit 857059
Packit 857059
	// see if last Record in list is complete
Packit 857059
	if (*pNumRecords 
Packit 857059
		&& (*pNumRecords-1)*(*pPaddedRecordSize)+(*pRecordSize) > saPayload)
Packit 857059
	{
Packit 857059
		// last record was truncated
Packit 857059
		_DBG_WARN(("Final Record of SA Response is truncated!\n"
Packit 857059
					"\tAttributeOffset........%d\n"
Packit 857059
					"\tPayloadLen.............%d\n"
Packit 857059
					"\tRecordSize.............%d\n",
Packit 857059
					pSaMad->SaHdr.AttributeOffset,
Packit 857059
					pSaMad->RmppHdr.u2.PayloadLen,
Packit 857059
					*pRecordSize));
Packit 857059
		--(*pNumRecords);	// TBD ignore or fail request????
Packit 857059
	}
Packit 857059
	_DBG_INFO(("SA Response:\n"
Packit 857059
				"\tAttributeOffset........%d (%d)\n"
Packit 857059
				"\tPayloadLen.............%d\n"
Packit 857059
				"\tRecordSize.............%d\n"
Packit 857059
				"\tNumRecords.............%d\n",
Packit 857059
				pSaMad->SaHdr.AttributeOffset,
Packit 857059
				*pPaddedRecordSize,
Packit 857059
				pSaMad->RmppHdr.u2.PayloadLen,
Packit 857059
				*pRecordSize, *pNumRecords));
Packit 857059
Packit 857059
	_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
Packit 857059
	return FSUCCESS;
Packit 857059
}
Packit 857059
Packit 857059
// called with pQueryList->m_Lock held
Packit 857059
// called with buffer==NULL and messageSize == 0 if query has timed out
Packit 857059
// pQueryElement is in WaitingForResult, still on list
Packit 857059
FSTATUS 
Packit 857059
SubnetAdmRecv(
Packit 857059
	PQueryDetails pQueryElement,
Packit 857059
	void *buffer,			// caller removed GRH already
Packit 857059
	uint32 messageSize		// caller removed GRH already
Packit 857059
	,IBT_DGRM_ELEMENT		*pDgrmList
Packit 857059
    )
Packit 857059
{
Packit 857059
	QUERY_RESULT_VALUES * pClientResult = NULL;
Packit 857059
	SA_MAD *pSaMad = (SA_MAD*)buffer;
Packit 857059
	uint16	MadAttributeID;
Packit 857059
	QUERY_RESULT_TYPE	QueryOutputType;
Packit 857059
	uint32				NumRecords;
Packit 857059
	uint32				RecordSize;	// before padding
Packit 857059
	uint32				PaddedRecordSize;	// after padding
Packit 857059
	uint8				*p;	// start of next record
Packit 857059
Packit 857059
	uint32	i;
Packit 857059
    
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, SubnetAdmRecv);
Packit 857059
Packit 857059
	if(pQueryElement->pParentQuery != NULL)
Packit 857059
	{
Packit 857059
		return SdHandleChildQuery(pQueryElement, buffer, messageSize);
Packit 857059
	}
Packit 857059
	// Handle the case if buffer == NULL;
Packit 857059
Packit 857059
	if (buffer == NULL) //Timeout 
Packit 857059
	{
Packit 857059
		_DBG_ERROR(("SA Query Timed Out <%d ms, %d retries>\n",
Packit 857059
			pQueryElement->ControlParameters.Timeout,
Packit 857059
			pQueryElement->ControlParameters.RetryCount));
Packit 857059
Packit 857059
		DEBUG_ASSERT(pQueryElement->SdSentCmd != UserQueryFabricInformation
Packit 857059
					|| pQueryElement->cmd.query.pClientResult == NULL);
Packit 857059
		pQueryElement->Status = FTIMEOUT;
Packit 857059
		pQueryElement->MadStatus = 0;	// unknown, no response
Packit 857059
		goto done;
Packit 857059
	}
Packit 857059
Packit 857059
	// Include MAD Status and reserved field
Packit 857059
	pQueryElement->MadStatus = (pSaMad->common.u.NS.Reserved1 << 16|
Packit 857059
									pSaMad->common.u.NS.Status.AsReg16);
Packit 857059
Packit 857059
	if (pSaMad->common.u.NS.Status.AsReg16 == MAD_STATUS_SUCCESS) 
Packit 857059
	{
Packit 857059
		_DBG_INFO(("Successful MAD completion received\n"));
Packit 857059
		pQueryElement->Status = FSUCCESS; 
Packit 857059
	} else if (pQueryElement->SdSentCmd == UserQueryFabricInformation
Packit 857059
			&& pSaMad->common.u.NS.Status.AsReg16 == MAD_STATUS_SA_NO_RECORDS)
Packit 857059
	{
Packit 857059
		_DBG_INFO(("No Records MAD completion received\n"));
Packit 857059
		pQueryElement->Status = FSUCCESS; 
Packit 857059
	} else {
Packit 857059
		_DBG_ERROR(("Failed MAD completion received, Status <0x%x: %s>, Port 0x%016"PRIx64"\n",
Packit 857059
			pSaMad->common.u.NS.Status.AsReg16,
Packit 857059
			_DBG_PTR(iba_sd_mad_status_msg(pQueryElement->MadStatus)),
Packit 857059
			pQueryElement->PortGuid));
Packit 857059
		pQueryElement->Status = FERROR; 
Packit 857059
		DEBUG_ASSERT(pQueryElement->SdSentCmd != UserQueryFabricInformation
Packit 857059
					|| pQueryElement->cmd.query.pClientResult == NULL);
Packit 857059
		goto done;
Packit 857059
	}
Packit 857059
Packit 857059
	//
Packit 857059
	// Based on the attribute ID figure out how to process the response
Packit 857059
	//
Packit 857059
	MadAttributeID = pSaMad->common.AttributeID;
Packit 857059
	BSWAP_SA_HDR(&pSaMad->SaHdr);
Packit 857059
	if (pQueryElement->SdSentCmd == UserFabricOperation)
Packit 857059
	{
Packit 857059
		// Fabric Operation Response
Packit 857059
		switch (MadAttributeID)
Packit 857059
		{
Packit 857059
			case SA_ATTRIB_SERVICE_RECORD:
Packit 857059
				{
Packit 857059
            	IB_SERVICE_RECORD          	*pServiceRecord;
Packit 857059
 	
Packit 857059
            	pServiceRecord = (IB_SERVICE_RECORD*)pSaMad->Data;
Packit 857059
                BSWAP_IB_SERVICE_RECORD(pServiceRecord);
Packit 857059
            	_DBG_INFO(("Processing SERVICE_RECORD..... NumRecords[1]\n"));
Packit 857059
				pQueryElement->cmd.op.FabOp.Value.ServiceRecordValue.ServiceRecord =
Packit 857059
							*pServiceRecord;
Packit 857059
				}
Packit 857059
				break;
Packit 857059
			case SA_ATTRIB_MCMEMBER_RECORD:
Packit 857059
				{
Packit 857059
            	IB_MCMEMBER_RECORD          	*pMcMemberRecord;
Packit 857059
 	
Packit 857059
            	pMcMemberRecord = (IB_MCMEMBER_RECORD*)pSaMad->Data;
Packit 857059
                BSWAP_IB_MCMEMBER_RECORD(pMcMemberRecord);
Packit 857059
				if (g_SdParams.MinPktLifeTime) {
Packit 857059
					uint32 PktLifeTime = TimeoutTimeMsToMult(g_SdParams.MinPktLifeTime);
Packit 857059
					if (PktLifeTime > pMcMemberRecord->PktLifeTime)
Packit 857059
						pMcMemberRecord->PktLifeTime = PktLifeTime;
Packit 857059
				}
Packit 857059
            	_DBG_INFO(("Processing MCMEMBER_RECORD..... NumRecords[1]\n"));
Packit 857059
				pQueryElement->cmd.op.FabOp.Value.McMemberRecordValue.McMemberRecord =
Packit 857059
							*pMcMemberRecord;
Packit 857059
				}
Packit 857059
				break;
Packit 857059
			case SA_ATTRIB_INFORM_INFO:
Packit 857059
				{
Packit 857059
            	IB_INFORM_INFO          	*pInformInfo;
Packit 857059
 	
Packit 857059
            	pInformInfo = (IB_INFORM_INFO*)pSaMad->Data;
Packit 857059
                BSWAP_INFORM_INFO(pInformInfo);
Packit 857059
            	_DBG_INFO(("Processing IB_INFORM_INFO..... NumRecords[1]\n"));
Packit 857059
				pQueryElement->cmd.op.FabOp.Value.InformInfo =
Packit 857059
							*pInformInfo;
Packit 857059
				}
Packit 857059
			default:
Packit 857059
				break;
Packit 857059
		}
Packit 857059
		goto done;
Packit 857059
	}
Packit 857059
Packit 857059
	if (pQueryElement->SdSentCmd != UserQueryFabricInformation)
Packit 857059
	{
Packit 857059
		DEBUG_ASSERT(0);
Packit 857059
		goto done;
Packit 857059
	}
Packit 857059
Packit 857059
	// Fabric Query
Packit 857059
	QueryOutputType = pQueryElement->cmd.query.UserQuery.OutputType;
Packit 857059
	pQueryElement->QState = ProcessingResponse; // holds our reference
Packit 857059
	// unlock so we can prempt during memory allocates below
Packit 857059
	SpinLockRelease(&pQueryList->m_Lock);
Packit 857059
Packit 857059
	if (pSaMad->common.u.NS.Status.AsReg16 == MAD_STATUS_SA_NO_RECORDS) {
Packit 857059
		NumRecords = 0;
Packit 857059
	} else {
Packit 857059
		(void)SdComputeResponseSizes( pSaMad, messageSize, &NumRecords,
Packit 857059
								&PaddedRecordSize, &RecordSize);
Packit 857059
	}
Packit 857059
Packit 857059
	switch (MadAttributeID)
Packit 857059
	{
Packit 857059
		case SA_ATTRIB_NODE_RECORD:
Packit 857059
		{
Packit 857059
			if (! g_SdParams.ValidateNodeRecord)
Packit 857059
			{
Packit 857059
				for (i = 0, p = pSaMad->Data;
Packit 857059
						i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            	{
Packit 857059
					BSWAP_IB_NODE_RECORD((IB_NODE_RECORD*)p);
Packit 857059
            	}
Packit 857059
			} else {
Packit 857059
				int dodump = 0;
Packit 857059
Packit 857059
				/* while we byte swap, also validate
Packit 857059
				 * we are checking for 0 Node or Port GUIDs.  This generally
Packit 857059
				 * indicates an RMPP or SA problem where records get skewed
Packit 857059
				 */
Packit 857059
				for (i = 0, p = pSaMad->Data;
Packit 857059
						i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            	{
Packit 857059
//#define VALID_GUID(guid) ((((guid) >> 40) == 0x66a) || (((guid) >> 40) == 0x2c9))
Packit 857059
#define VALID_GUID(guid) ((guid) != 0)
Packit 857059
					BSWAP_IB_NODE_RECORD((IB_NODE_RECORD*)p);
Packit 857059
					if ( ! VALID_GUID(((IB_NODE_RECORD*)p)->NodeInfoData.NodeGUID)
Packit 857059
						|| ! VALID_GUID(((IB_NODE_RECORD*)p)->NodeInfoData.PortGUID))
Packit 857059
#undef VALID_GUID
Packit 857059
					{
Packit 857059
						dodump=1;
Packit 857059
#ifdef ICS_LOGGING
Packit 857059
						_DBG_ERROR(("Corrupted Node Record %d of %d offset 0x%x", i+1, NumRecords, (unsigned)(p - pSaMad->Data)));
Packit 857059
						_DBG_DUMP_MEMORY(_DBG_LVL_ERROR, ("Corrupted Node Record"), (void*)p, sizeof(IB_NODE_RECORD));
Packit 857059
#else
Packit 857059
						_DBG_DUMP_MEMORY(_DBG_LVL_ERROR,
Packit 857059
							("Corrupted Node Record %d of %d offset 0x%x", i+1, NumRecords, (unsigned)(p - pSaMad->Data)),
Packit 857059
							(void*)p, sizeof(IB_NODE_RECORD));
Packit 857059
#endif
Packit 857059
					}
Packit 857059
				}
Packit 857059
				if (dodump && g_SdParams.DumpInvalidNodeRecord)
Packit 857059
				{
Packit 857059
					IBT_ELEMENT *pElement;
Packit 857059
Packit 857059
					_DBG_DUMP_MEMORY(_DBG_LVL_ERROR, ("Coalesed"), (void*)buffer, messageSize);
Packit 857059
Packit 857059
					for (i=0,pElement = &pDgrmList->Element; pElement; i++,pElement=pElement->pNextElement)
Packit 857059
					{
Packit 857059
						IBT_BUFFER *pBufferHdr = pElement->pBufferList->pNextBuffer;
Packit 857059
#ifdef ICS_LOGGING
Packit 857059
						_DBG_ERROR(("Dgrm %d", i));
Packit 857059
						_DBG_DUMP_MEMORY(_DBG_LVL_ERROR, ("Dgrm"), (void*)pBufferHdr->pData, pBufferHdr->ByteCount);
Packit 857059
#else
Packit 857059
						_DBG_DUMP_MEMORY(_DBG_LVL_ERROR, ("Dgrm %d", i), (void*)pBufferHdr->pData, pBufferHdr->ByteCount);
Packit 857059
#endif
Packit 857059
					}
Packit 857059
				}
Packit 857059
			}
Packit 857059
			_DBG_INFO(("Processing IB_NODE_RECORD..... NumRecords[%d]\n",
Packit 857059
										NumRecords));
Packit 857059
			switch(QueryOutputType)
Packit 857059
			{
Packit 857059
            	case (OutputTypeLid):
Packit 857059
				{
Packit 857059
    				PLID_RESULTS 			pLidResults;
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting LIDs from NodeRecord....\n"));
Packit 857059
Packit 857059
               		pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
										+ (NumRecords * sizeof(LID_RESULTS)),
Packit 857059
                    					IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
               		if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
               		pClientResult->ResultDataSize = NumRecords * sizeof(LID_RESULTS);
Packit 857059
					
Packit 857059
					if (NumRecords > 0 )
Packit 857059
					{
Packit 857059
               			pLidResults = (PLID_RESULTS)pClientResult->QueryResult;
Packit 857059
               			pLidResults->NumLids = NumRecords;
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
							i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
               	    		pLidResults->Lids[i] = 
Packit 857059
									((IB_NODE_RECORD*)p)->RID.s.LID;
Packit 857059
                    	}
Packit 857059
					}
Packit 857059
					break;
Packit 857059
				}
Packit 857059
Packit 857059
               	case (OutputTypeSystemImageGuid):
Packit 857059
				case (OutputTypeNodeGuid):
Packit 857059
                case (OutputTypePortGuid):
Packit 857059
				{
Packit 857059
   					PGUID_RESULTS 			pGuidResults;
Packit 857059
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
										+ (NumRecords * sizeof(GUID_RESULTS)),
Packit 857059
										IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(GUID_RESULTS);
Packit 857059
					switch (QueryOutputType)
Packit 857059
					{
Packit 857059
                    	case (OutputTypeSystemImageGuid):
Packit 857059
Packit 857059
							_DBG_INFO(("Extracting SystemImageGUIDs from NodeRecord - NumRecords[%d]\n",
Packit 857059
															NumRecords));
Packit 857059
                   			if (NumRecords > 0 )
Packit 857059
                    		{
Packit 857059
                    			pGuidResults = (PGUID_RESULTS)pClientResult->QueryResult;
Packit 857059
                    			pGuidResults->NumGuids = NumRecords;
Packit 857059
								for (i = 0, p = pSaMad->Data;
Packit 857059
									i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                       			{
Packit 857059
									pGuidResults->Guids[i] = 
Packit 857059
										((IB_NODE_RECORD*)p)->NodeInfoData.SystemImageGUID;
Packit 857059
                       			}
Packit 857059
							}
Packit 857059
							break;
Packit 857059
						case (OutputTypeNodeGuid):
Packit 857059
Packit 857059
							_DBG_INFO(("Extracting NodeGUIDs from NodeRecord - NumRecords[%d]\n",
Packit 857059
															NumRecords));
Packit 857059
                           	if (NumRecords > 0 )
Packit 857059
                            {
Packit 857059
                                pGuidResults = (PGUID_RESULTS)pClientResult->QueryResult;
Packit 857059
                                pGuidResults->NumGuids = NumRecords;
Packit 857059
								for (i = 0, p = pSaMad->Data;
Packit 857059
									i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
								{
Packit 857059
Packit 857059
									pGuidResults->Guids[i] = 
Packit 857059
										((IB_NODE_RECORD*)p)->NodeInfoData.NodeGUID;
Packit 857059
								}
Packit 857059
							}
Packit 857059
							break;
Packit 857059
                    	case (OutputTypePortGuid):
Packit 857059
Packit 857059
							_DBG_INFO(("Extracting PortGUIDS from NodeRecord - NumRecords[%d]\n",
Packit 857059
															NumRecords));
Packit 857059
                           	if (NumRecords > 0 )
Packit 857059
                            {
Packit 857059
                                pGuidResults = (PGUID_RESULTS)pClientResult->QueryResult;
Packit 857059
                                pGuidResults->NumGuids = NumRecords;
Packit 857059
								for (i = 0, p = pSaMad->Data;
Packit 857059
									i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                        		{
Packit 857059
									pGuidResults->Guids[i] = 
Packit 857059
										((IB_NODE_RECORD*)p)->NodeInfoData.PortGUID;
Packit 857059
Packit 857059
                        		}
Packit 857059
							}
Packit 857059
							break;
Packit 857059
						default:
Packit 857059
							break;
Packit 857059
					}
Packit 857059
					break;
Packit 857059
				}
Packit 857059
				case (OutputTypeNodeDesc):
Packit 857059
				{
Packit 857059
    				PNODEDESC_RESULTS 		pNodeDescResults;
Packit 857059
Packit 857059
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
									+ (NumRecords * sizeof(NODEDESC_RESULTS)),
Packit 857059
									IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(NODEDESC_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting NodeDescription from NodeRecord - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
					if ( NumRecords > 0 )	
Packit 857059
					{
Packit 857059
                    	pNodeDescResults = (PNODEDESC_RESULTS)pClientResult->QueryResult;
Packit 857059
						pNodeDescResults->NumDescs = NumRecords;
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
							i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                    		pNodeDescResults->NodeDescs[i] = 
Packit 857059
									((IB_NODE_RECORD*)p)->NodeDescData;
Packit 857059
                    	}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
				}
Packit 857059
Packit 857059
                case (OutputTypeNodeRecord):
Packit 857059
				{
Packit 857059
    				PNODE_RECORD_RESULTS	pNodeInfoResults;
Packit 857059
Packit 857059
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(NODE_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(NODE_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete NodeRecord - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0 )
Packit 857059
                    {
Packit 857059
                    	pNodeInfoResults = (PNODE_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                    	pNodeInfoResults->NumNodeRecords = NumRecords;
Packit 857059
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
							i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                        	pNodeInfoResults->NodeRecords[i] = 
Packit 857059
									*((IB_NODE_RECORD*)p);
Packit 857059
                    	}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
				}
Packit 857059
                case (OutputTypePathRecord):
Packit 857059
                {
Packit 857059
                	uint64 *pDestPortGuidsList;
Packit 857059
                	uint32 DestPortGuidsCount;
Packit 857059
					QueryDetails **pChildQueryElements;
Packit 857059
Packit 857059
                	extern uint32 NumTotalPorts;
Packit 857059
 
Packit 857059
                	if(NumTotalPorts == 0)
Packit 857059
                	{
Packit 857059
                    	_DBG_INFO(("Total Number of Ports turns out to be zero\n"));
Packit 857059
                    	break;
Packit 857059
                	}
Packit 857059
Packit 857059
                    if ( NumRecords == 0)
Packit 857059
                    {
Packit 857059
                    	pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES),
Packit 857059
                                                                IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    	if (pClientResult == NULL)
Packit 857059
							goto failalloc;
Packit 857059
                    	pClientResult->ResultDataSize = 0;
Packit 857059
						break;
Packit 857059
					}
Packit 857059
Packit 857059
                    pDestPortGuidsList = (EUI64*)MemoryAllocate2AndClear((sizeof(EUI64)*NumRecords),
Packit 857059
							IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION,
Packit 857059
							SUBNET_DRIVER_TAG);
Packit 857059
Packit 857059
					DestPortGuidsCount = NumRecords;
Packit 857059
                    if (pDestPortGuidsList == NULL)
Packit 857059
                    {
Packit 857059
                        _DBG_ERROR(("Cannot allocate memory for DestPortGuids\n"));
Packit 857059
                        goto failalloc2;
Packit 857059
                    }
Packit 857059
					 
Packit 857059
					for (i = 0, p = pSaMad->Data;
Packit 857059
							i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    {
Packit 857059
                        pDestPortGuidsList[i] = 
Packit 857059
							((IB_NODE_RECORD*)p)->NodeInfoData.PortGUID;
Packit 857059
                    } 
Packit 857059
 
Packit 857059
                	// Multistaged query
Packit 857059
                	pChildQueryElements = BuildSAChildQueriesForPathRecord(
Packit 857059
														pQueryElement,
Packit 857059
                    									pDestPortGuidsList, 
Packit 857059
														DestPortGuidsCount);
Packit 857059
                	MemoryDeallocate(pDestPortGuidsList);
Packit 857059
					if(! pChildQueryElements)
Packit 857059
                	{
Packit 857059
                        goto failalloc2;
Packit 857059
                	}
Packit 857059
					SpinLockAcquire(&pQueryList->m_Lock);
Packit 857059
					if (FreeCancelledQueryElement(pQueryElement))
Packit 857059
					{
Packit 857059
						SpinLockRelease(&pQueryList->m_Lock);
Packit 857059
						for(i = 0; i
Packit 857059
						{
Packit 857059
							FreeQueryElement(pChildQueryElements[i]);
Packit 857059
						}
Packit 857059
						MemoryDeallocate(pChildQueryElements);
Packit 857059
						SpinLockAcquire(&pQueryList->m_Lock);
Packit 857059
						goto ret;
Packit 857059
					}
Packit 857059
                	pQueryElement->QState = WaitingForChildToComplete;
Packit 857059
                	//Leave pQueryElement on pQueryList
Packit 857059
					DEBUG_ASSERT(pQueryElement->SdSentCmd == UserQueryFabricInformation);
Packit 857059
					DEBUG_ASSERT(pQueryElement->cmd.query.pClientResult == NULL);
Packit 857059
					// start the child queries
Packit 857059
					pQueryElement->NoOfChildQuery = DestPortGuidsCount;
Packit 857059
					for(i = 0; i
Packit 857059
					{
Packit 857059
						// Put this on to the child query List
Packit 857059
						LQListInsertHead(pChildQueryList, &(pChildQueryElements[i])->QueryListItem);
Packit 857059
					}
Packit 857059
					SpinLockRelease(&pQueryList->m_Lock);
Packit 857059
					MemoryDeallocate(pChildQueryElements);
Packit 857059
					SpinLockAcquire(&pQueryList->m_Lock);
Packit 857059
					// completion processing will processes pChildQueryList
Packit 857059
					ScheduleCompletionProcessing();
Packit 857059
					goto ret;
Packit 857059
                }
Packit 857059
				default:
Packit 857059
					break;
Packit 857059
			}
Packit 857059
			break;
Packit 857059
		}
Packit 857059
Packit 857059
		case	SA_ATTRIB_PORTINFO_RECORD:
Packit 857059
		{
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_PORTINFO_RECORD((IB_PORTINFO_RECORD*)p, TRUE);
Packit 857059
            }
Packit 857059
			_DBG_INFO(("Processing IB_PORTINFO_RECORD..... NumRecords[%d]\n",
Packit 857059
										NumRecords));
Packit 857059
 
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
Packit 857059
                case (OutputTypePortInfoRecord):
Packit 857059
				{
Packit 857059
					PPORTINFO_RECORD_RESULTS	pPortInfoResults;
Packit 857059
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
                                                                + (NumRecords * sizeof(PORTINFO_RECORD_RESULTS)),
Packit 857059
                                                                IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(PORTINFO_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete PortInfoRecords - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
					
Packit 857059
					if ( NumRecords > 0)
Packit 857059
					{
Packit 857059
                    	pPortInfoResults = (PPORTINFO_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                    	pPortInfoResults->NumPortInfoRecords = NumRecords;
Packit 857059
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                        	pPortInfoResults->PortInfoRecords[i] = 
Packit 857059
								*((IB_PORTINFO_RECORD*)p);
Packit 857059
                    	}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
				}
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
			}
Packit 857059
			break;
Packit 857059
		}
Packit 857059
		case	SA_ATTRIB_SMINFO_RECORD:
Packit 857059
		{
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_SMINFO_RECORD((IB_SMINFO_RECORD*)p);
Packit 857059
            }
Packit 857059
 
Packit 857059
			_DBG_INFO(("Processing IB_SMINFO_RECORD..... NumRecords[%d]\n",
Packit 857059
										NumRecords));
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
 
Packit 857059
                case (OutputTypeSMInfoRecord):
Packit 857059
                {
Packit 857059
                    PSMINFO_RECORD_RESULTS    pSMInfoResults;
Packit 857059
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(SMINFO_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(SMINFO_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete SMInfoRecords - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
                    	pSMInfoResults = (PSMINFO_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                    	pSMInfoResults->NumSMInfoRecords = NumRecords;
Packit 857059
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                        	pSMInfoResults->SMInfoRecords[i] = 
Packit 857059
										*((IB_SMINFO_RECORD*)p);
Packit 857059
                    	}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
		}
Packit 857059
		case	SA_ATTRIB_LINK_RECORD:
Packit 857059
		{
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_LINK_RECORD((IB_LINK_RECORD*)p);
Packit 857059
            }
Packit 857059
            _DBG_INFO(("Processing IB_LINK_RECORD..... NumRecords[%d]\n",
Packit 857059
                                        NumRecords));
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
                case (OutputTypeLinkRecord):
Packit 857059
                {
Packit 857059
                    PLINK_RECORD_RESULTS    pLinkResults;
Packit 857059
 
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(LINK_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(LINK_RECORD_RESULTS);
Packit 857059
Packit 857059
                    _DBG_INFO(("Extracting complete LinkRecords - NumRecords[%d]\n",
Packit 857059
                                                        NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
                    	pLinkResults = (PLINK_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                    	pLinkResults->NumLinkRecords = NumRecords;
Packit 857059
 
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                        	pLinkResults->LinkRecords[i] = *((IB_LINK_RECORD*)p);
Packit 857059
                    	}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
        }
Packit 857059
		case	SA_ATTRIB_PATH_RECORD:
Packit 857059
		{
Packit 857059
			uint32 PktLifeTime = 0;
Packit 857059
			if (g_SdParams.MinPktLifeTime)
Packit 857059
				PktLifeTime = TimeoutTimeMsToMult(g_SdParams.MinPktLifeTime);
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_PATH_RECORD((IB_PATH_RECORD*)p);
Packit 857059
				if (PktLifeTime > ((IB_PATH_RECORD*)p)->PktLifeTime)
Packit 857059
					((IB_PATH_RECORD*)p)->PktLifeTime = PktLifeTime;
Packit 857059
            }
Packit 857059
			_DBG_INFO(("Processing IB_PATH_RECORD..... NumRecords[%d]\n",
Packit 857059
										NumRecords));
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
 
Packit 857059
                case (OutputTypePathRecord):
Packit 857059
                {
Packit 857059
                    PPATH_RESULTS    pPathRecordResults;
Packit 857059
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(PATH_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(PATH_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete PathRecord - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
                    	pPathRecordResults = (PPATH_RESULTS)pClientResult->QueryResult;
Packit 857059
                    	pPathRecordResults->NumPathRecords = NumRecords;
Packit 857059
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                        	pPathRecordResults->PathRecords[i] = 
Packit 857059
										*((IB_PATH_RECORD*)p);
Packit 857059
                    	}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
		}
Packit 857059
		case	SA_ATTRIB_SERVICE_RECORD:
Packit 857059
		{
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_SERVICE_RECORD((IB_SERVICE_RECORD*)p);
Packit 857059
            }
Packit 857059
			_DBG_INFO(("Processing IB_SERVICE_RECORD..... NumRecords[%d]\n",
Packit 857059
						NumRecords));
Packit 857059
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
 
Packit 857059
                case (OutputTypeServiceRecord):
Packit 857059
                {
Packit 857059
                    PSERVICE_RECORD_RESULTS    pServiceResults;
Packit 857059
 
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(SERVICE_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(SERVICE_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete ServiceRecords - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
						pServiceResults = (PSERVICE_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                   		pServiceResults->NumServiceRecords = NumRecords;
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                   			pServiceResults->ServiceRecords[i] = *((IB_SERVICE_RECORD*)p);
Packit 857059
						}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
		}
Packit 857059
		case	SA_ATTRIB_MCMEMBER_RECORD:
Packit 857059
		{
Packit 857059
			uint32 PktLifeTime = 0;
Packit 857059
			if (g_SdParams.MinPktLifeTime)
Packit 857059
				PktLifeTime = TimeoutTimeMsToMult(g_SdParams.MinPktLifeTime);
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_MCMEMBER_RECORD((IB_MCMEMBER_RECORD*)p);
Packit 857059
				if (PktLifeTime > ((IB_MCMEMBER_RECORD*)p)->PktLifeTime)
Packit 857059
					((IB_MCMEMBER_RECORD*)p)->PktLifeTime = PktLifeTime;
Packit 857059
            }
Packit 857059
			_DBG_INFO(("Processing IB_MCMEMBER_RECORD..... NumRecords[%d]\n",
Packit 857059
						NumRecords));
Packit 857059
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
 
Packit 857059
                case (OutputTypeMcMemberRecord):
Packit 857059
                {
Packit 857059
                    PMCMEMBER_RECORD_RESULTS    pMcMemberResults;
Packit 857059
 
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(MCMEMBER_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(MCMEMBER_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete McMemberRecords - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
						pMcMemberResults = (PMCMEMBER_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                   		pMcMemberResults->NumMcMemberRecords = NumRecords;
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                   			pMcMemberResults->McMemberRecords[i] = *((IB_MCMEMBER_RECORD*)p);
Packit 857059
						}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
		}
Packit 857059
		case	SA_ATTRIB_INFORM_INFO_RECORD:
Packit 857059
		{
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_INFORM_INFO_RECORD((IB_INFORM_INFO_RECORD*)p);
Packit 857059
            }
Packit 857059
			_DBG_INFO(("Processing IB_INFORM_INFO_RECORD..... NumRecords[%d]\n",
Packit 857059
						NumRecords));
Packit 857059
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
 
Packit 857059
                case (OutputTypeInformInfoRecord):
Packit 857059
                {
Packit 857059
                    PINFORM_INFO_RECORD_RESULTS    pInformInfoResults;
Packit 857059
 
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(INFORM_INFO_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(INFORM_INFO_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete InformInfoRecords - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
						pInformInfoResults = (PINFORM_INFO_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                   		pInformInfoResults->NumInformInfoRecords = NumRecords;
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                   			pInformInfoResults->InformInfoRecords[i] = *((IB_INFORM_INFO_RECORD*)p);
Packit 857059
						}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
		}
Packit 857059
        case	SA_ATTRIB_TRACE_RECORD:
Packit 857059
		{
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_TRACE_RECORD((IB_TRACE_RECORD*)p);
Packit 857059
            }
Packit 857059
			_DBG_INFO(("Processing IB_TRACE_RECORD..... NumRecords[%d]\n",
Packit 857059
										NumRecords));
Packit 857059
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
 
Packit 857059
                case (OutputTypeTraceRecord):
Packit 857059
                {
Packit 857059
                    PTRACE_RECORD_RESULTS    pTraceRecordResults;
Packit 857059
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(TRACE_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(TRACE_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete TraceRecord - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
                    	pTraceRecordResults = (PTRACE_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                    	pTraceRecordResults->NumTraceRecords = NumRecords;
Packit 857059
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                        	pTraceRecordResults->TraceRecords[i] = 
Packit 857059
										*((IB_TRACE_RECORD*)p);
Packit 857059
                            // convert encrypted fields
Packit 857059
                            pTraceRecordResults->TraceRecords[i].GIDPrefix ^= IB_TRACE_RECORD_COMP_ENCRYPT_MASK;
Packit 857059
                            pTraceRecordResults->TraceRecords[i].NodeID ^= IB_TRACE_RECORD_COMP_ENCRYPT_MASK;
Packit 857059
                            pTraceRecordResults->TraceRecords[i].ChassisID ^= IB_TRACE_RECORD_COMP_ENCRYPT_MASK;
Packit 857059
                            pTraceRecordResults->TraceRecords[i].EntryPortID ^= IB_TRACE_RECORD_COMP_ENCRYPT_MASK;
Packit 857059
                            pTraceRecordResults->TraceRecords[i].ExitPortID ^= IB_TRACE_RECORD_COMP_ENCRYPT_MASK;
Packit 857059
                    	}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
		}
Packit 857059
		case	SA_ATTRIB_SWITCHINFO_RECORD:
Packit 857059
		{
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_SWITCHINFO_RECORD((IB_SWITCHINFO_RECORD*)p);
Packit 857059
            }
Packit 857059
			_DBG_INFO(("Processing IB_SWITCHINFO_RECORD..... NumRecords[%d]\n",
Packit 857059
						NumRecords));
Packit 857059
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
 
Packit 857059
                case (OutputTypeSwitchInfoRecord):
Packit 857059
                {
Packit 857059
                    PSWITCHINFO_RECORD_RESULTS    pSwitchInfoResults;
Packit 857059
 
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(SWITCHINFO_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(SWITCHINFO_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete SwitchInfoRecords - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
						pSwitchInfoResults = (PSWITCHINFO_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                   		pSwitchInfoResults->NumSwitchInfoRecords = NumRecords;
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                   			pSwitchInfoResults->SwitchInfoRecords[i] = *((IB_SWITCHINFO_RECORD*)p);
Packit 857059
						}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
		}
Packit 857059
		case	SA_ATTRIB_LINEAR_FWDTBL_RECORD:
Packit 857059
		{
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_LINEAR_FDB_RECORD((IB_LINEAR_FDB_RECORD*)p);
Packit 857059
            }
Packit 857059
			_DBG_INFO(("Processing IB_LINEAR_FDB_RECORD..... NumRecords[%d]\n",
Packit 857059
						NumRecords));
Packit 857059
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
 
Packit 857059
                case (OutputTypeLinearFDBRecord):
Packit 857059
                {
Packit 857059
                    PLINEAR_FDB_RECORD_RESULTS    pLinearFDBResults;
Packit 857059
 
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(LINEAR_FDB_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(LINEAR_FDB_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete LinearFDBRecords - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
						pLinearFDBResults = (PLINEAR_FDB_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                   		pLinearFDBResults->NumLinearFDBRecords = NumRecords;
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                   			pLinearFDBResults->LinearFDBRecords[i] = *((IB_LINEAR_FDB_RECORD*)p);
Packit 857059
						}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
		}
Packit 857059
		case	SA_ATTRIB_RANDOM_FWDTBL_RECORD:
Packit 857059
		{
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_RANDOM_FDB_RECORD((IB_RANDOM_FDB_RECORD*)p);
Packit 857059
            }
Packit 857059
			_DBG_INFO(("Processing IB_RANDOM_FDB_RECORD..... NumRecords[%d]\n",
Packit 857059
						NumRecords));
Packit 857059
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
 
Packit 857059
                case (OutputTypeRandomFDBRecord):
Packit 857059
                {
Packit 857059
                    PRANDOM_FDB_RECORD_RESULTS    pRandomFDBResults;
Packit 857059
 
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(RANDOM_FDB_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(RANDOM_FDB_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete RandomFDBRecords - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
						pRandomFDBResults = (PRANDOM_FDB_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                   		pRandomFDBResults->NumRandomFDBRecords = NumRecords;
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                   			pRandomFDBResults->RandomFDBRecords[i] = *((IB_RANDOM_FDB_RECORD*)p);
Packit 857059
						}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
		}
Packit 857059
		case	SA_ATTRIB_MCAST_FWDTBL_RECORD:
Packit 857059
		{
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_MCAST_FDB_RECORD((IB_MCAST_FDB_RECORD*)p);
Packit 857059
            }
Packit 857059
			_DBG_INFO(("Processing IB_MCAST_FDB_RECORD..... NumRecords[%d]\n",
Packit 857059
						NumRecords));
Packit 857059
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
 
Packit 857059
                case (OutputTypeMCastFDBRecord):
Packit 857059
                {
Packit 857059
                    PMCAST_FDB_RECORD_RESULTS    pMCastFDBResults;
Packit 857059
 
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(MCAST_FDB_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(MCAST_FDB_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete MCastFDBRecords - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
						pMCastFDBResults = (PMCAST_FDB_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                   		pMCastFDBResults->NumMCastFDBRecords = NumRecords;
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                   			pMCastFDBResults->MCastFDBRecords[i] = *((IB_MCAST_FDB_RECORD*)p);
Packit 857059
						}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
		}
Packit 857059
		case	SA_ATTRIB_VLARBTABLE_RECORD:
Packit 857059
		{
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_VLARBTABLE_RECORD((IB_VLARBTABLE_RECORD*)p);
Packit 857059
            }
Packit 857059
			_DBG_INFO(("Processing IB_VLARBTABLE_RECORD..... NumRecords[%d]\n",
Packit 857059
						NumRecords));
Packit 857059
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
 
Packit 857059
                case (OutputTypeVLArbTableRecord):
Packit 857059
                {
Packit 857059
                    PVLARBTABLE_RECORD_RESULTS    pVLArbTableResults;
Packit 857059
 
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(VLARBTABLE_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(VLARBTABLE_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete VLArbTableRecords - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
						pVLArbTableResults = (PVLARBTABLE_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                   		pVLArbTableResults->NumVLArbTableRecords = NumRecords;
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                   			pVLArbTableResults->VLArbTableRecords[i] = *((IB_VLARBTABLE_RECORD*)p);
Packit 857059
						}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
		}
Packit 857059
		case	SA_ATTRIB_P_KEY_TABLE_RECORD:
Packit 857059
		{
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
            {
Packit 857059
				BSWAP_IB_P_KEY_TABLE_RECORD((IB_P_KEY_TABLE_RECORD*)p);
Packit 857059
            }
Packit 857059
			_DBG_INFO(("Processing IB_P_KEY_TABLE_RECORD..... NumRecords[%d]\n",
Packit 857059
						NumRecords));
Packit 857059
Packit 857059
            switch(QueryOutputType)
Packit 857059
            {
Packit 857059
 
Packit 857059
                case (OutputTypePKeyTableRecord):
Packit 857059
                {
Packit 857059
                    PPKEYTABLE_RECORD_RESULTS    pPKeyTableResults;
Packit 857059
 
Packit 857059
                    pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(sizeof(QUERY_RESULT_VALUES)
Packit 857059
								+ (NumRecords * sizeof(PKEYTABLE_RECORD_RESULTS)),
Packit 857059
								IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
Packit 857059
                    if (pClientResult == NULL)
Packit 857059
						goto failalloc;
Packit 857059
                    pClientResult->ResultDataSize = NumRecords * sizeof(PKEYTABLE_RECORD_RESULTS);
Packit 857059
Packit 857059
					_DBG_INFO(("Extracting complete PKeyTableRecords - NumRecords[%d]\n",
Packit 857059
														NumRecords));
Packit 857059
                    if ( NumRecords > 0)
Packit 857059
                    {
Packit 857059
						pPKeyTableResults = (PPKEYTABLE_RECORD_RESULTS)pClientResult->QueryResult;
Packit 857059
                   		pPKeyTableResults->NumPKeyTableRecords = NumRecords;
Packit 857059
						for (i = 0, p = pSaMad->Data;
Packit 857059
								i < NumRecords; i++, p+=PaddedRecordSize)
Packit 857059
                    	{
Packit 857059
                   			pPKeyTableResults->PKeyTableRecords[i] = *((IB_P_KEY_TABLE_RECORD*)p);
Packit 857059
						}
Packit 857059
					}
Packit 857059
                    break;
Packit 857059
                }
Packit 857059
                default:
Packit 857059
                    break;
Packit 857059
            }
Packit 857059
			break;
Packit 857059
		}
Packit 857059
		default:
Packit 857059
			break;
Packit 857059
	}
Packit 857059
	SpinLockAcquire(&pQueryList->m_Lock);
Packit 857059
	if (FreeCancelledQueryElement(pQueryElement))
Packit 857059
		goto ret;
Packit 857059
	DEBUG_ASSERT(pQueryElement->SdSentCmd == UserQueryFabricInformation);
Packit 857059
	DEBUG_ASSERT(pQueryElement->cmd.query.pClientResult == NULL);
Packit 857059
	pQueryElement->cmd.query.pClientResult = pClientResult;
Packit 857059
	if (NULL != pClientResult)
Packit 857059
	{
Packit 857059
		pClientResult->Status = pQueryElement->Status;
Packit 857059
		pClientResult->MadStatus = pQueryElement->MadStatus;
Packit 857059
	}
Packit 857059
Packit 857059
done:
Packit 857059
	// Insert the Queryelement into the CompletionList
Packit 857059
	QListRemoveItem( &pQueryList->m_List, &pQueryElement->QueryListItem);
Packit 857059
	pQueryElement->QState = QueryComplete;
Packit 857059
	LQListInsertHead(pCompletionList, &pQueryElement->QueryListItem);  
Packit 857059
	ScheduleCompletionProcessing();
Packit 857059
ret:
Packit 857059
	_DBG_LEAVE_EXT(_DBG_LVL_FUNC_TRACE);
Packit 857059
	return (FSUCCESS);
Packit 857059
Packit 857059
failalloc:
Packit 857059
	_DBG_ERROR(("Cannot allocate memory for SA Response\n"));
Packit 857059
failalloc2:
Packit 857059
	SpinLockAcquire(&pQueryList->m_Lock);
Packit 857059
	if (FreeCancelledQueryElement(pQueryElement))
Packit 857059
		goto ret;
Packit 857059
	DEBUG_ASSERT(pQueryElement->SdSentCmd == UserQueryFabricInformation);
Packit 857059
	DEBUG_ASSERT(pQueryElement->cmd.query.pClientResult == NULL);
Packit 857059
	pQueryElement->Status = FINSUFFICIENT_MEMORY;
Packit 857059
	pQueryElement->MadStatus = 0;
Packit 857059
	goto done;
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
// called with pQueryList->m_Lock already held
Packit 857059
// This handles the 2nd tier of a 2 tiered query
Packit 857059
// currently only 2nd tier is a GetTable for PathRecord
Packit 857059
// called with buffer==NULL and messageSize == 0 if query has timed out
Packit 857059
// pQueryElement is in WaitingForResult, still on list
Packit 857059
FSTATUS 
Packit 857059
SdHandleChildQuery(
Packit 857059
	PQueryDetails pQueryElement,
Packit 857059
	void *buffer,			// caller removed GRH already
Packit 857059
	uint32 messageSize		// caller removed GRH already
Packit 857059
	)
Packit 857059
{
Packit 857059
	//FSTATUS Fstatus = FERROR;
Packit 857059
	QUERY_RESULT_VALUES * pClientResult = NULL;
Packit 857059
	uint32 NumRecords;
Packit 857059
	uint32 RecordSize;
Packit 857059
	uint32 PaddedRecordSize;
Packit 857059
	uint32 PreviousNumPathRecords = 0;
Packit 857059
	uint32 PrevDataSize = 0;
Packit 857059
	SA_MAD *pSaMad = (SA_MAD*)buffer;
Packit 857059
	char *temp;
Packit 857059
	PPATH_RESULTS pPathResults = NULL;
Packit 857059
	PQueryDetails pRootQueryElement = pQueryElement->pParentQuery;
Packit 857059
    
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, SdHandleChildQuery);
Packit 857059
	//Check for the Parent Query
Packit 857059
	// pQueryList->m_Lock already held
Packit 857059
	// this does not dereference pParentQuery
Packit 857059
	if (! QListIsItemInList(&pQueryList->m_List,&pRootQueryElement->QueryListItem))
Packit 857059
	{
Packit 857059
		_DBG_INFO(("Could not find the root queryelement\n"));
Packit 857059
		goto childdone;
Packit 857059
	}
Packit 857059
Packit 857059
	if (buffer == NULL) //Timeout 
Packit 857059
	{
Packit 857059
		_DBG_ERROR(("SA Query Timed Out <%d ms, %d retries>\n",
Packit 857059
			pQueryElement->ControlParameters.Timeout,
Packit 857059
			pQueryElement->ControlParameters.RetryCount));
Packit 857059
		pQueryElement->Status = FTIMEOUT;
Packit 857059
		pQueryElement->MadStatus = 0;	// unknown, no response
Packit 857059
		goto done;
Packit 857059
	}
Packit 857059
	// Include MAD Status and reserved field
Packit 857059
	pQueryElement->MadStatus = (pSaMad->common.u.NS.Reserved1 << 16|
Packit 857059
									pSaMad->common.u.NS.Status.AsReg16);
Packit 857059
	if (pSaMad->common.u.NS.Status.AsReg16 == MAD_STATUS_SA_NO_RECORDS)
Packit 857059
	{
Packit 857059
		_DBG_INFO(("No Records MAD completion received\n"));
Packit 857059
	} else if (pSaMad->common.u.NS.Status.AsReg16 != MAD_STATUS_SUCCESS) {
Packit 857059
		_DBG_ERROR(("Failed MAD completion received, Status <0x%x: %s>, Port 0x%016"PRIx64"\n",
Packit 857059
			pSaMad->common.u.NS.Status.AsReg16,
Packit 857059
			_DBG_PTR(iba_sd_mad_status_msg(pQueryElement->MadStatus)),
Packit 857059
			pQueryElement->PortGuid));
Packit 857059
		pQueryElement->Status = FERROR; 
Packit 857059
		goto done;
Packit 857059
	}
Packit 857059
Packit 857059
	pQueryElement->Status = FSUCCESS; 
Packit 857059
	_DBG_INFO(("Successful MAD completion received\n"));
Packit 857059
	BSWAP_SA_HDR(&pSaMad->SaHdr);
Packit 857059
	
Packit 857059
	DEBUG_ASSERT(pRootQueryElement->SdSentCmd == UserQueryFabricInformation);
Packit 857059
	pRootQueryElement->ChildProcessingResponseCount++;	// holds ref to parent
Packit 857059
	pQueryElement->QState = ProcessingResponse;	// prevent timeout of child
Packit 857059
	SpinLockRelease(&pQueryList->m_Lock);
Packit 857059
Packit 857059
	// This mutex prevents races between multiple child processes updating
Packit 857059
	// their parents pClientResult at the same time.  In reality, since there
Packit 857059
	// is one thread for SD GSA callbacks, there will be no contention for
Packit 857059
	// this mutex, hence there is no advantage to putting it into the
Packit 857059
	// parent query element.  Also note that for parent queries, the
Packit 857059
	// pClientResult of the parent is not modified until all children are done
Packit 857059
	MutexAcquire(pChildGrowParentMutex);
Packit 857059
	if(pRootQueryElement->cmd.query.pClientResult)
Packit 857059
	{
Packit 857059
		PrevDataSize = pRootQueryElement->cmd.query.pClientResult->ResultDataSize;
Packit 857059
		pPathResults =(PPATH_RESULTS)pRootQueryElement->cmd.query.pClientResult->QueryResult;
Packit 857059
		PreviousNumPathRecords =  pPathResults->NumPathRecords;
Packit 857059
	}else
Packit 857059
	{
Packit 857059
		PrevDataSize = sizeof(PATH_RESULTS) - sizeof(IB_PATH_RECORD);
Packit 857059
		PreviousNumPathRecords = 0;
Packit 857059
	}
Packit 857059
	
Packit 857059
	if (pSaMad->common.u.NS.Status.AsReg16 == MAD_STATUS_SA_NO_RECORDS)
Packit 857059
	{
Packit 857059
		NumRecords = 0;
Packit 857059
	} else {
Packit 857059
		(void)SdComputeResponseSizes(pSaMad, messageSize, &NumRecords,
Packit 857059
								&PaddedRecordSize, &RecordSize);
Packit 857059
	}
Packit 857059
	if(NumRecords)
Packit 857059
	{
Packit 857059
		uint32 ResBuffSize = 0;
Packit 857059
		uint32 PathRecSize = NumRecords*RecordSize;
Packit 857059
		
Packit 857059
		ResBuffSize = sizeof(QUERY_RESULT_VALUES) 
Packit 857059
				+ PathRecSize + PrevDataSize;
Packit 857059
		
Packit 857059
		pClientResult = (QUERY_RESULT_VALUES*)MemoryAllocate2AndClear(ResBuffSize,
Packit 857059
							IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION,
Packit 857059
							SUBNET_DRIVER_TAG);
Packit 857059
		if (pClientResult != NULL)  
Packit 857059
		{
Packit 857059
			uint8*	p;
Packit 857059
			uint32 i;
Packit 857059
			IB_PATH_RECORD *pIbPathRecDest;
Packit 857059
			uint32 PktLifeTime = 0;
Packit 857059
			
Packit 857059
			pClientResult->Status = FSUCCESS;
Packit 857059
			pClientResult->MadStatus = pQueryElement->MadStatus;
Packit 857059
			pClientResult->ResultDataSize = PathRecSize + PrevDataSize;
Packit 857059
			pPathResults = (PPATH_RESULTS)pClientResult->QueryResult;
Packit 857059
			if (g_SdParams.MinPktLifeTime) {
Packit 857059
				PktLifeTime = TimeoutTimeMsToMult(g_SdParams.MinPktLifeTime);
Packit 857059
			}
Packit 857059
Packit 857059
			pIbPathRecDest = pPathResults->PathRecords;
Packit 857059
			for (i = 0, p = pSaMad->Data;
Packit 857059
					i < NumRecords;
Packit 857059
					i++, p+=PaddedRecordSize, pIbPathRecDest++)
Packit 857059
			{
Packit 857059
				BSWAP_IB_PATH_RECORD((IB_PATH_RECORD*)p);
Packit 857059
				MemoryCopy(pIbPathRecDest, p, sizeof(IB_PATH_RECORD));
Packit 857059
				if (PktLifeTime > pIbPathRecDest->PktLifeTime)
Packit 857059
                	pIbPathRecDest->PktLifeTime = PktLifeTime;
Packit 857059
			}
Packit 857059
			if(PreviousNumPathRecords>0)
Packit 857059
			{
Packit 857059
				//Append the Previous Data
Packit 857059
				temp = (char *)pPathResults->PathRecords;
Packit 857059
				temp = temp + PathRecSize;
Packit 857059
				pPathResults = 
Packit 857059
					(PPATH_RESULTS)pRootQueryElement->cmd.query.pClientResult->QueryResult;
Packit 857059
				MemoryCopy(temp, 
Packit 857059
					pPathResults->PathRecords,
Packit 857059
					PreviousNumPathRecords * RecordSize);
Packit 857059
				MemoryDeallocate(pRootQueryElement->cmd.query.pClientResult);
Packit 857059
				
Packit 857059
			}
Packit 857059
			pPathResults = (PPATH_RESULTS)pClientResult->QueryResult;
Packit 857059
			pPathResults->NumPathRecords = PreviousNumPathRecords + NumRecords;
Packit 857059
			pRootQueryElement->cmd.query.pClientResult = pClientResult;
Packit 857059
		}else {
Packit 857059
			_DBG_ERROR( ("Cannot allocate memory for QueryElement\n"));
Packit 857059
		}
Packit 857059
	}
Packit 857059
	MutexRelease(pChildGrowParentMutex);
Packit 857059
	SpinLockAcquire(&pQueryList->m_Lock);
Packit 857059
	pRootQueryElement->ChildProcessingResponseCount--;
Packit 857059
	// children can't be cancelled directly
Packit 857059
	DEBUG_ASSERT(pQueryElement->QState != QueryDestroy);
Packit 857059
	if (FreeCancelledQueryElement(pRootQueryElement))
Packit 857059
	{
Packit 857059
		// parent has been cancelled, child is done but no parent
Packit 857059
		goto childdone;
Packit 857059
	}
Packit 857059
Packit 857059
done:
Packit 857059
	// Associate this child to the parent
Packit 857059
	(pRootQueryElement->NoOfChildQuery)--;
Packit 857059
	if(pRootQueryElement->NoOfChildQuery == 0)
Packit 857059
	{
Packit 857059
		ASSERT(pRootQueryElement->QState == WaitingForChildToComplete);
Packit 857059
		//Remove Parent from Qlist and insert it into CompletionList //NOTENOTE
Packit 857059
		// pQueryList->m_Lock already held
Packit 857059
		QListRemoveItem( &pQueryList->m_List, (LIST_ITEM *)pRootQueryElement );
Packit 857059
			
Packit 857059
		//Update the status from WaitingForChild to QueryComplete
Packit 857059
		
Packit 857059
		pRootQueryElement->QState = QueryComplete;
Packit 857059
		
Packit 857059
		// Insert the parent QueryElement into the CompletionList
Packit 857059
		LQListInsertHead(pCompletionList, &pRootQueryElement->QueryListItem);  
Packit 857059
	}
Packit 857059
childdone:
Packit 857059
	AtomicDecrementVoid(&ChildQueryActive);
Packit 857059
	QListRemoveItem( &pQueryList->m_List, &pQueryElement->QueryListItem);
Packit 857059
	if (buffer == NULL)
Packit 857059
	{
Packit 857059
		// called within TimerHandler, defer destroy to premptable context
Packit 857059
		pQueryElement->QState = QueryDestroy;
Packit 857059
		LQListInsertHead(pCompletionList, &pQueryElement->QueryListItem);  
Packit 857059
	} else {
Packit 857059
		// call free in a premptable context
Packit 857059
		SpinLockRelease(&pQueryList->m_Lock);
Packit 857059
		FreeQueryElement(pQueryElement);
Packit 857059
		SpinLockAcquire(&pQueryList->m_Lock);
Packit 857059
	}
Packit 857059
	// run CompletionQueue to queue next child queries or complete
Packit 857059
	// parent as appropriate
Packit 857059
	ScheduleCompletionProcessing();
Packit 857059
	_DBG_LEAVE_EXT(_DBG_LVL_FUNC_TRACE);
Packit 857059
	return(FSUCCESS);
Packit 857059
}
Packit 857059
 
Packit 857059
//////////////////////////////////////////////////////
Packit 857059
// called without pQueryList->m_Lock held
Packit 857059
// pRootQueryElement is in ProcessingResponse state, so we can access it
Packit 857059
// returns a list of Child queries which have been built and initialized
Packit 857059
// but have not yet been places on ChildQueryList, so they have not yet
Packit 857059
// been started
Packit 857059
QueryDetails **
Packit 857059
BuildSAChildQueriesForPathRecord(
Packit 857059
	PQueryDetails pRootQueryElement, 
Packit 857059
	uint64 *pDestPortGuidsList,
Packit 857059
	uint32 DestPortGuidsCount
Packit 857059
	)
Packit 857059
{
Packit 857059
	uint32 i;
Packit 857059
	QueryDetails *pQueryElement;
Packit 857059
	QueryDetails **pChildQueryElements;
Packit 857059
	FSTATUS status;
Packit 857059
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, BuildSAChildQueriesForPathRecord);
Packit 857059
Packit 857059
	pChildQueryElements = (QueryDetails**)MemoryAllocate2AndClear(
Packit 857059
							sizeof(QueryDetails*)*DestPortGuidsCount,
Packit 857059
							IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION,
Packit 857059
							SUBNET_DRIVER_TAG);
Packit 857059
	if (NULL == pChildQueryElements)
Packit 857059
	{
Packit 857059
		_DBG_ERROR(("Cannot allocate memory for list of Child SA Queries\n"));
Packit 857059
		goto done;
Packit 857059
	}
Packit 857059
Packit 857059
	for(i = 0; i
Packit 857059
	{
Packit 857059
		pQueryElement = (QueryDetails*)MemoryAllocate2AndClear(sizeof(QueryDetails),
Packit 857059
							IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION,
Packit 857059
							SUBNET_DRIVER_TAG);
Packit 857059
		if (pQueryElement == NULL)  
Packit 857059
		{
Packit 857059
			_DBG_ERROR(("Cannot allocate memory for Child SA Query\n"));
Packit 857059
			goto failalloc;
Packit 857059
		}
Packit 857059
		QListSetObj(&pQueryElement->QueryListItem, (void *)pQueryElement);
Packit 857059
Packit 857059
		pQueryElement->ControlParameters = pRootQueryElement->ControlParameters;
Packit 857059
Packit 857059
		pQueryElement->SdSentCmd = UserQueryFabricInformation;
Packit 857059
		pQueryElement->cmd.query.UserQuery.InputType = InputTypePortGuidPair;
Packit 857059
		pQueryElement->cmd.query.UserQuery.OutputType = OutputTypePathRecord;
Packit 857059
		pQueryElement->cmd.query.UserQuery.InputValue.PortGuidPair.DestPortGuid=
Packit 857059
						pDestPortGuidsList[i];
Packit 857059
		pQueryElement->cmd.query.UserQuery.InputValue.PortGuidPair.SourcePortGuid = 
Packit 857059
						pRootQueryElement->PortGuid;
Packit 857059
		pQueryElement->cmd.query.pClientResult = NULL;
Packit 857059
		pQueryElement->PortGuid = pRootQueryElement->PortGuid;
Packit 857059
		// do not associate directly to client, we let destruction of our parent
Packit 857059
		// be our control.
Packit 857059
		pQueryElement->ClientHandle = NULL;
Packit 857059
Packit 857059
       	status = ValidateAndFillSDQuery(pQueryElement,
Packit 857059
						IBA_MEM_FLAG_PREMPTABLE|IBA_MEM_FLAG_SHORT_DURATION);   
Packit 857059
		if (FSUCCESS != status)
Packit 857059
		{
Packit 857059
			_DBG_ERROR(("Unable to allocate Mad for Child SA Query\n"));
Packit 857059
			MemoryDeallocate(pQueryElement);
Packit 857059
			goto failalloc;
Packit 857059
		}
Packit 857059
Packit 857059
		//Update the parent pointer
Packit 857059
		pQueryElement->pParentQuery = pRootQueryElement;
Packit 857059
		pQueryElement->QState = ReadyToSend;
Packit 857059
Packit 857059
		pChildQueryElements[i] = pQueryElement;
Packit 857059
	}
Packit 857059
Packit 857059
done:
Packit 857059
	_DBG_LEAVE_EXT(_DBG_LVL_FUNC_TRACE);
Packit 857059
	return pChildQueryElements;
Packit 857059
Packit 857059
failalloc:
Packit 857059
	// we failed at i, free i-1 to 0
Packit 857059
	while (i > 0)
Packit 857059
		FreeQueryElement(pChildQueryElements[--i]);
Packit 857059
	MemoryDeallocate(pChildQueryElements);
Packit 857059
	pChildQueryElements = NULL;
Packit 857059
	goto done;
Packit 857059
}