示例#1
0
HRESULT nciCBAddressError(PB *packetBlock, uint32 nciCBtype)
{
	HRESULT		hResult = NO_ERROR;

	UNUSED_ARG(nciCBtype);

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

	// so far no implementation
	lhlReplyErrorResponse(packetBlock, RSP_ADDRESS_ERROR, TRUE);

	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
HRESULT avcHandlePacketBlock(PB* packetBlock)
{
	HRESULT			hResult = NO_ERROR;	
	AVC_HEADER		avcHeader;
	uint32			response = 0;
	pDataStream		pStream = NULL;
	BOOL			bReceivedResponse = FALSE;
	BOOL			bSendResponse = FALSE;

	hResult = pbGetApplicationDatastream(packetBlock, &pStream);
	if (hResult != NO_ERROR) return hResult;

	// Log the AV/C message in
	hResult = avcDecodeHeader(pStream, &avcHeader);

	if (hResult != NO_ERROR)								// there is some fault with the packet
	{
		hResult = E_PKT_AVC_NOT_IMPLEMENTED;
	}

	bReceivedResponse = avcCtypeIsResponse(avcHeader.ctype);

	if (hResult == NO_ERROR)
	{
		hResult = avcUnitReserveCheck(&avcHeader, packetBlock);	// check if (sub-) unit is reserved etc.
	}

	if (hResult == NO_ERROR)
	{
		if (rmInMap(avcHeader.opcode, avcDescriptorOpcodesRangeMap))
		{
			// pass descriptor command off to the DescriptorManager (includes responses from our descriptor reads)
			hResult = avcCallDescriptorHandler(&avcHeader, packetBlock);
		} 
		else
		{
			//	command is not mapped as a descriptor command so now we want to handle this normally
			hResult = avcHandleCallback(&avcHeader, packetBlock);
		}
	}

	if (hResult != NO_ERROR)
	{
		// need to take care of the response here

		// verify packet ctypes for response codes

		if (bReceivedResponse == FALSE)
		{
			bSendResponse = TRUE;
			switch (hResult)
			{
				case E_PKT_AVC_ACCEPTED:		response = AVC_RESPONSE_ACCEPTED;			break;
				case E_PKT_AVC_IMPLEMENTED:		response = AVC_RESPONSE_IMPLEMENTED;		break;	// command is supported - send IMPLEMENTED response
				case E_PKT_AVC_SUBUNIT_BUSY:	response = AVC_RESPONSE_REJECTED;			break;	// subunit cannot accept packet at this time - send REJECTED response
				case E_PKT_AVC_REJECTED:		response = AVC_RESPONSE_REJECTED;			break;	// send REJECTED response
				case E_PKT_AVC_NOT_IMPLEMENTED:	response = AVC_RESPONSE_NOT_IMPLEMENTED;	break;	// send NOT IMPLEMENTED response
				case E_PKT_AVC_INTERIM:			response = AVC_RESPONSE_INTERIM;			break;	// send INTERIM response
				case E_PKT_AVC_STABLE:			response = AVC_RESPONSE_STABLE;				break;	// send STABLE response
				default:						bSendResponse = FALSE;						break;
			}

			if (pbPacketIsBroadcast(packetBlock) == TRUE)
			{
				if (response == AVC_RESPONSE_NOT_IMPLEMENTED)
				{
					bSendResponse = FALSE;
				}
			}

			if (bSendResponse)
			{
				avcReplyResponse(response, packetBlock);
			}
		}
	}

	return hResult;
}