Index: trunk/kernel/kern/chdev.c
===================================================================
--- trunk/kernel/kern/chdev.c	(revision 545)
+++ trunk/kernel/kern/chdev.c	(revision 564)
@@ -37,6 +37,10 @@
 #include <devfs.h>
 
-
-extern chdev_directory_t    chdev_dir;   // allocated in kernel_init.c
+//////////////////////////////////////////////////////////////////////////////////////
+// Extern global variables
+//////////////////////////////////////////////////////////////////////////////////////
+
+extern chdev_directory_t    chdev_dir;         // allocated in kernel_init.c
+
 
 #if (DEBUG_SYS_READ & 1)
@@ -57,5 +61,6 @@
 char * chdev_func_str( uint32_t func_type ) 
 {
-  switch ( func_type ) {
+    switch ( func_type ) 
+    {
     case DEV_FUNC_RAM: return "RAM";
     case DEV_FUNC_ROM: return "ROM";
@@ -91,6 +96,8 @@
     if( chdev == NULL ) return NULL;
 
-    // initialize waiting threads queue and associated lock
-    remote_spinlock_init( XPTR( local_cxy , &chdev->wait_lock ) );
+    // initialize lock
+    remote_busylock_init( XPTR( local_cxy , &chdev->wait_lock ), LOCK_CHDEV_QUEUE );
+
+    // initialise waiting queue
     xlist_root_init( XPTR( local_cxy , &chdev->wait_root ) );
 
@@ -130,5 +137,5 @@
     core_t   * core_ptr;      // local pointer on core running the server thread
     uint32_t   server_lid;    // core running the server thread local index
-    xptr_t     lock_xp;       // extended pointer on lock protecting the chdev queue
+    xptr_t     lock_xp;       // extended pointer on lock protecting the chdev state
     uint32_t   save_sr;       // for critical section
 
@@ -147,4 +154,8 @@
     chdev_t * chdev_ptr = GET_PTR( chdev_xp );
 
+// check calling thread can yield
+assert( (this->busylocks == 0),
+"cannot yield : busylocks = %d\n", this->busylocks );
+
     // get local and extended pointers on server thread
     server_ptr = (thread_t *)hal_remote_lpt( XPTR( chdev_cxy , &chdev_ptr->server) );
@@ -155,8 +166,8 @@
 
     // get server core local index
-    server_lid = hal_remote_lw( XPTR( chdev_cxy , &core_ptr->lid ) );
+    server_lid = hal_remote_l32( XPTR( chdev_cxy , &core_ptr->lid ) );
 
 #if (DEBUG_CHDEV_CMD_RX || DEBUG_CHDEV_CMD_TX)
-bool_t is_rx = hal_remote_lw( XPTR( chdev_cxy , &chdev_ptr->is_rx ) );
+bool_t is_rx = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->is_rx ) );
 #endif
     
@@ -185,8 +196,8 @@
 
     // build extended pointer on lock protecting chdev waiting queue
-    lock_xp = XPTR( chdev_cxy , &chdev_ptr->wait_lock );
+    lock_xp            = XPTR( chdev_cxy , &chdev_ptr->wait_lock );
 
     // critical section for the following sequence: 
-    // (1) take the lock protecting waiting queue 
+    // (1) take the lock protecting the chdev state
     // (2) block the client thread
     // (3) unblock the server thread if required
@@ -200,6 +211,6 @@
     hal_disable_irq( &save_sr );
 
-    // take the lock protecting chdev waiting queue
-    remote_spinlock_lock( lock_xp );
+    // take the lock protecting chdev queue
+    remote_busylock_acquire( lock_xp );
 
     // block current thread
@@ -217,5 +228,5 @@
 
     // unblock server thread if required
-    if( hal_remote_lw( blocked_xp ) & THREAD_BLOCKED_IDLE )
+    if( hal_remote_l32( blocked_xp ) & THREAD_BLOCKED_IDLE )
     thread_unblock( server_xp , THREAD_BLOCKED_IDLE );
 
@@ -243,5 +254,5 @@
 #endif
  
-    // send IPI to core running the server thread when server != client
+    // send IPI to core running the server thread when server core != client core
     if( (server_lid != this->core->lid) || (local_cxy != chdev_cxy) )
     {
@@ -262,9 +273,8 @@
     }
  
-    // release lock
-    remote_spinlock_unlock( lock_xp );
+    // release lock protecting chdev queue
+    remote_busylock_release( lock_xp );
 
     // deschedule
-    assert( thread_can_yield() , "illegal sched_yield\n" );
     sched_yield("blocked on I/O");
 
@@ -308,6 +318,8 @@
     server = CURRENT_THREAD;
 
-    // get root and lock on command queue
+    // build extended pointer on root of client threads queue
     root_xp = XPTR( local_cxy , &chdev->wait_root );
+
+    // build extended pointer on lock protecting client threads queue
     lock_xp = XPTR( local_cxy , &chdev->wait_lock );
 
@@ -316,18 +328,51 @@
     while( 1 )
     {
+
+#if DEBUG_CHDEV_SERVER_RX
+uint32_t rx_cycle = (uint32_t)hal_get_cycles();
+if( (chdev->is_rx) && (DEBUG_CHDEV_SERVER_RX < rx_cycle) )
+printk("\n[DBG] %s : dev_thread %x start RX / cycle %d\n",
+__FUNCTION__ , server->trdid , rx_cycle );
+#endif
+
+#if DEBUG_CHDEV_SERVER_TX
+uint32_t tx_cycle = (uint32_t)hal_get_cycles();
+if( (chdev->is_rx == 0) && (DEBUG_CHDEV_SERVER_TX < tx_cycle) )
+printk("\n[DBG] %s : dev_thread %x start TX / cycle %d\n",
+__FUNCTION__ , server->trdid , tx_cycle );
+#endif
+
         // get the lock protecting the waiting queue
-        remote_spinlock_lock( lock_xp );
+        remote_busylock_acquire( lock_xp );
 
         // check waiting queue state
         if( xlist_is_empty( root_xp ) ) // waiting queue empty 
         {
+
+#if DEBUG_CHDEV_SERVER_RX
+rx_cycle = (uint32_t)hal_get_cycles();
+if( (chdev->is_rx) && (DEBUG_CHDEV_SERVER_RX < rx_cycle) )
+printk("\n[DBG] %s : dev_thread %x found RX queue empty => blocks / cycle %d\n",
+__FUNCTION__ , server->trdid , rx_cycle );
+#endif
+
+#if DEBUG_CHDEV_SERVER_TX
+tx_cycle = (uint32_t)hal_get_cycles();
+if( (chdev->is_rx == 0) && (DEBUG_CHDEV_SERVER_TX < tx_cycle) )
+printk("\n[DBG] %s : dev_thread %x found TX queue empty => blocks / cycle %d\n",
+__FUNCTION__ , server->trdid , tx_cycle );
+#endif
+
             // release lock 
-            remote_spinlock_unlock( lock_xp );
+            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
-            assert( thread_can_yield() , "illegal sched_yield\n" );
             sched_yield("I/O queue empty");
         } 
@@ -335,5 +380,5 @@
         {
             // get extended pointer on first client thread
-            client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list );
+            client_xp = XLIST_FIRST( root_xp , thread_t , wait_list );
 
             // get client thread cluster and local pointer
@@ -345,18 +390,18 @@
 
             // release lock 
-            remote_spinlock_unlock( lock_xp );
+            remote_busylock_release( lock_xp );
 
 #if DEBUG_CHDEV_SERVER_RX
-uint32_t rx_cycle = (uint32_t)hal_get_cycles();
+rx_cycle = (uint32_t)hal_get_cycles();
 if( (chdev->is_rx) && (DEBUG_CHDEV_SERVER_RX < rx_cycle) )
-printk("\n[DBG] %s : server_thread %x start RX / client %x / cycle %d\n",
-__FUNCTION__ , server , client_ptr , rx_cycle );
+printk("\n[DBG] %s : dev_thread %x for RX found client thread %x in process %x / cycle %d\n",
+__FUNCTION__, server->trdid ,client_ptr->trdid ,client_ptr->process->pid, rx_cycle );
 #endif
 
 #if DEBUG_CHDEV_SERVER_TX
-uint32_t tx_cycle = (uint32_t)hal_get_cycles();
+tx_cycle = (uint32_t)hal_get_cycles();
 if( (chdev->is_rx == 0) && (DEBUG_CHDEV_SERVER_TX < tx_cycle) )
-printk("\n[DBG] %s : server_thread %x start TX / client %x / cycle %d\n",
-__FUNCTION__ , server , client_ptr , tx_cycle );
+printk("\n[DBG] %s : dev_thread %x for TX found client thread %x in process %x / cycle %d\n",
+__FUNCTION__, server->trdid ,client_ptr->trdid ,client_ptr->process->pid, tx_cycle );
 #endif
 
@@ -378,6 +423,6 @@
 rx_cycle = (uint32_t)hal_get_cycles();
 if( (chdev->is_rx) && (DEBUG_CHDEV_SERVER_RX < rx_cycle) )
-printk("\n[DBG] %s : server_thread %x completes RX / client %x / cycle %d\n",
-__FUNCTION__ , server , client_ptr , rx_cycle );
+printk("\n[DBG] %s : dev_thread %x completes RX for client %x in process %x / cycle %d\n",
+__FUNCTION__, server->trdid, client_ptr->trdid, client_ptr->process->pid, rx_cycle );
 #endif
 
@@ -385,6 +430,6 @@
 tx_cycle = (uint32_t)hal_get_cycles();
 if( (chdev->is_rx == 0) && (DEBUG_CHDEV_SERVER_TX < tx_cycle) )
-printk("\n[DBG] %s : server_thread %x completes TX / client %x / cycle %d\n",
-__FUNCTION__ , server , client_ptr , tx_cycle );
+printk("\n[DBG] %s : dev_thread %x completes TX for client %x in process %x / cycle %d\n",
+__FUNCTION__, server->trdid, client_ptr->trdid, client_ptr->process->pid, tx_cycle );
 #endif
 
@@ -419,5 +464,5 @@
 
     // get inode type from file descriptor
-    inode_type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type ) );
+    inode_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type ) );
     inode_ptr  = (vfs_inode_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) );
 
