diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2008-08-16 11:52:04 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2008-10-15 16:21:08 -0400 |
commit | ddfb908d3f905dbb5964d6fbf783e69c417eb13e (patch) | |
tree | 9c271214e94eab002378daee5d6c8f8cbebb5762 /drivers | |
parent | 10963ea1bd966ba46a46178c4d6abcdf3c23538d (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.c | 211 |
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 */ | 2559 | static long raw1394_ioctl_inactive(struct file_info *fi, unsigned int cmd, |
2560 | static 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 | |||
2572 | static 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: | 2620 | static 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 */ | ||
2653 | static 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 | ||
2667 | static 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 | } |