[PATCH] spufs: implement mfc access for PPE-side DMA
[linux-2.6] / arch / powerpc / platforms / cell / spufs / file.c
1 /*
2  * SPU file system -- file contents
3  *
4  * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5  *
6  * Author: Arnd Bergmann <arndb@de.ibm.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #undef DEBUG
24
25 #include <linux/fs.h>
26 #include <linux/ioctl.h>
27 #include <linux/module.h>
28 #include <linux/pagemap.h>
29 #include <linux/poll.h>
30 #include <linux/ptrace.h>
31
32 #include <asm/io.h>
33 #include <asm/semaphore.h>
34 #include <asm/spu.h>
35 #include <asm/uaccess.h>
36
37 #include "spufs.h"
38
39
40 static int
41 spufs_mem_open(struct inode *inode, struct file *file)
42 {
43         struct spufs_inode_info *i = SPUFS_I(inode);
44         file->private_data = i->i_ctx;
45         file->f_mapping = i->i_ctx->local_store;
46         return 0;
47 }
48
49 static ssize_t
50 spufs_mem_read(struct file *file, char __user *buffer,
51                                 size_t size, loff_t *pos)
52 {
53         struct spu_context *ctx = file->private_data;
54         char *local_store;
55         int ret;
56
57         spu_acquire(ctx);
58
59         local_store = ctx->ops->get_ls(ctx);
60         ret = simple_read_from_buffer(buffer, size, pos, local_store, LS_SIZE);
61
62         spu_release(ctx);
63         return ret;
64 }
65
66 static ssize_t
67 spufs_mem_write(struct file *file, const char __user *buffer,
68                                         size_t size, loff_t *pos)
69 {
70         struct spu_context *ctx = file->private_data;
71         char *local_store;
72         int ret;
73
74         size = min_t(ssize_t, LS_SIZE - *pos, size);
75         if (size <= 0)
76                 return -EFBIG;
77         *pos += size;
78
79         spu_acquire(ctx);
80
81         local_store = ctx->ops->get_ls(ctx);
82         ret = copy_from_user(local_store + *pos - size,
83                              buffer, size) ? -EFAULT : size;
84
85         spu_release(ctx);
86         return ret;
87 }
88
89 #ifdef CONFIG_SPARSEMEM
90 static struct page *
91 spufs_mem_mmap_nopage(struct vm_area_struct *vma,
92                       unsigned long address, int *type)
93 {
94         struct page *page = NOPAGE_SIGBUS;
95
96         struct spu_context *ctx = vma->vm_file->private_data;
97         unsigned long offset = address - vma->vm_start;
98         offset += vma->vm_pgoff << PAGE_SHIFT;
99
100         spu_acquire(ctx);
101
102         if (ctx->state == SPU_STATE_SAVED)
103                 page = vmalloc_to_page(ctx->csa.lscsa->ls + offset);
104         else
105                 page = pfn_to_page((ctx->spu->local_store_phys + offset)
106                                    >> PAGE_SHIFT);
107
108         spu_release(ctx);
109
110         if (type)
111                 *type = VM_FAULT_MINOR;
112
113         page_cache_get(page);
114         return page;
115 }
116
117 static struct vm_operations_struct spufs_mem_mmap_vmops = {
118         .nopage = spufs_mem_mmap_nopage,
119 };
120
121 static int
122 spufs_mem_mmap(struct file *file, struct vm_area_struct *vma)
123 {
124         if (!(vma->vm_flags & VM_SHARED))
125                 return -EINVAL;
126
127         /* FIXME: */
128         vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
129                                      | _PAGE_NO_CACHE);
130
131         vma->vm_ops = &spufs_mem_mmap_vmops;
132         return 0;
133 }
134 #endif
135
136 static struct file_operations spufs_mem_fops = {
137         .open    = spufs_mem_open,
138         .read    = spufs_mem_read,
139         .write   = spufs_mem_write,
140         .llseek  = generic_file_llseek,
141 #ifdef CONFIG_SPARSEMEM
142         .mmap    = spufs_mem_mmap,
143 #endif
144 };
145
146 static int
147 spufs_regs_open(struct inode *inode, struct file *file)
148 {
149         struct spufs_inode_info *i = SPUFS_I(inode);
150         file->private_data = i->i_ctx;
151         return 0;
152 }
153
154 static ssize_t
155 spufs_regs_read(struct file *file, char __user *buffer,
156                 size_t size, loff_t *pos)
157 {
158         struct spu_context *ctx = file->private_data;
159         struct spu_lscsa *lscsa = ctx->csa.lscsa;
160         int ret;
161
162         spu_acquire_saved(ctx);
163
164         ret = simple_read_from_buffer(buffer, size, pos,
165                                       lscsa->gprs, sizeof lscsa->gprs);
166
167         spu_release(ctx);
168         return ret;
169 }
170
171 static ssize_t
172 spufs_regs_write(struct file *file, const char __user *buffer,
173                  size_t size, loff_t *pos)
174 {
175         struct spu_context *ctx = file->private_data;
176         struct spu_lscsa *lscsa = ctx->csa.lscsa;
177         int ret;
178
179         size = min_t(ssize_t, sizeof lscsa->gprs - *pos, size);
180         if (size <= 0)
181                 return -EFBIG;
182         *pos += size;
183
184         spu_acquire_saved(ctx);
185
186         ret = copy_from_user(lscsa->gprs + *pos - size,
187                              buffer, size) ? -EFAULT : size;
188
189         spu_release(ctx);
190         return ret;
191 }
192
193 static struct file_operations spufs_regs_fops = {
194         .open    = spufs_regs_open,
195         .read    = spufs_regs_read,
196         .write   = spufs_regs_write,
197         .llseek  = generic_file_llseek,
198 };
199
200 static ssize_t
201 spufs_fpcr_read(struct file *file, char __user * buffer,
202                 size_t size, loff_t * pos)
203 {
204         struct spu_context *ctx = file->private_data;
205         struct spu_lscsa *lscsa = ctx->csa.lscsa;
206         int ret;
207
208         spu_acquire_saved(ctx);
209
210         ret = simple_read_from_buffer(buffer, size, pos,
211                                       &lscsa->fpcr, sizeof(lscsa->fpcr));
212
213         spu_release(ctx);
214         return ret;
215 }
216
217 static ssize_t
218 spufs_fpcr_write(struct file *file, const char __user * buffer,
219                  size_t size, loff_t * pos)
220 {
221         struct spu_context *ctx = file->private_data;
222         struct spu_lscsa *lscsa = ctx->csa.lscsa;
223         int ret;
224
225         size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
226         if (size <= 0)
227                 return -EFBIG;
228         *pos += size;
229
230         spu_acquire_saved(ctx);
231
232         ret = copy_from_user((char *)&lscsa->fpcr + *pos - size,
233                              buffer, size) ? -EFAULT : size;
234
235         spu_release(ctx);
236         return ret;
237 }
238
239 static struct file_operations spufs_fpcr_fops = {
240         .open = spufs_regs_open,
241         .read = spufs_fpcr_read,
242         .write = spufs_fpcr_write,
243         .llseek = generic_file_llseek,
244 };
245
246 /* generic open function for all pipe-like files */
247 static int spufs_pipe_open(struct inode *inode, struct file *file)
248 {
249         struct spufs_inode_info *i = SPUFS_I(inode);
250         file->private_data = i->i_ctx;
251
252         return nonseekable_open(inode, file);
253 }
254
255 static ssize_t spufs_mbox_read(struct file *file, char __user *buf,
256                         size_t len, loff_t *pos)
257 {
258         struct spu_context *ctx = file->private_data;
259         u32 mbox_data;
260         int ret;
261
262         if (len < 4)
263                 return -EINVAL;
264
265         spu_acquire(ctx);
266         ret = ctx->ops->mbox_read(ctx, &mbox_data);
267         spu_release(ctx);
268
269         if (!ret)
270                 return -EAGAIN;
271
272         if (copy_to_user(buf, &mbox_data, sizeof mbox_data))
273                 return -EFAULT;
274
275         return 4;
276 }
277
278 static struct file_operations spufs_mbox_fops = {
279         .open   = spufs_pipe_open,
280         .read   = spufs_mbox_read,
281 };
282
283 static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf,
284                         size_t len, loff_t *pos)
285 {
286         struct spu_context *ctx = file->private_data;
287         u32 mbox_stat;
288
289         if (len < 4)
290                 return -EINVAL;
291
292         spu_acquire(ctx);
293
294         mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff;
295
296         spu_release(ctx);
297
298         if (copy_to_user(buf, &mbox_stat, sizeof mbox_stat))
299                 return -EFAULT;
300
301         return 4;
302 }
303
304 static struct file_operations spufs_mbox_stat_fops = {
305         .open   = spufs_pipe_open,
306         .read   = spufs_mbox_stat_read,
307 };
308
309 /* low-level ibox access function */
310 size_t spu_ibox_read(struct spu_context *ctx, u32 *data)
311 {
312         return ctx->ops->ibox_read(ctx, data);
313 }
314
315 static int spufs_ibox_fasync(int fd, struct file *file, int on)
316 {
317         struct spu_context *ctx = file->private_data;
318
319         return fasync_helper(fd, file, on, &ctx->ibox_fasync);
320 }
321
322 /* interrupt-level ibox callback function. */
323 void spufs_ibox_callback(struct spu *spu)
324 {
325         struct spu_context *ctx = spu->ctx;
326
327         wake_up_all(&ctx->ibox_wq);
328         kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN);
329 }
330
331 static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
332                         size_t len, loff_t *pos)
333 {
334         struct spu_context *ctx = file->private_data;
335         u32 ibox_data;
336         ssize_t ret;
337
338         if (len < 4)
339                 return -EINVAL;
340
341         spu_acquire(ctx);
342
343         ret = 0;
344         if (file->f_flags & O_NONBLOCK) {
345                 if (!spu_ibox_read(ctx, &ibox_data))
346                         ret = -EAGAIN;
347         } else {
348                 ret = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data));
349         }
350
351         spu_release(ctx);
352
353         if (ret)
354                 return ret;
355
356         ret = 4;
357         if (copy_to_user(buf, &ibox_data, sizeof ibox_data))
358                 ret = -EFAULT;
359
360         return ret;
361 }
362
363 static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait)
364 {
365         struct spu_context *ctx = file->private_data;
366         unsigned int mask;
367
368         poll_wait(file, &ctx->ibox_wq, wait);
369
370         spu_acquire(ctx);
371         mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM);
372         spu_release(ctx);
373
374         return mask;
375 }
376
377 static struct file_operations spufs_ibox_fops = {
378         .open   = spufs_pipe_open,
379         .read   = spufs_ibox_read,
380         .poll   = spufs_ibox_poll,
381         .fasync = spufs_ibox_fasync,
382 };
383
384 static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf,
385                         size_t len, loff_t *pos)
386 {
387         struct spu_context *ctx = file->private_data;
388         u32 ibox_stat;
389
390         if (len < 4)
391                 return -EINVAL;
392
393         spu_acquire(ctx);
394         ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff;
395         spu_release(ctx);
396
397         if (copy_to_user(buf, &ibox_stat, sizeof ibox_stat))
398                 return -EFAULT;
399
400         return 4;
401 }
402
403 static struct file_operations spufs_ibox_stat_fops = {
404         .open   = spufs_pipe_open,
405         .read   = spufs_ibox_stat_read,
406 };
407
408 /* low-level mailbox write */
409 size_t spu_wbox_write(struct spu_context *ctx, u32 data)
410 {
411         return ctx->ops->wbox_write(ctx, data);
412 }
413
414 static int spufs_wbox_fasync(int fd, struct file *file, int on)
415 {
416         struct spu_context *ctx = file->private_data;
417         int ret;
418
419         ret = fasync_helper(fd, file, on, &ctx->wbox_fasync);
420
421         return ret;
422 }
423
424 /* interrupt-level wbox callback function. */
425 void spufs_wbox_callback(struct spu *spu)
426 {
427         struct spu_context *ctx = spu->ctx;
428
429         wake_up_all(&ctx->wbox_wq);
430         kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT);
431 }
432
433 static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
434                         size_t len, loff_t *pos)
435 {
436         struct spu_context *ctx = file->private_data;
437         u32 wbox_data;
438         int ret;
439
440         if (len < 4)
441                 return -EINVAL;
442
443         if (copy_from_user(&wbox_data, buf, sizeof wbox_data))
444                 return -EFAULT;
445
446         spu_acquire(ctx);
447
448         ret = 0;
449         if (file->f_flags & O_NONBLOCK) {
450                 if (!spu_wbox_write(ctx, wbox_data))
451                         ret = -EAGAIN;
452         } else {
453                 ret = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data));
454         }
455
456         spu_release(ctx);
457
458         return ret ? ret : sizeof wbox_data;
459 }
460
461 static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait)
462 {
463         struct spu_context *ctx = file->private_data;
464         unsigned int mask;
465
466         poll_wait(file, &ctx->wbox_wq, wait);
467
468         spu_acquire(ctx);
469         mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM);
470         spu_release(ctx);
471
472         return mask;
473 }
474
475 static struct file_operations spufs_wbox_fops = {
476         .open   = spufs_pipe_open,
477         .write  = spufs_wbox_write,
478         .poll   = spufs_wbox_poll,
479         .fasync = spufs_wbox_fasync,
480 };
481
482 static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf,
483                         size_t len, loff_t *pos)
484 {
485         struct spu_context *ctx = file->private_data;
486         u32 wbox_stat;
487
488         if (len < 4)
489                 return -EINVAL;
490
491         spu_acquire(ctx);
492         wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff;
493         spu_release(ctx);
494
495         if (copy_to_user(buf, &wbox_stat, sizeof wbox_stat))
496                 return -EFAULT;
497
498         return 4;
499 }
500
501 static struct file_operations spufs_wbox_stat_fops = {
502         .open   = spufs_pipe_open,
503         .read   = spufs_wbox_stat_read,
504 };
505
506 static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
507                         size_t len, loff_t *pos)
508 {
509         struct spu_context *ctx = file->private_data;
510         u32 data;
511
512         if (len < 4)
513                 return -EINVAL;
514
515         spu_acquire(ctx);
516         data = ctx->ops->signal1_read(ctx);
517         spu_release(ctx);
518
519         if (copy_to_user(buf, &data, 4))
520                 return -EFAULT;
521
522         return 4;
523 }
524
525 static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
526                         size_t len, loff_t *pos)
527 {
528         struct spu_context *ctx;
529         u32 data;
530
531         ctx = file->private_data;
532
533         if (len < 4)
534                 return -EINVAL;
535
536         if (copy_from_user(&data, buf, 4))
537                 return -EFAULT;
538
539         spu_acquire(ctx);
540         ctx->ops->signal1_write(ctx, data);
541         spu_release(ctx);
542
543         return 4;
544 }
545
546 static struct file_operations spufs_signal1_fops = {
547         .open = spufs_pipe_open,
548         .read = spufs_signal1_read,
549         .write = spufs_signal1_write,
550 };
551
552 static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
553                         size_t len, loff_t *pos)
554 {
555         struct spu_context *ctx;
556         u32 data;
557
558         ctx = file->private_data;
559
560         if (len < 4)
561                 return -EINVAL;
562
563         spu_acquire(ctx);
564         data = ctx->ops->signal2_read(ctx);
565         spu_release(ctx);
566
567         if (copy_to_user(buf, &data, 4))
568                 return -EFAULT;
569
570         return 4;
571 }
572
573 static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
574                         size_t len, loff_t *pos)
575 {
576         struct spu_context *ctx;
577         u32 data;
578
579         ctx = file->private_data;
580
581         if (len < 4)
582                 return -EINVAL;
583
584         if (copy_from_user(&data, buf, 4))
585                 return -EFAULT;
586
587         spu_acquire(ctx);
588         ctx->ops->signal2_write(ctx, data);
589         spu_release(ctx);
590
591         return 4;
592 }
593
594 static struct file_operations spufs_signal2_fops = {
595         .open = spufs_pipe_open,
596         .read = spufs_signal2_read,
597         .write = spufs_signal2_write,
598 };
599
600 static void spufs_signal1_type_set(void *data, u64 val)
601 {
602         struct spu_context *ctx = data;
603
604         spu_acquire(ctx);
605         ctx->ops->signal1_type_set(ctx, val);
606         spu_release(ctx);
607 }
608
609 static u64 spufs_signal1_type_get(void *data)
610 {
611         struct spu_context *ctx = data;
612         u64 ret;
613
614         spu_acquire(ctx);
615         ret = ctx->ops->signal1_type_get(ctx);
616         spu_release(ctx);
617
618         return ret;
619 }
620 DEFINE_SIMPLE_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get,
621                                         spufs_signal1_type_set, "%llu");
622
623 static void spufs_signal2_type_set(void *data, u64 val)
624 {
625         struct spu_context *ctx = data;
626
627         spu_acquire(ctx);
628         ctx->ops->signal2_type_set(ctx, val);
629         spu_release(ctx);
630 }
631
632 static u64 spufs_signal2_type_get(void *data)
633 {
634         struct spu_context *ctx = data;
635         u64 ret;
636
637         spu_acquire(ctx);
638         ret = ctx->ops->signal2_type_get(ctx);
639         spu_release(ctx);
640
641         return ret;
642 }
643 DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get,
644                                         spufs_signal2_type_set, "%llu");
645
646
647 static int spufs_mfc_open(struct inode *inode, struct file *file)
648 {
649         struct spufs_inode_info *i = SPUFS_I(inode);
650         struct spu_context *ctx = i->i_ctx;
651
652         /* we don't want to deal with DMA into other processes */
653         if (ctx->owner != current->mm)
654                 return -EINVAL;
655
656         if (atomic_read(&inode->i_count) != 1)
657                 return -EBUSY;
658
659         file->private_data = ctx;
660         return nonseekable_open(inode, file);
661 }
662
663 /* interrupt-level mfc callback function. */
664 void spufs_mfc_callback(struct spu *spu)
665 {
666         struct spu_context *ctx = spu->ctx;
667
668         wake_up_all(&ctx->mfc_wq);
669
670         pr_debug("%s %s\n", __FUNCTION__, spu->name);
671         if (ctx->mfc_fasync) {
672                 u32 free_elements, tagstatus;
673                 unsigned int mask;
674
675                 /* no need for spu_acquire in interrupt context */
676                 free_elements = ctx->ops->get_mfc_free_elements(ctx);
677                 tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
678
679                 mask = 0;
680                 if (free_elements & 0xffff)
681                         mask |= POLLOUT;
682                 if (tagstatus & ctx->tagwait)
683                         mask |= POLLIN;
684
685                 kill_fasync(&ctx->mfc_fasync, SIGIO, mask);
686         }
687 }
688
689 static int spufs_read_mfc_tagstatus(struct spu_context *ctx, u32 *status)
690 {
691         /* See if there is one tag group is complete */
692         /* FIXME we need locking around tagwait */
693         *status = ctx->ops->read_mfc_tagstatus(ctx) & ctx->tagwait;
694         ctx->tagwait &= ~*status;
695         if (*status)
696                 return 1;
697
698         /* enable interrupt waiting for any tag group,
699            may silently fail if interrupts are already enabled */
700         ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1);
701         return 0;
702 }
703
704 static ssize_t spufs_mfc_read(struct file *file, char __user *buffer,
705                         size_t size, loff_t *pos)
706 {
707         struct spu_context *ctx = file->private_data;
708         int ret = -EINVAL;
709         u32 status;
710
711         if (size != 4)
712                 goto out;
713
714         spu_acquire(ctx);
715         if (file->f_flags & O_NONBLOCK) {
716                 status = ctx->ops->read_mfc_tagstatus(ctx);
717                 if (!(status & ctx->tagwait))
718                         ret = -EAGAIN;
719                 else
720                         ctx->tagwait &= ~status;
721         } else {
722                 ret = spufs_wait(ctx->mfc_wq,
723                            spufs_read_mfc_tagstatus(ctx, &status));
724         }
725         spu_release(ctx);
726
727         if (ret)
728                 goto out;
729
730         ret = 4;
731         if (copy_to_user(buffer, &status, 4))
732                 ret = -EFAULT;
733
734 out:
735         return ret;
736 }
737
738 static int spufs_check_valid_dma(struct mfc_dma_command *cmd)
739 {
740         pr_debug("queueing DMA %x %lx %x %x %x\n", cmd->lsa,
741                  cmd->ea, cmd->size, cmd->tag, cmd->cmd);
742
743         switch (cmd->cmd) {
744         case MFC_PUT_CMD:
745         case MFC_PUTF_CMD:
746         case MFC_PUTB_CMD:
747         case MFC_GET_CMD:
748         case MFC_GETF_CMD:
749         case MFC_GETB_CMD:
750                 break;
751         default:
752                 pr_debug("invalid DMA opcode %x\n", cmd->cmd);
753                 return -EIO;
754         }
755
756         if ((cmd->lsa & 0xf) != (cmd->ea &0xf)) {
757                 pr_debug("invalid DMA alignment, ea %lx lsa %x\n",
758                                 cmd->ea, cmd->lsa);
759                 return -EIO;
760         }
761
762         switch (cmd->size & 0xf) {
763         case 1:
764                 break;
765         case 2:
766                 if (cmd->lsa & 1)
767                         goto error;
768                 break;
769         case 4:
770                 if (cmd->lsa & 3)
771                         goto error;
772                 break;
773         case 8:
774                 if (cmd->lsa & 7)
775                         goto error;
776                 break;
777         case 0:
778                 if (cmd->lsa & 15)
779                         goto error;
780                 break;
781         error:
782         default:
783                 pr_debug("invalid DMA alignment %x for size %x\n",
784                         cmd->lsa & 0xf, cmd->size);
785                 return -EIO;
786         }
787
788         if (cmd->size > 16 * 1024) {
789                 pr_debug("invalid DMA size %x\n", cmd->size);
790                 return -EIO;
791         }
792
793         if (cmd->tag & 0xfff0) {
794                 /* we reserve the higher tag numbers for kernel use */
795                 pr_debug("invalid DMA tag\n");
796                 return -EIO;
797         }
798
799         if (cmd->class) {
800                 /* not supported in this version */
801                 pr_debug("invalid DMA class\n");
802                 return -EIO;
803         }
804
805         return 0;
806 }
807
808 static int spu_send_mfc_command(struct spu_context *ctx,
809                                 struct mfc_dma_command cmd,
810                                 int *error)
811 {
812         *error = ctx->ops->send_mfc_command(ctx, &cmd);
813         if (*error == -EAGAIN) {
814                 /* wait for any tag group to complete
815                    so we have space for the new command */
816                 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1);
817                 /* try again, because the queue might be
818                    empty again */
819                 *error = ctx->ops->send_mfc_command(ctx, &cmd);
820                 if (*error == -EAGAIN)
821                         return 0;
822         }
823         return 1;
824 }
825
826 static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
827                         size_t size, loff_t *pos)
828 {
829         struct spu_context *ctx = file->private_data;
830         struct mfc_dma_command cmd;
831         int ret = -EINVAL;
832
833         if (size != sizeof cmd)
834                 goto out;
835
836         ret = -EFAULT;
837         if (copy_from_user(&cmd, buffer, sizeof cmd))
838                 goto out;
839
840         ret = spufs_check_valid_dma(&cmd);
841         if (ret)
842                 goto out;
843
844         spu_acquire_runnable(ctx);
845         if (file->f_flags & O_NONBLOCK) {
846                 ret = ctx->ops->send_mfc_command(ctx, &cmd);
847         } else {
848                 int status;
849                 ret = spufs_wait(ctx->mfc_wq,
850                                  spu_send_mfc_command(ctx, cmd, &status));
851                 if (status)
852                         ret = status;
853         }
854         spu_release(ctx);
855
856         if (ret)
857                 goto out;
858
859         ctx->tagwait |= 1 << cmd.tag;
860
861 out:
862         return ret;
863 }
864
865 static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait)
866 {
867         struct spu_context *ctx = file->private_data;
868         u32 free_elements, tagstatus;
869         unsigned int mask;
870
871         spu_acquire(ctx);
872         ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
873         free_elements = ctx->ops->get_mfc_free_elements(ctx);
874         tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
875         spu_release(ctx);
876
877         poll_wait(file, &ctx->mfc_wq, wait);
878
879         mask = 0;
880         if (free_elements & 0xffff)
881                 mask |= POLLOUT | POLLWRNORM;
882         if (tagstatus & ctx->tagwait)
883                 mask |= POLLIN | POLLRDNORM;
884
885         pr_debug("%s: free %d tagstatus %d tagwait %d\n", __FUNCTION__,
886                 free_elements, tagstatus, ctx->tagwait);
887
888         return mask;
889 }
890
891 static int spufs_mfc_flush(struct file *file)
892 {
893         struct spu_context *ctx = file->private_data;
894         int ret;
895
896         spu_acquire(ctx);
897 #if 0
898 /* this currently hangs */
899         ret = spufs_wait(ctx->mfc_wq,
900                          ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2));
901         if (ret)
902                 goto out;
903         ret = spufs_wait(ctx->mfc_wq,
904                          ctx->ops->read_mfc_tagstatus(ctx) == ctx->tagwait);
905 out:
906 #else
907         ret = 0;
908 #endif
909         spu_release(ctx);
910
911         return ret;
912 }
913
914 static int spufs_mfc_fsync(struct file *file, struct dentry *dentry,
915                            int datasync)
916 {
917         return spufs_mfc_flush(file);
918 }
919
920 static int spufs_mfc_fasync(int fd, struct file *file, int on)
921 {
922         struct spu_context *ctx = file->private_data;
923
924         return fasync_helper(fd, file, on, &ctx->mfc_fasync);
925 }
926
927 static struct file_operations spufs_mfc_fops = {
928         .open    = spufs_mfc_open,
929         .read    = spufs_mfc_read,
930         .write   = spufs_mfc_write,
931         .poll    = spufs_mfc_poll,
932         .flush   = spufs_mfc_flush,
933         .fsync   = spufs_mfc_fsync,
934         .fasync  = spufs_mfc_fasync,
935 };
936
937 static void spufs_npc_set(void *data, u64 val)
938 {
939         struct spu_context *ctx = data;
940         spu_acquire(ctx);
941         ctx->ops->npc_write(ctx, val);
942         spu_release(ctx);
943 }
944
945 static u64 spufs_npc_get(void *data)
946 {
947         struct spu_context *ctx = data;
948         u64 ret;
949         spu_acquire(ctx);
950         ret = ctx->ops->npc_read(ctx);
951         spu_release(ctx);
952         return ret;
953 }
954 DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, "%llx\n")
955
956 static void spufs_decr_set(void *data, u64 val)
957 {
958         struct spu_context *ctx = data;
959         struct spu_lscsa *lscsa = ctx->csa.lscsa;
960         spu_acquire_saved(ctx);
961         lscsa->decr.slot[0] = (u32) val;
962         spu_release(ctx);
963 }
964
965 static u64 spufs_decr_get(void *data)
966 {
967         struct spu_context *ctx = data;
968         struct spu_lscsa *lscsa = ctx->csa.lscsa;
969         u64 ret;
970         spu_acquire_saved(ctx);
971         ret = lscsa->decr.slot[0];
972         spu_release(ctx);
973         return ret;
974 }
975 DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
976                         "%llx\n")
977
978 static void spufs_decr_status_set(void *data, u64 val)
979 {
980         struct spu_context *ctx = data;
981         struct spu_lscsa *lscsa = ctx->csa.lscsa;
982         spu_acquire_saved(ctx);
983         lscsa->decr_status.slot[0] = (u32) val;
984         spu_release(ctx);
985 }
986
987 static u64 spufs_decr_status_get(void *data)
988 {
989         struct spu_context *ctx = data;
990         struct spu_lscsa *lscsa = ctx->csa.lscsa;
991         u64 ret;
992         spu_acquire_saved(ctx);
993         ret = lscsa->decr_status.slot[0];
994         spu_release(ctx);
995         return ret;
996 }
997 DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get,
998                         spufs_decr_status_set, "%llx\n")
999
1000 static void spufs_spu_tag_mask_set(void *data, u64 val)
1001 {
1002         struct spu_context *ctx = data;
1003         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1004         spu_acquire_saved(ctx);
1005         lscsa->tag_mask.slot[0] = (u32) val;
1006         spu_release(ctx);
1007 }
1008
1009 static u64 spufs_spu_tag_mask_get(void *data)
1010 {
1011         struct spu_context *ctx = data;
1012         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1013         u64 ret;
1014         spu_acquire_saved(ctx);
1015         ret = lscsa->tag_mask.slot[0];
1016         spu_release(ctx);
1017         return ret;
1018 }
1019 DEFINE_SIMPLE_ATTRIBUTE(spufs_spu_tag_mask_ops, spufs_spu_tag_mask_get,
1020                         spufs_spu_tag_mask_set, "%llx\n")
1021
1022 static void spufs_event_mask_set(void *data, u64 val)
1023 {
1024         struct spu_context *ctx = data;
1025         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1026         spu_acquire_saved(ctx);
1027         lscsa->event_mask.slot[0] = (u32) val;
1028         spu_release(ctx);
1029 }
1030
1031 static u64 spufs_event_mask_get(void *data)
1032 {
1033         struct spu_context *ctx = data;
1034         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1035         u64 ret;
1036         spu_acquire_saved(ctx);
1037         ret = lscsa->event_mask.slot[0];
1038         spu_release(ctx);
1039         return ret;
1040 }
1041 DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get,
1042                         spufs_event_mask_set, "%llx\n")
1043
1044 static void spufs_srr0_set(void *data, u64 val)
1045 {
1046         struct spu_context *ctx = data;
1047         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1048         spu_acquire_saved(ctx);
1049         lscsa->srr0.slot[0] = (u32) val;
1050         spu_release(ctx);
1051 }
1052
1053 static u64 spufs_srr0_get(void *data)
1054 {
1055         struct spu_context *ctx = data;
1056         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1057         u64 ret;
1058         spu_acquire_saved(ctx);
1059         ret = lscsa->srr0.slot[0];
1060         spu_release(ctx);
1061         return ret;
1062 }
1063 DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set,
1064                         "%llx\n")
1065
1066 struct tree_descr spufs_dir_contents[] = {
1067         { "mem",  &spufs_mem_fops,  0666, },
1068         { "regs", &spufs_regs_fops,  0666, },
1069         { "mbox", &spufs_mbox_fops, 0444, },
1070         { "ibox", &spufs_ibox_fops, 0444, },
1071         { "wbox", &spufs_wbox_fops, 0222, },
1072         { "mbox_stat", &spufs_mbox_stat_fops, 0444, },
1073         { "ibox_stat", &spufs_ibox_stat_fops, 0444, },
1074         { "wbox_stat", &spufs_wbox_stat_fops, 0444, },
1075         { "signal1", &spufs_signal1_fops, 0666, },
1076         { "signal2", &spufs_signal2_fops, 0666, },
1077         { "signal1_type", &spufs_signal1_type, 0666, },
1078         { "signal2_type", &spufs_signal2_type, 0666, },
1079         { "mfc", &spufs_mfc_fops, 0666, },
1080         { "npc", &spufs_npc_ops, 0666, },
1081         { "fpcr", &spufs_fpcr_fops, 0666, },
1082         { "decr", &spufs_decr_ops, 0666, },
1083         { "decr_status", &spufs_decr_status_ops, 0666, },
1084         { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, },
1085         { "event_mask", &spufs_event_mask_ops, 0666, },
1086         { "srr0", &spufs_srr0_ops, 0666, },
1087         {},
1088 };