use rt_mutex instead of semaphore for mutual exclusion (use --enable-mutex)
authorMartin Troxler <ch1010277@ch10pc446>
Wed, 05 Jan 2011 08:36:53 +0100
changeset 2028 55854f070c4a
parent 2027 ac35f4d38a31
child 2029 5ef6507fc77a
use rt_mutex instead of semaphore for mutual exclusion (use --enable-mutex)
configure.ac
master/cdev.c
master/device.c
master/domain.c
master/ethernet.c
master/ethernet.h
master/fsm_master.c
master/globals.h
master/master.c
master/master.h
master/module.c
master/slave_config.c
tty/module.c
--- a/configure.ac	Thu Dec 23 09:48:56 2010 +0100
+++ b/configure.ac	Wed Jan 05 08:36:53 2011 +0100
@@ -537,6 +537,31 @@
 fi
 
 #------------------------------------------------------------------------------
+# use mutexes instead of semaphores
+#------------------------------------------------------------------------------
+
+AC_ARG_ENABLE([mutex],
+    AS_HELP_STRING([--enable-mutex],
+                   [Use mutex instead of semaphores for mutual exclusion (default: no)]),
+    [
+        case "${enableval}" in
+            yes) mutex=1
+                ;;
+            no) mutex=0
+                ;;
+            *) AC_MSG_ERROR([Invalid value for --enable-mutex])
+                ;;
+        esac
+    ],
+    [mutex=0]
+)
+
+if test "x${mutex}" = "x1"; then
+    AC_DEFINE([EC_USE_MUTEX], [1], [Use mutex for mutual exclusion])
+fi
+
+
+#------------------------------------------------------------------------------
 # Command-line tool
 #-----------------------------------------------------------------------------
 
--- a/master/cdev.c	Thu Dec 23 09:48:56 2010 +0100
+++ b/master/cdev.c	Wed Jan 05 08:36:53 2011 +0100
@@ -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,11 +529,11 @@
         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;
     }
@@ -545,7 +545,7 @@
     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;
@@ -570,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);
@@ -596,7 +596,7 @@
     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;
@@ -620,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;
@@ -639,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;
 }
 
@@ -688,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;
@@ -701,7 +701,7 @@
 
     ec_slave_request_state(slave, data.al_state);
 
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
     return 0;
 }
 
@@ -722,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;
@@ -735,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;
     }
@@ -744,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;
@@ -770,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;
@@ -784,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;
@@ -800,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;
@@ -822,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;
@@ -857,13 +857,13 @@
         data.sdo_index, data.sdo_entry_subindex);
     ecrt_sdo_request_read(&request->req);
 
-    if (down_interruptible(&master->master_sem))  {
+    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);
         kref_put(&request->refcount,ec_master_sdo_request_release);
         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
                 data.slave_position);
@@ -876,7 +876,7 @@
     kref_get(&request->refcount);
     list_add_tail(&request->list, &request->slave->slave_sdo_requests);
 
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 
     // wait for processing through FSM
     if (wait_event_interruptible(request->slave->sdo_queue,
@@ -964,13 +964,13 @@
     request->req.data_size = data.data_size;
     ecrt_sdo_request_write(&request->req);
 
-    if (down_interruptible(&master->master_sem)) {
+    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);
         kref_put(&request->refcount,ec_master_sdo_request_release);
@@ -983,7 +983,7 @@
     kref_get(&request->refcount);
     list_add_tail(&request->list, &request->slave->slave_sdo_requests);
 
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 
     // wait for processing through FSM
     if (wait_event_interruptible(request->slave->sdo_queue,
@@ -1030,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;
@@ -1043,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;
@@ -1055,7 +1055,7 @@
     else
         retval = 0;
 
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
     return retval;
 }
 
@@ -1094,12 +1094,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);
         kfree(words);
@@ -1117,21 +1117,21 @@
     // schedule SII write request.
     list_add_tail(&request.list, &master->sii_requests);
 
-    up(&master->master_sem);
+    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);
+        ec_mutex_lock(&master->master_mutex);
         if (request.state == EC_INT_REQUEST_QUEUED) {
             // abort request
             list_del(&request.list);
-            up(&master->master_sem);
+            ec_mutex_unlock(&master->master_mutex);
             kfree(words);
             return -EINTR;
         }
-        up(&master->master_sem);
+        ec_mutex_unlock(&master->master_mutex);
     }
 
     // wait until master FSM has finished processing
@@ -1169,12 +1169,12 @@
         return -ENOMEM;
     }
 
-    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;
@@ -1192,21 +1192,21 @@
     // schedule request.
     list_add_tail(&request.list, &master->reg_requests);
 
-    up(&master->master_sem);
+    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);
+        ec_mutex_lock(&master->master_mutex);
         if (request.state == EC_INT_REQUEST_QUEUED) {
             // abort request
             list_del(&request.list);
-            up(&master->master_sem);
+            ec_mutex_unlock(&master->master_mutex);
             kfree(contents);
             return -EINTR;
         }
-        up(&master->master_sem);
+        ec_mutex_unlock(&master->master_mutex);
     }
 
     // wait until master FSM has finished processing
@@ -1253,12 +1253,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);
         kfree(contents);
@@ -1277,21 +1277,21 @@
     // schedule request.
     list_add_tail(&request.list, &master->reg_requests);
 
-    up(&master->master_sem);
+    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);
+        ec_mutex_lock(&master->master_mutex);
         if (request.state == EC_INT_REQUEST_QUEUED) {
             // abort request
             list_del(&request.list);
-            up(&master->master_sem);
+            ec_mutex_unlock(&master->master_mutex);
             kfree(contents);
             return -EINTR;
         }
-        up(&master->master_sem);
+        ec_mutex_unlock(&master->master_mutex);
     }
 
     // wait until master FSM has finished processing
