summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/cell/spufs/file.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-08 09:31:42 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-08 09:31:42 -0800
commitdde0013782dbd09e1cc68ca03860f3a62b03cb34 (patch)
tree5be40012944c0fab834a385f2410eaa60e2b0d6e /arch/powerpc/platforms/cell/spufs/file.c
parentf3aafa6c2535d36542a6dfc8647cd2fdb5999648 (diff)
parenta99824f327c748b2753f4fa570eb1fefcd6a9c4d (diff)
Merge branch 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: [POWERPC] Add arch-specific walk_memory_remove() for 64-bit powerpc [POWERPC] Enable hotplug memory remove for 64-bit powerpc [POWERPC] Add remove_memory() for 64-bit powerpc [POWERPC] Make cell IOMMU fixed mapping printk more useful [POWERPC] Fix potential cell IOMMU bug when switching back to default DMA ops [POWERPC] Don't enable cell IOMMU fixed mapping if there are no dma-ranges [POWERPC] Fix cell IOMMU null pointer explosion on old firmwares [POWERPC] spufs: Fix timing dependent false return from spufs_run_spu [POWERPC] spufs: No need to have a runnable SPU for libassist update [POWERPC] spufs: Update SPU_Status[CISHP] in backing runcntl write [POWERPC] spufs: Fix state_mutex leaks [POWERPC] Disable G5 NAP mode during SMU commands on U3
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/file.c')
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index e393144d533..c66c3756970 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -358,6 +358,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
{
struct spu_context *ctx = vma->vm_file->private_data;
unsigned long area, offset = address - vma->vm_start;
+ int ret = 0;
spu_context_nospu_trace(spufs_ps_nopfn__enter, ctx);
@@ -379,7 +380,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
if (ctx->state == SPU_STATE_SAVED) {
up_read(&current->mm->mmap_sem);
spu_context_nospu_trace(spufs_ps_nopfn__sleep, ctx);
- spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
+ ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
spu_context_trace(spufs_ps_nopfn__wake, ctx, ctx->spu);
down_read(&current->mm->mmap_sem);
} else {
@@ -388,7 +389,8 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
spu_context_trace(spufs_ps_nopfn__insert, ctx, ctx->spu);
}
- spu_release(ctx);
+ if (!ret)
+ spu_release(ctx);
return NOPFN_REFAULT;
}
@@ -755,23 +757,25 @@ static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
count = spu_acquire(ctx);
if (count)
- return count;
+ goto out;
/* wait only for the first element */
count = 0;
if (file->f_flags & O_NONBLOCK) {
- if (!spu_ibox_read(ctx, &ibox_data))
+ if (!spu_ibox_read(ctx, &ibox_data)) {
count = -EAGAIN;
+ goto out_unlock;
+ }
} else {
count = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data));
+ if (count)
+ goto out;
}
- if (count)
- goto out;
/* if we can't write at all, return -EFAULT */
count = __put_user(ibox_data, udata);
if (count)
- goto out;
+ goto out_unlock;
for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) {
int ret;
@@ -788,9 +792,9 @@ static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
break;
}
-out:
+out_unlock:
spu_release(ctx);
-
+out:
return count;
}
@@ -905,7 +909,7 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
count = spu_acquire(ctx);
if (count)
- return count;
+ goto out;
/*
* make sure we can at least write one element, by waiting
@@ -913,14 +917,16 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
*/
count = 0;
if (file->f_flags & O_NONBLOCK) {
- if (!spu_wbox_write(ctx, wbox_data))
+ if (!spu_wbox_write(ctx, wbox_data)) {
count = -EAGAIN;
+ goto out_unlock;
+ }
} else {
count = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data));
+ if (count)
+ goto out;
}
- if (count)
- goto out;
/* write as much as possible */
for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) {
@@ -934,8 +940,9 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
break;
}
-out:
+out_unlock:
spu_release(ctx);
+out:
return count;
}
@@ -1598,12 +1605,11 @@ static ssize_t spufs_mfc_read(struct file *file, char __user *buffer,
} else {
ret = spufs_wait(ctx->mfc_wq,
spufs_read_mfc_tagstatus(ctx, &status));
+ if (ret)
+ goto out;
}
spu_release(ctx);
- if (ret)
- goto out;
-
ret = 4;
if (copy_to_user(buffer, &status, 4))
ret = -EFAULT;
@@ -1732,6 +1738,8 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
int status;
ret = spufs_wait(ctx->mfc_wq,
spu_send_mfc_command(ctx, cmd, &status));
+ if (ret)
+ goto out;
if (status)
ret = status;
}
@@ -1785,7 +1793,7 @@ static int spufs_mfc_flush(struct file *file, fl_owner_t id)
ret = spu_acquire(ctx);
if (ret)
- return ret;
+ goto out;
#if 0
/* this currently hangs */
ret = spufs_wait(ctx->mfc_wq,
@@ -1794,12 +1802,13 @@ static int spufs_mfc_flush(struct file *file, fl_owner_t id)
goto out;
ret = spufs_wait(ctx->mfc_wq,
ctx->ops->read_mfc_tagstatus(ctx) == ctx->tagwait);
-out:
+ if (ret)
+ goto out;
#else
ret = 0;
#endif
spu_release(ctx);
-
+out:
return ret;
}