Audio: sst: Prevents concurrent access to firmware download code
authorOmair Mohammed Abdullah <omair.m.abdullah@intel.com>
Wed, 12 Oct 2011 10:52:34 +0000 (16:22 +0530)
committerbuildbot <buildbot@intel.com>
Tue, 24 Jan 2012 10:34:58 +0000 (02:34 -0800)
BZ: 20940

OldBZ:9443

The code to download firmware can be accessed by more than one thread at a time
leading to panic. Proper locking along with a new sst state (firmware starting
to download) prevents this. (Ported to gb-stable)

Change-Id: Ic56e3bfd68cf89c2b8937a572a70f01b80e3b27e
Old-Change-Id: I16ef33e6ed26407ffe2e7c7693976ce1ec8e09cb
Signed-off-by: Omair Mohammed Abdullah <omair.m.abdullah@intel.com>
Reviewed-on: http://android.intel.com:8080/32721
Reviewed-by: M, Arulselvan <arulselvan.m@intel.com>
Tested-by: M, Arulselvan <arulselvan.m@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
sound/pci/sst/intel_sst.c
sound/pci/sst/intel_sst_app_interface.c
sound/pci/sst/intel_sst_drv_interface.c
sound/pci/sst/intel_sst_ipc.c

index 1a79083..1b6712d 100644 (file)
@@ -307,9 +307,7 @@ static int __devinit intel_sst_probe(struct pci_dev *pci,
                goto do_unmap_iram;
        pr_debug("DRAM Ptr %p\n", sst_drv_ctx->dram);
 
-       mutex_lock(&sst_drv_ctx->sst_lock);
-       sst_drv_ctx->sst_state = SST_UN_INIT;
-       mutex_unlock(&sst_drv_ctx->sst_lock);
+       sst_set_fw_state_locked(sst_drv_ctx, SST_UN_INIT);
        /* Register the ISR */
        ret = request_irq(pci->irq, intel_sst_interrupt,
                IRQF_SHARED, SST_DRV_NAME, sst_drv_ctx);
@@ -414,9 +412,7 @@ static void __devexit intel_sst_remove(struct pci_dev *pci)
        pm_runtime_get_noresume(&pci->dev);
        pm_runtime_forbid(&pci->dev);
        pci_dev_put(sst_drv_ctx->pci);
-       mutex_lock(&sst_drv_ctx->sst_lock);
-       sst_drv_ctx->sst_state = SST_UN_INIT;
-       mutex_unlock(&sst_drv_ctx->sst_lock);
+       sst_set_fw_state_locked(sst_drv_ctx, SST_UN_INIT);
        misc_deregister(&lpe_ctrl);
        free_irq(pci->irq, sst_drv_ctx);
        iounmap(sst_drv_ctx->dram);
@@ -582,9 +578,7 @@ static int intel_sst_runtime_resume(struct device *dev)
        sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr);
 
        intel_sst_set_pll(true, SST_PLL_AUDIO);
-       mutex_lock(&sst_drv_ctx->sst_lock);
-       sst_drv_ctx->sst_state = SST_UN_INIT;
-       mutex_unlock(&sst_drv_ctx->sst_lock);
+       sst_set_fw_state_locked(sst_drv_ctx, SST_UN_INIT);
        return 0;
 }
 
index 240258e..2fe916b 100644 (file)
@@ -61,18 +61,25 @@ static int intel_sst_check_device(void)
 {
        int retval = 0;
 
+
+       mutex_lock(&sst_drv_ctx->sst_lock);
        if (sst_drv_ctx->sst_state == SST_UN_INIT) {
                sst_drv_ctx->sst_state = SST_START_INIT;
+               mutex_unlock(&sst_drv_ctx->sst_lock);
                /* FW is not downloaded */
                retval = sst_download_fw();
-               if (retval)
+               if (retval) {
+                       sst_set_fw_state_locked(sst_drv_ctx, SST_UN_INIT);
                        return -ENODEV;
+               }
                if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
                        retval = sst_drv_ctx->rx_time_slot_status;
                        if (retval != RX_TIMESLOT_UNINIT
                                        && sst_drv_ctx->pmic_vendor != SND_NC)
                                sst_enable_rx_timeslot(retval);
                }
+       } else {
+               mutex_unlock(&sst_drv_ctx->sst_lock);
        }
        return 0;
 }
index 46f3d93..7ffdfe7 100644 (file)
@@ -89,9 +89,14 @@ int sst_download_fw(void)
 {
        int retval;
 
+       char name[20];
+
        if (sst_drv_ctx->sst_state != SST_START_INIT)
                return -EAGAIN;
 
+       snprintf(name, sizeof(name), "%s%04x%s", "fw_sst_",
+                                       sst_drv_ctx->pci_id, ".bin");
+
        retval = sst_request_fw();
        if (retval)
                return retval;
@@ -323,8 +328,8 @@ void sst_prepare_fw(void)
                pr_debug("DSP Downloading FW now...\n");
                retval = sst_download_fw();
                if (retval) {
-                       pr_err("FW download fail %x\n", retval);
-                       pr_debug("doing rtpm_put\n");
+                       pr_err("sst: FW download fail %x\n", retval);
+                       pr_debug("sst: doing rtpm_put\n");
                        sst_set_fw_state_locked(sst_drv_ctx, SST_UN_INIT);
                        pm_runtime_put(&sst_drv_ctx->pci->dev);
                }
@@ -406,8 +411,8 @@ static int sst_open_pcm_stream(struct snd_sst_params *str_param)
                pr_debug("DSP Downloading FW now...\n");
                retval = sst_download_fw();
                if (retval) {
-                       pr_err("FW download fail %x, abort\n", retval);
-                       pr_debug("open_pcm, doing rtpm_put\n");
+                       pr_err("sst: FW download fail %x, abort\n", retval);
+                       pr_debug("sst: open_pcm, doing rtpm_put\n");
                        sst_set_fw_state_locked(sst_drv_ctx, SST_UN_INIT);
                        pm_runtime_put(&sst_drv_ctx->pci->dev);
                        return retval;
index d5c894b..65aa0d5 100644 (file)
@@ -169,8 +169,8 @@ static int process_fw_init(struct sst_ipc_msg_wq *msg)
        pr_debug("*** FW Init msg came***\n");
        if (init->result) {
                sst_set_fw_state_locked(sst_drv_ctx, SST_ERROR);
-               pr_debug("FW Init failed, Error %x\n", init->result);
-               pr_err("FW Init failed, Error %x\n", init->result);
+               pr_debug("sst: FW Init failed, Error %x\n", init->result);
+               pr_err("sst: FW Init failed, Error %x\n", init->result);
                retval = -init->result;
                return retval;
        }