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; }
/********************************************************* 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 }
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; }
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 }
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, ¬ifyAddr); 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, ¬ify->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; }
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 **) ¬ify, pos++, &index); if (hResult != NO_ERROR) return NO_ERROR; hResult = pbGetPacketSrcNodeAddr (notify->notifyComm.packetBlock, ¬ifyAddr); 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; }
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; }
/********************************************************* 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 }
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; }
// 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; }
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; }
/***************************************************************************** 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; }
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; }
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; }
// 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; }
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 **) ¬ify, 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; }
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; }
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; }