Index: trunk/kernel/drivers/soclib/soclib_hba.c
===================================================================
--- trunk/kernel/drivers/soclib/soclib_hba.c	(revision 4)
+++ trunk/kernel/drivers/soclib/soclib_hba.c	(revision 23)
@@ -72,5 +72,8 @@
     chdev->ext.ioc.count = block_count;
 
-	// reset SOCLIB_HBA driver global variables
+    // activate HBA interrupts 
+    hal_remote_sw( XPTR( hba_cxy , hba_ptr + HBA_PXIE_REG ) , 0x1 );
+
+	// reset SOCLIB_HBA driver global variable
     hba_active_slots = 0;
 
@@ -78,16 +81,18 @@
 
 
-//////////////////////////////////////////////////////////////////
-void __attribute__ ((noinline)) soclib_hba_command( xptr_t th_xp )
+//////////////////////////////////////////////////////////////
+void __attribute__ ((noinline)) soclib_hba_cmd( xptr_t th_xp )
 {
 
-    uint32_t           to_mem;       // to_mem : command argument
+    uint32_t           cmd_type;     // IOC_READ / IOC_WRITE / IOC_SYNC_READ
     uint32_t           lba;          // lba    : command argument
     uint32_t           count;        // count  : command argument
     xptr_t             buf_xp;       // buffer : command argument
     xptr_t             dev_xp;       // device : command argument
+
     uint32_t           cmd_id;       // current slot index in command bit_vector
     hba_cmd_desc_t   * cmd_desc;     // command descriptor pointer   
     hba_cmd_table_t  * cmd_table;    // command table pointer
+
     bool_t             found;
     uint32_t           iter; 
@@ -98,5 +103,5 @@
 
     // get command arguments and extended pointer on IOC device
-    to_mem    =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.to_mem ) );
+    cmd_type  =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.type   ) );
     lba       =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.lba    ) );
     count     =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.count  ) );
@@ -135,5 +140,5 @@
         }
 
-        if( found )  // register and starts the I/O operation
+        if( found )  // slot available in SOCLIB_HBA 
         {
             // compute pointers on command descriptor and command table    
@@ -157,57 +162,80 @@
             cmd_desc->prdtl[0] = 1;
             cmd_desc->prdtl[1] = 0;
-            if( to_mem ) cmd_desc->flag[0] = 0x00;
-            else         cmd_desc->flag[0] = 0x40;     
+            if( cmd_type == IOC_WRITE ) cmd_desc->flag[0] = 0x40;
+            else                        cmd_desc->flag[0] = 0x00;     
 
 #if USE_IOB // software L2/L3 cache coherence 
 
-            // compute physical addresses 
-            paddr_t   cmd_desc_paddr;    // command descriptor physical address
-            paddr_t   cmd_table_paddr;   // command table header physical address
-            bool_t    ident = CONFIG_KERNEL_IDENTITY;
-            
-            error = vmm_v2p_translate( ident , cmd_table , &cmd_table_paddr );
-            if( error )
-            {
-                printk("\n[PANIC] in %s : cannot get paddr fo cmd_table\n", __FUNCTION__ );
-                hal_core_sleep()
-            }
-
-            error = vmm_v2p_translate( ident , cmd_desc , &cmd_desc_paddr );
-            if( error )
-            {
-                printk("\n[PANIC] in %s : cannot get paddr fo cmd_desc\n", __FUNCTION__ );
-                hal_core_sleep()
-            }
-
-            // update L3 for command table 
-            dev_mmc_sync( cmd_table_paddr , sizeof(hba_cmd_table_t) );
-
-            // update L3 for command descriptor
-            dev_mmc_sync( cmd_desc_paddr , sizeof(hba_cmd_desc_t) );
+            dev_mmc_sync( cmd_table , sizeof(hba_cmd_table_t) );
+            dev_mmc_sync( cmd_desc , sizeof(hba_cmd_desc_t) );
 
 #endif // end software L2/L3 cache coherence
-
-            // activates HBA interrupts 
-            hal_remote_sw( XPTR( hba_cxy , hba_ptr + HBA_PXIE_REG ) , 0x1 );
 
             // set hba_owner_thread[slot] 
             hba_owner_thread[cmd_id] = th_xp;
 
+            // register slot in bit_vector
+            hba_active_slots |= 1<<cmd_id;
+ 
             // set HBA_PXCI_REG to start transfer
             hal_remote_sw( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) , 1<<cmd_id );
 
-            ioc_dmsg("INFO in %s : thread %x / buffer = %llx at cycle %d\n",
-            __FUNCTION__ , hal_remote_lw( XPTR( th_cxy , &th_ptr->trdid ) ) ,
-            buf_xp , hal_time_stamp() );
-
             // exit the while 
             break;
         }
-        else   // deschedule if no slot available in SOCLIB_HBA
-        {
-            sched_yield();
-        }
-    }  // end while
+        else   // no slot available in SOCLIB_HBA
+        {
+            if( cmd_type == IOC_SYNC_READ )     // fatal if synchronous access
+            {
+                printk("\n[PANIC] in %s : no slot available for a SYNC_READ\n", __FUNCTION__ );
+                hal_core_sleep();
+            }
+            else                                // retry if asynchronous access.
+            {
+                sched_yield();
+            }
+        }
+    }  // end while to get a slot
+
+    // waiting policy depends on the command type
+
+    if( cmd_type == IOC_SYNC_READ )                // polling, busy waiting
+    {
+        uint32_t  pxis;
+        uint32_t  pxci;
+        uint32_t  error;
+        uint32_t  fault_id;
+        while(1)
+        {
+            pxis     = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) );
+            pxci     = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) );
+            error    = (pxis & 0x40000000) >> 30;
+            fault_id = (pxis & 0x1F000000) >> 24;
+
+            if( (pxci & (1<<cmd_id)) == 0 )  // completed
+            {
+                // release slot
+                hba_active_slots &= ~(1<<cmd_id);
+
+                // set operation status in client thread command
+                if( error && (fault_id == cmd_id) ) 
+                {
+                    hal_remote_sw( XPTR( th_cxy , &th_ptr->command.ioc.error ) , 1 );
+                }
+                else
+                {
+                    hal_remote_sw( XPTR( th_cxy , &th_ptr->command.ioc.error ) , 0 );
+                }
+
+                // exit while
+                break;
+            }    
+        }
+    }
+    else                                           // descheduling + IRQ
+    {
+        thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
+        sched_yield();
+    }
             
 } // end soclib_hba_cmd()
@@ -229,5 +257,5 @@
     uint32_t * hba_ptr  = (uint32_t *)GET_PTR( chdev->base );
 
-    // get HBA_PXIS_REG and HBA_PXIS_REG current values
+    // get HBA_PXIS_REG and HBA_PXCI_REG current values
     uint32_t current_pxis = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) );
     uint32_t current_pxci = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) );
