diff options
author | Brian Swetland <swetland@google.com> | 2009-10-31 00:22:05 +0100 |
---|---|---|
committer | Daniel Walker <dwalker@codeaurora.org> | 2010-05-12 18:15:21 +0200 |
commit | 34f719b0c25cca6e11164f926fc798c25499aa96 (patch) | |
tree | be4b551d1d7d492a924240858ad822fbc760fbcc /arch/arm/mach-msm | |
parent | [ARM] msm: smd: Update the correct fTAIL pointer after reading from fifo (diff) | |
download | linux-34f719b0c25cca6e11164f926fc798c25499aa96.tar.xz linux-34f719b0c25cca6e11164f926fc798c25499aa96.zip |
msm/qsd: smd: avoid race condition in smd channel allocation
Don't mark a channel as allocated if we failed to allocate it
(perhaps the modem updated one table but not the other, etc)
Signed-off-by: Brian Swetland <swetland@google.com>
Signed-off-by: Daniel Walker <dwalker@codeaurora.org>
Diffstat (limited to 'arch/arm/mach-msm')
-rw-r--r-- | arch/arm/mach-msm/smd.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 3fbba444e99c..34bcc327aa88 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -153,7 +153,7 @@ LIST_HEAD(smd_ch_list_dsp); static unsigned char smd_ch_allocated[64]; static struct work_struct probe_work; -static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type); +static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type); static void smd_channel_probe_worker(struct work_struct *work) { @@ -186,8 +186,8 @@ static void smd_channel_probe_worker(struct work_struct *work) type = shared[n].ctype & SMD_TYPE_MASK; if ((type == SMD_TYPE_APPS_MODEM) || (type == SMD_TYPE_APPS_DSP)) - smd_alloc_channel(shared[n].name, shared[n].cid, ctype); - smd_ch_allocated[n] = 1; + if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype)) + smd_ch_allocated[n] = 1; } } @@ -641,20 +641,20 @@ static int smd_alloc_v1(struct smd_channel *ch) } -static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) +static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) { struct smd_channel *ch; ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL); if (ch == 0) { pr_err("smd_alloc_channel() out of memory\n"); - return; + return -1; } ch->n = cid; if (smd_alloc_v2(ch) && smd_alloc_v1(ch)) { kfree(ch); - return; + return -1; } ch->fifo_mask = ch->fifo_size - 1; @@ -696,6 +696,7 @@ static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) mutex_unlock(&smd_creation_mutex); platform_device_register(&ch->pdev); + return 0; } static void do_nothing_notify(void *priv, unsigned flags) |