示例#1
0
/*********************************************************
	Build the topology map from the self-id bundle
*/
void briBuildTopologyMap(void)
{
#ifdef _BMC_CAPS
	HRESULT		hResult = NO_ERROR;
	uint32		generation;

	hResult = briGetCurrentBusGeneration(&generation);
	if (hResult != NO_ERROR) return;

	hResult = nciBMBuildTopologyMap (briGetSIDs(), briGetNumSIDQuads(), briGetNumNodes(), generation);
	if (hResult != NO_ERROR) return;
#endif //_BMC_CAPS
}
示例#2
0
HRESULT nciGetBusInfo(LAL_BUS_RESET_INFO* plalInfoBlock)
{
	HRESULT		hResult = NO_ERROR;
	uint32		busGen = 0;

	if (briIsSelfIDsValid() != TRUE)
	{
		hResult = E_NCI_BUS_INFO_NOT_AVAILABLE;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}

	if (nciInfoBlock.bValid != TRUE)
	{
		hResult = E_NCI_NODE_INFO_NOT_AVAILABLE;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}

	hResult = briGetCurrentBusGeneration(&busGen);
	if (hResult != NO_ERROR) return hResult;
	nciInfoBlock.busGeneration = busGen;

	hResult = briGetThisNodeAddr(&nciInfoBlock.nodeAddr);
	if (hResult != NO_ERROR) return hResult;

	hResult = briGetBusID(&nciInfoBlock.busId);
	if (hResult != NO_ERROR) return hResult;

	hResult = lhlBriGetCycleTime(&nciInfoBlock.currentTime);
	if (hResult != NO_ERROR) return hResult;

	plalInfoBlock->currentTime = nciInfoBlock.currentTime;
	plalInfoBlock->busGeneration = nciInfoBlock.busGeneration;
	plalInfoBlock->numNodes = nciInfoBlock.numNodes;
	plalInfoBlock->rootAddr = nciInfoBlock.rootAddr;
	plalInfoBlock->irmAddr = nciInfoBlock.irmAddr;
	plalInfoBlock->numSelfIDs = nciInfoBlock.numSelfIDs;
	plalInfoBlock->nodeAddr = nciInfoBlock.nodeAddr;
	plalInfoBlock->busId = nciInfoBlock.busId;
	plalInfoBlock->SIDBundle = nciInfoBlock.SIDBundle;

	return hResult;
}
示例#3
0
 /*********************************************************
	The tx thread calls this when any transmit queue has one or more packets to transmit.
		
	the priority queue is always checked first and serviced until empty, the 
	general queue is ignored during bus reset.  this allows node handles to be 
	fixed up after a bus reset, making them transparent to the upper layers,
	unless a node has left the bus of course. this routine will call the appropriate
	send routine for request or response.
*/
static HRESULT lhlTxSndPacketPend(void)
{
	HRESULT		hResult = NO_ERROR;
	PB*			packetBlock = NULL;
	PB_HEADER 	*pHeader = NULL;
	uint32		tLabel = 0;
	uint32		tCode = 0;
	uint32		nodeAddr = 0;
	uint32 busGenCurrent = 0;
	uint32 busGenPacket = 0;

	DO_FOREVER 
	{
		// look for priority packets (non-blocking)
		hResult = lhlMsgQueueGetPacketBlock(LHL_QUEUE_PRIORITY, &packetBlock, TC_NO_WAIT);
		if (hResult != NO_ERROR) return hResult;

		if (pbIsValid(packetBlock))
		{	
			// if bus reset happened, queued requests must be thrown out
			briGetCurrentBusGeneration(&busGenCurrent);			
			pbGetBusGeneration (packetBlock, &busGenPacket);
			
			if (busGenCurrent != busGenPacket)
			{
				
				pbSwapSrcDstNodeAddr(packetBlock);

				pbSetFinalStatus(packetBlock, E_LHL_BUS_RESET_IN_PROGRESS);
				pbPacketDone(packetBlock, PB_DONE_LHL_ATX_SND_PEND_1);
				hResult = E_BRI_NEW_BUS_RESET;
				sysLogError(hResult, __LINE__, moduleName);
				return hResult;
			}
		}
		else
		{
			if (briInBusReset() == FALSE)
			{
				// if not in bus reset processing, look for general packets (non-blocking)
				hResult = lhlMsgQueueGetPacketBlock(LHL_QUEUE_GENERAL, &packetBlock, TC_NO_WAIT);
				if (hResult != NO_ERROR) return hResult;
			}
			else
			{
				DO_FOREVER
				{
					// if in bus reset processing, free for general packets (non-blocking)
					hResult = lhlMsgQueueGetPacketBlock(LHL_QUEUE_GENERAL, &packetBlock, TC_NO_WAIT);
					if (hResult != NO_ERROR) return hResult;

					if (pbIsValid(packetBlock))
					{
#if 1 
						pbSwapSrcDstNodeAddr(packetBlock);
#endif
						pbSetFinalStatus(packetBlock, E_LHL_BUS_RESET_IN_PROGRESS);
						pbPacketDone(packetBlock, PB_DONE_LHL_ATX_SND_PEND_2);
					}
					else
					{
						break; // no more packetBlocks to free
					}
				}
			}
		}

		if (pbIsValid(packetBlock))
		{
			briGetCurrentBusGeneration(&busGenCurrent);			
			pbGetBusGeneration (packetBlock, &busGenPacket);
			if (busGenCurrent != busGenPacket)
			{				
				pbSwapSrcDstNodeAddr(packetBlock);
				pbSetFinalStatus(packetBlock, E_LHL_BUS_RESET_IN_PROGRESS);
				pbPacketDone(packetBlock, PB_DONE_LHL_ATX_SND_PEND_1);
				hResult = E_BRI_NEW_BUS_RESET;
				sysLogError(hResult, __LINE__, moduleName);
				return hResult;
			}

			hResult = pbGetPacketHeader (packetBlock, &pHeader);
			if (hResult != NO_ERROR) return hResult;
			hResult = pbGetPacketTLabel (packetBlock, &tLabel);
			if (hResult != NO_ERROR) return hResult;
			hResult = pbGetPacketDstNodeAddr (packetBlock, &nodeAddr);
			if (hResult != NO_ERROR) return hResult;
			hResult = lhlPendingTxAdd(tLabel, nodeAddr, packetBlock);		// insert before send and remove if send error
			if (hResult != NO_ERROR) return hResult;    
			hResult = context1PostPacket(packetBlock,lhlTxDoneSemID);
			if (hResult != NO_ERROR)
			{
#if 1 
				pbSwapSrcDstNodeAddr(packetBlock);
#endif
				pbSetFinalStatus(packetBlock, hResult);
				pbPacketDone(packetBlock, PB_DONE_LHL_ATX_SND_PEND_3);
			}
			else
			{
				// We have now posted the write, the semaphore will be signaled
				uint8	matchResponse = FALSE; // error in sending req/rsp - match corresponding type in PendingTx
				pbIsResponsePacket(packetBlock, &matchResponse);

				hResult = TCSemaphoreWait(lhlTxDoneSemID);
				
				tCode = (pHeader->quadlets[0] & MASK_TCODE) >> SHIFT_TCODE;
				lhlTxPacketDoneLLC(tLabel, tCode, nodeAddr, matchResponse);
			}
		}
		else
		{
			break; // no more packets to send
		}
	}