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

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

Fix several bugs in VFS to support the following
ksh commandis : cp, mv, rm, mkdir, cd, pwd

File size: 21.1 KB
RevLine 
[23]1/*
2 * devfs.c - DEVFS File system API implementation.
3 *
4 * Author   Mohamed Lamine Karaoui (2014,2015)
5 *          Alain Greiner (2016,2017)
6 *
7 * Copyright (c) Sorbonne Universites
8 *
9 * This file is part of ALMOS-MKH.
10 *
11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2.0 of the License.
14 *
15 * ALMOS-MKH is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
[457]25#include <hal_kernel_types.h>
[23]26#include <hal_special.h>
[407]27#include <hal_uspace.h>
[23]28#include <printk.h>
29#include <chdev.h>
[433]30#include <thread.h>
[407]31#include <dev_txt.h>
[188]32#include <cluster.h>
[23]33#include <vfs.h>
[188]34#include <kmem.h>
[23]35#include <devfs.h>
36
[188]37/////////////////////////////////////////////////////////////////////////////////////////
38//     Extern variables
39/////////////////////////////////////////////////////////////////////////////////////////
[23]40
[188]41extern vfs_ctx_t            fs_context[];   // allocated in kernel_init.c
42extern chdev_directory_t    chdev_dir;      // allocated in kernel_init.c
[23]43
[438]44#if (DEBUG_SYS_READ & 1)
[435]45extern uint32_t  enter_devfs_read;
46extern uint32_t  exit_devfs_read;
[407]47#endif
48
[438]49#if (DEBUG_SYS_WRITE & 1)
[435]50extern uint32_t  enter_devfs_write;
51extern uint32_t  exit_devfs_write;
52#endif
53
[568]54/////////////////////////////////////
[484]55devfs_ctx_t * devfs_ctx_alloc( void )
[188]56{
57    kmem_req_t    req;
[23]58
[188]59        req.type    = KMEM_DEVFS_CTX;
60        req.size    = sizeof(devfs_ctx_t);
61    req.flags   = AF_KERNEL | AF_ZERO;
[23]62
[188]63        return (devfs_ctx_t *)kmem_alloc( &req );
64}
[23]65
[188]66/////////////////////////////////////////////
67void devfs_ctx_init( devfs_ctx_t * devfs_ctx,
[204]68                     xptr_t        devfs_dev_inode_xp,
[188]69                     xptr_t        devfs_external_inode_xp )
[23]70{
[204]71    devfs_ctx->dev_inode_xp      = devfs_dev_inode_xp;
[188]72    devfs_ctx->external_inode_xp = devfs_external_inode_xp;
[23]73
[188]74    fs_context[FS_TYPE_DEVFS].extend = devfs_ctx;
75}
[23]76
[188]77/////////////////////////////////////////////////
78void devfs_ctx_destroy( devfs_ctx_t * devfs_ctx )
79{
80    kmem_req_t    req;
[23]81
[188]82    req.type = KMEM_DEVFS_CTX;
83    req.ptr  = devfs_ctx;
84    kmem_free( &req );
85}
[23]86
[437]87/////////////////////////////////////////////////
[602]88void devfs_global_init( xptr_t   root_inode_xp,
[204]89                        xptr_t * devfs_dev_inode_xp,
[188]90                        xptr_t * devfs_external_inode_xp )
[23]91{
92    error_t  error;
[602]93    xptr_t   unused_xp;   // required by vfs_add_child_in_parent()
[23]94
[610]95    // create DEVFS "dev" inode in cluster 0
[457]96    error = vfs_add_child_in_parent( 0,                // cxy
[188]97                                     INODE_TYPE_DIR,
98                                     FS_TYPE_DEVFS,
[602]99                                     root_inode_xp,
[188]100                                     "dev",
[602]101                                     &unused_xp,
102                                     devfs_dev_inode_xp );
[23]103
[610]104// check success
105assert( (error == 0) , "cannot create <dev>\n" );
[23]106
[568]107#if DEBUG_DEVFS_INIT
[598]108uint32_t   cycle = (uint32_t)hal_get_cycles();
109thread_t * this  = CURRENT_THREAD;
[438]110if( DEBUG_DEVFS_INIT < cycle )
[598]111printk("\n[%s] thread[%x,%x] created <dev> inode / cycle %d\n",
112__FUNCTION__, this->process->pid, this->trdid, cycle );
[437]113#endif
114
[457]115    // create DEVFS "external" inode in cluster 0
116    error = vfs_add_child_in_parent( 0,               // cxy
[188]117                                     INODE_TYPE_DIR,
118                                     FS_TYPE_DEVFS,
[204]119                                     *devfs_dev_inode_xp,
120                                     "external",
[602]121                                     &unused_xp,
122                                     devfs_external_inode_xp );
[23]123
[492]124    assert( (error == 0) , "cannot create <external>\n" );
[279]125
[438]126#if DEBUG_DEVFS_INIT
[433]127cycle = (uint32_t)hal_get_cycles();
[438]128if( DEBUG_DEVFS_INIT < cycle )
[598]129printk("\n[%s] thread[%x,%x] created <external> inode / cycle %d\n",
130__FUNCTION__, this->process->pid, this->trdid, cycle );
[433]131#endif
132
[602]133}  // end devfs_global_init()
[23]134
[204]135///////////////////////////////////////////////////
136void devfs_local_init( xptr_t   devfs_dev_inode_xp,
137                       xptr_t   devfs_external_inode_xp,
138                       xptr_t * devfs_internal_inode_xp )
[23]139{
140    char          node_name[16];
[188]141    xptr_t        chdev_xp;
142    cxy_t         chdev_cxy;
[407]143    chdev_t     * chdev_ptr;
[188]144    xptr_t        inode_xp;
[602]145    cxy_t         inode_cxy;
146    vfs_inode_t * inode_ptr;
[23]147    uint32_t      channel;
[602]148    xptr_t        unused_xp;    // required by add_child_in_parent()
[23]149
[568]150    // create "internal" directory
[188]151    snprintf( node_name , 16 , "internal_%x" , local_cxy );
[610]152
[188]153    vfs_add_child_in_parent( local_cxy,
154                             INODE_TYPE_DIR,
155                             FS_TYPE_DEVFS,
[204]156                             devfs_dev_inode_xp,
[188]157                             node_name,
[602]158                             &unused_xp,
[204]159                             devfs_internal_inode_xp );
[568]160#if DEBUG_DEVFS_INIT
[598]161uint32_t   cycle = (uint32_t)hal_get_cycles();
162thread_t * this  = CURRENT_THREAD;
[568]163if( DEBUG_DEVFS_INIT < cycle )
[598]164printk("\n[%s] thread[%x,%x] created <%s> inode in cluster %x / cycle %d\n",
165__FUNCTION__, this->process->pid, this->trdid, node_name, local_cxy, cycle );
[568]166#endif
[23]167
168    // create MMC chdev inode
[407]169    chdev_xp  = chdev_dir.mmc[local_cxy];
[188]170    if( chdev_xp != XPTR_NULL)
171    {
[602]172        chdev_ptr = GET_PTR( chdev_xp );
[610]173        chdev_cxy = GET_CXY( chdev_xp );
174
175assert( (chdev_cxy == local_cxy ), 
176"illegal MMC chdev_xp in cluster %x\n", local_cxy );
177
[188]178        vfs_add_child_in_parent( local_cxy,
179                                 INODE_TYPE_DEV,
180                                 FS_TYPE_DEVFS,
[204]181                                 *devfs_internal_inode_xp,
[407]182                                 chdev_ptr->name,
[602]183                                 &unused_xp,
[188]184                                 &inode_xp );
[602]185
186        // update child inode "extend" field
187        inode_cxy = GET_CXY( inode_xp );
188        inode_ptr = GET_PTR( inode_xp );
189        hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
190       
[568]191#if DEBUG_DEVFS_INIT
192cycle = (uint32_t)hal_get_cycles();
193if( DEBUG_DEVFS_INIT < cycle )
[598]194printk("\n[%s] thread[%x,%x] created <mmc> inode in cluster %x\n",
195__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
[568]196#endif
197
[188]198    }
[23]199
200    // create DMA chdev inodes (one DMA channel per core)
[188]201    for( channel = 0 ; channel < LOCAL_CLUSTER->cores_nr ; channel++ )
[23]202    {
[602]203        chdev_xp  = chdev_dir.dma[channel];
[188]204        if( chdev_xp != XPTR_NULL)
205        {
[602]206            chdev_ptr = GET_PTR( chdev_xp );
[610]207            chdev_cxy = GET_CXY( chdev_xp );
208
209assert( (chdev_cxy == local_cxy ), 
210"illegal DMA[%d] chdev_xp in cluster %x\n", channel, local_cxy );
211
[188]212            vfs_add_child_in_parent( local_cxy,
213                                     INODE_TYPE_DEV,
214                                     FS_TYPE_DEVFS,
[204]215                                     *devfs_internal_inode_xp,
[407]216                                     chdev_ptr->name,
[602]217                                     &unused_xp,
[188]218                                     &inode_xp );
[602]219
220            // update child inode "extend" field
221            inode_cxy = GET_CXY( inode_xp );
222            inode_ptr = GET_PTR( inode_xp );
223            hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
224       
[568]225#if DEBUG_DEVFS_INIT
226cycle = (uint32_t)hal_get_cycles();
227if( DEBUG_DEVFS_INIT < cycle )
[598]228printk("\n[%s] thread [%x,%x] created <dma[%d]> inode in cluster %x\n",
229__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]230#endif
[188]231        }
[23]232    }
233
[188]234    // create an IOB inode in cluster containing IOB chdev
235    chdev_xp = chdev_dir.iob;
236    if( chdev_xp != XPTR_NULL )
[23]237    {
[188]238        chdev_cxy = GET_CXY( chdev_xp );
[602]239        chdev_ptr = GET_PTR( chdev_xp );
[610]240
[188]241        if( chdev_cxy == local_cxy )
242        {
243            vfs_add_child_in_parent( local_cxy,
244                                     INODE_TYPE_DEV,
245                                     FS_TYPE_DEVFS,
246                                     devfs_external_inode_xp,
[407]247                                     chdev_ptr->name,
[602]248                                     &unused_xp,
[188]249                                     &inode_xp );
[602]250
251            // update child inode "extend" field
252            inode_cxy = GET_CXY( inode_xp );
253            inode_ptr = GET_PTR( inode_xp );
254            hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
255       
[568]256#if DEBUG_DEVFS_INIT
257cycle = (uint32_t)hal_get_cycles();
258if( DEBUG_DEVFS_INIT < cycle )
[598]259printk("\n[%s] thread[%x,%x] created <iob> inode in cluster %x\n",
260__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
[568]261#endif
[188]262        }
263    }
[23]264       
[188]265    // create a PIC inode in cluster containing PIC chdev
266    chdev_xp = chdev_dir.pic;
267    if( chdev_xp != XPTR_NULL )
268    {
269        chdev_cxy = GET_CXY( chdev_xp );
[602]270        chdev_ptr = GET_PTR( chdev_xp );
[610]271
[188]272        if( chdev_cxy == local_cxy )
[23]273        {
[188]274            vfs_add_child_in_parent( local_cxy,
275                                     INODE_TYPE_DEV,
276                                     FS_TYPE_DEVFS,
277                                     devfs_external_inode_xp,
[407]278                                     chdev_ptr->name,
[602]279                                     &unused_xp,
[188]280                                     &inode_xp );
[602]281
282            // update child inode "extend" field
283            inode_cxy = GET_CXY( inode_xp );
284            inode_ptr = GET_PTR( inode_xp );
285            hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
286       
[568]287#if DEBUG_DEVFS_INIT
288cycle = (uint32_t)hal_get_cycles();
289if( DEBUG_DEVFS_INIT < cycle )
[598]290printk("\n[%s] thread[%x,%x] created <pic> inode in cluster %x\n",
291__FUNCTION__, this->process->pid, this->trdid, local_cxy, cycle );
[568]292#endif
[23]293        }
[188]294    }
[23]295
[407]296    // create a TXT_RX inode in each cluster containing a TXT_RX chdev
[188]297    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
298    {
[407]299        chdev_xp = chdev_dir.txt_rx[channel];
[188]300        if( chdev_xp != XPTR_NULL )
[23]301        {
[188]302            chdev_cxy = GET_CXY( chdev_xp );
[602]303            chdev_ptr = GET_PTR( chdev_xp );
[610]304
[188]305            if( chdev_cxy == local_cxy )
306            {
307                vfs_add_child_in_parent( local_cxy,
308                                         INODE_TYPE_DEV,
309                                         FS_TYPE_DEVFS,
310                                         devfs_external_inode_xp,
[407]311                                         chdev_ptr->name,
[602]312                                         &unused_xp,
[188]313                                         &inode_xp );
[602]314
315                // update child inode "extend" field
316                inode_cxy = GET_CXY( inode_xp );
317                inode_ptr = GET_PTR( inode_xp );
318                hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
319       
[568]320#if DEBUG_DEVFS_INIT
321cycle = (uint32_t)hal_get_cycles();
322if( DEBUG_DEVFS_INIT < cycle )
[598]323printk("\n[%s] thread[%x,%x] created <txt_rx[%d]> inode in cluster %x\n",
324__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]325#endif
[188]326            }
[23]327        }
[188]328    }
[23]329
[407]330    // create a TXT_TX inode in each cluster containing a TXT_TX chdev
331    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
332    {
333        chdev_xp = chdev_dir.txt_tx[channel];
334        if( chdev_xp != XPTR_NULL )
335        {
336            chdev_cxy = GET_CXY( chdev_xp );
[602]337            chdev_ptr = GET_PTR( chdev_xp );
[610]338
[407]339            if( chdev_cxy == local_cxy )
340            {
341                vfs_add_child_in_parent( local_cxy,
342                                         INODE_TYPE_DEV,
343                                         FS_TYPE_DEVFS,
344                                         devfs_external_inode_xp,
345                                         chdev_ptr->name,
[602]346                                         &unused_xp,
[407]347                                         &inode_xp );
[602]348
349                // update child inode "extend" field
350                inode_cxy = GET_CXY( inode_xp );
351                inode_ptr = GET_PTR( inode_xp );
352                hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
353       
[568]354#if DEBUG_DEVFS_INIT
355cycle = (uint32_t)hal_get_cycles();
356if( DEBUG_DEVFS_INIT < cycle )
[598]357printk("\n[%s] thread[%x,%x] created <txt_tx[%d]> inode in cluster %x\n",
358__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]359#endif
[407]360            }
361        }
362    }
363
[188]364    // create an IOC inode in each cluster containing an IOC chdev
365    for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
366    {
367        chdev_xp = chdev_dir.ioc[channel];
368        if( chdev_xp != XPTR_NULL )
[23]369        {
[188]370            chdev_cxy = GET_CXY( chdev_xp );
[602]371            chdev_ptr = GET_PTR( chdev_xp );
[610]372
[188]373            if( chdev_cxy == local_cxy )
374            {
375                vfs_add_child_in_parent( local_cxy,
376                                         INODE_TYPE_DEV,
377                                         FS_TYPE_DEVFS,
378                                         devfs_external_inode_xp,
[407]379                                         chdev_ptr->name,
[602]380                                         &unused_xp,
[188]381                                         &inode_xp );
[602]382
383                // update child inode "extend" field
384                inode_cxy = GET_CXY( inode_xp );
385                inode_ptr = GET_PTR( inode_xp );
386                hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
387       
[568]388#if DEBUG_DEVFS_INIT
389cycle = (uint32_t)hal_get_cycles();
390if( DEBUG_DEVFS_INIT < cycle )
[598]391printk("\n[%s] thread[%x,%x] created <ioc[%d]> inode in cluster %x\n",
392__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]393#endif
[188]394            }
[23]395        }
[188]396    }
[23]397
[188]398    // create a FBF inode in each cluster containing a FBF chdev
[568]399    for( channel = 0 ; channel < CONFIG_MAX_FBF_CHANNELS ; channel++ )
[188]400    {
401        chdev_xp = chdev_dir.fbf[channel];
402        if( chdev_xp != XPTR_NULL )
[23]403        {
[188]404            chdev_cxy = GET_CXY( chdev_xp );
[602]405            chdev_ptr = GET_PTR( chdev_xp );
[610]406
[188]407            if( chdev_cxy == local_cxy )
408            {
409                vfs_add_child_in_parent( local_cxy,
410                                         INODE_TYPE_DEV,
411                                         FS_TYPE_DEVFS,
412                                         devfs_external_inode_xp,
[407]413                                         chdev_ptr->name,
[602]414                                         &unused_xp,
[188]415                                         &inode_xp );
[602]416
417                // update child inode "extend" field
418                inode_cxy = GET_CXY( inode_xp );
419                inode_ptr = GET_PTR( inode_xp );
420                hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
421       
[568]422#if DEBUG_DEVFS_INIT
423cycle = (uint32_t)hal_get_cycles();
424if( DEBUG_DEVFS_INIT < cycle )
[598]425printk("\n[%s] thread[%x,%x] created <fbf[%d]> inode in cluster %x\n",
426__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]427#endif
[188]428            }
[23]429        }
[188]430    }
[23]431
[188]432    // create a NIC_RX inode in each cluster containing a NIC_RX chdev
433    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
434    {
435        chdev_xp = chdev_dir.nic_rx[channel];
436        if( chdev_xp != XPTR_NULL )
[23]437        {
[188]438            chdev_cxy = GET_CXY( chdev_xp );
[610]439            chdev_ptr = GET_PTR( chdev_xp );
440
[188]441            if( chdev_cxy == local_cxy )
442            {
443                vfs_add_child_in_parent( local_cxy,
444                                         INODE_TYPE_DEV,
445                                         FS_TYPE_DEVFS,
446                                         devfs_external_inode_xp,
[407]447                                         chdev_ptr->name,
[602]448                                         &unused_xp,
[188]449                                         &inode_xp );
[568]450#if DEBUG_DEVFS_INIT
451cycle = (uint32_t)hal_get_cycles();
452if( DEBUG_DEVFS_INIT < cycle )
[598]453printk("\n[%s] thread[%x,%x] created <nic_rx[%d]> inode in cluster %x\n",
454__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[568]455#endif
[188]456            }
[23]457        }
458    }
459
[188]460    // create a NIC_TX inode in each cluster containing a NIC_TX chdev
461    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
[23]462    {
[188]463        chdev_xp = chdev_dir.nic_tx[channel];
464        if( chdev_xp != XPTR_NULL )
465        {
466            chdev_cxy = GET_CXY( chdev_xp );
[602]467            chdev_ptr = GET_PTR( chdev_xp );
[610]468
[188]469            if( chdev_cxy == local_cxy )
470            {
471                vfs_add_child_in_parent( local_cxy,
472                                         INODE_TYPE_DEV,
473                                         FS_TYPE_DEVFS,
474                                         devfs_external_inode_xp,
[407]475                                         chdev_ptr->name,
[602]476                                         &unused_xp,
[188]477                                         &inode_xp );
[602]478
479                // update child inode "extend" field
480                inode_cxy = GET_CXY( inode_xp );
481                inode_ptr = GET_PTR( inode_xp );
482                hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
483       
[438]484#if DEBUG_DEVFS_INIT
[433]485cycle = (uint32_t)hal_get_cycles();
[438]486if( DEBUG_DEVFS_INIT < cycle )
[598]487printk("\n[%s] thread[%x,%x] created <nic_tx[%d]> inode in cluster %x\n",
488__FUNCTION__, this->process->pid, this->trdid, channel, local_cxy, cycle );
[433]489#endif
[568]490            }
491        }
492    }
[188]493}  // end devfs_local_init()
[23]494
[407]495//////////////////////////////////////////
496int devfs_user_move( bool_t     to_buffer,
497                     xptr_t     file_xp,
[598]498                     char     * u_buf,
[407]499                     uint32_t   size )
500{
[598]501    xptr_t           chdev_xp;
502    cxy_t            chdev_cxy;
503    chdev_t        * chdev_ptr;                    // associated chdev type
504    uint32_t         func;                         // chdev functionnal type
505    uint32_t         channel;                      // chdev channel index
506    uint32_t         burst;                        // number of bytes in a burst
507    uint32_t         todo;                         // number of bytes not yet moved
508    error_t          error;
509    uint32_t         i;
[407]510
[598]511    char             k_buf[CONFIG_TXT_KBUF_SIZE];  // local kernel buffer
[407]512
[598]513assert( ( file_xp != XPTR_NULL ) , "file_xp == XPTR_NULL" );
[407]514
[438]515#if (DEBUG_SYS_READ & 1)
[435]516enter_devfs_read = hal_time_stamp();
517#endif
518
[438]519#if (DEBUG_SYS_WRITE & 1)
[435]520enter_devfs_write = hal_time_stamp();
521#endif
522
[438]523#if DEBUG_DEVFS_MOVE
[598]524uint32_t   cycle = (uint32_t)hal_get_cycles();
525thread_t * this  = CURRENT_THREAD;
[438]526if( DEBUG_DEVFS_MOVE < cycle )
[598]527printk("\n[%s] thread[%x,%x] enter / to_mem %d / cycle %d\n",
528__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
[433]529#endif
[407]530
[430]531    // get extended pointer on chdev_xp
532    chdev_xp = chdev_from_file( file_xp );
[407]533
[430]534    // get cluster and local pointer on chdev
535    chdev_cxy  = GET_CXY( chdev_xp );
536    chdev_ptr  = (chdev_t *)GET_PTR( chdev_xp );
[407]537
538    // get chdev functionnal type and channel
[568]539    func    = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->func ) );
540    channel = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->channel ) );
[407]541
[602]542// Only TXT devices are associated to a pseudo-file
[598]543assert( ( func == DEV_FUNC_TXT ) , __FUNCTION__, "illegal device func_type");
544
545    // initialise number of bytes to move
546    todo = size;
547
548    /////////////// TXT read
549    if( to_buffer )
550    { 
551        while( todo )
552        {
553            // set burst size
554            if( todo > CONFIG_TXT_KBUF_SIZE ) burst = CONFIG_TXT_KBUF_SIZE;
555            else                              burst = todo;
556
557            // read burst bytes from TXT device to kernel buffer
558            for( i = 0 ; i < burst ; i++ )
[407]559            {
560                error = dev_txt_read( channel , &k_buf[i] );
561
[598]562                if( error )  return -1;
563            }
[407]564
[598]565            // move burst bytes from k_buf to u_buf                   
566            hal_strcpy_to_uspace( u_buf , k_buf , burst );
567
568            // update loop variables
569            todo  -= burst;
570            u_buf += burst;
571        }
572
[438]573#if DEBUG_DEVFS_MOVE
[433]574cycle = (uint32_t)hal_get_cycles();
[438]575if( DEBUG_DEVFS_MOVE < cycle )
[598]576printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
577__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
[433]578#endif
579
[438]580#if (DEBUG_SYS_READ & 1)
[435]581exit_devfs_read = hal_time_stamp();
[407]582#endif
583            return size;
[598]584    } 
585    ///////////// TXT write 
586    else               
587    {
588        while( todo )
[407]589        {
[598]590            // set burst size
591            if( todo > CONFIG_TXT_KBUF_SIZE ) burst = CONFIG_TXT_KBUF_SIZE;
592            else                              burst = todo;
[407]593
[598]594            // move burst bytes from u_buf to k_buf
595            hal_strcpy_from_uspace( k_buf , u_buf , burst );
[407]596
[598]597            // write burst bytes from kernel buffer to TXT device
598            error = dev_txt_write( channel , k_buf , burst );
599
600            if( error ) return -1;
601
602            // update loop variables
603            todo  -= burst;
604            u_buf += burst;
605        } 
606
[438]607#if DEBUG_DEVFS_MOVE
[433]608cycle = (uint32_t)hal_get_cycles();
[438]609if( DEBUG_DEVFS_MOVE < cycle )
[598]610printk("\n[%s] thread[%x,%x] exit / to_mem %d / cycle %d\n",
611__FUNCTION__, this->process->pid, this->trdid, to_buffer, cycle );
[433]612#endif
[407]613
[438]614#if (DEBUG_SYS_WRITE & 1)
[435]615exit_devfs_write = hal_time_stamp();
616#endif
[598]617            return size;
[407]618    }
619
620}  // end devfs_user_move()
621
622
Note: See TracBrowser for help on using the repository browser.