Index: trunk/hal/tsar_mips32/drivers/soclib_bdv.c
===================================================================
--- trunk/hal/tsar_mips32/drivers/soclib_bdv.c	(revision 570)
+++ trunk/hal/tsar_mips32/drivers/soclib_bdv.c	(revision 610)
@@ -32,5 +32,5 @@
 void soclib_bdv_init( chdev_t * chdev )
 {
-    // get extended pointer on SOCLIB_BDV peripheral base address
+    // get extended pointer on SOCLIB_BDV peripheral base 
 	xptr_t  bdv_xp = chdev->base;
 
@@ -62,4 +62,7 @@
     xptr_t     buf_xp;
     xptr_t     ioc_xp;
+    uint32_t   status;      // I/0 operation status (from BDV)
+    reg_t      save_sr;     // for critical section
+    uint32_t   op;          // BDV_OP_READ / BDV_OP_WRITE 
 
     // get client thread cluster and local pointer
@@ -67,23 +70,29 @@
     thread_t * th_ptr = GET_PTR( th_xp );
 
+#if (DEBUG_HAL_IOC_RX || DEBUG_HAL_IOC_TX)
+uint32_t    cycle        = (uint32_t)hal_get_cycles();
+thread_t  * this         = CURRENT_THREAD;
+process_t * process      = hal_remote_lpt( XPTR( th_cxy , &th_ptr->process ) );
+pid_t       client_pid   = hal_remote_l32( XPTR( th_cxy , &process->pid ) );
+trdid_t     client_trdid = hal_remote_l32( XPTR( th_cxy , &th_ptr->trdid ) );
+#endif 
+
     // get command arguments and extended pointer on IOC device
-    cmd_type =         hal_remote_l32 ( XPTR( th_cxy , &th_ptr->ioc_cmd.type   ) );
-    lba      =         hal_remote_l32 ( XPTR( th_cxy , &th_ptr->ioc_cmd.lba    ) );
-    count    =         hal_remote_l32 ( XPTR( th_cxy , &th_ptr->ioc_cmd.count  ) );
+    cmd_type =         hal_remote_l32( XPTR( th_cxy , &th_ptr->ioc_cmd.type   ) );
+    lba      =         hal_remote_l32( XPTR( th_cxy , &th_ptr->ioc_cmd.lba    ) );
+    count    =         hal_remote_l32( XPTR( th_cxy , &th_ptr->ioc_cmd.count  ) );
     buf_xp   = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->ioc_cmd.buf_xp ) );
     ioc_xp   = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->ioc_cmd.dev_xp ) );
 
 #if DEBUG_HAL_IOC_RX
-uint32_t cycle = (uint32_t)hal_get_cycles();
 if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != IOC_WRITE ) )
-printk("\n[DBG] %s : thread %x enter for RX / cycle %d\n",
-__FUNCTION__ , CURRENT_THREAD , cycle );
-#endif
-
-#if DEBUG_HAL_IOC_TX
-uint32_t cycle = (uint32_t)hal_get_cycles();
+printk("\n[%s] thread[%x,%x] enters for client thread[%x,%x] / RX / cycle %d\n",
+__FUNCTION__ , this->process->pid, this->trdid, client_pid, client_trdid, cycle );
+#endif
+
+#if DEBUG_HAL_IOC_TX
 if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == IOC_WRITE) )
-printk("\n[DBG] %s : thread %x enter for TX / cycle %d\n",
-__FUNCTION__ , CURRENT_THREAD , cycle );
+printk("\n[%s] thread[%x,%x] enters for client thread[%x,%x] / TX / cycle %d\n",
+__FUNCTION__ , this->process->pid, this->trdid, client_pid, client_trdid, cycle );
 #endif
 
@@ -101,10 +110,9 @@
     uint32_t   buf_msb = (uint32_t)(buf_xp>>32);
 
-    // set operation
-    uint32_t   op;
+    // select operation
     if( cmd_type == IOC_WRITE ) op = BDV_OP_WRITE; 
     else                        op = BDV_OP_READ;
 
-    // set SOCLIB_BDV registers to start one I/O operation
+    // set SOCLIB_BDV registers to configure the I/O operation
     hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_IRQ_ENABLE_REG ) , 1       );
     hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_BUFFER_REG     ) , buf_lsb ); 
@@ -112,13 +120,18 @@
     hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_LBA_REG        ) , lba     );
     hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_COUNT_REG      ) , count   );
-    hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_OP_REG         ) , op      );
 
     // waiting policy  depends on the command type
     // - for IOC_READ / IOC_WRITE commands, this function is called by the server thread
-    // - for IOC_SYNC_READ command, this function is directly called by the client thread
+    //   that blocks and deschedules after launching the I/O transfer.
+    //   The I/O operation status is reported in the command by the ISR.
+    // - for IOC_SYNC_READ command, this function is called by the client thread
+    //   that polls the BDV status register until I/O transfer completion.
 
     if( cmd_type == IOC_SYNC_READ )                   // status polling policy
     {
-        uint32_t status;
+        // launch I/O operation on BDV device
+        hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_OP_REG ) , op );
+        
+        // wait completion 
         while (1)
         {
@@ -143,22 +156,44 @@
     else                                            // descheduling + IRQ policy
     { 
+        // enter critical section to atomically
+        // lauch I/O operation and deschedule  
+        hal_disable_irq( &save_sr );
+
+        // launch I/O operation on BDV device
+        hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_OP_REG ) , op );
+        
+        // server thread blocks on ISR
         thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR );
