static void bridge_load_firmware(void) { struct PROCESS_CONTEXT pr_ctxt; DSP_STATUS status; const char *argv[2]; argv[0] = firmware_file; argv[1] = NULL; pr_ctxt.hProcessor = NULL; status = PROC_Attach(0, NULL, &pr_ctxt.hProcessor, &pr_ctxt); if (DSP_FAILED(status)) goto func_err; status = PROC_Stop(pr_ctxt.hProcessor); if (DSP_FAILED(status)) goto func_err; status = PROC_Load(pr_ctxt.hProcessor, 1, argv, NULL); if (DSP_FAILED(status)) goto func_err; status = PROC_Start(pr_ctxt.hProcessor); if (DSP_FAILED(status)) goto func_err; status = PROC_Detach(&pr_ctxt); if (DSP_SUCCEEDED(status)) { pr_info("DSP recovery succeeded\n"); return; } func_err: pr_err("DSP could not be restarted, status = %x\n", status); }
/* * ======== PROCWRAP_Stop ======== */ u32 PROCWRAP_Stop(union Trapped_Args *args, void *pr_ctxt) { u32 retVal; GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Stop: entered\n"); retVal = PROC_Stop(args->ARGS_PROC_STOP.hProcessor); return retVal; }
/* * ======== procDelete ======== */ static Void procDelete(Processor_Handle proc) { DSP_STATUS status = DSP_SOK; GT_1trace(curTrace, GT_ENTER, "Processor_delete_d> Enter (proc=0x%x)\n", proc); if (proc == NULL) { goto procDelete_return; } /* * Disconnect the Power transport to the DSP */ if (proc->connected) { Power_disconnect(proc->powerHandle); proc->connected = FALSE; } /* if not using LAD: close tranport and stop DSP, detach, destroy */ if (!Global_useLinkArbiter) { /* * Close the remote transport */ GT_0trace(curTrace, GT_2CLASS, "Processor_delete_d> " "Closing remote transport...\n"); status = MSGQ_TransportClose(proc->cpuId); if (!DSP_SUCCEEDED(status)) { GT_1trace(curTrace, GT_6CLASS, "Processor_delete_d> " "Closing remote transport FAILED, status=0x%x.\n", status); } /* * Stop execution on DSP */ GT_0trace(curTrace, GT_2CLASS, "Processor_delete_d> " "Stopping DSP...\n"); status = PROC_Stop(proc->cpuId); if (!DSP_SUCCEEDED(status)) { GT_1trace(curTrace, GT_6CLASS, "Processor_delete_d> " "Stopping DSP FAILED, status=0x%x\n", status); } } #ifdef WIN32 if (!Global_useLinkArbiter) { #endif /* * Close the CE pool */ GT_0trace(curTrace, GT_2CLASS, "Processor_delete_d> " "Closing pool...\n"); status = POOL_Close(Global_cePoolId); if (!DSP_SUCCEEDED(status)) { GT_1trace(curTrace, GT_6CLASS, "Processor_delete_d> " "Closing pool FAILED, status=0x%x\n", status); } #ifdef WIN32 } #endif /* if not using LAD: detach and destroy */ if (!Global_useLinkArbiter) { /* * Detach from the processor */ GT_0trace(curTrace, GT_2CLASS, "Processor_delete_d> " "Detaching from DSP...\n"); status = PROC_Detach(proc->cpuId); if (!DSP_SUCCEEDED(status)) { GT_1trace(curTrace, GT_6CLASS, "Processor_delete_d> " "Detaching from DSP FAILED, status=0x%x\n", status); } /* * Destroy the PROC object */ GT_0trace(curTrace, GT_2CLASS, "Processor_delete_d> " "Destroying DSP... (object, that is)\n"); status = PROC_Destroy(); if (!DSP_SUCCEEDED(status)) { GT_1trace(curTrace, GT_6CLASS, "Processor_delete_d> " "Destroying DSP FAILED, status=0x%x\n", status); } } /* else, if using LAD: release DSP, disconnect, detach */ else { #ifndef WIN32 /* * Detach from DSP to allow Link cleanup */ GT_0trace(curTrace, GT_2CLASS, "Processor_delete_d> " "Detaching before LAD_releaseDsp...\n"); status = PROC_Detach(proc->cpuId); if (!DSP_SUCCEEDED(status)) { GT_1trace(curTrace, GT_6CLASS, "Processor_delete_d> " "Detaching from DSP FAILED, status=0x%x\n", status); } #endif /* * Release DSP */ GT_0trace(curTrace, GT_2CLASS, "Processor_delete_d> " "Releasing DSP via LAD_releaseDsp...\n"); ladStatus = LAD_releaseDsp(handle); if ((ladStatus != LAD_SUCCESS) && (ladStatus != LAD_STILLRUNNING)) { GT_1trace(curTrace, GT_6CLASS, "Processor_delete_d> " "LAD_releaseDsp FAILED, status=0x%x\n", ladStatus); } /* * Disconnect from LAD */ GT_0trace(curTrace, GT_2CLASS, "Processor_delete_d> " "Disconnecting from LAD...\n"); ladStatus = LAD_disconnect(handle); if (ladStatus != LAD_SUCCESS) { GT_1trace(curTrace, GT_6CLASS, "Processor_delete_d> " "LAD_disconnect FAILED, status=0x%x\n", ladStatus); } } if (proc->powerHandle != NULL) { Power_off(proc->powerHandle); proc->powerHandle = NULL; } /* if not using LAD: free memory alloc'd during create */ if (!Global_useLinkArbiter) { /* free up space allocated to modify the config table */ if (ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->memTables[0] != NULL) { Memory_free( ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->memTables[0], 0 /* this should be actual size, but hate to * add one more global variable and we know * on Linux free doesn't require size */, NULL); } } procDelete_return: GT_0trace(curTrace, GT_ENTER, "Processor_delete_d> return\n"); }
/* * ======== LAD_releaseDsp ======== */ LAD_Status LAD_releaseDsp(LAD_ClientHandle handle) { Bool setupDSP = FALSE; /* PROC_Setup called */ Bool attachedDSP = FALSE; /* PROC_Attach called */ Bool poolsOpenedDSP = FALSE; /* pools have been opened */ Bool dspRunning = FALSE; /* PROC_Start called */ Bool transportOpenedDSP = FALSE; /* MSGQ transport opened */ Int clientId = (Int)handle; DWORD waitStatus; LadRegData ladData; DSP_STATUS linkStatus = DSP_SOK; LAD_Status status = LAD_SUCCESS; /* sanity check args */ if ((clientId >= LAD_MAXNUMCLIENTS) || (clientId < 0)) { PRINTVERBOSE1("LAD_releaseDsp: Invalid clientId [%d]!\n", clientId); return (LAD_INVALIDARG); } /* check for initialization and connection */ if ((refCount <= 0) || (clientInfo[clientId].connectedToLAD == FALSE)) { PRINTVERBOSE0("LAD_releaseDsp: Client not connected!\n"); return (LAD_NOTCONNECTED); } /* if this client not connected nor started say denied */ if (!clientConnected[clientId] || !clientStarted[clientId]) { // TODO: Figure out what to do with this. //return (LAD_ACCESSDENIED); } /* Enter critical section */ waitStatus = WaitForSingleObject(_LAD_mutex, TIMEOUT); if (waitStatus != WAIT_OBJECT_0) { if (waitStatus == WAIT_TIMEOUT) { PRINTVERBOSE0("LAD_releaseDsp: WaitForSingleObject() timed out\n"); status = LAD_FAILURE; } else { PRINTVERBOSE0("LAD_releaseDsp: WaitForSingleObject() failed!\n"); status = LAD_FAILURE; } } if (status == LAD_SUCCESS) { /* * Get number of clients, link config ID, DSP status from registry. */ status = getLadRegData(&ladData, LadKey_NUMCLIENTSSTARTED | LadKey_LINKCONFIGID | LadKey_DSPSTATUS); if (status != LAD_SUCCESS) { PRINTVERBOSE0("\nLAD_releaseDsp: getLadRegData() failed\n"); goto failedLinkShutdown; } ladData.numClientsStarted--; /* Write numClientsStarted to registry */ status = setLadRegData(&ladData, LadKey_NUMCLIENTSSTARTED); if (status != LAD_SUCCESS) { PRINTVERBOSE0("\nLAD_releaseDsp: setLadRegData() failed\n"); goto failedLinkShutdown; } /* Last release must stop the DSP. */ if ((status == LAD_SUCCESS) && (ladData.numClientsStarted == 0)) { if (ladData.dspStatus & DspStatus_TRANSPORTOPEND) { linkStatus = MSGQ_TransportClose(clientCpu[clientId]); if (linkStatus == DSP_SCLOSED) { ladData.dspStatus &= ~DspStatus_TRANSPORTOPEND; } else { PRINTVERBOSE1("\nMSGQ_TransportClose FAILED 0x%lx", linkStatus); status = LAD_FAILURE; goto failedLinkShutdown; } } /* STOP DSP */ if (ladData.dspStatus & DspStatus_RUNNING) { linkStatus = PROC_Stop(clientCpu[clientId]); if (linkStatus == DSP_SSTOPPED) { ladData.dspStatus &= ~DspStatus_RUNNING; PRINTVERBOSE0("\n PROC_Stop - OK"); } else { PRINTVERBOSE1("\n PROC_Stop FAILED 0x%lx", linkStatus); status = LAD_FAILURE; goto failedLinkShutdown; } } /* CLOSE POOLS */ if (ladData.dspStatus & DspStatus_POOLSOPENED) { linkStatus = _LAD_closeAllPools(ladData.linkConfigId); if (linkStatus == DSP_SCLOSED) { ladData.dspStatus &= ~DspStatus_POOLSOPENED; PRINTVERBOSE0("\n POOL_Close - OK"); } else { PRINTVERBOSE1("\n POOL_Close FAILED 0x%lx", linkStatus); status = LAD_FAILURE; goto failedLinkShutdown; } } /* DETACH FROM DSP */ if (ladData.dspStatus & DspStatus_ATTACHED) { linkStatus = PROC_Detach(clientCpu[clientId]); if (linkStatus == DSP_SDETACHED) { ladData.dspStatus &= ~DspStatus_ATTACHED; PRINTVERBOSE0("\n PROC_Detach - OK"); } else { PRINTVERBOSE1("\n PROC_Detach FAILED 0x%lx", linkStatus); status = LAD_FAILURE; goto failedLinkShutdown; } } /* "DESTROY" DSP */ if (ladData.dspStatus & DspStatus_SETUP) { linkStatus = PROC_Destroy(); if (linkStatus == DSP_SDESTROYED) { ladData.dspStatus &= ~DspStatus_SETUP; PRINTVERBOSE0("\n PROC_Destroy - OK"); } else { PRINTVERBOSE1("\n PROC_Destroy FAILED 0x%lx", linkStatus); status = LAD_FAILURE; goto failedLinkShutdown; } } status = LAD_SUCCESS; } else { /* This is not the last client */ status = LAD_STILLRUNNING; } } failedLinkShutdown: if ((ladData.numClientsStarted == 0) && (ladData.dspStatus !=(UInt32)-1)) { /* Write the updated DSP status to the registry */ setLadRegData(&ladData, LadKey_DSPSTATUS); } if (waitStatus == WAIT_OBJECT_0) { ReleaseMutex(_LAD_mutex); } /* clear LAD startup flag for this client */ if ((status == LAD_SUCCESS) || (status == LAD_STILLRUNNING)) { clientInfo[clientId].startedOK = FALSE; } return (status); }