@@ -1319,12 +1319,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;
@@ -1350,7 +1350,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;
@@ -1381,12 +1381,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;
@@ -1395,7 +1395,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;
     }
@@ -1404,7 +1404,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;
@@ -1436,12 +1436,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;
@@ -1450,14 +1450,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;
     }
@@ -1467,7 +1467,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;
@@ -1492,12 +1492,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;
@@ -1505,7 +1505,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;
     }
@@ -1516,7 +1516,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;
@@ -1541,12 +1541,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;
@@ -1554,7 +1554,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;
     }
@@ -1566,7 +1566,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;
@@ -1592,11 +1592,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;
@@ -1616,7 +1616,7 @@
     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;
@@ -1698,7 +1698,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) {
@@ -1707,7 +1707,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;
@@ -1736,14 +1736,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);
@@ -1806,10 +1806,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;
 }
@@ -1828,9 +1828,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;
 }
 
@@ -1847,9 +1847,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;
 }
 
@@ -1935,9 +1935,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;
 }
 
@@ -1954,9 +1954,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;
 }
 
@@ -1973,9 +1973,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;
 }
 
@@ -1994,9 +1994,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;
@@ -2029,7 +2029,7 @@
         goto out_return;
     }
 
-    if (down_interruptible(&master->master_sem)) {
+    if (ec_mutex_lock_interruptible(&master->master_mutex)) {
         ret = -EINTR;
         goto out_return;
     }
@@ -2050,7 +2050,7 @@
     }
 
 out_up:
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 out_return:
     return ret;
 }
@@ -2079,7 +2079,7 @@
         goto out_return;
     }
 
-    if (down_interruptible(&master->master_sem)) {
+    if (ec_mutex_lock_interruptible(&master->master_mutex)) {
         ret = -EINTR;
         goto out_return;
     }
@@ -2093,7 +2093,7 @@
             data.watchdog_divider, data.watchdog_intervals);
 
 out_up:
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 out_return:
     return ret;
 }
@@ -2123,7 +2123,7 @@
         goto out_return;
     }
 
-    if (down_interruptible(&master->master_sem)) {
+    if (ec_mutex_lock_interruptible(&master->master_mutex)) {
         ret = -EINTR;
         goto out_return;
     }
@@ -2137,7 +2137,7 @@
             data.allow_overlapping_pdos);
 
 out_up:
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 out_return:
     return ret;
 }
@@ -2161,15 +2161,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);
 }
@@ -2193,15 +2193,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;
@@ -2226,15 +2226,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);
@@ -2259,15 +2259,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;
@@ -2294,20 +2294,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);
@@ -2337,11 +2337,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;
     }
 
@@ -2351,7 +2351,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;
 }
@@ -2389,18 +2389,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,
@@ -2436,12 +2436,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;
     }
 
@@ -2449,7 +2449,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);
@@ -2485,12 +2485,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;
     }
 
@@ -2498,7 +2498,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))
@@ -2531,17 +2531,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;
@@ -2582,18 +2582,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);
@@ -2617,19 +2617,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;
 }
 
@@ -2648,16 +2648,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;
 }
 
@@ -2676,16 +2676,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;
 }
 
@@ -2710,17 +2710,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;
@@ -2748,20 +2748,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;
@@ -2787,16 +2787,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;
     }
 
@@ -2806,7 +2806,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;
@@ -2834,20 +2834,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;
@@ -2879,20 +2879,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)
@@ -2926,20 +2926,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)))
@@ -2976,20 +2976,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;
@@ -3017,22 +3017,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))
@@ -3065,20 +3065,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;
@@ -3104,20 +3104,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;
@@ -3143,20 +3143,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))
@@ -3191,20 +3191,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)
@@ -3238,20 +3238,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)))
@@ -3281,12 +3281,12 @@
     ec_foe_request_read(&request.req);
     ec_foe_request_alloc(&request.req, 10000); // FIXME
 
-    if (down_interruptible(&master->master_sem))
+    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_foe_request_clear(&request.req);
         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
                 data.slave_position);
@@ -3296,7 +3296,7 @@
     // schedule request.
     list_add_tail(&request.list, &request.slave->foe_requests);
 
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 
     EC_SLAVE_DBG(request.slave, 1, "Scheduled FoE read request.\n");
 
@@ -3304,15 +3304,15 @@
     if (wait_event_interruptible(request.slave->foe_queue,
                 request.req.state != EC_INT_REQUEST_QUEUED)) {
         // interrupted by signal
-        down(&master->master_sem);
+        ec_mutex_lock(&master->master_mutex);
         if (request.req.state == EC_INT_REQUEST_QUEUED) {
             list_del(&request.list);
-            up(&master->master_sem);
+            ec_mutex_unlock(&master->master_mutex);
             ec_foe_request_clear(&request.req);
             return -EINTR;
         }
         // request already processing: interrupt not possible.
-        up(&master->master_sem);
+        ec_mutex_unlock(&master->master_mutex);
     }
 
     // wait until master FSM has finished processing
@@ -3387,12 +3387,12 @@
     request.req.data_size = data.buffer_size;
     ec_foe_request_write(&request.req);
 
-    if (down_interruptible(&master->master_sem))
+    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);
@@ -3404,21 +3404,21 @@
     // schedule FoE write request.
     list_add_tail(&request.list, &request.slave->foe_requests);
 
-    up(&master->master_sem);
+    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)) {
         // interrupted by signal
-        down(&master->master_sem);
+        ec_mutex_lock(&master->master_mutex);
         if (request.req.state == EC_INT_REQUEST_QUEUED) {
             // abort request
             list_del(&request.list);
-            up(&master->master_sem);
+            ec_mutex_unlock(&master->master_mutex);
             ec_foe_request_clear(&request.req);
             return -EINTR;
         }
-        up(&master->master_sem);
+        ec_mutex_unlock(&master->master_mutex);
     }
 
     // wait until master FSM has finished processing
