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

Last change on this file since 675 was 673, checked in by alain, 4 years ago

Introduce the DEBUG_VFS_ERROR in kernel_config to make
error messges display conditional.

File size: 28.6 KB
RevLine 
[23]1/*
2 * devfs.c - DEVFS File system API implementation.
3 *
4 * Author   Mohamed Lamine Karaoui (2014,2015)
[673]5 *          Alain Greiner          (2016,2017,2018,2019,2020)
[23]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
[657]55///////////////////////////////////
56xptr_t devfs_ctx_alloc( cxy_t cxy )
[188]57{
58    kmem_req_t    req;
[23]59
[635]60        req.type    = KMEM_KCM;
61        req.order   = bits_log2( sizeof(devfs_ctx_t) );
[188]62    req.flags   = AF_KERNEL | AF_ZERO;
[23]63
[657]64    // allocates devfs context from target cluster
65        return XPTR( cxy , kmem_remote_alloc( cxy , &req ) );
[188]66}
[23]67
[188]68/////////////////////////////////////////////
[657]69void devfs_ctx_init( xptr_t     devfs_ctx_xp,
70                     xptr_t     devfs_dev_inode_xp,
71                     xptr_t     devfs_external_inode_xp )
[23]72{
[657]73    // get cluster and local pointer on remote devfs context
74    devfs_ctx_t * devfs_ctx_ptr = GET_PTR( devfs_ctx_xp );
75    cxy_t         devfs_ctx_cxy = GET_CXY( devfs_ctx_xp );
[23]76
[657]77    // set values in remote devfs context
78    hal_remote_s64( XPTR( devfs_ctx_cxy  , &devfs_ctx_ptr->dev_inode_xp ),
79                    devfs_dev_inode_xp );
80
81    hal_remote_s64( XPTR( devfs_ctx_cxy  , &devfs_ctx_ptr->external_inode_xp ),
82                    devfs_external_inode_xp );
83
84    // register devfs context in the remote fs_context array[]
85    hal_remote_spt( XPTR( devfs_ctx_cxy , &fs_context[FS_TYPE_DEVFS].extend ),
86                          devfs_ctx_ptr ); 
[188]87}
[23]88
[657]89//////////////////////////////////////////////
90void devfs_ctx_destroy( xptr_t  devfs_ctx_xp )
[188]91{
92    kmem_req_t    req;
[23]93
[657]94    // get cluster and local pointer on devfs context
95    devfs_ctx_t * devfs_ctx_ptr = GET_PTR( devfs_ctx_xp );
96    cxy_t         devfs_ctx_cxy = GET_CXY( devfs_ctx_xp );
97
[635]98    req.type = KMEM_KCM;
[657]99    req.ptr  = devfs_ctx_ptr;
100
101    // release devfs context descriptor to remote cluster
102    kmem_remote_free( devfs_ctx_cxy , &req );
[188]103}
[23]104
[437]105/////////////////////////////////////////////////
[602]106void devfs_global_init( xptr_t   root_inode_xp,
[204]107                        xptr_t * devfs_dev_inode_xp,
[188]108                        xptr_t * devfs_external_inode_xp )
[23]109{
[623]110    error_t       error;
111    xptr_t        unused_xp;   // required by vfs_add_child_in_parent()
112    vfs_inode_t * inode;
[23]113
[657]114    // get
115
[610]116    // create DEVFS "dev" inode in cluster 0
[457]117    error = vfs_add_child_in_parent( 0,                // cxy
[188]118                                     FS_TYPE_DEVFS,
[602]119                                     root_inode_xp,
[188]120                                     "dev",
[602]121                                     &unused_xp,
122                                     devfs_dev_inode_xp );
[23]123
[623]124    // update inode "type" field
125    inode = GET_PTR( *devfs_dev_inode_xp );
[673]126    inode->type = FILE_TYPE_DIR;
[623]127 
[612]128    // create dentries <.> and <..> in <dev>
129    error |= vfs_add_special_dentries( *devfs_dev_inode_xp,
130                                       root_inode_xp );
131
[623]132    if( error )
133    {
134        printk("\n[PANIC] in %s : cannot create <dev> directory\n", __FUNCTION__ );
135        hal_core_sleep();
136    }
[23]137
[614]138#if DEBUG_DEVFS_GLOBAL_INIT
[598]139uint32_t   cycle = (uint32_t)hal_get_cycles();
140thread_t * this  = CURRENT_THREAD;
[614]141if( DEBUG_DEVFS_GLOBAL_INIT < cycle )
[598]142printk("\n[%s] thread[%x,%x] created <dev> inode / cycle %d\n",
143__FUNCTION__, this->process->pid, this->trdid, cycle );
[437]144#endif
145
[457]146    // create DEVFS "external" inode in cluster 0
147    error = vfs_add_child_in_parent( 0,               // cxy
[188]148                                     FS_TYPE_DEVFS,
[204]149                                     *devfs_dev_inode_xp,
150                                     "external",
[602]151                                     &unused_xp,
152                                     devfs_external_inode_xp );
[23]153
[623]154    // update inode "type" field
155    inode = GET_PTR( *devfs_external_inode_xp );
[673]156    inode->type = FILE_TYPE_DIR;
[623]157 
[612]158    // create dentries <.> and <..> in <external>
159    error |= vfs_add_special_dentries( *devfs_external_inode_xp,
160                                       *devfs_dev_inode_xp );
[279]161
[623]162    if( error )
163    {
164        printk("\n[PANIC] in %s : cannot create <external> directory\n", __FUNCTION__ );
165        hal_core_sleep();
166    }
[612]167
[614]168#if DEBUG_DEVFS_GLOBAL_INIT
[433]169cycle = (uint32_t)hal_get_cycles();
[614]170if( DEBUG_DEVFS_GLOBAL_INIT < cycle )
[598]171printk("\n[%s] thread[%x,%x] created <external> inode / cycle %d\n",
172__FUNCTION__, this->process->pid, this->trdid, cycle );
[433]173#endif
174
[602]175}  // end devfs_global_init()
[23]176
[204]177///////////////////////////////////////////////////
178void devfs_local_init( xptr_t   devfs_dev_inode_xp,
[657]179                       xptr_t   devfs_external_inode_xp )
[23]180{
[657]181    xptr_t        internal_inode_xp;   // extended pointer on <internal> inode
182    vfs_inode_t * internal_inode_ptr;  // local pointer on <internal> inode
[23]183    char          node_name[16];
[188]184    xptr_t        chdev_xp;
185    cxy_t         chdev_cxy;
[407]186    chdev_t     * chdev_ptr;
[188]187    xptr_t        inode_xp;
[602]188    vfs_inode_t * inode_ptr;
[23]189    uint32_t      channel;
[657]190    xptr_t        unused_xp;           // required by add_child_in_parent()
[612]191    error_t       error;
[657]192   
[23]193
[614]194#if DEBUG_DEVFS_LOCAL_INIT
195uint32_t   cycle = (uint32_t)hal_get_cycles();
196thread_t * this  = CURRENT_THREAD;
197if( DEBUG_DEVFS_LOCAL_INIT < cycle )
198printk("\n[%s] thread[%x,%x] enter / cycle %d\n",
199__FUNCTION__, this->process->pid, this->trdid, cycle );
200#endif
201
[657]202    // create <internal> directory
[673]203    snprintk( node_name , 16 , "internal_%x" , local_cxy );
[610]204
[657]205    error = vfs_add_child_in_parent( local_cxy,              // target cluster
206                                     FS_TYPE_DEVFS,          // FS type
207                                     devfs_dev_inode_xp,     // parent inode
208                                     node_name,              // child name
[612]209                                     &unused_xp,
[657]210                                     &internal_inode_xp );   // child inode
[612]211
[657]212    // set <internal> inode "type" field
213    internal_inode_ptr       = GET_PTR( internal_inode_xp );
[673]214    internal_inode_ptr->type = FILE_TYPE_DEV;
[623]215 
[612]216    // create dentries <.> and <..> in <internal>
[657]217    error |= vfs_add_special_dentries( internal_inode_xp,
[612]218                                       devfs_dev_inode_xp );
219
[623]220    if( error )
221    {
222        printk("\n[PANIC] in %s : cannot create <internal> directory\n", __FUNCTION__ );
223        hal_core_sleep();
224    }
[612]225
[614]226#if DEBUG_DEVFS_LOCAL_INIT
227cycle = (uint32_t)hal_get_cycles();
228if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]229printk("\n[%s] thread[%x,%x] created <%s> inode in cluster %x / cycle %d\n",
230__FUNCTION__, this->process->pid, this->trdid, node_name, local_cxy, cycle );
[568]231#endif
[23]232
233    // create MMC chdev inode
[407]234    chdev_xp  = chdev_dir.mmc[local_cxy];
[188]235    if( chdev_xp != XPTR_NULL)
236    {
[602]237        chdev_ptr = GET_PTR( chdev_xp );
[610]238        chdev_cxy = GET_CXY( chdev_xp );
239
[623]240        if( chdev_cxy != local_cxy )
241        {
242            printk("\n[PANIC] in %s : illegal MMC chdev in cluster %x\n",
243            __FUNCTION__, local_cxy );
244            hal_core_sleep();
245        }
[610]246
[612]247        error = vfs_add_child_in_parent( local_cxy,
248                                         FS_TYPE_DEVFS,
[657]249                                         internal_inode_xp,
[612]250                                         chdev_ptr->name,
251                                         &unused_xp,
252                                         &inode_xp );
[602]253
[623]254        if( error )
255        {
256            printk("\n[PANIC] in %s : cannot create MMC inode in cluster %x\n",
257            __FUNCTION__, local_cxy );
258            hal_core_sleep();
259        }
[612]260
[623]261        // update child inode "extend" and "type" fields
[602]262        inode_ptr = GET_PTR( inode_xp );
[623]263        inode_ptr->extend = chdev_ptr;
[673]264        inode_ptr->type   = FILE_TYPE_DEV;
[602]265       
[614]266#if DEBUG_DEVFS_LOCAL_INIT
[568]267cycle = (uint32_t)hal_get_cycles();
[614]268if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]269printk("\n[%s] thread[%x,%x] created <mmc> inode in cluster %x\n",
270__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
[568]271#endif
272
[188]273    }
[23]274
275    // create DMA chdev inodes (one DMA channel per core)
[188]276    for( channel = 0 ; channel < LOCAL_CLUSTER->cores_nr ; channel++ )
[23]277    {
[602]278        chdev_xp  = chdev_dir.dma[channel];
[188]279        if( chdev_xp != XPTR_NULL)
280        {
[602]281            chdev_ptr = GET_PTR( chdev_xp );
[610]282            chdev_cxy = GET_CXY( chdev_xp );
283
[623]284            if( chdev_cxy != local_cxy )
285            {
[624]286                printk("\n[PANIC] in %s : illegal DMA chdev in cluster %x\n",
[623]287                __FUNCTION__, local_cxy );
288                hal_core_sleep();
289            }
[610]290
[612]291            error = vfs_add_child_in_parent( local_cxy,
292                                             FS_TYPE_DEVFS,
[657]293                                             internal_inode_xp,
[612]294                                             chdev_ptr->name,
295                                             &unused_xp,
296                                             &inode_xp );
[623]297            if( error )
298            {
299                printk("\n[PANIC] in %s : cannot create DMA inode in cluster %x\n",
300                __FUNCTION__, local_cxy );
301                hal_core_sleep();
302            }
[602]303
[623]304            // update child inode "extend" and "type" fields
[602]305            inode_ptr = GET_PTR( inode_xp );
[623]306            inode_ptr->extend = chdev_ptr;
[673]307            inode_ptr->type   = FILE_TYPE_DEV;
[602]308       
[614]309#if DEBUG_DEVFS_LOCAL_INIT
[568]310cycle = (uint32_t)hal_get_cycles();
[614]311if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]312printk("\n[%s] thread [%x,%x] created <dma[%d]> inode in cluster %x\n",
313__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]314#endif
[188]315        }
[23]316    }
317
[188]318    // create an IOB inode in cluster containing IOB chdev
319    chdev_xp = chdev_dir.iob;
320    if( chdev_xp != XPTR_NULL )
[23]321    {
[188]322        chdev_cxy = GET_CXY( chdev_xp );
[602]323        chdev_ptr = GET_PTR( chdev_xp );
[610]324
[188]325        if( chdev_cxy == local_cxy )
326        {
[612]327            error = vfs_add_child_in_parent( local_cxy,
328                                             FS_TYPE_DEVFS,
329                                             devfs_external_inode_xp,
330                                             chdev_ptr->name,
331                                             &unused_xp,
332                                             &inode_xp );
[623]333            if( error )
334            {
335                printk("\n[PANIC] in %s : cannot create IOB inode in cluster %x\n",
336                __FUNCTION__, local_cxy );
337                hal_core_sleep();
338            }
[602]339
[623]340            // update child inode "extend" and "type" fields
[602]341            inode_ptr = GET_PTR( inode_xp );
[623]342            inode_ptr->extend = chdev_ptr;
[673]343            inode_ptr->type   = FILE_TYPE_DEV;
[602]344       
[614]345#if DEBUG_DEVFS_LOCAL_INIT
[568]346cycle = (uint32_t)hal_get_cycles();
[614]347if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]348printk("\n[%s] thread[%x,%x] created <iob> inode in cluster %x\n",
349__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
[568]350#endif
[188]351        }
352    }
[23]353       
[188]354    // create a PIC inode in cluster containing PIC chdev
355    chdev_xp = chdev_dir.pic;
356    if( chdev_xp != XPTR_NULL )
357    {
358        chdev_cxy = GET_CXY( chdev_xp );
[602]359        chdev_ptr = GET_PTR( chdev_xp );
[610]360
[188]361        if( chdev_cxy == local_cxy )
[23]362        {
[612]363            error = vfs_add_child_in_parent( local_cxy,
364                                             FS_TYPE_DEVFS,
365                                             devfs_external_inode_xp,
366                                             chdev_ptr->name,
367                                             &unused_xp,
368                                             &inode_xp );
[602]369
[623]370            if( error )
371            {
372                printk("\n[PANIC] in %s : cannot create PIC inode in cluster %x\n",
373                __FUNCTION__, local_cxy );
374                hal_core_sleep();
375            }
[612]376
[602]377            // update child inode "extend" field
378            inode_ptr = GET_PTR( inode_xp );
[623]379            inode_ptr->extend = chdev_ptr;
[673]380            inode_ptr->type   = FILE_TYPE_DEV;
[602]381       
[614]382#if DEBUG_DEVFS_LOCAL_INIT
[568]383cycle = (uint32_t)hal_get_cycles();
[614]384if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]385printk("\n[%s] thread[%x,%x] created <pic> inode in cluster %x\n",
386__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
[568]387#endif
[23]388        }
[188]389    }
[23]390
[407]391    // create a TXT_RX inode in each cluster containing a TXT_RX chdev
[188]392    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
393    {
[407]394        chdev_xp = chdev_dir.txt_rx[channel];
[188]395        if( chdev_xp != XPTR_NULL )
[23]396        {
[188]397            chdev_cxy = GET_CXY( chdev_xp );
[602]398            chdev_ptr = GET_PTR( chdev_xp );
[610]399
[188]400            if( chdev_cxy == local_cxy )
401            {
[612]402                error = vfs_add_child_in_parent( local_cxy,
403                                                 FS_TYPE_DEVFS,
404                                                 devfs_external_inode_xp,
405                                                 chdev_ptr->name,
406                                                 &unused_xp,
407                                                 &inode_xp );
[602]408
[623]409                if( error )
410                {
411                    printk("\n[PANIC] in %s : cannot create TXT_RX inode in cluster %x\n",
412                    __FUNCTION__, local_cxy );
413                    hal_core_sleep();
414                }
[612]415
[623]416                // update child inode "extend" and "type" fields
[602]417                inode_ptr = GET_PTR( inode_xp );
[623]418                inode_ptr->extend = chdev_ptr;
[673]419                inode_ptr->type   = FILE_TYPE_DEV;
[602]420       
[614]421#if DEBUG_DEVFS_LOCAL_INIT
[568]422cycle = (uint32_t)hal_get_cycles();
[614]423if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]424printk("\n[%s] thread[%x,%x] created <txt_rx[%d]> inode in cluster %x\n",
425__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]426#endif
[188]427            }
[23]428        }
[188]429    }
[23]430
[407]431    // create a TXT_TX inode in each cluster containing a TXT_TX chdev
432    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
433    {
434        chdev_xp = chdev_dir.txt_tx[channel];
435        if( chdev_xp != XPTR_NULL )
436        {
437            chdev_cxy = GET_CXY( chdev_xp );
[602]438            chdev_ptr = GET_PTR( chdev_xp );
[610]439
[407]440            if( chdev_cxy == local_cxy )
441            {
[612]442                error = vfs_add_child_in_parent( local_cxy,
443                                                 FS_TYPE_DEVFS,
444                                                 devfs_external_inode_xp,
445                                                 chdev_ptr->name,
446                                                 &unused_xp,
447                                                 &inode_xp );
[623]448                if( error )
449                {
450                    printk("\n[PANIC] in %s : cannot create TXT_TX inode in cluster %x\n",
451                    __FUNCTION__, local_cxy );
452                    hal_core_sleep();
453                }
[602]454
[623]455                // update child inode "extend" and "type" fields
[602]456                inode_ptr = GET_PTR( inode_xp );
[623]457                inode_ptr->extend = chdev_ptr;
[673]458                inode_ptr->type   = FILE_TYPE_DEV;
[602]459       
[614]460#if DEBUG_DEVFS_LOCAL_INIT
[568]461cycle = (uint32_t)hal_get_cycles();
[614]462if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]463printk("\n[%s] thread[%x,%x] created <txt_tx[%d]> inode in cluster %x\n",
464__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]465#endif
[407]466            }
467        }
468    }
469
[188]470    // create an IOC inode in each cluster containing an IOC chdev
471    for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
472    {
473        chdev_xp = chdev_dir.ioc[channel];
474        if( chdev_xp != XPTR_NULL )
[23]475        {
[188]476            chdev_cxy = GET_CXY( chdev_xp );
[602]477            chdev_ptr = GET_PTR( chdev_xp );
[610]478
[188]479            if( chdev_cxy == local_cxy )
480            {
[612]481                error = vfs_add_child_in_parent( local_cxy,
482                                                 FS_TYPE_DEVFS,
483                                                 devfs_external_inode_xp,
484                                                 chdev_ptr->name,
485                                                 &unused_xp,
486                                                 &inode_xp );
[623]487                if( error )
488                {
489                    printk("\n[PANIC] in %s : cannot create IOC inode in cluster %x\n",
490                    __FUNCTION__, local_cxy );
491                    hal_core_sleep();
492                }
[602]493
[623]494                // update child inode "extend" and "type" fields
[602]495                inode_ptr = GET_PTR( inode_xp );
[623]496                inode_ptr->extend = chdev_ptr;
[673]497                inode_ptr->type   = FILE_TYPE_DEV;
[602]498       
[614]499#if DEBUG_DEVFS_LOCAL_INIT
[568]500cycle = (uint32_t)hal_get_cycles();
[614]501if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]502printk("\n[%s] thread[%x,%x] created <ioc[%d]> inode in cluster %x\n",
503__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]504#endif
[188]505            }
[23]506        }
[188]507    }
[23]508
[188]509    // create a FBF inode in each cluster containing a FBF chdev
[568]510    for( channel = 0 ; channel < CONFIG_MAX_FBF_CHANNELS ; channel++ )
[188]511    {
512        chdev_xp = chdev_dir.fbf[channel];
513        if( chdev_xp != XPTR_NULL )
[23]514        {
[188]515            chdev_cxy = GET_CXY( chdev_xp );
[602]516            chdev_ptr = GET_PTR( chdev_xp );
[610]517
[188]518            if( chdev_cxy == local_cxy )
519            {
[612]520                error = vfs_add_child_in_parent( local_cxy,
521                                                 FS_TYPE_DEVFS,
522                                                 devfs_external_inode_xp,
523                                                 chdev_ptr->name,
524                                                 &unused_xp,
525                                                 &inode_xp );
[623]526                if( error )
527                {
528                    printk("\n[PANIC] in %s : cannot create FBF inode in cluster %x\n",
529                    __FUNCTION__, local_cxy );
530                    hal_core_sleep();
531                }
[602]532
[623]533                // update child inode "extend" and "type" fields
[602]534                inode_ptr = GET_PTR( inode_xp );
[623]535                inode_ptr->extend = chdev_ptr;
[673]536                inode_ptr->type   = FILE_TYPE_DEV;
[602]537       
[614]538#if DEBUG_DEVFS_LOCAL_INIT
[568]539cycle = (uint32_t)hal_get_cycles();
[614]540if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]541printk("\n[%s] thread[%x,%x] created <fbf[%d]> inode in cluster %x\n",
542__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]543#endif
[188]544            }
[23]545        }
[188]546    }
[23]547
[188]548    // create a NIC_RX inode in each cluster containing a NIC_RX chdev
549    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
550    {
551        chdev_xp = chdev_dir.nic_rx[channel];
552        if( chdev_xp != XPTR_NULL )
[23]553        {
[188]554            chdev_cxy = GET_CXY( chdev_xp );
[610]555            chdev_ptr = GET_PTR( chdev_xp );
556
[188]557            if( chdev_cxy == local_cxy )
558            {
[612]559                error = vfs_add_child_in_parent( local_cxy,
560                                                 FS_TYPE_DEVFS,
561                                                 devfs_external_inode_xp,
562                                                 chdev_ptr->name,
563                                                 &unused_xp,
564                                                 &inode_xp );
[623]565                if( error )
566                {
567                    printk("\n[PANIC] in %s : cannot create NIC_RX inode in cluster %x\n",
568                    __FUNCTION__, local_cxy );
569                    hal_core_sleep();
570                }
[612]571
[623]572                // update child inode "extend" and "type" fields
[612]573                inode_ptr = GET_PTR( inode_xp );
[623]574                inode_ptr->extend = chdev_ptr;
[673]575                inode_ptr->type   = FILE_TYPE_DEV;
[612]576 
[614]577#if DEBUG_DEVFS_LOCAL_INIT
[568]578cycle = (uint32_t)hal_get_cycles();
[614]579if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]580printk("\n[%s] thread[%x,%x] created <nic_rx[%d]> inode in cluster %x\n",
581__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]582#endif
[188]583            }
[23]584        }
585    }
586
[188]587    // create a NIC_TX inode in each cluster containing a NIC_TX chdev
588    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
[23]589    {
[188]590        chdev_xp = chdev_dir.nic_tx[channel];
591        if( chdev_xp != XPTR_NULL )
592        {
593            chdev_cxy = GET_CXY( chdev_xp );
[602]594            chdev_ptr = GET_PTR( chdev_xp );
[610]595
[188]596            if( chdev_cxy == local_cxy )
597            {
[612]598                error = vfs_add_child_in_parent( local_cxy,
599                                                 FS_TYPE_DEVFS,
600                                                 devfs_external_inode_xp,
601                                                 chdev_ptr->name,
602                                                 &unused_xp,
603                                                 &inode_xp );
[623]604                if( error )
605                {
606                    printk("\n[PANIC] in %s : cannot create NIC_TX inode in cluster %x\n",
607                    __FUNCTION__, local_cxy );
608                    hal_core_sleep();
609                }
[602]610
[623]611                // update child inode "extend" and "type" fields
[602]612                inode_ptr = GET_PTR( inode_xp );
[623]613                inode_ptr->extend = chdev_ptr;
[673]614                inode_ptr->type   = FILE_TYPE_DEV;
[602]615       
[614]616#if DEBUG_DEVFS_LOCAL_INIT
[433]617cycle = (uint32_t)hal_get_cycles();
[614]618if( DEBUG_DEVFS_LOCAL_INIT < cycle )
[598]619printk("\n[%s] thread[%x,%x] created <nic_tx[%d]> inode in cluster %x\n",
620__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[433]621#endif
[568]622            }
623        }
624    }
[188]625}  // end devfs_local_init()
[23]626
[407]627//////////////////////////////////////////
628int devfs_user_move( bool_t     to_buffer,
629                     xptr_t     file_xp,
[598]630                     char     * u_buf,
[407]631                     uint32_t   size )
632{
[598]633    xptr_t           chdev_xp;
634    cxy_t            chdev_cxy;
635    chdev_t        * chdev_ptr;                    // associated chdev type
636    uint32_t         func;                         // chdev functionnal type
637    uint32_t         channel;                      // chdev channel index
638    uint32_t         burst;                        // number of bytes in a burst
639    uint32_t         todo;                         // number of bytes not yet moved
640    error_t          error;
641    uint32_t         i;
[407]642
[598]643    char             k_buf[CONFIG_TXT_KBUF_SIZE];  // local kernel buffer
[407]644
[673]645assert( __FUNCTION__, ( file_xp != XPTR_NULL ) , "file_xp == XPTR_NULL" );
[407]646
[438]647#if (DEBUG_SYS_READ & 1)
[435]648enter_devfs_read = hal_time_stamp();
649#endif
650
[438]651#if (DEBUG_SYS_WRITE & 1)
[435]652enter_devfs_write = hal_time_stamp();
653#endif
654
[438]655#if DEBUG_DEVFS_MOVE
[598]656uint32_t   cycle = (uint32_t)hal_get_cycles();
657thread_t * this  = CURRENT_THREAD;
[438]658if( DEBUG_DEVFS_MOVE < cycle )
[598]659printk("\n[%s] thread[%x,%x] enter / to_mem %d / cycle %d\n",
660__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
[433]661#endif
[407]662
[430]663    // get extended pointer on chdev_xp
664    chdev_xp = chdev_from_file( file_xp );
[407]665
[430]666    // get cluster and local pointer on chdev
667    chdev_cxy  = GET_CXY( chdev_xp );
668    chdev_ptr  = (chdev_t *)GET_PTR( chdev_xp );
[407]669
670    // get chdev functionnal type and channel
[568]671    func    = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->func ) );
672    channel = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->channel ) );
[407]673
[602]674// Only TXT devices are associated to a pseudo-file
[673]675assert( __FUNCTION__, ( func == DEV_FUNC_TXT ) , "illegal device func_type");
[598]676
677    // initialise number of bytes to move
678    todo = size;
679
680    /////////////// TXT read
681    if( to_buffer )
682    { 
683        while( todo )
684        {
685            // set burst size
686            if( todo > CONFIG_TXT_KBUF_SIZE ) burst = CONFIG_TXT_KBUF_SIZE;
687            else                              burst = todo;
688
689            // read burst bytes from TXT device to kernel buffer
690            for( i = 0 ; i < burst ; i++ )
[407]691            {
692                error = dev_txt_read( channel , &k_buf[i] );
693
[598]694                if( error )  return -1;
695            }
[407]696
[598]697            // move burst bytes from k_buf to u_buf                   
[637]698            hal_strcpy_to_uspace( u_buf,
699                                  XPTR( local_cxy , k_buf ),
700                                  burst );
[598]701
702            // update loop variables
703            todo  -= burst;
704            u_buf += burst;
705        }
706
[438]707#if DEBUG_DEVFS_MOVE
[433]708cycle = (uint32_t)hal_get_cycles();
[438]709if( DEBUG_DEVFS_MOVE < cycle )
[598]710printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
711__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
[433]712#endif
713
[438]714#if (DEBUG_SYS_READ & 1)
[435]715exit_devfs_read = hal_time_stamp();
[407]716#endif
717            return size;
[598]718    } 
719    ///////////// TXT write 
720    else               
721    {
722        while( todo )
[407]723        {
[598]724            // set burst size
725            if( todo > CONFIG_TXT_KBUF_SIZE ) burst = CONFIG_TXT_KBUF_SIZE;
726            else                              burst = todo;
[407]727
[598]728            // move burst bytes from u_buf to k_buf
[637]729            hal_strcpy_from_uspace( XPTR( local_cxy , k_buf ) , u_buf , burst );
[407]730
[598]731            // write burst bytes from kernel buffer to TXT device
732            error = dev_txt_write( channel , k_buf , burst );
733
734            if( error ) return -1;
735
736            // update loop variables
737            todo  -= burst;
738            u_buf += burst;
739        } 
740
[438]741#if DEBUG_DEVFS_MOVE
[433]742cycle = (uint32_t)hal_get_cycles();
[438]743if( DEBUG_DEVFS_MOVE < cycle )
[598]744printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
745__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
[433]746#endif
[407]747
[438]748#if (DEBUG_SYS_WRITE & 1)
[435]749exit_devfs_write = hal_time_stamp();
750#endif
[598]751            return size;
[407]752    }
753
754}  // end devfs_user_move()
755
[612]756///////////////////////////////////////////////////////
757error_t devfs_get_user_dir( struct vfs_inode_s * inode,
758                            struct dirent      * array,
759                            uint32_t             max_dirent,
760                            uint32_t             min_dentry,
761                            bool_t               detailed,
762                            uint32_t           * entries,
763                            bool_t             * done )
764{
765    xptr_t         xhtab_xp;    // extended pointer on inode xhtab (children dentries)
766    xptr_t         dentry_xp;   // extended pointer on current dentry
767    vfs_dentry_t * dentry_ptr;  // local pointer on current dentry
768    uint32_t       dentry_id;   // dentry index in set of children dentry   
769    uint32_t       dirent_id;   // dirent index in array of dirent
[407]770
[612]771// detailed argument unused
[673]772assert( __FUNCTION__, (detailed == false) , "detailed argument not supported\n");
[612]773 
774    // One loop to scan the target inode xhtab containing the set of dentries
775    // exit loop if no more dentries, or dirent array full
776
777#if DEBUG_DEVFS_GET_USER_DIR
778char       inode_name[CONFIG_VFS_MAX_NAME_LENGTH];
779uint32_t   cycle = (uint32_t)hal_get_cycles();
780thread_t * this  = CURRENT_THREAD;
781vfs_inode_get_name( XPTR( local_cxy , inode ) , inode_name );
782if( DEBUG_DEVFS_GET_USER_DIR < cycle )
783printk("\n[%s]  thread[%x,%x] enter for inode <%s> / cycle %d\n",
784__FUNCTION__, this->process->pid, this->trdid, inode_name , cycle );
785#endif
786
787    // get extended pointer on inode xhtab
788    xhtab_xp  = XPTR( local_cxy , &inode->children );
789
790    // initialize loop variables
791    dentry_xp = xhtab_get_first( xhtab_xp );
792    dentry_id = 0;
793    dirent_id = 0;
794
795    while( (dentry_xp != XPTR_NULL ) && (dirent_id < max_dirent) )
796    {
797        if( dentry_id >= min_dentry )
798        {
799            // copy name into dirent array
800            dentry_ptr = GET_PTR( dentry_xp );
801            strcpy( array[dirent_id].d_name , dentry_ptr->name ); 
802
803            // increment dirent_id
804            dirent_id++;
805        }
806         
807        // update loop variables
808        dentry_xp = xhtab_get_next( xhtab_xp );
809        dentry_id++;
810    }
811
812    // return results of scan
813    *done    = (dentry_xp == XPTR_NULL);
814    *entries = dirent_id;
815
816#if DEBUG_DEVFS_GET_USER_DIR
817cycle = (uint32_t)hal_get_cycles();
818if( DEBUG_DEVFS_GET_USER_DIR < cycle )
819printk("\n[%s]  thread[%x,%x] exit for inode <%s> / %d entries / cycle %d\n",
820__FUNCTION__, this->process->pid, this->trdid, inode_name, entries, cycle );
821#endif
822
823    return 0;
824   
825}  // en devfs_get_user_dir()
826
Note: See TracBrowser for help on using the repository browser.