diff options
author | Alexandre Bounine <alexandre.bounine@idt.com> | 2016-08-02 17:06:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-02 19:35:36 -0400 |
commit | 06e1b2497ca4783f5f9997b09c77d93aeea69ec1 (patch) | |
tree | 7e94d59bf473eefd309b926f930e9de91670976e | |
parent | f5485eb0b6eb8a3e5841cfea34a930822f7252bc (diff) |
rapidio: fix error handling in mbox request/release functions
Add checking for error code returned by HW-specific mbox open routines.
Ensure that resources are properly release if failed.
This patch is applicable to kernel versions starting from v2.6.15.
Link: http://lkml.kernel.org/r/1469125134-16523-9-git-send-email-alexandre.bounine@idt.com
Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Andre van Herk <andre.van.herk@prodrive-technologies.com>
Cc: Barry Wood <barry.wood@idt.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/rapidio/rio.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 840802943dc0..1cd32603259f 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -268,6 +268,12 @@ int rio_request_inb_mbox(struct rio_mport *mport, | |||
268 | mport->inb_msg[mbox].mcback = minb; | 268 | mport->inb_msg[mbox].mcback = minb; |
269 | 269 | ||
270 | rc = mport->ops->open_inb_mbox(mport, dev_id, mbox, entries); | 270 | rc = mport->ops->open_inb_mbox(mport, dev_id, mbox, entries); |
271 | if (rc) { | ||
272 | mport->inb_msg[mbox].mcback = NULL; | ||
273 | mport->inb_msg[mbox].res = NULL; | ||
274 | release_resource(res); | ||
275 | kfree(res); | ||
276 | } | ||
271 | } else | 277 | } else |
272 | rc = -ENOMEM; | 278 | rc = -ENOMEM; |
273 | 279 | ||
@@ -285,13 +291,22 @@ int rio_request_inb_mbox(struct rio_mport *mport, | |||
285 | */ | 291 | */ |
286 | int rio_release_inb_mbox(struct rio_mport *mport, int mbox) | 292 | int rio_release_inb_mbox(struct rio_mport *mport, int mbox) |
287 | { | 293 | { |
288 | if (mport->ops->close_inb_mbox) { | 294 | int rc; |
289 | mport->ops->close_inb_mbox(mport, mbox); | ||
290 | 295 | ||
291 | /* Release the mailbox resource */ | 296 | if (!mport->ops->close_inb_mbox || !mport->inb_msg[mbox].res) |
292 | return release_resource(mport->inb_msg[mbox].res); | 297 | return -EINVAL; |
293 | } else | 298 | |
294 | return -ENOSYS; | 299 | mport->ops->close_inb_mbox(mport, mbox); |
300 | mport->inb_msg[mbox].mcback = NULL; | ||
301 | |||
302 | rc = release_resource(mport->inb_msg[mbox].res); | ||
303 | if (rc) | ||
304 | return rc; | ||
305 | |||
306 | kfree(mport->inb_msg[mbox].res); | ||
307 | mport->inb_msg[mbox].res = NULL; | ||
308 | |||
309 | return 0; | ||
295 | } | 310 | } |
296 | 311 | ||
297 | /** | 312 | /** |
@@ -336,6 +351,12 @@ int rio_request_outb_mbox(struct rio_mport *mport, | |||
336 | mport->outb_msg[mbox].mcback = moutb; | 351 | mport->outb_msg[mbox].mcback = moutb; |
337 | 352 | ||
338 | rc = mport->ops->open_outb_mbox(mport, dev_id, mbox, entries); | 353 | rc = mport->ops->open_outb_mbox(mport, dev_id, mbox, entries); |
354 | if (rc) { | ||
355 | mport->outb_msg[mbox].mcback = NULL; | ||
356 | mport->outb_msg[mbox].res = NULL; | ||
357 | release_resource(res); | ||
358 | kfree(res); | ||
359 | } | ||
339 | } else | 360 | } else |
340 | rc = -ENOMEM; | 361 | rc = -ENOMEM; |
341 | 362 | ||
@@ -353,13 +374,22 @@ int rio_request_outb_mbox(struct rio_mport *mport, | |||
353 | */ | 374 | */ |
354 | int rio_release_outb_mbox(struct rio_mport *mport, int mbox) | 375 | int rio_release_outb_mbox(struct rio_mport *mport, int mbox) |
355 | { | 376 | { |
356 | if (mport->ops->close_outb_mbox) { | 377 | int rc; |
357 | mport->ops->close_outb_mbox(mport, mbox); | ||
358 | 378 | ||
359 | /* Release the mailbox resource */ | 379 | if (!mport->ops->close_outb_mbox || !mport->outb_msg[mbox].res) |
360 | return release_resource(mport->outb_msg[mbox].res); | 380 | return -EINVAL; |
361 | } else | 381 | |
362 | return -ENOSYS; | 382 | mport->ops->close_outb_mbox(mport, mbox); |
383 | mport->outb_msg[mbox].mcback = NULL; | ||
384 | |||
385 | rc = release_resource(mport->outb_msg[mbox].res); | ||
386 | if (rc) | ||
387 | return rc; | ||
388 | |||
389 | kfree(mport->outb_msg[mbox].res); | ||
390 | mport->outb_msg[mbox].res = NULL; | ||
391 | |||
392 | return 0; | ||
363 | } | 393 | } |
364 | 394 | ||
365 | /** | 395 | /** |