--- a/master/cdev.c Thu Dec 23 09:28:39 2010 +0100
+++ b/master/cdev.c Thu Dec 23 09:48:56 2010 +0100
@@ -840,78 +840,74 @@
)
{
ec_ioctl_slave_sdo_upload_t data;
- ec_master_sdo_request_t request;
+ ec_master_sdo_request_t* request;
int retval;
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
return -EFAULT;
}
- ec_sdo_request_init(&request.req);
- ec_sdo_request_address(&request.req,
- data.sdo_index, data.sdo_entry_subindex);
- ecrt_sdo_request_read(&request.req);
-
- if (down_interruptible(&master->master_sem))
- return -EINTR;
-
- if (!(request.slave = ec_master_find_slave(
+ request = kmalloc(sizeof(*request), GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+ kref_init(&request->refcount);
+
+ ec_sdo_request_init(&request->req);
+ ec_sdo_request_address(&request->req,
+ data.sdo_index, data.sdo_entry_subindex);
+ ecrt_sdo_request_read(&request->req);
+
+ if (down_interruptible(&master->master_sem)) {
+ kref_put(&request->refcount,ec_master_sdo_request_release);
+ return -EINTR;
+ }
+ if (!(request->slave = ec_master_find_slave(
master, 0, data.slave_position))) {
up(&master->master_sem);
- ec_sdo_request_clear(&request.req);
+ kref_put(&request->refcount,ec_master_sdo_request_release);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
return -EINVAL;
}
- EC_SLAVE_DBG(request.slave, 1, "Schedule SDO upload request.\n");
+ EC_SLAVE_DBG(request->slave, 1, "Schedule SDO upload request %p.\n",request);
// schedule request.
- list_add_tail(&request.list, &request.slave->slave_sdo_requests);
+ kref_get(&request->refcount);
+ list_add_tail(&request->list, &request->slave->slave_sdo_requests);
up(&master->master_sem);
// wait for processing through FSM
- if (wait_event_interruptible(request.slave->sdo_queue,
- request.req.state != EC_INT_REQUEST_QUEUED)) {
+ if (wait_event_interruptible(request->slave->sdo_queue,
+ ((request->req.state == EC_INT_REQUEST_SUCCESS) || (request->req.state == EC_INT_REQUEST_FAILURE)))) {
// interrupted by signal
- down(&master->master_sem);
- if (request.req.state == EC_INT_REQUEST_QUEUED) {
- list_del(&request.list);
- up(&master->master_sem);
- ec_sdo_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->sdo_queue,
- request.req.state != EC_INT_REQUEST_BUSY);
-
- EC_SLAVE_DBG(request.slave, 1, "Finished SDO upload request.\n");
-
- data.abort_code = request.req.abort_code;
-
- if (request.req.state != EC_INT_REQUEST_SUCCESS) {
+ kref_put(&request->refcount,ec_master_sdo_request_release);
+ return -EINTR;
+ }
+
+ EC_SLAVE_DBG(request->slave, 1, "Finished SDO upload request %p.\n",request);
+
+ data.abort_code = request->req.abort_code;
+
+ if (request->req.state != EC_INT_REQUEST_SUCCESS) {
data.data_size = 0;
- if (request.req.errno) {
- retval = -request.req.errno;
+ if (request->req.errno) {
+ retval = -request->req.errno;
} else {
retval = -EIO;
}
} else {
- if (request.req.data_size > data.target_size) {
+ if (request->req.data_size > data.target_size) {
EC_MASTER_ERR(master, "Buffer too small.\n");
- ec_sdo_request_clear(&request.req);
+ kref_put(&request->refcount,ec_master_sdo_request_release);
return -EOVERFLOW;
}
- data.data_size = request.req.data_size;
+ data.data_size = request->req.data_size;
if (copy_to_user((void __user *) data.target,
- request.req.data, data.data_size)) {
- ec_sdo_request_clear(&request.req);
+ request->req.data, data.data_size)) {
+ kref_put(&request->refcount,ec_master_sdo_request_release);
return -EFAULT;
}
retval = 0;
@@ -921,7 +917,7 @@
retval = -EFAULT;
}
- ec_sdo_request_clear(&request.req);
+ kref_put(&request->refcount,ec_master_sdo_request_release);
return retval;
}
@@ -935,7 +931,7 @@
)
{
ec_ioctl_slave_sdo_download_t data;
- ec_master_sdo_request_t request;
+ ec_master_sdo_request_t* request;
int retval;
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
@@ -948,67 +944,63 @@
return -EINVAL;
}
- ec_sdo_request_init(&request.req);
- ec_sdo_request_address(&request.req,
+ request = kmalloc(sizeof(*request), GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+ kref_init(&request->refcount);
+
+ ec_sdo_request_init(&request->req);
+ ec_sdo_request_address(&request->req,
data.sdo_index, data.sdo_entry_subindex);
- if (ec_sdo_request_alloc(&request.req, data.data_size)) {
- ec_sdo_request_clear(&request.req);
+ if (ec_sdo_request_alloc(&request->req, data.data_size)) {
+ kref_put(&request->refcount,ec_master_sdo_request_release);
return -ENOMEM;
}
- if (copy_from_user(request.req.data,
+ if (copy_from_user(request->req.data,
(void __user *) data.data, data.data_size)) {
- ec_sdo_request_clear(&request.req);
- return -EFAULT;
- }
- request.req.data_size = data.data_size;
- ecrt_sdo_request_write(&request.req);
-
- if (down_interruptible(&master->master_sem))
- return -EINTR;
-
- if (!(request.slave = ec_master_find_slave(
+ kref_put(&request->refcount,ec_master_sdo_request_release);
+ return -EFAULT;
+ }
+ request->req.data_size = data.data_size;
+ ecrt_sdo_request_write(&request->req);
+
+ if (down_interruptible(&master->master_sem)) {
+ kref_put(&request->refcount,ec_master_sdo_request_release);
+ return -EINTR;
+ }
+ if (!(request->slave = ec_master_find_slave(
master, 0, data.slave_position))) {
up(&master->master_sem);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
- ec_sdo_request_clear(&request.req);
+ kref_put(&request->refcount,ec_master_sdo_request_release);
return -EINVAL;
}
- EC_SLAVE_DBG(request.slave, 1, "Schedule SDO download request.\n");
+ EC_SLAVE_DBG(request->slave, 1, "Schedule SDO download request %p.\n",request);
// schedule request.
- list_add_tail(&request.list, &request.slave->slave_sdo_requests);
+ kref_get(&request->refcount);
+ list_add_tail(&request->list, &request->slave->slave_sdo_requests);
up(&master->master_sem);
// wait for processing through FSM
- if (wait_event_interruptible(request.slave->sdo_queue,
- request.req.state != EC_INT_REQUEST_QUEUED)) {
+ if (wait_event_interruptible(request->slave->sdo_queue,
+ ((request->req.state == EC_INT_REQUEST_SUCCESS) || (request->req.state == EC_INT_REQUEST_FAILURE)))) {
// interrupted by signal
- down(&master->master_sem);
- if (request.req.state == EC_INT_REQUEST_QUEUED) {
- list_del(&request.list);
- up(&master->master_sem);
- ec_sdo_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->sdo_queue,
- request.req.state != EC_INT_REQUEST_BUSY);
-
- EC_SLAVE_DBG(request.slave, 1, "Finished SDO download request.\n");
-
- data.abort_code = request.req.abort_code;
-
- if (request.req.state == EC_INT_REQUEST_SUCCESS) {
+ kref_put(&request->refcount,ec_master_sdo_request_release);
+ return -EINTR;
+ }
+
+ EC_SLAVE_DBG(request->slave, 1, "Finished SDO download request %p.\n",request);
+
+ data.abort_code = request->req.abort_code;
+
+ if (request->req.state == EC_INT_REQUEST_SUCCESS) {
retval = 0;
- } else if (request.req.errno) {
- retval = -request.req.errno;
+ } else if (request->req.errno) {
+ retval = -request->req.errno;
} else {
retval = -EIO;
}
@@ -1017,7 +1009,7 @@
retval = -EFAULT;
}
- ec_sdo_request_clear(&request.req);
+ kref_put(&request->refcount,ec_master_sdo_request_release);
return retval;
}