master/cdev.c
branchstable-1.5
changeset 2109 755e6ce823f0
parent 2061 7982704c8599
child 2124 c4afc5fede19
equal deleted inserted replaced
2108:6d3620f2328f 2109:755e6ce823f0
   836         ec_master_t *master, /**< EtherCAT master. */
   836         ec_master_t *master, /**< EtherCAT master. */
   837         unsigned long arg /**< ioctl() argument. */
   837         unsigned long arg /**< ioctl() argument. */
   838         )
   838         )
   839 {
   839 {
   840     ec_ioctl_slave_sdo_upload_t data;
   840     ec_ioctl_slave_sdo_upload_t data;
   841     ec_master_sdo_request_t request;
   841     uint8_t *target;
   842     int retval;
   842     int ret;
   843 
   843 
   844     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
   844     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
   845         return -EFAULT;
   845         return -EFAULT;
   846     }
   846     }
   847 
   847 
   848     ec_sdo_request_init(&request.req);
   848     if (!(target = kmalloc(data.target_size, GFP_KERNEL))) {
   849     ec_sdo_request_address(&request.req,
   849         EC_MASTER_ERR(master, "Failed to allocate %u bytes"
   850             data.sdo_index, data.sdo_entry_subindex);
   850                 " for SDO upload.\n", data.target_size);
   851     ecrt_sdo_request_read(&request.req);
   851         return -ENOMEM;
   852 
   852     }
   853     if (down_interruptible(&master->master_sem))
   853 
   854         return -EINTR;
   854     ret = ecrt_master_sdo_upload(master, data.slave_position,
   855 
   855             data.sdo_index, data.sdo_entry_subindex, target,
   856     if (!(request.slave = ec_master_find_slave(
   856             data.target_size, &data.data_size, &data.abort_code);
   857                     master, 0, data.slave_position))) {
   857 
   858         up(&master->master_sem);
   858     if (!ret) {
   859         ec_sdo_request_clear(&request.req);
       
   860         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
       
   861                 data.slave_position);
       
   862         return -EINVAL;
       
   863     }
       
   864 
       
   865     EC_SLAVE_DBG(request.slave, 1, "Schedule SDO upload request.\n");
       
   866 
       
   867     // schedule request.
       
   868     list_add_tail(&request.list, &request.slave->slave_sdo_requests);
       
   869 
       
   870     up(&master->master_sem);
       
   871 
       
   872     // wait for processing through FSM
       
   873     if (wait_event_interruptible(request.slave->sdo_queue,
       
   874                 request.req.state != EC_INT_REQUEST_QUEUED)) {
       
   875         // interrupted by signal
       
   876         down(&master->master_sem);
       
   877         if (request.req.state == EC_INT_REQUEST_QUEUED) {
       
   878             list_del(&request.list);
       
   879             up(&master->master_sem);
       
   880             ec_sdo_request_clear(&request.req);
       
   881             return -EINTR;
       
   882         }
       
   883         // request already processing: interrupt not possible.
       
   884         up(&master->master_sem);
       
   885     }
       
   886 
       
   887     // wait until master FSM has finished processing
       
   888     wait_event(request.slave->sdo_queue,
       
   889             request.req.state != EC_INT_REQUEST_BUSY);
       
   890 
       
   891     EC_SLAVE_DBG(request.slave, 1, "Finished SDO upload request.\n");
       
   892 
       
   893     data.abort_code = request.req.abort_code;
       
   894 
       
   895     if (request.req.state != EC_INT_REQUEST_SUCCESS) {
       
   896         data.data_size = 0;
       
   897         if (request.req.errno) {
       
   898             retval = -request.req.errno;
       
   899         } else {
       
   900             retval = -EIO;
       
   901         }
       
   902     } else {
       
   903         if (request.req.data_size > data.target_size) {
       
   904             EC_MASTER_ERR(master, "Buffer too small.\n");
       
   905             ec_sdo_request_clear(&request.req);
       
   906             return -EOVERFLOW;
       
   907         }
       
   908         data.data_size = request.req.data_size;
       
   909 
       
   910         if (copy_to_user((void __user *) data.target,
   859         if (copy_to_user((void __user *) data.target,
   911                     request.req.data, data.data_size)) {
   860                     target, data.data_size)) {
   912             ec_sdo_request_clear(&request.req);
   861             kfree(target);
   913             return -EFAULT;
   862             return -EFAULT;
   914         }
   863         }
   915         retval = 0;
   864     }
   916     }
   865 
       
   866     kfree(target);
       
   867 
       
   868     if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
       
   869         return -EFAULT;
       
   870     }
       
   871 
       
   872     return 0;
       
   873 }
       
   874 
       
   875 /*****************************************************************************/
       
   876 
       
   877 /** Download SDO.
       
   878  */
       
   879 int ec_cdev_ioctl_slave_sdo_download(
       
   880         ec_master_t *master, /**< EtherCAT master. */
       
   881         unsigned long arg /**< ioctl() argument. */
       
   882         )
       
   883 {
       
   884     ec_ioctl_slave_sdo_download_t data;
       
   885     uint8_t *sdo_data;
       
   886     int retval;
       
   887 
       
   888     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
       
   889         return -EFAULT;
       
   890     }
       
   891 
       
   892     if (!(sdo_data = kmalloc(data.data_size, GFP_KERNEL))) {
       
   893         EC_MASTER_ERR(master, "Failed to allocate %u bytes"
       
   894                 " for SDO download.\n", data.data_size);
       
   895         return -ENOMEM;
       
   896     }
       
   897 
       
   898     if (copy_from_user(sdo_data, (void __user *) data.data, data.data_size)) {
       
   899         kfree(sdo_data);
       
   900         return -EFAULT;
       
   901     }
       
   902 
       
   903     retval = ecrt_master_sdo_download(master, data.slave_position,
       
   904             data.sdo_index, data.sdo_entry_subindex, sdo_data, data.data_size,
       
   905             &data.abort_code);
       
   906 
       
   907     kfree(sdo_data);
   917 
   908 
   918     if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
   909     if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
   919         retval = -EFAULT;
   910         retval = -EFAULT;
   920     }
   911     }
   921 
   912 
   922     ec_sdo_request_clear(&request.req);
       
   923     return retval;
       
   924 }
       
   925 
       
   926 /*****************************************************************************/
       
   927 
       
   928 /** Download SDO.
       
   929  */
       
   930 int ec_cdev_ioctl_slave_sdo_download(
       
   931         ec_master_t *master, /**< EtherCAT master. */
       
   932         unsigned long arg /**< ioctl() argument. */
       
   933         )
       
   934 {
       
   935     ec_ioctl_slave_sdo_download_t data;
       
   936     ec_master_sdo_request_t request;
       
   937     int retval;
       
   938 
       
   939     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
       
   940         return -EFAULT;
       
   941     }
       
   942 
       
   943     // copy data to download
       
   944     if (!data.data_size) {
       
   945         EC_MASTER_ERR(master, "Zero data size!\n");
       
   946         return -EINVAL;
       
   947     }
       
   948 
       
   949     ec_sdo_request_init(&request.req);
       
   950     ec_sdo_request_address(&request.req,
       
   951             data.sdo_index, data.sdo_entry_subindex);
       
   952     if (ec_sdo_request_alloc(&request.req, data.data_size)) {
       
   953         ec_sdo_request_clear(&request.req);
       
   954         return -ENOMEM;
       
   955     }
       
   956     if (copy_from_user(request.req.data,
       
   957                 (void __user *) data.data, data.data_size)) {
       
   958         ec_sdo_request_clear(&request.req);
       
   959         return -EFAULT;
       
   960     }
       
   961     request.req.data_size = data.data_size;
       
   962     ecrt_sdo_request_write(&request.req);
       
   963 
       
   964     if (down_interruptible(&master->master_sem))
       
   965         return -EINTR;
       
   966 
       
   967     if (!(request.slave = ec_master_find_slave(
       
   968                     master, 0, data.slave_position))) {
       
   969         up(&master->master_sem);
       
   970         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
       
   971                 data.slave_position);
       
   972         ec_sdo_request_clear(&request.req);
       
   973         return -EINVAL;
       
   974     }
       
   975     
       
   976     EC_SLAVE_DBG(request.slave, 1, "Schedule SDO download request.\n");
       
   977 
       
   978     // schedule request.
       
   979     list_add_tail(&request.list, &request.slave->slave_sdo_requests);
       
   980 
       
   981     up(&master->master_sem);
       
   982 
       
   983     // wait for processing through FSM
       
   984     if (wait_event_interruptible(request.slave->sdo_queue,
       
   985                 request.req.state != EC_INT_REQUEST_QUEUED)) {
       
   986         // interrupted by signal
       
   987         down(&master->master_sem);
       
   988         if (request.req.state == EC_INT_REQUEST_QUEUED) {
       
   989             list_del(&request.list);
       
   990             up(&master->master_sem);
       
   991             ec_sdo_request_clear(&request.req);
       
   992             return -EINTR;
       
   993         }
       
   994         // request already processing: interrupt not possible.
       
   995         up(&master->master_sem);
       
   996     }
       
   997 
       
   998     // wait until master FSM has finished processing
       
   999     wait_event(request.slave->sdo_queue,
       
  1000             request.req.state != EC_INT_REQUEST_BUSY);
       
  1001 
       
  1002     EC_SLAVE_DBG(request.slave, 1, "Finished SDO download request.\n");
       
  1003 
       
  1004     data.abort_code = request.req.abort_code;
       
  1005 
       
  1006     if (request.req.state == EC_INT_REQUEST_SUCCESS) {
       
  1007         retval = 0;
       
  1008     } else if (request.req.errno) {
       
  1009         retval = -request.req.errno;
       
  1010     } else {
       
  1011         retval = -EIO;
       
  1012     }
       
  1013 
       
  1014     if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
       
  1015         retval = -EFAULT;
       
  1016     }
       
  1017 
       
  1018     ec_sdo_request_clear(&request.req);
       
  1019     return retval;
   913     return retval;
  1020 }
   914 }
  1021 
   915 
  1022 /*****************************************************************************/
   916 /*****************************************************************************/
  1023 
   917