--- a/master/cdev.c Wed Mar 23 08:06:58 2011 +0100
+++ b/master/cdev.c Wed Apr 13 22:06:28 2011 +0200
@@ -186,7 +186,7 @@
ec_ioctl_master_t data;
unsigned int i;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
data.slave_count = master->slave_count;
data.config_count = ec_master_config_count(master);
@@ -197,9 +197,9 @@
data.phase = (uint8_t) master->phase;
data.active = (uint8_t) master->active;
data.scan_busy = master->scan_busy;
- up(&master->master_sem);
-
- if (down_interruptible(&master->device_sem))
+ ec_mutex_unlock(&master->master_mutex);
+
+ if (ec_mutex_lock_interruptible(&master->device_mutex))
return -EINTR;
if (master->main_device.dev) {
@@ -242,7 +242,7 @@
data.devices[1].loss_rates[i] = master->backup_device.loss_rates[i];
}
- up(&master->device_sem);
+ ec_mutex_unlock(&master->device_mutex);
data.app_time = master->app_time;
data.ref_clock =
@@ -271,12 +271,12 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(slave = ec_master_find_slave_const(
master, 0, data.position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave %u does not exist!\n", data.position);
return -EINVAL;
}
@@ -330,7 +330,7 @@
ec_cdev_strcpy(data.order, slave->sii.order);
ec_cdev_strcpy(data.name, slave->sii.name);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -355,19 +355,19 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(slave = ec_master_find_slave_const(
master, 0, data.slave_position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
return -EINVAL;
}
if (data.sync_index >= slave->sii.sync_count) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
data.sync_index);
return -EINVAL;
@@ -381,7 +381,7 @@
data.enable = sync->enable;
data.pdo_count = ec_pdo_list_count(&sync->pdos);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -407,19 +407,19 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(slave = ec_master_find_slave_const(
master, 0, data.slave_position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
return -EINVAL;
}
if (data.sync_index >= slave->sii.sync_count) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
data.sync_index);
return -EINVAL;
@@ -428,7 +428,7 @@
sync = &slave->sii.syncs[data.sync_index];
if (!(pdo = ec_pdo_list_find_pdo_by_pos_const(
&sync->pdos, data.pdo_pos))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
"position %u!\n", data.sync_index, data.pdo_pos);
return -EINVAL;
@@ -438,7 +438,7 @@
data.entry_count = ec_pdo_entry_count(pdo);
ec_cdev_strcpy(data.name, pdo->name);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -465,19 +465,19 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(slave = ec_master_find_slave_const(
master, 0, data.slave_position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
return -EINVAL;
}
if (data.sync_index >= slave->sii.sync_count) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
data.sync_index);
return -EINVAL;
@@ -486,7 +486,7 @@
sync = &slave->sii.syncs[data.sync_index];
if (!(pdo = ec_pdo_list_find_pdo_by_pos_const(
&sync->pdos, data.pdo_pos))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
"position %u!\n", data.sync_index, data.pdo_pos);
return -EINVAL;
@@ -494,7 +494,7 @@
if (!(entry = ec_pdo_find_entry_by_pos_const(
pdo, data.entry_pos))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_SLAVE_ERR(slave, "PDO 0x%04X does not contain an entry with "
"position %u!\n", data.pdo_pos, data.entry_pos);
return -EINVAL;
@@ -505,7 +505,7 @@
data.bit_length = entry->bit_length;
ec_cdev_strcpy(data.name, entry->name);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -529,22 +529,23 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(domain = ec_master_find_domain_const(master, data.index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Domain %u does not exist!\n", data.index);
return -EINVAL;
}
data.data_size = domain->data_size;
+ data.tx_size = domain->tx_size;
data.logical_base_address = domain->logical_base_address;
data.working_counter = domain->working_counter;
data.expected_working_counter = domain->expected_working_counter;
data.fmmu_count = ec_domain_fmmu_count(domain);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -569,18 +570,18 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Domain %u does not exist!\n",
data.domain_index);
return -EINVAL;
}
if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Domain %u has less than %u"
" fmmu configurations.\n",
data.domain_index, data.fmmu_index + 1);
@@ -592,9 +593,10 @@
data.sync_index = fmmu->sync_index;
data.dir = fmmu->dir;
data.logical_address = fmmu->logical_start_address;
+ data.domain_address = fmmu->domain_address;
data.data_size = fmmu->data_size;
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -618,18 +620,18 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Domain %u does not exist!\n",
data.domain_index);
return -EINVAL;
}
if (domain->data_size != data.data_size) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Data size mismatch %u/%zu!\n",
data.data_size, domain->data_size);
return -EFAULT;
@@ -637,11 +639,11 @@
if (copy_to_user((void __user *) data.target, domain->data,
domain->data_size)) {
- up(&master->master_sem);
- return -EFAULT;
- }
-
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
+ return -EFAULT;
+ }
+
+ ec_mutex_unlock(&master->master_mutex);
return 0;
}
@@ -686,12 +688,12 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(slave = ec_master_find_slave(
master, 0, data.slave_position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
return -EINVAL;
@@ -699,7 +701,7 @@
ec_slave_request_state(slave, data.al_state);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return 0;
}
@@ -720,12 +722,12 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(slave = ec_master_find_slave_const(
master, 0, data.slave_position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
return -EINVAL;
@@ -733,7 +735,7 @@
if (!(sdo = ec_slave_get_sdo_by_pos_const(
slave, data.sdo_position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", data.sdo_position);
return -EINVAL;
}
@@ -742,7 +744,7 @@
data.max_subindex = sdo->max_subindex;
ec_cdev_strcpy(data.name, sdo->name);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -768,12 +770,12 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(slave = ec_master_find_slave_const(
master, 0, data.slave_position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
return -EINVAL;
@@ -782,14 +784,14 @@
if (data.sdo_spec <= 0) {
if (!(sdo = ec_slave_get_sdo_by_pos_const(
slave, -data.sdo_spec))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", -data.sdo_spec);
return -EINVAL;
}
} else {
if (!(sdo = ec_slave_get_sdo_const(
slave, data.sdo_spec))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_SLAVE_ERR(slave, "SDO 0x%04X does not exist!\n",
data.sdo_spec);
return -EINVAL;
@@ -798,7 +800,7 @@
if (!(entry = ec_sdo_get_entry_const(
sdo, data.sdo_entry_subindex))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_SLAVE_ERR(slave, "SDO entry 0x%04X:%02X does not exist!\n",
sdo->index, data.sdo_entry_subindex);
return -EINVAL;
@@ -820,7 +822,7 @@
entry->write_access[EC_SDO_ENTRY_ACCESS_OP];
ec_cdev_strcpy(data.description, entry->description);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -838,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 (ec_mutex_lock_interruptible(&master->master_mutex)) {
+ 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);
+ ec_mutex_unlock(&master->master_mutex);
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");
+ kref_put(&request->refcount,ec_master_sdo_request_release);
+ return -EINVAL;
+ }
+
+ 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);
-
- up(&master->master_sem);
+ kref_get(&request->refcount);
+ list_add_tail(&request->list, &request->slave->slave_sdo_requests);
+
+ ec_mutex_unlock(&master->master_mutex);
// 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;
@@ -919,7 +917,7 @@
retval = -EFAULT;
}
- ec_sdo_request_clear(&request.req);
+ kref_put(&request->refcount,ec_master_sdo_request_release);
return retval;
}
@@ -933,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))) {
@@ -946,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 (ec_mutex_lock_interruptible(&master->master_mutex)) {
+ 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_mutex_unlock(&master->master_mutex);
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);
-
- up(&master->master_sem);
+ kref_get(&request->refcount);
+ list_add_tail(&request->list, &request->slave->slave_sdo_requests);
+
+ ec_mutex_unlock(&master->master_mutex);
// 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;
}
@@ -1015,7 +1009,7 @@
retval = -EFAULT;
}
- ec_sdo_request_clear(&request.req);
+ kref_put(&request->refcount,ec_master_sdo_request_release);
return retval;
}
@@ -1036,12 +1030,12 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(slave = ec_master_find_slave_const(
master, 0, data.slave_position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
return -EINVAL;
@@ -1049,7 +1043,7 @@
if (!data.nwords
|| data.offset + data.nwords > slave->sii_nwords) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_SLAVE_ERR(slave, "Invalid SII read offset/size %u/%u for slave SII"
" size %zu!\n", data.offset, data.nwords, slave->sii_nwords);
return -EINVAL;
@@ -1061,7 +1055,7 @@
else
retval = 0;
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return retval;
}
@@ -1078,7 +1072,8 @@
ec_slave_t *slave;
unsigned int byte_size;
uint16_t *words;
- ec_sii_write_request_t request;
+ ec_sii_write_request_t* request;
+ int retval;
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
return -EFAULT;
@@ -1094,58 +1089,57 @@
return -ENOMEM;
}
+ request = kmalloc(sizeof(*request), GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+ kref_init(&request->refcount);
+ // init SII write request
+ INIT_LIST_HEAD(&request->list);
+ request->words = words; // now "owned" by request, see ec_master_sii_write_request_release
+ request->offset = data.offset;
+ request->nwords = data.nwords;
+
if (copy_from_user(words,
(void __user *) data.words, byte_size)) {
- kfree(words);
- return -EFAULT;
- }
-
- if (down_interruptible(&master->master_sem))
- return -EINTR;
-
+ kref_put(&request->refcount,ec_master_sii_write_request_release);
+ return -EFAULT;
+ }
+
+ if (ec_mutex_lock_interruptible(&master->master_mutex)) {
+ kref_put(&request->refcount,ec_master_sii_write_request_release);
+ return -EINTR;
+ }
if (!(slave = ec_master_find_slave(
master, 0, data.slave_position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
- kfree(words);
- return -EINVAL;
- }
-
- // init SII write request
- INIT_LIST_HEAD(&request.list);
- request.slave = slave;
- request.words = words;
- request.offset = data.offset;
- request.nwords = data.nwords;
- request.state = EC_INT_REQUEST_QUEUED;
+ kref_put(&request->refcount,ec_master_sii_write_request_release);
+ return -EINVAL;
+ }
+
+ request->slave = slave;
+ request->state = EC_INT_REQUEST_QUEUED;
// schedule SII write request.
- list_add_tail(&request.list, &master->sii_requests);
-
- up(&master->master_sem);
+ list_add_tail(&request->list, &master->sii_requests);
+ kref_get(&request->refcount);
+
+ ec_mutex_unlock(&master->master_mutex);
// wait for processing through FSM
if (wait_event_interruptible(master->sii_queue,
- request.state != EC_INT_REQUEST_QUEUED)) {
- // interrupted by signal
- down(&master->master_sem);
- if (request.state == EC_INT_REQUEST_QUEUED) {
- // abort request
- list_del(&request.list);
- up(&master->master_sem);
- kfree(words);
- return -EINTR;
- }
- up(&master->master_sem);
- }
-
- // wait until master FSM has finished processing
- wait_event(master->sii_queue, request.state != EC_INT_REQUEST_BUSY);
-
- kfree(words);
-
- return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
+ ((request->state == EC_INT_REQUEST_SUCCESS) || (request->state == EC_INT_REQUEST_FAILURE)))) {
+ // interrupted by signal
+ kref_put(&request->refcount,ec_master_sii_write_request_release);
+ return -EINTR;
+ }
+
+
+ retval = request->state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
+ kref_put(&request->refcount,ec_master_sii_write_request_release);
+
+ return retval;
}
/*****************************************************************************/
@@ -1160,7 +1154,8 @@
ec_ioctl_slave_reg_t data;
ec_slave_t *slave;
uint8_t *contents;
- ec_reg_request_t request;
+ ec_reg_request_t* request;
+ int retval;
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
return -EFAULT;
@@ -1175,56 +1170,58 @@
return -ENOMEM;
}
- if (down_interruptible(&master->master_sem))
- return -EINTR;
-
+ request = kmalloc(sizeof(*request), GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+ kref_init(&request->refcount);
+
+ // init register request
+ INIT_LIST_HEAD(&request->list);
+ request->dir = EC_DIR_INPUT;
+ request->data = contents; // now "owned" by request, see ec_master_reg_request_release
+ request->offset = data.offset;
+ request->length = data.length;
+
+ if (ec_mutex_lock_interruptible(&master->master_mutex)) {
+ kref_put(&request->refcount,ec_master_reg_request_release);
+ return -EINTR;
+ }
if (!(slave = ec_master_find_slave(
master, 0, data.slave_position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
- return -EINVAL;
- }
-
- // init register request
- INIT_LIST_HEAD(&request.list);
- request.slave = slave;
- request.dir = EC_DIR_INPUT;
- request.data = contents;
- request.offset = data.offset;
- request.length = data.length;
- request.state = EC_INT_REQUEST_QUEUED;
+ kref_put(&request->refcount,ec_master_reg_request_release);
+ return -EINVAL;
+ }
+
+ request->slave = slave;
+ request->state = EC_INT_REQUEST_QUEUED;
// schedule request.
- list_add_tail(&request.list, &master->reg_requests);
-
- up(&master->master_sem);
+ list_add_tail(&request->list, &master->reg_requests);
+ kref_get(&request->refcount);
+
+ ec_mutex_unlock(&master->master_mutex);
// wait for processing through FSM
if (wait_event_interruptible(master->reg_queue,
- request.state != EC_INT_REQUEST_QUEUED)) {
- // interrupted by signal
- down(&master->master_sem);
- if (request.state == EC_INT_REQUEST_QUEUED) {
- // abort request
- list_del(&request.list);
- up(&master->master_sem);
- kfree(contents);
- return -EINTR;
+ ((request->state == EC_INT_REQUEST_SUCCESS) || (request->state == EC_INT_REQUEST_FAILURE)))) {
+ // interrupted by signal
+ kref_put(&request->refcount,ec_master_reg_request_release);
+ return -EINTR;
+ }
+
+ if (request->state == EC_INT_REQUEST_SUCCESS) {
+ if (copy_to_user((void __user *) data.data, request->data, data.length)) {
+ kref_put(&request->refcount,ec_master_reg_request_release);
+ return -EFAULT;
}
- up(&master->master_sem);
- }
-
- // wait until master FSM has finished processing
- wait_event(master->reg_queue, request.state != EC_INT_REQUEST_BUSY);
-
- if (request.state == EC_INT_REQUEST_SUCCESS) {
- if (copy_to_user((void __user *) data.data, contents, data.length))
- return -EFAULT;
- }
- kfree(contents);
-
- return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
+ }
+ retval = request->state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
+
+ kref_put(&request->refcount,ec_master_reg_request_release);
+ return retval;
}
/*****************************************************************************/
@@ -1239,7 +1236,8 @@
ec_ioctl_slave_reg_t data;
ec_slave_t *slave;
uint8_t *contents;
- ec_reg_request_t request;
+ ec_reg_request_t* request;
+ int retval;
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
return -EFAULT;
@@ -1259,53 +1257,52 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
- return -EINTR;
+ request = kmalloc(sizeof(*request), GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+ kref_init(&request->refcount);
+ // init register request
+ INIT_LIST_HEAD(&request->list);
+ request->dir = EC_DIR_OUTPUT;
+ request->data = contents; // now "owned" by request, see ec_master_reg_request_release
+ request->offset = data.offset;
+ request->length = data.length;
+
+ if (ec_mutex_lock_interruptible(&master->master_mutex)) {
+ kref_put(&request->refcount,ec_master_reg_request_release);
+ return -EINTR;
+ }
if (!(slave = ec_master_find_slave(
master, 0, data.slave_position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
- kfree(contents);
- return -EINVAL;
- }
-
- // init register request
- INIT_LIST_HEAD(&request.list);
- request.slave = slave;
- request.dir = EC_DIR_OUTPUT;
- request.data = contents;
- request.offset = data.offset;
- request.length = data.length;
- request.state = EC_INT_REQUEST_QUEUED;
+ kref_put(&request->refcount,ec_master_reg_request_release);
+ return -EINVAL;
+ }
+
+ request->slave = slave;
+ request->state = EC_INT_REQUEST_QUEUED;
// schedule request.
- list_add_tail(&request.list, &master->reg_requests);
-
- up(&master->master_sem);
+ list_add_tail(&request->list, &master->reg_requests);
+ kref_get(&request->refcount);
+
+ ec_mutex_unlock(&master->master_mutex);
// wait for processing through FSM
if (wait_event_interruptible(master->reg_queue,
- request.state != EC_INT_REQUEST_QUEUED)) {
- // interrupted by signal
- down(&master->master_sem);
- if (request.state == EC_INT_REQUEST_QUEUED) {
- // abort request
- list_del(&request.list);
- up(&master->master_sem);
- kfree(contents);
- return -EINTR;
- }
- up(&master->master_sem);
- }
-
- // wait until master FSM has finished processing
- wait_event(master->reg_queue, request.state != EC_INT_REQUEST_BUSY);
-
- kfree(contents);
-
- return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
+ ((request->state == EC_INT_REQUEST_SUCCESS) || (request->state == EC_INT_REQUEST_FAILURE)))) {
+ // interrupted by signal
+ kref_put(&request->refcount,ec_master_reg_request_release);
+ return -EINTR;
+ }
+
+ retval = request->state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
+ kref_put(&request->refcount,ec_master_reg_request_release);
+ return retval;
+
}
/*****************************************************************************/
@@ -1325,12 +1322,12 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config_const(
master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
data.config_index);
return -EINVAL;
@@ -1356,7 +1353,7 @@
data.dc_sync[i] = sc->dc_sync[i];
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -1387,12 +1384,12 @@
return -EINVAL;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config_const(
master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
data.config_index);
return -EINVAL;
@@ -1401,7 +1398,7 @@
if (!(pdo = ec_pdo_list_find_pdo_by_pos_const(
&sc->sync_configs[data.sync_index].pdos,
data.pdo_pos))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Invalid PDO position!\n");
return -EINVAL;
}
@@ -1410,7 +1407,7 @@
data.entry_count = ec_pdo_entry_count(pdo);
ec_cdev_strcpy(data.name, pdo->name);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -1442,12 +1439,12 @@
return -EINVAL;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config_const(
master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
data.config_index);
return -EINVAL;
@@ -1456,14 +1453,14 @@
if (!(pdo = ec_pdo_list_find_pdo_by_pos_const(
&sc->sync_configs[data.sync_index].pdos,
data.pdo_pos))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Invalid PDO position!\n");
return -EINVAL;
}
if (!(entry = ec_pdo_find_entry_by_pos_const(
pdo, data.entry_pos))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Entry not found!\n");
return -EINVAL;
}
@@ -1473,7 +1470,7 @@
data.bit_length = entry->bit_length;
ec_cdev_strcpy(data.name, entry->name);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -1498,12 +1495,12 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config_const(
master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
data.config_index);
return -EINVAL;
@@ -1511,7 +1508,7 @@
if (!(req = ec_slave_config_get_sdo_by_pos_const(
sc, data.sdo_pos))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Invalid SDO position!\n");
return -EINVAL;
}
@@ -1522,7 +1519,7 @@
memcpy(&data.data, req->data,
min((u32) data.size, (u32) EC_MAX_SDO_DATA_SIZE));
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -1547,12 +1544,12 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config_const(
master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
data.config_index);
return -EINVAL;
@@ -1560,7 +1557,7 @@
if (!(req = ec_slave_config_get_idn_by_pos_const(
sc, data.idn_pos))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Invalid IDN position!\n");
return -EINVAL;
}
@@ -1572,7 +1569,7 @@
memcpy(&data.data, req->data,
min((u32) data.size, (u32) EC_MAX_IDN_DATA_SIZE));
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -1598,11 +1595,11 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(eoe = ec_master_get_eoe_handler_const(master, data.eoe_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "EoE handler %u does not exist!\n",
data.eoe_index);
return -EINVAL;
@@ -1615,14 +1612,14 @@
}
snprintf(data.name, EC_DATAGRAM_NAME_SIZE, eoe->dev->name);
data.open = eoe->opened;
- data.rx_bytes = eoe->stats.tx_bytes;
+ data.tx_bytes = eoe->stats.tx_bytes;
+ data.tx_rate = eoe->tx_rate;
+ data.rx_bytes = eoe->stats.rx_bytes;
data.rx_rate = eoe->tx_rate;
- data.tx_bytes = eoe->stats.rx_bytes;
- data.tx_rate = eoe->tx_rate;
data.tx_queued_frames = eoe->tx_queued_frames;
data.tx_queue_size = eoe->tx_queue_size;
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -1704,7 +1701,7 @@
data.config_index = 0;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
list_for_each_entry(entry, &master->configs, list) {
@@ -1713,7 +1710,7 @@
data.config_index++;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -1742,14 +1739,14 @@
priv->process_data_size = 0;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
list_for_each_entry(domain, &master->domains, list) {
priv->process_data_size += ecrt_domain_size(domain);
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (priv->process_data_size) {
priv->process_data = vmalloc(priv->process_data_size);
@@ -1767,9 +1764,6 @@
}
}
- ecrt_master_callbacks(master, ec_master_internal_send_cb,
- ec_master_internal_receive_cb, master);
-
ret = ecrt_master_activate(master);
if (ret < 0)
return ret;
@@ -1815,10 +1809,10 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
ec_master_set_send_interval(master,send_interval);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return 0;
}
@@ -1837,9 +1831,9 @@
if (unlikely(!priv->requested))
return -EPERM;
- down(&master->io_sem);
+ ec_mutex_lock(&master->io_mutex);
ecrt_master_send(master);
- up(&master->io_sem);
+ ec_mutex_unlock(&master->io_mutex);
return 0;
}
@@ -1856,9 +1850,9 @@
if (unlikely(!priv->requested))
return -EPERM;
- down(&master->io_sem);
+ ec_mutex_lock(&master->io_mutex);
ecrt_master_receive(master);
- up(&master->io_sem);
+ ec_mutex_unlock(&master->io_mutex);
return 0;
}
@@ -1887,6 +1881,29 @@
/*****************************************************************************/
+/** Get the master state of all configured slaves.
+ */
+int ec_cdev_ioctl_master_sc_state(
+ ec_master_t *master, /**< EtherCAT master. */
+ unsigned long arg, /**< ioctl() argument. */
+ ec_cdev_priv_t *priv /**< Private data structure of file handle. */
+ )
+{
+ ec_master_state_t data;
+
+ if (unlikely(!priv->requested))
+ return -EPERM;
+
+ ecrt_master_configured_slaves_state(master, &data);
+
+ if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+ return -EFAULT;
+
+ return 0;
+}
+
+/*****************************************************************************/
+
/** Get the master state.
*/
int ec_cdev_ioctl_app_time(
@@ -1921,9 +1938,9 @@
if (unlikely(!priv->requested))
return -EPERM;
- down(&master->io_sem);
+ ec_mutex_lock(&master->io_mutex);
ecrt_master_sync_reference_clock(master);
- up(&master->io_sem);
+ ec_mutex_unlock(&master->io_mutex);
return 0;
}
@@ -1940,9 +1957,9 @@
if (unlikely(!priv->requested))
return -EPERM;
- down(&master->io_sem);
+ ec_mutex_lock(&master->io_mutex);
ecrt_master_sync_slave_clocks(master);
- up(&master->io_sem);
+ ec_mutex_unlock(&master->io_mutex);
return 0;
}
@@ -1959,9 +1976,9 @@
if (unlikely(!priv->requested))
return -EPERM;
- down(&master->io_sem);
+ ec_mutex_lock(&master->io_mutex);
ecrt_master_sync_monitor_queue(master);
- up(&master->io_sem);
+ ec_mutex_unlock(&master->io_mutex);
return 0;
}
@@ -1980,9 +1997,9 @@
if (unlikely(!priv->requested))
return -EPERM;
- down(&master->io_sem);
+ ec_mutex_lock(&master->io_mutex);
time_diff = ecrt_master_sync_monitor_process(master);
- up(&master->io_sem);
+ ec_mutex_unlock(&master->io_mutex);
if (copy_to_user((void __user *) arg, &time_diff, sizeof(time_diff)))
return -EFAULT;
@@ -2003,9 +2020,9 @@
if (unlikely(!priv->requested))
return -EPERM;
- down(&master->master_sem);
+ ec_mutex_lock(&master->master_mutex);
ecrt_master_reset(master);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return 0;
}
@@ -2034,7 +2051,7 @@
goto out_return;
}
- if (down_interruptible(&master->master_sem)) {
+ if (ec_mutex_lock_interruptible(&master->master_mutex)) {
ret = -EINTR;
goto out_return;
}
@@ -2055,7 +2072,7 @@
}
out_up:
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
out_return:
return ret;
}
@@ -2084,7 +2101,7 @@
goto out_return;
}
- if (down_interruptible(&master->master_sem)) {
+ if (ec_mutex_lock_interruptible(&master->master_mutex)) {
ret = -EINTR;
goto out_return;
}
@@ -2098,11 +2115,55 @@
data.watchdog_divider, data.watchdog_intervals);
out_up:
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
out_return:
return ret;
}
+
+/*****************************************************************************/
+
+/** Configure wether a slave allows overlapping PDOs.
+ */
+int ec_cdev_ioctl_sc_allow_overlapping_pdos(
+ ec_master_t *master, /**< EtherCAT master. */
+ unsigned long arg, /**< ioctl() argument. */
+ ec_cdev_priv_t *priv /**< Private data structure of file handle. */
+ )
+{
+ ec_ioctl_config_t data;
+ ec_slave_config_t *sc;
+ int ret = 0;
+
+ if (unlikely(!priv->requested)) {
+ ret = -EPERM;
+ goto out_return;
+ }
+
+ if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+ ret = -EFAULT;
+ goto out_return;
+ }
+
+ if (ec_mutex_lock_interruptible(&master->master_mutex)) {
+ ret = -EINTR;
+ goto out_return;
+ }
+
+ if (!(sc = ec_master_get_config(master, data.config_index))) {
+ ret = -ENOENT;
+ goto out_up;
+ }
+
+ ecrt_slave_config_overlapping_pdos(sc,
+ data.allow_overlapping_pdos);
+
+out_up:
+ ec_mutex_unlock(&master->master_mutex);
+out_return:
+ return ret;
+}
+
/*****************************************************************************/
/** Add a PDO to the assignment.
@@ -2122,15 +2183,15 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem); // FIXME
+ ec_mutex_unlock(&master->master_mutex); // FIXME
return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
}
@@ -2154,15 +2215,15 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem); // FIXME
+ ec_mutex_unlock(&master->master_mutex); // FIXME
ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
return 0;
@@ -2187,15 +2248,15 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem); // FIXME
+ ec_mutex_unlock(&master->master_mutex); // FIXME
return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
data.entry_index, data.entry_subindex, data.entry_bit_length);
@@ -2220,15 +2281,15 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem); // FIXME
+ ec_mutex_unlock(&master->master_mutex); // FIXME
ecrt_slave_config_pdo_mapping_clear(sc, data.index);
return 0;
@@ -2255,20 +2316,20 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(domain = ec_master_find_domain(master, data.domain_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem); // FIXME
+ ec_mutex_unlock(&master->master_mutex); // FIXME
ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
data.entry_subindex, domain, &data.bit_position);
@@ -2298,11 +2359,11 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
@@ -2312,7 +2373,7 @@
data.dc_sync[1].cycle_time,
data.dc_sync[1].shift_time);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return 0;
}
@@ -2350,18 +2411,18 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem)) {
+ if (ec_mutex_lock_interruptible(&master->master_mutex)) {
kfree(sdo_data);
return -EINTR;
}
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
kfree(sdo_data);
return -ENOENT;
}
- up(&master->master_sem); // FIXME
+ ec_mutex_unlock(&master->master_mutex); // FIXME
if (data.complete_access) {
ret = ecrt_slave_config_complete_sdo(sc,
@@ -2397,12 +2458,12 @@
data.request_index = 0;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
sc = ec_master_get_config(master, data.config_index);
if (!sc) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
@@ -2410,7 +2471,7 @@
data.request_index++;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
data.sdo_subindex, data.size);
@@ -2446,12 +2507,12 @@
data.voe_index = 0;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
sc = ec_master_get_config(master, data.config_index);
if (!sc) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
@@ -2459,7 +2520,7 @@
data.voe_index++;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
if (IS_ERR(voe))
@@ -2492,17 +2553,17 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config_const(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
ecrt_slave_config_state(sc, &state);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
return -EFAULT;
@@ -2543,18 +2604,18 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem)) {
+ if (ec_mutex_lock_interruptible(&master->master_mutex)) {
kfree(data);
return -EINTR;
}
if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
kfree(data);
return -ENOENT;
}
- up(&master->master_sem); // FIXME
+ ec_mutex_unlock(&master->master_mutex); // FIXME
ret = ecrt_slave_config_idn(
sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
@@ -2578,19 +2639,19 @@
if (unlikely(!priv->requested))
return -EPERM;
- if (down_interruptible(&master->master_sem)) {
+ if (ec_mutex_lock_interruptible(&master->master_mutex)) {
return -EINTR;
}
list_for_each_entry(domain, &master->domains, list) {
if (domain->index == arg) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return offset;
}
offset += ecrt_domain_size(domain);
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
@@ -2609,16 +2670,16 @@
if (unlikely(!priv->requested))
return -EPERM;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(domain = ec_master_find_domain(master, arg))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
ecrt_domain_process(domain);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return 0;
}
@@ -2637,16 +2698,16 @@
if (unlikely(!priv->requested))
return -EPERM;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(domain = ec_master_find_domain(master, arg))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
ecrt_domain_queue(domain);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return 0;
}
@@ -2671,17 +2732,17 @@
return -EFAULT;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
ecrt_domain_state(domain, &state);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
return -EFAULT;
@@ -2709,20 +2770,20 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
ecrt_sdo_request_timeout(req, data.timeout);
return 0;
@@ -2748,16 +2809,16 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
@@ -2767,7 +2828,7 @@
else
data.size = 0;
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
return -EFAULT;
@@ -2795,20 +2856,20 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
ecrt_sdo_request_read(req);
return 0;
@@ -2840,20 +2901,20 @@
return -EINVAL;
}
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
ret = ec_sdo_request_alloc(req, data.size);
if (ret)
@@ -2887,20 +2948,20 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
ecrt_sdo_request_data_size(req)))
@@ -2937,20 +2998,20 @@
if (get_user(vendor_type, data.vendor_type))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
return 0;
@@ -2978,22 +3039,22 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (likely(data.vendor_id))
if (put_user(vendor_id, data.vendor_id))
@@ -3026,20 +3087,20 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
ecrt_voe_handler_read(voe);
return 0;
@@ -3065,20 +3126,20 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
ecrt_voe_handler_read_nosync(voe);
return 0;
@@ -3104,20 +3165,20 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (data.size) {
if (data.size > ec_voe_handler_mem_size(voe))
@@ -3152,20 +3213,20 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
data.state = ecrt_voe_handler_execute(voe);
if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
@@ -3199,20 +3260,20 @@
if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
return -EFAULT;
- if (down_interruptible(&master->master_sem))
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
return -EINTR;
if (!(sc = ec_master_get_config(master, data.config_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
return -ENOENT;
}
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
ecrt_voe_handler_data_size(voe)))
@@ -3231,74 +3292,70 @@
)
{
ec_ioctl_slave_foe_t data;
- ec_master_foe_request_t request;
+ ec_master_foe_request_t* request;
int retval;
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
return -EFAULT;
}
- ec_foe_request_init(&request.req, data.file_name);
- ec_foe_request_read(&request.req);
- ec_foe_request_alloc(&request.req, 10000); // FIXME
-
- 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_foe_request_init(&request->req, data.file_name);
+ ec_foe_request_read(&request->req);
+ ec_foe_request_alloc(&request->req, 10000); // FIXME
+
+ if (ec_mutex_lock_interruptible(&master->master_mutex)) {
+ kref_put(&request->refcount,ec_master_foe_request_release);
+ return -EINTR;
+ }
+ if (!(request->slave = ec_master_find_slave(
master, 0, data.slave_position))) {
- up(&master->master_sem);
- ec_foe_request_clear(&request.req);
+ ec_mutex_unlock(&master->master_mutex);
+ kref_put(&request->refcount,ec_master_foe_request_release);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
return -EINVAL;
}
// schedule request.
- list_add_tail(&request.list, &request.slave->foe_requests);
-
- up(&master->master_sem);
-
- EC_SLAVE_DBG(request.slave, 1, "Scheduled FoE read request.\n");
+ list_add_tail(&request->list, &request->slave->foe_requests);
+ kref_get(&request->refcount);
+
+ ec_mutex_unlock(&master->master_mutex);
+
+ EC_SLAVE_DBG(request->slave, 1, "Scheduled FoE read request %p.\n",request);
// wait for processing through FSM
- if (wait_event_interruptible(request.slave->foe_queue,
- request.req.state != EC_INT_REQUEST_QUEUED)) {
+ if (wait_event_interruptible(request->slave->foe_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_foe_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->foe_queue,
- request.req.state != EC_INT_REQUEST_BUSY);
-
- data.result = request.req.result;
- data.error_code = request.req.error_code;
-
- EC_SLAVE_DBG(request.slave, 1, "Read %zd bytes via FoE"
- " (result = 0x%x).\n", request.req.data_size, request.req.result);
-
- if (request.req.state != EC_INT_REQUEST_SUCCESS) {
+ kref_put(&request->refcount,ec_master_foe_request_release);
+ return -EINTR;
+ }
+
+ data.result = request->req.result;
+ data.error_code = request->req.error_code;
+
+ EC_SLAVE_DBG(request->slave, 1, "Read %zd bytes via FoE"
+ " (result = 0x%x).\n", request->req.data_size, request->req.result);
+
+ if (request->req.state != EC_INT_REQUEST_SUCCESS) {
data.data_size = 0;
retval = -EIO;
} else {
- if (request.req.data_size > data.buffer_size) {
+ if (request->req.data_size > data.buffer_size) {
EC_MASTER_ERR(master, "Buffer too small.\n");
- ec_foe_request_clear(&request.req);
+ kref_put(&request->refcount,ec_master_foe_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.buffer,
- request.req.buffer, data.data_size)) {
- ec_foe_request_clear(&request.req);
+ request->req.buffer, data.data_size)) {
+ kref_put(&request->refcount,ec_master_foe_request_release);
return -EFAULT;
}
retval = 0;
@@ -3308,9 +3365,8 @@
retval = -EFAULT;
}
- EC_SLAVE_DBG(request.slave, 1, "Finished FoE read request.\n");
-
- ec_foe_request_clear(&request.req);
+ EC_SLAVE_DBG(request->slave, 1, "Finished FoE read request %p.\n",request);
+ kref_put(&request->refcount,ec_master_foe_request_release);
return retval;
}
@@ -3325,79 +3381,73 @@
)
{
ec_ioctl_slave_foe_t data;
- ec_master_foe_request_t request;
+ ec_master_foe_request_t* request;
int retval;
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
return -EFAULT;
}
- INIT_LIST_HEAD(&request.list);
-
- ec_foe_request_init(&request.req, data.file_name);
-
- if (ec_foe_request_alloc(&request.req, data.buffer_size)) {
- ec_foe_request_clear(&request.req);
+ request = kmalloc(sizeof(*request), GFP_KERNEL);
+ if (!request)
return -ENOMEM;
- }
- if (copy_from_user(request.req.buffer,
+ kref_init(&request->refcount);
+
+ INIT_LIST_HEAD(&request->list);
+
+ ec_foe_request_init(&request->req, data.file_name);
+
+ if (ec_foe_request_alloc(&request->req, data.buffer_size)) {
+ kref_put(&request->refcount,ec_master_foe_request_release);
+ return -ENOMEM;
+ }
+ if (copy_from_user(request->req.buffer,
(void __user *) data.buffer, data.buffer_size)) {
- ec_foe_request_clear(&request.req);
- return -EFAULT;
- }
- request.req.data_size = data.buffer_size;
- ec_foe_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_foe_request_release);
+ return -EFAULT;
+ }
+ request->req.data_size = data.buffer_size;
+ ec_foe_request_write(&request->req);
+
+ if (ec_mutex_lock_interruptible(&master->master_mutex))
+ return -EINTR;
+
+ if (!(request->slave = ec_master_find_slave(
master, 0, data.slave_position))) {
- up(&master->master_sem);
+ ec_mutex_unlock(&master->master_mutex);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
data.slave_position);
- ec_foe_request_clear(&request.req);
- return -EINVAL;
- }
-
- EC_SLAVE_DBG(request.slave, 1, "Scheduling FoE write request.\n");
+ kref_put(&request->refcount,ec_master_foe_request_release);
+ return -EINVAL;
+ }
+
+ EC_SLAVE_DBG(request->slave, 1, "Scheduling FoE write request %p.\n",request);
// schedule FoE write request.
- list_add_tail(&request.list, &request.slave->foe_requests);
-
- up(&master->master_sem);
+ list_add_tail(&request->list, &request->slave->foe_requests);
+ kref_get(&request->refcount);
+
+ ec_mutex_unlock(&master->master_mutex);
// wait for processing through FSM
- if (wait_event_interruptible(request.slave->foe_queue,
- request.req.state != EC_INT_REQUEST_QUEUED)) {
+ if (wait_event_interruptible(request->slave->foe_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) {
- // abort request
- list_del(&request.list);
- up(&master->master_sem);
- ec_foe_request_clear(&request.req);
- return -EINTR;
- }
- up(&master->master_sem);
- }
-
- // wait until master FSM has finished processing
- wait_event(request.slave->foe_queue,
- request.req.state != EC_INT_REQUEST_BUSY);
-
- data.result = request.req.result;
- data.error_code = request.req.error_code;
-
- retval = request.req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
+ kref_put(&request->refcount,ec_master_foe_request_release);
+ return -EINTR;
+ }
+
+ data.result = request->req.result;
+ data.error_code = request->req.error_code;
+
+ retval = request->req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
retval = -EFAULT;
}
- ec_foe_request_clear(&request.req);
-
- EC_SLAVE_DBG(request.slave, 1, "Finished FoE write request.\n");
+ EC_SLAVE_DBG(request->slave, 1, "Finished FoE write request %p.\n",request);
+ kref_put(&request->refcount,ec_master_foe_request_release);
return retval;
}
@@ -3670,6 +3720,8 @@
return ec_cdev_ioctl_receive(master, arg, priv);
case EC_IOCTL_MASTER_STATE:
return ec_cdev_ioctl_master_state(master, arg, priv);
+ case EC_IOCTL_MASTER_SC_STATE:
+ return ec_cdev_ioctl_master_sc_state(master, arg, priv);
case EC_IOCTL_APP_TIME:
if (!(filp->f_mode & FMODE_WRITE))
return -EPERM;
@@ -3702,6 +3754,10 @@
if (!(filp->f_mode & FMODE_WRITE))
return -EPERM;
return ec_cdev_ioctl_sc_watchdog(master, arg, priv);
+ case EC_IOCTL_SC_OVERLAPPING_IO:
+ if (!(filp->f_mode & FMODE_WRITE))
+ return -EPERM;
+ return ec_cdev_ioctl_sc_allow_overlapping_pdos(master,arg,priv);
case EC_IOCTL_SC_ADD_PDO:
if (!(filp->f_mode & FMODE_WRITE))
return -EPERM;