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