aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorBrian Swetland <swetland@google.com>2009-10-30 19:22:05 -0400
committerDaniel Walker <dwalker@codeaurora.org>2010-05-12 12:15:21 -0400
commit34f719b0c25cca6e11164f926fc798c25499aa96 (patch)
treebe4b551d1d7d492a924240858ad822fbc760fbcc /arch/arm
parent7632fba05197999fb0d24776b567682ebd62f62a (diff)
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')
-rw-r--r--arch/arm/mach-msm/smd.c13
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);
153static unsigned char smd_ch_allocated[64]; 153static unsigned char smd_ch_allocated[64];
154static struct work_struct probe_work; 154static struct work_struct probe_work;
155 155
156static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type); 156static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type);
157 157
158static void smd_channel_probe_worker(struct work_struct *work) 158static void smd_channel_probe_worker(struct work_struct *work)
159{ 159{
@@ -186,8 +186,8 @@ static void smd_channel_probe_worker(struct work_struct *work)
186 type = shared[n].ctype & SMD_TYPE_MASK; 186 type = shared[n].ctype & SMD_TYPE_MASK;
187 if ((type == SMD_TYPE_APPS_MODEM) || 187 if ((type == SMD_TYPE_APPS_MODEM) ||
188 (type == SMD_TYPE_APPS_DSP)) 188 (type == SMD_TYPE_APPS_DSP))
189 smd_alloc_channel(shared[n].name, shared[n].cid, ctype); 189 if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype))
190 smd_ch_allocated[n] = 1; 190 smd_ch_allocated[n] = 1;
191 } 191 }
192} 192}
193 193
@@ -641,20 +641,20 @@ static int smd_alloc_v1(struct smd_channel *ch)
641} 641}
642 642
643 643
644static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) 644static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type)
645{ 645{
646 struct smd_channel *ch; 646 struct smd_channel *ch;
647 647
648 ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL); 648 ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL);
649 if (ch == 0) { 649 if (ch == 0) {
650 pr_err("smd_alloc_channel() out of memory\n"); 650 pr_err("smd_alloc_channel() out of memory\n");
651 return; 651 return -1;
652 } 652 }
653 ch->n = cid; 653 ch->n = cid;
654 654
655 if (smd_alloc_v2(ch) && smd_alloc_v1(ch)) { 655 if (smd_alloc_v2(ch) && smd_alloc_v1(ch)) {
656 kfree(ch); 656 kfree(ch);
657 return; 657 return -1;
658 } 658 }
659 659
660 ch->fifo_mask = ch->fifo_size - 1; 660 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)
696 mutex_unlock(&smd_creation_mutex); 696 mutex_unlock(&smd_creation_mutex);
697 697
698 platform_device_register(&ch->pdev); 698 platform_device_register(&ch->pdev);
699 return 0;
699} 700}
700 701
701static void do_nothing_notify(void *priv, unsigned flags) 702static void do_nothing_notify(void *priv, unsigned flags)