//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaNonIpTxIoctl -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. // DtStatus DtaNonIpTxIoctl( DtaDeviceData* pDvcData, DtFileObject* pFile, DtIoctlObject* pIoctl) { DtStatus Status = DT_STATUS_OK; char* pCmdStr; // Mnemonic string for Command UInt InReqSize = 0; // Required length of input buffer UInt OutReqSize = 0; // Required length of output buffer Int NonIpPortIndex; // Index in the nonip port struct DtaIoctlNonIpTxCmdInput* pNonIpTxCmdInput = (DtaIoctlNonIpTxCmdInput*)pIoctl->m_pInputBuffer; DtaIoctlNonIpTxCmdOutput* pNonIpTxCmdOutput = (DtaIoctlNonIpTxCmdOutput*)pIoctl->m_pOutputBuffer; // Default require at least the size of the header preceding the data InReqSize = OFFSETOF(DtaIoctlNonIpTxCmdInput, m_Data); OutReqSize = OFFSETOF(DtaIoctlNonIpTxCmdOutput, m_Data); // Check if we can read m_Cmd / m_PortIndex if (pIoctl->m_InputBufferSize < InReqSize) return DT_STATUS_INVALID_PARAMETER; // Validate port index if (!DT_SUCCESS(DtaGetNonIpPortIndex(pDvcData, pNonIpTxCmdInput->m_PortIndex, &NonIpPortIndex))) return DT_STATUS_INVALID_PARAMETER; // Determine final required output/input sizes switch (pNonIpTxCmdInput->m_Cmd) { case DTA_NONIP_TX_CMD_GET_FLAGS: pCmdStr = "DTA_NONIP_TX_CMD_GET_FLAGS"; OutReqSize += sizeof(DtaIoctlNonIpTxCmdGetFlagsOutput); // We expect no additional data in the input buffer InReqSize += 0; break; case DTA_NONIP_TX_CMD_CLEAR_FLAGS: pCmdStr = "DTA_NONIP_TX_CMD_CLEAR_FLAGS"; InReqSize += sizeof(DtaIoctlNonIpTxCmdClearFlagsInput); // We expect no output buffer at all OutReqSize = 0; break; case DTA_NONIP_TX_CMD_SET_FAILSAFE_CFG: pCmdStr = "DTA_NONIP_TX_CMD_SET_FAILSAFE_CFG"; InReqSize += sizeof(DtaIoctlNonIpTxCmdSetFailsafeCfgInput); // We expect no output buffer at all OutReqSize = 0; break; case DTA_NONIP_TX_CMD_SET_FAILSAFE_ALIVE: pCmdStr = "DTA_NONIP_TX_CMD_SET_FAILSAFE_ALIVE"; // We expect no additional data in the input buffer InReqSize += 0; // We expect no output buffer at all OutReqSize = 0; break; case DTA_NONIP_TX_CMD_GET_FAILSAFE_INFO: pCmdStr = "DTA_NONIP_TX_CMD_GET_FAILSAFE_INFO"; OutReqSize += sizeof(DtaIoctlNonIpTxCmdGetFailsafeInfoOutput); // We expect no additional data in the input buffer InReqSize += 0; break; default: pCmdStr = "??UNKNOWN VPDCMD CODE??"; Status = DT_STATUS_NOT_SUPPORTED; } if (DT_SUCCESS(Status)) { // Check buffer sizes if (pIoctl->m_InputBufferSize < InReqSize) { DtDbgOut(ERR, NONIP, "%s: INPUT BUFFER TOO SMALL Size=%d Req=%d", pCmdStr, pIoctl->m_InputBufferSize, InReqSize); return DT_STATUS_INVALID_PARAMETER; } if (pIoctl->m_OutputBufferSize < OutReqSize) { DtDbgOut(ERR, NONIP, "%s: OUTPUT BUFFER TOO SMALL Size=%d Req=%d", pCmdStr, pIoctl->m_OutputBufferSize, OutReqSize); return DT_STATUS_INVALID_PARAMETER; } DtDbgOut(MAX, NONIP, "%s: In=%d (Rq=%d), Out=%d (Rq=%d)", pCmdStr, pIoctl->m_InputBufferSize, InReqSize, pIoctl->m_OutputBufferSize, OutReqSize); } // The bytes written will be updated if needed. Set the default value here. pIoctl->m_OutputBufferBytesWritten = OutReqSize; if (DT_SUCCESS(Status)) { // Execute cmd switch (pNonIpTxCmdInput->m_Cmd) { case DTA_NONIP_TX_CMD_GET_FLAGS: Status = DtaNonIpTxGetFlags(&pDvcData->m_pNonIpPorts[NonIpPortIndex], &pNonIpTxCmdOutput->m_Data.m_GetFlags.m_Status, &pNonIpTxCmdOutput->m_Data.m_GetFlags.m_Latched); break; case DTA_NONIP_TX_CMD_CLEAR_FLAGS: Status = DtaNonIpTxClearFlags(&pDvcData->m_pNonIpPorts[NonIpPortIndex], pNonIpTxCmdInput->m_Data.m_ClearFlags.m_FlagsToClear); break; case DTA_NONIP_TX_CMD_SET_FAILSAFE_CFG: Status = DtaNonIpTxSetFailsafeCfg(&pDvcData->m_pNonIpPorts[NonIpPortIndex], pNonIpTxCmdInput->m_Data.m_SetFailsafeCfg.m_Enable, pNonIpTxCmdInput->m_Data.m_SetFailsafeCfg.m_Timeout); break; case DTA_NONIP_TX_CMD_SET_FAILSAFE_ALIVE: Status = DtaNonIpTxSetFailsafeAlive(&pDvcData->m_pNonIpPorts[NonIpPortIndex]); break; case DTA_NONIP_TX_CMD_GET_FAILSAFE_INFO: Status = DtaNonIpTxGetFailsafeInfo(&pDvcData->m_pNonIpPorts[NonIpPortIndex], &pNonIpTxCmdOutput->m_Data.m_GetFailsafeInfo.m_Enable, &pNonIpTxCmdOutput->m_Data.m_GetFailsafeInfo.m_Timeout, &pNonIpTxCmdOutput->m_Data.m_GetFailsafeInfo.m_Alive); break; default: Status = DT_STATUS_NOT_SUPPORTED; } } // If we failed, no data has te be copied to user space if (!DT_SUCCESS(Status)) { pIoctl->m_OutputBufferBytesWritten = 0; if (Status == DT_STATUS_NOT_SUPPORTED) DtDbgOut(MIN, NONIP, "NonIpTxCmd=0x%x: NOT SUPPORTED", pNonIpTxCmdInput->m_Cmd); else DtDbgOut(MIN, NONIP, "%s: ERROR %xh", pCmdStr, Status); } return Status; }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEnDecIoctl -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtaEnDecIoctl( DtaDeviceData* pDvcData, DtFileObject* pFile, DtIoctlObject* pIoctl, Bool PowerDownPending) { DtStatus Status = DT_STATUS_OK; char* pCmdStr; // Mnemonic string for Command UInt InReqSize = 0; // Required length of input buffer UInt OutReqSize = 0; // Required length of output buffer Int NonIpPortIndex; // Index in the nonip port struct DtaNonIpPort* pNonIpPort = NULL; DtaIoctlEnDecCmdInput* pEnDecCmdInput = (DtaIoctlEnDecCmdInput*)pIoctl->m_pInputBuffer; DtaIoctlEnDecCmdOutput* pEnDecCmdOutput = (DtaIoctlEnDecCmdOutput*)pIoctl->m_pOutputBuffer; // Default require at least the size of the header preceding the data InReqSize = OFFSETOF(DtaIoctlEnDecCmdInput, m_Data); OutReqSize = OFFSETOF(DtaIoctlEnDecCmdOutput, m_Data); // Check if we can read m_Cmd / m_PortIndex if (pIoctl->m_InputBufferSize < InReqSize) return DT_STATUS_INVALID_PARAMETER; // Validate port index pNonIpPort = NULL; // Assume a board level request if (!DT_SUCCESS(DtaGetNonIpPortIndex(pDvcData, pEnDecCmdInput->m_PortIndex, &NonIpPortIndex))) return DT_STATUS_INVALID_PARAMETER; pNonIpPort = &pDvcData->m_pNonIpPorts[NonIpPortIndex]; if (!pNonIpPort->m_CapAvEnc) return DT_STATUS_NOT_SUPPORTED; // Determine final required output/input sizes switch (pEnDecCmdInput->m_Cmd) { case DTA_ENDEC_CMD_EXCLUSIVE_ACCESS: pCmdStr = "DTA_ENDEC_CMD_EXCLUSIVE_ACCESS"; InReqSize += sizeof(DtaIoctlNonIpCmdExclusiveAccessInput); OutReqSize = 0; break; case DTA_ENDEC_CMD_GET_SOURCE_PORT: pCmdStr = "DTA_ENDEC_CMD_GET_SOURCE_PORT"; InReqSize = 0; OutReqSize += sizeof(DtaIoctEnDecCmdGetSourcePortOutput); break; case DTA_ENDEC_CMD_SET_SOURCE_PORT: pCmdStr = "DTA_ENDEC_CMD_SET_SOURCE_PORT"; InReqSize += sizeof(DtaIoctEnDecCmdSetSourcePortInput); OutReqSize = 0; break; case DTA_ENDEC_CMD_GET_VIDSTD: pCmdStr = "DTA_ENDEC_CMD_GET_VIDSTD"; InReqSize = 0; OutReqSize += sizeof(DtaIoctEnDecCmdGetVidStdOutput); break; case DTA_ENDEC_CMD_SET_VIDSTD: pCmdStr = "DTA_ENDEC_CMD_SET_VIDSTD"; InReqSize += sizeof(DtaIoctEnDecCmdSetVidStdInput); OutReqSize = 0; break; default: pCmdStr = "??UNKNOWN ENDEC_CMD CODE??"; Status = DT_STATUS_NOT_SUPPORTED; } if (DT_SUCCESS(Status)) { // Check buffer sizes if (pIoctl->m_InputBufferSize < InReqSize) { DtDbgOut(ERR, D7PRO, "%s: INPUT BUFFER TOO SMALL Size=%d Req=%d", pCmdStr, pIoctl->m_InputBufferSize, InReqSize); return DT_STATUS_INVALID_PARAMETER; } if (pIoctl->m_OutputBufferSize < OutReqSize) { DtDbgOut(ERR, D7PRO, "%s: OUTPUT BUFFER TOO SMALL Size=%d Req=%d", pCmdStr, pIoctl->m_OutputBufferSize, OutReqSize); return DT_STATUS_INVALID_PARAMETER; } DtDbgOut(MAX, D7PRO, "%s: In=%d (Rq=%d), Out=%d (Rq=%d)", pCmdStr, pIoctl->m_InputBufferSize, InReqSize, pIoctl->m_OutputBufferSize, OutReqSize); } // The bytes written will be updated if needed. Set the default value here. pIoctl->m_OutputBufferBytesWritten = OutReqSize; if (DT_SUCCESS(Status)) { switch (pEnDecCmdInput->m_Cmd) { case DTA_ENDEC_CMD_EXCLUSIVE_ACCESS: Status = DtaEnDecExclusiveAccess(pNonIpPort, pFile, pEnDecCmdInput->m_Data.m_ExclusiveAccess.m_Cmd); break; case DTA_ENDEC_CMD_GET_SOURCE_PORT: Status = DtaEnDecGetSourcePort(pNonIpPort, &pEnDecCmdOutput->m_Data.m_GetSourcePort.m_PortIndex); break; case DTA_ENDEC_CMD_SET_SOURCE_PORT: Status = DtaEnDecSetSourcePort(pNonIpPort, pEnDecCmdInput->m_Data.m_SetSourcePort.m_PortIndex); break; case DTA_ENDEC_CMD_GET_VIDSTD: Status = DtaEnDecGetVidStd(pNonIpPort, &pEnDecCmdOutput->m_Data.m_GetVidStd.m_VidStd); break; case DTA_ENDEC_CMD_SET_VIDSTD: Status = DtaEnDecSetVidStd(pNonIpPort, pEnDecCmdInput->m_Data.m_SetVidStd.m_VidStd); break; } } // If we failed, no data has to be copied to user space if (!DT_SUCCESS(Status)) { pIoctl->m_OutputBufferBytesWritten = 0; if (Status == DT_STATUS_NOT_SUPPORTED) DtDbgOut(MIN, D7PRO, "EnDecCmd=0x%x: NOT SUPPORTED", pEnDecCmdInput->m_Cmd); else if (Status == DT_STATUS_IO_PENDING) DtDbgOut(MAX, D7PRO, "%s: ERROR %xh", pCmdStr, Status); // NOT A REAL ERROR else DtDbgOut(MIN, D7PRO, "%s: ERROR %xh", pCmdStr, Status); } return Status; }