Index: uspace/drv/uhci/Makefile
===================================================================
--- uspace/drv/uhci/Makefile	(revision 92f924c8f47ac9cd03d5e435a2c244dee1a328a6)
+++ uspace/drv/uhci/Makefile	(revision 7bd34e51264fb416395ef7b221918e455f97baed)
@@ -39,4 +39,5 @@
 	root_hub/root_hub.c \
 	uhci.c \
+	utils/fibril_semaphore.c \
 	utils/hc_synchronizer.c
 
Index: uspace/drv/uhci/root_hub/port.c
===================================================================
--- uspace/drv/uhci/root_hub/port.c	(revision 92f924c8f47ac9cd03d5e435a2c244dee1a328a6)
+++ uspace/drv/uhci/root_hub/port.c	(revision 7bd34e51264fb416395ef7b221918e455f97baed)
@@ -185,4 +185,5 @@
 	return EOK;
 }
+
 static usb_address_t assign_address_to_zero_device( device_t *hc )
 {
@@ -211,4 +212,5 @@
 
 	sync_value_t value;
+	sync_init(&value);
 
 	uhci_setup(
@@ -217,5 +219,5 @@
 	uhci_print_verbose("address assignment sent, waiting to complete.\n");
 
-//	sync_wait_for(&value);
+	sync_wait_for(&value);
 
 	uhci_print_info( "Assigned address %#x.\n", usb_address );
Index: uspace/drv/uhci/utils/fibril_semaphore.c
===================================================================
--- uspace/drv/uhci/utils/fibril_semaphore.c	(revision 7bd34e51264fb416395ef7b221918e455f97baed)
+++ uspace/drv/uhci/utils/fibril_semaphore.c	(revision 7bd34e51264fb416395ef7b221918e455f97baed)
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2010 Jan Vesely
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <assert.h>
+#include <async.h>
+#include <async_priv.h>
+#include <futex.h>
+
+#include "fibril_semaphore.h"
+static void optimize_execution_power(void)
+{
+  /*
+   * When waking up a worker fibril previously blocked in fibril
+   * synchronization, chances are that there is an idle manager fibril
+   * waiting for IPC, that could start executing the awakened worker
+   * fibril right away. We try to detect this and bring the manager
+   * fibril back to fruitful work.
+   */
+  if (atomic_get(&threads_in_ipc_wait) > 0)
+    ipc_poke();
+}
+/*----------------------------------------------------------------------------*/
+void fibril_semaphore_initialize(fibril_semaphore_t *fs, int value)
+{
+	assert( fs );
+  fs->oi.owned_by = NULL;
+  fs->counter = 1;
+	fs->value = value;
+  list_initialize(&fs->waiters);
+}
+/*----------------------------------------------------------------------------*/
+void fibril_semaphore_down(fibril_semaphore_t *fs)
+{
+	assert( fs );
+  fibril_t *f = (fibril_t *) fibril_get_id();
+
+  futex_down(&async_futex);
+  if (--fs->value < 0) {
+    awaiter_t wdata;
+    wdata.fid = fibril_get_id();
+    wdata.active = false;
+    wdata.wu_event.inlist = true;
+    link_initialize(&wdata.wu_event.link);
+    list_append(&wdata.wu_event.link, &fs->waiters);
+//    check_for_deadlock(&fm->oi);
+    f->waits_for = &fs->oi;
+		++fs->counter;
+    fibril_switch(FIBRIL_TO_MANAGER);
+  } else {
+    fs->oi.owned_by = f;
+    futex_up(&async_futex);
+  }
+}
+/*----------------------------------------------------------------------------*/
+bool fibril_semaphore_trydown(fibril_semaphore_t *fs)
+{
+  bool locked = false;
+
+  futex_down(&async_futex);
+  if (fs->value > 0) {
+    --fs->value;
+    fs->oi.owned_by = (fibril_t *) fibril_get_id();
+    locked = true;
+  }
+  futex_up(&async_futex);
+
+  return locked;
+}
+/*----------------------------------------------------------------------------*/
+void fibril_semaphore_up(fibril_semaphore_t *fs)
+{
+	assert(fs);
+	futex_down(&async_futex);
+  if (++fs->value <= 0) {
+    link_t *tmp;
+    awaiter_t *wdp;
+    fibril_t *f;
+
+    assert(!list_empty(&fs->waiters));
+
+    tmp = fs->waiters.next;
+    wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
+    wdp->active = true;
+    wdp->wu_event.inlist = false;
+
+    f = (fibril_t *) wdp->fid;
+    fs->oi.owned_by = f;
+    f->waits_for = NULL;
+
+    list_remove(&wdp->wu_event.link);
+    fibril_add_ready(wdp->fid);
+    optimize_execution_power();
+  } else {
+    fs->oi.owned_by = NULL;
+  }
+	futex_up(&async_futex);
+}
Index: uspace/drv/uhci/utils/fibril_semaphore.h
===================================================================
--- uspace/drv/uhci/utils/fibril_semaphore.h	(revision 7bd34e51264fb416395ef7b221918e455f97baed)
+++ uspace/drv/uhci/utils/fibril_semaphore.h	(revision 7bd34e51264fb416395ef7b221918e455f97baed)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2010 Jan Vesely
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup usb
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#ifndef DRV_UHCI_UTILS_FIBRIL_SEMAPHORE_H
+#define DRV_UHCI_UTILS_FIBRIL_SEMAPHORE_H
+
+#include <bool.h>
+#include <fibril.h>
+
+typedef struct {
+  fibril_owner_info_t oi;   /* Keep this the first thing. */
+  int counter;
+	int value;
+  link_t waiters;
+} fibril_semaphore_t;
+
+#define FIBRIL_SEMAPHORE_INITIALIZER(name) \
+  { \
+    .oi = { \
+      .owned_by = NULL \
+    }, \
+    .counter = 0, \
+		.value = 0, \
+    .waiters = { \
+      .prev = &name.waiters, \
+      .next = &name.waiters, \
+    } \
+  }
+
+extern void fibril_semaphore_initialize(fibril_semaphore_t *, int value);
+extern void fibril_semaphore_down(fibril_semaphore_t *);
+extern bool fibril_semaphore_trydown(fibril_semaphore_t *);
+extern void fibril_semaphore_up(fibril_semaphore_t *);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci/utils/hc_synchronizer.c
===================================================================
--- uspace/drv/uhci/utils/hc_synchronizer.c	(revision 92f924c8f47ac9cd03d5e435a2c244dee1a328a6)
+++ uspace/drv/uhci/utils/hc_synchronizer.c	(revision 7bd34e51264fb416395ef7b221918e455f97baed)
@@ -1,10 +1,14 @@
 #include "hc_synchronizer.h"
 
+void sync_init(sync_value_t *value)
+{
+	assert(value);
+	fibril_semaphore_initialize(&value->done, 0);
+}
+/*----------------------------------------------------------------------------*/
 void sync_wait_for(sync_value_t *value)
 {
 	assert( value );
-	value->waiting_fibril = fibril_get_id();
-	uhci_print_verbose("turning off fibril %p.\n", value->waiting_fibril);
-	fibril_switch(FIBRIL_TO_MANAGER);
+	fibril_semaphore_down(&value->done);
 }
 /*----------------------------------------------------------------------------*/
@@ -16,5 +20,5 @@
 	value->size = size;
 	value->result = result;
-	fibril_add_ready(value->waiting_fibril);
+	fibril_semaphore_up(&value->done);
 }
 /*----------------------------------------------------------------------------*/
@@ -25,5 +29,4 @@
 	assert(value);
 	value->result = result;
-	uhci_print_verbose("resuming fibril %p.\n", value->waiting_fibril);
-	fibril_add_ready(value->waiting_fibril);
+	fibril_semaphore_up(&value->done);
 }
Index: uspace/drv/uhci/utils/hc_synchronizer.h
===================================================================
--- uspace/drv/uhci/utils/hc_synchronizer.h	(revision 92f924c8f47ac9cd03d5e435a2c244dee1a328a6)
+++ uspace/drv/uhci/utils/hc_synchronizer.h	(revision 7bd34e51264fb416395ef7b221918e455f97baed)
@@ -37,17 +37,18 @@
 #include <assert.h>
 #include <driver.h>
-#include <fibril.h>
 #include <usb/usb.h>
 
 #include "debug.h"
+#include "utils/fibril_semaphore.h"
 
 typedef struct value
 {
 	/* TODO Think of better fibril synch to use */
-	fid_t waiting_fibril;
 	usb_transaction_outcome_t result;
 	size_t size;
-	bool done;
+	fibril_semaphore_t done;
 } sync_value_t;
+
+void sync_init(sync_value_t *value);
 
 void sync_wait_for(sync_value_t *value);
