Beispiel #1
0
HRESULT nciCBGeneric(PB *packetBlock, uint32 nciCBtype)
{
	HRESULT			hResult = NO_ERROR;
	uint32			numBytes = 0;
	uint16			i;
	PB_HEADER		*pHeader = NULL;
	QUADLET			*pPayload = NULL;
	QUADLET			*pRespPayload = NULL;
	PB*				respPacket = NULL;
	PB_PACKETTYPE	packetType = PB_TYPE_UNDEF;
	PB_LOCKTYPE		lockType = PB_LOCKTYPE_NONE;
	RCODE_1394		rCode = RSP_ADDRESS_ERROR;
	OFFSET_1394		destOffset;
	uint16			reqType = LHL_REQ_READ;

	hResult = pbGetPacketHeader(packetBlock, &pHeader);
	if (hResult != NO_ERROR) return hResult;
	hResult = pbGetPacketType(packetBlock, &packetType);
	if (hResult != NO_ERROR) return hResult;
	hResult = pbGetLockType(packetBlock, &lockType);
	if (hResult != NO_ERROR) return hResult;
	hResult = pbGetPayload(packetBlock, (void **) &pPayload);
	if (hResult != NO_ERROR) return hResult;

	// no broadcasts supported here
	if (pbPacketIsBroadcast(packetBlock))
	{
		return hResult;
	}

	switch (packetType)
	{
		case PB_TYPE_READ_REQUEST_QUADLET:
		case PB_TYPE_READ_REQUEST:
			reqType = LHL_REQ_READ;
			break;
		case PB_TYPE_WRITE_REQUEST_QUADLET:
		case PB_TYPE_WRITE_REQUEST:
			reqType = LHL_REQ_WRITE;
			break;
		case PB_TYPE_LOCK_REQUEST:
			reqType = LHL_REQ_LOCK;
			break;
	}

	switch (packetType)
	{
		case PB_TYPE_READ_REQUEST_QUADLET:
		case PB_TYPE_WRITE_REQUEST_QUADLET:
			numBytes = 4;
			break;
		case PB_TYPE_READ_REQUEST:
		case PB_TYPE_WRITE_REQUEST:
		case PB_TYPE_LOCK_REQUEST:
			hResult = pbGetDataLen(packetBlock, &numBytes);
			if (hResult != NO_ERROR) return hResult;
			break;
	}

	hResult = pbGetDestinationOffset(packetBlock, &destOffset);
	if (hResult != NO_ERROR) return hResult;

	switch (nciCBtype)
	{
		case NCI_CB_ARCH_SPACE:
			switch (packetType)
			{
				case PB_TYPE_READ_REQUEST_QUADLET:
				case PB_TYPE_READ_REQUEST:
				case PB_TYPE_WRITE_REQUEST_QUADLET:
				case PB_TYPE_WRITE_REQUEST:
					if (destOffset.Low + numBytes <= CSR_ARCH_SPACE_END + 1)
					{
						QUADLET		**pData = NULL;
						uint32		respLen = 0;

						switch (packetType)
						{
							case PB_TYPE_READ_REQUEST_QUADLET:
							case PB_TYPE_READ_REQUEST:
								pData = &pRespPayload;
								respLen = numBytes;
								break;
							case PB_TYPE_WRITE_REQUEST_QUADLET:
							case PB_TYPE_WRITE_REQUEST:
								pData = &pPayload;
								respLen = 0;
								break;
						}

						hResult = pbCreateDuplicatePacketWithSize(packetBlock, &respPacket, (uint16) respLen, NULL, PB_CREATE_NCI_CB);
						if (hResult != NO_ERROR) return hResult;

						hResult = pbGetPayload(respPacket, (void **) &pRespPayload);
						if (hResult != NO_ERROR) return hResult;

						for (i = 0; i < numBytes / 4; i++)
						{
							hResult = lhlLLCHandleCSR(destOffset, 4, *pData + i, reqType);
							if (hResult != NO_ERROR)
							{
								break;
							}
							destOffset.Low += 4;
						}
						if (hResult == NO_ERROR)
						{
							rCode = RSP_COMPLETE;
						}
						numBytes = respLen;
					}
				break;
			}
			break;

		case NCI_CB_SB_SPACE:
			switch (destOffset.Low)
			{
				case CSR_SB_CYCLE_TIME:
				case CSR_SB_BUS_TIME:
				case CSR_SB_BUSY_TIME_OUT:
					switch (packetType)
					{
						case PB_TYPE_READ_REQUEST_QUADLET:
							hResult = pbCreateDuplicatePacketWithSize(packetBlock, &respPacket, (uint16) numBytes, NULL, PB_CREATE_NCI_CB);
							if (hResult != NO_ERROR) return hResult;

							hResult = pbGetPayload(respPacket, (void **) &pRespPayload);
							if (hResult != NO_ERROR) return hResult;

							rCode = lhlWatchTransRead(destOffset.Low, pRespPayload);
							break;

						case PB_TYPE_WRITE_REQUEST_QUADLET:
							if (numBytes == 4) // only allow quadlet write
							{
									hResult = pbCreateDuplicatePacketWithSize (packetBlock, &respPacket, (uint16) 0, NULL, PB_CREATE_NCI_CB);
									if (hResult != NO_ERROR) return hResult;

									rCode = lhlWatchTransWrite(destOffset.Low, pPayload[0]);
							}

							break;
					}
					break;
				case CSR_SB_BM_ID:
				case CSR_SB_BW_AVAIL:
				case CSR_SB_CH_AVAIL_HI:
				case CSR_SB_CH_AVAIL_LO:
				case CSR_SB_BROADCAST_CH:
#ifdef _IRMC_CAPS
					if (nciIRMIsThisNodeIRM())
					{
						// handle IRM Registers here
						switch (packetType)
						{
							case PB_TYPE_READ_REQUEST_QUADLET:
								hResult = pbCreateDuplicatePacketWithSize(packetBlock, &respPacket, (uint16) numBytes, NULL, PB_CREATE_NCI_CB);
								if (hResult != NO_ERROR) return hResult;

								hResult = pbGetPayload(respPacket, (void **) &pRespPayload);
								if (hResult != NO_ERROR) return hResult;

								rCode = nciIRMRead(destOffset.Low, pRespPayload);
								break;

							case PB_TYPE_LOCK_REQUEST:
								if (numBytes == 8) // only allow quadlet lock
								{
									if (lockType == PB_LOCKTYPE_COMPARE_SWAP)
									{
										uint32		lockArg = pPayload[0];
										uint32		lockData = pPayload[1];

										// response payload length is 1/2 size of request packet
										numBytes /= 2;
										hResult = pbCreateDuplicatePacketWithSize (packetBlock, &respPacket, (uint16) numBytes, NULL, PB_CREATE_NCI_CB);
										if (hResult != NO_ERROR) return hResult;

										hResult = pbGetPayload(respPacket, (void **) &pRespPayload);
										if (hResult != NO_ERROR) return hResult;

										rCode = nciIRMLock(destOffset.Low, lockArg, lockData, pRespPayload);
									}
								}
								break;
							case PB_TYPE_WRITE_REQUEST:
								if (numBytes == 4) // only allow quadlet lock
								{
										hResult = pbCreateDuplicatePacketWithSize (packetBlock, &respPacket, (uint16) numBytes, NULL, PB_CREATE_NCI_CB);
										if (hResult != NO_ERROR) return hResult;

										rCode = nciIRMWrite(destOffset.Low, pPayload[0]);
								}
								break;
						}
					}
#endif //_IRMC_CAPS
					break;
			}
			break;
	
		case NCI_CB_CONFIG_ROM:
			switch (packetType)
			{
				case PB_TYPE_READ_REQUEST_QUADLET:
				case PB_TYPE_READ_REQUEST:
					if ((destOffset.Low >= CSR_ROM_SPACE_START) && 
						(destOffset.Low + numBytes <= CSR_ROM_SPACE_START + csrGetConfigROMQuadletSize() * 4))
					{
						hResult = pbCreateDuplicatePacketWithSize(packetBlock, &respPacket, (uint16) numBytes, NULL, PB_CREATE_NCI_CB);
						if (hResult != NO_ERROR) return hResult;

						hResult = pbGetPayload(respPacket, (void **) &pRespPayload);
						if (hResult != NO_ERROR) return hResult;

						for (i = 0; i < numBytes / 4; i++)
						{
							pRespPayload[i] = csrReadConfigROMQuadlet(destOffset.Low + (i * 4));
						}
						rCode = RSP_COMPLETE;
					}
					break;
			}
			break;

#ifdef _BMC_CAPS
		case NCI_CB_TOPOLOGY_MAP:
			switch (packetType)
			{
				case PB_TYPE_READ_REQUEST_QUADLET:
				case PB_TYPE_READ_REQUEST:
					if (destOffset.Low + numBytes <= CSR_TOPOLOGY_MAP_END + 1)
					{
						uint32	index = (destOffset.Low - CSR_TOPOLOGY_MAP_START) / 4;
						BOOL	bBusMaster = TRUE;

						hResult = pbCreateDuplicatePacketWithSize(packetBlock, &respPacket, (uint16) numBytes, NULL, PB_CREATE_NCI_CB);
						if (hResult != NO_ERROR) return hResult;

						hResult = pbGetPayload(respPacket, (void **) &pRespPayload);
						if (hResult != NO_ERROR) return hResult;

						for (i = 0; i < numBytes / 4; i++)
						{
							hResult = nciBMGetTopologyMapIndex(bBusMaster, index + i, &(pRespPayload[i]));
							if (hResult != NO_ERROR)
							{
								break;
							}
						}
						if (hResult == NO_ERROR)
						{
							rCode = RSP_COMPLETE;
						}
					}
					break;
			}
			break;

		case NCI_CB_SPEED_MAP:
			switch (packetType)
			{
				case PB_TYPE_READ_REQUEST_QUADLET:
				case PB_TYPE_READ_REQUEST:
					if (destOffset.Low + numBytes <= CSR_SPEED_MAP_END + 1)
					{
						uint32	index = (destOffset.Low - CSR_SPEED_MAP_START) / 4;
						BOOL	bBusMaster = TRUE;

						hResult = pbCreateDuplicatePacketWithSize(packetBlock, &respPacket, (uint16) numBytes, NULL, PB_CREATE_NCI_CB);
						if (hResult != NO_ERROR) return hResult;

						hResult = pbGetPayload(respPacket, (void **) &pRespPayload);
						if (hResult != NO_ERROR) return hResult;

						for (i = 0; i < numBytes / 4; i++)
						{
							hResult = nciBMGetSpeedMapIndex(bBusMaster, index + i, &(pRespPayload[i]));
							if (hResult != NO_ERROR)
							{
								break;
							}
						}
						if (hResult == NO_ERROR)
						{
							rCode = RSP_COMPLETE;
						}
					}
					break;
			}
			break;
#endif //_BMC_CAPS

		default:
			hResult = E_BAD_INPUT_PARAMETERS;
			sysLogError(hResult, __LINE__, moduleName);
			return hResult;
	}

	if (rCode != RSP_COMPLETE)
	{
		lhlReplyErrorResponse(packetBlock, rCode, TRUE);
		hResult = (HRESULT) (E_LHL_RSP_BASE + rCode);
	}
	else
	{
		switch (packetType)
		{
			case PB_TYPE_READ_REQUEST_QUADLET:
			case PB_TYPE_READ_REQUEST:
				hResult = lhlSendReadResponse(respPacket, rCode, (uint16) numBytes, pRespPayload);
				break;
			case PB_TYPE_WRITE_REQUEST_QUADLET:
			case PB_TYPE_WRITE_REQUEST:
				hResult = lhlSendWriteResponse(respPacket, rCode);
				break;
			case PB_TYPE_LOCK_REQUEST:
				hResult = lhlSendLockResponse(respPacket, rCode, (uint16) numBytes, pRespPayload);
				break;
		}
	}

	// clean up the resp packetBlock
	if (pbIsValid(respPacket))
	{
		pbPacketDone(respPacket, PB_DONE_NCI_CB);
	}
	
	return hResult;
}
Beispiel #2
0
HRESULT cliCBCallArea(PB * incomingPacket, PB_PACKETTYPE packetType, RCODE_1394 *errorResponse)
// Called when a CLI remote call arrives at the CLI_CALL_AREA for the new CLI interface
// Only block writes are allowed to this register
{
	HRESULT			hResult = NO_ERROR;
	uint32			payloadSize = 0;
	uint32*			pPayload = NULL;
	char			cliCommandStr[kTempBufferSize] = {0};

	*errorResponse = RSP_TYPE_ERROR;

	hResult = pbGetPayloadSize(incomingPacket,&payloadSize);
	if (hResult != NO_ERROR) return hResult;
	hResult = pbGetPayload(incomingPacket, (void **) &pPayload);
	if (hResult != NO_ERROR) return hResult;

	SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "CLI command call: ");
	SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "packetType: %i, ", packetType);
	SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "payloadSize: %i", payloadSize);
	SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "\n\r");

	if ((packetType == PB_TYPE_WRITE_REQUEST) && payloadSize > 4)
	{
		// Get the command and execute it
		if (payloadSize <= kTempBufferSize)
		{
			memcpy(cliCommandStr, pPayload, payloadSize);
			formatSwapStrBytes(cliCommandStr, payloadSize);

			SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "CLI command call: ");
			SYS_DEBUG(SYSDEBUG_TRACE_CLICB, cliCommandStr);
			SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "\n\r");

