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

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

Fix several bugs to use the instruction MMU in kernel mode
in replacement of the instruction address extension register,
and remove the "kentry" segment.

This version is running on the tsar_generic_iob" platform.

One interesting bug: the cp0_ebase defining the kernel entry point
(for interrupts, exceptions and syscalls) must be initialized
early in kernel_init(), because the VFS initialisation done by
kernel_ini() uses RPCs, and RPCs uses Inter-Processor-Interrup.

File size: 27.5 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_DEVFS_CTX;
61        req.size    = sizeof(devfs_ctx_t);
62    req.flags   = AF_KERNEL | AF_ZERO;
63
64        return (devfs_ctx_t *)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_DEVFS_CTX;
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 , k_buf , burst );
678
679            // update loop variables
680            todo  -= burst;
681            u_buf += burst;
682        }
683
684#if DEBUG_DEVFS_MOVE
685cycle = (uint32_t)hal_get_cycles();
686if( DEBUG_DEVFS_MOVE < cycle )
687printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
688__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
689#endif
690
691#if (DEBUG_SYS_READ & 1)
692exit_devfs_read = hal_time_stamp();
693#endif
694            return size;
695    } 
696    ///////////// TXT write 
697    else               
698    {
699        while( todo )
700        {
701            // set burst size
702            if( todo > CONFIG_TXT_KBUF_SIZE ) burst = CONFIG_TXT_KBUF_SIZE;
703            else                              burst = todo;
704
705            // move burst bytes from u_buf to k_buf
706            hal_strcpy_from_uspace( k_buf , u_buf , burst );
707
708            // write burst bytes from kernel buffer to TXT device
709            error = dev_txt_write( channel , k_buf , burst );
710
711            if( error ) return -1;
712
713            // update loop variables
714            todo  -= burst;
715            u_buf += burst;
716        } 
717
718#if DEBUG_DEVFS_MOVE
719cycle = (uint32_t)hal_get_cycles();
720if( DEBUG_DEVFS_MOVE < cycle )
721printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
722__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
723#endif
724
725#if (DEBUG_SYS_WRITE & 1)
726exit_devfs_write = hal_time_stamp();
727#endif
728            return size;
729    }
730
731}  // end devfs_user_move()
732
733///////////////////////////////////////////////////////
734error_t devfs_get_user_dir( struct vfs_inode_s * inode,
735                            struct dirent      * array,
736                            uint32_t             max_dirent,
737                            uint32_t             min_dentry,
738                            bool_t               detailed,
739                            uint32_t           * entries,
740                            bool_t             * done )
741{
742    xptr_t         xhtab_xp;    // extended pointer on inode xhtab (children dentries)
743    xptr_t         dentry_xp;   // extended pointer on current dentry
744    vfs_dentry_t * dentry_ptr;  // local pointer on current dentry
745    uint32_t       dentry_id;   // dentry index in set of children dentry   
746    uint32_t       dirent_id;   // dirent index in array of dirent
747
748// detailed argument unused
749assert( (detailed == false) , "detailed argument not supported\n");
750 
751    // One loop to scan the target inode xhtab containing the set of dentries
752    // exit loop if no more dentries, or dirent array full
753
754#if DEBUG_DEVFS_GET_USER_DIR
755char       inode_name[CONFIG_VFS_MAX_NAME_LENGTH];
756uint32_t   cycle = (uint32_t)hal_get_cycles();
757thread_t * this  = CURRENT_THREAD;
758vfs_inode_get_name( XPTR( local_cxy , inode ) , inode_name );
759if( DEBUG_DEVFS_GET_USER_DIR < cycle )
760printk("\n[%s]  thread[%x,%x] enter for inode <%s> / cycle %d\n",
761__FUNCTION__, this->process->pid, this->trdid, inode_name , cycle );
762#endif
763
764    // get extended pointer on inode xhtab
765    xhtab_xp  = XPTR( local_cxy , &inode->children );
766
767    // initialize loop variables
768    dentry_xp = xhtab_get_first( xhtab_xp );
769    dentry_id = 0;
770    dirent_id = 0;
771
772    while( (dentry_xp != XPTR_NULL ) && (dirent_id < max_dirent) )
773    {
774        if( dentry_id >= min_dentry )
775        {
776            // copy name into dirent array
777            dentry_ptr = GET_PTR( dentry_xp );
778            strcpy( array[dirent_id].d_name , dentry_ptr->name ); 
779
780            // increment dirent_id
781            dirent_id++;
782        }
783         
784        // update loop variables
785        dentry_xp = xhtab_get_next( xhtab_xp );
786        dentry_id++;
787    }
788
789    // return results of scan
790    *done    = (dentry_xp == XPTR_NULL);
791    *entries = dirent_id;
792
793#if DEBUG_DEVFS_GET_USER_DIR
794cycle = (uint32_t)hal_get_cycles();
795if( DEBUG_DEVFS_GET_USER_DIR < cycle )
796printk("\n[%s]  thread[%x,%x] exit for inode <%s> / %d entries / cycle %d\n",
797__FUNCTION__, this->process->pid, this->trdid, inode_name, entries, cycle );
798#endif
799
800    return 0;
801   
802}  // en devfs_get_user_dir()
803
Note: See TracBrowser for help on using the repository browser.