summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/cell/spufs/file.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2005-12-05 22:52:27 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-09 14:53:01 +1100
commit3a843d7cd30ab6815610d9d6aa66b56df0ee1228 (patch)
treeb344400a51bf794ec10c6a1fb788e1244969a00f /arch/powerpc/platforms/cell/spufs/file.c
parent2a911f0bb73e67826062b7d073dd7367ca449724 (diff)
[PATCH] spufs: fix mailbox polling
Handling mailbox interrupts was broken in multiple respects, the combination of which was hiding the bugs most of the time. - The ibox interrupt mask was open initially even though there are no waiters on a newly created SPU. - Acknowledging the mailbox interrupt did not work because it is level triggered and the mailbox data is never retrieved from inside the interrupt handler. - The interrupt handler delivered interrupts with a disabled mask if another interrupt is triggered for the same class but a different mask. - The poll function did not enable the interrupt if it had not been enabled, so we might run into the poll timeout if none of the other bugs saved us and no signal was delivered. We probably still have a similar problem with blocking read/write on mailbox files, but that will result in extra wakeup in the worst case, not in incorrect behaviour. Signed-off-by: Arnd Bergmann <arndb@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/file.c')
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c24
1 files changed, 6 insertions, 18 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index af5adc372224..9738de727f32 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -389,20 +389,13 @@ static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait)
{
struct spu_context *ctx = file->private_data;
- u32 mbox_stat;
unsigned int mask;
- spu_acquire(ctx);
-
- mbox_stat = ctx->ops->mbox_stat_read(ctx);
-
- spu_release(ctx);
-
poll_wait(file, &ctx->ibox_wq, wait);
- mask = 0;
- if (mbox_stat & 0xff0000)
- mask |= POLLIN | POLLRDNORM;
+ spu_acquire(ctx);
+ mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM);
+ spu_release(ctx);
return mask;
}
@@ -494,18 +487,13 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait)
{
struct spu_context *ctx = file->private_data;
- u32 mbox_stat;
unsigned int mask;
- spu_acquire(ctx);
- mbox_stat = ctx->ops->mbox_stat_read(ctx);
- spu_release(ctx);
-
poll_wait(file, &ctx->wbox_wq, wait);
- mask = 0;
- if (mbox_stat & 0x00ff00)
- mask = POLLOUT | POLLWRNORM;
+ spu_acquire(ctx);
+ mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM);
+ spu_release(ctx);
return mask;
}