#ifdef _CLICB_DEFERRED_TASK	
			if (cliCBDeferred == TRUE)
			{
				CLICB_CMD*	cmd = NULL;

				hResult = lalReplyWriteResponse(incomingPacket, RSP_COMPLETE, TRUE);
				*errorResponse = RSP_COMPLETE;

				SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "CLI command call: deferring to cli CB task \n\r");
				
				hResult = cliCBAllocateDeferredCmd(&cmd, cliCommandStr);
				if (hResult != NO_ERROR) return hResult;

				// thread cli CB deferred task message queue
				hResult = TCMsgQueueSend(cliCBDeferredQueueID, (void *) &cmd, TC_NO_WAIT);
				if (hResult != NO_ERROR)
				{
					sysLogError(hResult, __LINE__, moduleName);
				}
			}
			else
#endif //_CLICB_DEFERRED_TASK
			{
				cliCBResult = cliCBHandleCommand(cliCommandStr);
				if (cliCBResult == NO_ERROR)
				{
					hResult = lalReplyWriteResponse(incomingPacket, RSP_COMPLETE, TRUE);
					*errorResponse = RSP_COMPLETE;
				}
				else
				{
					*errorResponse = RSP_DATA_ERROR;
				}
			}
		}
		else
		{
			*errorResponse = RSP_DATA_ERROR;
		}
	}
	else 
	{
		if (payloadSize < 4) {
			// <4 = DATA ERROR, =4 = TYPE ERROR, >4 <max = ok, >max = DATA ERROR
			*errorResponse = RSP_DATA_ERROR;
		}
	}

	return hResult;
}
Beispiel #3
0
static HRESULT mixer8firewireCoreCallback(PB *packetBlock)
{
	HRESULT hResult = NO_ERROR;
	PB_HEADER		*pHeader = NULL;
	PB_PACKETTYPE	packetType = PB_TYPE_UNDEF;
	PB_LOCKTYPE		lockType;
	OFFSET_1394		OffSetDest;
	uint32			payloadSize = 0;
	uint32			RegionOffSet = 0;	
	QUADLET			*pPayload = NULL;

	hResult = pbGetPacketHeader (packetBlock, &pHeader);
	if (hResult != NO_ERROR) return hResult;
	hResult = pbGetPacketType(packetBlock,&packetType);
	if (hResult != NO_ERROR) return hResult;
	hResult = pbGetDestinationOffset(packetBlock, &OffSetDest);
	if (hResult != NO_ERROR) return hResult;

	RegionOffSet = OffSetDest.Low - MIXER8_BASE_START;	

	hResult = pbGetDataLen(packetBlock,&payloadSize);
	if(hResult != NO_ERROR) 
		return hResult;	

	if (packetType == PB_TYPE_WRITE_REQUEST_QUADLET)
	{
		hResult = pbGetPayload(packetBlock, (void **)&pPayload);
		if (hResult != NO_ERROR) return hResult;
		hResult = pbGetDataLen(packetBlock,&payloadSize);
		if (hResult != NO_ERROR) return hResult;
		payloadSize = 4;

		if(mixer8firewireCheckForWrite(RegionOffSet))
		{
			if (RegionOffSet == (MIXER8_OFFSET(CurrentConfiguration)))
			{
				if(mixer8CheckValidConfiguration((uint32)*pPayload))
				{
					memcpy((uint32*) ((int)&mixer8 + (int)RegionOffSet), pPayload, payloadSize);
					hResult = lalReplyWriteResponse(packetBlock, RSP_COMPLETE, TRUE);
					TCSemaphoreSignal(mixer8SemID);
				}
				else
				{
					hResult = lalReplyWriteResponse(packetBlock, RSP_DATA_ERROR, TRUE);
				}
			}
			else
			{
				memcpy((uint32*) ((int)&mixer8 + (int)RegionOffSet), pPayload, payloadSize);
				hResult = lalReplyWriteResponse(packetBlock, RSP_COMPLETE, TRUE);
				TCSemaphoreSignal(mixer8SemID);
			}
		}
		else
		{
			hResult = lalReplyWriteResponse(packetBlock, RSP_ADDRESS_ERROR, TRUE);			
		}		
	}
	if (packetType == PB_TYPE_WRITE_REQUEST)
	{
		hResult = pbGetPayload(packetBlock, (void **) &pPayload);
		if (hResult != NO_ERROR) return hResult;
		hResult = pbGetDataLen(packetBlock,&payloadSize);
		if (hResult != NO_ERROR) return hResult;

		if(mixer8firewireCheckForBulkWrite(RegionOffSet,payloadSize))
		{			
			memcpy((uint32*) ((int)&mixer8 + (int)RegionOffSet), pPayload, payloadSize);
			hResult = lalReplyWriteResponse(packetBlock, RSP_COMPLETE, TRUE);
			TCSemaphoreSignal(mixer8SemID);
		}
		else
		{
			hResult = lalReplyWriteResponse(packetBlock, RSP_ADDRESS_ERROR, TRUE);
		}
	}

	if (packetType == PB_TYPE_READ_REQUEST)
	{
		hResult = pbGetDataLen(packetBlock,&payloadSize);
		if (hResult != NO_ERROR) return hResult;

		hResult = lalReplyReadResponse(packetBlock, RSP_COMPLETE, (uint16) payloadSize,
			(uint32*) ((int)&mixer8 + (int)RegionOffSet), TRUE);
	}

	if (packetType == PB_TYPE_READ_REQUEST_QUADLET)
	{
		payloadSize = 4;
		hResult = lalReplyReadResponse(packetBlock, RSP_COMPLETE, (uint16) payloadSize,
			(uint32*) ((int)&mixer8 + (int)RegionOffSet), TRUE);
	}

	if (packetType == PB_TYPE_LOCK_REQUEST)
	{
		hResult = pbGetLockType(packetBlock, &lockType);
		if (hResult != NO_ERROR) return hResult;
		hResult = pbGetDataLen(packetBlock,&payloadSize);
		if (hResult != NO_ERROR) return hResult;
		hResult = pbGetPayload(packetBlock, (void **) &pPayload);
		if (hResult != NO_ERROR) return hResult;

		hResult = lalReplyLockResponse(packetBlock, RSP_COMPLETE, (uint16)payloadSize, pPayload, TRUE);
	}

	return hResult;
}
Beispiel #4
0
HRESULT cliCBControllerReg(PB * incomingPacket, PB_PACKETTYPE packetType, RCODE_1394 *errorResponse)
// Handle the CLI Controller register, which is two quads long
// It allows CompareSwap locks only to those two quads.
// The controller register contains the bus address of the device
// controlling this device. The lower bits specify an address on that
// device to inform it of the completion of a command.