--- a/master/device.c	Thu Dec 23 09:48:56 2010 +0100
+++ b/master/device.c	Wed Jan 05 08:36:53 2011 +0100
@@ -501,9 +501,9 @@
     ec_mac_print(device->dev->dev_addr, str);
     EC_MASTER_INFO(master, "Releasing main device %s.\n", str);
     
-    down(&master->device_sem);
+    ec_mutex_lock(&master->device_mutex);
     ec_device_detach(device);
-    up(&master->device_sem);
+    ec_mutex_unlock(&master->device_mutex);
 }
 
 /*****************************************************************************/
--- a/master/domain.c	Thu Dec 23 09:48:56 2010 +0100
+++ b/master/domain.c	Wed Jan 05 08:36:53 2011 +0100
@@ -381,14 +381,14 @@
     EC_MASTER_DBG(domain->master, 1, "ecrt_domain_external_memory("
             "domain = 0x%p, mem = 0x%p)\n", domain, mem);
 
-    down(&domain->master->master_sem);
+    ec_mutex_lock(&domain->master->master_mutex);
 
     ec_domain_clear_data(domain);
 
     domain->data = mem;
     domain->data_origin = EC_ORIG_EXTERNAL;
 
-    up(&domain->master->master_sem);
+    ec_mutex_unlock(&domain->master->master_mutex);
 }
 
 /*****************************************************************************/
--- a/master/ethernet.c	Thu Dec 23 09:48:56 2010 +0100
+++ b/master/ethernet.c	Wed Jan 05 08:36:53 2011 +0100
@@ -122,7 +122,7 @@
     eoe->tx_queue_size = EC_EOE_TX_QUEUE_SIZE;
     eoe->tx_queued_frames = 0;
 
-    sema_init(&eoe->tx_queue_sem, 1);
+    ec_mutex_init(&eoe->tx_queue_mutex);
     eoe->tx_frame_number = 0xFF;
     memset(&eoe->stats, 0, sizeof(struct net_device_stats));
 
@@ -231,7 +231,7 @@
 {
     ec_eoe_frame_t *frame, *next;
 
-    down(&eoe->tx_queue_sem);
+    ec_mutex_lock(&eoe->tx_queue_mutex);
 
     list_for_each_entry_safe(frame, next, &eoe->tx_queue, queue) {
         list_del(&frame->queue);
@@ -240,7 +240,7 @@
     }
     eoe->tx_queued_frames = 0;
 
-    up(&eoe->tx_queue_sem);
+    ec_mutex_unlock(&eoe->tx_queue_mutex);
 }
 
 /*****************************************************************************/
@@ -621,10 +621,10 @@
         return;
     }
 
-    down(&eoe->tx_queue_sem);
+    ec_mutex_lock(&eoe->tx_queue_mutex);
 
     if (!eoe->tx_queued_frames || list_empty(&eoe->tx_queue)) {
-        up(&eoe->tx_queue_sem);
+        ec_mutex_unlock(&eoe->tx_queue_mutex);
         eoe->tx_idle = 1;
         // no data available.
         // start a new receive immediately.
@@ -645,7 +645,7 @@
     }
 
     eoe->tx_queued_frames--;
-    up(&eoe->tx_queue_sem);
+    ec_mutex_unlock(&eoe->tx_queue_mutex);
 
     eoe->tx_idle = 0;
 
@@ -813,14 +813,14 @@
 
     frame->skb = skb;
 
-    down(&eoe->tx_queue_sem);
+    ec_mutex_lock(&eoe->tx_queue_mutex);
     list_add_tail(&frame->queue, &eoe->tx_queue);
     eoe->tx_queued_frames++;
     if (eoe->tx_queued_frames == eoe->tx_queue_size) {
         netif_stop_queue(dev);
         eoe->tx_queue_active = 0;
     }
