HRESULT cliCBResultReg(PB * incomingPacket, PB_PACKETTYPE packetType, RCODE_1394 *errorResponse) // Return the result of the last CLI call. // Only read this when you know the call has completed, otherwise it may // be a result for a previous call. Zero means no error. { HRESULT hResult = E_FAIL; SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "Result Register\n\r"); *errorResponse = RSP_TYPE_ERROR; if (packetType == PB_TYPE_READ_REQUEST_QUADLET) { hResult = lalReplyReadResponse(incomingPacket, RSP_COMPLETE, 4, &cliCBResult, TRUE); *errorResponse = RSP_COMPLETE; } else if (packetType == PB_TYPE_READ_REQUEST) { uint32 payloadSize = 0; // include status of command in packet hResult = pbGetDataLen(incomingPacket,&payloadSize); if (hResult != NO_ERROR) return hResult; if (payloadSize == 8) { uint32 data[2]; data[0] = cliCBStatus; data[1] = cliCBResult; hResult = lalReplyReadResponse(incomingPacket, RSP_COMPLETE, 8, data, TRUE); *errorResponse = RSP_COMPLETE; } else { *errorResponse = RSP_DATA_ERROR; } } return hResult; }
HRESULT cliCBResponseBufferCB(PB * incomingPacket, PB_PACKETTYPE packetType, RCODE_1394 *errorResponse) // Called when the other node wants to read the result of an operation { HRESULT hResult = E_FAIL; uint32 payloadSize = 0; OFFSET_1394 offsetDest; uint32 regionOffset; *errorResponse = RSP_TYPE_ERROR; SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "Controller Response Buffer\n\r"); hResult = pbGetDestinationOffset(incomingPacket, &offsetDest); if (hResult != NO_ERROR) return hResult; regionOffset = offsetDest.Low - CLI_CB_BASE_START - CLI_RESPONSE_AREA; if ((regionOffset+payloadSize) > CLI_MAX_MSG_SIZE) { *errorResponse = RSP_ADDRESS_ERROR; } else { 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 >= CLI_MAX_MSG_SIZE) { // Shouldnt be possible to trigger this, but anyway... *errorResponse = RSP_DATA_ERROR; } else { memcpy(cliCBResponseBuffer, cliCBSysLogErrorBuffer, payloadSize); // Copy the response data formatSwapStrBytes((char *)cliCBResponseBuffer, payloadSize); // and endian swap if needed hResult = lalReplyReadResponse(incomingPacket, RSP_COMPLETE, (uint16) payloadSize, &(cliCBResponseBuffer[0]), TRUE); // Reply *errorResponse = RSP_COMPLETE; } } } return hResult; }
HRESULT cliCBResponseCountReg(PB * incomingPacket, PB_PACKETTYPE packetType, RCODE_1394 *errorResponse) // Return the value of the response count register // This register contains the length of the command response including the zero // termination on the response. If the command has not yet completed, it will return // zero. If a command returns no response, it will return 1 and there is no response. { HRESULT hResult = E_FAIL; *errorResponse = RSP_TYPE_ERROR; SYS_DEBUG(SYSDEBUG_TRACE_CLICB, "Response Count Register\n\r"); if (packetType == PB_TYPE_READ_REQUEST_QUADLET) { hResult = lalReplyReadResponse(incomingPacket, RSP_COMPLETE, 4, &cliCBRespCount, TRUE); *errorResponse = RSP_COMPLETE; } return hResult; }
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; }
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; }