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