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 | |
| 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>
| -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 | } |
