Ejemplo n.º 1
0
HRESULT avcCreateResponsePacket(PB *packetBlock, PB **respPacket, BOOL bNewPayloadSize, uint32 payloadSize)
{
	HRESULT		hResult = NO_ERROR;	

	if (bNewPayloadSize)
	{
		hResult = pbCreateDuplicatePacketWithSize(packetBlock, respPacket, (uint16) payloadSize, NULL, PB_CREATE_AVC_SEND_RSP);
		if (hResult != NO_ERROR) return hResult;
	}
	else
	{
		hResult = pbCreateDuplicatePacket(packetBlock, respPacket, NULL, PB_CREATE_AVC_SEND_RSP);
		if (hResult != NO_ERROR) return hResult;
	}

#if 1 
	pbSwapSrcDstNodeAddr(*respPacket);
#endif

	return hResult;
}
Ejemplo n.º 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;
}