Index: trunk/kernel/devices/dev_ioc.h
===================================================================
--- trunk/kernel/devices/dev_ioc.h	(revision 690)
+++ trunk/kernel/devices/dev_ioc.h	(revision 1)
@@ -2,5 +2,5 @@
  * dev_ioc.h - IOC (Block Device Controler) generic device API definition.
  * 
- * Author  Alain Greiner    (2016,2017,2018,2019,2020)
+ * Author  Alain Greiner    (2016)
  *
  * Copyright (c) UPMC Sorbonne Universites
@@ -25,10 +25,9 @@
 #define _DEV_IOC_H
 
-#include <kernel_config.h>
-#include <hal_kernel_types.h>
+#include <hal_types.h>
 
 /****  Forward declarations  ****/
 
-struct chdev_s;
+struct device_s;
 
 /*****************************************************************************************
@@ -38,30 +37,27 @@
  * magnetic hard disk or a SD card, that can store blocks of data in a linear array
  * of sectors indexed by a simple lba (logic block address).
+ * It supports two command types:
+ * - READ  : move a given number of contiguous blocks from device to a memory buffer.
+ * - WRITE : move a given number of contiguous blocks from a memory buffer to device.
  *
- * It supports four command types:
- * - READ       : move blocks from device to memory, with a descheduling policy.
- * - WRITE      : move blocks from memory to device, with a descheduling policy.
- * - SYNC_READ  : move blocks from device to memory, with a busy waiting policy.
- * - SYNC_WRITE : move blocks from memory to device, with a busy waiting policy.
- *
- * For the READ or WRITE operations, the client thread is descheduled, and the work
- * is done by the server thread associated to the IOC device:
- * The client thread calls the dev_ioc_move_data() kernel functions that (i) registers
- * the command in the client thread descriptor, (ii) registers the client thread 
- * in the IOC device waiting queue, and (iii) blocks on the THREAD_BLOCKED_IO condition
- * and deschedules.
- * The server thread attached to the IOC device descriptor handles the commands
- * registered in the waiting queue, calling the IOC driver function.
- * Most IOC device implementations have a DMA capability, but some implementations,
- * such as the RDK (Ram Disk) implementation does not use DMA.
- * When the server thread completes an I/O operation, it reactivates the client thread.
- *
- * The SYNC_READ and SYNC_WRITE operations are used by the kernel in the initialisation
- * phase, to update the FAT (both the FAT mapper and the FAT on IOC device), or to update
- * a directory on IOC device when a new file is created. 
- * These synchronous operations do not not use the IOC device waiting queue, 
- * the server thread, and the IOC IRQ. The client thread does not deschedules:
- * it registers the command in the thread descriptor, calls directly the IOC driver,
- * and uses a busy-waiting policy to poll the IOC device status.
+ * An I/O operation requires dynamic ressource allocation, and is always blocking for
+ * the client thread. The general scenario is detailed below.
+ * A) the client thread start the I/O operation, by calling the dev_ioc_read()
+ *    or the dev_ioc_write() kernel functions that perform the following actions: 
+ *    1) it get a free WTI mailbox from the client cluster WTI allocator.
+ *    2) it enables the WTI IRQ on the client cluster ICU and update interrupt vector.
+ *    3) it access the PIC to link the WTI mailbox to the IOC IRQ.
+ *    4) it builds the command descriptor.
+ *    5) it registers in the IOCdevice waiting queue. 
+ *    6) itblock on the THREAD_BLOCKED_IO condition and deschedule.
+ * B) The server thread attached to the IOC device descriptor handles the commands
+ *    registered in the waiting queue, calling the IOC driver function.
+ *    Most hardware implementation have a DMA capability, but some implementations,
+ *    such as the RDK (Ram Disk) implementation does not use DMA.
+ * C) The ISR signaling the I/O operation completion reactivates the client thread,
+ *    that releases the allocated resources:
+ *    1) access the PIC to unlink the IOC IRQ.
+ *    2) disable the WTI IRQ in the client cluster ICU and update interrupt vector.
+ *    3) release the WTI mailbox to the client cluster WTI allocator.
  *****************************************************************************************/
 
@@ -82,5 +78,5 @@
  *****************************************************************************************/
 
