This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / 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         struct spu_context *ctx = i->i_ctx;
45         file->private_data = ctx;
46         file->f_mapping = inode->i_mapping;
47         ctx->local_store = inode->i_mapping;
48         return 0;
49 }
50
51 static ssize_t
52 spufs_mem_read(struct file *file, char __user *buffer,
53                                 size_t size, loff_t *pos)
54 {
55         struct spu_context *ctx = file->private_data;
56         char *local_store;
57         int ret;
58
59         spu_acquire(ctx);
60
61         local_store = ctx->ops->get_ls(ctx);
62         ret = simple_read_from_buffer(buffer, size, pos, local_store, LS_SIZE);
63
64         spu_release(ctx);
65         return ret;
66 }
67
68 static ssize_t
69 spufs_mem_write(struct file *file, const char __user *buffer,
70                                         size_t size, loff_t *pos)
71 {
72         struct spu_context *ctx = file->private_data;
73         char *local_store;
74         int ret;
75
76         size = min_t(ssize_t, LS_SIZE - *pos, size);
77         if (size <= 0)
78                 return -EFBIG;
79         *pos += size;
80
81         spu_acquire(ctx);
82
83         local_store = ctx->ops->get_ls(ctx);
84         ret = copy_from_user(local_store + *pos - size,
85                              buffer, size) ? -EFAULT : size;
86
87         spu_release(ctx);
88         return ret;
89 }
90
91 #ifdef CONFIG_SPUFS_MMAP
92 static struct page *
93 spufs_mem_mmap_nopage(struct vm_area_struct *vma,
94                       unsigned long address, int *type)
95 {
96         struct page *page = NOPAGE_SIGBUS;
97
98         struct spu_context *ctx = vma->vm_file->private_data;
99         unsigned long offset = address - vma->vm_start;
100         offset += vma->vm_pgoff << PAGE_SHIFT;
101
102         spu_acquire(ctx);
103
104         if (ctx->state == SPU_STATE_SAVED)
105                 page = vmalloc_to_page(ctx->csa.lscsa->ls + offset);
106         else
107                 page = pfn_to_page((ctx->spu->local_store_phys + offset)
108                                    >> PAGE_SHIFT);
109
110         spu_release(ctx);
111
112         if (type)
113                 *type = VM_FAULT_MINOR;
114
115         page_cache_get(page);
116         return page;
117 }
118
119 static struct vm_operations_struct spufs_mem_mmap_vmops = {
120         .nopage = spufs_mem_mmap_nopage,
121 };
122
123 static int
124 spufs_mem_mmap(struct file *file, struct vm_area_struct *vma)
125 {
126         if (!(vma->vm_flags & VM_SHARED))
127                 return -EINVAL;
128
129         /* FIXME: */
130         vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
131                                      | _PAGE_NO_CACHE);
132
133         vma->vm_ops = &spufs_mem_mmap_vmops;
134         return 0;
135 }
136 #endif
137
138 static struct file_operations spufs_mem_fops = {
139         .open    = spufs_mem_open,
140         .read    = spufs_mem_read,
141         .write   = spufs_mem_write,
142         .llseek  = generic_file_llseek,
143 #ifdef CONFIG_SPUFS_MMAP
144         .mmap    = spufs_mem_mmap,
145 #endif
146 };
147
148 #ifdef CONFIG_SPUFS_MMAP
149 static struct page *spufs_ps_nopage(struct vm_area_struct *vma,
150                                     unsigned long address,
151                                     int *type, unsigned long ps_offs)
152 {
153         struct page *page = NOPAGE_SIGBUS;
154         int fault_type = VM_FAULT_SIGBUS;
155         struct spu_context *ctx = vma->vm_file->private_data;
156         unsigned long offset = address - vma->vm_start;
157         unsigned long area;
158         int ret;
159
160         offset += vma->vm_pgoff << PAGE_SHIFT;
161         if (offset >= 0x4000)
162                 goto out;
163
164         ret = spu_acquire_runnable(ctx);
165         if (ret)
166                 goto out;
167
168         area = ctx->spu->problem_phys + ps_offs;
169         page = pfn_to_page((area + offset) >> PAGE_SHIFT);
170         fault_type = VM_FAULT_MINOR;
171         page_cache_get(page);
172
173         spu_release(ctx);
174
175       out:
176         if (type)
177                 *type = fault_type;
178
179         return page;
180 }
181
182 static struct page *spufs_cntl_mmap_nopage(struct vm_area_struct *vma,
183                                            unsigned long address, int *type)
184 {
185         return spufs_ps_nopage(vma, address, type, 0x4000);
186 }
187
188 static struct vm_operations_struct spufs_cntl_mmap_vmops = {
189         .nopage = spufs_cntl_mmap_nopage,
190 };
191
192 /*
193  * mmap support for problem state control area [0x4000 - 0x4fff].
194  * Mapping this area requires that the application have CAP_SYS_RAWIO,
195  * as these registers require special care when read/writing.
196  */
197 static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma)
198 {
199         if (!(vma->vm_flags & VM_SHARED))
200                 return -EINVAL;
201
202         if (!capable(CAP_SYS_RAWIO))
203                 return -EPERM;
204
205         vma->vm_flags |= VM_RESERVED;
206         vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
207                                      | _PAGE_NO_CACHE);
208
209         vma->vm_ops = &spufs_cntl_mmap_vmops;
210         return 0;
211 }
212 #endif
213
214 static int spufs_cntl_open(struct inode *inode, struct file *file)
215 {
216         struct spufs_inode_info *i = SPUFS_I(inode);
217         struct spu_context *ctx = i->i_ctx;
218
219         file->private_data = ctx;
220         file->f_mapping = inode->i_mapping;
221         ctx->cntl = inode->i_mapping;
222         return 0;
223 }
224
225 static ssize_t
226 spufs_cntl_read(struct file *file, char __user *buffer,
227                 size_t size, loff_t *pos)
228 {
229         /* FIXME: read from spu status */
230         return -EINVAL;
231 }
232
233 static ssize_t
234 spufs_cntl_write(struct file *file, const char __user *buffer,
235                  size_t size, loff_t *pos)
236 {
237         /* FIXME: write to runctl bit */
238         return -EINVAL;
239 }
240
241 static struct file_operations spufs_cntl_fops = {
242         .open = spufs_cntl_open,
243         .read = spufs_cntl_read,
244         .write = spufs_cntl_write,
245 #ifdef CONFIG_SPUFS_MMAP
246         .mmap = spufs_cntl_mmap,
247 #endif
248 };
249
250 static int
251 spufs_regs_open(struct inode *inode, struct file *file)
252 {
253         struct spufs_inode_info *i = SPUFS_I(inode);
254         file->private_data = i->i_ctx;
255         return 0;
256 }
257
258 static ssize_t
259 spufs_regs_read(struct file *file, char __user *buffer,
260                 size_t size, loff_t *pos)
261 {
262         struct spu_context *ctx = file->private_data;
263         struct spu_lscsa *lscsa = ctx->csa.lscsa;
264         int ret;
265
266         spu_acquire_saved(ctx);
267
268         ret = simple_read_from_buffer(buffer, size, pos,
269                                       lscsa->gprs, sizeof lscsa->gprs);
270
271         spu_release(ctx);
272         return ret;
273 }
274
275 static ssize_t
276 spufs_regs_write(struct file *file, const char __user *buffer,
277                  size_t size, loff_t *pos)
278 {
279         struct spu_context *ctx = file->private_data;
280         struct spu_lscsa *lscsa = ctx->csa.lscsa;
281         int ret;
282
283         size = min_t(ssize_t, sizeof lscsa->gprs - *pos, size);
284         if (size <= 0)
285                 return -EFBIG;
286         *pos += size;
287
288         spu_acquire_saved(ctx);
289
290         ret = copy_from_user(lscsa->gprs + *pos - size,
291                              buffer, size) ? -EFAULT : size;
292
293         spu_release(ctx);
294         return ret;
295 }
296
297 static struct file_operations spufs_regs_fops = {
298         .open    = spufs_regs_open,
299         .read    = spufs_regs_read,
300         .write   = spufs_regs_write,
301         .llseek  = generic_file_llseek,
302 };
303
304 static ssize_t
305 spufs_fpcr_read(struct file *file, char __user * buffer,
306                 size_t size, loff_t * pos)
307 {
308         struct spu_context *ctx = file->private_data;
309         struct spu_lscsa *lscsa = ctx->csa.lscsa;
310         int ret;
311
312         spu_acquire_saved(ctx);
313
314         ret = simple_read_from_buffer(buffer, size, pos,
315                                       &lscsa->fpcr, sizeof(lscsa->fpcr));
316
317         spu_release(ctx);
318         return ret;
319 }
320
321 static ssize_t
322 spufs_fpcr_write(struct file *file, const char __user * buffer,
323                  size_t size, loff_t * pos)
324 {
325         struct spu_context *ctx = file->private_data;
326         struct spu_lscsa *lscsa = ctx->csa.lscsa;
327         int ret;
328
329         size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
330         if (size <= 0)
331                 return -EFBIG;
332         *pos += size;
333
334         spu_acquire_saved(ctx);
335
336         ret = copy_from_user((char *)&lscsa->fpcr + *pos - size,
337                              buffer, size) ? -EFAULT : size;
338
339         spu_release(ctx);
340         return ret;
341 }
342
343 static struct file_operations spufs_fpcr_fops = {
344         .open = spufs_regs_open,
345         .read = spufs_fpcr_read,
346         .write = spufs_fpcr_write,
347         .llseek = generic_file_llseek,
348 };
349
350 /* generic open function for all pipe-like files */
351 static int spufs_pipe_open(struct inode *inode, struct file *file)
352 {
353         struct spufs_inode_info *i = SPUFS_I(inode);
354         file->private_data = i->i_ctx;
355
356         return nonseekable_open(inode, file);
357 }
358
359 static ssize_t spufs_mbox_read(struct file *file, char __user *buf,
360                         size_t len, loff_t *pos)
361 {
362         struct spu_context *ctx = file->private_data;
363         u32 mbox_data;
364         int ret;
365
366         if (len < 4)
367                 return -EINVAL;
368
369         spu_acquire(ctx);
370         ret = ctx->ops->mbox_read(ctx, &mbox_data);
371         spu_release(ctx);
372
373         if (!ret)
374                 return -EAGAIN;
375
376         if (copy_to_user(buf, &mbox_data, sizeof mbox_data))
377                 return -EFAULT;
378
379         return 4;
380 }
381
382 static struct file_operations spufs_mbox_fops = {
383         .open   = spufs_pipe_open,
384         .read   = spufs_mbox_read,
385 };
386
387 static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf,
388                         size_t len, loff_t *pos)
389 {
390         struct spu_context *ctx = file->private_data;
391         u32 mbox_stat;
392
393         if (len < 4)
394                 return -EINVAL;
395
396         spu_acquire(ctx);
397
398         mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff;
399
400         spu_release(ctx);
401
402         if (copy_to_user(buf, &mbox_stat, sizeof mbox_stat))
403                 return -EFAULT;
404
405         return 4;
406 }
407
408 static struct file_operations spufs_mbox_stat_fops = {
409         .open   = spufs_pipe_open,
410         .read   = spufs_mbox_stat_read,
411 };
412
413 /* low-level ibox access function */
414 size_t spu_ibox_read(struct spu_context *ctx, u32 *data)
415 {
416         return ctx->ops->ibox_read(ctx, data);
417 }
418
419 static int spufs_ibox_fasync(int fd, struct file *file, int on)
420 {
421         struct spu_context *ctx = file->private_data;
422
423         return fasync_helper(fd, file, on, &ctx->ibox_fasync);
424 }
425
426 /* interrupt-level ibox callback function. */
427 void spufs_ibox_callback(struct spu *spu)
428 {
429         struct spu_context *ctx = spu->ctx;
430
431         wake_up_all(&ctx->ibox_wq);
432         kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN);
433 }
434
435 static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
436                         size_t len, loff_t *pos)
437 {
438         struct spu_context *ctx = file->private_data;
439         u32 ibox_data;
440         ssize_t ret;
441
442         if (len < 4)
443                 return -EINVAL;
444
445         spu_acquire(ctx);
446
447         ret = 0;
448         if (file->f_flags & O_NONBLOCK) {
449                 if (!spu_ibox_read(ctx, &ibox_data))
450                         ret = -EAGAIN;
451         } else {
452                 ret = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data));
453         }
454
455         spu_release(ctx);
456
457         if (ret)
458                 return ret;
459
460         ret = 4;
461         if (copy_to_user(buf, &ibox_data, sizeof ibox_data))
462                 ret = -EFAULT;
463
464         return ret;
465 }
466
467 static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait)
468 {
469         struct spu_context *ctx = file->private_data;
470         unsigned int mask;
471
472         poll_wait(file, &ctx->ibox_wq, wait);
473
474         spu_acquire(ctx);
475         mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM);
476         spu_release(ctx);
477
478         return mask;
479 }
480
481 static struct file_operations spufs_ibox_fops = {
482         .open   = spufs_pipe_open,
483         .read   = spufs_ibox_read,
484         .poll   = spufs_ibox_poll,
485         .fasync = spufs_ibox_fasync,
486 };
487
488 static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf,
489                         size_t len, loff_t *pos)
490 {
491         struct spu_context *ctx = file->private_data;
492         u32 ibox_stat;
493
494         if (len < 4)
495                 return -EINVAL;
496
497         spu_acquire(ctx);
498         ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff;
499         spu_release(ctx);
500
501         if (copy_to_user(buf, &ibox_stat, sizeof ibox_stat))
502                 return -EFAULT;
503
504         return 4;
505 }
506
507 static struct file_operations spufs_ibox_stat_fops = {
508         .open   = spufs_pipe_open,
509         .read   = spufs_ibox_stat_read,
510 };
511
512 /* low-level mailbox write */
513 size_t spu_wbox_write(struct spu_context *ctx, u32 data)
514 {
515         return ctx->ops->wbox_write(ctx, data);
516 }
517
518 static int spufs_wbox_fasync(int fd, struct file *file, int on)
519 {
520         struct spu_context *ctx = file->private_data;
521         int ret;
522
523         ret = fasync_helper(fd, file, on, &ctx->wbox_fasync);
524
525         return ret;
526 }
527
528 /* interrupt-level wbox callback function. */
529 void spufs_wbox_callback(struct spu *spu)
530 {
531         struct spu_context *ctx = spu->ctx;
532
533         wake_up_all(&ctx->wbox_wq);
534         kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT);
535 }
536
537 static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
538                         size_t len, loff_t *pos)
539 {
540         struct spu_context *ctx = file->private_data;
541         u32 wbox_data;
542         int ret;
543
544         if (len < 4)
545                 return -EINVAL;
546
547         if (copy_from_user(&wbox_data, buf, sizeof wbox_data))
548                 return -EFAULT;
549
550         spu_acquire(ctx);
551
552         ret = 0;
553         if (file->f_flags & O_NONBLOCK) {
554                 if (!spu_wbox_write(ctx, wbox_data))
555                         ret = -EAGAIN;
556         } else {
557                 ret = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data));
558         }
559
560         spu_release(ctx);
561
562         return ret ? ret : sizeof wbox_data;
563 }
564
565 static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait)
566 {
567         struct spu_context *ctx = file->private_data;
568         unsigned int mask;
569
570         poll_wait(file, &ctx->wbox_wq, wait);
571
572         spu_acquire(ctx);
573         mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM);
574         spu_release(ctx);
575
576         return mask;
577 }
578
579 static struct file_operations spufs_wbox_fops = {
580         .open   = spufs_pipe_open,
581         .write  = spufs_wbox_write,
582         .poll   = spufs_wbox_poll,
583         .fasync = spufs_wbox_fasync,
584 };
585
586 static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf,
587                         size_t len, loff_t *pos)
588 {
589         struct spu_context *ctx = file->private_data;
590         u32 wbox_stat;
591
592         if (len < 4)
593                 return -EINVAL;
594
595         spu_acquire(ctx);
596         wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff;
597         spu_release(ctx);
598
599         if (copy_to_user(buf, &wbox_stat, sizeof wbox_stat))
600                 return -EFAULT;
601
602         return 4;
603 }
604
605 static struct file_operations spufs_wbox_stat_fops = {
606         .open   = spufs_pipe_open,
607         .read   = spufs_wbox_stat_read,
608 };
609
610 static int spufs_signal1_open(struct inode *inode, struct file *file)
611 {
612         struct spufs_inode_info *i = SPUFS_I(inode);
613         struct spu_context *ctx = i->i_ctx;
614         file->private_data = ctx;
615         file->f_mapping = inode->i_mapping;
616         ctx->signal1 = inode->i_mapping;
617         return nonseekable_open(inode, file);
618 }
619
620 static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
621                         size_t len, loff_t *pos)
622 {
623         struct spu_context *ctx = file->private_data;
624         u32 data;
625
626         if (len < 4)
627                 return -EINVAL;
628
629         spu_acquire(ctx);
630         data = ctx->ops->signal1_read(ctx);
631         spu_release(ctx);
632
633         if (copy_to_user(buf, &data, 4))
634                 return -EFAULT;
635
636         return 4;
637 }
638
639 static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
640                         size_t len, loff_t *pos)
641 {
642         struct spu_context *ctx;
643         u32 data;
644
645         ctx = file->private_data;
646
647         if (len < 4)
648                 return -EINVAL;
649
650         if (copy_from_user(&data, buf, 4))
651                 return -EFAULT;
652
653         spu_acquire(ctx);
654         ctx->ops->signal1_write(ctx, data);
655         spu_release(ctx);
656
657         return 4;
658 }
659
660 #ifdef CONFIG_SPUFS_MMAP
661 static struct page *spufs_signal1_mmap_nopage(struct vm_area_struct *vma,
662                                               unsigned long address, int *type)
663 {
664         return spufs_ps_nopage(vma, address, type, 0x14000);
665 }
666
667 static struct vm_operations_struct spufs_signal1_mmap_vmops = {
668         .nopage = spufs_signal1_mmap_nopage,
669 };
670
671 static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma)
672 {
673         if (!(vma->vm_flags & VM_SHARED))
674                 return -EINVAL;
675
676         vma->vm_flags |= VM_RESERVED;
677         vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
678                                      | _PAGE_NO_CACHE);
679
680         vma->vm_ops = &spufs_signal1_mmap_vmops;
681         return 0;
682 }
683 #endif
684
685 static struct file_operations spufs_signal1_fops = {
686         .open = spufs_signal1_open,
687         .read = spufs_signal1_read,
688         .write = spufs_signal1_write,
689 #ifdef CONFIG_SPUFS_MMAP
690         .mmap = spufs_signal1_mmap,
691 #endif
692 };
693
694 static int spufs_signal2_open(struct inode *inode, struct file *file)
695 {
696         struct spufs_inode_info *i = SPUFS_I(inode);
697         struct spu_context *ctx = i->i_ctx;
698         file->private_data = ctx;
699         file->f_mapping = inode->i_mapping;
700         ctx->signal2 = inode->i_mapping;
701         return nonseekable_open(inode, file);
702 }
703
704 static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
705                         size_t len, loff_t *pos)
706 {
707         struct spu_context *ctx;
708         u32 data;
709
710         ctx = file->private_data;
711
712         if (len < 4)
713                 return -EINVAL;
714
715         spu_acquire(ctx);
716         data = ctx->ops->signal2_read(ctx);
717         spu_release(ctx);
718
719         if (copy_to_user(buf, &data, 4))
720                 return -EFAULT;
721
722         return 4;
723 }
724
725 static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
726                         size_t len, loff_t *pos)
727 {
728         struct spu_context *ctx;
729         u32 data;
730
731         ctx = file->private_data;
732
733         if (len < 4)
734                 return -EINVAL;
735
736         if (copy_from_user(&data, buf, 4))
737                 return -EFAULT;
738
739         spu_acquire(ctx);
740         ctx->ops->signal2_write(ctx, data);
741         spu_release(ctx);
742
743         return 4;
744 }
745
746 #ifdef CONFIG_SPUFS_MMAP
747 static struct page *spufs_signal2_mmap_nopage(struct vm_area_struct *vma,
748                                               unsigned long address, int *type)
749 {
750         return spufs_ps_nopage(vma, address, type, 0x1c000);
751 }
752
753 static struct vm_operations_struct spufs_signal2_mmap_vmops = {
754         .nopage = spufs_signal2_mmap_nopage,
755 };
756
757 static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma)
758 {
759         if (!(vma->vm_flags & VM_SHARED))
760                 return -EINVAL;
761
762         /* FIXME: */
763         vma->vm_flags |= VM_RESERVED;
764         vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
765                                      | _PAGE_NO_CACHE);
766
767         vma->vm_ops = &spufs_signal2_mmap_vmops;
768         return 0;
769 }
770 #endif
771
772 static struct file_operations spufs_signal2_fops = {
773         .open = spufs_signal2_open,
774         .read = spufs_signal2_read,
775         .write = spufs_signal2_write,
776 #ifdef CONFIG_SPUFS_MMAP
777         .mmap = spufs_signal2_mmap,
778 #endif
779 };
780
781 static void spufs_signal1_type_set(void *data, u64 val)
782 {
783         struct spu_context *ctx = data;
784
785         spu_acquire(ctx);
786         ctx->ops->signal1_type_set(ctx, val);
787         spu_release(ctx);
788 }
789
790 static u64 spufs_signal1_type_get(void *data)
791 {
792         struct spu_context *ctx = data;
793         u64 ret;
794
795         spu_acquire(ctx);
796         ret = ctx->ops->signal1_type_get(ctx);
797         spu_release(ctx);
798
799         return ret;
800 }
801 DEFINE_SIMPLE_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get,
802                                         spufs_signal1_type_set, "%llu");
803
804 static void spufs_signal2_type_set(void *data, u64 val)
805 {
806         struct spu_context *ctx = data;
807
808         spu_acquire(ctx);
809         ctx->ops->signal2_type_set(ctx, val);
810         spu_release(ctx);
811 }
812
813 static u64 spufs_signal2_type_get(void *data)
814 {
815         struct spu_context *ctx = data;
816         u64 ret;
817
818         spu_acquire(ctx);
819         ret = ctx->ops->signal2_type_get(ctx);
820         spu_release(ctx);
821
822         return ret;
823 }
824 DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get,
825                                         spufs_signal2_type_set, "%llu");
826
827 #ifdef CONFIG_SPUFS_MMAP
828 static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma,
829                                            unsigned long address, int *type)
830 {
831         return spufs_ps_nopage(vma, address, type, 0x3000);
832 }
833
834 static struct vm_operations_struct spufs_mfc_mmap_vmops = {
835         .nopage = spufs_mfc_mmap_nopage,
836 };
837
838 /*
839  * mmap support for problem state MFC DMA area [0x0000 - 0x0fff].
840  * Mapping this area requires that the application have CAP_SYS_RAWIO,
841  * as these registers require special care when read/writing.
842  */
843 static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma)
844 {
845         if (!(vma->vm_flags & VM_SHARED))
846                 return -EINVAL;
847
848         if (!capable(CAP_SYS_RAWIO))
849                 return -EPERM;
850
851         vma->vm_flags |= VM_RESERVED;
852         vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
853                                      | _PAGE_NO_CACHE);
854
855         vma->vm_ops = &spufs_mfc_mmap_vmops;
856         return 0;
857 }
858 #endif
859
860 static int spufs_mfc_open(struct inode *inode, struct file *file)
861 {
862         struct spufs_inode_info *i = SPUFS_I(inode);
863         struct spu_context *ctx = i->i_ctx;
864
865         /* we don't want to deal with DMA into other processes */
866         if (ctx->owner != current->mm)
867                 return -EINVAL;
868
869         if (atomic_read(&inode->i_count) != 1)
870                 return -EBUSY;
871
872         file->private_data = ctx;
873         return nonseekable_open(inode, file);
874 }
875
876 /* interrupt-level mfc callback function. */
877 void spufs_mfc_callback(struct spu *spu)
878 {
879         struct spu_context *ctx = spu->ctx;
880
881         wake_up_all(&ctx->mfc_wq);
882
883         pr_debug("%s %s\n", __FUNCTION__, spu->name);
884         if (ctx->mfc_fasync) {
885                 u32 free_elements, tagstatus;
886                 unsigned int mask;
887
888                 /* no need for spu_acquire in interrupt context */
889                 free_elements = ctx->ops->get_mfc_free_elements(ctx);
890                 tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
891
892                 mask = 0;
893                 if (free_elements & 0xffff)
894                         mask |= POLLOUT;
895                 if (tagstatus & ctx->tagwait)
896                         mask |= POLLIN;
897
898                 kill_fasync(&ctx->mfc_fasync, SIGIO, mask);
899         }
900 }
901
902 static int spufs_read_mfc_tagstatus(struct spu_context *ctx, u32 *status)
903 {
904         /* See if there is one tag group is complete */
905         /* FIXME we need locking around tagwait */
906         *status = ctx->ops->read_mfc_tagstatus(ctx) & ctx->tagwait;
907         ctx->tagwait &= ~*status;
908         if (*status)
909                 return 1;
910
911         /* enable interrupt waiting for any tag group,
912            may silently fail if interrupts are already enabled */
913         ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1);
914         return 0;
915 }
916
917 static ssize_t spufs_mfc_read(struct file *file, char __user *buffer,
918                         size_t size, loff_t *pos)
919 {
920         struct spu_context *ctx = file->private_data;
921         int ret = -EINVAL;
922         u32 status;
923
924         if (size != 4)
925                 goto out;
926
927         spu_acquire(ctx);
928         if (file->f_flags & O_NONBLOCK) {
929                 status = ctx->ops->read_mfc_tagstatus(ctx);
930                 if (!(status & ctx->tagwait))
931                         ret = -EAGAIN;
932                 else
933                         ctx->tagwait &= ~status;
934         } else {
935                 ret = spufs_wait(ctx->mfc_wq,
936                            spufs_read_mfc_tagstatus(ctx, &status));
937         }
938         spu_release(ctx);
939
940         if (ret)
941                 goto out;
942
943         ret = 4;
944         if (copy_to_user(buffer, &status, 4))
945                 ret = -EFAULT;
946
947 out:
948         return ret;
949 }
950
951 static int spufs_check_valid_dma(struct mfc_dma_command *cmd)
952 {
953         pr_debug("queueing DMA %x %lx %x %x %x\n", cmd->lsa,
954                  cmd->ea, cmd->size, cmd->tag, cmd->cmd);
955
956         switch (cmd->cmd) {
957         case MFC_PUT_CMD:
958         case MFC_PUTF_CMD:
959         case MFC_PUTB_CMD:
960         case MFC_GET_CMD:
961         case MFC_GETF_CMD:
962         case MFC_GETB_CMD:
963                 break;
964         default:
965                 pr_debug("invalid DMA opcode %x\n", cmd->cmd);
966                 return -EIO;
967         }
968
969         if ((cmd->lsa & 0xf) != (cmd->ea &0xf)) {
970                 pr_debug("invalid DMA alignment, ea %lx lsa %x\n",
971                                 cmd->ea, cmd->lsa);
972                 return -EIO;
973         }
974
975         switch (cmd->size & 0xf) {
976         case 1:
977                 break;
978         case 2:
979                 if (cmd->lsa & 1)
980                         goto error;
981                 break;
982         case 4:
983                 if (cmd->lsa & 3)
984                         goto error;
985                 break;
986         case 8:
987                 if (cmd->lsa & 7)
988                         goto error;
989                 break;
990         case 0:
991                 if (cmd->lsa & 15)
992                         goto error;
993                 break;
994         error:
995         default:
996                 pr_debug("invalid DMA alignment %x for size %x\n",
997                         cmd->lsa & 0xf, cmd->size);
998                 return -EIO;
999         }
1000
1001         if (cmd->size > 16 * 1024) {
1002                 pr_debug("invalid DMA size %x\n", cmd->size);
1003                 return -EIO;
1004         }
1005
1006         if (cmd->tag & 0xfff0) {
1007                 /* we reserve the higher tag numbers for kernel use */
1008                 pr_debug("invalid DMA tag\n");
1009                 return -EIO;
1010         }
1011
1012         if (cmd->class) {
1013                 /* not supported in this version */
1014                 pr_debug("invalid DMA class\n");
1015                 return -EIO;
1016         }
1017
1018         return 0;
1019 }
1020
1021 static int spu_send_mfc_command(struct spu_context *ctx,
1022                                 struct mfc_dma_command cmd,
1023                                 int *error)
1024 {
1025         *error = ctx->ops->send_mfc_command(ctx, &cmd);
1026         if (*error == -EAGAIN) {
1027                 /* wait for any tag group to complete
1028                    so we have space for the new command */
1029                 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1);
1030                 /* try again, because the queue might be
1031                    empty again */
1032                 *error = ctx->ops->send_mfc_command(ctx, &cmd);
1033                 if (*error == -EAGAIN)
1034                         return 0;
1035         }
1036         return 1;
1037 }
1038
1039 static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
1040                         size_t size, loff_t *pos)
1041 {
1042         struct spu_context *ctx = file->private_data;
1043         struct mfc_dma_command cmd;
1044         int ret = -EINVAL;
1045
1046         if (size != sizeof cmd)
1047                 goto out;
1048
1049         ret = -EFAULT;
1050         if (copy_from_user(&cmd, buffer, sizeof cmd))
1051                 goto out;
1052
1053         ret = spufs_check_valid_dma(&cmd);
1054         if (ret)
1055                 goto out;
1056
1057         spu_acquire_runnable(ctx);
1058         if (file->f_flags & O_NONBLOCK) {
1059                 ret = ctx->ops->send_mfc_command(ctx, &cmd);
1060         } else {
1061                 int status;
1062                 ret = spufs_wait(ctx->mfc_wq,
1063                                  spu_send_mfc_command(ctx, cmd, &status));
1064                 if (status)
1065                         ret = status;
1066         }
1067         spu_release(ctx);
1068
1069         if (ret)
1070                 goto out;
1071
1072         ctx->tagwait |= 1 << cmd.tag;
1073
1074 out:
1075         return ret;
1076 }
1077
1078 static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait)
1079 {
1080         struct spu_context *ctx = file->private_data;
1081         u32 free_elements, tagstatus;
1082         unsigned int mask;
1083
1084         spu_acquire(ctx);
1085         ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
1086         free_elements = ctx->ops->get_mfc_free_elements(ctx);
1087         tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
1088         spu_release(ctx);
1089
1090         poll_wait(file, &ctx->mfc_wq, wait);
1091
1092         mask = 0;
1093         if (free_elements & 0xffff)
1094                 mask |= POLLOUT | POLLWRNORM;
1095         if (tagstatus & ctx->tagwait)
1096                 mask |= POLLIN | POLLRDNORM;
1097
1098         pr_debug("%s: free %d tagstatus %d tagwait %d\n", __FUNCTION__,
1099                 free_elements, tagstatus, ctx->tagwait);
1100
1101         return mask;
1102 }
1103
1104 static int spufs_mfc_flush(struct file *file)
1105 {
1106         struct spu_context *ctx = file->private_data;
1107         int ret;
1108
1109         spu_acquire(ctx);
1110 #if 0
1111 /* this currently hangs */
1112         ret = spufs_wait(ctx->mfc_wq,
1113                          ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2));
1114         if (ret)
1115                 goto out;
1116         ret = spufs_wait(ctx->mfc_wq,
1117                          ctx->ops->read_mfc_tagstatus(ctx) == ctx->tagwait);
1118 out:
1119 #else
1120         ret = 0;
1121 #endif
1122         spu_release(ctx);
1123
1124         return ret;
1125 }
1126
1127 static int spufs_mfc_fsync(struct file *file, struct dentry *dentry,
1128                            int datasync)
1129 {
1130         return spufs_mfc_flush(file);
1131 }
1132
1133 static int spufs_mfc_fasync(int fd, struct file *file, int on)
1134 {
1135         struct spu_context *ctx = file->private_data;
1136
1137         return fasync_helper(fd, file, on, &ctx->mfc_fasync);
1138 }
1139
1140 static struct file_operations spufs_mfc_fops = {
1141         .open    = spufs_mfc_open,
1142         .read    = spufs_mfc_read,
1143         .write   = spufs_mfc_write,
1144         .poll    = spufs_mfc_poll,
1145         .flush   = spufs_mfc_flush,
1146         .fsync   = spufs_mfc_fsync,
1147         .fasync  = spufs_mfc_fasync,
1148 #ifdef CONFIG_SPUFS_MMAP
1149         .mmap    = spufs_mfc_mmap,
1150 #endif
1151 };
1152
1153 static void spufs_npc_set(void *data, u64 val)
1154 {
1155         struct spu_context *ctx = data;
1156         spu_acquire(ctx);
1157         ctx->ops->npc_write(ctx, val);
1158         spu_release(ctx);
1159 }
1160
1161 static u64 spufs_npc_get(void *data)
1162 {
1163         struct spu_context *ctx = data;
1164         u64 ret;
1165         spu_acquire(ctx);
1166         ret = ctx->ops->npc_read(ctx);
1167         spu_release(ctx);
1168         return ret;
1169 }
1170 DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, "%llx\n")
1171
1172 static void spufs_decr_set(void *data, u64 val)
1173 {
1174         struct spu_context *ctx = data;
1175         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1176         spu_acquire_saved(ctx);
1177         lscsa->decr.slot[0] = (u32) val;
1178         spu_release(ctx);
1179 }
1180
1181 static u64 spufs_decr_get(void *data)
1182 {
1183         struct spu_context *ctx = data;
1184         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1185         u64 ret;
1186         spu_acquire_saved(ctx);
1187         ret = lscsa->decr.slot[0];
1188         spu_release(ctx);
1189         return ret;
1190 }
1191 DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
1192                         "%llx\n")
1193
1194 static void spufs_decr_status_set(void *data, u64 val)
1195 {
1196         struct spu_context *ctx = data;
1197         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1198         spu_acquire_saved(ctx);
1199         lscsa->decr_status.slot[0] = (u32) val;
1200         spu_release(ctx);
1201 }
1202
1203 static u64 spufs_decr_status_get(void *data)
1204 {
1205         struct spu_context *ctx = data;
1206         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1207         u64 ret;
1208         spu_acquire_saved(ctx);
1209         ret = lscsa->decr_status.slot[0];
1210         spu_release(ctx);
1211         return ret;
1212 }
1213 DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get,
1214                         spufs_decr_status_set, "%llx\n")
1215
1216 static void spufs_spu_tag_mask_set(void *data, u64 val)
1217 {
1218         struct spu_context *ctx = data;
1219         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1220         spu_acquire_saved(ctx);
1221         lscsa->tag_mask.slot[0] = (u32) val;
1222         spu_release(ctx);
1223 }
1224
1225 static u64 spufs_spu_tag_mask_get(void *data)
1226 {
1227         struct spu_context *ctx = data;
1228         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1229         u64 ret;
1230         spu_acquire_saved(ctx);
1231         ret = lscsa->tag_mask.slot[0];
1232         spu_release(ctx);
1233         return ret;
1234 }
1235 DEFINE_SIMPLE_ATTRIBUTE(spufs_spu_tag_mask_ops, spufs_spu_tag_mask_get,
1236                         spufs_spu_tag_mask_set, "%llx\n")
1237
1238 static void spufs_event_mask_set(void *data, u64 val)
1239 {
1240         struct spu_context *ctx = data;
1241         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1242         spu_acquire_saved(ctx);
1243         lscsa->event_mask.slot[0] = (u32) val;
1244         spu_release(ctx);
1245 }
1246
1247 static u64 spufs_event_mask_get(void *data)
1248 {
1249         struct spu_context *ctx = data;
1250         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1251         u64 ret;
1252         spu_acquire_saved(ctx);
1253         ret = lscsa->event_mask.slot[0];
1254         spu_release(ctx);
1255         return ret;
1256 }
1257 DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get,
1258                         spufs_event_mask_set, "%llx\n")
1259
1260 static void spufs_srr0_set(void *data, u64 val)
1261 {
1262         struct spu_context *ctx = data;
1263         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1264         spu_acquire_saved(ctx);
1265         lscsa->srr0.slot[0] = (u32) val;
1266         spu_release(ctx);
1267 }
1268
1269 static u64 spufs_srr0_get(void *data)
1270 {
1271         struct spu_context *ctx = data;
1272         struct spu_lscsa *lscsa = ctx->csa.lscsa;
1273         u64 ret;
1274         spu_acquire_saved(ctx);
1275         ret = lscsa->srr0.slot[0];
1276         spu_release(ctx);
1277         return ret;
1278 }
1279 DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set,
1280                         "%llx\n")
1281
1282 struct tree_descr spufs_dir_contents[] = {
1283         { "mem",  &spufs_mem_fops,  0666, },
1284         { "regs", &spufs_regs_fops,  0666, },
1285         { "mbox", &spufs_mbox_fops, 0444, },
1286         { "ibox", &spufs_ibox_fops, 0444, },
1287         { "wbox", &spufs_wbox_fops, 0222, },
1288         { "mbox_stat", &spufs_mbox_stat_fops, 0444, },
1289         { "ibox_stat", &spufs_ibox_stat_fops, 0444, },
1290         { "wbox_stat", &spufs_wbox_stat_fops, 0444, },
1291         { "signal1", &spufs_signal1_fops, 0666, },
1292         { "signal2", &spufs_signal2_fops, 0666, },
1293         { "signal1_type", &spufs_signal1_type, 0666, },
1294         { "signal2_type", &spufs_signal2_type, 0666, },
1295         { "mfc", &spufs_mfc_fops, 0666, },
1296         { "cntl", &spufs_cntl_fops,  0666, },
1297         { "npc", &spufs_npc_ops, 0666, },
1298         { "fpcr", &spufs_fpcr_fops, 0666, },
1299         { "decr", &spufs_decr_ops, 0666, },
1300         { "decr_status", &spufs_decr_status_ops, 0666, },
1301         { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, },
1302         { "event_mask", &spufs_event_mask_ops, 0666, },
1303         { "srr0", &spufs_srr0_ops, 0666, },
1304         {},
1305 };