diff --git a/master/master.c b/master/master.c
index 37a3e7c33eedb155e23939c1acd58faca086d1a6..b96bd190dc780d49844bb06d7967e8a9cb564430 100644
--- a/master/master.c
+++ b/master/master.c
@@ -109,6 +109,7 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
 
     master->index = index;
     master->device = NULL;
+    init_MUTEX(&master->device_sem);
     atomic_set(&master->available, 1);
     INIT_LIST_HEAD(&master->slaves);
     INIT_LIST_HEAD(&master->datagram_queue);
diff --git a/master/master.h b/master/master.h
index 31caa5b8ce9d4d9675ed102ab994e39bb7c35e94..e706089f9333724054fa6646870d958ab509ac29 100644
--- a/master/master.h
+++ b/master/master.h
@@ -45,6 +45,7 @@
 #include <linux/sysfs.h>
 #include <linux/timer.h>
 #include <asm/atomic.h>
+#include <asm/semaphore.h>
 
 #include "device.h"
 #include "domain.h"
@@ -99,6 +100,7 @@ struct ec_master
     struct kobject kobj; /**< kobject */
 
     ec_device_t *device; /**< EtherCAT device */
+    struct semaphore device_sem; /**< device semaphore */
 
     ec_xmldev_t xmldev; /**< XML character device */
 
diff --git a/master/module.c b/master/module.c
index 47996cf36ba3eedf3bb7a41a504a551ab8c476f5..a78db34594e2244a0baa4e80f81fb78ff5e2e50f 100644
--- a/master/module.c
+++ b/master/module.c
@@ -290,15 +290,20 @@ ec_device_t *ecdev_register(unsigned int master_index, /**< master index */
 
     if (!(master = ec_find_master(master_index))) return NULL;
 
+    if (down_interruptible(&master->device_sem)) {
+        EC_ERR("Interrupted while waiting for device!\n");
+        goto out_return;
+    }
+
     if (master->device) {
         EC_ERR("Master %i already has a device!\n", master_index);
-        goto out_return;
+        goto out_up;
     }
 
     if (!(master->device =
           (ec_device_t *) kmalloc(sizeof(ec_device_t), GFP_KERNEL))) {
         EC_ERR("Failed to allocate device!\n");
-        goto out_return;
+        goto out_up;
     }
 
     if (ec_device_init(master->device, master, net_dev, isr, module)) {
@@ -306,11 +311,14 @@ ec_device_t *ecdev_register(unsigned int master_index, /**< master index */
         goto out_free;
     }
 
+    up(&master->device_sem);
     return master->device;
 
  out_free:
     kfree(master->device);
     master->device = NULL;
+ out_up:
+    up(&master->device_sem);
  out_return:
     return NULL;
 }
@@ -334,7 +342,10 @@ void ecdev_unregister(unsigned int master_index, /**< master index */
 
     if (!(master = ec_find_master(master_index))) return;
 
+    down(&master->device_sem);
+
     if (!master->device || master->device != device) {
+        up(&master->device_sem);
         EC_WARN("Unable to unregister device!\n");
         return;
     }
@@ -342,6 +353,8 @@ void ecdev_unregister(unsigned int master_index, /**< master index */
     ec_device_clear(master->device);
     kfree(master->device);
     master->device = NULL;
+
+    up(&master->device_sem);
 }
 
 /*****************************************************************************/
@@ -415,16 +428,25 @@ ec_master_t *ecrt_request_master(unsigned int master_index
         goto out_return;
     }
 
+    if (down_interruptible(&master->device_sem)) {
+        EC_ERR("Interrupted while waiting for device!\n");
+        goto out_release;
+    }
+
     if (!master->device) {
+        up(&master->device_sem);
         EC_ERR("Master %i has no assigned device!\n", master_index);
         goto out_release;
     }
 
-    if (!try_module_get(master->device->module)) { // possible race?
-        EC_ERR("Failed to reserve device module!\n");
+    if (!try_module_get(master->device->module)) {
+        up(&master->device_sem);
+        EC_ERR("Device module is unloading!\n");
         goto out_release;
     }
 
+    up(&master->device_sem);
+
     if (!master->device->link_state) {
         EC_ERR("Link is DOWN.\n");
         goto out_module_put;