master/ioctl.c
branchstable-1.5
changeset 2464 e6cc33cac6a2
parent 2453 d461b1f07296
child 2467 74ede087bc85
equal deleted inserted replaced
2463:71d38ff288b3 2464:e6cc33cac6a2
  3564 static int ec_ioctl_slave_foe_read(
  3564 static int ec_ioctl_slave_foe_read(
  3565         ec_master_t *master, /**< EtherCAT master. */
  3565         ec_master_t *master, /**< EtherCAT master. */
  3566         void *arg /**< ioctl() argument. */
  3566         void *arg /**< ioctl() argument. */
  3567         )
  3567         )
  3568 {
  3568 {
  3569     ec_ioctl_slave_foe_t data;
  3569     ec_ioctl_slave_foe_t io;
  3570     ec_master_foe_request_t request;
  3570     ec_foe_request_t request;
  3571     int retval;
  3571     ec_slave_t *slave;
  3572 
  3572     int ret;
  3573     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  3573 
  3574         return -EFAULT;
  3574     if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
  3575     }
  3575         return -EFAULT;
  3576 
  3576     }
  3577     ec_foe_request_init(&request.req, data.file_name);
  3577 
  3578     ec_foe_request_read(&request.req);
  3578     ec_foe_request_init(&request, io.file_name);
  3579     ec_foe_request_alloc(&request.req, 10000); // FIXME
  3579     ret = ec_foe_request_alloc(&request, 10000); // FIXME
       
  3580     if (ret) {
       
  3581         ec_foe_request_clear(&request);
       
  3582         return ret;
       
  3583     }
       
  3584 
       
  3585     ec_foe_request_read(&request);
  3580 
  3586 
  3581     if (down_interruptible(&master->master_sem)) {
  3587     if (down_interruptible(&master->master_sem)) {
  3582         ec_foe_request_clear(&request.req);
  3588         ec_foe_request_clear(&request);
  3583         return -EINTR;
  3589         return -EINTR;
  3584     }
  3590     }
  3585 
  3591 
  3586     if (!(request.slave = ec_master_find_slave(
  3592     if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
  3587                     master, 0, data.slave_position))) {
  3593         up(&master->master_sem);
  3588         up(&master->master_sem);
  3594         ec_foe_request_clear(&request);
  3589         ec_foe_request_clear(&request.req);
       
  3590         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  3595         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  3591                 data.slave_position);
  3596                 io.slave_position);
  3592         return -EINVAL;
  3597         return -EINVAL;
  3593     }
  3598     }
  3594 
  3599 
  3595     // schedule request.
  3600     // schedule request.
  3596     list_add_tail(&request.list, &request.slave->foe_requests);
  3601     list_add_tail(&request.list, &slave->foe_requests);
  3597 
  3602 
  3598     up(&master->master_sem);
  3603     up(&master->master_sem);
  3599 
  3604 
  3600     EC_SLAVE_DBG(request.slave, 1, "Scheduled FoE read request.\n");
  3605     EC_SLAVE_DBG(slave, 1, "Scheduled FoE read request.\n");
  3601 
  3606 
  3602     // wait for processing through FSM
  3607     // wait for processing through FSM
  3603     if (wait_event_interruptible(request.slave->foe_queue,
  3608     if (wait_event_interruptible(slave->foe_queue,
  3604                 request.req.state != EC_INT_REQUEST_QUEUED)) {
  3609                 request.state != EC_INT_REQUEST_QUEUED)) {
  3605         // interrupted by signal
  3610         // interrupted by signal
  3606         down(&master->master_sem);
  3611         down(&master->master_sem);
  3607         if (request.req.state == EC_INT_REQUEST_QUEUED) {
  3612         if (request.state == EC_INT_REQUEST_QUEUED) {
  3608             list_del(&request.list);
  3613             list_del(&request.list);
  3609             up(&master->master_sem);
  3614             up(&master->master_sem);
  3610             ec_foe_request_clear(&request.req);
  3615             ec_foe_request_clear(&request);
  3611             return -EINTR;
  3616             return -EINTR;
  3612         }
  3617         }
  3613         // request already processing: interrupt not possible.
  3618         // request already processing: interrupt not possible.
  3614         up(&master->master_sem);
  3619         up(&master->master_sem);
  3615     }
  3620     }
  3616 
  3621 
       
  3622     // FIXME slave may become invalid
       
  3623 
  3617     // wait until master FSM has finished processing
  3624     // wait until master FSM has finished processing
  3618     wait_event(request.slave->foe_queue,
  3625     wait_event(slave->foe_queue, request.state != EC_INT_REQUEST_BUSY);
  3619             request.req.state != EC_INT_REQUEST_BUSY);
  3626 
  3620 
  3627     io.result = request.result;
  3621     data.result = request.req.result;
  3628     io.error_code = request.error_code;
  3622     data.error_code = request.req.error_code;
  3629 
  3623 
  3630     EC_SLAVE_DBG(slave, 1, "Read %zd bytes via FoE (result = 0x%x).\n",
  3624     EC_SLAVE_DBG(request.slave, 1, "Read %zd bytes via FoE"
  3631             request.data_size, request.result);
  3625             " (result = 0x%x).\n", request.req.data_size, request.req.result);
  3632 
  3626 
  3633     if (request.state != EC_INT_REQUEST_SUCCESS) {
  3627     if (request.req.state != EC_INT_REQUEST_SUCCESS) {
  3634         io.data_size = 0;
  3628         data.data_size = 0;
  3635         ret = -EIO;
  3629         retval = -EIO;
       
  3630     } else {
  3636     } else {
  3631         if (request.req.data_size > data.buffer_size) {
  3637         if (request.data_size > io.buffer_size) {
  3632             EC_MASTER_ERR(master, "Buffer too small.\n");
  3638             EC_MASTER_ERR(master, "Buffer too small.\n");
  3633             ec_foe_request_clear(&request.req);
  3639             ec_foe_request_clear(&request);
  3634             return -EOVERFLOW;
  3640             return -EOVERFLOW;
  3635         }
  3641         }
  3636         data.data_size = request.req.data_size;
  3642         io.data_size = request.data_size;
  3637         if (copy_to_user((void __user *) data.buffer,
  3643         if (copy_to_user((void __user *) io.buffer,
  3638                     request.req.buffer, data.data_size)) {
  3644                     request.buffer, io.data_size)) {
  3639             ec_foe_request_clear(&request.req);
  3645             ec_foe_request_clear(&request);
  3640             return -EFAULT;
  3646             return -EFAULT;
  3641         }
  3647         }
  3642         retval = 0;
  3648         ret = 0;
  3643     }
  3649     }
  3644 
  3650 
  3645     if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
  3651     if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
  3646         retval = -EFAULT;
  3652         ret = -EFAULT;
  3647     }
  3653     }
  3648 
  3654 
  3649     EC_SLAVE_DBG(request.slave, 1, "Finished FoE read request.\n");
  3655     EC_SLAVE_DBG(slave, 1, "Finished FoE read request.\n");
  3650 
  3656 
  3651     ec_foe_request_clear(&request.req);
  3657     ec_foe_request_clear(&request);
  3652 
  3658 
  3653     return retval;
  3659     return ret;
  3654 }
  3660 }
  3655 
  3661 
  3656 /*****************************************************************************/
  3662 /*****************************************************************************/
  3657 
  3663 
  3658 /** Write a file to a slave via FoE
  3664 /** Write a file to a slave via FoE
  3660 static int ec_ioctl_slave_foe_write(
  3666 static int ec_ioctl_slave_foe_write(
  3661         ec_master_t *master, /**< EtherCAT master. */
  3667         ec_master_t *master, /**< EtherCAT master. */
  3662         void *arg /**< ioctl() argument. */
  3668         void *arg /**< ioctl() argument. */
  3663         )
  3669         )
  3664 {
  3670 {
  3665     ec_ioctl_slave_foe_t data;
  3671     ec_ioctl_slave_foe_t io;
  3666     ec_master_foe_request_t request;
  3672     ec_foe_request_t request;
  3667     int retval;
  3673     ec_slave_t *slave;
  3668 
  3674     int ret;
  3669     if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
  3675 
  3670         return -EFAULT;
  3676     if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
  3671     }
  3677         return -EFAULT;
  3672 
  3678     }
  3673     INIT_LIST_HEAD(&request.list);
  3679 
  3674 
  3680     ec_foe_request_init(&request, io.file_name);
  3675     ec_foe_request_init(&request.req, data.file_name);
  3681 
  3676 
  3682     ret = ec_foe_request_alloc(&request, io.buffer_size);
  3677     if (ec_foe_request_alloc(&request.req, data.buffer_size)) {
  3683     if (ret) {
  3678         ec_foe_request_clear(&request.req);
  3684         ec_foe_request_clear(&request);
  3679         return -ENOMEM;
  3685         return ret;
  3680     }
  3686     }
  3681     if (copy_from_user(request.req.buffer,
  3687 
  3682                 (void __user *) data.buffer, data.buffer_size)) {
  3688     if (copy_from_user(request.buffer,
  3683         ec_foe_request_clear(&request.req);
  3689                 (void __user *) io.buffer, io.buffer_size)) {
  3684         return -EFAULT;
  3690         ec_foe_request_clear(&request);
  3685     }
  3691         return -EFAULT;
  3686     request.req.data_size = data.buffer_size;
  3692     }
  3687     ec_foe_request_write(&request.req);
  3693 
       
  3694     request.data_size = io.buffer_size;
       
  3695     ec_foe_request_write(&request);
  3688 
  3696 
  3689     if (down_interruptible(&master->master_sem)) {
  3697     if (down_interruptible(&master->master_sem)) {
  3690         ec_foe_request_clear(&request.req);
  3698         ec_foe_request_clear(&request);
  3691         return -EINTR;
  3699         return -EINTR;
  3692     }
  3700     }
  3693 
  3701 
  3694     if (!(request.slave = ec_master_find_slave(
  3702     if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
  3695                     master, 0, data.slave_position))) {
       
  3696         up(&master->master_sem);
  3703         up(&master->master_sem);
  3697         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  3704         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  3698                 data.slave_position);
  3705                 io.slave_position);
  3699         ec_foe_request_clear(&request.req);
  3706         ec_foe_request_clear(&request);
  3700         return -EINVAL;
  3707         return -EINVAL;
  3701     }
  3708     }
  3702 
  3709 
  3703     EC_SLAVE_DBG(request.slave, 1, "Scheduling FoE write request.\n");
  3710     EC_SLAVE_DBG(slave, 1, "Scheduling FoE write request.\n");
  3704 
  3711 
  3705     // schedule FoE write request.
  3712     // schedule FoE write request.
  3706     list_add_tail(&request.list, &request.slave->foe_requests);
  3713     list_add_tail(&request.list, &slave->foe_requests);
  3707 
  3714 
  3708     up(&master->master_sem);
  3715     up(&master->master_sem);
  3709 
  3716 
  3710     // wait for processing through FSM
  3717     // wait for processing through FSM
  3711     if (wait_event_interruptible(request.slave->foe_queue,
  3718     if (wait_event_interruptible(slave->foe_queue,
  3712                 request.req.state != EC_INT_REQUEST_QUEUED)) {
  3719                 request.state != EC_INT_REQUEST_QUEUED)) {
  3713         // interrupted by signal
  3720         // interrupted by signal
  3714         down(&master->master_sem);
  3721         down(&master->master_sem);
  3715         if (request.req.state == EC_INT_REQUEST_QUEUED) {
  3722         if (request.state == EC_INT_REQUEST_QUEUED) {
  3716             // abort request
  3723             // abort request
  3717             list_del(&request.list);
  3724             list_del(&request.list);
  3718             up(&master->master_sem);
  3725             up(&master->master_sem);
  3719             ec_foe_request_clear(&request.req);
  3726             ec_foe_request_clear(&request);
  3720             return -EINTR;
  3727             return -EINTR;
  3721         }
  3728         }
  3722         up(&master->master_sem);
  3729         up(&master->master_sem);
  3723     }
  3730     }
  3724 
  3731 
       
  3732     // FIXME slave may become invalid
       
  3733 
  3725     // wait until master FSM has finished processing
  3734     // wait until master FSM has finished processing
  3726     wait_event(request.slave->foe_queue,
  3735     wait_event(slave->foe_queue, request.state != EC_INT_REQUEST_BUSY);
  3727             request.req.state != EC_INT_REQUEST_BUSY);
  3736 
  3728 
  3737     io.result = request.result;
  3729     data.result = request.req.result;
  3738     io.error_code = request.error_code;
  3730     data.error_code = request.req.error_code;
  3739 
  3731 
  3740     ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
  3732     retval = request.req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
  3741 
  3733 
  3742     if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
  3734     if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
  3743         ret = -EFAULT;
  3735         retval = -EFAULT;
  3744     }
  3736     }
  3745 
  3737 
  3746     ec_foe_request_clear(&request);
  3738     ec_foe_request_clear(&request.req);
  3747 
  3739 
  3748     EC_SLAVE_DBG(slave, 1, "Finished FoE write request.\n");
  3740     EC_SLAVE_DBG(request.slave, 1, "Finished FoE write request.\n");
  3749 
  3741 
  3750     return ret;
  3742     return retval;
       
  3743 }
  3751 }
  3744 
  3752 
  3745 /*****************************************************************************/
  3753 /*****************************************************************************/
  3746 
  3754 
  3747 /** Read an SoE IDN.
  3755 /** Read an SoE IDN.