-    up(&eoe->tx_queue_sem);
+    ec_mutex_unlock(&eoe->tx_queue_mutex);
 
 #if EOE_DEBUG_LEVEL >= 2
     EC_SLAVE_DBG(eoe->slave, 0, "EoE %s TX queued frame"
--- a/master/ethernet.h	Thu Dec 23 09:48:56 2010 +0100
+++ b/master/ethernet.h	Wed Jan 05 08:36:53 2011 +0100
@@ -92,7 +92,7 @@
     unsigned int tx_queue_size; /**< Transmit queue size. */
     unsigned int tx_queue_active; /**< kernel netif queue started */
     unsigned int tx_queued_frames; /**< number of frames in the queue */
-    struct semaphore tx_queue_sem; /**< Semaphore for the send queue. */
+    struct ec_mutex_t tx_queue_mutex; /**< Mutex for the send queue. */
     ec_eoe_frame_t *tx_frame; /**< current TX frame */
     uint8_t tx_frame_number; /**< number of the transmitted frame */
     uint8_t tx_fragment_number; /**< number of the fragment */
--- a/master/fsm_master.c	Thu Dec 23 09:48:56 2010 +0100
+++ b/master/fsm_master.c	Wed Jan 05 08:36:53 2011 +0100
@@ -238,12 +238,12 @@
     }
 
     if (fsm->rescan_required) {
-        down(&master->scan_sem);
+        ec_mutex_lock(&master->scan_mutex);
         if (!master->allow_scan) {
-            up(&master->scan_sem);
+            ec_mutex_unlock(&master->scan_mutex);
         } else {
             master->scan_busy = 1;
-            up(&master->scan_sem);
+            ec_mutex_unlock(&master->scan_mutex);
 
             // clear all slaves and scan the bus
             fsm->rescan_required = 0;
@@ -570,12 +570,12 @@
                 || slave->force_config) && !slave->error_flag) {
 
         // Start slave configuration, if it is allowed.
-        down(&master->config_sem);
+        ec_mutex_lock(&master->config_mutex);
         if (!master->allow_config) {
-            up(&master->config_sem);
+            ec_mutex_unlock(&master->config_mutex);
         } else {
             master->config_busy = 1;
-            up(&master->config_sem);
+            ec_mutex_unlock(&master->config_mutex);
 
             if (master->debug_level) {
                 char old_state[EC_STATE_STRING_SIZE],
--- a/master/globals.h	Thu Dec 23 09:48:56 2010 +0100
+++ b/master/globals.h	Wed Jan 05 08:36:53 2011 +0100
@@ -39,6 +39,12 @@
 #include "../globals.h"
 #include "../include/ecrt.h"
 
+#ifdef __KERNEL__
+#ifdef EC_USE_MUTEX
+#include <linux/rtmutex.h>
+#endif  // EC_USE_MUTEX
+#endif // __KERNEL__
+
 /******************************************************************************
  * EtherCAT master
  *****************************************************************************/
@@ -305,4 +311,60 @@
 
 /*****************************************************************************/
 
+/*****************************************************************************/
+
+#ifdef __KERNEL__
+
+/** Mutual exclusion helpers.
+ *
+ */
+#ifdef EC_USE_MUTEX
+#define ec_mutex_t rt_mutex
+static inline void ec_mutex_init(struct ec_mutex_t *mutex)
+{
+    rt_mutex_init(mutex);
+}
+static inline void ec_mutex_lock(struct ec_mutex_t *mutex)
+{
+    rt_mutex_lock(mutex);
+}
+static inline int ec_mutex_trylock(struct ec_mutex_t *mutex)
+{
+    return rt_mutex_trylock(mutex);
+}
+static inline int ec_mutex_lock_interruptible(struct ec_mutex_t *mutex)
+{
+    return rt_mutex_lock_interruptible(mutex,0);
+}
+static inline void ec_mutex_unlock(struct ec_mutex_t *mutex)
+{
+    rt_mutex_unlock(mutex);
+}
+#else   // EC_USE_MUTEX
+#define ec_mutex_t semaphore
+static inline void ec_mutex_init(struct ec_mutex_t *sem)
+{
+    sema_init(sem, 1);
+}
+static inline void ec_mutex_lock(struct ec_mutex_t *sem)
+{
+    down(sem);
+}
+static inline int ec_mutex_trylock(struct ec_mutex_t *sem)
+{
+    down(sem);
+    return 1;
+}
+static inline int ec_mutex_lock_interruptible(struct ec_mutex_t *sem)
+{
+    return down_interruptible(sem);
+}
+static inline void ec_mutex_unlock(struct ec_mutex_t *sem)
+{
+    up(sem);
+}
+
+#endif // EC_USE_MUTEX
+#endif // __KERNEL__
+
 #endif
--- a/master/master.c	Thu Dec 23 09:48:56 2010 +0100
+++ b/master/master.c	Wed Jan 05 08:36:53 2011 +0100
@@ -130,12 +130,12 @@
     master->index = index;
     master->reserved = 0;
 
-    sema_init(&master->master_sem, 1);
+    ec_mutex_init(&master->master_mutex);
 
     master->main_mac = main_mac;
     master->backup_mac = backup_mac;
 
-    sema_init(&master->device_sem, 1);
+    ec_mutex_init(&master->device_mutex);
 
     master->phase = EC_ORPHANED;
     master->active = 0;
@@ -158,18 +158,18 @@
 
     master->scan_busy = 0;
     master->allow_scan = 1;
-    sema_init(&master->scan_sem, 1);
+    ec_mutex_init(&master->scan_mutex);
     init_waitqueue_head(&master->scan_queue);
 
     master->config_busy = 0;
     master->allow_config = 1;
-    sema_init(&master->config_sem, 1);
+    ec_mutex_init(&master->config_mutex);
     init_waitqueue_head(&master->config_queue);
     
     INIT_LIST_HEAD(&master->datagram_queue);
     master->datagram_index = 0;
 
-    sema_init(&master->fsm_queue_sem, 1);
+    ec_mutex_init(&master->fsm_queue_mutex);
     INIT_LIST_HEAD(&master->fsm_datagram_queue);
     
     // send interval in IDLE phase
@@ -190,7 +190,7 @@
     INIT_LIST_HEAD(&master->eoe_handlers);
 #endif
 
-    sema_init(&master->io_sem, 1);
+    ec_mutex_init(&master->io_mutex);
     master->fsm_queue_lock_cb = NULL;
     master->fsm_queue_unlock_cb = NULL;
     master->fsm_queue_locking_data = NULL;
@@ -447,10 +447,10 @@
         ec_master_t *master /**< EtherCAT master. */
         )
 {
-    down(&master->master_sem);
+    ec_mutex_lock(&master->master_mutex);
     ec_master_clear_domains(master);
     ec_master_clear_slave_configs(master);
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 }
 
 /*****************************************************************************/
@@ -545,9 +545,9 @@
     
     ec_master_thread_stop(master);
 
-    down(&master->master_sem);
+    ec_mutex_lock(&master->master_mutex);
     ec_master_clear_slaves(master);
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 }
 
 /*****************************************************************************/
@@ -564,10 +564,10 @@
 
     EC_MASTER_DBG(master, 1, "IDLE -> OPERATION.\n");
 
-    down(&master->config_sem);
+    ec_mutex_lock(&master->config_mutex);
     master->allow_config = 0; // temporarily disable slave configuration
     if (master->config_busy) {
-        up(&master->config_sem);
+        ec_mutex_unlock(&master->config_mutex);
 
         // wait for slave configuration to complete
         ret = wait_event_interruptible(master->config_queue,
@@ -581,15 +581,15 @@
         EC_MASTER_DBG(master, 1, "Waiting for pending slave"
                 " configuration returned.\n");
     } else {
-        up(&master->config_sem);
-    }
-
-    down(&master->scan_sem);
+        ec_mutex_unlock(&master->config_mutex);
+    }
+
+    ec_mutex_lock(&master->scan_mutex);
     master->allow_scan = 0; // 'lock' the slave list
     if (!master->scan_busy) {
-        up(&master->scan_sem);
+        ec_mutex_unlock(&master->scan_mutex);
     } else {
-        up(&master->scan_sem);
+        ec_mutex_unlock(&master->scan_mutex);
 
         // wait for slave scan to complete
         ret = wait_event_interruptible(master->scan_queue, !master->scan_busy);
@@ -662,9 +662,10 @@
 
     if (master->fsm_queue_lock_cb)
         master->fsm_queue_lock_cb(master->fsm_queue_locking_data);
-    down(&master->fsm_queue_sem);
+    if (ec_mutex_trylock(&master->fsm_queue_mutex) == 0)
+        return;
     if (list_empty(&master->fsm_datagram_queue)) {
-        up(&master->fsm_queue_sem);
+        ec_mutex_unlock(&master->fsm_queue_mutex);
         if (master->fsm_queue_unlock_cb)
             master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
         return;
@@ -736,7 +737,7 @@
             }
         }
     }
