Index: trunk/kernel/devices/dev_txt.c
===================================================================
--- trunk/kernel/devices/dev_txt.c	(revision 1)
+++ trunk/kernel/devices/dev_txt.c	(revision 3)
@@ -35,79 +35,63 @@
 /////////////////////////////////////////////////////////////////////////////////////////
 
-extern devices_directory_t  devices_dir;         // allocated in kernel_init.c
+extern chdev_directory_t  chdev_dir;         // allocated in kernel_init.c
 
-extern devices_input_irq_t  devices_input_irq;   // allocated in kernel_init.c
+extern chdev_pic_input_t  chdev_pic_input;   // allocated in kernel_init.c
 
-//////////////////////////////////
-void dev_txt_init( xptr_t  dev_xp )
+////////////////////////////////////
+void dev_txt_init( chdev_t * chdev )
 {
-    // get device descriptor cluster and local pointer
-    cxy_t      dev_cxy = GET_CXY( dev_xp );
-    device_t * dev_ptr = (device_t *)GET_PTR( dev_xp );
+    // the local ICU chdev must be initialized before the TXT chdev, because
+    // the TXT chdev initialisation requires allocation of a WTI from local ICU
+    xptr_t  icu_xp  = chdev_dir.icu[local_cxy];
+    assert( (icu_xp != XPTR_NULL) , __FUNCTION__ , "ICU not initialised before TXT" );
 
-    // get implementation index from device descriptor
-    uint32_t  impl = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->impl ) );
+    // get implementation and channel index
+    uint32_t  impl    = chdev->impl;
+    uint32_t  channel = chdev->channel;
 
-    // get channel index from device descriptor
-    // uint32_t  channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) );
-
-    // set fields "cmd", "isr", and "name" in device descriptor
-    // and call implementation specific init function
-
-    // TODO replace fixed "TXT_TTY" name by a channel indexed "TXT_TTY%d" name
-    // as soon as the sprintk() function is available
-
+    // set fields "cmd", "isr", and call driver init function
     if( impl == IMPL_TXT_TTY )
     {
-        hal_remote_spt( XPTR( dev_cxy , &dev_ptr->cmd ) , &soclib_tty_command );
-        hal_remote_spt( XPTR( dev_cxy , &dev_ptr->isr ) , &soclib_tty_isr );
-        // sprintk( name , "TXT_TTY%d" , channel )
-        hal_remote_memcpy( XPTR( dev_cxy , &dev_ptr->name ),
-                           XPTR( local_cxy , "TXT_TTY" ) , 16 );
-        soclib_tty_init( dev_xp );
+        chdev->cmd = &soclib_tty_cmd;
+        chdev->isr = &soclib_tty_isr;
+        soclib_tty_init( chdev );
     }
     else
     {
-        printk("\n[PANIC] in %s: undefined TXT device implementation\n", __FUNCTION__ );
-        hal_core_sleep();
+        assert( false , __FUNCTION__ , "undefined TXT device implementation" );
     }
 
+    // get a WTI mailbox from local ICU
+    uint32_t wti_id = dev_icu_wti_alloc();
+
+    assert( (wti_id != -1) , __FUNCTION__ , "cannot allocate WTI mailbox" );
+
+    // select a core
+    lid_t lid = cluster_select_local_core();
+
+    // enable WTI IRQ and update WTI interrupt vector
+    dev_icu_enable_irq( lid , WTI_TYPE , wti_id , chdev );
+
+    // link IOC IRQ to WTI mailbox in PIC component 
+    uint32_t irq_id = chdev_pic_input.txt[channel];
+    dev_pic_bind_irq( irq_id , local_cxy , wti_id );
+
     // create server thread
-    xptr_t     new_thread_xp;
-    thread_t * new_thread_ptr;
+    thread_t * new_thread;
     error_t    error;
 
-    if( dev_cxy == local_cxy )         // device cluster is local
-    {
-        error = thread_kernel_create( &new_thread_ptr,
-                                      THREAD_DEV,
-                                      &dev_txt_server,
-                                      dev_ptr,
-                                      cluster_select_local_core() );
- 
-        new_thread_xp = XPTR( local_cxy , new_thread_ptr );
-    }
-    else                                        // device cluster is remote
-    {
-        rpc_thread_kernel_create_client( dev_cxy,
-                                         THREAD_DEV,
-                                         &dev_txt_server,
-                                         dev_ptr,
-                                         &new_thread_xp,
-                                         &error );
+    error = thread_kernel_create( &new_thread,
+                                  THREAD_DEV,
+                                  &chdev_sequencial_server,
+                                  chdev,
+                                  lid ); 
+    assert( (error == 0) , __FUNCTION__ , "cannot create server thread" );
 
-        new_thread_ptr = (thread_t *)GET_PTR( new_thread_xp );
-    }
-    if( error )
-    {
-        printk("\n[PANIC] in %s : cannot create server thread\n", __FUNCTION__ );
-        hal_core_sleep();
-    }
-
-    // initialises server field in device descriptor
-    hal_remote_spt( XPTR( dev_cxy , &dev_ptr->server ) , new_thread_ptr );
+    // set "server" field in chdev descriptor
+    chdev->server = new_thread;
     
     // start server thread
