master/cdev.c
branchredundancy
changeset 2306 4c0c7347a956
parent 2267 2d36f36a433c
child 2345 4b7d9158acac
equal deleted inserted replaced
2305:668bdb89879b 2306:4c0c7347a956
    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 *);
  1721         return -EFAULT;
  1727         return -EFAULT;
  1722     }
  1728     }
  1723 
  1729 
  1724     if (down_interruptible(&master->master_sem))
  1730     if (down_interruptible(&master->master_sem))
  1725         return -EINTR;
  1731         return -EINTR;
  1726     ec_master_set_send_interval(master,send_interval);
  1732 
       
  1733     ec_master_set_send_interval(master, send_interval);
       
  1734 
  1727     up(&master->master_sem);
  1735     up(&master->master_sem);
  1728 
  1736     return 0;
  1729     return 0;
  1737 }
  1730 }
       
  1731 
       
  1732 
  1738 
  1733 /*****************************************************************************/
  1739 /*****************************************************************************/
  1734 
  1740 
  1735 /** Send frames.
  1741 /** Send frames.
  1736  */
  1742  */
  2034     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2040     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2035         up(&master->master_sem);
  2041         up(&master->master_sem);
  2036         return -ENOENT;
  2042         return -ENOENT;
  2037     }
  2043     }
  2038 
  2044 
  2039     up(&master->master_sem); // FIXME
  2045     up(&master->master_sem); /** \fixme sc could be invalidated */
  2040 
  2046 
  2041     return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
  2047     return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
  2042 }
  2048 }
  2043 
  2049 
  2044 /*****************************************************************************/
  2050 /*****************************************************************************/
  2066     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2072     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2067         up(&master->master_sem);
  2073         up(&master->master_sem);
  2068         return -ENOENT;
  2074         return -ENOENT;
  2069     }
  2075     }
  2070 
  2076 
  2071     up(&master->master_sem); // FIXME
  2077     up(&master->master_sem); /** \fixme sc could be invalidated */
  2072 
  2078 
  2073     ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
  2079     ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
  2074     return 0;
  2080     return 0;
  2075 }
  2081 }
  2076 
  2082 
  2099     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2105     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2100         up(&master->master_sem);
  2106         up(&master->master_sem);
  2101         return -ENOENT;
  2107         return -ENOENT;
  2102     }
  2108     }
  2103 
  2109 
  2104     up(&master->master_sem); // FIXME
  2110     up(&master->master_sem); /** \fixme sc could be invalidated */
  2105 
  2111 
  2106     return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
  2112     return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
  2107             data.entry_index, data.entry_subindex, data.entry_bit_length);
  2113             data.entry_index, data.entry_subindex, data.entry_bit_length);
  2108 }
  2114 }
  2109 
  2115 
  2132     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2138     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2133         up(&master->master_sem);
  2139         up(&master->master_sem);
  2134         return -ENOENT;
  2140         return -ENOENT;
  2135     }
  2141     }
  2136 
  2142 
  2137     up(&master->master_sem); // FIXME
  2143     up(&master->master_sem); /** \fixme sc could be invalidated */
  2138 
  2144 
  2139     ecrt_slave_config_pdo_mapping_clear(sc, data.index);
  2145     ecrt_slave_config_pdo_mapping_clear(sc, data.index);
  2140     return 0;
  2146     return 0;
  2141 }
  2147 }
  2142 
  2148 
  2172     if (!(domain = ec_master_find_domain(master, data.domain_index))) {
  2178     if (!(domain = ec_master_find_domain(master, data.domain_index))) {
  2173         up(&master->master_sem);
  2179         up(&master->master_sem);
  2174         return -ENOENT;
  2180         return -ENOENT;
  2175     }
  2181     }
  2176 
  2182 
  2177     up(&master->master_sem); // FIXME
  2183     up(&master->master_sem); /** \fixme sc or domain could be invalidated */
  2178 
  2184 
  2179     ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
  2185     ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
  2180             data.entry_subindex, domain, &data.bit_position);
  2186             data.entry_subindex, domain, &data.bit_position);
  2181 
  2187 
  2182     if (copy_to_user((void __user *) arg, &data, sizeof(data)))
  2188     if (copy_to_user((void __user *) arg, &data, sizeof(data)))
  2265         up(&master->master_sem);
  2271         up(&master->master_sem);
  2266         kfree(sdo_data);
  2272         kfree(sdo_data);
  2267         return -ENOENT;
  2273         return -ENOENT;
  2268     }
  2274     }
  2269 
  2275 
  2270     up(&master->master_sem); // FIXME
  2276     up(&master->master_sem); /** \fixme sc could be invalidated */
  2271 
  2277 
  2272     if (data.complete_access) {
  2278     if (data.complete_access) {
  2273         ret = ecrt_slave_config_complete_sdo(sc,
  2279         ret = ecrt_slave_config_complete_sdo(sc,
  2274                 data.index, sdo_data, data.size);
  2280                 data.index, sdo_data, data.size);
  2275     } else {
  2281     } else {
  2314 
  2320 
  2315     list_for_each_entry(req, &sc->sdo_requests, list) {
  2321     list_for_each_entry(req, &sc->sdo_requests, list) {
  2316         data.request_index++;
  2322         data.request_index++;
  2317     }
  2323     }
  2318 
  2324 
  2319     up(&master->master_sem);
  2325     up(&master->master_sem); /** \fixme sc could be invalidated */
  2320 
  2326 
  2321     req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
  2327     req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
  2322             data.sdo_subindex, data.size);
  2328             data.sdo_subindex, data.size);
  2323     if (IS_ERR(req))
  2329     if (IS_ERR(req))
  2324         return PTR_ERR(req);
  2330         return PTR_ERR(req);
  2363 
  2369 
  2364     list_for_each_entry(voe, &sc->voe_handlers, list) {
  2370     list_for_each_entry(voe, &sc->voe_handlers, list) {
  2365         data.voe_index++;
  2371         data.voe_index++;
  2366     }
  2372     }
  2367 
  2373 
  2368     up(&master->master_sem);
  2374     up(&master->master_sem); /** \fixme sc could be invalidated */
  2369 
  2375 
  2370     voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
  2376     voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
  2371     if (IS_ERR(voe))
  2377     if (IS_ERR(voe))
  2372         return PTR_ERR(voe);
  2378         return PTR_ERR(voe);
  2373 
  2379 
  2396 
  2402 
  2397     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  2403     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  2398         return -EFAULT;
  2404         return -EFAULT;
  2399     }
  2405     }
  2400 
  2406 
  2401     if (down_interruptible(&master->master_sem))
  2407     /* no locking of master_sem needed, because sc will not be deleted in the
  2402         return -EINTR;
  2408      * meantime. */
  2403 
  2409 
  2404     if (!(sc = ec_master_get_config_const(master, data.config_index))) {
  2410     if (!(sc = ec_master_get_config_const(master, data.config_index))) {
  2405         up(&master->master_sem);
       
  2406         return -ENOENT;
  2411         return -ENOENT;
  2407     }
  2412     }
  2408 
  2413 
  2409     ecrt_slave_config_state(sc, &state);
  2414     ecrt_slave_config_state(sc, &state);
  2410 
       
  2411     up(&master->master_sem);
       
  2412 
  2415 
  2413     if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
  2416     if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
  2414         return -EFAULT;
  2417         return -EFAULT;
  2415 
  2418 
  2416     return 0;
  2419     return 0;
  2458         up(&master->master_sem);
  2461         up(&master->master_sem);
  2459         kfree(data);
  2462         kfree(data);
  2460         return -ENOENT;
  2463         return -ENOENT;
  2461     }
  2464     }
  2462 
  2465 
  2463     up(&master->master_sem); // FIXME
  2466     up(&master->master_sem); /** \fixme sc could be invalidated */
  2464 
  2467 
  2465     ret = ecrt_slave_config_idn(
  2468     ret = ecrt_slave_config_idn(
  2466             sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
  2469             sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
  2467     kfree(data);
  2470     kfree(data);
  2468     return ret;
  2471     return ret;
  2513     ec_domain_t *domain;
  2516     ec_domain_t *domain;
  2514 
  2517 
  2515     if (unlikely(!priv->requested))
  2518     if (unlikely(!priv->requested))
  2516         return -EPERM;
  2519         return -EPERM;
  2517 
  2520 
  2518     if (down_interruptible(&master->master_sem))
  2521     /* no locking of master_sem needed, because domain will not be deleted in
  2519         return -EINTR;
  2522      * the meantime. */
  2520 
  2523 
  2521     if (!(domain = ec_master_find_domain(master, arg))) {
  2524     if (!(domain = ec_master_find_domain(master, arg))) {
  2522         up(&master->master_sem);
       
  2523         return -ENOENT;
  2525         return -ENOENT;
  2524     }
  2526     }
  2525 
  2527 
  2526     ecrt_domain_process(domain);
  2528     ecrt_domain_process(domain);
  2527     up(&master->master_sem);
       
  2528     return 0;
  2529     return 0;
  2529 }
  2530 }
  2530 
  2531 
  2531 /*****************************************************************************/
  2532 /*****************************************************************************/
  2532 
  2533 
  2541     ec_domain_t *domain;
  2542     ec_domain_t *domain;
  2542 
  2543 
  2543     if (unlikely(!priv->requested))
  2544     if (unlikely(!priv->requested))
  2544         return -EPERM;
  2545         return -EPERM;
  2545 
  2546 
  2546     if (down_interruptible(&master->master_sem))
  2547     /* no locking of master_sem needed, because domain will not be deleted in
  2547         return -EINTR;
  2548      * the meantime. */
  2548 
  2549 
  2549     if (!(domain = ec_master_find_domain(master, arg))) {
  2550     if (!(domain = ec_master_find_domain(master, arg))) {
  2550         up(&master->master_sem);
       
  2551         return -ENOENT;
  2551         return -ENOENT;
  2552     }
  2552     }
  2553 
  2553 
  2554     ecrt_domain_queue(domain);
  2554     ecrt_domain_queue(domain);
  2555     up(&master->master_sem);
       
  2556     return 0;
  2555     return 0;
  2557 }
  2556 }
  2558 
  2557 
  2559 /*****************************************************************************/
  2558 /*****************************************************************************/
  2560 
  2559 
  2575 
  2574 
  2576     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  2575     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  2577         return -EFAULT;
  2576         return -EFAULT;
  2578     }
  2577     }
  2579 
  2578 
  2580     if (down_interruptible(&master->master_sem))
  2579     /* no locking of master_sem needed, because domain will not be deleted in
  2581         return -EINTR;
  2580      * the meantime. */
  2582 
  2581 
  2583     if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
  2582     if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
  2584         up(&master->master_sem);
       
  2585         return -ENOENT;
  2583         return -ENOENT;
  2586     }
  2584     }
  2587 
  2585 
  2588     ecrt_domain_state(domain, &state);
  2586     ecrt_domain_state(domain, &state);
  2589 
       
  2590     up(&master->master_sem);
       
  2591 
  2587 
  2592     if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
  2588     if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
  2593         return -EFAULT;
  2589         return -EFAULT;
  2594 
  2590 
  2595     return 0;
  2591     return 0;
  2613         return -EPERM;
  2609         return -EPERM;
  2614 
  2610 
  2615     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2611     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2616         return -EFAULT;
  2612         return -EFAULT;
  2617 
  2613 
  2618     if (down_interruptible(&master->master_sem))
  2614     /* no locking of master_sem needed, because neither sc nor req will not be
  2619         return -EINTR;
  2615      * deleted in the meantime. */
  2620 
  2616 
  2621     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2617     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2622         up(&master->master_sem);
       
  2623         return -ENOENT;
  2618         return -ENOENT;
  2624     }
  2619     }
  2625 
  2620 
  2626     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2621     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2627         up(&master->master_sem);
       
  2628         return -ENOENT;
  2622         return -ENOENT;
  2629     }
  2623     }
  2630 
       
  2631     up(&master->master_sem);
       
  2632 
  2624 
  2633     ecrt_sdo_request_timeout(req, data.timeout);
  2625     ecrt_sdo_request_timeout(req, data.timeout);
  2634     return 0;
  2626     return 0;
  2635 }
  2627 }
  2636 
  2628 
  2652         return -EPERM;
  2644         return -EPERM;
  2653 
  2645 
  2654     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2646     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2655         return -EFAULT;
  2647         return -EFAULT;
  2656 
  2648 
  2657     if (down_interruptible(&master->master_sem))
  2649     /* no locking of master_sem needed, because neither sc nor req will not be
  2658         return -EINTR;
  2650      * deleted in the meantime. */
  2659 
  2651 
  2660     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2652     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2661         up(&master->master_sem);
       
  2662         return -ENOENT;
  2653         return -ENOENT;
  2663     }
  2654     }
  2664 
  2655 
  2665     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2656     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2666         up(&master->master_sem);
       
  2667         return -ENOENT;
  2657         return -ENOENT;
  2668     }
  2658     }
  2669 
  2659 
  2670     data.state = ecrt_sdo_request_state(req);
  2660     data.state = ecrt_sdo_request_state(req);
  2671     if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
  2661     if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
  2672         data.size = ecrt_sdo_request_data_size(req);
  2662         data.size = ecrt_sdo_request_data_size(req);
  2673     else
  2663     else
  2674         data.size = 0;
  2664         data.size = 0;
  2675 
  2665 
  2676     up(&master->master_sem);
       
  2677 
       
  2678     if (copy_to_user((void __user *) arg, &data, sizeof(data)))
  2666     if (copy_to_user((void __user *) arg, &data, sizeof(data)))
  2679         return -EFAULT;
  2667         return -EFAULT;
  2680 
  2668 
  2681     return 0;
  2669     return 0;
  2682 }
  2670 }
  2699         return -EPERM;
  2687         return -EPERM;
  2700 
  2688 
  2701     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2689     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2702         return -EFAULT;
  2690         return -EFAULT;
  2703 
  2691 
  2704     if (down_interruptible(&master->master_sem))
  2692     /* no locking of master_sem needed, because neither sc nor req will not be
  2705         return -EINTR;
  2693      * deleted in the meantime. */
  2706 
  2694 
  2707     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2695     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2708         up(&master->master_sem);
       
  2709         return -ENOENT;
  2696         return -ENOENT;
  2710     }
  2697     }
  2711 
  2698 
  2712     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2699     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2713         up(&master->master_sem);
       
  2714         return -ENOENT;
  2700         return -ENOENT;
  2715     }
  2701     }
  2716 
       
  2717     up(&master->master_sem);
       
  2718 
  2702 
  2719     ecrt_sdo_request_read(req);
  2703     ecrt_sdo_request_read(req);
  2720     return 0;
  2704     return 0;
  2721 }
  2705 }
  2722 
  2706 
  2744     if (!data.size) {
  2728     if (!data.size) {
  2745         EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
  2729         EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
  2746         return -EINVAL;
  2730         return -EINVAL;
  2747     }
  2731     }
  2748 
  2732 
  2749     if (down_interruptible(&master->master_sem))
  2733     /* no locking of master_sem needed, because neither sc nor req will not be
  2750         return -EINTR;
  2734      * deleted in the meantime. */
  2751 
  2735 
  2752     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2736     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2753         up(&master->master_sem);
       
  2754         return -ENOENT;
  2737         return -ENOENT;
  2755     }
  2738     }
  2756 
  2739 
  2757     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2740     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2758         up(&master->master_sem);
       
  2759         return -ENOENT;
  2741         return -ENOENT;
  2760     }
  2742     }
  2761 
       
  2762     up(&master->master_sem);
       
  2763 
  2743 
  2764     ret = ec_sdo_request_alloc(req, data.size);
  2744     ret = ec_sdo_request_alloc(req, data.size);
  2765     if (ret)
  2745     if (ret)
  2766         return ret;
  2746         return ret;
  2767 
  2747 
  2791         return -EPERM;
  2771         return -EPERM;
  2792 
  2772 
  2793     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2773     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2794         return -EFAULT;
  2774         return -EFAULT;
  2795 
  2775 
  2796     if (down_interruptible(&master->master_sem))
  2776     /* no locking of master_sem needed, because neither sc nor req will not be
  2797         return -EINTR;
  2777      * deleted in the meantime. */
  2798 
  2778 
  2799     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2779     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2800         up(&master->master_sem);
       
  2801         return -ENOENT;
  2780         return -ENOENT;
  2802     }
  2781     }
  2803 
  2782 
  2804     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2783     if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
  2805         up(&master->master_sem);
       
  2806         return -ENOENT;
  2784         return -ENOENT;
  2807     }
  2785     }
  2808 
       
  2809     up(&master->master_sem);
       
  2810 
  2786 
  2811     if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
  2787     if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
  2812                 ecrt_sdo_request_data_size(req)))
  2788                 ecrt_sdo_request_data_size(req)))
  2813         return -EFAULT;
  2789         return -EFAULT;
  2814 
  2790 
  2841         return -EFAULT;
  2817         return -EFAULT;
  2842 
  2818 
  2843     if (get_user(vendor_type, data.vendor_type))
  2819     if (get_user(vendor_type, data.vendor_type))
  2844         return -EFAULT;
  2820         return -EFAULT;
  2845 
  2821 
  2846     if (down_interruptible(&master->master_sem))
  2822     /* no locking of master_sem needed, because neither sc nor voe will not be
  2847         return -EINTR;
  2823      * deleted in the meantime. */
  2848 
  2824 
  2849     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2825     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2850         up(&master->master_sem);
       
  2851         return -ENOENT;
  2826         return -ENOENT;
  2852     }
  2827     }
  2853 
  2828 
  2854     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2829     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2855         up(&master->master_sem);
       
  2856         return -ENOENT;
  2830         return -ENOENT;
  2857     }
  2831     }
  2858 
       
  2859     up(&master->master_sem);
       
  2860 
  2832 
  2861     ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
  2833     ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
  2862     return 0;
  2834     return 0;
  2863 }
  2835 }
  2864 
  2836 
  2882         return -EPERM;
  2854         return -EPERM;
  2883 
  2855 
  2884     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2856     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2885         return -EFAULT;
  2857         return -EFAULT;
  2886 
  2858 
  2887     if (down_interruptible(&master->master_sem))
  2859     /* no locking of master_sem needed, because neither sc nor voe will not be
  2888         return -EINTR;
  2860      * deleted in the meantime. */
  2889 
  2861 
  2890     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2862     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2891         up(&master->master_sem);
       
  2892         return -ENOENT;
  2863         return -ENOENT;
  2893     }
  2864     }
  2894 
  2865 
  2895     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2866     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2896         up(&master->master_sem);
       
  2897         return -ENOENT;
  2867         return -ENOENT;
  2898     }
  2868     }
  2899 
  2869 
  2900     ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
  2870     ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
  2901 
       
  2902     up(&master->master_sem);
       
  2903 
  2871 
  2904     if (likely(data.vendor_id))
  2872     if (likely(data.vendor_id))
  2905         if (put_user(vendor_id, data.vendor_id))
  2873         if (put_user(vendor_id, data.vendor_id))
  2906             return -EFAULT;
  2874             return -EFAULT;
  2907 
  2875 
  2930         return -EPERM;
  2898         return -EPERM;
  2931 
  2899 
  2932     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2900     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2933         return -EFAULT;
  2901         return -EFAULT;
  2934 
  2902 
  2935     if (down_interruptible(&master->master_sem))
  2903     /* no locking of master_sem needed, because neither sc nor voe will not be
  2936         return -EINTR;
  2904      * deleted in the meantime. */
  2937 
  2905 
  2938     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2906     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2939         up(&master->master_sem);
       
  2940         return -ENOENT;
  2907         return -ENOENT;
  2941     }
  2908     }
  2942 
  2909 
  2943     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2910     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2944         up(&master->master_sem);
       
  2945         return -ENOENT;
  2911         return -ENOENT;
  2946     }
  2912     }
  2947 
       
  2948     up(&master->master_sem);
       
  2949 
  2913 
  2950     ecrt_voe_handler_read(voe);
  2914     ecrt_voe_handler_read(voe);
  2951     return 0;
  2915     return 0;
  2952 }
  2916 }
  2953 
  2917 
  2969         return -EPERM;
  2933         return -EPERM;
  2970 
  2934 
  2971     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2935     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2972         return -EFAULT;
  2936         return -EFAULT;
  2973 
  2937 
  2974     if (down_interruptible(&master->master_sem))
  2938     /* no locking of master_sem needed, because neither sc nor voe will not be
  2975         return -EINTR;
  2939      * deleted in the meantime. */
  2976 
  2940 
  2977     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2941     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2978         up(&master->master_sem);
       
  2979         return -ENOENT;
  2942         return -ENOENT;
  2980     }
  2943     }
  2981 
  2944 
  2982     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2945     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2983         up(&master->master_sem);
       
  2984         return -ENOENT;
  2946         return -ENOENT;
  2985     }
  2947     }
  2986 
       
  2987     up(&master->master_sem);
       
  2988 
  2948 
  2989     ecrt_voe_handler_read_nosync(voe);
  2949     ecrt_voe_handler_read_nosync(voe);
  2990     return 0;
  2950     return 0;
  2991 }
  2951 }
  2992 
  2952 
  3008         return -EPERM;
  2968         return -EPERM;
  3009 
  2969 
  3010     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  2970     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3011         return -EFAULT;
  2971         return -EFAULT;
  3012 
  2972 
  3013     if (down_interruptible(&master->master_sem))
  2973     /* no locking of master_sem needed, because neither sc nor voe will not be
  3014         return -EINTR;
  2974      * deleted in the meantime. */
  3015 
  2975 
  3016     if (!(sc = ec_master_get_config(master, data.config_index))) {
  2976     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3017         up(&master->master_sem);
       
  3018         return -ENOENT;
  2977         return -ENOENT;
  3019     }
  2978     }
  3020 
  2979 
  3021     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  2980     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3022         up(&master->master_sem);
       
  3023         return -ENOENT;
  2981         return -ENOENT;
  3024     }
  2982     }
  3025 
       
  3026     up(&master->master_sem);
       
  3027 
  2983 
  3028     if (data.size) {
  2984     if (data.size) {
  3029         if (data.size > ec_voe_handler_mem_size(voe))
  2985         if (data.size > ec_voe_handler_mem_size(voe))
  3030             return -EOVERFLOW;
  2986             return -EOVERFLOW;
  3031 
  2987 
  3056         return -EPERM;
  3012         return -EPERM;
  3057 
  3013 
  3058     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3014     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3059         return -EFAULT;
  3015         return -EFAULT;
  3060 
  3016 
  3061     if (down_interruptible(&master->master_sem))
  3017     /* no locking of master_sem needed, because neither sc nor voe will not be
  3062         return -EINTR;
  3018      * deleted in the meantime. */
  3063 
  3019 
  3064     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3020     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3065         up(&master->master_sem);
       
  3066         return -ENOENT;
  3021         return -ENOENT;
  3067     }
  3022     }
  3068 
  3023 
  3069     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3024     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3070         up(&master->master_sem);
       
  3071         return -ENOENT;
  3025         return -ENOENT;
  3072     }
  3026     }
  3073 
       
  3074     up(&master->master_sem);
       
  3075 
  3027 
  3076     data.state = ecrt_voe_handler_execute(voe);
  3028     data.state = ecrt_voe_handler_execute(voe);
  3077     if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
  3029     if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
  3078         data.size = ecrt_voe_handler_data_size(voe);
  3030         data.size = ecrt_voe_handler_data_size(voe);
  3079     else
  3031     else
  3103         return -EPERM;
  3055         return -EPERM;
  3104 
  3056 
  3105     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3057     if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
  3106         return -EFAULT;
  3058         return -EFAULT;
  3107 
  3059 
  3108     if (down_interruptible(&master->master_sem))
  3060     /* no locking of master_sem needed, because neither sc nor voe will not be
  3109         return -EINTR;
  3061      * deleted in the meantime. */
  3110 
  3062 
  3111     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3063     if (!(sc = ec_master_get_config(master, data.config_index))) {
  3112         up(&master->master_sem);
       
  3113         return -ENOENT;
  3064         return -ENOENT;
  3114     }
  3065     }
  3115 
  3066 
  3116     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3067     if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
  3117         up(&master->master_sem);
       
  3118         return -ENOENT;
  3068         return -ENOENT;
  3119     }
  3069     }
  3120 
       
  3121     up(&master->master_sem);
       
  3122 
  3070 
  3123     if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
  3071     if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
  3124                 ecrt_voe_handler_data_size(voe)))
  3072                 ecrt_voe_handler_data_size(voe)))
  3125         return -EFAULT;
  3073         return -EFAULT;
  3126 
  3074 
  3146 
  3094 
  3147     ec_foe_request_init(&request.req, data.file_name);
  3095     ec_foe_request_init(&request.req, data.file_name);
  3148     ec_foe_request_read(&request.req);
  3096     ec_foe_request_read(&request.req);
  3149     ec_foe_request_alloc(&request.req, 10000); // FIXME
  3097     ec_foe_request_alloc(&request.req, 10000); // FIXME
  3150 
  3098 
  3151     if (down_interruptible(&master->master_sem))
  3099     if (down_interruptible(&master->master_sem)) {
       
  3100         ec_foe_request_clear(&request.req);
  3152         return -EINTR;
  3101         return -EINTR;
       
  3102     }
  3153 
  3103 
  3154     if (!(request.slave = ec_master_find_slave(
  3104     if (!(request.slave = ec_master_find_slave(
  3155                     master, 0, data.slave_position))) {
  3105                     master, 0, data.slave_position))) {
  3156         up(&master->master_sem);
  3106         up(&master->master_sem);
  3157         ec_foe_request_clear(&request.req);
  3107         ec_foe_request_clear(&request.req);
  3252         return -EFAULT;
  3202         return -EFAULT;
  3253     }
  3203     }
  3254     request.req.data_size = data.buffer_size;
  3204     request.req.data_size = data.buffer_size;
  3255     ec_foe_request_write(&request.req);
  3205     ec_foe_request_write(&request.req);
  3256 
  3206 
  3257     if (down_interruptible(&master->master_sem))
  3207     if (down_interruptible(&master->master_sem)) {
       
  3208         ec_foe_request_clear(&request.req);
  3258         return -EINTR;
  3209         return -EINTR;
       
  3210     }
  3259 
  3211 
  3260     if (!(request.slave = ec_master_find_slave(
  3212     if (!(request.slave = ec_master_find_slave(
  3261                     master, 0, data.slave_position))) {
  3213                     master, 0, data.slave_position))) {
  3262         up(&master->master_sem);
  3214         up(&master->master_sem);
  3263         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  3215         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  3457 
  3409 
  3458 /** Called when an ioctl() command is issued.
  3410 /** Called when an ioctl() command is issued.
  3459  */
  3411  */
  3460 long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  3412 long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  3461 {
  3413 {
       
  3414 #if DEBUG_LATENCY
       
  3415     cycles_t a = get_cycles(), b;
       
  3416     unsigned int t;
       
  3417 #endif
  3462     ec_cdev_priv_t *priv = (ec_cdev_priv_t *) filp->private_data;
  3418     ec_cdev_priv_t *priv = (ec_cdev_priv_t *) filp->private_data;
  3463     ec_master_t *master = priv->cdev->master;
  3419     ec_master_t *master = priv->cdev->master;
       
  3420     int ret;
  3464 
  3421 
  3465 #if DEBUG_IOCTL
  3422 #if DEBUG_IOCTL
  3466     EC_MASTER_DBG(master, 0, "ioctl(filp = 0x%p, cmd = 0x%08x (0x%02x),"
  3423     EC_MASTER_DBG(master, 0, "ioctl(filp = 0x%p, cmd = 0x%08x (0x%02x),"
  3467             " arg = 0x%lx)\n", filp, cmd, _IOC_NR(cmd), arg);
  3424             " arg = 0x%lx)\n", filp, cmd, _IOC_NR(cmd), arg);
  3468 #endif
  3425 #endif
  3469 
  3426 
  3470     switch (cmd) {
  3427     switch (cmd) {
  3471         case EC_IOCTL_MODULE:
  3428         case EC_IOCTL_MODULE:
  3472             return ec_cdev_ioctl_module(arg);
  3429             ret = ec_cdev_ioctl_module(arg);
       
  3430             break;
  3473         case EC_IOCTL_MASTER:
  3431         case EC_IOCTL_MASTER:
  3474             return ec_cdev_ioctl_master(master, arg);
  3432             ret = ec_cdev_ioctl_master(master, arg);
       
  3433             break;
  3475         case EC_IOCTL_SLAVE:
  3434         case EC_IOCTL_SLAVE:
  3476             return ec_cdev_ioctl_slave(master, arg);
  3435             ret = ec_cdev_ioctl_slave(master, arg);
       
  3436             break;
  3477         case EC_IOCTL_SLAVE_SYNC:
  3437         case EC_IOCTL_SLAVE_SYNC:
  3478             return ec_cdev_ioctl_slave_sync(master, arg);
  3438             ret = ec_cdev_ioctl_slave_sync(master, arg);
       
  3439             break;
  3479         case EC_IOCTL_SLAVE_SYNC_PDO:
  3440         case EC_IOCTL_SLAVE_SYNC_PDO:
  3480             return ec_cdev_ioctl_slave_sync_pdo(master, arg);
  3441             ret = ec_cdev_ioctl_slave_sync_pdo(master, arg);
       
  3442             break;
  3481         case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
  3443         case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
  3482             return ec_cdev_ioctl_slave_sync_pdo_entry(master, arg);
  3444             ret = ec_cdev_ioctl_slave_sync_pdo_entry(master, arg);
       
  3445             break;
  3483         case EC_IOCTL_DOMAIN:
  3446         case EC_IOCTL_DOMAIN:
  3484             return ec_cdev_ioctl_domain(master, arg);
  3447             ret = ec_cdev_ioctl_domain(master, arg);
       
  3448             break;
  3485         case EC_IOCTL_DOMAIN_FMMU:
  3449         case EC_IOCTL_DOMAIN_FMMU:
  3486             return ec_cdev_ioctl_domain_fmmu(master, arg);
  3450             ret = ec_cdev_ioctl_domain_fmmu(master, arg);
       
  3451             break;
  3487         case EC_IOCTL_DOMAIN_DATA:
  3452         case EC_IOCTL_DOMAIN_DATA:
  3488             return ec_cdev_ioctl_domain_data(master, arg);
  3453             ret = ec_cdev_ioctl_domain_data(master, arg);
       
  3454             break;
  3489         case EC_IOCTL_MASTER_DEBUG:
  3455         case EC_IOCTL_MASTER_DEBUG:
  3490             if (!(filp->f_mode & FMODE_WRITE))
  3456             if (!(filp->f_mode & FMODE_WRITE)) {
  3491                 return -EPERM;
  3457                 ret = -EPERM;
  3492             return ec_cdev_ioctl_master_debug(master, arg);
  3458                 break;
       
  3459             }
       
  3460             ret = ec_cdev_ioctl_master_debug(master, arg);
       
  3461             break;
  3493         case EC_IOCTL_MASTER_RESCAN:
  3462         case EC_IOCTL_MASTER_RESCAN:
  3494             if (!(filp->f_mode & FMODE_WRITE))
  3463             if (!(filp->f_mode & FMODE_WRITE)) {
  3495                 return -EPERM;
  3464                 ret = -EPERM;
  3496             return ec_cdev_ioctl_master_rescan(master, arg);
  3465                 break;
       
  3466             }
       
  3467             ret = ec_cdev_ioctl_master_rescan(master, arg);
       
  3468             break;
  3497         case EC_IOCTL_SLAVE_STATE:
  3469         case EC_IOCTL_SLAVE_STATE:
  3498             if (!(filp->f_mode & FMODE_WRITE))
  3470             if (!(filp->f_mode & FMODE_WRITE)) {
  3499                 return -EPERM;
  3471                 ret = -EPERM;
  3500             return ec_cdev_ioctl_slave_state(master, arg);
  3472                 break;
       
  3473             }
       
  3474             ret = ec_cdev_ioctl_slave_state(master, arg);
       
  3475             break;
  3501         case EC_IOCTL_SLAVE_SDO:
  3476         case EC_IOCTL_SLAVE_SDO:
  3502             return ec_cdev_ioctl_slave_sdo(master, arg);
  3477             ret = ec_cdev_ioctl_slave_sdo(master, arg);
       
  3478             break;
  3503         case EC_IOCTL_SLAVE_SDO_ENTRY:
  3479         case EC_IOCTL_SLAVE_SDO_ENTRY:
  3504             return ec_cdev_ioctl_slave_sdo_entry(master, arg);
  3480             ret = ec_cdev_ioctl_slave_sdo_entry(master, arg);
       
  3481             break;
  3505         case EC_IOCTL_SLAVE_SDO_UPLOAD:
  3482         case EC_IOCTL_SLAVE_SDO_UPLOAD:
  3506             return ec_cdev_ioctl_slave_sdo_upload(master, arg);
  3483             ret = ec_cdev_ioctl_slave_sdo_upload(master, arg);
       
  3484             break;
  3507         case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
  3485         case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
  3508             if (!(filp->f_mode & FMODE_WRITE))
  3486             if (!(filp->f_mode & FMODE_WRITE)) {
  3509                 return -EPERM;
  3487                 ret = -EPERM;
  3510             return ec_cdev_ioctl_slave_sdo_download(master, arg);
  3488                 break;
       
  3489             }
       
  3490             ret = ec_cdev_ioctl_slave_sdo_download(master, arg);
       
  3491             break;
  3511         case EC_IOCTL_SLAVE_SII_READ:
  3492         case EC_IOCTL_SLAVE_SII_READ:
  3512             return ec_cdev_ioctl_slave_sii_read(master, arg);
  3493             ret = ec_cdev_ioctl_slave_sii_read(master, arg);
       
  3494             break;
  3513         case EC_IOCTL_SLAVE_SII_WRITE:
  3495         case EC_IOCTL_SLAVE_SII_WRITE:
  3514             if (!(filp->f_mode & FMODE_WRITE))
  3496             if (!(filp->f_mode & FMODE_WRITE)) {
  3515                 return -EPERM;
  3497                 ret = -EPERM;
  3516             return ec_cdev_ioctl_slave_sii_write(master, arg);
  3498                 break;
       
  3499             }
       
  3500             ret = ec_cdev_ioctl_slave_sii_write(master, arg);
       
  3501             break;
  3517         case EC_IOCTL_SLAVE_REG_READ:
  3502         case EC_IOCTL_SLAVE_REG_READ:
  3518             return ec_cdev_ioctl_slave_reg_read(master, arg);
  3503             ret = ec_cdev_ioctl_slave_reg_read(master, arg);
       
  3504             break;
  3519         case EC_IOCTL_SLAVE_REG_WRITE:
  3505         case EC_IOCTL_SLAVE_REG_WRITE:
  3520             if (!(filp->f_mode & FMODE_WRITE))
  3506             if (!(filp->f_mode & FMODE_WRITE)) {
  3521                 return -EPERM;
  3507                 ret = -EPERM;
  3522             return ec_cdev_ioctl_slave_reg_write(master, arg);
  3508                 break;
       
  3509             }
       
  3510             ret = ec_cdev_ioctl_slave_reg_write(master, arg);
       
  3511             break;
  3523         case EC_IOCTL_SLAVE_FOE_READ:
  3512         case EC_IOCTL_SLAVE_FOE_READ:
  3524             return ec_cdev_ioctl_slave_foe_read(master, arg);
  3513             ret = ec_cdev_ioctl_slave_foe_read(master, arg);
       
  3514             break;
  3525         case EC_IOCTL_SLAVE_FOE_WRITE:
  3515         case EC_IOCTL_SLAVE_FOE_WRITE:
  3526             if (!(filp->f_mode & FMODE_WRITE))
  3516             if (!(filp->f_mode & FMODE_WRITE)) {
  3527                 return -EPERM;
  3517                 ret = -EPERM;
  3528             return ec_cdev_ioctl_slave_foe_write(master, arg);
  3518                 break;
       
  3519             }
       
  3520             ret = ec_cdev_ioctl_slave_foe_write(master, arg);
       
  3521             break;
  3529         case EC_IOCTL_SLAVE_SOE_READ:
  3522         case EC_IOCTL_SLAVE_SOE_READ:
  3530             return ec_cdev_ioctl_slave_soe_read(master, arg);
  3523             ret = ec_cdev_ioctl_slave_soe_read(master, arg);
       
  3524             break;
  3531         case EC_IOCTL_SLAVE_SOE_WRITE:
  3525         case EC_IOCTL_SLAVE_SOE_WRITE:
  3532             if (!(filp->f_mode & FMODE_WRITE))
  3526             if (!(filp->f_mode & FMODE_WRITE)) {
  3533                 return -EPERM;
  3527                 ret = -EPERM;
  3534             return ec_cdev_ioctl_slave_soe_write(master, arg);
  3528                 break;
       
  3529             }
       
  3530             ret = ec_cdev_ioctl_slave_soe_write(master, arg);
       
  3531             break;
  3535         case EC_IOCTL_CONFIG:
  3532         case EC_IOCTL_CONFIG:
  3536             return ec_cdev_ioctl_config(master, arg);
  3533             ret = ec_cdev_ioctl_config(master, arg);
       
  3534             break;
  3537         case EC_IOCTL_CONFIG_PDO:
  3535         case EC_IOCTL_CONFIG_PDO:
  3538             return ec_cdev_ioctl_config_pdo(master, arg);
  3536             ret = ec_cdev_ioctl_config_pdo(master, arg);
       
  3537             break;
  3539         case EC_IOCTL_CONFIG_PDO_ENTRY:
  3538         case EC_IOCTL_CONFIG_PDO_ENTRY:
  3540             return ec_cdev_ioctl_config_pdo_entry(master, arg);
  3539             ret = ec_cdev_ioctl_config_pdo_entry(master, arg);
       
  3540             break;
  3541         case EC_IOCTL_CONFIG_SDO:
  3541         case EC_IOCTL_CONFIG_SDO:
  3542             return ec_cdev_ioctl_config_sdo(master, arg);
  3542             ret = ec_cdev_ioctl_config_sdo(master, arg);
       
  3543             break;
  3543         case EC_IOCTL_CONFIG_IDN:
  3544         case EC_IOCTL_CONFIG_IDN:
  3544             return ec_cdev_ioctl_config_idn(master, arg);
  3545             ret = ec_cdev_ioctl_config_idn(master, arg);
       
  3546             break;
  3545 #ifdef EC_EOE
  3547 #ifdef EC_EOE
  3546         case EC_IOCTL_EOE_HANDLER:
  3548         case EC_IOCTL_EOE_HANDLER:
  3547             return ec_cdev_ioctl_eoe_handler(master, arg);
  3549             ret = ec_cdev_ioctl_eoe_handler(master, arg);
       
  3550             break;
  3548 #endif
  3551 #endif
  3549         case EC_IOCTL_REQUEST:
  3552         case EC_IOCTL_REQUEST:
  3550             if (!(filp->f_mode & FMODE_WRITE))
  3553             if (!(filp->f_mode & FMODE_WRITE)) {
  3551                 return -EPERM;
  3554                 ret = -EPERM;
  3552             return ec_cdev_ioctl_request(master, arg, priv);
  3555                 break;
       
  3556             }
       
  3557             ret = ec_cdev_ioctl_request(master, arg, priv);
       
  3558             break;
  3553         case EC_IOCTL_CREATE_DOMAIN:
  3559         case EC_IOCTL_CREATE_DOMAIN:
  3554             if (!(filp->f_mode & FMODE_WRITE))
  3560             if (!(filp->f_mode & FMODE_WRITE)) {
  3555                 return -EPERM;
  3561                 ret = -EPERM;
  3556             return ec_cdev_ioctl_create_domain(master, arg, priv);
  3562                 break;
       
  3563             }
       
  3564             ret = ec_cdev_ioctl_create_domain(master, arg, priv);
       
  3565             break;
  3557         case EC_IOCTL_CREATE_SLAVE_CONFIG:
  3566         case EC_IOCTL_CREATE_SLAVE_CONFIG:
  3558             if (!(filp->f_mode & FMODE_WRITE))
  3567             if (!(filp->f_mode & FMODE_WRITE)) {
  3559                 return -EPERM;
  3568                 ret = -EPERM;
  3560             return ec_cdev_ioctl_create_slave_config(master, arg, priv);
  3569                 break;
       
  3570             }
       
  3571             ret = ec_cdev_ioctl_create_slave_config(master, arg, priv);
       
  3572             break;
  3561         case EC_IOCTL_ACTIVATE:
  3573         case EC_IOCTL_ACTIVATE:
  3562             if (!(filp->f_mode & FMODE_WRITE))
  3574             if (!(filp->f_mode & FMODE_WRITE)) {
  3563                 return -EPERM;
  3575                 ret = -EPERM;
  3564             return ec_cdev_ioctl_activate(master, arg, priv);
  3576                 break;
       
  3577             }
       
  3578             ret = ec_cdev_ioctl_activate(master, arg, priv);
       
  3579             break;
  3565         case EC_IOCTL_DEACTIVATE:
  3580         case EC_IOCTL_DEACTIVATE:
  3566             if (!(filp->f_mode & FMODE_WRITE))
  3581             if (!(filp->f_mode & FMODE_WRITE)) {
  3567                 return -EPERM;
  3582                 ret = -EPERM;
  3568             return ec_cdev_ioctl_deactivate(master, arg, priv);
  3583                 break;
       
  3584             }
       
  3585             ret = ec_cdev_ioctl_deactivate(master, arg, priv);
       
  3586             break;
  3569         case EC_IOCTL_SEND:
  3587         case EC_IOCTL_SEND:
  3570             if (!(filp->f_mode & FMODE_WRITE))
  3588             if (!(filp->f_mode & FMODE_WRITE)) {
  3571                 return -EPERM;
  3589                 ret = -EPERM;
  3572             return ec_cdev_ioctl_send(master, arg, priv);
  3590                 break;
       
  3591             }
       
  3592             ret = ec_cdev_ioctl_send(master, arg, priv);
       
  3593             break;
  3573         case EC_IOCTL_RECEIVE:
  3594         case EC_IOCTL_RECEIVE:
  3574             if (!(filp->f_mode & FMODE_WRITE))
  3595             if (!(filp->f_mode & FMODE_WRITE)) {
  3575                 return -EPERM;
  3596                 ret = -EPERM;
  3576             return ec_cdev_ioctl_receive(master, arg, priv);
  3597                 break;
       
  3598             }
       
  3599             ret = ec_cdev_ioctl_receive(master, arg, priv);
       
  3600             break;
  3577         case EC_IOCTL_MASTER_STATE:
  3601         case EC_IOCTL_MASTER_STATE:
  3578             return ec_cdev_ioctl_master_state(master, arg, priv);
  3602             ret = ec_cdev_ioctl_master_state(master, arg, priv);
       
  3603             break;
  3579         case EC_IOCTL_APP_TIME:
  3604         case EC_IOCTL_APP_TIME:
  3580             if (!(filp->f_mode & FMODE_WRITE))
  3605             if (!(filp->f_mode & FMODE_WRITE)) {
  3581                 return -EPERM;
  3606                 ret = -EPERM;
  3582             return ec_cdev_ioctl_app_time(master, arg, priv);
  3607                 break;
       
  3608             }
       
  3609             ret = ec_cdev_ioctl_app_time(master, arg, priv);
       
  3610             break;
  3583         case EC_IOCTL_SYNC_REF:
  3611         case EC_IOCTL_SYNC_REF:
  3584             if (!(filp->f_mode & FMODE_WRITE))
  3612             if (!(filp->f_mode & FMODE_WRITE)) {
  3585                 return -EPERM;
  3613                 ret = -EPERM;
  3586             return ec_cdev_ioctl_sync_ref(master, arg, priv);
  3614                 break;
       
  3615             }
       
  3616             ret = ec_cdev_ioctl_sync_ref(master, arg, priv);
       
  3617             break;
  3587         case EC_IOCTL_SYNC_SLAVES:
  3618         case EC_IOCTL_SYNC_SLAVES:
  3588             if (!(filp->f_mode & FMODE_WRITE))
  3619             if (!(filp->f_mode & FMODE_WRITE)) {
  3589                 return -EPERM;
  3620                 ret = -EPERM;
  3590             return ec_cdev_ioctl_sync_slaves(master, arg, priv);
  3621                 break;
       
  3622             }
       
  3623             ret = ec_cdev_ioctl_sync_slaves(master, arg, priv);
       
  3624             break;
  3591         case EC_IOCTL_SYNC_MON_QUEUE:
  3625         case EC_IOCTL_SYNC_MON_QUEUE:
  3592             if (!(filp->f_mode & FMODE_WRITE))
  3626             if (!(filp->f_mode & FMODE_WRITE)) {
  3593                 return -EPERM;
  3627                 ret = -EPERM;
  3594             return ec_cdev_ioctl_sync_mon_queue(master, arg, priv);
  3628                 break;
       
  3629             }
       
  3630             ret = ec_cdev_ioctl_sync_mon_queue(master, arg, priv);
       
  3631             break;
  3595         case EC_IOCTL_SYNC_MON_PROCESS:
  3632         case EC_IOCTL_SYNC_MON_PROCESS:
  3596             if (!(filp->f_mode & FMODE_WRITE))
  3633             if (!(filp->f_mode & FMODE_WRITE)) {
  3597                 return -EPERM;
  3634                 ret = -EPERM;
  3598             return ec_cdev_ioctl_sync_mon_process(master, arg, priv);
  3635                 break;
       
  3636             }
       
  3637             ret = ec_cdev_ioctl_sync_mon_process(master, arg, priv);
       
  3638             break;
  3599         case EC_IOCTL_RESET:
  3639         case EC_IOCTL_RESET:
  3600             if (!(filp->f_mode & FMODE_WRITE))
  3640             if (!(filp->f_mode & FMODE_WRITE)) {
  3601                 return -EPERM;
  3641                 ret = -EPERM;
  3602             return ec_cdev_ioctl_reset(master, arg, priv);
  3642                 break;
       
  3643             }
       
  3644             ret = ec_cdev_ioctl_reset(master, arg, priv);
       
  3645             break;
  3603         case EC_IOCTL_SC_SYNC:
  3646         case EC_IOCTL_SC_SYNC:
  3604             if (!(filp->f_mode & FMODE_WRITE))
  3647             if (!(filp->f_mode & FMODE_WRITE)) {
  3605                 return -EPERM;
  3648                 ret = -EPERM;
  3606             return ec_cdev_ioctl_sc_sync(master, arg, priv);
  3649                 break;
       
  3650             }
       
  3651             ret = ec_cdev_ioctl_sc_sync(master, arg, priv);
       
  3652             break;
  3607         case EC_IOCTL_SC_WATCHDOG:
  3653         case EC_IOCTL_SC_WATCHDOG:
  3608             if (!(filp->f_mode & FMODE_WRITE))
  3654             if (!(filp->f_mode & FMODE_WRITE)) {
  3609                 return -EPERM;
  3655                 ret = -EPERM;
  3610             return ec_cdev_ioctl_sc_watchdog(master, arg, priv);
  3656                 break;
       
  3657             }
       
  3658             ret = ec_cdev_ioctl_sc_watchdog(master, arg, priv);
       
  3659             break;
  3611         case EC_IOCTL_SC_ADD_PDO:
  3660         case EC_IOCTL_SC_ADD_PDO:
  3612             if (!(filp->f_mode & FMODE_WRITE))
  3661             if (!(filp->f_mode & FMODE_WRITE)) {
  3613                 return -EPERM;
  3662                 ret = -EPERM;
  3614             return ec_cdev_ioctl_sc_add_pdo(master, arg, priv);
  3663                 break;
       
  3664             }
       
  3665             ret = ec_cdev_ioctl_sc_add_pdo(master, arg, priv);
       
  3666             break;
  3615         case EC_IOCTL_SC_CLEAR_PDOS:
  3667         case EC_IOCTL_SC_CLEAR_PDOS:
  3616             if (!(filp->f_mode & FMODE_WRITE))
  3668             if (!(filp->f_mode & FMODE_WRITE)) {
  3617                 return -EPERM;
  3669                 ret = -EPERM;
  3618             return ec_cdev_ioctl_sc_clear_pdos(master, arg, priv);
  3670                 break;
       
  3671             }
       
  3672             ret = ec_cdev_ioctl_sc_clear_pdos(master, arg, priv);
       
  3673             break;
  3619         case EC_IOCTL_SC_ADD_ENTRY:
  3674         case EC_IOCTL_SC_ADD_ENTRY:
  3620             if (!(filp->f_mode & FMODE_WRITE))
  3675             if (!(filp->f_mode & FMODE_WRITE)) {
  3621                 return -EPERM;
  3676                 ret = -EPERM;
  3622             return ec_cdev_ioctl_sc_add_entry(master, arg, priv);
  3677                 break;
       
  3678             }
       
  3679             ret = ec_cdev_ioctl_sc_add_entry(master, arg, priv);
       
  3680             break;
  3623         case EC_IOCTL_SC_CLEAR_ENTRIES:
  3681         case EC_IOCTL_SC_CLEAR_ENTRIES:
  3624             if (!(filp->f_mode & FMODE_WRITE))
  3682             if (!(filp->f_mode & FMODE_WRITE)) {
  3625                 return -EPERM;
  3683                 ret = -EPERM;
  3626             return ec_cdev_ioctl_sc_clear_entries(master, arg, priv);
  3684                 break;
       
  3685             }
       
  3686             ret = ec_cdev_ioctl_sc_clear_entries(master, arg, priv);
       
  3687             break;
  3627         case EC_IOCTL_SC_REG_PDO_ENTRY:
  3688         case EC_IOCTL_SC_REG_PDO_ENTRY:
  3628             if (!(filp->f_mode & FMODE_WRITE))
  3689             if (!(filp->f_mode & FMODE_WRITE)) {
  3629                 return -EPERM;
  3690                 ret = -EPERM;
  3630             return ec_cdev_ioctl_sc_reg_pdo_entry(master, arg, priv);
  3691                 break;
       
  3692             }
       
  3693             ret = ec_cdev_ioctl_sc_reg_pdo_entry(master, arg, priv);
       
  3694             break;
  3631         case EC_IOCTL_SC_DC:
  3695         case EC_IOCTL_SC_DC:
  3632             if (!(filp->f_mode & FMODE_WRITE))
  3696             if (!(filp->f_mode & FMODE_WRITE)) {
  3633                 return -EPERM;
  3697                 ret = -EPERM;
  3634             return ec_cdev_ioctl_sc_dc(master, arg, priv);
  3698                 break;
       
  3699             }
       
  3700             ret = ec_cdev_ioctl_sc_dc(master, arg, priv);
       
  3701             break;
  3635         case EC_IOCTL_SC_SDO:
  3702         case EC_IOCTL_SC_SDO:
  3636             if (!(filp->f_mode & FMODE_WRITE))
  3703             if (!(filp->f_mode & FMODE_WRITE)) {
  3637                 return -EPERM;
  3704                 ret = -EPERM;
  3638             return ec_cdev_ioctl_sc_sdo(master, arg, priv);
  3705                 break;
       
  3706             }
       
  3707             ret = ec_cdev_ioctl_sc_sdo(master, arg, priv);
       
  3708             break;
  3639         case EC_IOCTL_SC_SDO_REQUEST:
  3709         case EC_IOCTL_SC_SDO_REQUEST:
  3640             if (!(filp->f_mode & FMODE_WRITE))
  3710             if (!(filp->f_mode & FMODE_WRITE)) {
  3641                 return -EPERM;
  3711                 ret = -EPERM;
  3642             return ec_cdev_ioctl_sc_create_sdo_request(master, arg, priv);
  3712                 break;
       
  3713             }
       
  3714             ret = ec_cdev_ioctl_sc_create_sdo_request(master, arg, priv);
       
  3715             break;
  3643         case EC_IOCTL_SC_VOE:
  3716         case EC_IOCTL_SC_VOE:
  3644             if (!(filp->f_mode & FMODE_WRITE))
  3717             if (!(filp->f_mode & FMODE_WRITE)) {
  3645                 return -EPERM;
  3718                 ret = -EPERM;
  3646             return ec_cdev_ioctl_sc_create_voe_handler(master, arg, priv);
  3719                 break;
       
  3720             }
       
  3721             ret = ec_cdev_ioctl_sc_create_voe_handler(master, arg, priv);
       
  3722             break;
  3647         case EC_IOCTL_SC_STATE:
  3723         case EC_IOCTL_SC_STATE:
  3648             return ec_cdev_ioctl_sc_state(master, arg, priv);
  3724             ret = ec_cdev_ioctl_sc_state(master, arg, priv);
       
  3725             break;
  3649         case EC_IOCTL_SC_IDN:
  3726         case EC_IOCTL_SC_IDN:
  3650             if (!(filp->f_mode & FMODE_WRITE))
  3727             if (!(filp->f_mode & FMODE_WRITE)) {
  3651                 return -EPERM;
  3728                 ret = -EPERM;
  3652             return ec_cdev_ioctl_sc_idn(master, arg, priv);
  3729                 break;
       
  3730             }
       
  3731             ret = ec_cdev_ioctl_sc_idn(master, arg, priv);
       
  3732             break;
  3653         case EC_IOCTL_DOMAIN_OFFSET:
  3733         case EC_IOCTL_DOMAIN_OFFSET:
  3654             return ec_cdev_ioctl_domain_offset(master, arg, priv);
  3734             ret = ec_cdev_ioctl_domain_offset(master, arg, priv);
       
  3735             break;
  3655         case EC_IOCTL_DOMAIN_PROCESS:
  3736         case EC_IOCTL_DOMAIN_PROCESS:
  3656             if (!(filp->f_mode & FMODE_WRITE))
  3737             if (!(filp->f_mode & FMODE_WRITE)) {
  3657                 return -EPERM;
  3738                 ret = -EPERM;
  3658             return ec_cdev_ioctl_domain_process(master, arg, priv);
  3739                 break;
       
  3740             }
       
  3741             ret = ec_cdev_ioctl_domain_process(master, arg, priv);
       
  3742             break;
  3659         case EC_IOCTL_DOMAIN_QUEUE:
  3743         case EC_IOCTL_DOMAIN_QUEUE:
  3660             if (!(filp->f_mode & FMODE_WRITE))
  3744             if (!(filp->f_mode & FMODE_WRITE)) {
  3661                 return -EPERM;
  3745                 ret = -EPERM;
  3662             return ec_cdev_ioctl_domain_queue(master, arg, priv);
  3746                 break;
       
  3747             }
       
  3748             ret = ec_cdev_ioctl_domain_queue(master, arg, priv);
       
  3749             break;
  3663         case EC_IOCTL_DOMAIN_STATE:
  3750         case EC_IOCTL_DOMAIN_STATE:
  3664             return ec_cdev_ioctl_domain_state(master, arg, priv);
  3751             ret = ec_cdev_ioctl_domain_state(master, arg, priv);
       
  3752             break;
  3665         case EC_IOCTL_SDO_REQUEST_TIMEOUT:
  3753         case EC_IOCTL_SDO_REQUEST_TIMEOUT:
  3666             if (!(filp->f_mode & FMODE_WRITE))
  3754             if (!(filp->f_mode & FMODE_WRITE)) {
  3667                 return -EPERM;
  3755                 ret = -EPERM;
  3668             return ec_cdev_ioctl_sdo_request_timeout(master, arg, priv);
  3756                 break;
       
  3757             }
       
  3758             ret = ec_cdev_ioctl_sdo_request_timeout(master, arg, priv);
       
  3759             break;
  3669         case EC_IOCTL_SDO_REQUEST_STATE:
  3760         case EC_IOCTL_SDO_REQUEST_STATE:
  3670             return ec_cdev_ioctl_sdo_request_state(master, arg, priv);
  3761             ret = ec_cdev_ioctl_sdo_request_state(master, arg, priv);
       
  3762             break;
  3671         case EC_IOCTL_SDO_REQUEST_READ:
  3763         case EC_IOCTL_SDO_REQUEST_READ:
  3672             if (!(filp->f_mode & FMODE_WRITE))
  3764             if (!(filp->f_mode & FMODE_WRITE)) {
  3673                 return -EPERM;
  3765                 ret = -EPERM;
  3674             return ec_cdev_ioctl_sdo_request_read(master, arg, priv);
  3766                 break;
       
  3767             }
       
  3768             ret = ec_cdev_ioctl_sdo_request_read(master, arg, priv);
       
  3769             break;
  3675         case EC_IOCTL_SDO_REQUEST_WRITE:
  3770         case EC_IOCTL_SDO_REQUEST_WRITE:
  3676             if (!(filp->f_mode & FMODE_WRITE))
  3771             if (!(filp->f_mode & FMODE_WRITE)) {
  3677                 return -EPERM;
  3772                 ret = -EPERM;
  3678             return ec_cdev_ioctl_sdo_request_write(master, arg, priv);
  3773                 break;
       
  3774             }
       
  3775             ret = ec_cdev_ioctl_sdo_request_write(master, arg, priv);
       
  3776             break;
  3679         case EC_IOCTL_SDO_REQUEST_DATA:
  3777         case EC_IOCTL_SDO_REQUEST_DATA:
  3680             return ec_cdev_ioctl_sdo_request_data(master, arg, priv);
  3778             ret = ec_cdev_ioctl_sdo_request_data(master, arg, priv);
       
  3779             break;
  3681         case EC_IOCTL_VOE_SEND_HEADER:
  3780         case EC_IOCTL_VOE_SEND_HEADER:
  3682             if (!(filp->f_mode & FMODE_WRITE))
  3781             if (!(filp->f_mode & FMODE_WRITE)) {
  3683                 return -EPERM;
  3782                 ret = -EPERM;
  3684             return ec_cdev_ioctl_voe_send_header(master, arg, priv);
  3783                 break;
       
  3784             }
       
  3785             ret = ec_cdev_ioctl_voe_send_header(master, arg, priv);
       
  3786             break;
  3685         case EC_IOCTL_VOE_REC_HEADER:
  3787         case EC_IOCTL_VOE_REC_HEADER:
  3686             return ec_cdev_ioctl_voe_rec_header(master, arg, priv);
  3788             ret = ec_cdev_ioctl_voe_rec_header(master, arg, priv);
       
  3789             break;
  3687         case EC_IOCTL_VOE_READ:
  3790         case EC_IOCTL_VOE_READ:
  3688             if (!(filp->f_mode & FMODE_WRITE))
  3791             if (!(filp->f_mode & FMODE_WRITE)) {
  3689                 return -EPERM;
  3792                 ret = -EPERM;
  3690             return ec_cdev_ioctl_voe_read(master, arg, priv);
  3793                 break;
       
  3794             }
       
  3795             ret = ec_cdev_ioctl_voe_read(master, arg, priv);
       
  3796             break;
  3691         case EC_IOCTL_VOE_READ_NOSYNC:
  3797         case EC_IOCTL_VOE_READ_NOSYNC:
  3692             if (!(filp->f_mode & FMODE_WRITE))
  3798             if (!(filp->f_mode & FMODE_WRITE)) {
  3693                 return -EPERM;
  3799                 ret = -EPERM;
  3694             return ec_cdev_ioctl_voe_read_nosync(master, arg, priv);
  3800                 break;
       
  3801             }
       
  3802             ret = ec_cdev_ioctl_voe_read_nosync(master, arg, priv);
       
  3803             break;
  3695         case EC_IOCTL_VOE_WRITE:
  3804         case EC_IOCTL_VOE_WRITE:
  3696             if (!(filp->f_mode & FMODE_WRITE))
  3805             if (!(filp->f_mode & FMODE_WRITE)) {
  3697                 return -EPERM;
  3806                 ret = -EPERM;
  3698             return ec_cdev_ioctl_voe_write(master, arg, priv);
  3807                 break;
       
  3808             }
       
  3809             ret = ec_cdev_ioctl_voe_write(master, arg, priv);
       
  3810             break;
  3699         case EC_IOCTL_VOE_EXEC:
  3811         case EC_IOCTL_VOE_EXEC:
  3700             if (!(filp->f_mode & FMODE_WRITE))
  3812             if (!(filp->f_mode & FMODE_WRITE)) {
  3701                 return -EPERM;
  3813                 ret = -EPERM;
  3702             return ec_cdev_ioctl_voe_exec(master, arg, priv);
  3814                 break;
       
  3815             }
       
  3816             ret = ec_cdev_ioctl_voe_exec(master, arg, priv);
       
  3817             break;
  3703         case EC_IOCTL_VOE_DATA:
  3818         case EC_IOCTL_VOE_DATA:
  3704             return ec_cdev_ioctl_voe_data(master, arg, priv);
  3819             ret = ec_cdev_ioctl_voe_data(master, arg, priv);
       
  3820             break;
  3705         case EC_IOCTL_SET_SEND_INTERVAL:
  3821         case EC_IOCTL_SET_SEND_INTERVAL:
  3706             if (!(filp->f_mode & FMODE_WRITE))
  3822             if (!(filp->f_mode & FMODE_WRITE)) {
  3707                 return -EPERM;
  3823                 ret = -EPERM;
  3708             return ec_cdev_ioctl_set_send_interval(master, arg, priv);
  3824                 break;
       
  3825             }
       
  3826             ret = ec_cdev_ioctl_set_send_interval(master, arg, priv);
       
  3827             break;
  3709         default:
  3828         default:
  3710             return -ENOTTY;
  3829             ret = -ENOTTY;
  3711     }
  3830             break;
       
  3831     }
       
  3832 
       
  3833 #if DEBUG_LATENCY
       
  3834     b = get_cycles();
       
  3835     t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
       
  3836     if (t > 50) {
       
  3837         EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
       
  3838                 _IOC_NR(cmd), t);
       
  3839     }
       
  3840 #endif
       
  3841 
       
  3842     return ret;
  3712 }
  3843 }
  3713 
  3844 
  3714 /*****************************************************************************/
  3845 /*****************************************************************************/
  3715 
  3846 
  3716 /** Memory-map callback for the EtherCAT character device.
  3847 /** Memory-map callback for the EtherCAT character device.