+
+#if DEBUG_HAL_IOC_RX 
+if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != IOC_WRITE ) )
+printk("\n[%s] thread[%x,%x] blocks & deschedules after lauching RX transfer\n",
+__FUNCTION__ , this->process->pid, this->trdid );
+#endif
+
+#if DEBUG_HAL_IOC_TX
+if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == IOC_WRITE) )
+printk("\n[%s] thread[%x,%x] blocks & deschedules after lauching TX transfer\n",
+__FUNCTION__ , this->process->pid, this->trdid );
+#endif
+        // server thread deschedules
         sched_yield("blocked on ISR");
 
-        // the IO operation status is reported in the command by the ISR
+        // exit critical section
+        hal_restore_irq( save_sr );
     }
     
 #if DEBUG_HAL_IOC_RX
 cycle = (uint32_t)hal_get_cycles();
-if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != TXT_WRITE) )
-printk("\n[DBG] %s : thread %x exit after RX / cycle %d\n",
-__FUNCTION__ , CURRENT_THREAD , cycle );
+if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != IOC_WRITE) )
+printk("\n[%s] thread[%x,%x] exit after RX for client thread[%x,%x] / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, client_pid, client_trdid, cycle );
 #endif
 
 #if DEBUG_HAL_IOC_TX
 cycle = (uint32_t)hal_get_cycles();
-if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == TXT_WRITE) )
-printk("\n[DBG] %s : thread %x exit after TX / cycle %d\n",
-__FUNCTION__ , CURRENT_THREAD , cycle );
+if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == IOC_WRITE) )
+printk("\n[%s] thread[%x,%x] exit after TX for client thread[%x,%x] / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, client_pid, client_trdid, cycle );
 #endif
 
@@ -171,21 +206,31 @@
     error_t  error = 0;
 
+    // get extended pointer on server thread
+    xptr_t server_xp = XPTR( local_cxy , chdev->server );
+
     // get extended pointer on client thread
-    xptr_t root = XPTR( local_cxy , &chdev->wait_root );
+    xptr_t root      = XPTR( local_cxy , &chdev->wait_root );
     xptr_t client_xp = XLIST_FIRST( root , thread_t , wait_list );
-
-    // get extended pointer on server thread
-    xptr_t server_xp = XPTR( local_cxy , &chdev->server );
 
     // get client thread cluster and local pointer
     cxy_t      client_cxy = GET_CXY( client_xp );
-    thread_t * client_ptr = (thread_t *)GET_PTR( client_xp );
+    thread_t * client_ptr = GET_PTR( client_xp );
 
     // get command type
     uint32_t   cmd_type = hal_remote_l32( XPTR( client_cxy , &client_ptr->ioc_cmd.type ) );
     
+#if (DEBUG_HAL_IOC_RX || DEBUG_HAL_IOC_TX)
+uint32_t    cycle        = (uint32_t)hal_get_cycles();
+process_t * process      = hal_remote_lpt( XPTR( client_cxy , &client_ptr->process ) );
+pid_t       client_pid   = hal_remote_l32( XPTR( client_cxy , &process->pid ) );
+trdid_t     client_trdid = hal_remote_l32( XPTR( client_cxy , &client_ptr->trdid ) );
+thread_t  * server       = GET_PTR( server_xp );
+pid_t       server_pid   = server->process->pid;
+trdid_t     server_trdid = server->trdid;
+#endif
+
     // get SOCLIB_BDV device cluster and local pointer
     cxy_t      bdv_cxy  = GET_CXY( chdev->base );
-    uint32_t * bdv_ptr  = (uint32_t *)GET_PTR( chdev->base );
+    uint32_t * bdv_ptr  = GET_PTR( chdev->base );
 
     // get BDV status register and acknowledge IRQ
@@ -197,8 +242,7 @@
 
 #if DEBUG_HAL_IOC_RX
-uint32_t cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_HAL_IOC_RX < cycle )
-printk("\n[DBG] %s : IOC_IRQ / RX transfer / client %x / server %x / cycle %d\n",
-__FUNCTION__, client_ptr , chdev->server , cycle );
+printk("\n[%s] RX transfer completed for client[%x,%x] / server[%x,%x] / cycle %d\n",
+__FUNCTION__, client_pid, client_trdid, server_pid, server_trdid, cycle );
 #endif
 
@@ -209,8 +253,7 @@
 
 #if DEBUG_HAL_IOC_TX
-uint32_t cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_HAL_IOC_TX < cycle )
-printk("\n[DBG] %s : IOC_IRQ / RX transfer / client %x / server %x / cycle %d\n",
-__FUNCTION__, client_ptr , chdev->server , cycle );
+printk("\n[%s] TX transfer completed for client[%x,%x] / server[%x,%x] / cycle %d\n",
+__FUNCTION__, client_pid, client_trdid, server_pid, server_trdid, cycle );
 #endif
 
