Index: trunk/kernel/kern/chdev.c
===================================================================
--- trunk/kernel/kern/chdev.c	(revision 418)
+++ trunk/kernel/kern/chdev.c	(revision 428)
@@ -276,81 +276,115 @@
 }  // end chdev_sequencial_server()
 
+////////////////////////////////////////
+xptr_t chdev_from_file( xptr_t file_xp )
+{
+    cxy_t         file_cxy;
+    vfs_file_t  * file_ptr;
+    uint32_t      inode_type;
+    vfs_inode_t * inode_ptr;
+    chdev_t     * chdev_ptr;
+
+    // get cluster and local pointer on remote file descriptor
+    // associated inode and chdev are stored in same cluster as the file desc.
+    file_cxy  = GET_CXY( file_xp );
+    file_ptr  = (vfs_file_t *)GET_PTR( file_xp );
+
+    // get inode type from file descriptor
+    inode_type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type ) );
+    inode_ptr  = (vfs_inode_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) );
+
+    assert( (inode_type == INODE_TYPE_DEV) , __FUNCTION__ ,
+    "inode type %d is not INODE_TYPE_DEV", inode_type );
+
+    // get chdev local pointer from inode extension
+    chdev_ptr = (chdev_t *)hal_remote_lpt( XPTR( file_cxy , &inode_ptr->extend ) );
+
+    return XPTR( file_cxy , chdev_ptr );
+
+}  // end chdev_from_file()
+
 ////////////////////////
 void chdev_dir_display()
 {
-    cxy_t     iob_cxy  = GET_CXY( chdev_dir.iob );
-    chdev_t * iob_ptr  = (chdev_t *)GET_PTR( chdev_dir.iob );
-    uint32_t  iob_base = (uint32_t)hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) );
-
-    cxy_t     pic_cxy  = GET_CXY( chdev_dir.pic );
-    chdev_t * pic_ptr  = (chdev_t *)GET_PTR( chdev_dir.pic );
-    uint32_t  pic_base = (uint32_t)hal_remote_lwd( XPTR( pic_cxy , &pic_ptr->base ) );
-
-    cxy_t     txt0_tx_cxy  = GET_CXY( chdev_dir.txt_tx[0] );
-    chdev_t * txt0_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_tx[0] );
-    uint32_t  txt0_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt0_tx_cxy , &txt0_tx_ptr->base ) );
-
-    cxy_t     txt0_rx_cxy  = GET_CXY( chdev_dir.txt_rx[0] );
-    chdev_t * txt0_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_rx[0] );
-    uint32_t  txt0_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt0_rx_cxy , &txt0_rx_ptr->base ) );
-
-    cxy_t     txt1_tx_cxy  = GET_CXY( chdev_dir.txt_tx[1] );
-    chdev_t * txt1_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_tx[1] );
-    uint32_t  txt1_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt1_tx_cxy , &txt1_tx_ptr->base ) );
-
-    cxy_t     txt1_rx_cxy  = GET_CXY( chdev_dir.txt_rx[1] );
-    chdev_t * txt1_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_rx[1] );
-    uint32_t  txt1_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt1_rx_cxy , &txt1_rx_ptr->base ) );
-
-    cxy_t     txt2_tx_cxy  = GET_CXY( chdev_dir.txt_tx[2] );
-    chdev_t * txt2_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_tx[2] );
-    uint32_t  txt2_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt2_tx_cxy , &txt2_tx_ptr->base ) );
-
-    cxy_t     txt2_rx_cxy  = GET_CXY( chdev_dir.txt_rx[2] );
-    chdev_t * txt2_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_rx[2] );
-    uint32_t  txt2_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt2_rx_cxy , &txt2_rx_ptr->base ) );
-
-    cxy_t     ioc_cxy  = GET_CXY( chdev_dir.ioc[0] );
-    chdev_t * ioc_ptr  = (chdev_t *)GET_PTR( chdev_dir.ioc[0] );
-    uint32_t  ioc_base = (uint32_t)hal_remote_lwd( XPTR( ioc_cxy , &ioc_ptr->base ) );
-
-    cxy_t     fbf_cxy  = GET_CXY( chdev_dir.fbf[0] );
-    chdev_t * fbf_ptr  = (chdev_t *)GET_PTR( chdev_dir.fbf[0] );
-    uint32_t  fbf_base = (uint32_t)hal_remote_lwd( XPTR( fbf_cxy , &fbf_ptr->base ) );
-
-    cxy_t     nic0_rx_cxy  = GET_CXY( chdev_dir.nic_rx[0] );
-    chdev_t * nic0_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.nic_rx[0] );
-    uint32_t  nic0_rx_base = (uint32_t)hal_remote_lwd( XPTR( nic0_rx_cxy , &nic0_rx_ptr->base ) );
-
-    cxy_t     nic0_tx_cxy  = GET_CXY( chdev_dir.nic_tx[0] );
-    chdev_t * nic0_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.nic_tx[0] );
-    uint32_t  nic0_tx_base = (uint32_t)hal_remote_lwd( XPTR( nic0_tx_cxy , &nic0_tx_ptr->base ) );
-
-    printk("\n***** external chdev directory in cluster %x\n"
-           "  - iob       : cxy = %X / ptr = %X / base = %X\n"
-           "  - pic       : cxy = %X / ptr = %X / base = %X\n"
-           "  - ioc       : cxy = %X / ptr = %X / base = %X\n"
-           "  - fbf       : cxy = %X / ptr = %X / base = %X\n"
-           "  - txt_rx[0] : cxy = %X / ptr = %X / base = %X\n"
-           "  - txt_tx[0] : cxy = %X / ptr = %X / base = %X\n"
-           "  - txt_rx[1] : cxy = %X / ptr = %X / base = %X\n"
-           "  - txt_tx[1] : cxy = %X / ptr = %X / base = %X\n"
-           "  - txt_rx[2] : cxy = %X / ptr = %X / base = %X\n"
-           "  - txt_tx[2] : cxy = %X / ptr = %X / base = %X\n"
-           "  - nic_rx[0] : cxy = %X / ptr = %X / base = %X\n"
-           "  - nic_tx[0] : cxy = %X / ptr = %X / base = %X\n",
-           local_cxy,
-           iob_cxy , iob_ptr , iob_base ,
-           pic_cxy , pic_ptr , pic_base ,
-           ioc_cxy , ioc_ptr , ioc_base ,
-           fbf_cxy , fbf_ptr , fbf_base ,
-           txt0_rx_cxy , txt0_rx_ptr , txt0_rx_base ,
-           txt0_tx_cxy , txt0_tx_ptr , txt0_tx_base ,
-           txt1_rx_cxy , txt1_rx_ptr , txt1_rx_base ,
-           txt1_tx_cxy , txt1_tx_ptr , txt1_tx_base ,
-           txt2_rx_cxy , txt2_rx_ptr , txt2_rx_base ,
-           txt2_tx_cxy , txt2_tx_ptr , txt2_tx_base ,
-           nic0_rx_cxy , nic0_rx_ptr , nic0_rx_base ,
-           nic0_tx_cxy , nic0_tx_ptr , nic0_tx_base );
+    uint32_t  i;
+    cxy_t     cxy;
+    chdev_t * ptr;
+    uint32_t  base;
+    reg_t     save_sr;
+
+    // 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 remote TXT0 chdev 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 );
+
+    // header
+    nolock_printk("\n***** external chdevs directory *****\n");
+
+    // IOB
+    cxy  = GET_CXY( chdev_dir.iob );
+    ptr  = GET_PTR( chdev_dir.iob );
+    base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
+    nolock_printk("  - iob       : cxy = %X / ptr = %X / base = %X\n", cxy, ptr, base);
+
+    // PIC
+    cxy  = GET_CXY( chdev_dir.pic );
+    ptr  = GET_PTR( chdev_dir.pic );
+    base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
+    nolock_printk("  - pic       : cxy = %X / ptr = %X / base = %X\n", cxy, ptr, base);
+
+    // TXT
+    for( i = 0 ; i < LOCAL_CLUSTER->nb_txt_channels ; i++ )
+    {
+        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 ) );
+        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 ) );
+        nolock_printk("  - txt_tx[%d] : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
+    }
+
+    // IOC
+    for( i = 0 ; i < LOCAL_CLUSTER->nb_ioc_channels ; i++ )
+    {
+        cxy = GET_CXY( chdev_dir.ioc[i] );
+        ptr = GET_PTR( chdev_dir.ioc[i] );
+        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
+        nolock_printk("  - ioc[%d]    : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
+    }
+
+    // FBF
+    for( i = 0 ; i < LOCAL_CLUSTER->nb_fbf_channels ; i++ )
+    {
+        cxy  = GET_CXY( chdev_dir.fbf[i] );
+        ptr  = GET_PTR( chdev_dir.fbf[i] );
+        base = (uint32_t)hal_remote_lwd( XPTR( cxy , &ptr->base ) );
+        nolock_printk("  - fbf[%d]    : cxy = %X / ptr = %X / base = %X\n", i, cxy, ptr, base);
+    }
+
+    // NIC
+    for( i = 0 ; i < LOCAL_CLUSTER->nb_nic_channels ; i++ )
+    {
+        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 ) );
+        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 ) );
+        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 );
 
 }  // end chdev_dir_display()
