Index: trunk/kernel/kern/chdev.c
===================================================================
--- trunk/kernel/kern/chdev.c	(revision 593)
+++ trunk/kernel/kern/chdev.c	(revision 601)
@@ -175,5 +175,6 @@
 if( (is_rx) && (DEBUG_CHDEV_CMD_RX < rx_cycle) )
 printk("\n[%s] client[%x,%x] enter for RX / server[%x,%x] / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, server_ptr->process->pid, server_ptr->trdid, rx_cycle );
+__FUNCTION__, this->process->pid, this->trdid, 
+server_ptr->process->pid, server_ptr->trdid, rx_cycle );
 #endif
 
@@ -182,5 +183,6 @@
 if( (is_rx == 0) && (DEBUG_CHDEV_CMD_TX < tx_cycle) )
 printk("\n[%s] client[%x,%x] enter for TX / server[%x,%x] / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, server_ptr->process->pid, server_ptr->trdid, tx_cycle );
+__FUNCTION__, this->process->pid, this->trdid, 
+server_ptr->process->pid, server_ptr->trdid, tx_cycle );
 #endif
 
@@ -223,5 +225,5 @@
 if( (is_rx == 0) && (DEBUG_CHDEV_CMD_TX < tx_cycle) )
 printk("\n[%s] client thread[%x,%x] blocked\n",
-__FUNCTION__, this->process_pid, this->trdid );
+__FUNCTION__, this->process->pid, this->trdid );
 #endif
 
@@ -341,5 +343,5 @@
 uint32_t rx_cycle = (uint32_t)hal_get_cycles();
 if( (chdev->is_rx) && (DEBUG_CHDEV_SERVER_RX < rx_cycle) )
