source: trunk/kernel/fs/devfs.c @ 614

Last change on this file since 614 was 614, checked in by alain, 5 years ago

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.

File size: 26.0 KB
RevLine 
[23]1/*
2 * devfs.c - DEVFS File system API implementation.
3 *
4 * Author   Mohamed Lamine Karaoui (2014,2015)
5 *          Alain Greiner (2016,2017)
6 *
7 * Copyright (c) Sorbonne Universites
8 *
9 * This file is part of ALMOS-MKH.
10 *
11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2.0 of the License.
14 *
15 * ALMOS-MKH is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
[457]25#include <hal_kernel_types.h>
[23]26#include <hal_special.h>
[407]27#include <hal_uspace.h>
[23]28#include <printk.h>
[612]29#include <string.h>
[23]30#include <chdev.h>
[433]31#include <thread.h>
[407]32#include <dev_txt.h>
[188]33#include <cluster.h>
[23]34#include <vfs.h>
[188]35#include <kmem.h>
[23]36#include <devfs.h>
37
[188]38/////////////////////////////////////////////////////////////////////////////////////////
39//     Extern variables
40/////////////////////////////////////////////////////////////////////////////////////////
[23]41
[188]42extern vfs_ctx_t            fs_context[];   // allocated in kernel_init.c
43extern chdev_directory_t    chdev_dir;      // allocated in kernel_init.c
[23]44
[438]45#if (DEBUG_SYS_READ & 1)
[435]46extern uint32_t  enter_devfs_read;
47extern uint32_t  exit_devfs_read;
[407]48#endif
49
[438]50#if (DEBUG_SYS_WRITE & 1)
[435]51extern uint32_t  enter_devfs_write;
52extern uint32_t  exit_devfs_write;
53#endif
54
[568]55/////////////////////////////////////
[484]56devfs_ctx_t * devfs_ctx_alloc( void )
[188]57{
58    kmem_req_t    req;
[23]59
[188]60        req.type    = KMEM_DEVFS_CTX;
61        req.size    = sizeof(devfs_ctx_t);
62    req.flags   = AF_KERNEL | AF_ZERO;
[23]63
[188]64        return (devfs_ctx_t *)kmem_alloc( &req );
65}
[23]66
[188]67/////////////////////////////////////////////
68void devfs_ctx_init( devfs_ctx_t * devfs_ctx,
[204]69                     xptr_t        devfs_dev_inode_xp,
[188]70                     xptr_t        devfs_external_inode_xp )
[23]71{
[204]72    devfs_ctx->dev_inode_xp      = devfs_dev_inode_xp;
[188]73    devfs_ctx->external_inode_xp = devfs_external_inode_xp;
[23]74
[188]75    fs_context[FS_TYPE_DEVFS].extend = devfs_ctx;
76}
[23]77
[188]78/////////////////////////////////////////////////
79void devfs_ctx_destroy( devfs_ctx_t * devfs_ctx )
80{
81    kmem_req_t    req;
[23]82
[188]83    req.type = KMEM_DEVFS_CTX;
84    req.ptr  = devfs_ctx;
85    kmem_free( &req );
86}
[23]87
[437]88/////////////////////////////////////////////////
[602]89void devfs_global_init( xptr_t   root_inode_xp,
[204]90                        xptr_t * devfs_dev_inode_xp,
[188]91                        xptr_t * devfs_external_inode_xp )
[23]92{
93    error_t  error;
[602]94    xptr_t   unused_xp;   // required by vfs_add_child_in_parent()
[23]95
[610]96    // create DEVFS "dev" inode in cluster 0
[457]97    error = vfs_add_child_in_parent( 0,                // cxy
[188]98                                     INODE_TYPE_DIR,
99                                     FS_TYPE_DEVFS,
[602]100                                     root_inode_xp,
[188]101                                     "dev",
[602]102                                     &unused_xp,
103                                     devfs_dev_inode_xp );
[23]104
[612]105    // create dentries <.> and <..> in <dev>
106    error |= vfs_add_special_dentries( *devfs_dev_inode_xp,
107                                       root_inode_xp );
108
[610]109// check success
110assert( (error == 0) , "cannot create <dev>\n" );
[23]111
[614]112#if DEBUG_DEVFS_GLOBAL_INIT
[598]113uint32_t   cycle = (uint32_t)hal_get_cycles();
114thread_t * this  = CURRENT_THREAD;
[614]115if( DEBUG_DEVFS_GLOBAL_INIT < cycle )
[598]116printk("\n[%s] thread[%x,%x] created <dev> inode / cycle %d\n",
117__FUNCTION__, this->process->pid, this->trdid, cycle );
[437]118#endif
119
[457]120    // create DEVFS "external" inode in cluster 0
121    error = vfs_add_child_in_parent( 0,               // cxy
[188]122                                     INODE_TYPE_DIR,
123                                     FS_TYPE_DEVFS,
[204]124                                     *devfs_dev_inode_xp,
125                                     "external",
[602]126                                     &unused_xp,
127                                     devfs_external_inode_xp );
[23]128
[612]129    // create dentries <.> and <..> in <external>
130    error |= vfs_add_special_dentries( *devfs_external_inode_xp,
131                                       *devfs_dev_inode_xp );
[279]132
[612]133// check success
134assert( (error == 0) , "cannot create <external>\n" );
135
[614]136#if DEBUG_DEVFS_GLOBAL_INIT
[433]137cycle = (uint32_t)hal_get_cycles();
[614]138if( DEBUG_DEVFS_GLOBAL_INIT < cycle )
[598]139printk("\n[%s] thread[%x,%x] created <external> inode / cycle %d\n",
140__FUNCTION__, this->process->pid, this->trdid, cycle );
[433]141#endif
142
[602]143}  // end devfs_global_init()
[23]144
[204]145///////////////////////////////////////////////////
146void devfs_local_init( xptr_t   devfs_dev_inode_xp,
147                       xptr_t   devfs_external_inode_xp,
148                       xptr_t * devfs_internal_inode_xp )
[23]149{
150    char          node_name[16];
[188]151    xptr_t        chdev_xp;
152    cxy_t         chdev_cxy;
[407]153    chdev_t     * chdev_ptr;
[188]154    xptr_t        inode_xp;
[602]155    cxy_t         inode_cxy;
156    vfs_inode_t * inode_ptr;
[23]157    uint32_t      channel;
[602]158    xptr_t        unused_xp;    // required by add_child_in_parent()
[612]159    error_t       error;
[23]160
[614]161#if DEBUG_DEVFS_LOCAL_INIT
162uint32_t   cycle = (uint32_t)hal_get_cycles();
163thread_t * this  = CURRENT_THREAD;
164if( DEBUG_DEVFS_LOCAL_INIT < cycle )
165printk("\n[%s] thread[%x,%x] enter / cycle %d\n",
166__FUNCTION__, this->process->pid, this->trdid, cycle );
167#endif
168
[568]169    // create "internal" directory
[188]170    snprintf( node_name , 16 , "internal_%x" , local_cxy );
[610]171
[612]172    error = vfs_add_child_in_parent( local_cxy,
173                                     INODE_TYPE_DIR,
174                                     FS_TYPE_DEVFS,
175                                     devfs_dev_inode_xp,
176                                     node_name,
177                                     &unused_xp,
178                                     devfs_internal_inode_xp );
179
180    // create dentries <.> and <..> in <internal>
181    error |= vfs_add_special_dentries( *devfs_internal_inode_xp,
182                                       devfs_dev_inode_xp );
183
184// check success
185assert( (error == 0) , "cannot create <external>\n" );
186
[614]187#if DEBUG_DEVFS_LOCAL_INIT
188cycle = (uint32_t)hal_get_cycles();
189if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]190printk("\n[%s] thread[%x,%x] created <%s> inode in cluster %x / cycle %d\n",
191__FUNCTION__, this->process->pid, this->trdid, node_name, local_cxy, cycle );
[568]192#endif
[23]193
194    // create MMC chdev inode
[407]195    chdev_xp  = chdev_dir.mmc[local_cxy];
[188]196    if( chdev_xp != XPTR_NULL)
197    {
[602]198        chdev_ptr = GET_PTR( chdev_xp );
[610]199        chdev_cxy = GET_CXY( chdev_xp );
200
[612]201assert( (chdev_cxy == local_cxy ), "illegal MMC chdev in cluster %x\n", local_cxy );
[610]202
[612]203        error = vfs_add_child_in_parent( local_cxy,
204                                         INODE_TYPE_DEV,
205                                         FS_TYPE_DEVFS,
206                                         *devfs_internal_inode_xp,
207                                         chdev_ptr->name,
208                                         &unused_xp,
209                                         &inode_xp );
[602]210
[612]211assert( (error == 0) , "cannot create MMC inode\n" );
212
[602]213        // update child inode "extend" field
214        inode_cxy = GET_CXY( inode_xp );
215        inode_ptr = GET_PTR( inode_xp );
216        hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
217       
[614]218#if DEBUG_DEVFS_LOCAL_INIT
[568]219cycle = (uint32_t)hal_get_cycles();
[614]220if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]221printk("\n[%s] thread[%x,%x] created <mmc> inode in cluster %x\n",
222__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
[568]223#endif
224
[188]225    }
[23]226
227    // create DMA chdev inodes (one DMA channel per core)
[188]228    for( channel = 0 ; channel < LOCAL_CLUSTER->cores_nr ; channel++ )
[23]229    {
[602]230        chdev_xp  = chdev_dir.dma[channel];
[188]231        if( chdev_xp != XPTR_NULL)
232        {
[602]233            chdev_ptr = GET_PTR( chdev_xp );
[610]234            chdev_cxy = GET_CXY( chdev_xp );
235
[612]236assert( (chdev_cxy == local_cxy ), "illegal DMA chdev in cluster %x\n", local_cxy );
[610]237
[612]238            error = vfs_add_child_in_parent( local_cxy,
239                                             INODE_TYPE_DEV,
240                                             FS_TYPE_DEVFS,
241                                             *devfs_internal_inode_xp,
242                                             chdev_ptr->name,
243                                             &unused_xp,
244                                             &inode_xp );
[602]245
[612]246assert( (error == 0) , "cannot create DMA inode\n" );
247
[602]248            // update child inode "extend" field
249            inode_cxy = GET_CXY( inode_xp );
250            inode_ptr = GET_PTR( inode_xp );
251            hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
252       
[614]253#if DEBUG_DEVFS_LOCAL_INIT
[568]254cycle = (uint32_t)hal_get_cycles();
[614]255if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]256printk("\n[%s] thread [%x,%x] created <dma[%d]> inode in cluster %x\n",
257__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]258#endif
[188]259        }
[23]260    }
261
[188]262    // create an IOB inode in cluster containing IOB chdev
263    chdev_xp = chdev_dir.iob;
264    if( chdev_xp != XPTR_NULL )
[23]265    {
[188]266        chdev_cxy = GET_CXY( chdev_xp );
[602]267        chdev_ptr = GET_PTR( chdev_xp );
[610]268
[188]269        if( chdev_cxy == local_cxy )
270        {
[612]271            error = vfs_add_child_in_parent( local_cxy,
272                                             INODE_TYPE_DEV,
273                                             FS_TYPE_DEVFS,
274                                             devfs_external_inode_xp,
275                                             chdev_ptr->name,
276                                             &unused_xp,
277                                             &inode_xp );
[602]278
[612]279assert( (error == 0) , "cannot create IOB inode\n" );
280
[602]281            // update child inode "extend" field
282            inode_cxy = GET_CXY( inode_xp );
283            inode_ptr = GET_PTR( inode_xp );
284            hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
285       
[614]286#if DEBUG_DEVFS_LOCAL_INIT
[568]287cycle = (uint32_t)hal_get_cycles();
[614]288if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]289printk("\n[%s] thread[%x,%x] created <iob> inode in cluster %x\n",
290__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
[568]291#endif
[188]292        }
293    }
[23]294       
[188]295    // create a PIC inode in cluster containing PIC chdev
296    chdev_xp = chdev_dir.pic;
297    if( chdev_xp != XPTR_NULL )
298    {
299        chdev_cxy = GET_CXY( chdev_xp );
[602]300        chdev_ptr = GET_PTR( chdev_xp );
[610]301
[188]302        if( chdev_cxy == local_cxy )
[23]303        {
[612]304            error = vfs_add_child_in_parent( local_cxy,
305                                             INODE_TYPE_DEV,
306                                             FS_TYPE_DEVFS,
307                                             devfs_external_inode_xp,
308                                             chdev_ptr->name,
309                                             &unused_xp,
310                                             &inode_xp );
[602]311
[612]312assert( (error == 0) , "cannot create PIC inode\n" );
313
[602]314            // update child inode "extend" field
315            inode_cxy = GET_CXY( inode_xp );
316            inode_ptr = GET_PTR( inode_xp );
317            hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
318       
[614]319#if DEBUG_DEVFS_LOCAL_INIT
[568]320cycle = (uint32_t)hal_get_cycles();
[614]321if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]322printk("\n[%s] thread[%x,%x] created <pic> inode in cluster %x\n",
323__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
[568]324#endif
[23]325        }
[188]326    }
[23]327
[407]328    // create a TXT_RX inode in each cluster containing a TXT_RX chdev
[188]329    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
330    {
[407]331        chdev_xp = chdev_dir.txt_rx[channel];
[188]332        if( chdev_xp != XPTR_NULL )
[23]333        {
[188]334            chdev_cxy = GET_CXY( chdev_xp );
[602]335            chdev_ptr = GET_PTR( chdev_xp );
[610]336
[188]337            if( chdev_cxy == local_cxy )
338            {
[612]339                error = vfs_add_child_in_parent( local_cxy,
340                                                 INODE_TYPE_DEV,
341                                                 FS_TYPE_DEVFS,
342                                                 devfs_external_inode_xp,
343                                                 chdev_ptr->name,
344                                                 &unused_xp,
345                                                 &inode_xp );
[602]346
[612]347assert( (error == 0) , "cannot create TXT_RX inode\n" );
348
[602]349                // update child inode "extend" field
350                inode_cxy = GET_CXY( inode_xp );
351                inode_ptr = GET_PTR( inode_xp );
352                hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
353       
[614]354#if DEBUG_DEVFS_LOCAL_INIT
[568]355cycle = (uint32_t)hal_get_cycles();
[614]356if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]357printk("\n[%s] thread[%x,%x] created <txt_rx[%d]> inode in cluster %x\n",
358__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]359#endif
[188]360            }
[23]361        }
[188]362    }
[23]363
[407]364    // create a TXT_TX inode in each cluster containing a TXT_TX chdev
365    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
366    {
367        chdev_xp = chdev_dir.txt_tx[channel];
368        if( chdev_xp != XPTR_NULL )
369        {
370            chdev_cxy = GET_CXY( chdev_xp );
[602]371            chdev_ptr = GET_PTR( chdev_xp );
[610]372
[407]373            if( chdev_cxy == local_cxy )
374            {
[612]375                error = vfs_add_child_in_parent( local_cxy,
376                                                 INODE_TYPE_DEV,
377                                                 FS_TYPE_DEVFS,
378                                                 devfs_external_inode_xp,
379                                                 chdev_ptr->name,
380                                                 &unused_xp,
381                                                 &inode_xp );
[602]382
[612]383assert( (error == 0) , "cannot create TXT_TX inode\n" );
384
[602]385                // update child inode "extend" field
386                inode_cxy = GET_CXY( inode_xp );
387                inode_ptr = GET_PTR( inode_xp );
388                hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
389       
[614]390#if DEBUG_DEVFS_LOCAL_INIT
[568]391cycle = (uint32_t)hal_get_cycles();
[614]392if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]393printk("\n[%s] thread[%x,%x] created <txt_tx[%d]> inode in cluster %x\n",
394__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]395#endif
[407]396            }
397        }
398    }
399
[188]400    // create an IOC inode in each cluster containing an IOC chdev
401    for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
402    {
403        chdev_xp = chdev_dir.ioc[channel];
404        if( chdev_xp != XPTR_NULL )
[23]405        {
[188]406            chdev_cxy = GET_CXY( chdev_xp );
[602]407            chdev_ptr = GET_PTR( chdev_xp );
[610]408
[188]409            if( chdev_cxy == local_cxy )
410            {
[612]411                error = vfs_add_child_in_parent( local_cxy,
412                                                 INODE_TYPE_DEV,
413                                                 FS_TYPE_DEVFS,
414                                                 devfs_external_inode_xp,
415                                                 chdev_ptr->name,
416                                                 &unused_xp,
417                                                 &inode_xp );
[602]418
[612]419assert( (error == 0) , "cannot create IOC inode\n" );
420
[602]421                // update child inode "extend" field
422                inode_cxy = GET_CXY( inode_xp );
423                inode_ptr = GET_PTR( inode_xp );
424                hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
425       
[614]426#if DEBUG_DEVFS_LOCAL_INIT
[568]427cycle = (uint32_t)hal_get_cycles();
[614]428if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]429printk("\n[%s] thread[%x,%x] created <ioc[%d]> inode in cluster %x\n",
430__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]431#endif
[188]432            }
[23]433        }
[188]434    }
[23]435
[188]436    // create a FBF inode in each cluster containing a FBF chdev
[568]437    for( channel = 0 ; channel < CONFIG_MAX_FBF_CHANNELS ; channel++ )
[188]438    {
439        chdev_xp = chdev_dir.fbf[channel];
440        if( chdev_xp != XPTR_NULL )
[23]441        {
[188]442            chdev_cxy = GET_CXY( chdev_xp );
[602]443            chdev_ptr = GET_PTR( chdev_xp );
[610]444
[188]445            if( chdev_cxy == local_cxy )
446            {
[612]447                error = vfs_add_child_in_parent( local_cxy,
448                                                 INODE_TYPE_DEV,
449                                                 FS_TYPE_DEVFS,
450                                                 devfs_external_inode_xp,
451                                                 chdev_ptr->name,
452                                                 &unused_xp,
453                                                 &inode_xp );
[602]454
[612]455assert( (error == 0) , "cannot create FBF inode\n" );
456
[602]457                // update child inode "extend" field
458                inode_cxy = GET_CXY( inode_xp );
459                inode_ptr = GET_PTR( inode_xp );
460                hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
461       
[614]462#if DEBUG_DEVFS_LOCAL_INIT
[568]463cycle = (uint32_t)hal_get_cycles();
[614]464if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]465printk("\n[%s] thread[%x,%x] created <fbf[%d]> inode in cluster %x\n",
466__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]467#endif
[188]468            }
[23]469        }
[188]470    }
[23]471
[188]472    // create a NIC_RX inode in each cluster containing a NIC_RX chdev
473    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
474    {
475        chdev_xp = chdev_dir.nic_rx[channel];
476        if( chdev_xp != XPTR_NULL )
[23]477        {
[188]478            chdev_cxy = GET_CXY( chdev_xp );
[610]479            chdev_ptr = GET_PTR( chdev_xp );
480
[188]481            if( chdev_cxy == local_cxy )
482            {
[612]483                error = vfs_add_child_in_parent( local_cxy,
484                                                 INODE_TYPE_DEV,
485                                                 FS_TYPE_DEVFS,
486                                                 devfs_external_inode_xp,
487                                                 chdev_ptr->name,
488                                                 &unused_xp,
489                                                 &inode_xp );
490
491assert( (error == 0) , "cannot create NIC_RX inode\n" );
492
493                // update child inode "extend" field
494                inode_cxy = GET_CXY( inode_xp );
495                inode_ptr = GET_PTR( inode_xp );
496                hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
497 
[614]498#if DEBUG_DEVFS_LOCAL_INIT
[568]499cycle = (uint32_t)hal_get_cycles();
[614]500if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]501printk("\n[%s] thread[%x,%x] created <nic_rx[%d]> inode in cluster %x\n",
502__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]503#endif
[188]504            }
[23]505        }
506    }
507
[188]508    // create a NIC_TX inode in each cluster containing a NIC_TX chdev
509    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
[23]510    {
[188]511        chdev_xp = chdev_dir.nic_tx[channel];
512        if( chdev_xp != XPTR_NULL )
513        {
514            chdev_cxy = GET_CXY( chdev_xp );
[602]515            chdev_ptr = GET_PTR( chdev_xp );
[610]516
[188]517            if( chdev_cxy == local_cxy )
518            {
[612]519                error = vfs_add_child_in_parent( local_cxy,
520                                                 INODE_TYPE_DEV,
521                                                 FS_TYPE_DEVFS,
522                                                 devfs_external_inode_xp,
523                                                 chdev_ptr->name,
524                                                 &unused_xp,
525                                                 &inode_xp );
[602]526
[612]527assert( (error == 0) , "cannot create NIC_TX inode\n" );
528
[602]529                // update child inode "extend" field
530                inode_cxy = GET_CXY( inode_xp );
531                inode_ptr = GET_PTR( inode_xp );
532                hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
533       
[614]534#if DEBUG_DEVFS_LOCAL_INIT
[433]535cycle = (uint32_t)hal_get_cycles();
[614]536if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]537printk("\n[%s] thread[%x,%x] created <nic_tx[%d]> inode in cluster %x\n",
538__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[433]539#endif
[568]540            }
541        }
542    }
[188]543}  // end devfs_local_init()
[23]544
[407]545//////////////////////////////////////////
546int devfs_user_move( bool_t     to_buffer,
547                     xptr_t     file_xp,
[598]548                     char     * u_buf,
[407]549                     uint32_t   size )
550{
[598]551    xptr_t           chdev_xp;
552    cxy_t            chdev_cxy;
553    chdev_t        * chdev_ptr;                    // associated chdev type
554    uint32_t         func;                         // chdev functionnal type
555    uint32_t         channel;                      // chdev channel index
556    uint32_t         burst;                        // number of bytes in a burst
557    uint32_t         todo;                         // number of bytes not yet moved
558    error_t          error;
559    uint32_t         i;
[407]560
[598]561    char             k_buf[CONFIG_TXT_KBUF_SIZE];  // local kernel buffer
[407]562
[598]563assert( ( file_xp != XPTR_NULL ) , "file_xp == XPTR_NULL" );
[407]564
[438]565#if (DEBUG_SYS_READ & 1)
[435]566enter_devfs_read = hal_time_stamp();
567#endif
568
[438]569#if (DEBUG_SYS_WRITE & 1)
[435]570enter_devfs_write = hal_time_stamp();
571#endif
572
[438]573#if DEBUG_DEVFS_MOVE
[598]574uint32_t   cycle = (uint32_t)hal_get_cycles();
575thread_t * this  = CURRENT_THREAD;
[438]576if( DEBUG_DEVFS_MOVE < cycle )
[598]577printk("\n[%s] thread[%x,%x] enter / to_mem %d / cycle %d\n",
578__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
[433]579#endif
[407]580
[430]581    // get extended pointer on chdev_xp
582    chdev_xp = chdev_from_file( file_xp );
[407]583
[430]584    // get cluster and local pointer on chdev
585    chdev_cxy  = GET_CXY( chdev_xp );
586    chdev_ptr  = (chdev_t *)GET_PTR( chdev_xp );
[407]587
588    // get chdev functionnal type and channel
[568]589    func    = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->func ) );
590    channel = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->channel ) );
[407]591
[602]592// Only TXT devices are associated to a pseudo-file
[598]593assert( ( func == DEV_FUNC_TXT ) , __FUNCTION__, "illegal device func_type");
594
595    // initialise number of bytes to move
596    todo = size;
597
598    /////////////// TXT read
599    if( to_buffer )
600    { 
601        while( todo )
602        {
603            // set burst size
604            if( todo > CONFIG_TXT_KBUF_SIZE ) burst = CONFIG_TXT_KBUF_SIZE;
605            else                              burst = todo;
606
607            // read burst bytes from TXT device to kernel buffer
608            for( i = 0 ; i < burst ; i++ )
[407]609            {
610                error = dev_txt_read( channel , &k_buf[i] );
611
[598]612                if( error )  return -1;
613            }
[407]614
[598]615            // move burst bytes from k_buf to u_buf                   
616            hal_strcpy_to_uspace( u_buf , k_buf , burst );
617
618            // update loop variables
619            todo  -= burst;
620            u_buf += burst;
621        }
622
[438]623#if DEBUG_DEVFS_MOVE
[433]624cycle = (uint32_t)hal_get_cycles();
[438]625if( DEBUG_DEVFS_MOVE < cycle )
[598]626printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
627__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
[433]628#endif
629
[438]630#if (DEBUG_SYS_READ & 1)
[435]631exit_devfs_read = hal_time_stamp();
[407]632#endif
633            return size;
[598]634    } 
635    ///////////// TXT write 
636    else               
637    {
638        while( todo )
[407]639        {
[598]640            // set burst size
641            if( todo > CONFIG_TXT_KBUF_SIZE ) burst = CONFIG_TXT_KBUF_SIZE;
642            else                              burst = todo;
[407]643
[598]644            // move burst bytes from u_buf to k_buf
645            hal_strcpy_from_uspace( k_buf , u_buf , burst );
[407]646
[598]647            // write burst bytes from kernel buffer to TXT device
648            error = dev_txt_write( channel , k_buf , burst );
649
650            if( error ) return -1;
651
652            // update loop variables
653            todo  -= burst;
654            u_buf += burst;
655        } 
656
[438]657#if DEBUG_DEVFS_MOVE
[433]658cycle = (uint32_t)hal_get_cycles();
[438]659if( DEBUG_DEVFS_MOVE < cycle )
[598]660printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
661__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
[433]662#endif
[407]663
[438]664#if (DEBUG_SYS_WRITE & 1)
[435]665exit_devfs_write = hal_time_stamp();
666#endif
[598]667            return size;
[407]668    }
669
670}  // end devfs_user_move()
671
[612]672///////////////////////////////////////////////////////
673error_t devfs_get_user_dir( struct vfs_inode_s * inode,
674                            struct dirent      * array,
675                            uint32_t             max_dirent,
676                            uint32_t             min_dentry,
677                            bool_t               detailed,
678                            uint32_t           * entries,
679                            bool_t             * done )
680{
681    xptr_t         xhtab_xp;    // extended pointer on inode xhtab (children dentries)
682    xptr_t         dentry_xp;   // extended pointer on current dentry
683    vfs_dentry_t * dentry_ptr;  // local pointer on current dentry
684    uint32_t       dentry_id;   // dentry index in set of children dentry   
685    uint32_t       dirent_id;   // dirent index in array of dirent
[407]686
[612]687// detailed argument unused
688assert( (detailed == false) , "detailed argument not supported\n");
689 
690    // One loop to scan the target inode xhtab containing the set of dentries
691    // exit loop if no more dentries, or dirent array full
692
693#if DEBUG_DEVFS_GET_USER_DIR
694char       inode_name[CONFIG_VFS_MAX_NAME_LENGTH];
695uint32_t   cycle = (uint32_t)hal_get_cycles();
696thread_t * this  = CURRENT_THREAD;
697vfs_inode_get_name( XPTR( local_cxy , inode ) , inode_name );
698if( DEBUG_DEVFS_GET_USER_DIR < cycle )
699printk("\n[%s]  thread[%x,%x] enter for inode <%s> / cycle %d\n",
700__FUNCTION__, this->process->pid, this->trdid, inode_name , cycle );
701#endif
702
703    // get extended pointer on inode xhtab
704    xhtab_xp  = XPTR( local_cxy , &inode->children );
705
706    // initialize loop variables
707    dentry_xp = xhtab_get_first( xhtab_xp );
708    dentry_id = 0;
709    dirent_id = 0;
710
711    while( (dentry_xp != XPTR_NULL ) && (dirent_id < max_dirent) )
712    {
713        if( dentry_id >= min_dentry )
714        {
715            // copy name into dirent array
716            dentry_ptr = GET_PTR( dentry_xp );
717            strcpy( array[dirent_id].d_name , dentry_ptr->name ); 
718
719            // increment dirent_id
720            dirent_id++;
721        }
722         
723        // update loop variables
724        dentry_xp = xhtab_get_next( xhtab_xp );
725        dentry_id++;
726    }
727
728    // return results of scan
729    *done    = (dentry_xp == XPTR_NULL);
730    *entries = dirent_id;
731
732#if DEBUG_DEVFS_GET_USER_DIR
733cycle = (uint32_t)hal_get_cycles();
734if( DEBUG_DEVFS_GET_USER_DIR < cycle )
735printk("\n[%s]  thread[%x,%x] exit for inode <%s> / %d entries / cycle %d\n",
736__FUNCTION__, this->process->pid, this->trdid, inode_name, entries, cycle );
737#endif
738
739    return 0;
740   
741}  // en devfs_get_user_dir()
742
Note: See TracBrowser for help on using the repository browser.