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

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

Introduce the non-standard pthread_parallel_create() system call
and re-write the <fft> and <sort> applications to improve the
intrinsic paralelism in applications.

File size: 27.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)
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/////////////////////////////////////
56devfs_ctx_t * devfs_ctx_alloc( void )
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        return kmem_alloc( &req );
65}
66
67/////////////////////////////////////////////
68void devfs_ctx_init( devfs_ctx_t * devfs_ctx,
69                     xptr_t        devfs_dev_inode_xp,
70                     xptr_t        devfs_external_inode_xp )
71{
72    devfs_ctx->dev_inode_xp      = devfs_dev_inode_xp;
73    devfs_ctx->external_inode_xp = devfs_external_inode_xp;
74
75    fs_context[FS_TYPE_DEVFS].extend = devfs_ctx;
76}
77
78/////////////////////////////////////////////////
79void devfs_ctx_destroy( devfs_ctx_t * devfs_ctx )
80{
81    kmem_req_t    req;
82
83    req.type = KMEM_KCM;
84    req.ptr  = devfs_ctx;
85    kmem_free( &req );
86}
87
88/////////////////////////////////////////////////
89void devfs_global_init( xptr_t   root_inode_xp,
90                        xptr_t * devfs_dev_inode_xp,
91                        xptr_t * devfs_external_inode_xp )
92{
93    error_t       error;
94    xptr_t        unused_xp;   // required by vfs_add_child_in_parent()
95    vfs_inode_t * inode;
96
97    // create DEVFS "dev" inode in cluster 0
98    error = vfs_add_child_in_parent( 0,                // cxy
99                                     FS_TYPE_DEVFS,
100                                     root_inode_xp,
101                                     "dev",
102                                     &unused_xp,
103                                     devfs_dev_inode_xp );
104
105    // update inode "type" field
106    inode = GET_PTR( *devfs_dev_inode_xp );
107    inode->type = INODE_TYPE_DIR;
108 
109    // create dentries <.> and <..> in <dev>
110    error |= vfs_add_special_dentries( *devfs_dev_inode_xp,
111                                       root_inode_xp );
112
113    if( error )
114    {
115        printk("\n[PANIC] in %s : cannot create <dev> directory\n", __FUNCTION__ );
116        hal_core_sleep();
117    }
118
119#if DEBUG_DEVFS_GLOBAL_INIT
120uint32_t   cycle = (uint32_t)hal_get_cycles();
121thread_t * this  = CURRENT_THREAD;
122if( DEBUG_DEVFS_GLOBAL_INIT < cycle )
123printk("\n[%s] thread[%x,%x] created <dev> inode / cycle %d\n",
124__FUNCTION__, this->process->pid, this->trdid, cycle );
125#endif
126
127    // create DEVFS "external" inode in cluster 0
128    error = vfs_add_child_in_parent( 0,               // cxy
129                                     FS_TYPE_DEVFS,
130                                     *devfs_dev_inode_xp,
131                                     "external",
132                                     &unused_xp,
133                                     devfs_external_inode_xp );
134
135    // update inode "type" field
136    inode = GET_PTR( *devfs_external_inode_xp );
137    inode->type = INODE_TYPE_DIR;
138 
139    // create dentries <.> and <..> in <external>
140    error |= vfs_add_special_dentries( *devfs_external_inode_xp,
141                                       *devfs_dev_inode_xp );
142
143    if( error )
144    {
145        printk("\n[PANIC] in %s : cannot create <external> directory\n", __FUNCTION__ );
146        hal_core_sleep();
147    }
148
149#if DEBUG_DEVFS_GLOBAL_INIT
150cycle = (uint32_t)hal_get_cycles();
151if( DEBUG_DEVFS_GLOBAL_INIT < cycle )
152printk("\n[%s] thread[%x,%x] created <external> inode / cycle %d\n",
153__FUNCTION__, this->process->pid, this->trdid, cycle );
154#endif
155
156}  // end devfs_global_init()
157
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 )
162{
163    char          node_name[16];
164    xptr_t        chdev_xp;
165    cxy_t         chdev_cxy;
166    chdev_t     * chdev_ptr;
167    xptr_t        inode_xp;
168    vfs_inode_t * inode_ptr;
169    uint32_t      channel;
170    xptr_t        unused_xp;    // required by add_child_in_parent()
171    error_t       error;
172
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
181    // create "internal" directory
182    snprintf( node_name , 16 , "internal_%x" , local_cxy );
183
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
191    // set inode "type" field
192    inode_ptr = GET_PTR( *devfs_internal_inode_xp );
193    inode_ptr->type = INODE_TYPE_DEV;
194 
195    // create dentries <.> and <..> in <internal>
196    error |= vfs_add_special_dentries( *devfs_internal_inode_xp,
197                                       devfs_dev_inode_xp );
198
199    if( error )
200    {
201        printk("\n[PANIC] in %s : cannot create <internal> directory\n", __FUNCTION__ );
202        hal_core_sleep();
203    }
204
205#if DEBUG_DEVFS_LOCAL_INIT
206cycle = (uint32_t)hal_get_cycles();
207if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
210#endif
211
212    // create MMC chdev inode
213    chdev_xp  = chdev_dir.mmc[local_cxy];
214    if( chdev_xp != XPTR_NULL)
215    {
216        chdev_ptr = GET_PTR( chdev_xp );
217        chdev_cxy = GET_CXY( chdev_xp );
218
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        }
225
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 );
232
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        }
239
240        // update child inode "extend" and "type" fields
241        inode_ptr = GET_PTR( inode_xp );
242        inode_ptr->extend = chdev_ptr;
243        inode_ptr->type   = INODE_TYPE_DEV;
244       
245#if DEBUG_DEVFS_LOCAL_INIT
246cycle = (uint32_t)hal_get_cycles();
247if( DEBUG_DEVFS_LOCAL_INIT < cycle )
248printk("\n[%s] thread[%x,%x] created <mmc> inode in cluster %x\n",
249__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
250#endif
251
252    }
253
254    // create DMA chdev inodes (one DMA channel per core)
255    for( channel = 0 ; channel < LOCAL_CLUSTER->cores_nr ; channel++ )
256    {
257        chdev_xp  = chdev_dir.dma[channel];
258        if( chdev_xp != XPTR_NULL)
259        {
260            chdev_ptr = GET_PTR( chdev_xp );
261            chdev_cxy = GET_CXY( chdev_xp );
262
263            if( chdev_cxy != local_cxy )
264            {
265                printk("\n[PANIC] in %s : illegal DMA chdev in cluster %x\n",
266                __FUNCTION__, local_cxy );
267                hal_core_sleep();
268            }
269
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 );
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            }
282
283            // update child inode "extend" and "type" fields
284            inode_ptr = GET_PTR( inode_xp );
285            inode_ptr->extend = chdev_ptr;
286            inode_ptr->type   = INODE_TYPE_DEV;
287       
288#if DEBUG_DEVFS_LOCAL_INIT
289cycle = (uint32_t)hal_get_cycles();
290if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
293#endif
294        }
295    }
296
297    // create an IOB inode in cluster containing IOB chdev
298    chdev_xp = chdev_dir.iob;
299    if( chdev_xp != XPTR_NULL )
300    {
301        chdev_cxy = GET_CXY( chdev_xp );
302        chdev_ptr = GET_PTR( chdev_xp );
303
304        if( chdev_cxy == local_cxy )
305        {
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 );
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            }
318
319            // update child inode "extend" and "type" fields
320            inode_ptr = GET_PTR( inode_xp );
321            inode_ptr->extend = chdev_ptr;
322            inode_ptr->type   = INODE_TYPE_DEV;
323       
324#if DEBUG_DEVFS_LOCAL_INIT
325cycle = (uint32_t)hal_get_cycles();
326if( DEBUG_DEVFS_LOCAL_INIT < cycle )
327printk("\n[%s] thread[%x,%x] created <iob> inode in cluster %x\n",
328__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
329#endif
330        }
331    }
332       
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 );
338        chdev_ptr = GET_PTR( chdev_xp );
339
340        if( chdev_cxy == local_cxy )
341        {
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 );
348
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            }
355
356            // update child inode "extend" field
357            inode_ptr = GET_PTR( inode_xp );
358            inode_ptr->extend = chdev_ptr;
359            inode_ptr->type   = INODE_TYPE_DEV;
360       
361#if DEBUG_DEVFS_LOCAL_INIT
362cycle = (uint32_t)hal_get_cycles();
363if( DEBUG_DEVFS_LOCAL_INIT < cycle )
364printk("\n[%s] thread[%x,%x] created <pic> inode in cluster %x\n",
365__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
366#endif
367        }
368    }
369
370    // create a TXT_RX inode in each cluster containing a TXT_RX chdev
371    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
372    {
373        chdev_xp = chdev_dir.txt_rx[channel];
374        if( chdev_xp != XPTR_NULL )
375        {
376            chdev_cxy = GET_CXY( chdev_xp );
377            chdev_ptr = GET_PTR( chdev_xp );
378
379            if( chdev_cxy == local_cxy )
380            {
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 );
387
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                }
394
395                // update child inode "extend" and "type" fields
396                inode_ptr = GET_PTR( inode_xp );
397                inode_ptr->extend = chdev_ptr;
398                inode_ptr->type   = INODE_TYPE_DEV;
399       
400#if DEBUG_DEVFS_LOCAL_INIT
401cycle = (uint32_t)hal_get_cycles();
402if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
405#endif
406            }
407        }
408    }
409
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 );
417            chdev_ptr = GET_PTR( chdev_xp );
418
419            if( chdev_cxy == local_cxy )
420            {
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 );
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                }
433
434                // update child inode "extend" and "type" fields
435                inode_ptr = GET_PTR( inode_xp );
436                inode_ptr->extend = chdev_ptr;
437                inode_ptr->type   = INODE_TYPE_DEV;
438       
439#if DEBUG_DEVFS_LOCAL_INIT
440cycle = (uint32_t)hal_get_cycles();
441if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
444#endif
445            }
446        }
447    }
448
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 )
454        {
455            chdev_cxy = GET_CXY( chdev_xp );
456            chdev_ptr = GET_PTR( chdev_xp );
457
458            if( chdev_cxy == local_cxy )
459            {
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 );
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                }
472
473                // update child inode "extend" and "type" fields
474                inode_ptr = GET_PTR( inode_xp );
475                inode_ptr->extend = chdev_ptr;
476                inode_ptr->type   = INODE_TYPE_DEV;
477       
478#if DEBUG_DEVFS_LOCAL_INIT
479cycle = (uint32_t)hal_get_cycles();
480if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
483#endif
484            }
485        }
486    }
487
488    // create a FBF inode in each cluster containing a FBF chdev
489    for( channel = 0 ; channel < CONFIG_MAX_FBF_CHANNELS ; channel++ )
490    {
491        chdev_xp = chdev_dir.fbf[channel];
492        if( chdev_xp != XPTR_NULL )
493        {
494            chdev_cxy = GET_CXY( chdev_xp );
495            chdev_ptr = GET_PTR( chdev_xp );
496
497            if( chdev_cxy == local_cxy )
498            {
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 );
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                }
511
512                // update child inode "extend" and "type" fields
513                inode_ptr = GET_PTR( inode_xp );
514                inode_ptr->extend = chdev_ptr;
515                inode_ptr->type   = INODE_TYPE_DEV;
516       
517#if DEBUG_DEVFS_LOCAL_INIT
518cycle = (uint32_t)hal_get_cycles();
519if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
522#endif
523            }
524        }
525    }
526
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 )
532        {
533            chdev_cxy = GET_CXY( chdev_xp );
534            chdev_ptr = GET_PTR( chdev_xp );
535
536            if( chdev_cxy == local_cxy )
537            {
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 );
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                }
550
551                // update child inode "extend" and "type" fields
552                inode_ptr = GET_PTR( inode_xp );
553                inode_ptr->extend = chdev_ptr;
554                inode_ptr->type   = INODE_TYPE_DEV;
555 
556#if DEBUG_DEVFS_LOCAL_INIT
557cycle = (uint32_t)hal_get_cycles();
558if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
561#endif
562            }
563        }
564    }
565
566    // create a NIC_TX inode in each cluster containing a NIC_TX chdev
567    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
568    {
569        chdev_xp = chdev_dir.nic_tx[channel];
570        if( chdev_xp != XPTR_NULL )
571        {
572            chdev_cxy = GET_CXY( chdev_xp );
573            chdev_ptr = GET_PTR( chdev_xp );
574
575            if( chdev_cxy == local_cxy )
576            {
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 );
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                }
589
590                // update child inode "extend" and "type" fields
591                inode_ptr = GET_PTR( inode_xp );
592                inode_ptr->extend = chdev_ptr;
593                inode_ptr->type   = INODE_TYPE_DEV;
594       
595#if DEBUG_DEVFS_LOCAL_INIT
596cycle = (uint32_t)hal_get_cycles();
597if( DEBUG_DEVFS_LOCAL_INIT < cycle )
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 );
600#endif
601            }
602        }
603    }
604}  // end devfs_local_init()
605
606//////////////////////////////////////////
607int devfs_user_move( bool_t     to_buffer,
608                     xptr_t     file_xp,
609                     char     * u_buf,
610                     uint32_t   size )
611{
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;
621
622    char             k_buf[CONFIG_TXT_KBUF_SIZE];  // local kernel buffer
623
624assert( ( file_xp != XPTR_NULL ) , "file_xp == XPTR_NULL" );
625
626#if (DEBUG_SYS_READ & 1)
627enter_devfs_read = hal_time_stamp();
628#endif
629
630#if (DEBUG_SYS_WRITE & 1)
631enter_devfs_write = hal_time_stamp();
632#endif
633
634#if DEBUG_DEVFS_MOVE
635uint32_t   cycle = (uint32_t)hal_get_cycles();
636thread_t * this  = CURRENT_THREAD;
637if( DEBUG_DEVFS_MOVE < cycle )
638printk("\n[%s] thread[%x,%x] enter / to_mem %d / cycle %d\n",
639__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
640#endif
641
642    // get extended pointer on chdev_xp
643    chdev_xp = chdev_from_file( file_xp );
644
645    // get cluster and local pointer on chdev
646    chdev_cxy  = GET_CXY( chdev_xp );
647    chdev_ptr  = (chdev_t *)GET_PTR( chdev_xp );
648
649    // get chdev functionnal type and channel
650    func    = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->func ) );
651    channel = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->channel ) );
652
653// Only TXT devices are associated to a pseudo-file
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++ )
670            {
671                error = dev_txt_read( channel , &k_buf[i] );
672
673                if( error )  return -1;
674            }
675
676            // move burst bytes from k_buf to u_buf                   
677            hal_strcpy_to_uspace( u_buf,
678                                  XPTR( local_cxy , k_buf ),
679                                  burst );
680
681            // update loop variables
682            todo  -= burst;
683            u_buf += burst;
684        }
685
686#if DEBUG_DEVFS_MOVE
687cycle = (uint32_t)hal_get_cycles();
688if( DEBUG_DEVFS_MOVE < cycle )
689printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
690__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
691#endif
692
693#if (DEBUG_SYS_READ & 1)
694exit_devfs_read = hal_time_stamp();
695#endif
696            return size;
697    } 
698    ///////////// TXT write 
699    else               
700    {
701        while( todo )
702        {
703            // set burst size
704            if( todo > CONFIG_TXT_KBUF_SIZE ) burst = CONFIG_TXT_KBUF_SIZE;
705            else                              burst = todo;
706
707            // move burst bytes from u_buf to k_buf
708            hal_strcpy_from_uspace( XPTR( local_cxy , k_buf ) , u_buf , burst );
709
710            // write burst bytes from kernel buffer to TXT device
711            error = dev_txt_write( channel , k_buf , burst );
712
713            if( error ) return -1;
714
715            // update loop variables
716            todo  -= burst;
717            u_buf += burst;
718        } 
719
720#if DEBUG_DEVFS_MOVE
721cycle = (uint32_t)hal_get_cycles();
722if( DEBUG_DEVFS_MOVE < cycle )
723printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
724__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
725#endif
726
727#if (DEBUG_SYS_WRITE & 1)
728exit_devfs_write = hal_time_stamp();
729#endif
730            return size;
731    }
732
733}  // end devfs_user_move()
734
735///////////////////////////////////////////////////////
736error_t devfs_get_user_dir( struct vfs_inode_s * inode,
737                            struct dirent      * array,
738                            uint32_t             max_dirent,
739                            uint32_t             min_dentry,
740                            bool_t               detailed,
741                            uint32_t           * entries,
742                            bool_t             * done )
743{
744    xptr_t         xhtab_xp;    // extended pointer on inode xhtab (children dentries)
745    xptr_t         dentry_xp;   // extended pointer on current dentry
746    vfs_dentry_t * dentry_ptr;  // local pointer on current dentry
747    uint32_t       dentry_id;   // dentry index in set of children dentry   
748    uint32_t       dirent_id;   // dirent index in array of dirent
749
750// detailed argument unused
751assert( (detailed == false) , "detailed argument not supported\n");
752 
753    // One loop to scan the target inode xhtab containing the set of dentries
754    // exit loop if no more dentries, or dirent array full
755
756#if DEBUG_DEVFS_GET_USER_DIR
757char       inode_name[CONFIG_VFS_MAX_NAME_LENGTH];
758uint32_t   cycle = (uint32_t)hal_get_cycles();
759thread_t * this  = CURRENT_THREAD;
760vfs_inode_get_name( XPTR( local_cxy , inode ) , inode_name );
761if( DEBUG_DEVFS_GET_USER_DIR < cycle )
762printk("\n[%s]  thread[%x,%x] enter for inode <%s> / cycle %d\n",
763__FUNCTION__, this->process->pid, this->trdid, inode_name , cycle );
764#endif
765
766    // get extended pointer on inode xhtab
767    xhtab_xp  = XPTR( local_cxy , &inode->children );
768
769    // initialize loop variables
770    dentry_xp = xhtab_get_first( xhtab_xp );
771    dentry_id = 0;
772    dirent_id = 0;
773
774    while( (dentry_xp != XPTR_NULL ) && (dirent_id < max_dirent) )
775    {
776        if( dentry_id >= min_dentry )
777        {
778            // copy name into dirent array
779            dentry_ptr = GET_PTR( dentry_xp );
780            strcpy( array[dirent_id].d_name , dentry_ptr->name ); 
781
782            // increment dirent_id
783            dirent_id++;
784        }
785         
786        // update loop variables
787        dentry_xp = xhtab_get_next( xhtab_xp );
788        dentry_id++;
789    }
790
791    // return results of scan
792    *done    = (dentry_xp == XPTR_NULL);
793    *entries = dirent_id;
794
795#if DEBUG_DEVFS_GET_USER_DIR
796cycle = (uint32_t)hal_get_cycles();
797if( DEBUG_DEVFS_GET_USER_DIR < cycle )
798printk("\n[%s]  thread[%x,%x] exit for inode <%s> / %d entries / cycle %d\n",
799__FUNCTION__, this->process->pid, this->trdid, inode_name, entries, cycle );
800#endif
801
802    return 0;
803   
804}  // en devfs_get_user_dir()
805
Note: See TracBrowser for help on using the repository browser.