-    thread_unblock( new_thread_xp , THREAD_BLOCKED_GLOBAL );
+    thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL );
 
 } // end dev_txt_init()
@@ -115,12 +99,5 @@
 
 //////////////////////////////////////////////////////////////////////////////////
-// This static function is called by dev_txt_read(), dev_txt_write(), and
-// dev_txt_sync_write() functions. 
-// For the TXT_READ and TXT_WRITE operation types:
-//  - it build the command, and registers it in the calling thread descriptor. 
-//  - then, it registers the calling thead in device waiting queue.
-//  - finally, it blocks on the THREAD_BLOCKED_DEV condition and deschedule.
-// For the TXT_SYNC_WRITE operation type:
-//  - it directly call the relevant driver, using a busy waiting policy.
+// This static function is called by dev_txt_read(), dev_txt_write() functions.
 ////////////////////////////////////i/////////////////////////////////////////////
 static error_t dev_txt_access( uint32_t   type,
@@ -135,83 +112,27 @@
 
     // check channel argument
-    if( channel >= CONFIG_MAX_TXT_CHANNELS )
-    {
-        printk("\n[PANIC] in %s : illegal channel index = %d\n", __FUNCTION__ , channel );
-        hal_core_sleep();
-    }
+    assert( (channel < CONFIG_MAX_TXT_CHANNELS) , __FUNCTION__ , "illegal channel index" );
 
-    // get extended pointer on remote TXT device descriptor
-    xptr_t  dev_xp = devices_dir.txt[channel];
+    // get extended pointer on remote TXT chdev descriptor
+    xptr_t  dev_xp = chdev_dir.txt[channel];
 
-    if ( dev_xp == XPTR_NULL )
-    {
-        printk("\n[PANIC] in %s : undefined TXT device descriptor for channel %d\n",
-               __FUNCTION__ , channel );
-        hal_core_sleep();
-    }
+    assert( (dev_xp != XPTR_NULL) , __FUNCTION__ , "undefined TXT chdev descriptor" );
 
     // register command in calling thread descriptor
-    this->dev.txt.dev_xp  = dev_xp;
-    this->dev.txt.type    = type;
-    this->dev.txt.buf_xp  = XPTR( local_cxy , buffer );
-    this->dev.txt.count   = count;
+    this->command.txt.dev_xp  = dev_xp;
+    this->command.txt.type    = type;
+    this->command.txt.buf_xp  = XPTR( local_cxy , buffer );
+    this->command.txt.count   = count;
 
+    // register client thread in waiting queue, activate server thread
+    // block client thread on THREAD_BLOCKED_IO and deschedule.
+    // it is re-activated by the ISR signaling IO operation completion.
+    chdev_register_command( dev_xp , this );
 
-    if( (type == TXT_READ) || (type == TXT_WRITE) )  // descheduling policy
-    {
-        // get a free WTI mailbox  
-        uint32_t wti_id;
-        while( 1 )
-        {
-            wti_id = dev_icu_wti_alloc();
-            if( wti_id == -1 )  sched_yield();
-            else                break;
-        }
-
-        // enable WTI IRQ in local ICU and update WTI interrupt vector
-        dev_icu_enable_irq( local_cxy , CURRENT_CORE->lid , WTI_TYPE , wti_id , dev_xp );
-
-        // link TXT IRQ to WTI mailbox in PIC component 
-        uint32_t irq_id = devices_input_irq.txt[channel];
-        dev_pic_bind_irq( irq_id , local_cxy , wti_id );
-
-        // register client thread in waiting queue, activate server thread
-        // block client thread on THREAD_BLOCKED_IO and deschedule.
-        // it is re-activated by the ISR signaling IO operation completion.
-        device_register_command( dev_xp , this );
-
-        // access PIC to unlink the IOC IRQ
-        dev_pic_unbind_irq( irq_id );
-
-        // disable WTI IRQ in ICU and update interrupt vector
-        dev_icu_disable_irq( local_cxy , CURRENT_CORE->lid , WTI_TYPE , wti_id );
-
-        // release  WTI mailbox
-        dev_icu_wti_release( wti_id );
-
-        txt_dmsg("\n[INFO] in %s : thread %x in process %x completes / error = %d\n", 
-                     __FUNCTION__ , this->trdid , this->process->pid , this->dev.txt.error );
-    }
-    else if( type == TXT_SYNC_WRITE )            // busy waiting policy
-    {
-        // get driver command function pointer from remote TXT device descriptor
-        cxy_t       dev_cxy = GET_CXY( dev_xp );
-        device_t  * dev_ptr = (device_t *)GET_PTR( dev_xp );
-        dev_cmd_t * cmd = (dev_cmd_t *)hal_remote_lpt( XPTR( dev_cxy , &dev_ptr->cmd ) );
-
-        // take the TXT device lock, because the calling thread does NOT
-        // register in device waiting queue for this synchronous command,
-        // and has exclusive access to the terminal...
-        remote_spinlock_lock( XPTR( dev_cxy , &dev_ptr->wait_lock ) );
- 
-        // call directly driver command 
-        cmd( XPTR( local_cxy , this ) );
-
-        // release the TXT device lock
-        remote_spinlock_unlock( XPTR( dev_cxy , &dev_ptr->wait_lock ) );
-    }    
+    txt_dmsg("\n[INFO] in %s : thread %x in process %x completes / error = %d\n", 
+             __FUNCTION__ , this->trdid , this->process->pid , this->command.txt.error );
 
     // return I/O operation status from calling thread descriptor
-    return this->dev.txt.error;  
+    return this->command.txt.error;  
 
 }  // end dev_txt_access()
