/*{{{ TransformerGetLogEvent*/ static int TransformerGetLogEvent(struct MMEContext_s *Context) { MME_Command_t MMECommand; MME_ERROR MMEStatus; /*EVENT_LOG_TransformParam_t TransformParams;*/ memset(&MMECommand, 0x00, sizeof(MME_Command_t)); MMECommand.CmdStatus.AdditionalInfoSize = sizeof(EVENT_LOG_CommandStatus_t); MMECommand.CmdStatus.AdditionalInfo_p = (MME_GenericParams_t)(&(Context->MMECommandStatus)); MMECommand.StructSize = sizeof(MME_Command_t); MMECommand.CmdCode = MME_TRANSFORM; MMECommand.CmdEnd = MME_COMMAND_END_RETURN_NOTIFY; MMECommand.DueTime = (MME_Time_t)0; MMECommand.NumberInputBuffers = 0; MMECommand.NumberOutputBuffers = 0; MMECommand.DataBuffers_p = NULL; MMECommand.ParamSize = 0;/*sizeof(EVENT_LOG_TransformParam_t);*/ MMECommand.Param_p = NULL; /*(MME_GenericParams_t)&TransformParams;*/ MMEStatus = MME_SendCommand(Context->MMEHandle, &MMECommand); if (MMEStatus != MME_SUCCESS) { MONITOR_ERROR("%s: Failed to send command - Error 0x%08x.\n", Context->TransformerName, MMEStatus); return -EFAULT; } return 0; }
static MME_ERROR simpleMix(MME_TransformerHandle_t hdl) { MME_ERROR err; MME_DataBuffer_t *bufs[3] = { 0, 0, 0 }; MME_Command_t cmd = { sizeof(MME_Command_t) }; /* allocate databuffers using MME_ALLOCATION_PHYSICAL to guarantee * a single scatter page per allocation */ err = MME_AllocDataBuffer(hdl, sizeof(sample1), MME_ALLOCATION_PHYSICAL, bufs+0); if (MME_SUCCESS != err) goto error_recovery; memcpy(bufs[0]->ScatterPages_p->Page_p, sample1, sizeof(sample1)); err = MME_AllocDataBuffer(hdl, sizeof(sample2), MME_ALLOCATION_PHYSICAL, bufs+1); if (MME_SUCCESS != err) goto error_recovery; memcpy(bufs[1]->ScatterPages_p->Page_p, sample2, sizeof(sample2)); err = MME_AllocDataBuffer(hdl, sizeof(sample1), MME_ALLOCATION_PHYSICAL, bufs+2); if (MME_SUCCESS != err) goto error_recovery; /* fill in the non-zero parts of the command structure and issue the command. * * Note that setting constant due times will cause transforms to happen in * strict FIFO order within a transformer (and round-robin within multiple * transformers) */ cmd.CmdCode = MME_TRANSFORM; cmd.CmdEnd = MME_COMMAND_END_RETURN_NOTIFY; cmd.DueTime = 0; cmd.NumberInputBuffers = 2; cmd.NumberOutputBuffers = 1; cmd.DataBuffers_p = bufs; err = MME_SendCommand(hdl, &cmd); if (MME_SUCCESS != err) goto error_recovery; OS_SIGNAL_WAIT(&callbackSignal); /* in normal use we would send many more commands before returning (at which * point the transformer will be terminated. */ /* show the mixed waveform */ printSignal(bufs[2]->ScatterPages_p->Page_p, sizeof(sample1)); /*FALLTHRU*/ error_recovery: if (bufs[0]) (void) MME_FreeDataBuffer(bufs[0]); if (bufs[1]) (void) MME_FreeDataBuffer(bufs[1]); if (bufs[2]) (void) MME_FreeDataBuffer(bufs[2]); return err; }
MME_ERROR acc_MME_SendCommand(MME_TransformerHandle_t Handle, MME_Command_t *CmdInfo_p) { MME_ERROR mme_status; FILE *fcmd = NULL; int i, j, nbuf; if (log_enable == ACC_TRUE) { // log the command; int hdl_idx = handles_search(Handle); fcmd = cmd_log_lock(); FWRITE(cmd_str[CMD_SEND], strlen(cmd_str[CMD_SEND]) + 1, 1, fcmd); FWRITE(&hdl_idx, sizeof(int), 1, fcmd); FWRITE(CmdInfo_p, sizeof(MME_Command_t), 1, fcmd); FWRITE(CmdInfo_p->Param_p, CmdInfo_p->ParamSize, 1, fcmd); // printk("Param: %d\n", ((int*)CmdInfo_p->Param_p)[2]); nbuf = CmdInfo_p->NumberInputBuffers + CmdInfo_p->NumberOutputBuffers; for (i = 0; i < nbuf; i++) { MME_DataBuffer_t *db = CmdInfo_p->DataBuffers_p[i]; MME_ScatterPage_t *sc; FWRITE(db, sizeof(MME_DataBuffer_t), 1, fcmd); if (db->NumberOfScatterPages == 0) { // check whether a buffer is sent without any pages !! should never happen. //acc_warning(ACC_WARNING_NO_SCATTERPAGE_IN_BUFFER); } for (j = 0; j < db->NumberOfScatterPages; j++) { sc = &db->ScatterPages_p[j]; FWRITE(sc, sizeof(MME_ScatterPage_t), 1, fcmd); if (sc->Size != 0) { if (i < CmdInfo_p->NumberInputBuffers) { FWRITE(sc->Page_p, sizeof(unsigned char), sc->Size, fcmd); } } } } } // send the command to get back the ID generated by Multicom mme_status = MME_SendCommand(Handle, CmdInfo_p); if (log_enable == ACC_TRUE) { // replace the ID in the local copy FWRITE(&CmdInfo_p->CmdStatus.CmdId, sizeof(unsigned int), 1, fcmd); cmd_log_release(fcmd); } return mme_status; }
//////////////////////////////////////////////////////////////////////////// /// /// Populate the AUDIO_DECODER's MME_SEND_BUFFERS parameters for SPDIFIN audio. /// Copy some code of codec_mme_base.cpp /// Do not expect any Callback upon completion of this SEND_BUFFER as its /// completion must be synchronous with the TRANSFORM command that contains the /// corresponding decoded buffer. CodecStatus_t Codec_MmeAudioSpdifin_c::FillOutSendBufferCommand(void) { SpdifinAudioCodecDecodeContext_t *Context = (SpdifinAudioCodecDecodeContext_t *)DecodeContext; if (EOF.SentEOFCommand) { CODEC_TRACE("Already sent EOF command - refusing to queue more buffers\n"); return CodecNoError; } // // Initialize the input buffer parameters (we don't actually have much to say here) // memset(&Context->BufferParameters, 0, sizeof(Context->BufferParameters)); // // Zero the reply structure // memset(&Context->BufferStatus, 0, sizeof(Context->BufferStatus)); // // Fill out the actual command // Context->BufferCommand.CmdStatus.AdditionalInfoSize = sizeof(Context->BufferStatus); Context->BufferCommand.CmdStatus.AdditionalInfo_p = (MME_GenericParams_t)(&Context->BufferStatus); Context->BufferCommand.ParamSize = sizeof(Context->BufferParameters); Context->BufferCommand.Param_p = (MME_GenericParams_t)(&Context->BufferParameters); // Feed back will be managed at same time as the return of the corresponding MME_TRANSFORM. Context->BufferCommand.StructSize = sizeof(MME_Command_t); Context->BufferCommand.CmdCode = MME_SEND_BUFFERS; Context->BufferCommand.CmdEnd = MME_COMMAND_END_RETURN_NO_INFO; #ifdef __KERNEL__ flush_cache_all(); #endif MME_ERROR Status = MME_SendCommand(MMEHandle, &Context->BufferCommand); if (Status != MME_SUCCESS) { report(severity_error, "Codec_MmeAudioSpdifin_c::FillOutSendBufferCommand(%s) - Unable to send buffer command (%08x).\n", Configuration.CodecName, Status); return CodecError; } return CodecNoError; }
int mme_user_send_command (mme_user_t *instance, void *arg) { int res = 0; MME_ERROR status = MME_INTERNAL_ERROR; MME_TransformerHandle_t handle; mme_send_command_t *sendCommand = (mme_send_command_t *)arg; mme_user_command_t *intCommand; MME_Command_t* command; mme_user_trans_t *trans; int type, cpuNum, ver, idx; /* Allocate an internal Command desc */ _ICS_OS_ZALLOC(intCommand, sizeof(*intCommand)); if (intCommand == NULL) { status = MME_NOMEM; res = -ENOMEM; goto exit; } /* Get address of embedded MME_Command_t */ command = &intCommand->command; /* Bugzilla 4956 * We set the reference count of this data structure to 2 so that it * will not be freed by on completion until we have done the * copy_to_user() below */ atomic_set(&intCommand->refCount, 2); INIT_LIST_HEAD(&intCommand->list); /* Copy in transformer handle and CommandInfo from userspace */ if (get_user(handle, &(sendCommand->handle)) || get_user(intCommand->userCommand, &(sendCommand->command)) || copy_from_user(command, intCommand->userCommand, sizeof(*command))) { res = -EFAULT; goto errorFreeCmd; } /* Decode the supplied transformer handle */ _MME_DECODE_HDL(handle, type, cpuNum, ver, idx); if (handle == 0 || type != _MME_TYPE_TRANSFORMER || idx >= _MME_TRANSFORMER_INSTANCES) { res = -EINVAL; status = MME_INVALID_HANDLE; goto errorFreeCmd; } /* Get a handle into the local transformer table */ trans = instance->insTrans[idx]; if (trans == NULL) { res = -EINVAL; status = MME_INVALID_HANDLE; goto errorFreeCmd; } if (sizeof(MME_Command_t) != command->StructSize) { res = -EINVAL; status = MME_INVALID_HANDLE; goto errorFreeCmd; } /* Allocate kernel mem for the user private data and copy across */ if (command->Param_p && command->ParamSize) { void* userParam_p = command->Param_p; command->Param_p = _ICS_OS_MALLOC(command->ParamSize); if (NULL == command->Param_p) { status = MME_NOMEM; res = -ENOMEM; goto errorFreeCmd; } if (copy_from_user(command->Param_p, userParam_p, command->ParamSize)) { res = -EFAULT; goto errorFreeParam; } } /* Allocate kernel mem for the AddionalInfo data and copy across */ if (command->CmdStatus.AdditionalInfo_p && command->CmdStatus.AdditionalInfoSize) { /* Need the user address to copy back when the command completes */ intCommand->userAdditionalInfo = command->CmdStatus.AdditionalInfo_p; command->CmdStatus.AdditionalInfo_p = _ICS_OS_MALLOC(command->CmdStatus.AdditionalInfoSize); if (NULL == command->CmdStatus.AdditionalInfo_p) { status = MME_NOMEM; res = -ENOMEM; goto errorFreeParam; } if (copy_from_user(command->CmdStatus.AdditionalInfo_p, intCommand->userAdditionalInfo, command->CmdStatus.AdditionalInfoSize)) { res = -EFAULT; goto errorFree; } } /* Copy in all the data buffer information from userspace */ res = CopyBuffers(command); if (0 != res) { if (-ENOMEM == res) { status = MME_NOMEM; } goto errorFree; } /* * Unless we are using MME_WaitCommand() then we require * the internal Command callback to occur (mme_user_help_callback) */ if (command->CmdEnd != MME_COMMAND_END_RETURN_WAKE) command->CmdEnd = MME_COMMAND_END_RETURN_NOTIFY; /* Call the MME api */ status = MME_SendCommand(handle, command); if (MME_SUCCESS != status) { goto errorFree; } /* Copy the command status structure back - contains command id, state etc */ if (copy_to_user(&(intCommand->userCommand->CmdStatus), &(command->CmdStatus), offsetof(MME_CommandStatus_t, AdditionalInfo_p))) { /* Yuk - need to improve this */ res = -EFAULT; } _ICS_OS_MUTEX_TAKE(&instance->ulock); /* Add to list of currently executing commands */ list_add_tail(&intCommand->list, &trans->issuedCmds); _ICS_OS_MUTEX_RELEASE(&instance->ulock); /* Now call command_free which will * only free the structure when the refCount hits 0 * Command completion will also call it and the winner will * free off the memory */ mme_user_command_free(instance, intCommand); goto exit; errorFree: if (command->CmdStatus.AdditionalInfo_p && command->CmdStatus.AdditionalInfoSize) { _ICS_OS_FREE(command->CmdStatus.AdditionalInfo_p); } errorFreeParam: if (command->Param_p && command->ParamSize) { _ICS_OS_FREE(command->Param_p); } errorFreeCmd: _ICS_OS_FREE(intCommand); exit: /* Write back MME status to caller */ if (put_user(status, &(sendCommand->status))) { res = -EFAULT; } return res; }
CodecStatus_t Codec_MmeAudioSpdifin_c::SendEofCommand() { MME_Command_t *eof = &EOF.Command; if (EOF.SentEOFCommand) { CODEC_TRACE("Already sent EOF command once, refusing to do it again.\n"); return CodecNoError; } EOF.SentEOFCommand = true; // Setup EOF Command :: eof->StructSize = sizeof(MME_Command_t); eof->CmdCode = MME_SEND_BUFFERS; eof->CmdEnd = MME_COMMAND_END_RETURN_NO_INFO; eof->NumberInputBuffers = 1; eof->NumberOutputBuffers = 0; eof->DataBuffers_p = (MME_DataBuffer_t **) &EOF.DataBuffers; eof->ParamSize = sizeof(MME_StreamingBufferParams_t); eof->Param_p = &EOF.Params; // // The following fields were reset during the Class Instantiation :: // //eof->DueTime = 0; //eof->CmdStatus.AdditionalInfoSize = 0; //eof->CmdStatus.AdditionalInfo_p = NULL; // Setup EOF Params EOF.Params.StructSize = sizeof(MME_StreamingBufferParams_t); #if DRV_MULTICOM_AUDIO_DECODER_VERSION >= 0x090128 STREAMING_SET_BUFFER_TYPE(((unsigned int *)&EOF.Params.BufferFlags), STREAMING_DEC_EOF); #else STREAMING_SET_BUFFER_TYPE(EOF.Params.BufferParams, STREAMING_DEC_EOF); #endif // Setup DataBuffer :: EOF.DataBuffers[0] = &EOF.DataBuffer; EOF.DataBuffer.StructSize = sizeof(MME_DataBuffer_t); EOF.DataBuffer.UserData_p = NULL; EOF.DataBuffer.NumberOfScatterPages = 1; EOF.DataBuffer.ScatterPages_p = &EOF.ScatterPage; // // The following fields were reset during the Class Instantiation :: // //eof->DueTime = 0; // immediate. //EOF.DataBuffer.Flags = 0; //EOF.DataBuffer.StreamNumber = 0; //EOF.DataBuffer.TotalSize = 0; //EOF.DataBuffer.StartOffset = 0; // Setup EOF ScatterPage :: // // The following fields were reset during the Class Instantiation :: // //EOF.ScatterPage.Page_p = NULL; //EOF.ScatterPage.Size = 0; //EOF.ScatterPage.BytesUsed = 0; //EOF.ScatterPage.FlagsIn = 0; //EOF.ScatterPage.FlagsOut = 0; MME_ERROR Result = MME_SendCommand(MMEHandle, eof); if (Result != MME_SUCCESS) { CODEC_ERROR("Unable to send eof (%08x).\n", Result); return CodecError; } return CodecNoError; }