-    up(&master->fsm_queue_sem);
+    ec_mutex_unlock(&master->fsm_queue_mutex);
     if (master->fsm_queue_unlock_cb)
         master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
 }
@@ -783,14 +784,14 @@
 
     if (master->fsm_queue_lock_cb)
         master->fsm_queue_lock_cb(master->fsm_queue_locking_data);
-    down(&master->fsm_queue_sem);
+    ec_mutex_lock(&master->fsm_queue_mutex);
 
     // check, if the datagram is already queued
     list_for_each_entry(queued_datagram, &master->fsm_datagram_queue,
             queue) {
         if (queued_datagram == datagram) {
             datagram->state = EC_DATAGRAM_QUEUED;
-            up(&master->fsm_queue_sem);
+            ec_mutex_unlock(&master->fsm_queue_mutex);
             if (master->fsm_queue_unlock_cb)
                 master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
             return;
@@ -809,7 +810,7 @@
 #endif
     datagram->jiffies_sent = jiffies;
 
-    up(&master->fsm_queue_sem);
+    ec_mutex_unlock(&master->fsm_queue_mutex);
     if (master->fsm_queue_unlock_cb)
         master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
 }
@@ -1252,12 +1253,12 @@
         ec_datagram_output_stats(&master->fsm_datagram);
 
         // receive
-        down(&master->io_sem);
+        ec_mutex_lock(&master->io_mutex);
         ecrt_master_receive(master);
-        up(&master->io_sem);
+        ec_mutex_unlock(&master->io_mutex);
 
         // execute master & slave state machines
-        if (down_interruptible(&master->master_sem))
+        if (ec_mutex_lock_interruptible(&master->master_mutex))
             break;
         if (ec_fsm_master_exec(&master->fsm)) {
             ec_master_queue_fsm_datagram(master, &master->fsm_datagram);
@@ -1271,14 +1272,14 @@
         if (!ec_master_eoe_processing(master))
             master->fsm.idle = 0;  // pump the bus as fast as possible
 #endif
-        up(&master->master_sem);
+        ec_mutex_unlock(&master->master_mutex);
 
         // queue and send
-        down(&master->io_sem);
+        ec_mutex_lock(&master->io_mutex);
         ecrt_master_send(master);
         sent_bytes = master->main_device.tx_skb[
             master->main_device.tx_ring_index]->len;
-        up(&master->io_sem);
+        ec_mutex_unlock(&master->io_mutex);
 
         if (ec_fsm_master_idle(&master->fsm)) {
 #ifdef EC_USE_HRTIMER
@@ -1321,7 +1322,7 @@
         ec_master_output_stats(master);
 
         // execute master & slave state machines
-        if (down_interruptible(&master->master_sem))
+        if (ec_mutex_lock_interruptible(&master->master_mutex))
             break;
         if (ec_fsm_master_exec(&master->fsm))
             ec_master_queue_fsm_datagram(master, &master->fsm_datagram);
@@ -1333,7 +1334,7 @@
 #if defined(EC_EOE)
         ec_master_eoe_processing(master);
 #endif
-        up(&master->master_sem);
+        ec_mutex_unlock(&master->master_mutex);
 
 #ifdef EC_USE_HRTIMER
         // the op thread should not work faster than the sending RT thread
@@ -1858,7 +1859,7 @@
         return ERR_PTR(-ENOMEM);
     }
 
-    down(&master->master_sem);
+    ec_mutex_lock(&master->master_mutex);
 
     if (list_empty(&master->domains)) {
         index = 0;
@@ -1870,7 +1871,7 @@
     ec_domain_init(domain, master, index);
     list_add_tail(&domain->list, &master->domains);
 
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 
     EC_MASTER_DBG(master, 1, "Created domain %u.\n", domain->index);
 
@@ -1902,21 +1903,21 @@
         return 0;
     }
 
-    down(&master->master_sem);
+    ec_mutex_lock(&master->master_mutex);
 
     // finish all domains
     domain_offset = 0;
     list_for_each_entry(domain, &master->domains, list) {
         ret = ec_domain_finish(domain, domain_offset);
         if (ret < 0) {
-            up(&master->master_sem);
+            ec_mutex_unlock(&master->master_mutex);
             EC_MASTER_ERR(master, "Failed to finish domain 0x%p!\n", domain);
             return ret;
         }
         domain_offset += domain->data_size;
     }
     
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 
     // restart EoE process and master thread with new locking
 
@@ -2128,14 +2129,14 @@
         ec_slave_config_init(sc, master,
                 alias, position, vendor_id, product_code);
 
-        down(&master->master_sem);
+        ec_mutex_lock(&master->master_mutex);
 
         // try to find the addressed slave
         ec_slave_config_attach(sc);
         ec_slave_config_load_default_sync_config(sc);
         list_add_tail(&sc->list, &master->configs);
 
-        up(&master->master_sem);
+        ec_mutex_unlock(&master->master_mutex);
     }
 
     return sc;
@@ -2173,7 +2174,7 @@
 {
     const ec_slave_t *slave;
 
-    if (down_interruptible(&master->master_sem)) {
+    if (ec_mutex_lock_interruptible(&master->master_mutex)) {
         return -EINTR;
     }
 
@@ -2196,7 +2197,7 @@
         slave_info->name[0] = 0;
     }
 
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 
     return 0;
 }
@@ -2325,12 +2326,12 @@
     request.req.data_size = data_size;
     ec_soe_request_write(&request.req);
 
-    if (down_interruptible(&master->master_sem))
+    if (ec_mutex_lock_interruptible(&master->master_mutex))
         return -EINTR;
 
     if (!(request.slave = ec_master_find_slave(
                     master, 0, slave_position))) {
-        up(&master->master_sem);
+        ec_mutex_unlock(&master->master_mutex);
         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
                 slave_position);
         ec_soe_request_clear(&request.req);
@@ -2342,21 +2343,21 @@
     // schedule SoE write request.
     list_add_tail(&request.list, &request.slave->soe_requests);
 
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 
     // 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);
+        ec_mutex_lock(&master->master_mutex);
         if (request.req.state == EC_INT_REQUEST_QUEUED) {
             // abort request
             list_del(&request.list);
-            up(&master->master_sem);
+            ec_mutex_unlock(&master->master_mutex);
             ec_soe_request_clear(&request.req);
             return -EINTR;
         }
-        up(&master->master_sem);
+        ec_mutex_unlock(&master->master_mutex);
     }
 
     // wait until master FSM has finished processing