-printk("\n[%s] dev_thread[%x,%x] start RX / cycle %d\n",
+printk("\n[%s] thread[%x,%x] start RX / cycle %d\n",
 __FUNCTION__ , server->process->pid, server->trdid, rx_cycle );
 #endif
@@ -348,7 +350,10 @@
 uint32_t tx_cycle = (uint32_t)hal_get_cycles();
 if( (chdev->is_rx == 0) && (DEBUG_CHDEV_SERVER_TX < tx_cycle) )
-printk("\n[%s] dev_thread[%x,%x] start TX / cycle %d\n",
+printk("\n[%s] thread[%x,%x] start TX / cycle %d\n",
 __FUNCTION__ , server->process->pid, server->trdid, tx_cycle );
 #endif
+
+        // check server thread can yield
+        thread_assert_can_yield( server , __FUNCTION__ );
 
         // get the lock protecting the waiting queue
@@ -358,9 +363,11 @@
         if( xlist_is_empty( root_xp ) ) // waiting queue empty 
         {
+            // release lock protecting the waiting queue
+            remote_busylock_release( lock_xp );
 
 #if DEBUG_CHDEV_SERVER_RX
 rx_cycle = (uint32_t)hal_get_cycles();
 if( (chdev->is_rx) && (DEBUG_CHDEV_SERVER_RX < rx_cycle) )
-printk("\n[%s] dev_thread[%x,%x] found RX queue empty => blocks / cycle %d\n",
+printk("\n[%s] thread[%x,%x] found RX queue empty => blocks / cycle %d\n",
 __FUNCTION__ , server->process->pid, server->trdid, rx_cycle );
 #endif
@@ -369,17 +376,9 @@
 tx_cycle = (uint32_t)hal_get_cycles();
 if( (chdev->is_rx == 0) && (DEBUG_CHDEV_SERVER_TX < tx_cycle) )
-printk("\n[%s] dev_thread[%x,%x] found TX queue empty => blocks / cycle %d\n",
+printk("\n[%s] thread[%x,%x] found TX queue empty => blocks / cycle %d\n",
 __FUNCTION__ , server->process->pid, server->trdid, tx_cycle );
 #endif
-
-            // release lock 
-            remote_busylock_release( lock_xp );
-
             // block 
             thread_block( XPTR( local_cxy , server ) , THREAD_BLOCKED_IDLE ); 
-
-// check server thread can yield
-assert( (server->busylocks == 0),
-"cannot yield : busylocks = %d\n", server->busylocks );
 
             // deschedule
@@ -388,4 +387,7 @@
         else                            // waiting queue not empty
         {
+            // release lock protecting the waiting queue
+            remote_busylock_release( lock_xp );
+
             // get extended pointer on first client thread
             client_xp = XLIST_FIRST( root_xp , thread_t , wait_list );
@@ -395,16 +397,15 @@
             client_ptr = GET_PTR( client_xp );
 
-            // remove this first client thread from waiting queue
-            xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) );
-
-            // release lock 
-            remote_busylock_release( lock_xp );
+#if( DDEBUG_CHDEV_SERVER_TX || DEBUG_CHDEV_SERVER_RX )
+process_t * process      = hal_remote_lpt( XPTR( client_cxy , &client_ptr->process ) );
+pid_t       client_pid   = hal_remote_l32( XPTR( client_cxy , &process->pid ) );
+process_t   client_trdid = hal_remote_l32( XPTR( client_cxy , &client_ptr->trdid ) );
+#endif
 
 #if DEBUG_CHDEV_SERVER_RX
 rx_cycle = (uint32_t)hal_get_cycles();
 if( (chdev->is_rx) && (DEBUG_CHDEV_SERVER_RX < rx_cycle) )
-printk("\n[%s] dev_thread[%x,%x] for RX get client thread[%x,%x] / cycle %d\n",
-__FUNCTION__, server->process->pid, server->trdid,
-client_ptr->process->pid, client_ptr->trdid, rx_cycle );
+printk("\n[%s] thread[%x,%x] for RX get client thread[%x,%x] / cycle %d\n",
+__FUNCTION__, server->process->pid, server->trdid, client_pid, client_trdid, cycle );
 #endif
 
@@ -412,7 +413,6 @@
 tx_cycle = (uint32_t)hal_get_cycles();
 if( (chdev->is_rx == 0) && (DEBUG_CHDEV_SERVER_TX < tx_cycle) )
-printk("\n[%s] dev_thread[%x,%x] for TX get client thread[%x,%x] / cycle %d\n",
-__FUNCTION__, server->process->pid, server->trdid,
-client_ptr->process->pid, client_ptr->trdid, tx_cycle );
+printk("\n[%s] thread[%x,%x] for TX get client thread[%x,%x] / cycle %d\n",
+__FUNCTION__, server->process->pid, server->trdid, client_pid, client_trdid, cycle );
 #endif
 
@@ -425,16 +425,25 @@
 #endif
 
-            // call driver command function to execute I/O operation
+            // call the (blocking) driver command function
+            // to launch I/O operation AND wait completion
             chdev->cmd( client_xp );
         
-            // unblock client thread
+            // unblock client thread when driver returns
             thread_unblock( client_xp , THREAD_BLOCKED_IO );
+
+            // get the lock protecting the waiting queue
+            remote_busylock_acquire( lock_xp );
+
+            // remove this client thread from chdev waiting queue
+            xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) );
+
+            // release lock protecting the waiting queue
+            remote_busylock_release( lock_xp );
 
 #if DEBUG_CHDEV_SERVER_RX
 rx_cycle = (uint32_t)hal_get_cycles();
 if( (chdev->is_rx) && (DEBUG_CHDEV_SERVER_RX < rx_cycle) )
-printk("\n[%s] dev_thread[%x,%x] completes RX for client thread[%x,%x] / cycle %d\n",
-__FUNCTION__, server->process->pid, server->trdid,
-client_ptr->process->pid, client_ptr->trdid, rx_cycle );
+printk("\n[%s] thread[%x,%x] completes RX for client thread[%x,%x] / cycle %d\n",
+__FUNCTION__, server->process->pid, server->trdid, client_pid, client_trdid, cycle );
 #endif
 
@@ -442,7 +451,6 @@
 tx_cycle = (uint32_t)hal_get_cycles();
 if( (chdev->is_rx == 0) && (DEBUG_CHDEV_SERVER_TX < tx_cycle) )
-printk("\n[%s] dev_thread[%x,%x] completes TX for client thread[%x,%x] / cycle %d\n",
-__FUNCTION__, server->process->pid, server->trdid,
-client_ptr->process->pid, client_ptr->trdid, tx_cycle );
+printk("\n[%s] thread[%x,%x] completes TX for client thread[%x,%x] / cycle %d\n",
+__FUNCTION__, server->process->pid, server->trdid, client_pid, client_trdid, cycle );
 #endif
 
@@ -633,6 +641,5 @@
 			pid        = hal_remote_l32 ( XPTR( thread_cxy , &process->pid        ) );
 
-            nolock_printk("- thread %X / cluster %X / trdid %X / pid %X\n",
-            thread_ptr, thread_cxy, trdid, pid );
+            nolock_printk("- thread[%x,%x]\n", pid, trdid );
         }
     }