{
	HRESULT			hResult = E_FAIL;
	PB_LOCKTYPE		lockType;
	uint32			payloadSize = 0;
	uint32*			pPayload = NULL;

	*errorResponse = RSP_TYPE_ERROR;

	SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "Controller Register\n\r");

	if ((packetType == PB_TYPE_READ_REQUEST_QUADLET) || (packetType == PB_TYPE_READ_REQUEST))
	{
		if (packetType == PB_TYPE_READ_REQUEST_QUADLET)
		{
			payloadSize = 4;
		} 
		else
		{
			hResult = pbGetDataLen(incomingPacket,&payloadSize);
			if (hResult != NO_ERROR) return hResult;
		}
		if (payloadSize > 8)
		{
			*errorResponse = RSP_DATA_ERROR;
		} 
		else
		{
			SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "\tRead request, %u bytes\n\r", payloadSize);
		
			hResult = lalReplyReadResponse(incomingPacket, RSP_COMPLETE, (uint16) payloadSize, &(cliCBController[0]), TRUE); // Reply
			*errorResponse = RSP_COMPLETE;
		}
	}

	if (packetType == PB_TYPE_LOCK_REQUEST)
	{
		hResult = pbGetLockType(incomingPacket, &lockType);
		if (hResult != NO_ERROR) return hResult;
		hResult = pbGetDataLen(incomingPacket,&payloadSize);
		if (hResult != NO_ERROR) return hResult;
		hResult = pbGetPayload(incomingPacket, (void **) &pPayload);
		if (hResult != NO_ERROR) return hResult;

		SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "\tLock request, %u bytes\n\r", payloadSize);

		if (payloadSize == 16)
		{
			if (lockType == PB_LOCKTYPE_COMPARE_SWAP)
			{
				QUADLET lockArgHi  = pPayload[0];
				QUADLET lockArgLo  = pPayload[1];
				QUADLET lockDataHi = pPayload[2];
				QUADLET lockDataLo = pPayload[3];

				pPayload[0] = cliCBController[0];
				pPayload[1] = cliCBController[1];
				payloadSize /= 2;
			
				if ((lockArgHi == cliCBController[0]  ) && (lockArgLo == cliCBController[1]))
				{
					cliCBController[0] = lockDataHi;
					cliCBController[1] = lockDataLo;
				}
				hResult = lalReplyLockResponse(incomingPacket, RSP_COMPLETE, (uint16)payloadSize, pPayload, TRUE);
				*errorResponse = RSP_COMPLETE;
			}
		}
	}

	return hResult;
}
Beispiel #5
0
static HRESULT context1PostPacket(PB * pPacket,uint32 semID)
{
	HRESULT hResult = NO_ERROR;

	//check if context is available, should be as we only have one thread using the context
	volatile POSTED_TX_CONTEXT * pContext = &postedTxState.contexts[1];
	if (pContext->bPosted)
	{
			hResult = E_LAL_RESPONSE_UNEXPECTED;
			sysLogError(hResult, __LINE__, moduleName);
			return hResult;
	}
	PB_HEADER*	pHeader = 0;
	uint32		speedCode = 0;
#ifdef _LOOSE_ISO
	uint8		asyncStream = FALSE;
#endif //_LOOSE_ISO


 	// ML 140610: Busreset storm fix. Let's skip if we ar ein bus reset
 	if (postedTxState.inBr)
	{
	  hResult = E_LAL_BUS_RESET_IN_PROGRESS;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}

	pbGetPacketHeader(pPacket, &pHeader);
	pbGetPacketSpeed(pPacket, &speedCode);

	PB_PACKETTYPE packetType;
	pbGetPacketType(pPacket, &packetType);

	pContext->header.quadlets[0] = (pHeader->quadlets[0] & 0x0000ffff);		// 0:spd,tag,ch,tcode,sy
	pContext->header.quadlets[0]|= speedCode;

#ifdef _LOOSE_ISO
	pbIsAsyncStreamPacket (pPacket, &asyncStream);
	if (asyncStream == TRUE)
	{
		pContext->header.quadlets[1] = (pHeader->quadlets[1] & 0xffff0000);		// 1:data_length,reserved
	}
	else
#endif //_LOOSE_ISO
	if (packetType == TCODE_PHY_PACKET)
	{
		pContext->header.quadlets[0] = ((uint32)TCODE_LLC_SPECIFIC) << SHIFT_TCODE;
		pContext->header.quadlets[1] = pHeader->quadlets[0];
		pContext->header.quadlets[2] = ~pHeader->quadlets[0];
	}
	else
	{
		pContext->header.quadlets[0] |= LLC_SOURCEID_NODEID;
		pContext->header.quadlets[1] = (pHeader->quadlets[0] & 0xffff0000);		// 1:dstId,destination_offsetHigh
		pContext->header.quadlets[1] |= (pHeader->quadlets[1] & 0x0000ffff);
		pContext->header.quadlets[2] = pHeader->quadlets[2];						// 2:destination_offsetLow
		pContext->header.quadlets[3] = pHeader->quadlets[3];						// 3:data_length,extended_tcode
	}
	hResult = lhlGetHeaderQuadSizeFromTCode(LHL_TX, packetType, (uint16 *)&pContext->headerLen);
	if (hResult != NO_ERROR) return hResult;

	uint32 payloadNumBytes=0;
	
	pbGetPayload(pPacket, (void **)&pContext->pPayload);
	pbGetPayloadSize(pPacket, &payloadNumBytes);
	
	//Ugly, the payload is not always refering to the outgoing packet.
	if ((packetType==PB_TYPE_READ_REQUEST) || (packetType==PB_TYPE_READ_REQUEST_QUADLET) ||(packetType==PB_TYPE_WRITE_RESPONSE) || (packetType==TCODE_PHY_PACKET)) 
		payloadNumBytes=0;
	//Another hack as the read resp payload should always be one quadlet even in case of error
	if (packetType==PB_TYPE_READ_RESPONSE_QUADLET)
		payloadNumBytes=4;

	pContext->payloadLen = (payloadNumBytes+3)>>2;
	
	// ML 140610: Busreset storm fix. There is potentially a race condition here if
	//            Isr or Dsr comes here. Fixed with interrupt disable.
	TCInterruptGlobalDisable();
	if (postedTxState.inBr)
	{
	  TCInterruptGlobalEnable();
	  hResult = E_LAL_BUS_RESET_IN_PROGRESS;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}
  pContext->semID = semID;
	pContext->bPosted = TRUE;
  fSYS_TRACE1(SYSDEBUG_TRACE_TESTS,0);
  llcLinkRegWrite(INTERRUPT_REG_SET_DP, LLC_INT_BIT(LLCID_ASY_TX_CMPL));	
	TCInterruptGlobalEnable();
	return hResult;
}