source: trunk/kernel/fs/devfs.c

Last change on this file was 683, checked in by alain, 13 months ago

All modifications required to support the <tcp_chat> application
including error recovery in case of packet loss.A

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