Changeset 614 for trunk/kernel/devices


Ignore:
Timestamp:
Jan 15, 2019, 1:59:32 PM (6 years ago)
Author:
alain
Message:

1) introduce a dev_ioc_sync_write() function in IOC API,

to improve the DEVFS synchronous update.

2) fix a big bug in both the user_dir_create() and user_dir_destroy()

functions: add an extended pointer on the reference client process
in the function's arguments.

Location:
trunk/kernel/devices
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/devices/dev_ioc.c

    r605 r614  
    9191// This static function is called by dev_ioc_read() & dev_ioc_write() functions.
    9292// It builds and registers the command in the calling thread descriptor.
    93 // Then, it registers the calling thead in IOCchdev waiting queue.
     93// Then, it registers the calling thead in IOC chdev waiting queue.
    9494// Finally it blocks on the THREAD_BLOCKED_IO condition and deschedule.
    9595////////////////////////////////////i/////////////////////////////////////////////
     
    108108    if( chdev_dir.iob )
    109109    {
    110         if ( cmd_type == IOC_READ ) dev_mmc_inval( XPTR( local_cxy , buffer ) , count<<9 );
    111         else                        dev_mmc_sync ( XPTR( local_cxy , buffer ) , count<<9 );
     110        if (cmd_type == IOC_READ) dev_mmc_inval( XPTR( local_cxy , buffer ) , count<<9 );
     111        else                      dev_mmc_sync ( XPTR( local_cxy , buffer ) , count<<9 );
    112112    }
    113113
     
    162162
    163163    return dev_ioc_access( IOC_READ , buffer , lba , count );
    164 
    165 #if DEBUG_DEV_IOC_RX
    166 cycle = (uint32_t)hal_get_cycles();
    167 if( DEBUG_DEV_IOC_RX < cycle )
    168 printk("\n[%s] thread[%x,%x] exit / lba  %x / buffer %x / cycle %d\n",
    169 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle );
    170 #endif
    171 
    172164}
    173165
     
    187179
    188180    return dev_ioc_access( IOC_WRITE , buffer , lba , count );
    189 
    190 #if DEBUG_DEV_IOC_TX
    191 cycle = (uint32_t)hal_get_cycles();
    192 if( DEBUG_DEV_IOC_TX < cycle )
    193 printk("\n[%s] thread[%x,%x] exit / lba  %x / buffer %x / cycle %d\n",
    194 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle );
    195 #endif
    196 
    197181}
     182
     183
     184
     185
     186
     187//////////////////////////////////////////////////////////////////////////////////
     188// This static function is called by dev_ioc_sync_read() & dev_ioc_sync_write().
     189// It builds and registers the command in the calling thread descriptor, and
     190// calls directly the blocking IOC driver command, that returns only when the
     191// IO operation is completed.
     192////////////////////////////////////i/////////////////////////////////////////////
     193error_t dev_ioc_sync_access( uint32_t   cmd_type,
     194                             uint8_t  * buffer,
     195                             uint32_t   lba,
     196                             uint32_t   count )
     197{
     198    // get pointer on calling thread
     199    thread_t * this = CURRENT_THREAD;
     200
     201    // software L2/L3 cache coherence for memory buffer
     202    if( chdev_dir.iob )
     203    {
     204        if (cmd_type == IOC_SYNC_READ) dev_mmc_inval( XPTR(local_cxy,buffer) , count<<9 );
     205        else                           dev_mmc_sync ( XPTR(local_cxy,buffer) , count<<9 );
     206    }
     207
     208    // get extended pointer on IOC[0] chdev
     209    xptr_t  ioc_xp = chdev_dir.ioc[0];
     210
     211// check ioc_xp
     212assert( (ioc_xp != XPTR_NULL) , "undefined IOC chdev descriptor" );
     213
     214    // register command in calling thread descriptor
     215    this->ioc_cmd.dev_xp    = ioc_xp;
     216    this->ioc_cmd.type      = cmd_type;
     217    this->ioc_cmd.buf_xp    = XPTR( local_cxy , buffer );
     218    this->ioc_cmd.lba       = lba;
     219    this->ioc_cmd.count     = count;
     220
     221    // get driver command function
     222    cxy_t       ioc_cxy = GET_CXY( ioc_xp );
     223    chdev_t   * ioc_ptr = GET_PTR( ioc_xp );
     224    dev_cmd_t * cmd = (dev_cmd_t *)hal_remote_lpt( XPTR( ioc_cxy , &ioc_ptr->cmd ) );
     225
     226    // get core local index for the core handling the IOC IRQ
     227    thread_t * server = (thread_t *)hal_remote_lpt( XPTR( ioc_cxy , &ioc_ptr->server ) );
     228    core_t   * core   = (core_t *)hal_remote_lpt( XPTR( ioc_cxy , &server->core ) );
     229    lid_t      lid    = (lid_t)hal_remote_l32( XPTR( ioc_cxy , &core->lid ) );
     230
     231    // mask the IRQ
     232    dev_pic_disable_irq( lid , ioc_xp );
     233
     234    // call driver function
     235    cmd( XPTR( local_cxy , this ) );
     236
     237    // unmask the IRQ
     238    dev_pic_enable_irq( lid , ioc_xp );
     239
     240    // return I/O operation status from calling thread descriptor
     241    return this->ioc_cmd.error;
     242
     243}  // end ioc_sync_access()
    198244
    199245/////////////////////////////////////////////
     
    202248                           uint32_t   count )
    203249{
    204     // get pointer on calling thread
    205     thread_t * this = CURRENT_THREAD;
    206250
    207251#if DEBUG_DEV_IOC_RX
    208 uint32_t cycle = (uint32_t)hal_get_cycles();
     252thread_t * this  = CURRENT_THREAD;
     253uint32_t   cycle = (uint32_t)hal_get_cycles();
     254if( DEBUG_DEV_IOC_RX < cycle )
     255printk("\n[%s] thread[%x,%x] : lba  %x / buffer %x / cycle %d\n",
     256__FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle );
     257#endif
     258
     259    return dev_ioc_sync_access( IOC_SYNC_READ , buffer , lba , count );
     260}
     261
     262//////////////////////////////////////////////
     263error_t dev_ioc_sync_write( uint8_t  * buffer,
     264                            uint32_t   lba,
     265                            uint32_t   count )
     266{
     267
     268#if DEBUG_DEV_IOC_RX
     269thread_t * this  = CURRENT_THREAD;
     270uint32_t   cycle = (uint32_t)hal_get_cycles();
    209271if( DEBUG_DEV_IOC_RX < cycle )
    210272printk("\n[%s] thread[%x,%x] enters / lba  %x / buffer %x / cycle %d\n",
     
    212274#endif
    213275
    214     // software L2/L3 cache coherence for memory buffer
    215     if( chdev_dir.iob ) dev_mmc_inval( XPTR( local_cxy , buffer ) , count<<9 );
    216 
    217     // get extended pointer on IOC[0] chdev
    218     xptr_t  ioc_xp = chdev_dir.ioc[0];
    219 
    220     assert( (ioc_xp != XPTR_NULL) , "undefined IOC chdev descriptor" );
    221 
    222     // register command in calling thread descriptor
    223     this->ioc_cmd.dev_xp    = ioc_xp;
    224     this->ioc_cmd.type      = IOC_SYNC_READ;
    225     this->ioc_cmd.buf_xp    = XPTR( local_cxy , buffer );
    226     this->ioc_cmd.lba       = lba;
    227     this->ioc_cmd.count     = count;
    228 
    229     // get driver command function
    230     cxy_t       ioc_cxy = GET_CXY( ioc_xp );
    231     chdev_t   * ioc_ptr = (chdev_t *)GET_PTR( ioc_xp );
    232     dev_cmd_t * cmd = (dev_cmd_t *)hal_remote_lpt( XPTR( ioc_cxy , &ioc_ptr->cmd ) );
    233 
    234     // get core local index for the core handling the IOC IRQ
    235     thread_t * server = (thread_t *)hal_remote_lpt( XPTR( ioc_cxy , &ioc_ptr->server ) );
    236     core_t   * core   = (core_t *)hal_remote_lpt( XPTR( ioc_cxy , &server->core ) );
    237     lid_t      lid    = (lid_t)hal_remote_l32( XPTR( ioc_cxy , &core->lid ) );
    238 
    239     // mask the IRQ
    240     dev_pic_disable_irq( lid , ioc_xp );
    241 
    242     // call driver function
    243     cmd( XPTR( local_cxy , this ) );
    244 
    245     // unmask the IRQ
    246     dev_pic_enable_irq( lid , ioc_xp );
    247 
    248 #if DEBUG_DEV_IOC_RX
    249 cycle = (uint32_t)hal_get_cycles();
    250 if( DEBUG_DEV_IOC_RX < cycle )
    251 printk("\n[%s] thread[%x,%x] exit / lba  %x / buffer %x / cycle %d\n",
    252 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle );
    253 #endif
    254 
    255     // return I/O operation status from calling thread descriptor
    256     return this->ioc_cmd.error;
    257 
    258 }  // end ioc_sync_read()
    259 
     276    return dev_ioc_sync_access( IOC_SYNC_WRITE , buffer , lba , count );
     277}
     278
  • trunk/kernel/devices/dev_ioc.h

    r457 r614  
    3838 * magnetic hard disk or a SD card, that can store blocks of data in a linear array
    3939 * of sectors indexed by a simple lba (logic block address).
    40  * It supports three command types:
    41  * - READ      : move blocks from device to memory, with a descheduling policy.
    42  * - WRITE     : move blocks from memory to device, with a descheduling policy.
    43  * - SYNC_READ : move blocks from device to memory, with a busy waiting policy.
     40 * It supports four command types:
     41 * - READ       : move blocks from device to memory, with a descheduling policy.
     42 * - WRITE      : move blocks from memory to device, with a descheduling policy.
     43 * - SYNC_READ  : move blocks from device to memory, with a busy waiting policy.
     44 * - SYNC_WRITE : move blocks from memory to device, with a busy waiting policy.
    4445
    4546 * A READ or WRITE operation requires dynamic ressource allocation. The calling thread
     
    6465 *    3) release the WTI mailbox to the client cluster WTI allocator.
    6566 *
    66  * The SYNC_READ operation is used by the kernel in the initialisation phase. It does
    67  * not uses the IOC device waiting queue and server thread, and does not use the IOC IRQ,
    68  * but implement a busy-waiting policy for the calling thread.
     67 * The SYNC_READ and SYNC_WRITE operations are used by the kernel in the initialisation
     68 * phase. These operations do not not use the IOC device waiting queue, the server thread,
     69 * and the IOC IRQ, but implement a busy-waiting policy for the calling thread.
    6970 *****************************************************************************************/
    7071
     
    8586 *****************************************************************************************/
    8687
    87 enum ioc_impl_e
     88typedef enum
    8889{
    8990    IMPL_IOC_BDV =   0,     
     
    99100 *****************************************************************************************/
    100101
    101 enum
     102typedef enum
    102103{
    103104    IOC_READ       = 0,
    104105    IOC_WRITE      = 1,
    105106    IOC_SYNC_READ  = 2,
    106 };
     107    IOC_SYNC_WRITE = 3,
     108}
     109cmd_type_t;
    107110
    108111typedef struct ioc_command_s
     
    131134
    132135/******************************************************************************************
    133  * This blocking function try to tranfer one or several contiguous blocks of data
     136 * This blocking function moves one or several contiguous blocks of data
    134137 * from the block device to a local memory buffer. The corresponding request is actually
    135138 * registered in the device pending request queue, and the calling thread is descheduled,
     
    147150
    148151/******************************************************************************************
    149  * This blocking function try to tranfer one or several contiguous blocks of data
     152 * This blocking function moves one or several contiguous blocks of data
    150153 * from a local memory buffer to the block device. The corresponding request is actually
    151154 * registered in the device pending request queue, and the calling thread is descheduled,
     
    163166
    164167/******************************************************************************************
    165  * This blocking function try to tranfer one or several contiguous blocks of data
    166  * from the block device to a memory buffer.
     168 * This blocking function moves one or several contiguous blocks of data
     169 * from the block device to a local memory buffer.
    167170 * It does  not uses the IOC device waiting queue and server thread, and does not use
    168171 * the IOC IRQ, but call directly the relevant IOC driver, implementing a busy-waiting
     
    179182                           uint32_t       count );
    180183
     184/******************************************************************************************
     185 * This blocking function moves one or several contiguous blocks of data
     186 * from a local memory buffer to the block device.
     187 * It does  not uses the IOC device waiting queue and server thread, and does not use
     188 * the IOC IRQ, but call directly the relevant IOC driver, implementing a busy-waiting
     189 * policy for the calling thread.
     190 * It must be called in the client cluster.
     191 ******************************************************************************************
     192 * @ buffer    : local pointer on source buffer in memory (must be block aligned).
     193 * @ lba       : first block index on device.
     194 * @ count     : number of blocks to transfer.
     195 * @ returns 0 if success / returns EINVAL if error.
     196 *****************************************************************************************/
     197error_t dev_ioc_sync_write( uint8_t      * buffer,
     198                            uint32_t       lba,
     199                            uint32_t       count );
     200
    181201#endif  /* _DEV_IOC_H */
Note: See TracChangeset for help on using the changeset viewer.