@@ -2391,11 +2392,11 @@
     ec_soe_request_set_idn(&request.req, idn);
     ec_soe_request_read(&request.req);
 
-    if (down_interruptible(&master->master_sem))
+    if (ec_mutex_lock_interruptible(&master->master_mutex))
         return -EINTR;
 
     if (!(request.slave = ec_master_find_slave(master, 0, slave_position))) {
-        up(&master->master_sem);
+        ec_mutex_unlock(&master->master_mutex);
         ec_soe_request_clear(&request.req);
         EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
         return -EINVAL;
@@ -2404,7 +2405,7 @@
     // schedule request.
     list_add_tail(&request.list, &request.slave->soe_requests);
 
-    up(&master->master_sem);
+    ec_mutex_unlock(&master->master_mutex);
 
     EC_SLAVE_DBG(request.slave, 1, "Scheduled SoE read request.\n");
 
@@ -2412,15 +2413,15 @@
     if (wait_event_interruptible(request.slave->soe_queue,
                 request.req.state != EC_INT_REQUEST_QUEUED)) {
         // interrupted by signal
-        down(&master->master_sem);
+        ec_mutex_lock(&master->master_mutex);
         if (request.req.state == EC_INT_REQUEST_QUEUED) {
             list_del(&request.list);
-            up(&master->master_sem);
+            ec_mutex_unlock(&master->master_mutex);
             ec_soe_request_clear(&request.req);
             return -EINTR;
         }
         // request already processing: interrupt not possible.
-        up(&master->master_sem);
+        ec_mutex_unlock(&master->master_mutex);
     }
 
     // wait until master FSM has finished processing
--- a/master/master.h	Thu Dec 23 09:48:56 2010 +0100
+++ b/master/master.h	Wed Jan 05 08:36:53 2011 +0100
@@ -43,18 +43,13 @@
 #include <linux/wait.h>
 #include <linux/kthread.h>
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
-#include <linux/semaphore.h>
-#else
-#include <asm/semaphore.h>
-#endif
-
 #include "device.h"
 #include "domain.h"
 #include "ethernet.h"
 #include "fsm_master.h"
 #include "cdev.h"
 
+
 /*****************************************************************************/
 
 /** Convenience macro for printing master-specific information to syslog.
@@ -152,13 +147,13 @@
     struct class_device *class_device; /**< Master class device. */
 #endif
 
-    struct semaphore master_sem; /**< Master semaphore. */
+    struct ec_mutex_t master_mutex; /**< Master mutex. */
 
     ec_device_t main_device; /**< EtherCAT main device. */
     const uint8_t *main_mac; /**< MAC address of main device. */
     ec_device_t backup_device; /**< EtherCAT backup device. */
     const uint8_t *backup_mac; /**< MAC address of backup device. */
-    struct semaphore device_sem; /**< Device semaphore. */
+    struct ec_mutex_t device_mutex; /**< Device mutex. */
 
     ec_fsm_master_t fsm; /**< Master state machine. */
     ec_datagram_t fsm_datagram; /**< Datagram used for state machines. */
@@ -194,7 +189,7 @@
                                             ecrt_master_sync() call.*/
     unsigned int scan_busy; /**< Current scan state. */
     unsigned int allow_scan; /**< \a True, if slave scanning is allowed. */
-    struct semaphore scan_sem; /**< Semaphore protecting the \a scan_busy
+    struct ec_mutex_t scan_mutex; /**< Mutex protecting the \a scan_busy
                                  variable and the \a allow_scan flag. */
     wait_queue_head_t scan_queue; /**< Queue for processes that wait for
                                     slave scanning. */
@@ -202,7 +197,7 @@
     unsigned int config_busy; /**< State of slave configuration. */
     unsigned int allow_config; /**< \a True, if slave configuration is
                                  allowed. */
-    struct semaphore config_sem; /**< Semaphore protecting the \a config_busy
+    struct ec_mutex_t config_mutex; /**< Mutex protecting the \a config_busy
                                    variable and the allow_config flag. */
     wait_queue_head_t config_queue; /**< Queue for processes that wait for
                                       slave configuration. */
@@ -210,7 +205,7 @@
     struct list_head datagram_queue; /**< Datagram queue. */
     uint8_t datagram_index; /**< Current datagram index. */
 
-    struct semaphore fsm_queue_sem; /**< Semaphore protecting the \a
+    struct ec_mutex_t fsm_queue_mutex; /**< Mutex protecting the \a
                                       fsm_datagram_queue. */
     struct list_head fsm_datagram_queue; /**< External Datagram queue. */
 
@@ -227,7 +222,7 @@
     struct list_head eoe_handlers; /**< Ethernet over EtherCAT handlers. */
 #endif
 
-    struct semaphore io_sem; /**< Semaphore used in \a IDLE phase. */
+    struct ec_mutex_t io_mutex; /**< Mutex used in \a IDLE phase. */
 
     void (*fsm_queue_lock_cb)(void *); /**< FSM queue lock callback. */
     void (*fsm_queue_unlock_cb)(void *); /**< FSM queue unlock callback. */
--- a/master/module.c	Thu Dec 23 09:48:56 2010 +0100
+++ b/master/module.c	Wed Jan 05 08:36:53 2011 +0100
@@ -61,7 +61,7 @@
 static unsigned int debug_level;  /**< Debug level parameter. */
 
 static ec_master_t *masters; /**< Array of masters. */
-static struct semaphore master_sem; /**< Master semaphore. */
+static struct ec_mutex_t master_mutex; /**< Master mutex. */
 
 dev_t device_number; /**< Device number for master cdevs. */
 struct class *class; /**< Device class. */
@@ -101,7 +101,7 @@
 
     EC_INFO("Master driver %s\n", EC_MASTER_VERSION);
 
-    sema_init(&master_sem, 1);
+    ec_mutex_init(&master_mutex);
 
     if (master_count) {
         if (alloc_chrdev_region(&device_number,
@@ -468,9 +468,9 @@
     for (i = 0; i < master_count; i++) {
         master = &masters[i];
 
-        down(&master->device_sem);
+        ec_mutex_lock(&master->device_mutex);
         if (master->main_device.dev) { // master already has a device
-            up(&master->device_sem);
+            ec_mutex_unlock(&master->device_mutex);
             continue;
         }
             
@@ -481,14 +481,14 @@
                     str, master->index);
 
             ec_device_attach(&master->main_device, net_dev, poll, module);
-            up(&master->device_sem);
+            ec_mutex_unlock(&master->device_mutex);
             
             snprintf(net_dev->name, IFNAMSIZ, "ec%u", master->index);
 
             return &master->main_device; // offer accepted
         }
         else {
-            up(&master->device_sem);
+            ec_mutex_unlock(&master->device_mutex);
 
             if (master->debug_level) {
                 ec_mac_print(net_dev->dev_addr, str);
@@ -524,40 +524,40 @@
     }
     master = &masters[master_index];
 
-    if (down_interruptible(&master_sem)) {
+    if (ec_mutex_lock_interruptible(&master_mutex)) {
         errptr = ERR_PTR(-EINTR);
         goto out_return;
     }
 
     if (master->reserved) {
-        up(&master_sem);
+        ec_mutex_unlock(&master_mutex);
         EC_MASTER_ERR(master, "Master already in use!\n");
         errptr = ERR_PTR(-EBUSY);
         goto out_return;
     }
     master->reserved = 1;
-    up(&master_sem);
-
-    if (down_interruptible(&master->device_sem)) {
+    ec_mutex_unlock(&master_mutex);
+
+    if (ec_mutex_lock_interruptible(&master->device_mutex)) {
         errptr = ERR_PTR(-EINTR);
         goto out_release;
     }
     
     if (master->phase != EC_IDLE) {
-        up(&master->device_sem);
+        ec_mutex_unlock(&master->device_mutex);
         EC_MASTER_ERR(master, "Master still waiting for devices!\n");
         errptr = ERR_PTR(-ENODEV);
         goto out_release;
     }
 
     if (!try_module_get(master->main_device.module)) {
-        up(&master->device_sem);
+        ec_mutex_unlock(&master->device_mutex);
         EC_ERR("Device module is unloading!\n");
         errptr = ERR_PTR(-ENODEV);
         goto out_release;
     }
 
-    up(&master->device_sem);
+    ec_mutex_unlock(&master->device_mutex);
 
     if (ec_master_enter_operation_phase(master)) {
         EC_MASTER_ERR(master, "Failed to enter OPERATION phase!\n");
--- a/master/slave_config.c	Thu Dec 23 09:48:56 2010 +0100
+++ b/master/slave_config.c	Wed Jan 05 08:36:53 2011 +0100
@@ -182,7 +182,7 @@
 
     fmmu = &sc->fmmu_configs[sc->used_fmmus];
 
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     ec_fmmu_config_init(fmmu, sc, sync_index, dir);
     fmmu_logical_start_address = domain->tx_size;
     tx_size = fmmu->data_size;
@@ -199,7 +199,7 @@
         }
     }
     ec_fmmu_config_domain(fmmu,domain,fmmu_logical_start_address,tx_size);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
 
     ++sc->used_fmmus;
     return fmmu->domain_address;
@@ -536,18 +536,18 @@
         return -EINVAL;
     }
 
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
 
     pdo = ec_pdo_list_add_pdo(&sc->sync_configs[sync_index].pdos, pdo_index);
     if (IS_ERR(pdo)) {
-        up(&sc->master->master_sem);
+        ec_mutex_unlock(&sc->master->master_mutex);
         return PTR_ERR(pdo);
     }
     pdo->sync_index = sync_index;
 
     ec_slave_config_load_default_mapping(sc, pdo);
 
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
     return 0;
 }
 
@@ -564,9 +564,9 @@
         return;
     }
 
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     ec_pdo_list_clear_pdos(&sc->sync_configs[sync_index].pdos);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
 }
 
 /*****************************************************************************/
@@ -592,10 +592,10 @@
             break;
 
     if (pdo) {
-        down(&sc->master->master_sem);
+        ec_mutex_lock(&sc->master->master_mutex);
         entry = ec_pdo_add_entry(pdo, entry_index, entry_subindex,
                 entry_bit_length);
-        up(&sc->master->master_sem);
+        ec_mutex_unlock(&sc->master->master_mutex);
         if (IS_ERR(entry))
             retval = PTR_ERR(entry);
     } else {
@@ -623,9 +623,9 @@
             break;
 
     if (pdo) {
-        down(&sc->master->master_sem);
+        ec_mutex_lock(&sc->master->master_mutex);
         ec_pdo_clear_entries(pdo);
-        up(&sc->master->master_sem);
+        ec_mutex_unlock(&sc->master->master_mutex);
     } else {
         EC_CONFIG_WARN(sc, "PDO 0x%04X is not assigned.\n", pdo_index);
     }
@@ -805,9 +805,9 @@
         return ret;
     }
         
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     list_add_tail(&req->list, &sc->sdo_configs);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
     return 0;
 }
 
