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; }
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; }
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; }