master/cdev.c
changeset 974 5868944a6456
parent 972 ad59641a68c8
child 978 2962baf7e6d1
equal deleted inserted replaced
973:a560a124a92e 974:5868944a6456
   682 
   682 
   683                 ec_sdo_request_clear(&request.req);
   683                 ec_sdo_request_clear(&request.req);
   684                 break;
   684                 break;
   685             }
   685             }
   686 
   686 
       
   687         case EC_IOCTL_SDO_DOWNLOAD:
       
   688             {
       
   689                 ec_ioctl_sdo_download_t data;
       
   690                 ec_master_sdo_request_t request;
       
   691 
       
   692                 if (!(filp->f_mode & FMODE_WRITE))
       
   693                     return -EPERM;
       
   694 
       
   695                 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
       
   696                     retval = -EFAULT;
       
   697                     break;
       
   698                 }
       
   699                 
       
   700                 if (!(request.slave = ec_master_find_slave(
       
   701                                 master, 0, data.slave_position))) {
       
   702                     EC_ERR("Slave %u does not exist!\n", data.slave_position);
       
   703                     retval = -EINVAL;
       
   704                     break;
       
   705                 }
       
   706 
       
   707                 // copy data to download
       
   708                 if (!data.data_size) {
       
   709                     EC_ERR("Zero data size!\n");
       
   710                     retval = -EINVAL;
       
   711                     break;
       
   712                 }
       
   713 
       
   714                 ec_sdo_request_init(&request.req);
       
   715                 ec_sdo_request_address(&request.req,
       
   716                         data.sdo_index, data.sdo_entry_subindex);
       
   717                 if (ec_sdo_request_alloc(&request.req, data.data_size)) {
       
   718                     ec_sdo_request_clear(&request.req);
       
   719                     retval = -ENOMEM;
       
   720                     break;
       
   721                 }
       
   722                 if (copy_from_user(request.req.data,
       
   723                             (void __user *) data.data, data.data_size)) {
       
   724                     ec_sdo_request_clear(&request.req);
       
   725                     retval = -EFAULT;
       
   726                     break;
       
   727                 }
       
   728                 request.req.data_size = data.data_size;
       
   729                 ecrt_sdo_request_write(&request.req);
       
   730 
       
   731                 // schedule request.
       
   732                 down(&master->sdo_sem);
       
   733                 list_add_tail(&request.list, &master->slave_sdo_requests);
       
   734                 up(&master->sdo_sem);
       
   735 
       
   736                 // wait for processing through FSM
       
   737                 if (wait_event_interruptible(master->sdo_queue,
       
   738                             request.req.state != EC_REQUEST_QUEUED)) {
       
   739                     // interrupted by signal
       
   740                     down(&master->sdo_sem);
       
   741                     if (request.req.state == EC_REQUEST_QUEUED) {
       
   742                         list_del(&request.req.list);
       
   743                         up(&master->sdo_sem);
       
   744                         retval = -EINTR;
       
   745                         break;
       
   746                     }
       
   747                     // request already processing: interrupt not possible.
       
   748                     up(&master->sdo_sem);
       
   749                 }
       
   750 
       
   751                 // wait until master FSM has finished processing
       
   752                 wait_event(master->sdo_queue, request.req.state != EC_REQUEST_BUSY);
       
   753 
       
   754                 if (request.req.state != EC_REQUEST_SUCCESS) {
       
   755                     retval = -EIO;
       
   756                     break;
       
   757                 }
       
   758 
       
   759                 ec_sdo_request_clear(&request.req);
       
   760                 break;
       
   761             }
       
   762 
   687         default:
   763         default:
   688             retval = -ENOTTY;
   764             retval = -ENOTTY;
   689     }
   765     }
   690 
   766 
   691     return retval;
   767     return retval;