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

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

This version is a major evolution: The physical memory allocators,
defined in the kmem.c, ppm.c, and kcm.c files have been modified
to support remote accesses. The RPCs that were previously user
to allocate physical memory in a remote cluster have been removed.
This has been done to cure a dead-lock in case of concurrent page-faults.

This version 2.2 has been tested on a (4 clusters / 2 cores per cluster)
TSAR architecture, for both the "sort" and the "fft" applications.

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