aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/tidspbridge
diff options
context:
space:
mode:
authorIonut Nicu <ionut.nicu@gmail.com>2010-11-05 13:01:50 -0400
committerOmar Ramirez Luna <omar.ramirez@ti.com>2011-02-04 21:11:24 -0500
commit74c2d1f63f6fff26503f538ddacf0e45feb15f0d (patch)
treedccf4dc5836c0293548c837faa2123d37b422ff4 /drivers/staging/tidspbridge
parent59403c21afdcd2e89aeadc73b99ccd82d32733b3 (diff)
staging: tidspbridge: fix kernel oops in bridge_io_get_proc_load
The DSP shared memory area gets initialized only when a COFF file is loaded. If bridge_io_get_proc_load is called before loading a base image into the DSP, the shared_mem member of the io manager will be NULL, resulting in a kernel oops when it's dereferenced. Also made some coding style changes to bridge_io_create. Signed-off-by: Ionut Nicu <ionut.nicu@mindbit.ro> Signed-off-by: Omar Ramirez Luna <omar.ramirez@ti.com>
Diffstat (limited to 'drivers/staging/tidspbridge')
-rw-r--r--drivers/staging/tidspbridge/core/io_sm.c78
1 files changed, 30 insertions, 48 deletions
diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c
index 27e0aa81a58..9cea3eacf1a 100644
--- a/drivers/staging/tidspbridge/core/io_sm.c
+++ b/drivers/staging/tidspbridge/core/io_sm.c
@@ -167,57 +167,41 @@ int bridge_io_create(struct io_mgr **io_man,
167 struct dev_object *hdev_obj, 167 struct dev_object *hdev_obj,
168 const struct io_attrs *mgr_attrts) 168 const struct io_attrs *mgr_attrts)
169{ 169{
170 int status = 0;
171 struct io_mgr *pio_mgr = NULL; 170 struct io_mgr *pio_mgr = NULL;
172 struct shm *shared_mem = NULL;
173 struct bridge_dev_context *hbridge_context = NULL; 171 struct bridge_dev_context *hbridge_context = NULL;
174 struct cfg_devnode *dev_node_obj; 172 struct cfg_devnode *dev_node_obj;
175 struct chnl_mgr *hchnl_mgr; 173 struct chnl_mgr *hchnl_mgr;
176 u8 dev_type; 174 u8 dev_type;
177 175
178 /* Check requirements */ 176 /* Check requirements */
179 if (!io_man || !mgr_attrts || mgr_attrts->word_size == 0) { 177 if (!io_man || !mgr_attrts || mgr_attrts->word_size == 0)
180 status = -EFAULT; 178 return -EFAULT;
181 goto func_end; 179
182 } 180 *io_man = NULL;
181
183 dev_get_chnl_mgr(hdev_obj, &hchnl_mgr); 182 dev_get_chnl_mgr(hdev_obj, &hchnl_mgr);
184 if (!hchnl_mgr || hchnl_mgr->hio_mgr) { 183 if (!hchnl_mgr || hchnl_mgr->hio_mgr)
185 status = -EFAULT; 184 return -EFAULT;
186 goto func_end; 185
187 }
188 /* 186 /*
189 * Message manager will be created when a file is loaded, since 187 * Message manager will be created when a file is loaded, since
190 * size of message buffer in shared memory is configurable in 188 * size of message buffer in shared memory is configurable in
191 * the base image. 189 * the base image.
192 */ 190 */
193 dev_get_bridge_context(hdev_obj, &hbridge_context); 191 dev_get_bridge_context(hdev_obj, &hbridge_context);
194 if (!hbridge_context) { 192 if (!hbridge_context)
195 status = -EFAULT; 193 return -EFAULT;
196 goto func_end; 194
197 }
198 dev_get_dev_type(hdev_obj, &dev_type); 195 dev_get_dev_type(hdev_obj, &dev_type);
199 /*
200 * DSP shared memory area will get set properly when
201 * a program is loaded. They are unknown until a COFF file is
202 * loaded. I chose the value -1 because it was less likely to be
203 * a valid address than 0.
204 */
205 shared_mem = (struct shm *)-1;
206 196
207 /* Allocate IO manager object */ 197 /* Allocate IO manager object */
208 pio_mgr = kzalloc(sizeof(struct io_mgr), GFP_KERNEL); 198 pio_mgr = kzalloc(sizeof(struct io_mgr), GFP_KERNEL);
209 if (pio_mgr == NULL) { 199 if (!pio_mgr)
210 status = -ENOMEM; 200 return -ENOMEM;
211 goto func_end;
212 }
213 201
214 /* Initialize chnl_mgr object */ 202 /* Initialize chnl_mgr object */
215#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
216 pio_mgr->pmsg = NULL;
217#endif
218 pio_mgr->hchnl_mgr = hchnl_mgr; 203 pio_mgr->hchnl_mgr = hchnl_mgr;
219 pio_mgr->word_size = mgr_attrts->word_size; 204 pio_mgr->word_size = mgr_attrts->word_size;
220 pio_mgr->shared_mem = shared_mem;
221 205
222 if (dev_type == DSP_UNIT) { 206 if (dev_type == DSP_UNIT) {
223 /* Create an IO DPC */ 207 /* Create an IO DPC */
@@ -229,29 +213,24 @@ int bridge_io_create(struct io_mgr **io_man,
229 213
230 spin_lock_init(&pio_mgr->dpc_lock); 214 spin_lock_init(&pio_mgr->dpc_lock);
231 215
232 status = dev_get_dev_node(hdev_obj, &dev_node_obj); 216 if (dev_get_dev_node(hdev_obj, &dev_node_obj)) {
217 bridge_io_destroy(pio_mgr);
218 return -EIO;
219 }
233 } 220 }
234 221
235 if (!status) { 222 pio_mgr->hbridge_context = hbridge_context;
236 pio_mgr->hbridge_context = hbridge_context; 223 pio_mgr->shared_irq = mgr_attrts->irq_shared;
237 pio_mgr->shared_irq = mgr_attrts->irq_shared; 224 if (dsp_wdt_init()) {
238 if (dsp_wdt_init())
239 status = -EPERM;
240 } else {
241 status = -EIO;
242 }
243func_end:
244 if (status) {
245 /* Cleanup */
246 bridge_io_destroy(pio_mgr); 225 bridge_io_destroy(pio_mgr);
247 if (io_man) 226 return -EPERM;
248 *io_man = NULL;
249 } else {
250 /* Return IO manager object to caller... */
251 hchnl_mgr->hio_mgr = pio_mgr;
252 *io_man = pio_mgr;
253 } 227 }
254 return status; 228
229 /* Return IO manager object to caller... */
230 hchnl_mgr->hio_mgr = pio_mgr;
231 *io_man = pio_mgr;
232
233 return 0;
255} 234}
256 235
257/* 236/*
@@ -1714,6 +1693,9 @@ int io_sh_msetting(struct io_mgr *hio_mgr, u8 desc, void *pargs)
1714int bridge_io_get_proc_load(struct io_mgr *hio_mgr, 1693int bridge_io_get_proc_load(struct io_mgr *hio_mgr,
1715 struct dsp_procloadstat *proc_lstat) 1694 struct dsp_procloadstat *proc_lstat)
1716{ 1695{
1696 if (!hio_mgr->shared_mem)
1697 return -EFAULT;
1698
1717 proc_lstat->curr_load = 1699 proc_lstat->curr_load =
1718 hio_mgr->shared_mem->load_mon_info.curr_dsp_load; 1700 hio_mgr->shared_mem->load_mon_info.curr_dsp_load;
1719 proc_lstat->predicted_load = 1701 proc_lstat->predicted_load =