diff -r 55a6e3294dab -r 024a3c6aa3f7 master/cdev.c --- a/master/cdev.c Sun Jun 06 23:21:09 2010 +0200 +++ b/master/cdev.c Tue Jul 06 15:09:57 2010 +0200 @@ -3319,86 +3319,40 @@ ) { ec_ioctl_slave_soe_read_t ioctl; - ec_master_soe_request_t request; + u8 *data; int retval; if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) { return -EFAULT; } - ec_soe_request_init(&request.req); - ec_soe_request_set_idn(&request.req, ioctl.idn); - ec_soe_request_read(&request.req); - - if (down_interruptible(&master->master_sem)) - return -EINTR; - - if (!(request.slave = ec_master_find_slave( - master, 0, ioctl.slave_position))) { - up(&master->master_sem); - ec_soe_request_clear(&request.req); - EC_MASTER_ERR(master, "Slave %u does not exist!\n", - ioctl.slave_position); - return -EINVAL; - } - - // schedule request. - list_add_tail(&request.list, &request.slave->soe_requests); - - up(&master->master_sem); - - EC_SLAVE_DBG(request.slave, 1, "Scheduled SoE read request.\n"); - - // wait for processing through FSM - if (wait_event_interruptible(request.slave->soe_queue, - request.req.state != EC_INT_REQUEST_QUEUED)) { - // interrupted by signal - down(&master->master_sem); - if (request.req.state == EC_INT_REQUEST_QUEUED) { - list_del(&request.list); - up(&master->master_sem); - ec_soe_request_clear(&request.req); - return -EINTR; - } - // request already processing: interrupt not possible. - up(&master->master_sem); - } - - // wait until master FSM has finished processing - wait_event(request.slave->soe_queue, - request.req.state != EC_INT_REQUEST_BUSY); - - ioctl.error_code = request.req.error_code; - - EC_SLAVE_DBG(request.slave, 1, "Read %zd bytes via SoE.\n", - request.req.data_size); - - if (request.req.state != EC_INT_REQUEST_SUCCESS) { - ioctl.data_size = 0; - retval = -EIO; - } else { - if (request.req.data_size > ioctl.mem_size) { - EC_MASTER_ERR(master, "Buffer too small.\n"); - ec_soe_request_clear(&request.req); - return -EOVERFLOW; - } - ioctl.data_size = request.req.data_size; - if (copy_to_user((void __user *) ioctl.data, - request.req.data, ioctl.data_size)) { - ec_soe_request_clear(&request.req); - return -EFAULT; - } - retval = 0; - } + data = kmalloc(ioctl.mem_size, GFP_KERNEL); + if (!data) { + EC_MASTER_ERR(master, "Failed to allocate %u bytes of IDN data.\n", + ioctl.mem_size); + return -ENOMEM; + } + + retval = ecrt_master_read_idn(master, ioctl.slave_position, + ioctl.idn, data, ioctl.mem_size, &ioctl.data_size, + &ioctl.error_code); + if (retval) { + kfree(data); + return retval; + } + + if (copy_to_user((void __user *) ioctl.data, + data, ioctl.data_size)) { + kfree(data); + return -EFAULT; + } + kfree(data); if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) { retval = -EFAULT; } - EC_SLAVE_DBG(request.slave, 1, "Finished SoE read request.\n"); - - ec_soe_request_clear(&request.req); - + EC_MASTER_DBG(master, 1, "Finished SoE read request.\n"); return retval; } @@ -3412,79 +3366,36 @@ ) { ec_ioctl_slave_soe_write_t ioctl; - ec_master_soe_request_t request; + u8 *data; int retval; if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) { return -EFAULT; } - INIT_LIST_HEAD(&request.list); - - ec_soe_request_init(&request.req); - ec_soe_request_set_idn(&request.req, ioctl.idn); - - if (ec_soe_request_alloc(&request.req, ioctl.data_size)) { - ec_soe_request_clear(&request.req); + data = kmalloc(ioctl.data_size, GFP_KERNEL); + if (!data) { + EC_MASTER_ERR(master, "Failed to allocate %u bytes of IDN data.\n", + ioctl.data_size); return -ENOMEM; } - if (copy_from_user(request.req.data, - (void __user *) ioctl.data, ioctl.data_size)) { - ec_soe_request_clear(&request.req); - return -EFAULT; - } - request.req.data_size = ioctl.data_size; - ec_soe_request_write(&request.req); - - if (down_interruptible(&master->master_sem)) - return -EINTR; - - if (!(request.slave = ec_master_find_slave( - master, 0, ioctl.slave_position))) { - up(&master->master_sem); - EC_MASTER_ERR(master, "Slave %u does not exist!\n", - ioctl.slave_position); - ec_soe_request_clear(&request.req); - return -EINVAL; - } - - EC_SLAVE_DBG(request.slave, 1, "Scheduling SoE write request.\n"); - - // schedule SoE write request. - list_add_tail(&request.list, &request.slave->soe_requests); - - up(&master->master_sem); - - // wait for processing through FSM - if (wait_event_interruptible(request.slave->soe_queue, - request.req.state != EC_INT_REQUEST_QUEUED)) { - // interrupted by signal - down(&master->master_sem); - if (request.req.state == EC_INT_REQUEST_QUEUED) { - // abort request - list_del(&request.list); - up(&master->master_sem); - ec_soe_request_clear(&request.req); - return -EINTR; - } - up(&master->master_sem); - } - - // wait until master FSM has finished processing - wait_event(request.slave->soe_queue, - request.req.state != EC_INT_REQUEST_BUSY); - - ioctl.error_code = request.req.error_code; - retval = request.req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; + if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) { + kfree(data); + return -EFAULT; + } + + retval = ecrt_master_write_idn(master, ioctl.slave_position, + ioctl.idn, data, ioctl.data_size, &ioctl.error_code); + kfree(data); + if (retval) { + return retval; + } if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) { retval = -EFAULT; } - ec_soe_request_clear(&request.req); - - EC_SLAVE_DBG(request.slave, 1, "Finished SoE write request.\n"); - + EC_MASTER_DBG(master, 1, "Finished SoE write request.\n"); return retval; }