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