HRESULT briGetNodeAddrRoot(uint32 *pNodeAddr) { HRESULT hResult = NO_ERROR; uint16 busId = 0; uint32 rootId = ROOT_ID_UNDEF; uint32 numNodes = 0; // find out Root node address numNodes = briGetNumNodes(); if (numNodes == 0) { hResult = E_NCI_NODE_ID_OUT_OF_RANGE; sysLogError(hResult, __LINE__, moduleName); return hResult; } rootId = numNodes - 1; hResult = briGetBusID(&busId); if (hResult != NO_ERROR) return hResult; *pNodeAddr = rootId | busId; return hResult; }
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; }
HRESULT nciUpdateBusInfoBlocks (uint32 numNodes, BIB_DATA *bibs, BOOL bClear) { HRESULT hResult = NO_ERROR; uint32 nodeNum = 0; // current node, index into bifs UQUAD romHeader; // 1st quadlet in rom BIB_DATA *pCurBib; // I.E. bib[nodeNum] uint16 busId = 0; OFFSET_1394 destOffset; uint32 i; // bk: uint32 maxRetry = 5; //LM??? 3,..,5? // retries are blocking fcp outgoing traffic, reducing them to 1 is a temporary fix. // AV/C should be reworked to use nodeID-based API's then defer bib reads to the // application level. A bib should only be read whenever a handle is required for // a specific node uint32 maxRetry = 1; BOOL bRetry = FALSE; #ifdef _SYSDEBUG if (sysDebugIsEnabled(SYSDEBUG_TRACE_BUSRESET)) { sysDebugPrintf("Getting bibs for %d nodes\n\r", numNodes); } #endif //_SYSDEBUG hResult = briGetBusID(&busId); if (hResult != NO_ERROR) return hResult; if (bClear) for (nodeNum = 0; nodeNum < numNodes; ++nodeNum) { // all devices may be accessed by (bus_id | node_id). Insert this // here in case the node does not implement general ROM format or // does not respond to bus info block reads. pCurBib = &bibs[nodeNum]; memset(pCurBib, 0, sizeof(BIB_DATA)); pCurBib->bibDataRetry = TRUE; //LM??? retry reading bibData pCurBib->busInfoBlock[BIB_WWUIDLO_QUAD] = (busId | nodeNum); } destOffset.High = 0xffff; for (i = 0; i < maxRetry; i++) { bRetry = FALSE; for (nodeNum = 0; nodeNum < numNodes; ++nodeNum) { pCurBib = &bibs[nodeNum]; if (pCurBib->bibDataRetry == TRUE) { // bail if this bus reset was interrupted if (briNewBusReset() == TRUE) { hResult = E_BRI_NEW_BUS_RESET; sysLogError(hResult, __LINE__, moduleName); //LM??? return hResult; // new bus reset detected elsewhere } #if 1 if (nciIsNodeLinkActive (nodeNum) == TRUE) #endif { // read the first quadlet in config rom for the length byte. // If length = 1, the ROM format is minimal and there is no bus info block. // If length > 1 (general ROM format), read the 4 quadlets of the bus info block. (see 1394-1995, Section 8.2.3.5) #ifdef _SYSDEBUG if (sysDebugIsEnabled(SYSDEBUG_TRACE_BUSRESET)) { sysDebugPrintf("read ROM base for node %d\n\r", nodeNum); } #endif //_SYSDEBUG destOffset.Low = CONFIG_ROM_BASE_ADDR; hResult = lhlReadNodeTimeout(nodeNum | busId, destOffset, 4, (QUADLET*)&romHeader, LHL_QUEUE_PRIORITY, LHL_TX_REQ_SHORT_TIMEOUT_MSECS); if (hResult != NO_ERROR) { #ifdef _SYSDEBUG if (sysDebugIsEnabled(SYSDEBUG_TRACE_BUSRESET)) { sysDebugPrintf("failed read ROM base for node %d\n\r", nodeNum); } #endif //_SYSDEBUG // retry but be aware that non-compliant devices will have errors // - this is normal - just skip those devices bRetry = TRUE; } else if (romHeader.b.msb == 0) // examine length { hResult = E_NCI_ZERO_INFO_LENGTH; // 0 is not a valid value sysLogError(hResult, __LINE__, moduleName); pCurBib->bibDataRetry = FALSE; } else if (romHeader.b.msb == 1) { // minimal format pCurBib->bibDataRetry = FALSE; } else // length > 1, general rom format { hResult = nciReadNodeGeneralROMFormat (nodeNum, busId, pCurBib); if (hResult == NO_ERROR) { pCurBib->bibDataRetry = FALSE; bRetry = TRUE; } } } #if 1 else { pCurBib->bibDataRetry = FALSE; } #endif } } if (bRetry == FALSE) { break; } TCTaskWait((i*2+1)*(i*2+1)*10); } #ifdef _SYSDEBUG if (sysDebugIsEnabled(SYSDEBUG_TRACE_BUSRESET)) { sysDebugPrintf("nodeinfos done\n\r"); } #endif //_SYSDEBUG return hResult; }