Beispiel #1
0
HRESULT avcSendRequest(uint32 ctype, PB *packetBlock)
{
	HRESULT		hResult = NO_ERROR;	

	// pad the data to the next full 32bit boundary. This is a requirement for AV/C Packets.
	// stream position not always at the end - avcPadToNextQuadlet(packetBlock);

#ifdef _SYSDEBUG
		if (sysDebugIsEnabled(SYSDEBUG_TRACE_AVC))
		{
			if (avcUnitCliIsPrintMode(AVC_UNIT_PRINT_SND_RAW))
			{
				avcUnitCliPrintPacketBlockRawData(ctype, packetBlock);
			}
		}
#endif //_SYSDEBUG
#ifdef _SYSDEBUG
	if (sysDebugIsEnabled(SYSDEBUG_TRACE_AVC))
	{
		if ((avcCtypeIsResponse(ctype) &&	// response
			((avcUnitCliIsPrintMode(AVC_UNIT_PRINT_SND_RESPONSE_ALL)) ||
			 (avcUnitCliIsPrintMode(AVC_UNIT_PRINT_SND_RESPONSE_IMPLEMENTED) && ctype != AVC_RESPONSE_NOT_IMPLEMENTED) ||
			 (avcUnitCliIsPrintMode(AVC_UNIT_PRINT_SND_RESPONSE_NOT_IMPLEMENTED) && ctype == AVC_RESPONSE_NOT_IMPLEMENTED))) ||
			(avcCtypeIsCommand(ctype) &&	// commands
			(avcUnitCliIsPrintMode(AVC_UNIT_PRINT_SND_COMMAND_ALL))))
		{
			avcUnitCliPrintPacketBlock(packetBlock);
		}
	}
#endif //_SYSDEBUG

	hResult = fcpSend(packetBlock, avcCtypeIsResponse(ctype));

	return hResult;
}
Beispiel #2
0
/*********************************************************
	reenable general async packet traffic, set event flag to wake up any suspended threads
*/
void briBusResetCompletion(void)
{
	briInBusResetProgress = FALSE;

#ifdef _BRI_PRE_COMPLETION
	briPreCompletionDone = TRUE;
#else //_BRI_PRE_COMPLETION
	// moved to briBusResetPreCompletion from briBusResetCompletion
	briLastResetCompletion = TCTimeGet();
#endif //_BRI_PRE_COMPLETION

	briSignalOnResetCompletion ();

	/*
		it is a common situation for nodes to set up manager preferences by 
		setting things and doing follow-on resets, however if there are many 
		more than this, there could be a cranky node on the bus
	*/
	if (briNumBRBeforeCompletion > BRI_BUSRESET_STORM_THRESHOLD)
	{
		sysDebugPrintf("%d interrupted bus resets\n\r", briNumBRBeforeCompletion);
	}
	briNumBRBeforeCompletion = 0;

#ifdef _SYSDEBUG
	if (sysDebugIsEnabled(SYSDEBUG_TRACE_BUSRESET))
	{
		sysDebugPrintf("bus reset completion done\n\r");
	}
#endif //_SYSDEBUG
}
Beispiel #3
0
HRESULT avcBlockingSendRequest(NODEHANDLE hHandle, uint8 ctype, uint16 byteLength, uint32 *bufPtr)
{
	HRESULT		hResult = NO_ERROR;	

#ifdef _SYSDEBUG
		if (sysDebugIsEnabled(SYSDEBUG_TRACE_AVC))
		{
			if (avcUnitCliIsPrintMode(AVC_UNIT_PRINT_SND_RAW))
			{
				avcUnitCliPrintRawData(ctype, byteLength, bufPtr);
			}
		}
#endif //_SYSDEBUG
#ifdef _SYSDEBUG
	if (sysDebugIsEnabled(SYSDEBUG_TRACE_AVC))
	{
		if ((avcCtypeIsResponse(ctype) &&	// response
			((avcUnitCliIsPrintMode(AVC_UNIT_PRINT_SND_RESPONSE_ALL)) ||
			 (avcUnitCliIsPrintMode(AVC_UNIT_PRINT_SND_RESPONSE_IMPLEMENTED) && ctype != AVC_RESPONSE_NOT_IMPLEMENTED) ||
			 (avcUnitCliIsPrintMode(AVC_UNIT_PRINT_SND_RESPONSE_NOT_IMPLEMENTED) && ctype == AVC_RESPONSE_NOT_IMPLEMENTED))) ||
			(avcCtypeIsCommand(ctype) &&	// commands
			(avcUnitCliIsPrintMode(AVC_UNIT_PRINT_SND_COMMAND_ALL))))
		{
			DataStream  ds;
		
			hResult = dsOpenStream(&ds, bufPtr, byteLength, dsMODE_READ);
			if (hResult == NO_ERROR)
			{
				avcUnitCliPrintDataStream(&ds);
			}
		}
	}
#endif //_SYSDEBUG

	hResult = fcpBlockingSend(hHandle, byteLength, bufPtr, avcCtypeIsResponse(ctype));

	return hResult;
}
Beispiel #4
0
void briBusResetPreCompletion(void)
{
	// moved to briBusResetPreCompletion from briBusResetCompletion
	briLastResetCompletion = TCTimeGet();

	briPreCompletionDone = TRUE;

	briSignalOnResetPreCompletion ();

#ifdef _SYSDEBUG
	if (sysDebugIsEnabled(SYSDEBUG_TRACE_BUSRESET))
	{
		sysDebugPrintf("bus reset pre completion done\n\r");
	}
#endif //_SYSDEBUG
}
Beispiel #5
0
HRESULT	avcUnitNotifyAdd(LM_CONTEXT* notifyList, UNION_NOTIFY *notify, PB *packetBlock, BOOL bUsePacketBlock)
{
    HRESULT				hResult = NO_ERROR;
    uint32				notifyAddr = 0;

    notify->notifyComm.bUsePacketBlock = bUsePacketBlock;

    hResult = pbGetPacketSrcNodeAddr (packetBlock, &notifyAddr);
    if (hResult != NO_ERROR) return hResult;

    // determine if there is a notify from same nodeAddr
    hResult = avcUnitNotifyRemoveOld(notifyList, notifyAddr);
    if (hResult != NO_ERROR) return hResult;

    if (bUsePacketBlock)
    {
        // copy packetBlock, and add it to our list of Notifications
        hResult = pbCreateDuplicatePacket(packetBlock, &notify->notifyComm.packetBlock, NULL, PB_CREATE_AVC_CB);
        if (hResult != NO_ERROR) return hResult;
    }
    else
    {
        NODEHANDLE handle = 0;

        lalGetHandleFromNodeAddr(notifyAddr, &handle);
        notify->notifyComm.handle = handle;
    }

    hResult = lmAddElement(notifyList, notify, NULL);
    if (hResult != NO_ERROR)
    {
        avcUnitNotifyRemoveComm(notify);
        return hResult;
    }


#ifdef _SYSDEBUG
    if (sysDebugIsEnabled(SYSDEBUG_TRACE_AVC & SYSDEBUG_TRACE_ERRORS)) //SYSDEBUG_TRACE_AVC
    {
        sysPrintCurTime();
        sysDebugPrintf("avcUnitNotify insert new notify\n\r");
    }
#endif //_SYSDEBUG

    return hResult;
}
Beispiel #6
0
HRESULT	avcUnitNotifyRemoveOld(LM_CONTEXT* notifyList, uint32 nodeAddr)
{
    HRESULT				hResult = NO_ERROR;
    uint32				pos = 0;
    uint32				index = 0;
    UNION_NOTIFY		*notify;
    uint32				notifyAddr = 0;
    BOOL				bFound = FALSE;

    DO_FOREVER
    {
        hResult = lmGetNthElement(notifyList, (void **) &notify, pos++, &index);
        if (hResult != NO_ERROR) return NO_ERROR;

        hResult = pbGetPacketSrcNodeAddr (notify->notifyComm.packetBlock, &notifyAddr);

        lmReleaseElement(notifyList, index);

        if (hResult != NO_ERROR) return NO_ERROR;

        if (nodeAddr == notifyAddr)
        {
            lmRemoveElement(notifyList, index);
            bFound = TRUE;
            break;
        }
    }

#ifdef _SYSDEBUG
    if (bFound)
    {
        if (sysDebugIsEnabled(SYSDEBUG_TRACE_AVC & SYSDEBUG_TRACE_ERRORS)) //SYSDEBUG_TRACE_AVC
        {
            sysPrintCurTime();
            sysDebugPrintf("avcUnitNotify removed old notify\n\r");
        }
    }
#endif //_SYSDEBUG

    return hResult;
}
Beispiel #7
0
HRESULT cmpP2PInConnectionBreak(uint32 iPCRNumber, uint32 oPCRNumber, uint16 oNodeAddr)
{
	HRESULT		hResult = NO_ERROR;
	uint32		iNodeAddr = 0;
	BOOL		bUnconnected = TRUE;

	// check range of iPCRNumber;
	if (iPCRNumber > plugsGetNumIsochInPlugs())
	{
		hResult = E_CMP_PCR_INVALID;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}

	hResult = lalGetThisNodeAddr(&iNodeAddr);
	if (hResult != NO_ERROR) return hResult;

	//LM??? retry?
	hResult = cmpP2PConnectionBreaking(iPCRNumber, (uint16) iNodeAddr, oPCRNumber, oNodeAddr, &bUnconnected);
#ifdef _SYSDEBUG
	if (hResult != NO_ERROR)
	{
		if (sysDebugIsEnabled(SYSDEBUG_TRACE_CMP))
		{
			sysPrintCurTime();
			sysDebugPrintf("cmp: cmpP2PConnectionBreaking failed - we should retry?\n\r");
		}
	}
#endif //_SYSDEBUG

	// update owned connections
	if (bUnconnected == TRUE)
	{
		cmpP2PInConnectionSetOwnedStatus(iPCRNumber, CONNECTION_STATUS_UNCONNECTED);
	}

	return hResult;
}
Beispiel #8
0
/*********************************************************
	Let everyone who registered interest know that the bus reset is finished
*/
void briCallBusResetCompletionCBs(void)
{
	while (briCompletionIndex < briCompletionNumCBs)
	{
		if (briCompletionCBs[briCompletionIndex])
		{
			(briCompletionCBs[briCompletionIndex])();
			briCompletionIndex++;
		}
		else
		{
			break;
		}
	}
	briCompletionIndex = 0;

#ifdef _SYSDEBUG
	if (sysDebugIsEnabled(SYSDEBUG_TRACE_BUSRESET))
	{
		sysDebugPrintf("bri completion cbs done\n\r");
	}
#endif //_SYSDEBUG
}
Beispiel #9
0
HRESULT cmpP2PInConnectionRestore(uint32 iPCRNumber, uint32 oPCRNumber, uint16 oNodeAddr)
{
	HRESULT		hResult = NO_ERROR;
	uint32		iNodeAddr = 0;

	// check range of iPCRNumber;
	if (iPCRNumber > plugsGetNumIsochInPlugs())
	{
		hResult = E_CMP_PCR_INVALID;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}

	hResult = lalGetThisNodeAddr(&iNodeAddr);
	if (hResult != NO_ERROR) return hResult;

	//LM???  retry
	hResult = cmpP2PConnectionEstablishing(iPCRNumber, (uint16) iNodeAddr, oPCRNumber, oNodeAddr, TRUE /*bRestore*/);
#ifdef _SYSDEBUG
	if (hResult != NO_ERROR)
	{
		if (sysDebugIsEnabled(SYSDEBUG_TRACE_CMP))
		{
			sysPrintCurTime();
			sysDebugPrintf("cmp: cmpP2PConnectionRestore failed - we should retry\n\r");
		}
	}
#endif //_SYSDEBUG

	if (hResult != NO_ERROR) return hResult;

	// update owned connections
	hResult = cmpP2PInConnectionSetOwned(iPCRNumber, oPCRNumber, oNodeAddr, CONNECTION_STATUS_CONNECTED);

	return hResult;
}
Beispiel #10
0
// create or overlay a connection between the iPCR,iNodeAddr and the oPCR,oNodeAddr specified
static HRESULT cmpP2PConnectionEstablishing(uint32 iPCRNumber, uint16 iNodeAddr, uint32 oPCRNumber, uint16 oNodeAddr, BOOL bRestore)
{
	HRESULT		hResult = NO_ERROR;
	uint32		iPCR = 0;
	uint32		oPCR = 0;
	uint32		iPCRP2PCount = 0;
	uint32		oPCRConnCount = 0;
	uint32		channel = IRM_ANY_AVAIL_ISOCH_CHANNEL;
	uint32		bandwidth = 0;

	hResult = cmpReadiPCRWithPriority(iPCRNumber, iNodeAddr, &iPCR, TRUE);
	if (hResult != NO_ERROR) return hResult;

	hResult = cmpReadoPCRWithPriority(oPCRNumber, oNodeAddr, &oPCR, TRUE);
	if (hResult != NO_ERROR) return hResult;

	iPCRP2PCount = cmpGetPCRP2PCount(iPCR);
	oPCRConnCount = cmpGetPCRConnCount(oPCR);

	if (iPCRP2PCount != 0)		// iPCR already connected (can't establish p2p connection)
	{
		hResult = E_CMP_PCR_ALREADY_CONNECTED;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}

	if (bRestore)				// channel in oPCR already specified (perform restoring of p2p connection)
	{
		channel = cmpGetPCRChannel(oPCR);
	}

	if (oPCRConnCount == 0)		// oPCR not connected (allocate IRM resources)
	{
		bandwidth = cmpGetPCRBandwidth(oPCR);

		hResult = cmpAllocateIRMResources(&channel, bandwidth);
		if (hResult != NO_ERROR) return hResult;
	}
	else if (bRestore == FALSE)	// oPCR already connected (perform overlaying of p2p connection)
	{
		channel = cmpGetPCRChannel(oPCR);
	}

	//LM??? retry
	hResult = cmpP2PConnectionOverlaying(iPCR, iPCRNumber, iNodeAddr, oPCR, oPCRNumber, oNodeAddr, channel, FALSE);
#ifdef _SYSDEBUG
	if (hResult != NO_ERROR)
	{
		if (sysDebugIsEnabled(SYSDEBUG_TRACE_CMP))
		{
			sysPrintCurTime();
			sysDebugPrintf("cmp: cmpP2PConnectionOverlaying failed - we should retry\n\r");
		}
	}
#endif //_SYSDEBUG

	if (hResult != NO_ERROR)
	{
		if (bandwidth) cmpDeallocateIRMResources(channel, bandwidth);
		return hResult;
	}

	return hResult;
}
Beispiel #11
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;
}
Beispiel #12
0
/*****************************************************************************

	nciReadNodeGeneralROMFormat

******************************************************************************/
HRESULT	nciReadNodeGeneralROMFormat (uint32 nodeNum, uint32 busId, BIB_DATA *pCurBib)
{
	HRESULT		hResult = NO_ERROR;
	int32		quadNum = 0;	// current bus info quadlet index
	OFFSET_1394	destOffset;
	uint32		i;
	uint32		maxRetry = 3;	//LM???
	QUADLET		busInfoBlock[BIB_QUAD_ITEMS];
	destOffset.High = 0xffff;

	for (quadNum = 0; (quadNum < BIB_QUAD_ITEMS) && (hResult == NO_ERROR); quadNum++)
	{
#ifdef _SYSDEBUG
		if (sysDebugIsEnabled(SYSDEBUG_TRACE_BUSRESET))
		{
			sysDebugPrintf("read quad %d for node %d\n\r", quadNum+1, nodeNum);
		}
#endif //_SYSDEBUG

		destOffset.Low = BUS_INFO_BLOCK_ADDR + (quadNum * 4);

		for (i = 0; i < maxRetry; i++)
		{
			hResult = lhlReadNodeTimeout((uint32) (nodeNum | busId), destOffset, 4, &busInfoBlock[quadNum], LHL_QUEUE_PRIORITY, LHL_TX_REQ_SHORT_TIMEOUT_MSECS);
			if (hResult == NO_ERROR)
			{
				break;
			}
#if 1 //LM???
			if (lhlBriNewBusResetDetected(FALSE))
			{
				return E_BRI_NEW_BUS_RESET;
			}
#endif

#ifdef _SYSDEBUG
			if (sysDebugIsEnabled(SYSDEBUG_TRACE_BUSRESET))
			{
				sysDebugPrintf("failed read quad %d for node %d\n\r", quadNum+1, nodeNum);
			}
#endif //_SYSDEBUG

#if 1 //LM???
			TCTaskWait(10);
#endif
		}
	}	

	if (hResult == NO_ERROR)
	{
		for (quadNum = 0; quadNum < BIB_QUAD_ITEMS; quadNum++)
		{
			pCurBib->busInfoBlock[quadNum] = busInfoBlock[quadNum];
		}
#ifdef _SIMULATE
		pCurBib->busInfoBlock[BIB_WWUIDLO_QUAD] += nodeNum;
#endif //_SIMULATE
	}

	return hResult;
}
Beispiel #13
0
HRESULT	nciVerifySelfIDs (QUADLET *pSelfIDs, uint32 numSelfIDs, uint32 numNodes)
{
	HRESULT	hResult = NO_ERROR;
	uint32	i;
	QUADLET	curSelfid;				// current packet
	int32	prevNodeId = -1;		// id of previous packet
	int32	curNodeId;				// id of current packet
	int32	curSeqNum;				// sequence number of current extended packet
	int32	rootNodeId = -1;		// id of root node
	int32	irmNodeId = -1;			// id of irm node
	int32	numParents;
	int32	numChildren;
	BOOL  	expectMore = FALSE;		// next self-id s/b extended selfid from same node
	int32	expectedSeqNum = -1;	// expected sequence number if expectMore
	int32	numContenders = 0;		// how many nodes contending to be manager
	BOOL	bHandleBit23;

	// verify caller's parms

	if (!(numNodes > 0) ||
		!(numNodes < MAX_NODES_PER_BUS) ||
		!(numSelfIDs >= numNodes))
	{
		hResult = E_NCI_NODE_COUNT_ERROR;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}
	if (pSelfIDs == NULL)
	{
		hResult = E_BAD_INPUT_PARAMETERS;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}

	memset(&nciInfoBlock, 0, sizeof(nciInfoBlock));

	for (i = 0; i < numSelfIDs; ++i)
	{
		curSelfid = pSelfIDs[i];
		curNodeId = nciExtractSelfidNodeId(curSelfid);
		curSeqNum = nciExtractSelfidSeqNum(curSelfid);
		bHandleBit23 = FALSE;

		if ((curSelfid & (BIT31 | BIT30)) != BIT31)				// self-id packet has bit31=1 and bit30 = 0
		{
			hResult = E_NCI_PACKET_NOT_SELFID;
			sysLogError(hResult, __LINE__, moduleName);
		}
																// verify packet format
		if (i == 0)												// 1st packet is a special case
		{
			if (curNodeId == 0)									// must be node 0
			{
				bHandleBit23 = TRUE;
			}
			else
			{
				hResult = E_NCI_ID_SEQ_ERROR_0;  				// 1st selfid packet in error
				sysLogError(hResult, __LINE__, moduleName);
			}
		}
		else													// not first self id packet, we have some context to work from 
		{
			if (expectMore)
			{
				if ((curNodeId == prevNodeId)		&&			// must have same node id as previous packet
					(expectedSeqNum == curSeqNum)	&&			// sequence number must increase
					((curSelfid & BIT23) != 0))					// extended packet can't have bit 23 set
				{
					expectedSeqNum = curSeqNum+1;				// if there is another extended packet
					expectMore = (BOOL)(curSelfid & MORE_MASK);
				}
				else											// packet is verified OK, set up for next
				{
					hResult = E_NCI_EXT_SELFID_ERROR;		
					sysLogError(hResult, __LINE__, moduleName);
				}
			}
			else												// we're expecting packet #0 from the next node
			{
				if (curNodeId == (prevNodeId+1))
				{
					bHandleBit23 = TRUE;
				}
				else											// packet is from next node, check it out
				{
					hResult = E_NCI_NODE_SEQ_ERROR;				// node id's out of sequence
					sysLogError(hResult, __LINE__, moduleName);
				}
			}
		}

		if (bHandleBit23 == TRUE)
		{
			if ((curSelfid & BIT23) == 0)						// packet #0 has bit23 = 0
			{
				rootNodeId = curNodeId;							// save for later	
				expectedSeqNum = 0;
				expectMore = (BOOL)(curSelfid & MORE_MASK);
				if (nciExtractSelfidLinkActive(curSelfid) &&
					nciExtractSelfidContender(curSelfid))
				{
					numContenders++;
					irmNodeId = curNodeId;
				}
			}
			else
			{
				hResult = E_NCI_PACKET0_FORMAT_ERROR;  			// 1st selfid packet in error
				sysLogError(hResult, __LINE__, moduleName);
			}
		}

		prevNodeId = curNodeId;
	}

	// Individual packets have had their format and sequence verified,
	// now check for system consistency:
	// - there must be a contender for bus/isoc manager
	// - our node count must match caller's

	if (hResult == NO_ERROR)
	{
		if (!numContenders)
		{
#if 1 //LM???
#ifdef _SYSDEBUG
			if (sysDebugIsEnabled(SYSDEBUG_TRACE_BUSRESET))
			{
				sysDebugPrintf("nci VerifySelfIds: no contenders\n\r");
			}
#endif //_SYSDEBUG
#else
			hResult = E_NCI_NO_CONTENDERS;						// gotta have at least one contender
			sysLogError(hResult, __LINE__, moduleName);
#endif //LM???
		}
		else if (numNodes != (uint32) (rootNodeId + 1))
		{
			hResult = E_NCI_NODE_COUNT_ERROR;
			sysLogError(hResult, __LINE__, moduleName);
		}
	}

	// More consistency checks
	// - root must have no parents
	// - branch and leaf nodes must have exactly 1 parent
	// - node 0 must be a leaf (no children)

	i = 0;
	while ((hResult == NO_ERROR) && (i < numSelfIDs))
	{
		curSelfid = pSelfIDs[i];
		curNodeId = nciExtractSelfidNodeId(curSelfid);
		numParents = nciNumParentsPacket0(curSelfid);
		numChildren = nciNumChildrenPacket0(curSelfid);
		while (pSelfIDs[i] & MORE_MASK)
		{
			++i;
			numParents += nciNumParentsExtendedPacket(pSelfIDs[i]);
			numChildren += nciNumChildrenExtendedPacket(pSelfIDs[i]);
			if (curNodeId != nciExtractSelfidNodeId(pSelfIDs[i]))
			{
				hResult = E_NCI_NODE_COUNT_ERROR;
				sysLogError(hResult, __LINE__, moduleName);
				return hResult;
			}
		}	

		if ((curNodeId == rootNodeId) && (numParents > 0))
		{
			hResult = E_NCI_ROOT_HAS_PARENTS;
			sysLogError(hResult, __LINE__, moduleName);
			sysDebugPrintf("numParents: %i\n\r", numParents);
		}
		else if ((curNodeId == 0) && (numChildren > 0))
		{
			hResult = E_NCI_NODE0_HAS_KIDS;
			sysLogError(hResult, __LINE__, moduleName);
			sysDebugPrintf("numChildren: %i\n\r", numChildren);
		}
		if (numParents > 1)
		{
			hResult = E_NCI_TOO_MANY_PARENTS;
			sysLogError(hResult, __LINE__, moduleName);
			sysDebugPrintf("curNodeId: %i\n\r", curNodeId);
		}
		++i;
	}

	if (hResult == NO_ERROR)
	{
		nciInfoBlock.numNodes = numNodes;
		nciInfoBlock.rootAddr = (uint32) (LOCAL_BUS_ID_MASK | rootNodeId);
		nciInfoBlock.irmAddr = (uint32) (LOCAL_BUS_ID_MASK | irmNodeId);
		nciInfoBlock.numSelfIDs = numSelfIDs;
		nciInfoBlock.SIDBundle = pSelfIDs;
		nciInfoBlock.bValid = TRUE;
	}

#ifdef _SYSDEBUG
	if (sysDebugIsEnabled(SYSDEBUG_TRACE_BUSRESET))
	{
		sysDebugPrintf("selfids validated\n\r");
	}
#endif //_SYSDEBUG

	return hResult;
}
Beispiel #14
0
HRESULT lhlStatusQueueMatch(uint32 nodeAddr, uint32 tLabel, uint32 genType, PB_PACKETTYPE packetType, STATUS_INFO **statusInfo, BOOL bRemoveEntry)
{
	HRESULT		hResult = NO_ERROR;
	uint32		index;
	STATUS_INFO	*si = NULL;
	BOOL		bFound = FALSE;

	// exclusive access for the statusInfoQueue (mutex)
	hResult = TCMutexLock(lhlStatusQueueMutexSemID);
	if (hResult != NO_ERROR) return hResult;

	if (statusInfo)
	{
		*statusInfo = NULL;
	}

	// find a matching statusInfo from the pool
	for (index = 0; index < STATUS_INFO_ITEMS; index++)
	{
		si = &statusInfoQueue.statusInfo[index];
		if (statusInfoQueue.allocated[index] == TRUE)
		{
			if (si->nodeAddr == nodeAddr &&
				si->tLabel == tLabel &&
				si->packetType == packetType &&
				si->genType == genType)
			{
				bFound = TRUE;
				if (statusInfo)
				{
					*statusInfo = si;
				}
				if (bRemoveEntry)
				{
					hResult = si->hResultFinal;
					lhlStatusQueueResetInfo(si);
					statusInfoQueue.allocated[index] = FALSE;
					statusInfoQueue.ptr = index;

#ifdef _STATISTICS
					lhlStatistics.statusInfoInuse--;
#endif //_STATISTICS
				}
				break;
			}
		}
	}

	if (bFound == FALSE ||
		(statusInfo && *statusInfo == NULL))
	{
		SYS_DEBUG(SYSDEBUG_TRACE_WARNINGS, "lhlStatusQueue: No match nodeAddr 0x%04x, tLabel 0x%04x, pckType:0x%04x, genType:0x%04x\n\r", nodeAddr, tLabel, packetType, genType);
#ifdef _SYSDEBUGERROR
		if (sysDebugIsEnabled(SYSDEBUG_TRACE_ERRORS))
		{
			sysDebugPrintf("lhlStatusQueueMatch\n\r");
			__lhlStatusQueueDisplay();
		}
#endif //_SYSDEBUGERROR
		hResult = E_NULL_PTR;
		sysLogError(hResult, __LINE__, moduleName);
	}

	// exclusive access for the statusInfoQueue (mutex)
	TCMutexUnlock(lhlStatusQueueMutexSemID);

	return hResult;
}
Beispiel #15
0
// break a connection between the iPCR,iNodeAddr and the oPCR,oNodeAddr specified
static HRESULT cmpP2PConnectionBreaking(uint32 iPCRNumber, uint16 iNodeAddr, uint32 oPCRNumber, uint16 oNodeAddr, BOOL *bUnconnected)
{
	HRESULT		hResult = NO_ERROR;
	uint32		iPCR = 0;
	uint32		oPCR = 0;
	uint32		iPCRNew = 0;
	uint32		oPCRNew = 0;
	uint32		iPCRP2PCount = 0;
	uint32		oPCRP2PCount = 0;
	uint32		oPCRConnCount = 0;
	uint32		channel = 0;
	uint32		bandwidth = 0;
	BOOL		bBreakingOK = FALSE;

	hResult = cmpReadiPCR(iPCRNumber, iNodeAddr, &iPCR);
	if (hResult != NO_ERROR) return hResult;

	hResult = cmpReadoPCR(oPCRNumber, oNodeAddr, &oPCR);
	if (hResult != NO_ERROR) return hResult;

	iPCRNew = iPCR;
	oPCRNew = oPCR;

	iPCRP2PCount = cmpGetPCRP2PCount(iPCR);
	oPCRP2PCount = cmpGetPCRP2PCount(oPCR);

	if (iPCRP2PCount == 0)		// oPCR not connected (can't break p2p connection)
	{
		hResult = E_CMP_PCR_NOT_CONNECTED;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}

	if (oPCRP2PCount == 0)		// oPCR not connected (just update local iPCR - connection was not established correctly)
	{
#ifdef _SYSDEBUG
		if (sysDebugIsEnabled(SYSDEBUG_TRACE_CMP))
		{
			sysPrintCurTime();
			sysDebugPrintf("cmp:couldn't break connection completely because oPCRP2PCount: 0\n\r");
		}
#endif //_SYSDEBUG
	}
	
	if (oPCRP2PCount > 0)
	{
		oPCRP2PCount--;
		cmpSetPCRP2PCount(&oPCRNew, oPCRP2PCount);

		hResult = cmpLockoPCR(oPCRNumber, oNodeAddr, oPCR, oPCRNew);
		bBreakingOK = (hResult == NO_ERROR);
	}

	if (hResult == NO_ERROR)
	{
		iPCRP2PCount--;
		cmpSetPCRP2PCount(&iPCRNew, iPCRP2PCount);
		hResult = cmpLockiPCR(iPCRNumber, iNodeAddr, iPCR, iPCRNew);
	}

	*bUnconnected = (cmpGetPCRP2PCount(iPCRNew) == 0);

	if (bBreakingOK == TRUE)
	{
		oPCRConnCount = cmpGetPCRConnCount(oPCRNew);

		if (oPCRConnCount == 0)		// deallocate 1394 resources if oPCR unconnected
		{
			bandwidth = cmpGetPCRBandwidth(oPCR);
			channel = cmpGetPCRChannel(oPCR);

			cmpDeallocateIRMResources(channel, bandwidth);
		}
	}

	return hResult;
}
Beispiel #16
0
HRESULT avcUnitNotifyCheck(LM_CONTEXT* notifyList, NOTIFY_CHECK_CALLBACK notifyCheckCB, NOTIFY_UPDATE_CALLBACK notifyUpdateCB)
{
    HRESULT				hResult = NO_ERROR;
    uint32				pos = 0;
    uint32				index = 0;
    pDataStream			pStream = NULL;
    UNION_NOTIFY*		notify = NULL;
    AVC_HEADER			avcHeader;
    BOOL				bChanged = FALSE;
    PB					*packetBlock;

    // determine if there is a notify on the specified subunit
    DO_FOREVER
    {
        hResult = lmGetNthElement(notifyList, (void **) &notify, pos, &index);
        if (hResult != NO_ERROR) return NO_ERROR;

        bChanged = FALSE;

        // call callback to make notify specific check on notify state
        hResult = (* notifyCheckCB) (notify, &bChanged);

        if (bChanged)
        {
#ifdef _SYSDEBUG
            if (sysDebugIsEnabled(SYSDEBUG_TRACE_AVC & SYSDEBUG_TRACE_ERRORS)) //SYSDEBUG_TRACE_AVC
            {
                sysPrintCurTime();
                sysDebugPrintf("avcUnitNotify changed state for notify\n\r");
            }
#endif //_SYSDEBUG

            hResult = pbGetApplicationDatastream(notify->notifyComm.packetBlock, &pStream);
            if (hResult != NO_ERROR) break;

            hResult = avcDecodeHeader(pStream, &avcHeader);
            if (hResult != NO_ERROR) break;

            hResult = dsGotoMarker(pStream, DSMARKER_OPERAND_0);
            if (hResult != NO_ERROR) break;

            hResult = dsSwitchMode(pStream, dsMODE_WRITE);
            if (hResult != NO_ERROR) break;

            // call callback to write notify specific data into stream (from operand[0])
            hResult = (* notifyUpdateCB) (notify, pStream);
            if (hResult != NO_ERROR) break;

            packetBlock = notify->notifyComm.packetBlock;

            hResult = lmReleaseElement(notifyList, index);
            if (hResult != NO_ERROR) break;

            hResult = lmRemoveElement(notifyList, index);
            if (hResult != NO_ERROR) break;

            hResult = avcReplyResponse (AVC_RESPONSE_CHANGED, packetBlock);
            if (hResult != NO_ERROR) break;
        }
        else
        {
            lmReleaseElement(notifyList, index);
            pos++;
        }
    }

    lmReleaseElement(notifyList, index);

    return hResult;
}
Beispiel #17
0
HRESULT avcHandleCallback(AVC_HEADER *pHeader, PB *packetBlock)
{
	HRESULT	 				hResult = NO_ERROR;
	uint32	 				index = 0;
	uint32					subunitidcounter = 0;
	CALLBACK_DESCRIPTOR*	cb = NULL;
	AVC_SUBUNIT_CALLBACK	callback = NULL;
	BOOL					bFound = FALSE;

#ifdef _SYSDEBUG
	if (sysDebugIsEnabled(SYSDEBUG_TRACE_AVC))
	{
		if (avcUnitCliIsPrintMode(AVC_UNIT_PRINT_RCV_RAW))
		{
			avcUnitCliPrintPacketBlockRawData(pHeader->ctype, packetBlock);
		}
	}
#endif //_SYSDEBUG

	DO_FOREVER
	{
		hResult = crGetCallback(AVC_SUBUNIT_TYPE, index++, &cb);
		if (hResult != NO_ERROR) break;

		hResult = kvIsValue(cb, AVC_SUBUNIT_SUBUNITTYPE_KEY, pHeader->addrSubunit.subunit_type);
		if (hResult != NO_ERROR) continue;
		
		hResult = kvGetValue(cb, AVC_SUBUNIT_ID_KEY, &subunitidcounter);
		if (hResult != NO_ERROR) continue;

		if (subunitidcounter != AVC_SU_ID_IGNORE &&
			subunitidcounter != pHeader->addrSubunit.subunit_ID) continue;
			
		hResult = kvGetValue(cb, AVC_SUBUNIT_CALLBACK_KEY, (uint32 *) &callback);
		if (hResult != NO_ERROR) break;

		// found the appropriate callback so let's make it.
		hResult = (callback) (pHeader, packetBlock);
		bFound = TRUE;
		break;
	}

	if (bFound == FALSE)
	{
		SYS_DEBUG(SYSDEBUG_TRACE_AVC | SYSDEBUG_TRACE_ERRORS, 
				  "avcHandleCallback: Could not find callback for registered subunittype\n\r");
#ifdef _SYSDEBUG
		if (avcCtypeIsResponse(pHeader->ctype))
		{
			if (sysDebugIsEnabled(SYSDEBUG_TRACE_AVC))
			{
				sysDebugPrintf("avcHandleCallback: Response\n\r");
				avcUnitCliPrintHeader(pHeader);
			}
		}
#endif //_SYSDEBUG
		hResult = E_PKT_AVC_NOT_IMPLEMENTED;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}

	return hResult;
}
Beispiel #18
0
HRESULT cmpP2PInConnectionRestoreOwned(BOOL *bRestoreAllDone)
{
	HRESULT				hResult = NO_ERROR;
	uint32				iPCRNumber = 0;
	uint32				oPCRNumber = 0;
	uint16				oNodeAddr = 0;
	CONNECTION_STATUS	status = CONNECTION_STATUS_UNCONNECTED;

	*bRestoreAllDone = TRUE;

	for (iPCRNumber = 0; iPCRNumber < plugsGetNumIsochInPlugs(); iPCRNumber++)
	{
		hResult = cmpP2PInConnectionGetOwnedStatus(iPCRNumber, &status);
		
		if (hResult == NO_ERROR &&
			status == CONNECTION_STATUS_PENDING)
		{
#ifdef _CMP_P2P_USE_NODE_HANDLE
			// handles are already updated during bus reset
			if (hResult == NO_ERROR)
			{
				hResult = cmpP2PInConnectionGetOwned(iPCRNumber, &oPCRNumber, &oNodeAddr, &status);
			}
#else //_CMP_P2P_USE_NODE_HANDLE
			// get nodeID from CIP header of a isoch packet on specified channel in iPCR update owned connection with obtained nodeAddr
			uint32	sourceID = 0;
			uint16	busID = 0;
			BOOL	bValid = FALSE;
			bValid = avsRxGetSourceID(iPCRNumber, &sourceID);
			if (bValid == TRUE)
			{
				if (hResult == NO_ERROR)
				{
					hResult = lalGetBusID(&busID);
				}
#ifdef _SYSDEBUG
				if (sysDebugIsEnabled(SYSDEBUG_TRACE_CMP))
				{
					uint32	iNodeAddr = 0;
					hResult = lalGetThisNodeAddr(&iNodeAddr);
					sysPrintCurTime();
					sysDebugPrintf("cmp:avsRxGetSourceID returned sourceNodeAddr: 0x%04x, thisNodeAddr: 0x%04x\n\r", busID | sourceID, iNodeAddr);
				}
#endif //_SYSDEBUG
				if (hResult == NO_ERROR)
				{
					hResult = cmpP2PInConnectionGetOwned(iPCRNumber, &oPCRNumber, &oNodeAddr, &status);
				}
				if (hResult == NO_ERROR)
				{
					oNodeAddr = (uint16) (busID | sourceID);
					hResult = cmpP2PInConnectionSetOwned(iPCRNumber, oPCRNumber, oNodeAddr, status);
				}
			}
			else
			{
#ifdef _SYSDEBUG
				if (sysDebugIsEnabled(SYSDEBUG_TRACE_CMP))
				{
					sysPrintCurTime();
					sysDebugPrintf("cmp:avsRxGetSourceID returned FALSE\n\r");
				}
#endif //_SYSDEBUG
				hResult = E_CMP_PCR_NOT_CONNECTED;
			}
#endif //_CMP_P2P_USE_NODE_HANDLE

			if (hResult == NO_ERROR)
			{
				hResult = cmpP2PInConnectionRestore(iPCRNumber, oPCRNumber, oNodeAddr);
			}
			if (hResult != NO_ERROR)
			{
				*bRestoreAllDone = FALSE;
			}
		}
	}

	return hResult;
}