@@ -225,12 +146,4 @@
 }
  
-///////////////////////////////////////////////
-error_t dev_txt_sync_write( uint32_t   channel,
-                            char     * buffer,
-                            uint32_t   count )
-{
-    return dev_txt_access( TXT_SYNC_WRITE , channel , buffer , count );
-}
- 
 /////////////////////////////////////////
 error_t dev_txt_read( uint32_t   channel,
@@ -240,53 +153,34 @@
 }
 
-/////////////////////////////////////
-void dev_txt_server( device_t * dev )
+///////////////////////////////////////////////
+error_t dev_txt_sync_write( uint32_t   channel,
+                            char     * buffer,
+                            uint32_t   count )
 {
-    xptr_t          client_xp;    // extended pointer on waiting thread
-    cxy_t           client_cxy;   // cluster of client thread
-    thread_t      * client_ptr;   // local pointer on client thread
-    thread_t      * server;       // local pointer on server thread
-    xptr_t          root_xp;      // extended pointer on device waiting queue root
+    // get pointer on calling thread 
+    thread_t * this = CURRENT_THREAD;
 
-    server = CURRENT_THREAD;
+    // get extended pointer on TXT[0] chdev 
+    xptr_t  dev_xp = chdev_dir.txt[channel];
 
-    root_xp = XPTR( local_cxy , &dev->wait_root );
+    // register command in calling thread 
+    this->command.txt.dev_xp  = dev_xp;
+    this->command.txt.type    = TXT_SYNC_WRITE;
+    this->command.txt.buf_xp  = XPTR( local_cxy , buffer );
+    this->command.txt.count   = count;
 
-	// infinite loop handling commands of threads 
-    // registered in the TXT waiting queue
-    while( 1 )
-    {
-        // get lock protecting queue
-        remote_spinlock_lock( XPTR( local_cxy , &dev->wait_lock ) );
+    // get driver command function 
+    cxy_t       dev_cxy = GET_CXY( dev_xp );
+    chdev_t   * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
+    dev_cmd_t * cmd = (dev_cmd_t *)hal_remote_lpt( XPTR( dev_cxy , &dev_ptr->cmd ) );
 
-        // block and deschedule server thread if waiting queue empty 
-        if( xlist_is_empty( root_xp ) )
-        {
-            thread_block( server , THREAD_BLOCKED_DEV_QUEUE );
-            remote_spinlock_unlock( XPTR( local_cxy , &dev->wait_lock ) );
-            sched_yield();
-        }
-        else
-        {
-            remote_spinlock_unlock( XPTR( local_cxy , &dev->wait_lock ) );
-        } 
+    // call directly driver command after taking chdev lock
+    remote_spinlock_lock( XPTR( dev_cxy , &dev_ptr->wait_lock ) );
+    cmd( XPTR( local_cxy , this ) );
+    remote_spinlock_unlock( XPTR( dev_cxy , &dev_ptr->wait_lock ) );
 
-        // get extended pointer on first client thread
-        client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list );
+    // return I/O operation status from calling thread descriptor
+    return this->command.txt.error;
+  
+}  // end dev_txt_sync_write()
 
-        // call driver command function to start I/O operation
-        dev->cmd( client_xp );
-        
-        // get client thread cluster and local pointer
-        client_cxy = GET_CXY( client_xp );
-        client_ptr = (thread_t *)GET_PTR( client_xp );
-
-        // remove the client thread from waiting queue
-        remote_spinlock_lock( XPTR( local_cxy , &dev->wait_lock ) );
-        xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) );
-        remote_spinlock_unlock( XPTR( local_cxy , &dev->wait_lock ) );
-
-    }  // end while
-
-}  // end dev_txt_server()
-
