Title: [6732] trunk/drivers/char/bfin-dma.c: use atomic status field to prevent multiple progs from freeing the dmas at the same time
- Revision
- 6732
- Author
- vapier
- Date
- 2009-06-16 00:34:10 -0500 (Tue, 16 Jun 2009)
Log Message
use atomic status field to prevent multiple progs from freeing the dmas at the same time
Modified Paths
Diff
Modified: trunk/drivers/char/bfin-dma.c (6731 => 6732)
--- trunk/drivers/char/bfin-dma.c 2009-06-16 03:49:39 UTC (rev 6731)
+++ trunk/drivers/char/bfin-dma.c 2009-06-16 05:34:10 UTC (rev 6732)
@@ -18,6 +18,7 @@
#include <linux/types.h>
#include <linux/uaccess.h>
+#include <asm/atomic.h>
#include <asm/blackfin.h>
#include <asm/cacheflush.h>
#include <asm/dma.h>
@@ -45,7 +46,7 @@
/*** User space interface: END ***/
struct dma_state {
- bool ours;
+ atomic_t status;
unsigned int chan_src, chan_dst;
struct dmasg dsc_src, dsc_dst;
volatile int *user_done;
@@ -121,7 +122,7 @@
stampit();
- if (state->ours)
+ if (atomic_read(&state->status))
return -EBUSY;
ret = request_dma(state->chan_src, DRIVER_NAME);
@@ -134,9 +135,9 @@
if (ret)
goto err_free_2;
- state->ours = true;
state->user_done = &ustate->done;
init_completion(&state->c);
+ atomic_set(&state->status, 1);
return 0;
@@ -154,9 +155,13 @@
static int bdi_free_dma(struct dma_state *state)
{
stampit();
+ if (atomic_inc_return(&state->status) != 2) {
+ atomic_dec(&state->status);
+ return -EBUSY;
+ }
free_dma(state->chan_src);
free_dma(state->chan_dst);
- state->ours = false;
+ atomic_sub(2, &state->status);
return 0;
}
@@ -171,7 +176,7 @@
stampit();
- if (!state->ours)
+ if (!atomic_read(&state->status))
return -EINVAL;
/* Anomaly 05000301 notes:
@@ -247,7 +252,7 @@
/* Make sure we've allocated the channel before doing anything */
if (cmd != BF_DMA_REQUEST) {
- if (!state->ours)
+ if (!atomic_read(&state->status))
return -EINVAL;
if (copy_from_user(&state->dsc_src, &ustate->dsc_src, sizeof(state->dsc_dst)))
return -EFAULT;
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits