Exemplo n.º 1
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;
}
Exemplo n.º 2
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;
}