aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2008-08-16 11:52:04 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2008-10-15 16:21:08 -0400
commitddfb908d3f905dbb5964d6fbf783e69c417eb13e (patch)
tree9c271214e94eab002378daee5d6c8f8cbebb5762 /drivers
parent10963ea1bd966ba46a46178c4d6abcdf3c23538d (diff)
ieee1394: raw1394: narrow down the state_mutex protected region
Refactor the ioctl dispatcher in order to move a fraction of it out of the section which is serialized by fi->state_mutex. This is not so much about performance but more about self-documentation: The mutex_lock()/ mutex_unlock() calls are now closer to the data accesses which the mutex protects, i.e. to the iso_state switch. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ieee1394/raw1394.c211
1 files changed, 110 insertions, 101 deletions
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 975ed7062aa1..d1594427601f 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -2556,102 +2556,106 @@ static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
2556 return ret; 2556 return ret;
2557} 2557}
2558 2558
2559/* ioctl is only used for rawiso operations */ 2559static long raw1394_ioctl_inactive(struct file_info *fi, unsigned int cmd,
2560static long do_raw1394_ioctl(struct file *file, unsigned int cmd, 2560 void __user *argp)
2561 unsigned long arg) 2561{
2562 switch (cmd) {
2563 case RAW1394_IOC_ISO_XMIT_INIT:
2564 return raw1394_iso_xmit_init(fi, argp);
2565 case RAW1394_IOC_ISO_RECV_INIT:
2566 return raw1394_iso_recv_init(fi, argp);
2567 default:
2568 return -EINVAL;
2569 }
2570}
2571
2572static long raw1394_ioctl_recv(struct file_info *fi, unsigned int cmd,
2573 unsigned long arg)
2562{ 2574{
2563 struct file_info *fi = file->private_data;
2564 void __user *argp = (void __user *)arg; 2575 void __user *argp = (void __user *)arg;
2565 2576
2566 switch (fi->iso_state) { 2577 switch (cmd) {
2567 case RAW1394_ISO_INACTIVE: 2578 case RAW1394_IOC_ISO_RECV_START:{
2568 switch (cmd) { 2579 int args[3];
2569 case RAW1394_IOC_ISO_XMIT_INIT: 2580
2570 return raw1394_iso_xmit_init(fi, argp); 2581 if (copy_from_user(&args[0], argp, sizeof(args)))
2571 case RAW1394_IOC_ISO_RECV_INIT: 2582 return -EFAULT;
2572 return raw1394_iso_recv_init(fi, argp); 2583 return hpsb_iso_recv_start(fi->iso_handle,
2573 default: 2584 args[0], args[1], args[2]);
2574 break;
2575 } 2585 }
2576 break; 2586 case RAW1394_IOC_ISO_XMIT_RECV_STOP:
2577 case RAW1394_ISO_RECV: 2587 hpsb_iso_stop(fi->iso_handle);
2578 switch (cmd) { 2588 return 0;
2579 case RAW1394_IOC_ISO_RECV_START:{ 2589 case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
2580 /* copy args from user-space */ 2590 return hpsb_iso_recv_listen_channel(fi->iso_handle, arg);
2581 int args[3]; 2591 case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
2582 if (copy_from_user 2592 return hpsb_iso_recv_unlisten_channel(fi->iso_handle, arg);
2583 (&args[0], argp, sizeof(args))) 2593 case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{
2584 return -EFAULT; 2594 u64 mask;
2585 return hpsb_iso_recv_start(fi->iso_handle, 2595
2586 args[0], args[1], 2596 if (copy_from_user(&mask, argp, sizeof(mask)))
2587 args[2]); 2597 return -EFAULT;
2588 } 2598 return hpsb_iso_recv_set_channel_mask(fi->iso_handle,
2589 case RAW1394_IOC_ISO_XMIT_RECV_STOP: 2599 mask);
2590 hpsb_iso_stop(fi->iso_handle);
2591 return 0;
2592 case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
2593 return hpsb_iso_recv_listen_channel(fi->iso_handle,
2594 arg);
2595 case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
2596 return hpsb_iso_recv_unlisten_channel(fi->iso_handle,
2597 arg);
2598 case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{
2599 /* copy the u64 from user-space */
2600 u64 mask;
2601 if (copy_from_user(&mask, argp, sizeof(mask)))
2602 return -EFAULT;
2603 return hpsb_iso_recv_set_channel_mask(fi->
2604 iso_handle,
2605 mask);
2606 }
2607 case RAW1394_IOC_ISO_GET_STATUS:
2608 return raw1394_iso_get_status(fi, argp);
2609 case RAW1394_IOC_ISO_RECV_PACKETS:
2610 return raw1394_iso_recv_packets(fi, argp);
2611 case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
2612 return hpsb_iso_recv_release_packets(fi->iso_handle,
2613 arg);
2614 case RAW1394_IOC_ISO_RECV_FLUSH:
2615 return hpsb_iso_recv_flush(fi->iso_handle);
2616 case RAW1394_IOC_ISO_SHUTDOWN:
2617 raw1394_iso_shutdown(fi);
2618 return 0;
2619 case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
2620 queue_rawiso_event(fi);
2621 return 0;
2622 } 2600 }
2623 break; 2601 case RAW1394_IOC_ISO_GET_STATUS:
2624 case RAW1394_ISO_XMIT: 2602 return raw1394_iso_get_status(fi, argp);
2625 switch (cmd) { 2603 case RAW1394_IOC_ISO_RECV_PACKETS:
2626 case RAW1394_IOC_ISO_XMIT_START:{ 2604 return raw1394_iso_recv_packets(fi, argp);
2627 /* copy two ints from user-space */ 2605 case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
2628 int args[2]; 2606 return hpsb_iso_recv_release_packets(fi->iso_handle, arg);
2629 if (copy_from_user 2607 case RAW1394_IOC_ISO_RECV_FLUSH:
2630 (&args[0], argp, sizeof(args))) 2608 return hpsb_iso_recv_flush(fi->iso_handle);
2631 return -EFAULT; 2609 case RAW1394_IOC_ISO_SHUTDOWN:
2632 return hpsb_iso_xmit_start(fi->iso_handle, 2610 raw1394_iso_shutdown(fi);
2633 args[0], args[1]); 2611 return 0;
2634 } 2612 case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
2635 case RAW1394_IOC_ISO_XMIT_SYNC: 2613 queue_rawiso_event(fi);
2636 return hpsb_iso_xmit_sync(fi->iso_handle); 2614 return 0;
2637 case RAW1394_IOC_ISO_XMIT_RECV_STOP: 2615 default:
2638 hpsb_iso_stop(fi->iso_handle); 2616 return -EINVAL;
2639 return 0; 2617 }
2640 case RAW1394_IOC_ISO_GET_STATUS: 2618}
2641 return raw1394_iso_get_status(fi, argp); 2619
2642 case RAW1394_IOC_ISO_XMIT_PACKETS: 2620static long raw1394_ioctl_xmit(struct file_info *fi, unsigned int cmd,
2643 return raw1394_iso_send_packets(fi, argp); 2621 void __user *argp)
2644 case RAW1394_IOC_ISO_SHUTDOWN: 2622{
2645 raw1394_iso_shutdown(fi); 2623 switch (cmd) {
2646 return 0; 2624 case RAW1394_IOC_ISO_XMIT_START:{
2647 case RAW1394_IOC_ISO_QUEUE_ACTIVITY: 2625 int args[2];
2648 queue_rawiso_event(fi); 2626
2649 return 0; 2627 if (copy_from_user(&args[0], argp, sizeof(args)))
2628 return -EFAULT;
2629 return hpsb_iso_xmit_start(fi->iso_handle,
2630 args[0], args[1]);
2650 } 2631 }
2651 break; 2632 case RAW1394_IOC_ISO_XMIT_SYNC:
2633 return hpsb_iso_xmit_sync(fi->iso_handle);
2634 case RAW1394_IOC_ISO_XMIT_RECV_STOP:
2635 hpsb_iso_stop(fi->iso_handle);
2636 return 0;
2637 case RAW1394_IOC_ISO_GET_STATUS:
2638 return raw1394_iso_get_status(fi, argp);
2639 case RAW1394_IOC_ISO_XMIT_PACKETS:
2640 return raw1394_iso_send_packets(fi, argp);
2641 case RAW1394_IOC_ISO_SHUTDOWN:
2642 raw1394_iso_shutdown(fi);
2643 return 0;
2644 case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
2645 queue_rawiso_event(fi);
2646 return 0;
2652 default: 2647 default:
2653 break; 2648 return -EINVAL;
2654 } 2649 }
2650}
2651
2652/* ioctl is only used for rawiso operations */
2653static long raw1394_ioctl(struct file *file, unsigned int cmd,
2654 unsigned long arg)
2655{
2656 struct file_info *fi = file->private_data;
2657 void __user *argp = (void __user *)arg;
2658 long ret;
2655 2659
2656 /* state-independent commands */ 2660 /* state-independent commands */
2657 switch(cmd) { 2661 switch(cmd) {
@@ -2661,18 +2665,25 @@ static long do_raw1394_ioctl(struct file *file, unsigned int cmd,
2661 break; 2665 break;
2662 } 2666 }
2663 2667
2664 return -EINVAL; 2668 mutex_lock(&fi->state_mutex);
2665}
2666 2669
2667static long raw1394_ioctl(struct file *file, unsigned int cmd, 2670 switch (fi->iso_state) {
2668 unsigned long arg) 2671 case RAW1394_ISO_INACTIVE:
2669{ 2672 ret = raw1394_ioctl_inactive(fi, cmd, argp);
2670 struct file_info *fi = file->private_data; 2673 break;
2671 long ret; 2674 case RAW1394_ISO_RECV:
2675 ret = raw1394_ioctl_recv(fi, cmd, arg);
2676 break;
2677 case RAW1394_ISO_XMIT:
2678 ret = raw1394_ioctl_xmit(fi, cmd, argp);
2679 break;
2680 default:
2681 ret = -EINVAL;
2682 break;
2683 }
2672 2684
2673 mutex_lock(&fi->state_mutex);
2674 ret = do_raw1394_ioctl(file, cmd, arg);
2675 mutex_unlock(&fi->state_mutex); 2685 mutex_unlock(&fi->state_mutex);
2686
2676 return ret; 2687 return ret;
2677} 2688}
2678 2689
@@ -2710,7 +2721,7 @@ static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd,
2710 !copy_from_user(&infos32, &arg->infos, sizeof infos32)) { 2721 !copy_from_user(&infos32, &arg->infos, sizeof infos32)) {
2711 infos = compat_ptr(infos32); 2722 infos = compat_ptr(infos32);
2712 if (!copy_to_user(&dst->infos, &infos, sizeof infos)) 2723 if (!copy_to_user(&dst->infos, &infos, sizeof infos))
2713 err = do_raw1394_ioctl(file, cmd, (unsigned long)dst); 2724 err = raw1394_ioctl(file, cmd, (unsigned long)dst);
2714 } 2725 }
2715 return err; 2726 return err;
2716} 2727}
@@ -2734,7 +2745,6 @@ static long raw1394_compat_ioctl(struct file *file,
2734 void __user *argp = (void __user *)arg; 2745 void __user *argp = (void __user *)arg;
2735 long err; 2746 long err;
2736 2747
2737 mutex_lock(&fi->state_mutex);
2738 switch (cmd) { 2748 switch (cmd) {
2739 /* These requests have same format as long as 'int' has same size. */ 2749 /* These requests have same format as long as 'int' has same size. */
2740 case RAW1394_IOC_ISO_RECV_INIT: 2750 case RAW1394_IOC_ISO_RECV_INIT:
@@ -2751,7 +2761,7 @@ static long raw1394_compat_ioctl(struct file *file,
2751 case RAW1394_IOC_ISO_GET_STATUS: 2761 case RAW1394_IOC_ISO_GET_STATUS:
2752 case RAW1394_IOC_ISO_SHUTDOWN: 2762 case RAW1394_IOC_ISO_SHUTDOWN:
2753 case RAW1394_IOC_ISO_QUEUE_ACTIVITY: 2763 case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
2754 err = do_raw1394_ioctl(file, cmd, arg); 2764 err = raw1394_ioctl(file, cmd, arg);
2755 break; 2765 break;
2756 /* These request have different format. */ 2766 /* These request have different format. */
2757 case RAW1394_IOC_ISO_RECV_PACKETS32: 2767 case RAW1394_IOC_ISO_RECV_PACKETS32:
@@ -2767,7 +2777,6 @@ static long raw1394_compat_ioctl(struct file *file,
2767 err = -EINVAL; 2777 err = -EINVAL;
2768 break; 2778 break;
2769 } 2779 }
2770 mutex_unlock(&fi->state_mutex);
2771 2780
2772 return err; 2781 return err;
2773} 2782}