@@ -890,9 +890,9 @@
         return ret;
     }
         
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     list_add_tail(&req->list, &sc->sdo_configs);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
     return 0;
 }
 
@@ -931,9 +931,9 @@
     memset(req->data, 0x00, size);
     req->data_size = size;
     
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     list_add_tail(&req->list, &sc->sdo_requests);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
 
     return req; 
 }
@@ -973,9 +973,9 @@
         return ERR_PTR(ret);
     }
 
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     list_add_tail(&voe->list, &sc->voe_handlers);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
 
     return voe; 
 }
@@ -1056,9 +1056,9 @@
         return ret;
     }
         
-    down(&sc->master->master_sem);
+    ec_mutex_lock(&sc->master->master_mutex);
     list_add_tail(&req->list, &sc->soe_configs);
-    up(&sc->master->master_sem);
+    ec_mutex_unlock(&sc->master->master_mutex);
     return 0;
 }
 
--- a/tty/module.c	Thu Dec 23 09:48:56 2010 +0100
+++ b/tty/module.c	Wed Jan 05 08:36:53 2011 +0100
@@ -65,7 +65,7 @@
 
 static struct tty_driver *tty_driver = NULL;
 ec_tty_t *ttys[EC_TTY_MAX_DEVICES];
-struct semaphore tty_sem;
+struct ec_mutex_t tty_sem;
 
 void ec_tty_wakeup(unsigned long);
 
