예제 #1
0
HRESULT cliCBCallback(PB * incomingPacket)
// Called when a CLI remote call arrives
{
	HRESULT			hResult = NO_ERROR;
	PB_PACKETTYPE	packetType = PB_TYPE_UNDEF;
	OFFSET_1394		offsetDest;
	uint32			regionOffset;
	RCODE_1394		errorResponse = RSP_ADDRESS_ERROR;

	hResult = pbGetPacketType(incomingPacket,&packetType);
	if (hResult != NO_ERROR) return hResult;

	hResult = pbGetDestinationOffset(incomingPacket, &offsetDest);
	if (hResult != NO_ERROR) return hResult;

	regionOffset = offsetDest.Low - CLI_CB_BASE_START;

	SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "Access to Remote CLI memory:\n\r");
	SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "offset: %04hx_%08x, regionOffset:%08x\n\r", offsetDest.High, offsetDest.Low, regionOffset);

	switch (regionOffset) {
		case CLI_CONTROLLER_HREG :
			hResult = cliCBControllerReg(incomingPacket, packetType, &errorResponse);		// All in one block lock.
			break;
		case CLI_RESP_CLEAR_REG :
			hResult = cliCBResponseClearReg(incomingPacket, packetType, &errorResponse);	// Quadlet write only
			break;
		case CLI_RESP_COUNT_REG :
			hResult = cliCBResponseCountReg(incomingPacket, packetType, &errorResponse);	// Quadlet read only
			break;
		case CLI_RESULT_REG :
			hResult = cliCBResultReg(incomingPacket, packetType, &errorResponse);			// Quadlet read only
			break;
		case CLI_CALL_AREA :
			hResult = cliCBCallArea(incomingPacket, packetType, &errorResponse);			// This has to be an all in one blockwrite
			break;
		default :
			if ((regionOffset >= CLI_RESPONSE_AREA) && (regionOffset < (CLI_RESPONSE_AREA + CLI_MAX_MSG_SIZE))) {
				// Deal with any kind of read to the response area
				hResult = cliCBResponseBufferCB(incomingPacket, packetType, &errorResponse);
			}
			break;
	}

	if (errorResponse != RSP_COMPLETE)
	{	
		// If something went wrong above, return the appropriate error response
		hResult = lalReplyErrorResponse(incomingPacket, errorResponse, TRUE);
		SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "\tReplied with error response:0x%08x\n\r", errorResponse);
	}

	return hResult;
}
예제 #2
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;
}
예제 #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;
}
예제 #4
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;
}