master/cdev.c
changeset 2182 4dc680830349
parent 2150 5144a4bc6184
child 2260 f9b1c6d58435
equal deleted inserted replaced
2181:cac59f7a42c4 2182:4dc680830349
    46 #include "ioctl.h"
    46 #include "ioctl.h"
    47 
    47 
    48 /** Set to 1 to enable ioctl() command debugging.
    48 /** Set to 1 to enable ioctl() command debugging.
    49  */
    49  */
    50 #define DEBUG_IOCTL 0
    50 #define DEBUG_IOCTL 0
       
    51 
       
    52 /** Set to 1 to enable ioctl() latency warnings.
       
    53  *
       
    54  * Requires CPU timestamp counter!
       
    55  */
       
    56 #define DEBUG_LATENCY 0
    51 
    57 
    52 /*****************************************************************************/
    58 /*****************************************************************************/
    53 
    59 
    54 static int eccdev_open(struct inode *, struct file *);
    60 static int eccdev_open(struct inode *, struct file *);
    55 static int eccdev_release(struct inode *, struct file *);
    61 static int eccdev_release(struct inode *, struct file *);
  1722         return -EFAULT;
  1728         return -EFAULT;
  1723     }
  1729     }
  1724 
  1730 
  1725     if (ec_mutex_lock_interruptible(&master->master_mutex))
  1731     if (ec_mutex_lock_interruptible(&master->master_mutex))
  1726         return -EINTR;
  1732         return -EINTR;
       
  1733 
  1727     ec_master_set_send_interval(master, send_interval);
  1734     ec_master_set_send_interval(master, send_interval);
       
  1735 
  1728     ec_mutex_unlock(&master->master_mutex);
  1736     ec_mutex_unlock(&master->master_mutex);
  1729 
  1737     return 0;
  1730     return 0;
  1738 }
  1731 }
       
  1732 
       
  1733 
  1739 
  1734 /*****************************************************************************/
  1740 /*****************************************************************************/
  1735 
  1741 
  1736 /** Send frames.
  1742 /** Send frames.
  1737  */
  1743  */
  2102     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2108     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2103         ec_mutex_unlock(&master->master_mutex);
  2109         ec_mutex_unlock(&master->master_mutex);
  2104         return -ENOENT;
  2110         return -ENOENT;
  2105     }
  2111     }
  2106 
  2112 
  2107     ec_mutex_unlock(&master->master_mutex); // FIXME
  2113     ec_mutex_unlock(&master->master_mutex); /** \fixme sc could be invalidated
       
  2114                                              */
  2108 
  2115 
  2109     return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
  2116     return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
  2110 }
  2117 }
  2111 
  2118 
  2112 /*****************************************************************************/
  2119 /*****************************************************************************/
  2134     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2141     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2135         ec_mutex_unlock(&master->master_mutex);
  2142         ec_mutex_unlock(&master->master_mutex);
  2136         return -ENOENT;
  2143         return -ENOENT;
  2137     }
  2144     }
  2138 
  2145 
  2139     ec_mutex_unlock(&master->master_mutex); // FIXME
  2146     ec_mutex_unlock(&master->master_mutex); /** \fixme sc could be invalidated
       
  2147                                              */
  2140 
  2148 
  2141     ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
  2149     ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
  2142     return 0;
  2150     return 0;
  2143 }
  2151 }
  2144 
  2152 
  2167     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2175     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2168         ec_mutex_unlock(&master->master_mutex);
  2176         ec_mutex_unlock(&master->master_mutex);
  2169         return -ENOENT;
  2177         return -ENOENT;
  2170     }
  2178     }
  2171 
  2179 
  2172     ec_mutex_unlock(&master->master_mutex); // FIXME
  2180     ec_mutex_unlock(&master->master_mutex); /** \fixme sc could be invalidated
       
  2181                                              */
  2173 
  2182 
  2174     return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
  2183     return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
  2175             data.entry_index, data.entry_subindex, data.entry_bit_length);
  2184             data.entry_index, data.entry_subindex, data.entry_bit_length);
  2176 }
  2185 }
  2177 
  2186 
  2200     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2209     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2201         ec_mutex_unlock(&master->master_mutex);
  2210         ec_mutex_unlock(&master->master_mutex);
  2202         return -ENOENT;
  2211         return -ENOENT;
  2203     }
  2212     }
  2204 
  2213 
  2205     ec_mutex_unlock(&master->master_mutex); // FIXME
  2214     ec_mutex_unlock(&master->master_mutex); /** \fixme sc could be invalidated
       
  2215                                              */
  2206 
  2216 
  2207     ecrt_slave_config_pdo_mapping_clear(sc, data.index);
  2217     ecrt_slave_config_pdo_mapping_clear(sc, data.index);
  2208     return 0;
  2218     return 0;
  2209 }
  2219 }
  2210 
  2220 
  2240     if (!(domain = ec_master_find_domain(master, data.domain_index))) {
  2250     if (!(domain = ec_master_find_domain(master, data.domain_index))) {
  2241         ec_mutex_unlock(&master->master_mutex);
  2251         ec_mutex_unlock(&master->master_mutex);
  2242         return -ENOENT;
  2252         return -ENOENT;
  2243     }
  2253     }
  2244 
  2254 
  2245     ec_mutex_unlock(&master->master_mutex); // FIXME
  2255     ec_mutex_unlock(&master->master_mutex);/** \fixme sc or domain could be
       
  2256                                              invalidated */
  2246 
  2257 
  2247     ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
  2258     ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
  2248             data.entry_subindex, domain, &data.bit_position);
  2259             data.entry_subindex, domain, &data.bit_position);
  2249 
  2260 
  2250     if (copy_to_user((void __user *) arg, &data, sizeof(data)))
  2261     if (copy_to_user((void __user *) arg, &data, sizeof(data)))
  2333         ec_mutex_unlock(&master->master_mutex);
  2344         ec_mutex_unlock(&master->master_mutex);
  2334         kfree(sdo_data);
  2345         kfree(sdo_data);
  2335         return -ENOENT;
  2346         return -ENOENT;
  2336     }
  2347     }
  2337 
  2348 
  2338     ec_mutex_unlock(&master->master_mutex); // FIXME
  2349     ec_mutex_unlock(&master->master_mutex); /** \fixme sc could be invalidated
       
  2350                                              */
  2339 
  2351 
  2340     if (data.complete_access) {
  2352     if (data.complete_access) {
  2341         ret = ecrt_slave_config_complete_sdo(sc,
  2353         ret = ecrt_slave_config_complete_sdo(sc,
  2342                 data.index, sdo_data, data.size);
  2354                 data.index, sdo_data, data.size);
  2343     } else {
  2355     } else {
  2464 
  2476 
  2465     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  2477     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  2466         return -EFAULT;
  2478         return -EFAULT;
  2467     }
  2479     }
  2468 
  2480 
  2469     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2481     /* no locking of master_mutex needed, because sc will not be deleted in
  2470         return -EINTR;
  2482      * the meantime. */
  2471 
  2483 
  2472     if (!(sc = ec_master_get_config_const(master, data.config_index))) {
  2484     if (!(sc = ec_master_get_config_const(master, data.config_index))) {
  2473         ec_mutex_unlock(&master->master_mutex);
       
  2474         return -ENOENT;
  2485         return -ENOENT;
  2475     }
  2486     }
  2476 
  2487 
  2477     ecrt_slave_config_state(sc, &state);
  2488     ecrt_slave_config_state(sc, &state);
  2478 
       
  2479     ec_mutex_unlock(&master->master_mutex);
       
  2480 
  2489 
  2481     if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
  2490     if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
  2482         return -EFAULT;
  2491         return -EFAULT;
  2483 
  2492 
  2484     return 0;
  2493     return 0;
  2526         ec_mutex_unlock(&master->master_mutex);
  2535         ec_mutex_unlock(&master->master_mutex);
  2527         kfree(data);
  2536         kfree(data);
  2528         return -ENOENT;
  2537         return -ENOENT;
  2529     }
  2538     }
  2530 
  2539 
  2531     ec_mutex_unlock(&master->master_mutex); // FIXME
  2540     ec_mutex_unlock(&master->master_mutex);/** \fixme sc could be invalidated
       
  2541                                              */
  2532 
  2542 
  2533     ret = ecrt_slave_config_idn(
  2543     ret = ecrt_slave_config_idn(
  2534             sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
  2544             sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
  2535     kfree(data);
  2545     kfree(data);
  2536     return ret;
  2546     return ret;
  2581     ec_domain_t *domain;
  2591     ec_domain_t *domain;
  2582 
  2592 
  2583     if (unlikely(!priv->requested))
  2593     if (unlikely(!priv->requested))
  2584         return -EPERM;
  2594         return -EPERM;
  2585 
  2595 
  2586     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2596     /* no locking of master_mutex needed, because domain will not be deleted
  2587         return -EINTR;
  2597      * in the meantime. */
  2588 
  2598 
  2589     if (!(domain = ec_master_find_domain(master, arg))) {
  2599     if (!(domain = ec_master_find_domain(master, arg))) {
  2590         ec_mutex_unlock(&master->master_mutex);
       
  2591         return -ENOENT;
  2600         return -ENOENT;
  2592     }
  2601     }
  2593 
  2602 
  2594     ecrt_domain_process(domain);
  2603     ecrt_domain_process(domain);
  2595     ec_mutex_unlock(&master->master_mutex);
       
  2596     return 0;
  2604     return 0;
  2597 }
  2605 }
  2598 
  2606 
  2599 /*****************************************************************************/
  2607 /*****************************************************************************/
  2600 
  2608 
  2609     ec_domain_t *domain;
  2617     ec_domain_t *domain;
  2610 
  2618 
  2611     if (unlikely(!priv->requested))
  2619     if (unlikely(!priv->requested))
  2612         return -EPERM;
  2620         return -EPERM;
  2613 
  2621 
  2614     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2622     /* no locking of master_mutex needed, because domain will not be deleted
  2615         return -EINTR;
  2623      * in the meantime. */
  2616 
  2624 
  2617     if (!(domain = ec_master_find_domain(master, arg))) {
  2625     if (!(domain = ec_master_find_domain(master, arg))) {
  2618         ec_mutex_unlock(&master->master_mutex);
       
  2619         return -ENOENT;
  2626         return -ENOENT;
  2620     }
  2627     }
  2621 
  2628 
  2622     ecrt_domain_queue(domain);
  2629     ecrt_domain_queue(domain);
  2623     ec_mutex_unlock(&master->master_mutex);
       
  2624     return 0;
  2630     return 0;
  2625 }
  2631 }
  2626 
  2632 
  2627 /*****************************************************************************/
  2633 /*****************************************************************************/
  2628 
  2634 
  2643 
  2649 
  2644     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  2650     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  2645         return -EFAULT;
  2651         return -EFAULT;
  2646     }
  2652     }
  2647 
  2653 
  2648     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2654     /* no locking of master_mutex needed, because domain will not be deleted
  2649         return -EINTR;
  2655      * in the meantime. */
  2650 
  2656 
  2651     if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
  2657     if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
  2652         ec_mutex_unlock(&master->master_mutex);
       
  2653         return -ENOENT;
  2658         return -ENOENT;
  2654     }
  2659     }
  2655 
  2660 
  2656     ecrt_domain_state(domain, &state);
  2661     ecrt_domain_state(domain, &state);
  2657 
       
  2658     ec_mutex_unlock(&master->master_mutex);
       
  2659 
  2662 
  2660     if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
  2663     if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
  2661         return -EFAULT;
  2664         return -EFAULT;
  2662 
  2665 
  2663     return 0;
  2666     return 0;
  2681         return -EPERM;
  2684         return -EPERM;
  2682 
  2685 
  2683     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2686     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2684         return -EFAULT;
  2687         return -EFAULT;
  2685 
  2688 
  2686     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2689     /* no locking of master_mutex needed, because neither sc nor req will not
  2687         return -EINTR;
  2690      * be deleted in the meantime. */
  2688 
  2691 
  2689     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2692     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2690         ec_mutex_unlock(&master->master_mutex);
       
  2691         return -ENOENT;
  2693         return -ENOENT;
  2692     }
  2694     }
  2693 
  2695 
  2694     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2696     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2695         ec_mutex_unlock(&master->master_mutex);
       
  2696         return -ENOENT;
  2697         return -ENOENT;
  2697     }
  2698     }
  2698 
       
  2699     ec_mutex_unlock(&master->master_mutex);
       
  2700 
  2699 
  2701     ecrt_sdo_request_timeout(req, data.timeout);
  2700     ecrt_sdo_request_timeout(req, data.timeout);
  2702     return 0;
  2701     return 0;
  2703 }
  2702 }
  2704 
  2703 
  2720         return -EPERM;
  2719         return -EPERM;
  2721 
  2720 
  2722     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2721     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2723         return -EFAULT;
  2722         return -EFAULT;
  2724 
  2723 
  2725     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2724     /* no locking of master_mutex needed, because neither sc nor req will not
  2726         return -EINTR;
  2725      * be deleted in the meantime. */
  2727 
  2726 
  2728     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2727     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2729         ec_mutex_unlock(&master->master_mutex);
       
  2730         return -ENOENT;
  2728         return -ENOENT;
  2731     }
  2729     }
  2732 
  2730 
  2733     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2731     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2734         ec_mutex_unlock(&master->master_mutex);
       
  2735         return -ENOENT;
  2732         return -ENOENT;
  2736     }
  2733     }
  2737 
  2734 
  2738     data.state = ecrt_sdo_request_state(req);
  2735     data.state = ecrt_sdo_request_state(req);
  2739     if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
  2736     if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
  2740         data.size = ecrt_sdo_request_data_size(req);
  2737         data.size = ecrt_sdo_request_data_size(req);
  2741     else
  2738     else
  2742         data.size = 0;
  2739         data.size = 0;
  2743 
  2740 
  2744     ec_mutex_unlock(&master->master_mutex);
       
  2745 
       
  2746     if (copy_to_user((void __user *) arg, &data, sizeof(data)))
  2741     if (copy_to_user((void __user *) arg, &data, sizeof(data)))
  2747         return -EFAULT;
  2742         return -EFAULT;
  2748 
  2743 
  2749     return 0;
  2744     return 0;
  2750 }
  2745 }
  2767         return -EPERM;
  2762         return -EPERM;
  2768 
  2763 
  2769     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2764     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2770         return -EFAULT;
  2765         return -EFAULT;
  2771 
  2766 
  2772     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2767     /* no locking of master_mutex needed, because neither sc nor req will not
  2773         return -EINTR;
  2768      * be deleted in the meantime. */
  2774 
  2769 
  2775     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2770     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2776         ec_mutex_unlock(&master->master_mutex);
       
  2777         return -ENOENT;
  2771         return -ENOENT;
  2778     }
  2772     }
  2779 
  2773 
  2780     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2774     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2781         ec_mutex_unlock(&master->master_mutex);
       
  2782         return -ENOENT;
  2775         return -ENOENT;
  2783     }
  2776     }
  2784 
       
  2785     ec_mutex_unlock(&master->master_mutex);
       
  2786 
  2777 
  2787     ecrt_sdo_request_read(req);
  2778     ecrt_sdo_request_read(req);
  2788     return 0;
  2779     return 0;
  2789 }
  2780 }
  2790 
  2781 
  2812     if (!data.size) {
  2803     if (!data.size) {
  2813         EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
  2804         EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
  2814         return -EINVAL;
  2805         return -EINVAL;
  2815     }
  2806     }
  2816 
  2807 
  2817     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2808     /* no locking of master_mutex needed, because neither sc nor req will not
  2818         return -EINTR;
  2809      * be deleted in the meantime. */
  2819 
  2810 
  2820     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2811     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2821         ec_mutex_unlock(&master->master_mutex);
       
  2822         return -ENOENT;
  2812         return -ENOENT;
  2823     }
  2813     }
  2824 
  2814 
  2825     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2815     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2826         ec_mutex_unlock(&master->master_mutex);
       
  2827         return -ENOENT;
  2816         return -ENOENT;
  2828     }
  2817     }
  2829 
       
  2830     ec_mutex_unlock(&master->master_mutex);
       
  2831 
  2818 
  2832     ret = ec_sdo_request_alloc(req, data.size);
  2819     ret = ec_sdo_request_alloc(req, data.size);
  2833     if (ret)
  2820     if (ret)
  2834         return ret;
  2821         return ret;
  2835 
  2822 
  2859         return -EPERM;
  2846         return -EPERM;
  2860 
  2847 
  2861     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2848     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2862         return -EFAULT;
  2849         return -EFAULT;
  2863 
  2850 
  2864     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2851     /* no locking of master_mutex needed, because neither sc nor req will not
  2865         return -EINTR;
  2852      * be deleted in the meantime. */
  2866 
  2853 
  2867     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2854     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2868         ec_mutex_unlock(&master->master_mutex);
       
  2869         return -ENOENT;
  2855         return -ENOENT;
  2870     }
  2856     }
  2871 
  2857 
  2872     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2858     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2873         ec_mutex_unlock(&master->master_mutex);
       
  2874         return -ENOENT;
  2859         return -ENOENT;
  2875     }
  2860     }
  2876 
       
  2877     ec_mutex_unlock(&master->master_mutex);
       
  2878 
  2861 
  2879     if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
  2862     if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
  2880                 ecrt_sdo_request_data_size(req)))
  2863                 ecrt_sdo_request_data_size(req)))
  2881         return -EFAULT;
  2864         return -EFAULT;
  2882 
  2865 
  2909         return -EFAULT;
  2892         return -EFAULT;
  2910 
  2893 
  2911     if (get_user(vendor_type, data.vendor_type))
  2894     if (get_user(vendor_type, data.vendor_type))
  2912         return -EFAULT;
  2895         return -EFAULT;
  2913 
  2896 
  2914     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2897     /* no locking of master_mutex needed, because neither sc nor voe will not
  2915         return -EINTR;
  2898      * be deleted in the meantime. */
  2916 
  2899 
  2917     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2900     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2918         ec_mutex_unlock(&master->master_mutex);
       
  2919         return -ENOENT;
  2901         return -ENOENT;
  2920     }
  2902     }
  2921 
  2903 
  2922     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2904     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2923         ec_mutex_unlock(&master->master_mutex);
       
  2924         return -ENOENT;
  2905         return -ENOENT;
  2925     }
  2906     }
  2926 
       
  2927     ec_mutex_unlock(&master->master_mutex);
       
  2928 
  2907 
  2929     ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
  2908     ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
  2930     return 0;
  2909     return 0;
  2931 }
  2910 }
  2932 
  2911 
  2950         return -EPERM;
  2929         return -EPERM;
  2951 
  2930 
  2952     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2931     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2953         return -EFAULT;
  2932         return -EFAULT;
  2954 
  2933 
  2955     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2934     /* no locking of master_mutex needed, because neither sc nor voe will not
  2956         return -EINTR;
  2935      * be deleted in the meantime. */
  2957 
  2936 
  2958     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2937     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2959         ec_mutex_unlock(&master->master_mutex);
       
  2960         return -ENOENT;
  2938         return -ENOENT;
  2961     }
  2939     }
  2962 
  2940 
  2963     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2941     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2964         ec_mutex_unlock(&master->master_mutex);
       
  2965         return -ENOENT;
  2942         return -ENOENT;
  2966     }
  2943     }
  2967 
  2944 
  2968     ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
  2945     ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
  2969 
       
  2970     ec_mutex_unlock(&master->master_mutex);
       
  2971 
  2946 
  2972     if (likely(data.vendor_id))
  2947     if (likely(data.vendor_id))
  2973         if (put_user(vendor_id, data.vendor_id))
  2948         if (put_user(vendor_id, data.vendor_id))
  2974             return -EFAULT;
  2949             return -EFAULT;
  2975 
  2950 
  2998         return -EPERM;
  2973         return -EPERM;
  2999 
  2974 
  3000     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2975     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3001         return -EFAULT;
  2976         return -EFAULT;
  3002 
  2977 
  3003     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2978     /* no locking of master_mutex needed, because neither sc nor voe will not
  3004         return -EINTR;
  2979      * be deleted in the meantime. */
  3005 
  2980 
  3006     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2981     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3007         ec_mutex_unlock(&master->master_mutex);
       
  3008         return -ENOENT;
  2982         return -ENOENT;
  3009     }
  2983     }
  3010 
  2984 
  3011     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2985     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3012         ec_mutex_unlock(&master->master_mutex);
       
  3013         return -ENOENT;
  2986         return -ENOENT;
  3014     }
  2987     }
  3015 
       
  3016     ec_mutex_unlock(&master->master_mutex);
       
  3017 
  2988 
  3018     ecrt_voe_handler_read(voe);
  2989     ecrt_voe_handler_read(voe);
  3019     return 0;
  2990     return 0;
  3020 }
  2991 }
  3021 
  2992 
  3037         return -EPERM;
  3008         return -EPERM;
  3038 
  3009 
  3039     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3010     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3040         return -EFAULT;
  3011         return -EFAULT;
  3041 
  3012 
  3042     if (ec_mutex_lock_interruptible(&master->master_mutex))
  3013     /* no locking of master_mutex needed, because neither sc nor voe will not
  3043         return -EINTR;
  3014      * be deleted in the meantime. */
  3044 
  3015 
  3045     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3016     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3046         ec_mutex_unlock(&master->master_mutex);
       
  3047         return -ENOENT;
  3017         return -ENOENT;
  3048     }
  3018     }
  3049 
  3019 
  3050     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3020     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3051         ec_mutex_unlock(&master->master_mutex);
       
  3052         return -ENOENT;
  3021         return -ENOENT;
  3053     }
  3022     }
  3054 
       
  3055     ec_mutex_unlock(&master->master_mutex);
       
  3056 
  3023 
  3057     ecrt_voe_handler_read_nosync(voe);
  3024     ecrt_voe_handler_read_nosync(voe);
  3058     return 0;
  3025     return 0;
  3059 }
  3026 }
  3060 
  3027 
  3076         return -EPERM;
  3043         return -EPERM;
  3077 
  3044 
  3078     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3045     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3079         return -EFAULT;
  3046         return -EFAULT;
  3080 
  3047 
  3081     if (ec_mutex_lock_interruptible(&master->master_mutex))
  3048     /* no locking of master_mutex needed, because neither sc nor voe will not
  3082         return -EINTR;
  3049      * be deleted in the meantime. */
  3083 
  3050 
  3084     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3051     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3085         ec_mutex_unlock(&master->master_mutex);
       
  3086         return -ENOENT;
  3052         return -ENOENT;
  3087     }
  3053     }
  3088 
  3054 
  3089     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3055     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3090         ec_mutex_unlock(&master->master_mutex);
       
  3091         return -ENOENT;
  3056         return -ENOENT;
  3092     }
  3057     }
  3093 
       
  3094     ec_mutex_unlock(&master->master_mutex);
       
  3095 
  3058 
  3096     if (data.size) {
  3059     if (data.size) {
  3097         if (data.size > ec_voe_handler_mem_size(voe))
  3060         if (data.size > ec_voe_handler_mem_size(voe))
  3098             return -EOVERFLOW;
  3061             return -EOVERFLOW;
  3099 
  3062 
  3124         return -EPERM;
  3087         return -EPERM;
  3125 
  3088 
  3126     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3089     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3127         return -EFAULT;
  3090         return -EFAULT;
  3128 
  3091 
  3129     if (ec_mutex_lock_interruptible(&master->master_mutex))
  3092     /* no locking of master_mutex needed, because neither sc nor voe will not
  3130         return -EINTR;
  3093      * be deleted in the meantime. */
  3131 
  3094 
  3132     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3095     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3133         ec_mutex_unlock(&master->master_mutex);
       
  3134         return -ENOENT;
  3096         return -ENOENT;
  3135     }
  3097     }
  3136 
  3098 
  3137     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3099     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3138         ec_mutex_unlock(&master->master_mutex);
       
  3139         return -ENOENT;
  3100         return -ENOENT;
  3140     }
  3101     }
  3141 
       
  3142     ec_mutex_unlock(&master->master_mutex);
       
  3143 
  3102 
  3144     data.state = ecrt_voe_handler_execute(voe);
  3103     data.state = ecrt_voe_handler_execute(voe);
  3145     if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
  3104     if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
  3146         data.size = ecrt_voe_handler_data_size(voe);
  3105         data.size = ecrt_voe_handler_data_size(voe);
  3147     else
  3106     else
  3171         return -EPERM;
  3130         return -EPERM;
  3172 
  3131 
  3173     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3132     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3174         return -EFAULT;
  3133         return -EFAULT;
  3175 
  3134 
  3176     if (ec_mutex_lock_interruptible(&master->master_mutex))
  3135     /* no locking of master_mutex needed, because neither sc nor voe will not
  3177         return -EINTR;
  3136      * be deleted in the meantime. */
  3178 
  3137 
  3179     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3138     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3180         ec_mutex_unlock(&master->master_mutex);
       
  3181         return -ENOENT;
  3139         return -ENOENT;
  3182     }
  3140     }
  3183 
  3141 
  3184     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3142     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3185         ec_mutex_unlock(&master->master_mutex);
       
  3186         return -ENOENT;
  3143         return -ENOENT;
  3187     }
  3144     }
  3188 
       
  3189     ec_mutex_unlock(&master->master_mutex);
       
  3190 
  3145 
  3191     if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
  3146     if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
  3192                 ecrt_voe_handler_data_size(voe)))
  3147                 ecrt_voe_handler_data_size(voe)))
  3193         return -EFAULT;
  3148         return -EFAULT;
  3194 
  3149 
  3324         return -EFAULT;
  3279         return -EFAULT;
  3325     }
  3280     }
  3326     request->req.data_size = data.buffer_size;
  3281     request->req.data_size = data.buffer_size;
  3327     ec_foe_request_write(&request->req);
  3282     ec_foe_request_write(&request->req);
  3328 
  3283 
  3329     if (ec_mutex_lock_interruptible(&master->master_mutex))
  3284     if (ec_mutex_lock_interruptible(&master->master_mutex)) {
       
  3285         kref_put(&request->refcount, ec_master_foe_request_release);
  3330         return -EINTR;
  3286         return -EINTR;
       
  3287     }
  3331 
  3288 
  3332     if (!(request->slave = ec_master_find_slave(
  3289     if (!(request->slave = ec_master_find_slave(
  3333                     master, 0, data.slave_position))) {
  3290                     master, 0, data.slave_position))) {
  3334         ec_mutex_unlock(&master->master_mutex);
  3291         ec_mutex_unlock(&master->master_mutex);
  3335         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  3292         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  3520 
  3477 
  3521 /** Called when an ioctl() command is issued.
  3478 /** Called when an ioctl() command is issued.
  3522  */
  3479  */
  3523 long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  3480 long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  3524 {
  3481 {
       
  3482 #if DEBUG_LATENCY
       
  3483     cycles_t a = get_cycles(), b;
       
  3484     unsigned int t;
       
  3485 #endif
  3525     ec_cdev_priv_t *priv = (ec_cdev_priv_t *) filp->private_data;
  3486     ec_cdev_priv_t *priv = (ec_cdev_priv_t *) filp->private_data;
  3526     ec_master_t *master = priv->cdev->master;
  3487     ec_master_t *master = priv->cdev->master;
       
  3488     int ret;
  3527 
  3489 
  3528 #if DEBUG_IOCTL
  3490 #if DEBUG_IOCTL
  3529     EC_MASTER_DBG(master, 0, "ioctl(filp = 0x%p, cmd = 0x%08x (0x%02x),"
  3491     EC_MASTER_DBG(master, 0, "ioctl(filp = 0x%p, cmd = 0x%08x (0x%02x),"
  3530             " arg = 0x%lx)\n", filp, cmd, _IOC_NR(cmd), arg);
  3492             " arg = 0x%lx)\n", filp, cmd, _IOC_NR(cmd), arg);
  3531 #endif
  3493 #endif
  3532 
  3494 
  3533     switch (cmd) {
  3495     switch (cmd) {
  3534         case EC_IOCTL_MODULE:
  3496         case EC_IOCTL_MODULE:
  3535             return ec_cdev_ioctl_module(arg);
  3497             ret = ec_cdev_ioctl_module(arg);
       
  3498             break;
  3536         case EC_IOCTL_MASTER:
  3499         case EC_IOCTL_MASTER:
  3537             return ec_cdev_ioctl_master(master, arg);
  3500             ret = ec_cdev_ioctl_master(master, arg);
       
  3501             break;
  3538         case EC_IOCTL_SLAVE:
  3502         case EC_IOCTL_SLAVE:
  3539             return ec_cdev_ioctl_slave(master, arg);
  3503             ret = ec_cdev_ioctl_slave(master, arg);
       
  3504             break;
  3540         case EC_IOCTL_SLAVE_SYNC:
  3505         case EC_IOCTL_SLAVE_SYNC:
  3541             return ec_cdev_ioctl_slave_sync(master, arg);
  3506             ret = ec_cdev_ioctl_slave_sync(master, arg);
       
  3507             break;
  3542         case EC_IOCTL_SLAVE_SYNC_PDO:
  3508         case EC_IOCTL_SLAVE_SYNC_PDO:
  3543             return ec_cdev_ioctl_slave_sync_pdo(master, arg);
  3509             ret = ec_cdev_ioctl_slave_sync_pdo(master, arg);
       
  3510             break;
  3544         case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
  3511         case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
  3545             return ec_cdev_ioctl_slave_sync_pdo_entry(master, arg);
  3512             ret = ec_cdev_ioctl_slave_sync_pdo_entry(master, arg);
       
  3513             break;
  3546         case EC_IOCTL_DOMAIN:
  3514         case EC_IOCTL_DOMAIN:
  3547             return ec_cdev_ioctl_domain(master, arg);
  3515             ret = ec_cdev_ioctl_domain(master, arg);
       
  3516             break;
  3548         case EC_IOCTL_DOMAIN_FMMU:
  3517         case EC_IOCTL_DOMAIN_FMMU:
  3549             return ec_cdev_ioctl_domain_fmmu(master, arg);
  3518             ret = ec_cdev_ioctl_domain_fmmu(master, arg);
       
  3519             break;
  3550         case EC_IOCTL_DOMAIN_DATA:
  3520         case EC_IOCTL_DOMAIN_DATA:
  3551             return ec_cdev_ioctl_domain_data(master, arg);
  3521             ret = ec_cdev_ioctl_domain_data(master, arg);
       
  3522             break;
  3552         case EC_IOCTL_MASTER_DEBUG:
  3523         case EC_IOCTL_MASTER_DEBUG:
  3553             if (!(filp->f_mode & FMODE_WRITE))
  3524             if (!(filp->f_mode & FMODE_WRITE)) {
  3554                 return -EPERM;
  3525                 ret = -EPERM;
  3555             return ec_cdev_ioctl_master_debug(master, arg);
  3526                 break;
       
  3527             }
       
  3528             ret = ec_cdev_ioctl_master_debug(master, arg);
       
  3529             break;
  3556         case EC_IOCTL_MASTER_RESCAN:
  3530         case EC_IOCTL_MASTER_RESCAN:
  3557             if (!(filp->f_mode & FMODE_WRITE))
  3531             if (!(filp->f_mode & FMODE_WRITE)) {
  3558                 return -EPERM;
  3532                 ret = -EPERM;
  3559             return ec_cdev_ioctl_master_rescan(master, arg);
  3533                 break;
       
  3534             }
       
  3535             ret = ec_cdev_ioctl_master_rescan(master, arg);
       
  3536             break;
  3560         case EC_IOCTL_SLAVE_STATE:
  3537         case EC_IOCTL_SLAVE_STATE:
  3561             if (!(filp->f_mode & FMODE_WRITE))
  3538             if (!(filp->f_mode & FMODE_WRITE)) {
  3562                 return -EPERM;
  3539                 ret = -EPERM;
  3563             return ec_cdev_ioctl_slave_state(master, arg);
  3540                 break;
       
  3541             }
       
  3542             ret = ec_cdev_ioctl_slave_state(master, arg);
       
  3543             break;
  3564         case EC_IOCTL_SLAVE_SDO:
  3544         case EC_IOCTL_SLAVE_SDO:
  3565             return ec_cdev_ioctl_slave_sdo(master, arg);
  3545             ret = ec_cdev_ioctl_slave_sdo(master, arg);
       
  3546             break;
  3566         case EC_IOCTL_SLAVE_SDO_ENTRY:
  3547         case EC_IOCTL_SLAVE_SDO_ENTRY:
  3567             return ec_cdev_ioctl_slave_sdo_entry(master, arg);
  3548             ret = ec_cdev_ioctl_slave_sdo_entry(master, arg);
       
  3549             break;
  3568         case EC_IOCTL_SLAVE_SDO_UPLOAD:
  3550         case EC_IOCTL_SLAVE_SDO_UPLOAD:
  3569             return ec_cdev_ioctl_slave_sdo_upload(master, arg);
  3551             ret = ec_cdev_ioctl_slave_sdo_upload(master, arg);
       
  3552             break;
  3570         case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
  3553         case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
  3571             if (!(filp->f_mode & FMODE_WRITE))
  3554             if (!(filp->f_mode & FMODE_WRITE)) {
  3572                 return -EPERM;
  3555                 ret = -EPERM;
  3573             return ec_cdev_ioctl_slave_sdo_download(master, arg);
  3556                 break;
       
  3557             }
       
  3558             ret = ec_cdev_ioctl_slave_sdo_download(master, arg);
       
  3559             break;
  3574         case EC_IOCTL_SLAVE_SII_READ:
  3560         case EC_IOCTL_SLAVE_SII_READ:
  3575             return ec_cdev_ioctl_slave_sii_read(master, arg);
  3561             ret = ec_cdev_ioctl_slave_sii_read(master, arg);
       
  3562             break;
  3576         case EC_IOCTL_SLAVE_SII_WRITE:
  3563         case EC_IOCTL_SLAVE_SII_WRITE:
  3577             if (!(filp->f_mode & FMODE_WRITE))
  3564             if (!(filp->f_mode & FMODE_WRITE)) {
  3578                 return -EPERM;
  3565                 ret = -EPERM;
  3579             return ec_cdev_ioctl_slave_sii_write(master, arg);
  3566                 break;
       
  3567             }
       
  3568             ret = ec_cdev_ioctl_slave_sii_write(master, arg);
       
  3569             break;
  3580         case EC_IOCTL_SLAVE_REG_READ:
  3570         case EC_IOCTL_SLAVE_REG_READ:
  3581             return ec_cdev_ioctl_slave_reg_read(master, arg);
  3571             ret = ec_cdev_ioctl_slave_reg_read(master, arg);
       
  3572             break;
  3582         case EC_IOCTL_SLAVE_REG_WRITE:
  3573         case EC_IOCTL_SLAVE_REG_WRITE:
  3583             if (!(filp->f_mode & FMODE_WRITE))
  3574             if (!(filp->f_mode & FMODE_WRITE)) {
  3584                 return -EPERM;
  3575                 ret = -EPERM;
  3585             return ec_cdev_ioctl_slave_reg_write(master, arg);
  3576                 break;
       
  3577             }
       
  3578             ret = ec_cdev_ioctl_slave_reg_write(master, arg);
       
  3579             break;
  3586         case EC_IOCTL_SLAVE_FOE_READ:
  3580         case EC_IOCTL_SLAVE_FOE_READ:
  3587             return ec_cdev_ioctl_slave_foe_read(master, arg);
  3581             ret = ec_cdev_ioctl_slave_foe_read(master, arg);
       
  3582             break;
  3588         case EC_IOCTL_SLAVE_FOE_WRITE:
  3583         case EC_IOCTL_SLAVE_FOE_WRITE:
  3589             if (!(filp->f_mode & FMODE_WRITE))
  3584             if (!(filp->f_mode & FMODE_WRITE)) {
  3590                 return -EPERM;
  3585                 ret = -EPERM;
  3591             return ec_cdev_ioctl_slave_foe_write(master, arg);
  3586                 break;
       
  3587             }
       
  3588             ret = ec_cdev_ioctl_slave_foe_write(master, arg);
       
  3589             break;
  3592         case EC_IOCTL_SLAVE_SOE_READ:
  3590         case EC_IOCTL_SLAVE_SOE_READ:
  3593             return ec_cdev_ioctl_slave_soe_read(master, arg);
  3591             ret = ec_cdev_ioctl_slave_soe_read(master, arg);
       
  3592             break;
  3594         case EC_IOCTL_SLAVE_SOE_WRITE:
  3593         case EC_IOCTL_SLAVE_SOE_WRITE:
  3595             if (!(filp->f_mode & FMODE_WRITE))
  3594             if (!(filp->f_mode & FMODE_WRITE)) {
  3596                 return -EPERM;
  3595                 ret = -EPERM;
  3597             return ec_cdev_ioctl_slave_soe_write(master, arg);
  3596                 break;
       
  3597             }
       
  3598             ret = ec_cdev_ioctl_slave_soe_write(master, arg);
       
  3599             break;
  3598         case EC_IOCTL_CONFIG:
  3600         case EC_IOCTL_CONFIG:
  3599             return ec_cdev_ioctl_config(master, arg);
  3601             ret = ec_cdev_ioctl_config(master, arg);
       
  3602             break;
  3600         case EC_IOCTL_CONFIG_PDO:
  3603         case EC_IOCTL_CONFIG_PDO:
  3601             return ec_cdev_ioctl_config_pdo(master, arg);
  3604             ret = ec_cdev_ioctl_config_pdo(master, arg);
       
  3605             break;
  3602         case EC_IOCTL_CONFIG_PDO_ENTRY:
  3606         case EC_IOCTL_CONFIG_PDO_ENTRY:
  3603             return ec_cdev_ioctl_config_pdo_entry(master, arg);
  3607             ret = ec_cdev_ioctl_config_pdo_entry(master, arg);
       
  3608             break;
  3604         case EC_IOCTL_CONFIG_SDO:
  3609         case EC_IOCTL_CONFIG_SDO:
  3605             return ec_cdev_ioctl_config_sdo(master, arg);
  3610             ret = ec_cdev_ioctl_config_sdo(master, arg);
       
  3611             break;
  3606         case EC_IOCTL_CONFIG_IDN:
  3612         case EC_IOCTL_CONFIG_IDN:
  3607             return ec_cdev_ioctl_config_idn(master, arg);
  3613             ret = ec_cdev_ioctl_config_idn(master, arg);
       
  3614             break;
  3608 #ifdef EC_EOE
  3615 #ifdef EC_EOE
  3609         case EC_IOCTL_EOE_HANDLER:
  3616         case EC_IOCTL_EOE_HANDLER:
  3610             return ec_cdev_ioctl_eoe_handler(master, arg);
  3617             ret = ec_cdev_ioctl_eoe_handler(master, arg);
       
  3618             break;
  3611 #endif
  3619 #endif
  3612         case EC_IOCTL_REQUEST:
  3620         case EC_IOCTL_REQUEST:
  3613             if (!(filp->f_mode & FMODE_WRITE))
  3621             if (!(filp->f_mode & FMODE_WRITE)) {
  3614                 return -EPERM;
  3622                 ret = -EPERM;
  3615             return ec_cdev_ioctl_request(master, arg, priv);
  3623                 break;
       
  3624             }
       
  3625             ret = ec_cdev_ioctl_request(master, arg, priv);
       
  3626             break;
  3616         case EC_IOCTL_CREATE_DOMAIN:
  3627         case EC_IOCTL_CREATE_DOMAIN:
  3617             if (!(filp->f_mode & FMODE_WRITE))
  3628             if (!(filp->f_mode & FMODE_WRITE)) {
  3618                 return -EPERM;
  3629                 ret = -EPERM;
  3619             return ec_cdev_ioctl_create_domain(master, arg, priv);
  3630                 break;
       
  3631             }
       
  3632             ret = ec_cdev_ioctl_create_domain(master, arg, priv);
       
  3633             break;
  3620         case EC_IOCTL_CREATE_SLAVE_CONFIG:
  3634         case EC_IOCTL_CREATE_SLAVE_CONFIG:
  3621             if (!(filp->f_mode & FMODE_WRITE))
  3635             if (!(filp->f_mode & FMODE_WRITE)) {
  3622                 return -EPERM;
  3636                 ret = -EPERM;
  3623             return ec_cdev_ioctl_create_slave_config(master, arg, priv);
  3637                 break;
       
  3638             }
       
  3639             ret = ec_cdev_ioctl_create_slave_config(master, arg, priv);
       
  3640             break;
  3624         case EC_IOCTL_ACTIVATE:
  3641         case EC_IOCTL_ACTIVATE:
  3625             if (!(filp->f_mode & FMODE_WRITE))
  3642             if (!(filp->f_mode & FMODE_WRITE)) {
  3626                 return -EPERM;
  3643                 ret = -EPERM;
  3627             return ec_cdev_ioctl_activate(master, arg, priv);
  3644                 break;
       
  3645             }
       
  3646             ret = ec_cdev_ioctl_activate(master, arg, priv);
       
  3647             break;
  3628         case EC_IOCTL_DEACTIVATE:
  3648         case EC_IOCTL_DEACTIVATE:
  3629             if (!(filp->f_mode & FMODE_WRITE))
  3649             if (!(filp->f_mode & FMODE_WRITE)) {
  3630                 return -EPERM;
  3650                 ret = -EPERM;
  3631             return ec_cdev_ioctl_deactivate(master, arg, priv);
  3651                 break;
       
  3652             }
       
  3653             ret = ec_cdev_ioctl_deactivate(master, arg, priv);
       
  3654             break;
  3632         case EC_IOCTL_SEND:
  3655         case EC_IOCTL_SEND:
  3633             if (!(filp->f_mode & FMODE_WRITE))
  3656             if (!(filp->f_mode & FMODE_WRITE)) {
  3634                 return -EPERM;
  3657                 ret = -EPERM;
  3635             return ec_cdev_ioctl_send(master, arg, priv);
  3658                 break;
       
  3659             }
       
  3660             ret = ec_cdev_ioctl_send(master, arg, priv);
       
  3661             break;
  3636         case EC_IOCTL_RECEIVE:
  3662         case EC_IOCTL_RECEIVE:
  3637             if (!(filp->f_mode & FMODE_WRITE))
  3663             if (!(filp->f_mode & FMODE_WRITE)) {
  3638                 return -EPERM;
  3664                 ret = -EPERM;
  3639             return ec_cdev_ioctl_receive(master, arg, priv);
  3665                 break;
       
  3666             }
       
  3667             ret = ec_cdev_ioctl_receive(master, arg, priv);
       
  3668             break;
  3640         case EC_IOCTL_MASTER_STATE:
  3669         case EC_IOCTL_MASTER_STATE:
  3641             return ec_cdev_ioctl_master_state(master, arg, priv);
  3670             ret = ec_cdev_ioctl_master_state(master, arg, priv);
       
  3671             break;
  3642         case EC_IOCTL_MASTER_SC_STATE:
  3672         case EC_IOCTL_MASTER_SC_STATE:
  3643             return ec_cdev_ioctl_master_sc_state(master, arg, priv);
  3673             ret = ec_cdev_ioctl_master_sc_state(master, arg, priv);
       
  3674             break;
  3644         case EC_IOCTL_APP_TIME:
  3675         case EC_IOCTL_APP_TIME:
  3645             if (!(filp->f_mode & FMODE_WRITE))
  3676             if (!(filp->f_mode & FMODE_WRITE)) {
  3646                 return -EPERM;
  3677                 ret = -EPERM;
  3647             return ec_cdev_ioctl_app_time(master, arg, priv);
  3678                 break;
       
  3679             }
       
  3680             ret = ec_cdev_ioctl_app_time(master, arg, priv);
       
  3681             break;
  3648         case EC_IOCTL_SYNC_REF:
  3682         case EC_IOCTL_SYNC_REF:
  3649             if (!(filp->f_mode & FMODE_WRITE))
  3683             if (!(filp->f_mode & FMODE_WRITE)) {
  3650                 return -EPERM;
  3684                 ret = -EPERM;
  3651             return ec_cdev_ioctl_sync_ref(master, arg, priv);
  3685                 break;
       
  3686             }
       
  3687             ret = ec_cdev_ioctl_sync_ref(master, arg, priv);
       
  3688             break;
  3652         case EC_IOCTL_SYNC_SLAVES:
  3689         case EC_IOCTL_SYNC_SLAVES:
  3653             if (!(filp->f_mode & FMODE_WRITE))
  3690             if (!(filp->f_mode & FMODE_WRITE)) {
  3654                 return -EPERM;
  3691                 ret = -EPERM;
  3655             return ec_cdev_ioctl_sync_slaves(master, arg, priv);
  3692                 break;
       
  3693             }
       
  3694             ret = ec_cdev_ioctl_sync_slaves(master, arg, priv);
       
  3695             break;
  3656         case EC_IOCTL_SYNC_MON_QUEUE:
  3696         case EC_IOCTL_SYNC_MON_QUEUE:
  3657             if (!(filp->f_mode & FMODE_WRITE))
  3697             if (!(filp->f_mode & FMODE_WRITE)) {
  3658                 return -EPERM;
  3698                 ret = -EPERM;
  3659             return ec_cdev_ioctl_sync_mon_queue(master, arg, priv);
  3699                 break;
       
  3700             }
       
  3701             ret = ec_cdev_ioctl_sync_mon_queue(master, arg, priv);
       
  3702             break;
  3660         case EC_IOCTL_SYNC_MON_PROCESS:
  3703         case EC_IOCTL_SYNC_MON_PROCESS:
  3661             if (!(filp->f_mode & FMODE_WRITE))
  3704             if (!(filp->f_mode & FMODE_WRITE)) {
  3662                 return -EPERM;
  3705                 ret = -EPERM;
  3663             return ec_cdev_ioctl_sync_mon_process(master, arg, priv);
  3706                 break;
       
  3707             }
       
  3708             ret = ec_cdev_ioctl_sync_mon_process(master, arg, priv);
       
  3709             break;
  3664         case EC_IOCTL_RESET:
  3710         case EC_IOCTL_RESET:
  3665             if (!(filp->f_mode & FMODE_WRITE))
  3711             if (!(filp->f_mode & FMODE_WRITE)) {
  3666                 return -EPERM;
  3712                 ret = -EPERM;
  3667             return ec_cdev_ioctl_reset(master, arg, priv);
  3713                 break;
       
  3714             }
       
  3715             ret = ec_cdev_ioctl_reset(master, arg, priv);
       
  3716             break;
  3668         case EC_IOCTL_SC_SYNC:
  3717         case EC_IOCTL_SC_SYNC:
  3669             if (!(filp->f_mode & FMODE_WRITE))
  3718             if (!(filp->f_mode & FMODE_WRITE)) {
  3670                 return -EPERM;
  3719                 ret = -EPERM;
  3671             return ec_cdev_ioctl_sc_sync(master, arg, priv);
  3720                 break;
       
  3721             }
       
  3722             ret = ec_cdev_ioctl_sc_sync(master, arg, priv);
       
  3723             break;
  3672         case EC_IOCTL_SC_WATCHDOG:
  3724         case EC_IOCTL_SC_WATCHDOG:
  3673             if (!(filp->f_mode & FMODE_WRITE))
  3725             if (!(filp->f_mode & FMODE_WRITE)) {
  3674                 return -EPERM;
  3726                 ret = -EPERM;
  3675             return ec_cdev_ioctl_sc_watchdog(master, arg, priv);
  3727                 break;
       
  3728             }
       
  3729             ret = ec_cdev_ioctl_sc_watchdog(master, arg, priv);
       
  3730             break;
  3676         case EC_IOCTL_SC_OVERLAPPING_IO:
  3731         case EC_IOCTL_SC_OVERLAPPING_IO:
  3677             if (!(filp->f_mode & FMODE_WRITE))
  3732             if (!(filp->f_mode & FMODE_WRITE)) {
  3678                 return -EPERM;
  3733                 ret = -EPERM;
  3679             return ec_cdev_ioctl_sc_allow_overlapping_pdos(master, arg, priv);
  3734                 break;
       
  3735             }
       
  3736             ret = ec_cdev_ioctl_sc_allow_overlapping_pdos(master, arg, priv);
       
  3737             break;
  3680         case EC_IOCTL_SC_ADD_PDO:
  3738         case EC_IOCTL_SC_ADD_PDO:
  3681             if (!(filp->f_mode & FMODE_WRITE))
  3739             if (!(filp->f_mode & FMODE_WRITE)) {
  3682                 return -EPERM;
  3740                 ret = -EPERM;
  3683             return ec_cdev_ioctl_sc_add_pdo(master, arg, priv);
  3741                 break;
       
  3742             }
       
  3743             ret = ec_cdev_ioctl_sc_add_pdo(master, arg, priv);
       
  3744             break;
  3684         case EC_IOCTL_SC_CLEAR_PDOS:
  3745         case EC_IOCTL_SC_CLEAR_PDOS:
  3685             if (!(filp->f_mode & FMODE_WRITE))
  3746             if (!(filp->f_mode & FMODE_WRITE)) {
  3686                 return -EPERM;
  3747                 ret = -EPERM;
  3687             return ec_cdev_ioctl_sc_clear_pdos(master, arg, priv);
  3748                 break;
       
  3749             }
       
  3750             ret = ec_cdev_ioctl_sc_clear_pdos(master, arg, priv);
       
  3751             break;
  3688         case EC_IOCTL_SC_ADD_ENTRY:
  3752         case EC_IOCTL_SC_ADD_ENTRY:
  3689             if (!(filp->f_mode & FMODE_WRITE))
  3753             if (!(filp->f_mode & FMODE_WRITE)) {
  3690                 return -EPERM;
  3754                 ret = -EPERM;
  3691             return ec_cdev_ioctl_sc_add_entry(master, arg, priv);
  3755                 break;
       
  3756             }
       
  3757             ret = ec_cdev_ioctl_sc_add_entry(master, arg, priv);
       
  3758             break;
  3692         case EC_IOCTL_SC_CLEAR_ENTRIES:
  3759         case EC_IOCTL_SC_CLEAR_ENTRIES:
  3693             if (!(filp->f_mode & FMODE_WRITE))
  3760             if (!(filp->f_mode & FMODE_WRITE)) {
  3694                 return -EPERM;
  3761                 ret = -EPERM;
  3695             return ec_cdev_ioctl_sc_clear_entries(master, arg, priv);
  3762                 break;
       
  3763             }
       
  3764             ret = ec_cdev_ioctl_sc_clear_entries(master, arg, priv);
       
  3765             break;
  3696         case EC_IOCTL_SC_REG_PDO_ENTRY:
  3766         case EC_IOCTL_SC_REG_PDO_ENTRY:
  3697             if (!(filp->f_mode & FMODE_WRITE))
  3767             if (!(filp->f_mode & FMODE_WRITE)) {
  3698                 return -EPERM;
  3768                 ret = -EPERM;
  3699             return ec_cdev_ioctl_sc_reg_pdo_entry(master, arg, priv);
  3769                 break;
       
  3770             }
       
  3771             ret = ec_cdev_ioctl_sc_reg_pdo_entry(master, arg, priv);
       
  3772             break;
  3700         case EC_IOCTL_SC_DC:
  3773         case EC_IOCTL_SC_DC:
  3701             if (!(filp->f_mode & FMODE_WRITE))
  3774             if (!(filp->f_mode & FMODE_WRITE)) {
  3702                 return -EPERM;
  3775                 ret = -EPERM;
  3703             return ec_cdev_ioctl_sc_dc(master, arg, priv);
  3776                 break;
       
  3777             }
       
  3778             ret = ec_cdev_ioctl_sc_dc(master, arg, priv);
       
  3779             break;
  3704         case EC_IOCTL_SC_SDO:
  3780         case EC_IOCTL_SC_SDO:
  3705             if (!(filp->f_mode & FMODE_WRITE))
  3781             if (!(filp->f_mode & FMODE_WRITE)) {
  3706                 return -EPERM;
  3782                 ret = -EPERM;
  3707             return ec_cdev_ioctl_sc_sdo(master, arg, priv);
  3783                 break;
       
  3784             }
       
  3785             ret = ec_cdev_ioctl_sc_sdo(master, arg, priv);
       
  3786             break;
  3708         case EC_IOCTL_SC_SDO_REQUEST:
  3787         case EC_IOCTL_SC_SDO_REQUEST:
  3709             if (!(filp->f_mode & FMODE_WRITE))
  3788             if (!(filp->f_mode & FMODE_WRITE)) {
  3710                 return -EPERM;
  3789                 ret = -EPERM;
  3711             return ec_cdev_ioctl_sc_create_sdo_request(master, arg, priv);
  3790                 break;
       
  3791             }
       
  3792             ret = ec_cdev_ioctl_sc_create_sdo_request(master, arg, priv);
       
  3793             break;
  3712         case EC_IOCTL_SC_VOE:
  3794         case EC_IOCTL_SC_VOE:
  3713             if (!(filp->f_mode & FMODE_WRITE))
  3795             if (!(filp->f_mode & FMODE_WRITE)) {
  3714                 return -EPERM;
  3796                 ret = -EPERM;
  3715             return ec_cdev_ioctl_sc_create_voe_handler(master, arg, priv);
  3797                 break;
       
  3798             }
       
  3799             ret = ec_cdev_ioctl_sc_create_voe_handler(master, arg, priv);
       
  3800             break;
  3716         case EC_IOCTL_SC_STATE:
  3801         case EC_IOCTL_SC_STATE:
  3717             return ec_cdev_ioctl_sc_state(master, arg, priv);
  3802             ret = ec_cdev_ioctl_sc_state(master, arg, priv);
       
  3803             break;
  3718         case EC_IOCTL_SC_IDN:
  3804         case EC_IOCTL_SC_IDN:
  3719             if (!(filp->f_mode & FMODE_WRITE))
  3805             if (!(filp->f_mode & FMODE_WRITE)) {
  3720                 return -EPERM;
  3806                 ret = -EPERM;
  3721             return ec_cdev_ioctl_sc_idn(master, arg, priv);
  3807                 break;
       
  3808             }
       
  3809             ret = ec_cdev_ioctl_sc_idn(master, arg, priv);
       
  3810             break;
  3722         case EC_IOCTL_DOMAIN_OFFSET:
  3811         case EC_IOCTL_DOMAIN_OFFSET:
  3723             return ec_cdev_ioctl_domain_offset(master, arg, priv);
  3812             ret = ec_cdev_ioctl_domain_offset(master, arg, priv);
       
  3813             break;
  3724         case EC_IOCTL_DOMAIN_PROCESS:
  3814         case EC_IOCTL_DOMAIN_PROCESS:
  3725             if (!(filp->f_mode & FMODE_WRITE))
  3815             if (!(filp->f_mode & FMODE_WRITE)) {
  3726                 return -EPERM;
  3816                 ret = -EPERM;
  3727             return ec_cdev_ioctl_domain_process(master, arg, priv);
  3817                 break;
       
  3818             }
       
  3819             ret = ec_cdev_ioctl_domain_process(master, arg, priv);
       
  3820             break;
  3728         case EC_IOCTL_DOMAIN_QUEUE:
  3821         case EC_IOCTL_DOMAIN_QUEUE:
  3729             if (!(filp->f_mode & FMODE_WRITE))
  3822             if (!(filp->f_mode & FMODE_WRITE)) {
  3730                 return -EPERM;
  3823                 ret = -EPERM;
  3731             return ec_cdev_ioctl_domain_queue(master, arg, priv);
  3824                 break;
       
  3825             }
       
  3826             ret = ec_cdev_ioctl_domain_queue(master, arg, priv);
       
  3827             break;
  3732         case EC_IOCTL_DOMAIN_STATE:
  3828         case EC_IOCTL_DOMAIN_STATE:
  3733             return ec_cdev_ioctl_domain_state(master, arg, priv);
  3829             ret = ec_cdev_ioctl_domain_state(master, arg, priv);
       
  3830             break;
  3734         case EC_IOCTL_SDO_REQUEST_TIMEOUT:
  3831         case EC_IOCTL_SDO_REQUEST_TIMEOUT:
  3735             if (!(filp->f_mode & FMODE_WRITE))
  3832             if (!(filp->f_mode & FMODE_WRITE)) {
  3736                 return -EPERM;
  3833                 ret = -EPERM;
  3737             return ec_cdev_ioctl_sdo_request_timeout(master, arg, priv);
  3834                 break;
       
  3835             }
       
  3836             ret = ec_cdev_ioctl_sdo_request_timeout(master, arg, priv);
       
  3837             break;
  3738         case EC_IOCTL_SDO_REQUEST_STATE:
  3838         case EC_IOCTL_SDO_REQUEST_STATE:
  3739             return ec_cdev_ioctl_sdo_request_state(master, arg, priv);
  3839             ret = ec_cdev_ioctl_sdo_request_state(master, arg, priv);
       
  3840             break;
  3740         case EC_IOCTL_SDO_REQUEST_READ:
  3841         case EC_IOCTL_SDO_REQUEST_READ:
  3741             if (!(filp->f_mode & FMODE_WRITE))
  3842             if (!(filp->f_mode & FMODE_WRITE)) {
  3742                 return -EPERM;
  3843                 ret = -EPERM;
  3743             return ec_cdev_ioctl_sdo_request_read(master, arg, priv);
  3844                 break;
       
  3845             }
       
  3846             ret = ec_cdev_ioctl_sdo_request_read(master, arg, priv);
       
  3847             break;
  3744         case EC_IOCTL_SDO_REQUEST_WRITE:
  3848         case EC_IOCTL_SDO_REQUEST_WRITE:
  3745             if (!(filp->f_mode & FMODE_WRITE))
  3849             if (!(filp->f_mode & FMODE_WRITE)) {
  3746                 return -EPERM;
  3850                 ret = -EPERM;
  3747             return ec_cdev_ioctl_sdo_request_write(master, arg, priv);
  3851                 break;
       
  3852             }
       
  3853             ret = ec_cdev_ioctl_sdo_request_write(master, arg, priv);
       
  3854             break;
  3748         case EC_IOCTL_SDO_REQUEST_DATA:
  3855         case EC_IOCTL_SDO_REQUEST_DATA:
  3749             return ec_cdev_ioctl_sdo_request_data(master, arg, priv);
  3856             ret = ec_cdev_ioctl_sdo_request_data(master, arg, priv);
       
  3857             break;
  3750         case EC_IOCTL_VOE_SEND_HEADER:
  3858         case EC_IOCTL_VOE_SEND_HEADER:
  3751             if (!(filp->f_mode & FMODE_WRITE))
  3859             if (!(filp->f_mode & FMODE_WRITE)) {
  3752                 return -EPERM;
  3860                 ret = -EPERM;
  3753             return ec_cdev_ioctl_voe_send_header(master, arg, priv);
  3861                 break;
       
  3862             }
       
  3863             ret = ec_cdev_ioctl_voe_send_header(master, arg, priv);
       
  3864             break;
  3754         case EC_IOCTL_VOE_REC_HEADER:
  3865         case EC_IOCTL_VOE_REC_HEADER:
  3755             return ec_cdev_ioctl_voe_rec_header(master, arg, priv);
  3866             ret = ec_cdev_ioctl_voe_rec_header(master, arg, priv);
       
  3867             break;
  3756         case EC_IOCTL_VOE_READ:
  3868         case EC_IOCTL_VOE_READ:
  3757             if (!(filp->f_mode & FMODE_WRITE))
  3869             if (!(filp->f_mode & FMODE_WRITE)) {
  3758                 return -EPERM;
  3870                 ret = -EPERM;
  3759             return ec_cdev_ioctl_voe_read(master, arg, priv);
  3871                 break;
       
  3872             }
       
  3873             ret = ec_cdev_ioctl_voe_read(master, arg, priv);
       
  3874             break;
  3760         case EC_IOCTL_VOE_READ_NOSYNC:
  3875         case EC_IOCTL_VOE_READ_NOSYNC:
  3761             if (!(filp->f_mode & FMODE_WRITE))
  3876             if (!(filp->f_mode & FMODE_WRITE)) {
  3762                 return -EPERM;
  3877                 ret = -EPERM;
  3763             return ec_cdev_ioctl_voe_read_nosync(master, arg, priv);
  3878                 break;
       
  3879             }
       
  3880             ret = ec_cdev_ioctl_voe_read_nosync(master, arg, priv);
       
  3881             break;
  3764         case EC_IOCTL_VOE_WRITE:
  3882         case EC_IOCTL_VOE_WRITE:
  3765             if (!(filp->f_mode & FMODE_WRITE))
  3883             if (!(filp->f_mode & FMODE_WRITE)) {
  3766                 return -EPERM;
  3884                 ret = -EPERM;
  3767             return ec_cdev_ioctl_voe_write(master, arg, priv);
  3885                 break;
       
  3886             }
       
  3887             ret = ec_cdev_ioctl_voe_write(master, arg, priv);
       
  3888             break;
  3768         case EC_IOCTL_VOE_EXEC:
  3889         case EC_IOCTL_VOE_EXEC:
  3769             if (!(filp->f_mode & FMODE_WRITE))
  3890             if (!(filp->f_mode & FMODE_WRITE)) {
  3770                 return -EPERM;
  3891                 ret = -EPERM;
  3771             return ec_cdev_ioctl_voe_exec(master, arg, priv);
  3892                 break;
       
  3893             }
       
  3894             ret = ec_cdev_ioctl_voe_exec(master, arg, priv);
       
  3895             break;
  3772         case EC_IOCTL_VOE_DATA:
  3896         case EC_IOCTL_VOE_DATA:
  3773             return ec_cdev_ioctl_voe_data(master, arg, priv);
  3897             ret = ec_cdev_ioctl_voe_data(master, arg, priv);
       
  3898             break;
  3774         case EC_IOCTL_SET_SEND_INTERVAL:
  3899         case EC_IOCTL_SET_SEND_INTERVAL:
  3775             if (!(filp->f_mode & FMODE_WRITE))
  3900             if (!(filp->f_mode & FMODE_WRITE)) {
  3776                 return -EPERM;
  3901                 ret = -EPERM;
  3777             return ec_cdev_ioctl_set_send_interval(master, arg, priv);
  3902                 break;
       
  3903             }
       
  3904             ret = ec_cdev_ioctl_set_send_interval(master, arg, priv);
       
  3905             break;
  3778         default:
  3906         default:
  3779             return -ENOTTY;
  3907             ret = -ENOTTY;
  3780     }
  3908             break;
       
  3909     }
       
  3910 
       
  3911 #if DEBUG_LATENCY
       
  3912     b = get_cycles();
       
  3913     t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
       
  3914     if (t > 50) {
       
  3915         EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
       
  3916                 _IOC_NR(cmd), t);
       
  3917     }
       
  3918 #endif
       
  3919 
       
  3920     return ret;
  3781 }
  3921 }
  3782 
  3922 
  3783 /*****************************************************************************/
  3923 /*****************************************************************************/
  3784 
  3924 
  3785 /** Memory-map callback for the EtherCAT character device.
  3925 /** Memory-map callback for the EtherCAT character device.