@@ -432,5 +477,5 @@
 }  // end chdev_from_file()
 
-////////////////////////
+//////////////////////////////
 void chdev_dir_display( void )
 {
@@ -439,5 +484,4 @@
     chdev_t * ptr;
     uint32_t  base;
-    reg_t     save_sr;
 
     // get pointers on TXT0 chdev
@@ -446,9 +490,9 @@
     chdev_t * txt0_ptr = GET_PTR( txt0_xp );
 
-    // get extended pointer on remote TXT0 chdev lock
+    // get extended pointer on TXT0 lock
     xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
 
-    // get TXT0 lock in busy waiting mode
-    remote_spinlock_lock_busy( lock_xp , &save_sr );
+    // get TXT0 lock 
+    remote_busylock_acquire( lock_xp );
 
     // header
@@ -456,9 +500,9 @@
 
     // IOB
-    if (chdev_dir.iob != NULL )
+    if (chdev_dir.iob != XPTR_NULL )
     {
         cxy  = GET_CXY( chdev_dir.iob );
         ptr  = GET_PTR( chdev_dir.iob );
-        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
+        base = (uint32_t)hal_remote_l64( XPTR( cxy , &ptr->base ) );
         nolock_printk("  - iob       : cxy = %X / ptr = %X / base = %X\n", cxy, ptr, base);
     }
@@ -467,5 +511,5 @@
     cxy  = GET_CXY( chdev_dir.pic );
     ptr  = GET_PTR( chdev_dir.pic );
-    base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
+    base = (uint32_t)hal_remote_l64( XPTR( cxy , &ptr->base ) );
     nolock_printk("  - pic       : cxy = %X / ptr = %X / base = %X\n", cxy, ptr, base);
 
@@ -475,10 +519,10 @@
         cxy = GET_CXY( chdev_dir.txt_rx[i] );
         ptr = GET_PTR( chdev_dir.txt_rx[i] );
-        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
+        base = (uint32_t)hal_remote_l64( XPTR( cxy , &ptr->base ) );
         nolock_printk("  - txt_rx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
 
         cxy = GET_CXY( chdev_dir.txt_tx[i] );
         ptr = GET_PTR( chdev_dir.txt_tx[i] );
-        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
+        base = (uint32_t)hal_remote_l64( XPTR( cxy , &ptr->base ) );
         nolock_printk("  - txt_tx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
     }
@@ -489,5 +533,5 @@
         cxy = GET_CXY( chdev_dir.ioc[i] );
         ptr = GET_PTR( chdev_dir.ioc[i] );
-        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
+        base = (uint32_t)hal_remote_l64( XPTR( cxy , &ptr->base ) );
         nolock_printk("  - ioc[%d]    : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
     }
@@ -498,5 +542,5 @@
         cxy  = GET_CXY( chdev_dir.fbf[i] );
         ptr  = GET_PTR( chdev_dir.fbf[i] );
-        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
+        base = (uint32_t)hal_remote_l64( XPTR( cxy , &ptr->base ) );
         nolock_printk("  - fbf[%d]    : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
     }
@@ -507,15 +551,15 @@
         cxy = GET_CXY( chdev_dir.nic_rx[i] );
         ptr = GET_PTR( chdev_dir.nic_rx[i] );
-        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
+        base = (uint32_t)hal_remote_l64( XPTR( cxy , &ptr->base ) );
         nolock_printk("  - nic_rx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
 
         cxy = GET_CXY( chdev_dir.nic_tx[i] );
         ptr = GET_PTR( chdev_dir.nic_tx[i] );
-        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
+        base = (uint32_t)hal_remote_l64( XPTR( cxy , &ptr->base ) );
         nolock_printk("  - nic_tx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
     }
 
     // release lock
-    remote_spinlock_unlock_busy( lock_xp , save_sr );
+    remote_busylock_release( lock_xp );
 
 }  // end chdev_dir_display()
@@ -546,12 +590,23 @@
     hal_remote_strcpy( XPTR( local_cxy , name ), XPTR( chdev_cxy , chdev_ptr->name ) );
 
+    // get pointers on TXT0 chdev
+    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
+    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
+    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
+
+    // get extended pointer on TXT0 lock
+    xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
+
+    // get TXT0 lock 
+    remote_busylock_acquire( lock_xp );
+
     // check queue empty
     if( xlist_is_empty( root_xp ) )
     {
-        printk("\n***** Waiting queue empty for chdev %s\n", name ); 
+        nolock_printk("\n***** Waiting queue empty for chdev %s\n", name ); 
     }
     else
     {
-        printk("\n***** Waiting queue for chdev %s\n", name ); 
+        nolock_printk("\n***** Waiting queue for chdev %s\n", name ); 
 
         // scan the waiting queue
@@ -561,12 +616,16 @@
             thread_cxy = GET_CXY( thread_xp );
             thread_ptr = GET_PTR( thread_xp );
-            trdid      = hal_remote_lw ( XPTR( thread_cxy , &thread_ptr->trdid   ) );
+            trdid      = hal_remote_l32 ( XPTR( thread_cxy , &thread_ptr->trdid   ) );
             process    = hal_remote_lpt( XPTR( thread_cxy , &thread_ptr->process ) );
-			pid        = hal_remote_lw ( XPTR( thread_cxy , &process->pid        ) );
-
-            printk("- thread %X / cluster %X / trdid %X / pid %X\n",
+			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 );
         }
     }
+
+    // release TXT0 lock 
+    remote_busylock_release( lock_xp );
+
 }  // end chdev_queue_display()
 
