aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394/raw1394.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ieee1394/raw1394.c')
-rw-r--r--drivers/ieee1394/raw1394.c230
1 files changed, 127 insertions, 103 deletions
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index c7833bb37ae1..9f19ac492106 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -34,6 +34,7 @@
34#include <linux/fs.h> 34#include <linux/fs.h>
35#include <linux/poll.h> 35#include <linux/poll.h>
36#include <linux/module.h> 36#include <linux/module.h>
37#include <linux/mutex.h>
37#include <linux/init.h> 38#include <linux/init.h>
38#include <linux/interrupt.h> 39#include <linux/interrupt.h>
39#include <linux/vmalloc.h> 40#include <linux/vmalloc.h>
@@ -2267,6 +2268,8 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
2267 return -EFAULT; 2268 return -EFAULT;
2268 } 2269 }
2269 2270
2271 mutex_lock(&fi->state_mutex);
2272
2270 switch (fi->state) { 2273 switch (fi->state) {
2271 case opened: 2274 case opened:
2272 retval = state_opened(fi, req); 2275 retval = state_opened(fi, req);
@@ -2281,6 +2284,8 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
2281 break; 2284 break;
2282 } 2285 }
2283 2286
2287 mutex_unlock(&fi->state_mutex);
2288
2284 if (retval < 0) { 2289 if (retval < 0) {
2285 free_pending_request(req); 2290 free_pending_request(req);
2286 } else { 2291 } else {
@@ -2541,109 +2546,120 @@ static int raw1394_read_cycle_timer(struct file_info *fi, void __user * uaddr)
2541static int raw1394_mmap(struct file *file, struct vm_area_struct *vma) 2546static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
2542{ 2547{
2543 struct file_info *fi = file->private_data; 2548 struct file_info *fi = file->private_data;
2549 int ret;
2550
2551 mutex_lock(&fi->state_mutex);
2544 2552
2545 if (fi->iso_state == RAW1394_ISO_INACTIVE) 2553 if (fi->iso_state == RAW1394_ISO_INACTIVE)
2546 return -EINVAL; 2554 ret = -EINVAL;
2555 else
2556 ret = dma_region_mmap(&fi->iso_handle->data_buf, file, vma);
2557
2558 mutex_unlock(&fi->state_mutex);
2547 2559
2548 return dma_region_mmap(&fi->iso_handle->data_buf, file, vma); 2560 return ret;
2549} 2561}
2550 2562
2551/* ioctl is only used for rawiso operations */ 2563static long raw1394_ioctl_inactive(struct file_info *fi, unsigned int cmd,
2552static long do_raw1394_ioctl(struct file *file, unsigned int cmd, 2564 void __user *argp)
2553 unsigned long arg) 2565{
2566 switch (cmd) {
2567 case RAW1394_IOC_ISO_XMIT_INIT:
2568 return raw1394_iso_xmit_init(fi, argp);
2569 case RAW1394_IOC_ISO_RECV_INIT:
2570 return raw1394_iso_recv_init(fi, argp);
2571 default:
2572 return -EINVAL;
2573 }
2574}
2575
2576static long raw1394_ioctl_recv(struct file_info *fi, unsigned int cmd,
2577 unsigned long arg)
2554{ 2578{
2555 struct file_info *fi = file->private_data;
2556 void __user *argp = (void __user *)arg; 2579 void __user *argp = (void __user *)arg;
2557 2580
2558 switch (fi->iso_state) { 2581 switch (cmd) {
2559 case RAW1394_ISO_INACTIVE: 2582 case RAW1394_IOC_ISO_RECV_START:{
2560 switch (cmd) { 2583 int args[3];
2561 case RAW1394_IOC_ISO_XMIT_INIT: 2584
2562 return raw1394_iso_xmit_init(fi, argp); 2585 if (copy_from_user(&args[0], argp, sizeof(args)))
2563 case RAW1394_IOC_ISO_RECV_INIT: 2586 return -EFAULT;
2564 return raw1394_iso_recv_init(fi, argp); 2587 return hpsb_iso_recv_start(fi->iso_handle,
2565 default: 2588 args[0], args[1], args[2]);
2566 break;
2567 } 2589 }
2568 break; 2590 case RAW1394_IOC_ISO_XMIT_RECV_STOP:
2569 case RAW1394_ISO_RECV: 2591 hpsb_iso_stop(fi->iso_handle);
2570 switch (cmd) { 2592 return 0;
2571 case RAW1394_IOC_ISO_RECV_START:{ 2593 case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
2572 /* copy args from user-space */ 2594 return hpsb_iso_recv_listen_channel(fi->iso_handle, arg);
2573 int args[3]; 2595 case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
2574 if (copy_from_user 2596 return hpsb_iso_recv_unlisten_channel(fi->iso_handle, arg);
2575 (&args[0], argp, sizeof(args))) 2597 case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{
2576 return -EFAULT; 2598 u64 mask;
2577 return hpsb_iso_recv_start(fi->iso_handle, 2599
2578 args[0], args[1], 2600 if (copy_from_user(&mask, argp, sizeof(mask)))
2579 args[2]); 2601 return -EFAULT;
2580 } 2602 return hpsb_iso_recv_set_channel_mask(fi->iso_handle,
2581 case RAW1394_IOC_ISO_XMIT_RECV_STOP: 2603 mask);
2582 hpsb_iso_stop(fi->iso_handle);
2583 return 0;
2584 case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
2585 return hpsb_iso_recv_listen_channel(fi->iso_handle,
2586 arg);
2587 case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
2588 return hpsb_iso_recv_unlisten_channel(fi->iso_handle,
2589 arg);
2590 case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{
2591 /* copy the u64 from user-space */
2592 u64 mask;
2593 if (copy_from_user(&mask, argp, sizeof(mask)))
2594 return -EFAULT;
2595 return hpsb_iso_recv_set_channel_mask(fi->
2596 iso_handle,
2597 mask);
2598 }
2599 case RAW1394_IOC_ISO_GET_STATUS:
2600 return raw1394_iso_get_status(fi, argp);
2601 case RAW1394_IOC_ISO_RECV_PACKETS:
2602 return raw1394_iso_recv_packets(fi, argp);
2603 case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
2604 return hpsb_iso_recv_release_packets(fi->iso_handle,
2605 arg);
2606 case RAW1394_IOC_ISO_RECV_FLUSH:
2607 return hpsb_iso_recv_flush(fi->iso_handle);
2608 case RAW1394_IOC_ISO_SHUTDOWN:
2609 raw1394_iso_shutdown(fi);
2610 return 0;
2611 case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
2612 queue_rawiso_event(fi);
2613 return 0;
2614 } 2604 }
2615 break; 2605 case RAW1394_IOC_ISO_GET_STATUS:
2616 case RAW1394_ISO_XMIT: 2606 return raw1394_iso_get_status(fi, argp);
2617 switch (cmd) { 2607 case RAW1394_IOC_ISO_RECV_PACKETS:
2618 case RAW1394_IOC_ISO_XMIT_START:{ 2608 return raw1394_iso_recv_packets(fi, argp);
2619 /* copy two ints from user-space */ 2609 case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
2620 int args[2]; 2610 return hpsb_iso_recv_release_packets(fi->iso_handle, arg);
2621 if (copy_from_user 2611 case RAW1394_IOC_ISO_RECV_FLUSH:
2622 (&args[0], argp, sizeof(args))) 2612 return hpsb_iso_recv_flush(fi->iso_handle);
2623 return -EFAULT; 2613 case RAW1394_IOC_ISO_SHUTDOWN:
2624 return hpsb_iso_xmit_start(fi->iso_handle, 2614 raw1394_iso_shutdown(fi);
2625 args[0], args[1]); 2615 return 0;
2626 } 2616 case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
2627 case RAW1394_IOC_ISO_XMIT_SYNC: 2617 queue_rawiso_event(fi);
2628 return hpsb_iso_xmit_sync(fi->iso_handle); 2618 return 0;
2629 case RAW1394_IOC_ISO_XMIT_RECV_STOP: 2619 default:
2630 hpsb_iso_stop(fi->iso_handle); 2620 return -EINVAL;
2631 return 0; 2621 }
2632 case RAW1394_IOC_ISO_GET_STATUS: 2622}
2633 return raw1394_iso_get_status(fi, argp); 2623
2634 case RAW1394_IOC_ISO_XMIT_PACKETS: 2624static long raw1394_ioctl_xmit(struct file_info *fi, unsigned int cmd,
2635 return raw1394_iso_send_packets(fi, argp); 2625 void __user *argp)
2636 case RAW1394_IOC_ISO_SHUTDOWN: 2626{
2637 raw1394_iso_shutdown(fi); 2627 switch (cmd) {
2638 return 0; 2628 case RAW1394_IOC_ISO_XMIT_START:{
2639 case RAW1394_IOC_ISO_QUEUE_ACTIVITY: 2629 int args[2];
2640 queue_rawiso_event(fi); 2630
2641 return 0; 2631 if (copy_from_user(&args[0], argp, sizeof(args)))
2632 return -EFAULT;
2633 return hpsb_iso_xmit_start(fi->iso_handle,
2634 args[0], args[1]);
2642 } 2635 }
2643 break; 2636 case RAW1394_IOC_ISO_XMIT_SYNC:
2637 return hpsb_iso_xmit_sync(fi->iso_handle);
2638 case RAW1394_IOC_ISO_XMIT_RECV_STOP:
2639 hpsb_iso_stop(fi->iso_handle);
2640 return 0;
2641 case RAW1394_IOC_ISO_GET_STATUS:
2642 return raw1394_iso_get_status(fi, argp);
2643 case RAW1394_IOC_ISO_XMIT_PACKETS:
2644 return raw1394_iso_send_packets(fi, argp);
2645 case RAW1394_IOC_ISO_SHUTDOWN:
2646 raw1394_iso_shutdown(fi);
2647 return 0;
2648 case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
2649 queue_rawiso_event(fi);
2650 return 0;
2644 default: 2651 default:
2645 break; 2652 return -EINVAL;
2646 } 2653 }
2654}
2655
2656/* ioctl is only used for rawiso operations */
2657static long raw1394_ioctl(struct file *file, unsigned int cmd,
2658 unsigned long arg)
2659{
2660 struct file_info *fi = file->private_data;
2661 void __user *argp = (void __user *)arg;
2662 long ret;
2647 2663
2648 /* state-independent commands */ 2664 /* state-independent commands */
2649 switch(cmd) { 2665 switch(cmd) {
@@ -2653,16 +2669,25 @@ static long do_raw1394_ioctl(struct file *file, unsigned int cmd,
2653 break; 2669 break;
2654 } 2670 }
2655 2671
2656 return -EINVAL; 2672 mutex_lock(&fi->state_mutex);
2657} 2673
2674 switch (fi->iso_state) {
2675 case RAW1394_ISO_INACTIVE:
2676 ret = raw1394_ioctl_inactive(fi, cmd, argp);
2677 break;
2678 case RAW1394_ISO_RECV:
2679 ret = raw1394_ioctl_recv(fi, cmd, arg);
2680 break;
2681 case RAW1394_ISO_XMIT:
2682 ret = raw1394_ioctl_xmit(fi, cmd, argp);
2683 break;
2684 default:
2685 ret = -EINVAL;
2686 break;
2687 }
2688
2689 mutex_unlock(&fi->state_mutex);
2658 2690
2659static long raw1394_ioctl(struct file *file, unsigned int cmd,
2660 unsigned long arg)
2661{
2662 long ret;
2663 lock_kernel();
2664 ret = do_raw1394_ioctl(file, cmd, arg);
2665 unlock_kernel();
2666 return ret; 2691 return ret;
2667} 2692}
2668 2693
@@ -2700,7 +2725,7 @@ static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd,
2700 !copy_from_user(&infos32, &arg->infos, sizeof infos32)) { 2725 !copy_from_user(&infos32, &arg->infos, sizeof infos32)) {
2701 infos = compat_ptr(infos32); 2726 infos = compat_ptr(infos32);
2702 if (!copy_to_user(&dst->infos, &infos, sizeof infos)) 2727 if (!copy_to_user(&dst->infos, &infos, sizeof infos))
2703 err = do_raw1394_ioctl(file, cmd, (unsigned long)dst); 2728 err = raw1394_ioctl(file, cmd, (unsigned long)dst);
2704 } 2729 }
2705 return err; 2730 return err;
2706} 2731}
@@ -2724,7 +2749,6 @@ static long raw1394_compat_ioctl(struct file *file,
2724 void __user *argp = (void __user *)arg; 2749 void __user *argp = (void __user *)arg;
2725 long err; 2750 long err;
2726 2751
2727 lock_kernel();
2728 switch (cmd) { 2752 switch (cmd) {
2729 /* These requests have same format as long as 'int' has same size. */ 2753 /* These requests have same format as long as 'int' has same size. */
2730 case RAW1394_IOC_ISO_RECV_INIT: 2754 case RAW1394_IOC_ISO_RECV_INIT:
@@ -2741,7 +2765,7 @@ static long raw1394_compat_ioctl(struct file *file,
2741 case RAW1394_IOC_ISO_GET_STATUS: 2765 case RAW1394_IOC_ISO_GET_STATUS:
2742 case RAW1394_IOC_ISO_SHUTDOWN: 2766 case RAW1394_IOC_ISO_SHUTDOWN:
2743 case RAW1394_IOC_ISO_QUEUE_ACTIVITY: 2767 case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
2744 err = do_raw1394_ioctl(file, cmd, arg); 2768 err = raw1394_ioctl(file, cmd, arg);
2745 break; 2769 break;
2746 /* These request have different format. */ 2770 /* These request have different format. */
2747 case RAW1394_IOC_ISO_RECV_PACKETS32: 2771 case RAW1394_IOC_ISO_RECV_PACKETS32:
@@ -2757,7 +2781,6 @@ static long raw1394_compat_ioctl(struct file *file,
2757 err = -EINVAL; 2781 err = -EINVAL;
2758 break; 2782 break;
2759 } 2783 }
2760 unlock_kernel();
2761 2784
2762 return err; 2785 return err;
2763} 2786}
@@ -2791,6 +2814,7 @@ static int raw1394_open(struct inode *inode, struct file *file)
2791 fi->notification = (u8) RAW1394_NOTIFY_ON; /* busreset notification */ 2814 fi->notification = (u8) RAW1394_NOTIFY_ON; /* busreset notification */
2792 2815
2793 INIT_LIST_HEAD(&fi->list); 2816 INIT_LIST_HEAD(&fi->list);
2817 mutex_init(&fi->state_mutex);
2794 fi->state = opened; 2818 fi->state = opened;
2795 INIT_LIST_HEAD(&fi->req_pending); 2819 INIT_LIST_HEAD(&fi->req_pending);
2796 INIT_LIST_HEAD(&fi->req_complete); 2820 INIT_LIST_HEAD(&fi->req_complete);