예제 #1
0
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;
}
예제 #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
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;
}