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

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

Introduce remote_buf.c/.h & socket.c/.h files.
Update dev_nic.c/.h files.

File size: 28.6 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    kmem_req_t    req;
59
60        req.type    = KMEM_KCM;
61        req.order   = bits_log2( sizeof(devfs_ctx_t) );
62    req.flags   = AF_KERNEL | AF_ZERO;
63
64    // allocates devfs context from target cluster
65        return XPTR( cxy , kmem_remote_alloc( cxy , &req ) );
66}
67
68/////////////////////////////////////////////
69void devfs_ctx_init( xptr_t     devfs_ctx_xp,
70                     xptr_t     devfs_dev_inode_xp,
71                     xptr_t     devfs_external_inode_xp )
72{
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 );
76
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 ); 
87}
88
89//////////////////////////////////////////////
90void devfs_ctx_destroy( xptr_t  devfs_ctx_xp )
91{
92    kmem_req_t    req;
93
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
98    req.type = KMEM_KCM;
99    req.ptr  = devfs_ctx_ptr;
100
101    // release devfs context descriptor to remote cluster
102    kmem_remote_free( devfs_ctx_cxy , &req );
103}
104
105/////////////////////////////////////////////////
106void devfs_global_init( xptr_t   root_inode_xp,
107                        xptr_t * devfs_dev_inode_xp,
108                        xptr_t * devfs_external_inode_xp )
109{
110    error_t       error;
111    xptr_t        unused_xp;   // required by vfs_add_child_in_parent()
112    vfs_inode_t * inode;
113
114    // get
115
116    // create DEVFS "dev" inode in cluster 0
117    error = vfs_add_child_in_parent( 0,                // cxy
118                                     FS_TYPE_DEVFS,
119                                     root_inode_xp,
120                                     "dev",
121                                     &unused_xp,
122                                     devfs_dev_inode_xp );
123
124    // update inode "type" field
125    inode = GET_PTR( *devfs_dev_inode_xp );
126    inode->type = INODE_TYPE_DIR;
127 
128    // create dentries <.> and <..> in <dev>
129    error |= vfs_add_special_dentries( *devfs_dev_inode_xp,
130                                       root_inode_xp );
131
132    if( error )
133    {
134        printk("\n[PANIC] in %s : cannot create <dev> directory\n", __FUNCTION__ );
135        hal_core_sleep();
136    }
137
138#if DEBUG_DEVFS_GLOBAL_INIT
139uint32_t   cycle = (uint32_t)hal_get_cycles();
140thread_t * this  = CURRENT_THREAD;
141if( DEBUG_DEVFS_GLOBAL_INIT < cycle )
142printk("\n[%s] thread[%x,%x] created <dev> inode / cycle %d\n",
143__FUNCTION__, this->process->pid, this->trdid, cycle );
144#endif
145
146    // create DEVFS "external" inode in cluster 0
147    error = vfs_add_child_in_parent( 0,               // cxy
148                                     FS_TYPE_DEVFS,
149                                     *devfs_dev_inode_xp,
150                                     "external",
151                                     &unused_xp,
152                                     devfs_external_inode_xp );
153
154    // update inode "type" field
155    inode = GET_PTR( *devfs_external_inode_xp );
156    inode->type = INODE_TYPE_DIR;
157 
158    // create dentries <.> and <..> in <external>
159    error |= vfs_add_special_dentries( *devfs_external_inode_xp,
160                                       *devfs_dev_inode_xp );
161
162    if( error )
163    {
164        printk("\n[PANIC] in %s : cannot create <external> directory\n", __FUNCTION__ );
165        hal_core_sleep();
166    }
167
168#if DEBUG_DEVFS_GLOBAL_INIT
169cycle = (uint32_t)hal_get_cycles();
170if( DEBUG_DEVFS_GLOBAL_INIT < cycle )
171printk("\n[%s] thread[%x,%x] created <external> inode / cycle %d\n",
172__FUNCTION__, this->process->pid, this->trdid, cycle );
173#endif
174
175}  // end devfs_global_init()
176
177///////////////////////////////////////////////////
178void devfs_local_init( xptr_t   devfs_dev_inode_xp,
179                       xptr_t   devfs_external_inode_xp )
180{
181    xptr_t        internal_inode_xp;   // extended pointer on <internal> inode
182    vfs_inode_t * internal_inode_ptr;  // local pointer on <internal> inode
183    char          node_name[16];
184    xptr_t        chdev_xp;
185    cxy_t         chdev_cxy;
186    chdev_t     * chdev_ptr;
187    xptr_t        inode_xp;
188    vfs_inode_t * inode_ptr;
189    uint32_t      channel;
190    xptr_t        unused_xp;           // required by add_child_in_parent()
191    error_t       error;
192   
193
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
202    // create <internal> directory
203    snprintf( node_name , 16 , "internal_%x" , local_cxy );
204
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
209                                     &unused_xp,
210                                     &internal_inode_xp );   // child inode
211
212    // set <internal> inode "type" field
213    internal_inode_ptr       = GET_PTR( internal_inode_xp );
214    internal_inode_ptr->type = INODE_TYPE_DEV;
215 
216    // create dentries <.> and <..> in <internal>
217    error |= vfs_add_special_dentries( internal_inode_xp,
218                                       devfs_dev_inode_xp );
219
220    if( error )
221    {
222        printk("\n[PANIC] in %s : cannot create <internal> directory\n", __FUNCTION__ );
223        hal_core_sleep();
224    }
225
226#if DEBUG_DEVFS_LOCAL_INIT
227cycle = (uint32_t)hal_get_cycles();
228if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
231#endif
232
233    // create MMC chdev inode
234    chdev_xp  = chdev_dir.mmc[local_cxy];
235    if( chdev_xp != XPTR_NULL)
236    {
237        chdev_ptr = GET_PTR( chdev_xp );
238        chdev_cxy = GET_CXY( chdev_xp );
239
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        }
246
247        error = vfs_add_child_in_parent( local_cxy,
248                                         FS_TYPE_DEVFS,
249                                         internal_inode_xp,
250                                         chdev_ptr->name,
251                                         &unused_xp,
252                                         &inode_xp );
253
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        }
260
261        // update child inode "extend" and "type" fields
262        inode_ptr = GET_PTR( inode_xp );
263        inode_ptr->extend = chdev_ptr;
264        inode_ptr->type   = INODE_TYPE_DEV;
265       
266#if DEBUG_DEVFS_LOCAL_INIT
267cycle = (uint32_t)hal_get_cycles();
268if( DEBUG_DEVFS_LOCAL_INIT < cycle )
269printk("\n[%s] thread[%x,%x] created <mmc> inode in cluster %x\n",
270__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
271#endif
272
273    }
274
275    // create DMA chdev inodes (one DMA channel per core)
276    for( channel = 0 ; channel < LOCAL_CLUSTER->cores_nr ; channel++ )
277    {
278        chdev_xp  = chdev_dir.dma[channel];
279        if( chdev_xp != XPTR_NULL)
280        {
281            chdev_ptr = GET_PTR( chdev_xp );
282            chdev_cxy = GET_CXY( chdev_xp );
283
284            if( chdev_cxy != local_cxy )
285            {
286                printk("\n[PANIC] in %s : illegal DMA chdev in cluster %x\n",
287                __FUNCTION__, local_cxy );
288                hal_core_sleep();
289            }
290
291            error = vfs_add_child_in_parent( local_cxy,
292                                             FS_TYPE_DEVFS,
293                                             internal_inode_xp,
294                                             chdev_ptr->name,
295                                             &unused_xp,
296                                             &inode_xp );
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            }
303
304            // update child inode "extend" and "type" fields
305            inode_ptr = GET_PTR( inode_xp );
306            inode_ptr->extend = chdev_ptr;
307            inode_ptr->type   = INODE_TYPE_DEV;
308       
309#if DEBUG_DEVFS_LOCAL_INIT
310cycle = (uint32_t)hal_get_cycles();
311if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
314#endif
315        }
316    }
317
318    // create an IOB inode in cluster containing IOB chdev
319    chdev_xp = chdev_dir.iob;
320    if( chdev_xp != XPTR_NULL )
321    {
322        chdev_cxy = GET_CXY( chdev_xp );
323        chdev_ptr = GET_PTR( chdev_xp );
324
325        if( chdev_cxy == local_cxy )
326        {
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 );
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            }
339
340            // update child inode "extend" and "type" fields
341            inode_ptr = GET_PTR( inode_xp );
342            inode_ptr->extend = chdev_ptr;
343            inode_ptr->type   = INODE_TYPE_DEV;
344       
345#if DEBUG_DEVFS_LOCAL_INIT
346cycle = (uint32_t)hal_get_cycles();
347if( DEBUG_DEVFS_LOCAL_INIT < cycle )
348printk("\n[%s] thread[%x,%x] created <iob> inode in cluster %x\n",
349__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
350#endif
351        }
352    }
353       
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 );
359        chdev_ptr = GET_PTR( chdev_xp );
360
361        if( chdev_cxy == local_cxy )
362        {
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 );
369
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            }
376
377            // update child inode "extend" field
378            inode_ptr = GET_PTR( inode_xp );
379            inode_ptr->extend = chdev_ptr;
380            inode_ptr->type   = INODE_TYPE_DEV;
381       
382#if DEBUG_DEVFS_LOCAL_INIT
383cycle = (uint32_t)hal_get_cycles();
384if( DEBUG_DEVFS_LOCAL_INIT < cycle )
385printk("\n[%s] thread[%x,%x] created <pic> inode in cluster %x\n",
386__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
387#endif
388        }
389    }
390
391    // create a TXT_RX inode in each cluster containing a TXT_RX chdev
392    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
393    {
394        chdev_xp = chdev_dir.txt_rx[channel];
395        if( chdev_xp != XPTR_NULL )
396        {
397            chdev_cxy = GET_CXY( chdev_xp );
398            chdev_ptr = GET_PTR( chdev_xp );
399
400            if( chdev_cxy == local_cxy )
401            {
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 );
408
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                }
415
416                // update child inode "extend" and "type" fields
417                inode_ptr = GET_PTR( inode_xp );
418                inode_ptr->extend = chdev_ptr;
419                inode_ptr->type   = INODE_TYPE_DEV;
420       
421#if DEBUG_DEVFS_LOCAL_INIT
422cycle = (uint32_t)hal_get_cycles();
423if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
426#endif
427            }
428        }
429    }
430
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 );
438            chdev_ptr = GET_PTR( chdev_xp );
439
440            if( chdev_cxy == local_cxy )
441            {
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 );
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                }
454
455                // update child inode "extend" and "type" fields
456                inode_ptr = GET_PTR( inode_xp );
457                inode_ptr->extend = chdev_ptr;
458                inode_ptr->type   = INODE_TYPE_DEV;
459       
460#if DEBUG_DEVFS_LOCAL_INIT
461cycle = (uint32_t)hal_get_cycles();
462if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
465#endif
466            }
467        }
468    }
469
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 )
475        {
476            chdev_cxy = GET_CXY( chdev_xp );
477            chdev_ptr = GET_PTR( chdev_xp );
478
479            if( chdev_cxy == local_cxy )
480            {
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 );
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                }
493
494                // update child inode "extend" and "type" fields
495                inode_ptr = GET_PTR( inode_xp );
496                inode_ptr->extend = chdev_ptr;
497                inode_ptr->type   = INODE_TYPE_DEV;
498       
499#if DEBUG_DEVFS_LOCAL_INIT
500cycle = (uint32_t)hal_get_cycles();
501if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
504#endif
505            }
506        }
507    }
508
509    // create a FBF inode in each cluster containing a FBF chdev
510    for( channel = 0 ; channel < CONFIG_MAX_FBF_CHANNELS ; channel++ )
511    {
512        chdev_xp = chdev_dir.fbf[channel];
513        if( chdev_xp != XPTR_NULL )
514        {
515            chdev_cxy = GET_CXY( chdev_xp );
516            chdev_ptr = GET_PTR( chdev_xp );
517
518            if( chdev_cxy == local_cxy )
519            {
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 );
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                }
532
533                // update child inode "extend" and "type" fields
534                inode_ptr = GET_PTR( inode_xp );
535                inode_ptr->extend = chdev_ptr;
536                inode_ptr->type   = INODE_TYPE_DEV;
537       
538#if DEBUG_DEVFS_LOCAL_INIT
539cycle = (uint32_t)hal_get_cycles();
540if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
543#endif
544            }
545        }
546    }
547
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 )
553        {
554            chdev_cxy = GET_CXY( chdev_xp );
555            chdev_ptr = GET_PTR( chdev_xp );
556
557            if( chdev_cxy == local_cxy )
558            {
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 );
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                }
571
572                // update child inode "extend" and "type" fields
573                inode_ptr = GET_PTR( inode_xp );
574                inode_ptr->extend = chdev_ptr;
575                inode_ptr->type   = INODE_TYPE_DEV;
576 
577#if DEBUG_DEVFS_LOCAL_INIT
578cycle = (uint32_t)hal_get_cycles();
579if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
582#endif
583            }
584        }
585    }
586
587    // create a NIC_TX inode in each cluster containing a NIC_TX chdev
588    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
589    {
590        chdev_xp = chdev_dir.nic_tx[channel];
591        if( chdev_xp != XPTR_NULL )
592        {
593            chdev_cxy = GET_CXY( chdev_xp );
594            chdev_ptr = GET_PTR( chdev_xp );
595
596            if( chdev_cxy == local_cxy )
597            {
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 );
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                }
610
611                // update child inode "extend" and "type" fields
612                inode_ptr = GET_PTR( inode_xp );
613                inode_ptr->extend = chdev_ptr;
614                inode_ptr->type   = INODE_TYPE_DEV;
615       
616#if DEBUG_DEVFS_LOCAL_INIT
617cycle = (uint32_t)hal_get_cycles();
618if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
621#endif
622            }
623        }
624    }
625}  // end devfs_local_init()
626
627//////////////////////////////////////////
628int devfs_user_move( bool_t     to_buffer,
629                     xptr_t     file_xp,
630                     char     * u_buf,
631                     uint32_t   size )
632{
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;
642
643    char             k_buf[CONFIG_TXT_KBUF_SIZE];  // local kernel buffer
644
645assert( ( file_xp != XPTR_NULL ) , "file_xp == XPTR_NULL" );
646
647#if (DEBUG_SYS_READ & 1)
648enter_devfs_read = hal_time_stamp();
649#endif
650
651#if (DEBUG_SYS_WRITE & 1)
652enter_devfs_write = hal_time_stamp();
653#endif
654
655#if DEBUG_DEVFS_MOVE
656uint32_t   cycle = (uint32_t)hal_get_cycles();
657thread_t * this  = CURRENT_THREAD;
658if( DEBUG_DEVFS_MOVE < cycle )
659printk("\n[%s] thread[%x,%x] enter / to_mem %d / cycle %d\n",
660__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
661#endif
662
663    // get extended pointer on chdev_xp
664    chdev_xp = chdev_from_file( file_xp );
665
666    // get cluster and local pointer on chdev
667    chdev_cxy  = GET_CXY( chdev_xp );
668    chdev_ptr  = (chdev_t *)GET_PTR( chdev_xp );
669
670    // get chdev functionnal type and channel
671    func    = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->func ) );
672    channel = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->channel ) );
673
674// Only TXT devices are associated to a pseudo-file
675assert( ( func == DEV_FUNC_TXT ) , __FUNCTION__, "illegal device func_type");
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++ )
691            {
692                error = dev_txt_read( channel , &k_buf[i] );
693
694                if( error )  return -1;
695            }
696
697            // move burst bytes from k_buf to u_buf                   
698            hal_strcpy_to_uspace( u_buf,
699                                  XPTR( local_cxy , k_buf ),
700                                  burst );
701
702            // update loop variables
703            todo  -= burst;
704            u_buf += burst;
705        }
706
707#if DEBUG_DEVFS_MOVE
708cycle = (uint32_t)hal_get_cycles();
709if( DEBUG_DEVFS_MOVE < cycle )
710printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
711__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
712#endif
713
714#if (DEBUG_SYS_READ & 1)
715exit_devfs_read = hal_time_stamp();
716#endif
717            return size;
718    } 
719    ///////////// TXT write 
720    else               
721    {
722        while( todo )
723        {
724            // set burst size
725            if( todo > CONFIG_TXT_KBUF_SIZE ) burst = CONFIG_TXT_KBUF_SIZE;
726            else                              burst = todo;
727
728            // move burst bytes from u_buf to k_buf
729            hal_strcpy_from_uspace( XPTR( local_cxy , k_buf ) , u_buf , burst );
730
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
741#if DEBUG_DEVFS_MOVE
742cycle = (uint32_t)hal_get_cycles();
743if( DEBUG_DEVFS_MOVE < cycle )
744printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
745__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
746#endif
747
748#if (DEBUG_SYS_WRITE & 1)
749exit_devfs_write = hal_time_stamp();
750#endif
751            return size;
752    }
753
754}  // end devfs_user_move()
755
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
770
771// detailed argument unused
772assert( (detailed == false) , "detailed argument not supported\n");
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.