@@ -111,7 +111,7 @@
     struct timer_list timer;
     struct tty_struct *tty;
     unsigned int open_count;
-    struct semaphore sem;
+    struct ec_mutex_t sem;
 
     ec_tty_operations_t ops;
     void *cb_data;
@@ -131,7 +131,7 @@
 
     printk(KERN_INFO PFX "TTY driver %s\n", EC_MASTER_VERSION);
 
-    sema_init(&tty_sem, 1);
+    ec_mutex_init(&tty_sem);
 
     for (i = 0; i < EC_TTY_MAX_DEVICES; i++) {
         ttys[i] = NULL;
@@ -202,7 +202,7 @@
     init_timer(&t->timer);
     t->tty = NULL;
     t->open_count = 0;
-    sema_init(&t->sem, 1);
+    ec_mutex_init(&t->sem);
     t->ops = *ops;
     t->cb_data = cb_data;
 
@@ -391,9 +391,9 @@
         tty->driver_data = t;
     }
 
-    down(&t->sem);
+    ec_mutex_lock(&t->sem);
     t->open_count++;
-    up(&t->sem);
+    ec_mutex_unlock(&t->sem);
     return 0;
 }
 
@@ -409,11 +409,11 @@
 #endif
 
     if (t) {
-        down(&t->sem);
+        ec_mutex_lock(&t->sem);
         if (--t->open_count == 0) {
             t->tty = NULL;
         }
-        up(&t->sem);
+        ec_mutex_unlock(&t->sem);
     }
 }
 
@@ -676,7 +676,7 @@
     ec_tty_t *tty;
     int minor, ret;
 
-    if (down_interruptible(&tty_sem)) {
+    if (ec_mutex_lock_interruptible(&tty_sem)) {
         return ERR_PTR(-EINTR);
     }
 
@@ -686,25 +686,25 @@
 
             tty = kmalloc(sizeof(ec_tty_t), GFP_KERNEL);
             if (!tty) {
-                up(&tty_sem);
+                ec_mutex_unlock(&tty_sem);
                 printk(KERN_ERR PFX "Failed to allocate memory.\n");
                 return ERR_PTR(-ENOMEM);
             }
 
             ret = ec_tty_init(tty, minor, ops, cb_data);
             if (ret) {
-                up(&tty_sem);
+                ec_mutex_unlock(&tty_sem);
                 kfree(tty);
                 return ERR_PTR(ret);
             }
 
             ttys[minor] = tty;
-            up(&tty_sem);
+            ec_mutex_unlock(&tty_sem);
             return tty;
         }
     }
 
-    up(&tty_sem);
+    ec_mutex_unlock(&tty_sem);
     printk(KERN_ERR PFX "No free interfaces avaliable.\n");
     return ERR_PTR(-EBUSY);
 }