diff options
author | Ionut Nicu <ionut.nicu@gmail.com> | 2010-11-05 13:01:50 -0400 |
---|---|---|
committer | Omar Ramirez Luna <omar.ramirez@ti.com> | 2011-02-04 21:11:24 -0500 |
commit | 74c2d1f63f6fff26503f538ddacf0e45feb15f0d (patch) | |
tree | dccf4dc5836c0293548c837faa2123d37b422ff4 /drivers/staging/tidspbridge | |
parent | 59403c21afdcd2e89aeadc73b99ccd82d32733b3 (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.c | 78 |
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 | } | ||
243 | func_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) | |||
1714 | int bridge_io_get_proc_load(struct io_mgr *hio_mgr, | 1693 | int 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 = |