master/cdev.c
changeset 1335 09c6fce1ae45
parent 1328 00c0e0ecd2c4
child 1336 e27b37e80a99
equal deleted inserted replaced
1334:da3d22a27500 1335:09c6fce1ae45
  2388     if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
  2388     if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
  2389                 ecrt_voe_handler_data_size(voe)))
  2389                 ecrt_voe_handler_data_size(voe)))
  2390         return -EFAULT;
  2390         return -EFAULT;
  2391 
  2391 
  2392     return 0;
  2392     return 0;
       
  2393 }
       
  2394 
       
  2395 /*****************************************************************************/
       
  2396 
       
  2397 /** Read a file from a slave via FoE.
       
  2398  */
       
  2399 int ec_cdev_ioctl_slave_foe_read(
       
  2400         ec_master_t *master, /**< EtherCAT master. */
       
  2401         unsigned long arg /**< ioctl() argument. */
       
  2402         )
       
  2403 {
       
  2404     ec_ioctl_slave_foe_t data;
       
  2405     ec_master_foe_request_t request;
       
  2406     int retval;
       
  2407 
       
  2408     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
       
  2409         return -EFAULT;
       
  2410     }
       
  2411 
       
  2412     ec_foe_request_init(&request.req, data.file_name);
       
  2413     ec_foe_request_read(&request.req);
       
  2414     ec_foe_request_alloc(&request.req, 10000); // FIXME
       
  2415 
       
  2416     if (down_interruptible(&master->master_sem))
       
  2417         return -EINTR;
       
  2418 
       
  2419     if (!(request.slave = ec_master_find_slave(
       
  2420                     master, 0, data.slave_position))) {
       
  2421         up(&master->master_sem);
       
  2422         ec_foe_request_clear(&request.req);
       
  2423         EC_ERR("Slave %u does not exist!\n", data.slave_position);
       
  2424         return -EINVAL;
       
  2425     }
       
  2426 
       
  2427     // schedule request.
       
  2428     list_add_tail(&request.list, &master->foe_requests);
       
  2429 
       
  2430     up(&master->master_sem);
       
  2431 
       
  2432     // wait for processing through FSM
       
  2433     if (wait_event_interruptible(master->foe_queue,
       
  2434                 request.req.state != EC_INT_REQUEST_QUEUED)) {
       
  2435         // interrupted by signal
       
  2436         down(&master->master_sem);
       
  2437         if (request.req.state == EC_INT_REQUEST_QUEUED) {
       
  2438             list_del(&request.list);
       
  2439             up(&master->master_sem);
       
  2440             ec_foe_request_clear(&request.req);
       
  2441             return -EINTR;
       
  2442         }
       
  2443         // request already processing: interrupt not possible.
       
  2444         up(&master->master_sem);
       
  2445     }
       
  2446 
       
  2447     // wait until master FSM has finished processing
       
  2448     wait_event(master->foe_queue, request.req.state != EC_REQUEST_BUSY);
       
  2449 
       
  2450     data.abort_code = request.req.abort_code;
       
  2451 
       
  2452 	if (master->debug_level) {
       
  2453 		EC_DBG("%d bytes read via FoE (abort_code = 0x%x).\n",
       
  2454 				request.req.data_size, request.req.abort_code);
       
  2455 	}
       
  2456 
       
  2457     if (request.req.state != EC_REQUEST_SUCCESS) {
       
  2458         data.data_size = 0;
       
  2459         retval = -EIO;
       
  2460     } else {
       
  2461         if (request.req.data_size > data.buffer_size) {
       
  2462             EC_ERR("Buffer too small.\n");
       
  2463             ec_foe_request_clear(&request.req);
       
  2464             return -EOVERFLOW;
       
  2465         }
       
  2466         data.data_size = request.req.data_size;
       
  2467         if (copy_to_user((void __user *) data.buffer,
       
  2468                     request.req.buffer, data.data_size)) {
       
  2469             ec_foe_request_clear(&request.req);
       
  2470             return -EFAULT;
       
  2471         }
       
  2472         retval = 0;
       
  2473     }
       
  2474 
       
  2475     if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
       
  2476         retval = -EFAULT;
       
  2477     }
       
  2478 
       
  2479     ec_foe_request_clear(&request.req);
       
  2480     return retval;
       
  2481 }
       
  2482 
       
  2483 /*****************************************************************************/
       
  2484 
       
  2485 /** Write a file to a slave via FoE
       
  2486  */
       
  2487 int ec_cdev_ioctl_slave_foe_write(
       
  2488         ec_master_t *master, /**< EtherCAT master. */
       
  2489         unsigned long arg /**< ioctl() argument. */
       
  2490         )
       
  2491 {
       
  2492     ec_ioctl_slave_foe_t data;
       
  2493     ec_master_foe_request_t request;
       
  2494     int retval;
       
  2495 
       
  2496     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
       
  2497         return -EFAULT;
       
  2498     }
       
  2499 
       
  2500     INIT_LIST_HEAD(&request.list);
       
  2501 
       
  2502     ec_foe_request_init(&request.req, data.file_name);
       
  2503 
       
  2504     if (ec_foe_request_alloc(&request.req, data.buffer_size)) {
       
  2505         ec_foe_request_clear(&request.req);
       
  2506         return -ENOMEM;
       
  2507     }
       
  2508     if (copy_from_user(request.req.buffer,
       
  2509                 (void __user *) data.buffer, data.buffer_size)) {
       
  2510         ec_foe_request_clear(&request.req);
       
  2511         return -EFAULT;
       
  2512     }
       
  2513     request.req.data_size = data.buffer_size;
       
  2514     ec_foe_request_write(&request.req);
       
  2515 
       
  2516     if (down_interruptible(&master->master_sem))
       
  2517         return -EINTR;
       
  2518 
       
  2519     if (!(request.slave = ec_master_find_slave(
       
  2520                     master, 0, data.slave_position))) {
       
  2521         up(&master->master_sem);
       
  2522         EC_ERR("Slave %u does not exist!\n", data.slave_position);
       
  2523         ec_foe_request_clear(&request.req);
       
  2524         return -EINVAL;
       
  2525     }
       
  2526 
       
  2527 	if (master->debug_level) {
       
  2528 		EC_DBG("Scheduling FoE write request.\n");
       
  2529 	}
       
  2530 
       
  2531     // schedule FoE write request.
       
  2532     list_add_tail(&request.list, &master->foe_requests);
       
  2533 
       
  2534     up(&master->master_sem);
       
  2535 
       
  2536     // wait for processing through FSM
       
  2537     if (wait_event_interruptible(master->foe_queue,
       
  2538                 request.req.state != EC_INT_REQUEST_QUEUED)) {
       
  2539         // interrupted by signal
       
  2540         down(&master->master_sem);
       
  2541         if (request.req.state == EC_INT_REQUEST_QUEUED) {
       
  2542             // abort request
       
  2543             list_del(&request.list);
       
  2544             up(&master->master_sem);
       
  2545             ec_foe_request_clear(&request.req);
       
  2546             return -EINTR;
       
  2547         }
       
  2548         up(&master->master_sem);
       
  2549     }
       
  2550 
       
  2551     // wait until master FSM has finished processing
       
  2552     wait_event(master->foe_queue, request.req.state != EC_REQUEST_BUSY);
       
  2553 
       
  2554     data.abort_code = request.req.abort_code;
       
  2555 
       
  2556     retval = request.req.state == EC_REQUEST_SUCCESS ? 0 : -EIO;
       
  2557 
       
  2558     if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
       
  2559         retval = -EFAULT;
       
  2560     }
       
  2561 
       
  2562     ec_foe_request_clear(&request.req);
       
  2563 
       
  2564 	if (master->debug_level) {
       
  2565 		printk ("Finished FoE writing.\n");
       
  2566 	}
       
  2567 
       
  2568     return retval;
  2393 }
  2569 }
  2394 
  2570 
  2395 /******************************************************************************
  2571 /******************************************************************************
  2396  * File operations
  2572  * File operations
  2397  *****************************************************************************/
  2573  *****************************************************************************/
  2500             return ec_cdev_ioctl_slave_phy_read(master, arg);
  2676             return ec_cdev_ioctl_slave_phy_read(master, arg);
  2501         case EC_IOCTL_SLAVE_PHY_WRITE:
  2677         case EC_IOCTL_SLAVE_PHY_WRITE:
  2502             if (!(filp->f_mode & FMODE_WRITE))
  2678             if (!(filp->f_mode & FMODE_WRITE))
  2503                 return -EPERM;
  2679                 return -EPERM;
  2504             return ec_cdev_ioctl_slave_phy_write(master, arg);
  2680             return ec_cdev_ioctl_slave_phy_write(master, arg);
       
  2681         case EC_IOCTL_SLAVE_FOE_READ:
       
  2682             return ec_cdev_ioctl_slave_foe_read(master, arg);
       
  2683         case EC_IOCTL_SLAVE_FOE_WRITE:
       
  2684             if (!(filp->f_mode & FMODE_WRITE))
       
  2685                 return -EPERM;
       
  2686             return ec_cdev_ioctl_slave_foe_write(master, arg);
  2505         case EC_IOCTL_CONFIG:
  2687         case EC_IOCTL_CONFIG:
  2506             return ec_cdev_ioctl_config(master, arg);
  2688             return ec_cdev_ioctl_config(master, arg);
  2507         case EC_IOCTL_CONFIG_PDO:
  2689         case EC_IOCTL_CONFIG_PDO:
  2508             return ec_cdev_ioctl_config_pdo(master, arg);
  2690             return ec_cdev_ioctl_config_pdo(master, arg);
  2509         case EC_IOCTL_CONFIG_PDO_ENTRY:
  2691         case EC_IOCTL_CONFIG_PDO_ENTRY: