/********************************************************* 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 }
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; }
/********************************************************* 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 } }