-typedef enum
+enum ioc_impl_e
 {
     IMPL_IOC_BDV =   0,     
@@ -93,23 +89,14 @@
 
 /******************************************************************************************
- * This structure defines the IOC command for all drivers implementing the IOC device.
+ * This defines the (implementation independant)  command passed to the driver.
  *****************************************************************************************/
-
-typedef enum
-{
-    IOC_READ       = 0,
-    IOC_WRITE      = 1,
-    IOC_SYNC_READ  = 2,
-    IOC_SYNC_WRITE = 3,
-}
-ioc_cmd_type_t;
 
 typedef struct ioc_command_s
 {
-    xptr_t      dev_xp;     /*! extended pointer on IOC device descriptor                */
-    uint32_t    type;       /*! command type above                                       */
+    xptr_t      dev_xp;      /*! extended pointer on device descriptor                    */
+    uint32_t    to_mem;     /*! requested operation (WRITE if zero / READ if non-zero)   */
     uint32_t    lba;        /*! first block index                                        */
     uint32_t    count;      /*! number of blocks                                         */
-    xptr_t      buf_xp;     /*! extended pointer on kernel memory buffer                 */
+    xptr_t      buf_xp;     /*! extended pointer on memory buffer                        */
     uint32_t    error;      /*! operation status (0 if success)                          */
 }
@@ -117,95 +104,68 @@
 
 /******************************************************************************************
- * This function returns a printable string for a IOC command type.
+ * This function completes the IOC device descriptor initialisation,
+ * namely the link with the implementation specific driver.
+ * The func, impl, channel, is_rxt, base, and size fields must be previously initialised.
+ * It calls the specific driver initialisation function, to initialise the hardware
+ * device and the specific data structures when required.
+ * It creates the associated server thread.
+ * It can be executed in another cluster than the cluster containing the device descriptor
+ * or the hardware device itself.
  ******************************************************************************************
- * @ cmd  : command type.
- * @ return pointer on string.
+ * @ xp_dev     : extended pointer on IOC device descriptor.
  *****************************************************************************************/
-char * dev_ioc_cmd_str( ioc_cmd_type_t cmd );
+void dev_ioc_init( xptr_t  xp_dev );
 
 /******************************************************************************************
- * This function completes the IOC chdev descriptor initialisation,
- * namely the link with the implementation specific driver.
- * The func, impl, channel, is_rx, base fields have been previously initialised.
- * It calls the specific driver initialisation function, to initialise the hardware
- * device and the specific data structures when required.
- * It creates the associated server thread and allocates a WTI from local ICU.
- * It must de executed by a local thread.
+ * This blocking function try to tranfer one or several contiguous blocks of data
+ * from the block device to a memory buffer. The corresponding request is actually
+ * registered in the device pending request queue, and the calling thread is descheduled,
+ * waiting on transfer completion. It will be resumed by the IRQ signaling completion.
+ * It must be called in the client cluster.
  ******************************************************************************************
- * @ chdev     : local pointer on IOC chdev descriptor.
+ * @ buffer    : local pointer on target buffer in memory.
+ * @ lba       : first block index on device.
+ * @ count     : number of blocks to transfer.
+ * @ returns 0 if success / returns EINVAL if error.
  *****************************************************************************************/
-void dev_ioc_init( struct chdev_s * chdev );
+error_t dev_ioc_read( char         * buffer,
+                      uint32_t       lba,
+                      uint32_t       count );
 
 /******************************************************************************************
- * This blocking function register an asynchronous READ request : move <count> contiguous
- * blocks from the block device, starting from block defined by the <lba> argument, to a
- * kernel buffer defined by the <buffer_xp> argument.
- * It register the request in the client thread descriptor, it register the client thread
- * in the IOC device queue, it blocks on the THREAD_BLOCKED_IO condition, and deschedules.
- * It will be reactivated by the DEV server thread when the transfer is completed.
- * It can be executed by a thread running in any cluster.
+ * This blocking function try to tranfer one or several contiguous blocks of data
+ * from a memory buffer to the block device. The corresponding request is actually
+ * registered in the device pending request queue, and the calling thread is descheduled,
+ * waiting on transfer completion. It will be resumed by the IRQ signaling completion.
+ * It must be called in the client cluster.
  ******************************************************************************************
- * @ buffer_xp : extended pointer on kernel buffer in memory (must be block aligned).
+ * @ buffer    : local pointer on source buffer in memory.
  * @ lba       : first block index on device.
  * @ count     : number of blocks to transfer.
- * @ returns 0 if success / returns -1 if error.
+ * @ returns 0 if success / returns EINVAL if error.
  *****************************************************************************************/
-error_t dev_ioc_read( xptr_t    buffer_xp,
-                      uint32_t  lba,
-                      uint32_t  count );
+error_t dev_ioc_write( char         * buffer,
+                       uint32_t       lba,
+                       uint32_t       count );
 
 /******************************************************************************************
- * This blocking function register an asynchronous WRITE request : move <count> contiguous
- * blocks from a kernel buffer defined by the <buffer_xp> argument to the block device,
- * starting from block defined by the <lba> argument.
- * It register the request in the client thread descriptor, it register the client thread
- * in the IOC device queue, it blocks on the THREAD_BLOCKED_IO condition, and deschedules.
- * It will be reactivated by the DEV server thread when the transfer is completed.
- * It can be executed by a thread running in any cluster.
+ * This function is executed by the server thread associated to the IOC device descriptor. 
+ * This thread is created and activated by the dev_ioc_init() function.
+ * It executes an infinite loop to handle sequencially all commands registered 
+ * by the client threads in the device waiting queue, calling the driver CMD function. 
+ *  
+ * - If the peripheral can only handle one single command, the driver block the server 
+ *   thread on the THREAD_BLOCKED_DEV_ISR condition, waiting I/O operation conmpletion.
+ *   The server thread must be reacticated by the driver ISR function.
+ * - If the peripheral can handle several commands in parallel (AHCI is an example), the
+ *   driver does not block the server thread (it is only descheduled if the number of
+ *   commands exceeeds the max number of parallel commands supported by the peripheral.
+ *
+ * When the waiting queue is empty, the server thread blocks on the THREAD_BLOCKED_CMD
+ * condition and deschedule. It is re-activated by a client thread registering a command.
  ******************************************************************************************
- * @ buffer_xp : extended pointer on kernel buffer in memory (must be block aligned).
- * @ lba       : first block index on device.
- * @ count     : number of blocks to transfer.
- * @ returns 0 if success / returns -1 if error.
+ * @ dev     : local pointer on IOC device descriptor.
  *****************************************************************************************/
-error_t dev_ioc_write( xptr_t    buffer_xp,
-                       uint32_t  lba,
-                       uint32_t  count );
-
-/******************************************************************************************
- * This blocking function executes a synchronous SYNC_READ request : it moves <count>
- * contiguous blocks of data from the block device, starting from block defined by the
- * <lba> argument to a kernel memory buffer, defined by the <buffer_xp> argument. 
- * The request is registered in the calling thread descriptor, but the client thread calls
- * directly the driver cmd function, that is also a blocking function returning only
- * when the transfer is completed.
- * It can be executed by a thread running in any cluster.
- ******************************************************************************************
- * @ buffer_xp : extended pointer on kernel buffer in memory (must be block aligned).
- * @ lba       : first block index on device.
- * @ count     : number of blocks to transfer.
- * @ returns 0 if success / returns -1 if error.
- *****************************************************************************************/
-error_t dev_ioc_sync_read( xptr_t    buffer_xp,
-                           uint32_t  lba,
-                           uint32_t  count );
-
-/******************************************************************************************
- * This blocking function executes a synchronous SYNC_WRITE request : it moves <count>
- * contiguous blocks of data from a kernel memory buffer, defined by the <buffer_xp>
- * argument to the block device, starting from block defined by the <lba> argument. 
- * The request is registered in the calling thread descriptor, but the client thread calls
- * directly the driver cmd() function, that is also a blocking function returning only
- * when the transfer is completed.
- * It can be executed by a thread running in any cluster.
- ******************************************************************************************
- * @ buffer_xp : extended pointer on kernel buffer in memory (must be block aligned).
- * @ lba       : first block index on device.
- * @ count     : number of blocks to transfer.
- * @ returns 0 if success / returns -1 if error.
- *****************************************************************************************/
-error_t dev_ioc_sync_write( xptr_t    buffer_xp,
-                            uint32_t  lba,
-                            uint32_t  count );
+void dev_ioc_server( struct device_s * dev );
 
 #endif	/* _DEV_IOC_H */
