Ignore:
Timestamp:
Jul 12, 2017, 8:12:41 PM (7 years ago)
Author:
alain
Message:

Redefine the PIC device API.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/vfs/devfs.c

    r50 r188  
    2626#include <hal_special.h>
    2727#include <printk.h>
     28#include <chdev.h>
     29#include <cluster.h>
     30#include <vfs.h>
    2831#include <kmem.h>
    29 #include <string.h>
    30 #include <chdev.h>
    31 #include <core.h>
    32 #include <thread.h>
    33 #include <vfs.h>
    34 #include <errno.h>
    3532#include <devfs.h>
    36 #include <rpc.h>
    37 
    38 
    39 //////////////////////////////////////////////////////////////////////////////////////////
    40 //          Extern  variables         
    41 //////////////////////////////////////////////////////////////////////////////////////////
    42 
    43 extern vfs_ctx_t          fs_context[FS_TYPES_NR];   // allocated in vfs.c file
    44 
    45 extern remote_barrier_t   global_barrier;            // allocated in kernel_init.c
    46  
    47 extern chdev_directory_t  chdev_dir;                 // allocated in kernel_init.c
    48 
    49 ////////////////////////////////////////////////////////////////////////////////////////
    50 //                DEVFS private functions
    51 ////////////////////////////////////////////////////////////////////////////////////////
    52 
    53 ////////////////////////////////////////////////////////////////////////////////////////
    54 // This function creates in the local cluster the dentry and the associated inode,
    55 // for a DEVFS directory (level 0 or level 1 in DEVFS tree).
    56 ////////////////////////////////////////////////////////////////////////////////////////
    57 // @ name        : directory entry name.
    58 // @ parent_xp   : extended pointer on parent inode.
    59 // @ inode_xp    : [out] buffer for extended pointer on created inode.
    60 ////////////////////////////////////////////////////////////////////////////////////////
    61 static void devfs_create_directory( char        * name,
    62                                     xptr_t        parent_xp,
    63                                     xptr_t      * inode_xp )
    64 {
    65     error_t       error;
    66     xptr_t        new_dentry_xp;     // extended pointer on created dentry
    67     xptr_t        new_inode_xp;      // extended pointer on created inode
    68  
    69     // get parent inode cluster and local pointer
    70     cxy_t         parent_cxy = GET_CXY( parent_xp );
    71     vfs_inode_t * parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );
    72 
    73     // create vfs_dentry in cluster containing the parent inode
    74     if( parent_cxy == local_cxy )
    75     {
    76         error = vfs_dentry_create( FS_TYPE_DEVFS,
    77                                    name,
    78                                    parent_ptr,
    79                                    &new_dentry_xp );
    80     }
    81     else
    82     {
    83         rpc_vfs_dentry_create_client( parent_cxy,
    84                                       FS_TYPE_DEVFS,
    85                                       name,
    86                                       parent_ptr,
    87                                       &new_dentry_xp,
    88                                       &error );
    89     }
    90 
    91     if ( error )
    92     {
    93         printk("\n[PANIC] in %s : cannot create dentry for %s in cluster %x/n",
    94                __FUNCTION__ , name , local_cxy );
    95         hal_core_sleep();
    96     }
    97 
    98     // create vfs_inode in local cluster TODO define the 4 arguments below [AG]
    99     uint32_t  attr   = 0;
    100     uint32_t  rights = 0;
    101     uid_t     uid    = 0;
    102     gid_t     gid    = 0;
    103     error = vfs_inode_create( new_dentry_xp,
    104                               FS_TYPE_DEVFS,
    105                               INODE_TYPE_DIR,
    106                               attr,
    107                               rights,
    108                               uid,
    109                               gid,
    110                               &new_inode_xp );
    111     if( error )
    112     {
    113         printk("\n[PANIC] in %s : cannot create inode for %s in cluster %x/n",
    114                __FUNCTION__ , name , local_cxy );
    115         hal_core_sleep();
    116     }
    117 
    118     // return extended pointer on directory inode
    119     *inode_xp = new_inode_xp;
    120 
    121 }  // end devfs_create_directory()
    122                                    
    123 ////////////////////////////////////////////////////////////////////////////////////////
    124 // This function creates in the local cluster the dentry and the associated inode,
    125 // for a chdev (level 2 in DEVFS tree).
    126 ////////////////////////////////////////////////////////////////////////////////////////
    127 // @ chdev    : local pointer on local chdev.
    128 // @ name     : directory entry name.
    129 // @ parent   : local pointer on local parent inode.
    130 // @ inode_xp : [out] buffer for extended pointer on created inode.
    131 ////////////////////////////////////////////////////////////////////////////////////////
    132 static void devfs_register_chdev( chdev_t     * chdev,
    133                                   char        * name,
    134                                   vfs_inode_t * parent,
    135                                   xptr_t      * inode_xp )
     33
     34/////////////////////////////////////////////////////////////////////////////////////////
     35//     Extern variables
     36/////////////////////////////////////////////////////////////////////////////////////////
     37
     38extern vfs_ctx_t            fs_context[];   // allocated in kernel_init.c
     39extern chdev_directory_t    chdev_dir;      // allocated in kernel_init.c
     40
     41///////////////////////////////
     42devfs_ctx_t * devfs_ctx_alloc()
     43{
     44    kmem_req_t    req;
     45
     46        req.type    = KMEM_DEVFS_CTX;
     47        req.size    = sizeof(devfs_ctx_t);
     48    req.flags   = AF_KERNEL | AF_ZERO;
     49
     50        return (devfs_ctx_t *)kmem_alloc( &req );
     51}
     52
     53/////////////////////////////////////////////
     54void devfs_ctx_init( devfs_ctx_t * devfs_ctx,
     55                     xptr_t        devfs_root_inode_xp,
     56                     xptr_t        devfs_external_inode_xp )
     57{
     58    devfs_ctx->root_inode_xp     = devfs_root_inode_xp;
     59    devfs_ctx->external_inode_xp = devfs_external_inode_xp;
     60
     61    fs_context[FS_TYPE_DEVFS].extend = devfs_ctx;
     62}
     63
     64/////////////////////////////////////////////////
     65void devfs_ctx_destroy( devfs_ctx_t * devfs_ctx )
     66{
     67    kmem_req_t    req;
     68
     69    req.type = KMEM_DEVFS_CTX;
     70    req.ptr  = devfs_ctx;
     71    kmem_free( &req );
     72}
     73
     74///////////////////////////////////////////////////
     75void devfs_global_init( xptr_t   parent_inode_xp,
     76                        xptr_t * devfs_root_inode_xp,
     77                        xptr_t * devfs_external_inode_xp )
    13678{
    13779    error_t  error;
    138     xptr_t   new_dentry_xp;
    139     xptr_t   new_inode_xp;
    140 
    141     devfs_dmsg("\n[INFO] %s : create dentry for %s\n", __FUNCTION__ , name );
    142    
    143     // create vfs_dentry in local cluster
    144     error = vfs_dentry_create( FS_TYPE_DEVFS,
    145                                name,
    146                                parent,
    147                                &new_dentry_xp );
    148     if ( error )
    149     {
    150         printk("\n[PANIC] in %s : cannot create dentry for %s in cluster %x/n",
    151                __FUNCTION__ , name , local_cxy );
    152         hal_core_sleep();
    153     }
    154 
    155     devfs_dmsg("\n[INFO] %s : create inode for %s\n", __FUNCTION__ , name );
    156    
    157     // create vfs_inode in local cluster
    158     uint32_t  attr   = 0;
    159     uint32_t  rights = 0;
    160     uid_t     uid    = 0;
    161     gid_t     gid    = 0;
    162     error = vfs_inode_create( new_dentry_xp,
    163                               FS_TYPE_DEVFS,
    164                               INODE_TYPE_DEV,
    165                               attr,
    166                               rights,
    167                               uid,
    168                               gid,
    169                               &new_inode_xp );
    170     if( error )
    171     {
    172         printk("\n[PANIC] in %s : cannot create inode for %s in cluster %x/n",
    173                __FUNCTION__ , name , local_cxy );
    174         hal_core_sleep();
    175     }
    176 
    177     // return extended pointer on chdev inode
    178     *inode_xp = new_inode_xp;
    179    
    180 }  // end devfs_register_chdev()
    181 
    182 
    183 
    184 ///////////////////////////////////////////////////////////////////////////////////////
    185 // Generic API : the following functions are called by the VFS,
    186 //               and must be defined by all supported file systems.
    187 ///////////////////////////////////////////////////////////////////////////////////////
    188 
    189 ////////////////////////////////////////////
    190 
    191 ////////////////////////////////////////////
    192 error_t devfs_mount( xptr_t   parent_inode_xp,
    193                      char   * devfs_root_name )
    194 {
    195     assert( (CURRENT_CORE->lid == 0) , __FUNCTION__ , "only CP0 should do it" );
    196 
    197     vfs_inode_t * parent_inode_ptr;
    198     cxy_t         parent_inode_cxy;
    199     vfs_ctx_t   * vfs_ctx;
    200 
     80
     81    // creates DEVFS "dev" inode in cluster IO
     82    error = vfs_add_child_in_parent( LOCAL_CLUSTER->io_cxy,
     83                                     INODE_TYPE_DIR,
     84                                     FS_TYPE_DEVFS,
     85                                     parent_inode_xp,
     86                                     "dev",
     87                                     NULL,
     88                                     devfs_root_inode_xp );
     89
     90    nolock_assert( (error == 0) , __FUNCTION__ , "cannot create <dev>\n" );
     91
     92    // create DEVFS "external" inode in cluster IO
     93    error = vfs_add_child_in_parent( LOCAL_CLUSTER->io_cxy,
     94                                     INODE_TYPE_DIR,
     95                                     FS_TYPE_DEVFS,
     96                                     *devfs_root_inode_xp,
     97                                     "dev",
     98                                     NULL,
     99                                     devfs_external_inode_xp );
     100
     101    nolock_assert( (error == 0) , __FUNCTION__ , "cannot create <external>\n" );
     102}
     103
     104//////////////////////////////////////////////////
     105void devfs_local_init( xptr_t devfs_root_inode_xp,
     106                       xptr_t devfs_external_inode_xp )
     107{
    201108    char          node_name[16];
     109    xptr_t        chdev_xp;
     110    cxy_t         chdev_cxy;
     111    xptr_t        inode_xp;
     112    xptr_t        internal_inode_xp;
    202113    uint32_t      channel;
    203114
    204     xptr_t        root_inode_xp;
    205     xptr_t        external_inode_xp;
    206     xptr_t        internal_inode_xp;
    207     xptr_t        chdev_inode_xp;
    208 
    209     chdev_t     * chdev_ptr;
    210 
    211     // get number of kernel instances and extended pointer on global barrier
    212     cluster_t * cluster     = LOCAL_CLUSTER;
    213     uint32_t    nb_clusters = cluster->x_size * cluster->y_size;
    214     xptr_t      barrier_xp  = XPTR( cluster->io_cxy , &global_barrier );
    215 
    216     // get VFS root inode cluster and local pointer
    217     parent_inode_cxy = GET_CXY( parent_inode_xp );
    218     parent_inode_ptr = (vfs_inode_t *)GET_PTR( parent_inode_xp );
    219 
    220     // get local pointer on VFS context for DEVFS
    221     vfs_ctx = &fs_context[FS_TYPE_DEVFS];
    222 
    223     ///// step 1 : all clusters initialize local DEVFS context  /////
    224 
    225     devfs_ctx_init( vfs_ctx , parent_inode_xp );
    226 
    227     ///// step 2 : cluster_0 creates DEVFS root    /////
    228 
    229     if( local_cxy == 0 )
    230     {
    231         devfs_create_directory( devfs_root_name,
    232                                 parent_inode_xp,
    233                                 &root_inode_xp );
    234     }
    235 
    236     // synchronize all clusters
    237     remote_barrier( barrier_xp , nb_clusters );
    238 
    239     ///// step 3 : all clusters create "internal" directory and chdevs  /////
    240 
    241     // TODO check device existence : (chdev_xp != XPTR_NULL) in chdev_dir
    242 
     115    // create "internal" directory linked to "dev"
    243116    snprintf( node_name , 16 , "internal_%x" , local_cxy );
    244 
    245     devfs_create_directory( node_name,
    246                             root_inode_xp,
    247                             &internal_inode_xp );
     117    vfs_add_child_in_parent( local_cxy,
     118                             INODE_TYPE_DIR,
     119                             FS_TYPE_DEVFS,
     120                             devfs_root_inode_xp,
     121                             node_name,
     122                             NULL,
     123                             &internal_inode_xp );
    248124
    249125    // create ICU chdev inode
    250     chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.icu[local_cxy] );
    251     devfs_register_chdev( chdev_ptr,
    252                           "icu",
    253                           (vfs_inode_t *)GET_PTR( internal_inode_xp ),
    254                           &chdev_inode_xp );
     126    chdev_xp = chdev_dir.icu[local_cxy];
     127    if( chdev_xp != XPTR_NULL)
     128    {
     129        vfs_add_child_in_parent( local_cxy,
     130                                 INODE_TYPE_DEV,
     131                                 FS_TYPE_DEVFS,
     132                                 internal_inode_xp,
     133                                 "icu",
     134                                 GET_PTR( chdev_xp ),
     135                                 &inode_xp );
     136    }
    255137
    256138    // create MMC chdev inode
    257     chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.mmc[local_cxy] );
    258     devfs_register_chdev( chdev_ptr,
    259                           "mmc",
    260                           (vfs_inode_t *)GET_PTR( internal_inode_xp ),
    261                           &chdev_inode_xp );
     139    chdev_xp = chdev_dir.mmc[local_cxy];
     140    if( chdev_xp != XPTR_NULL)
     141    {
     142        vfs_add_child_in_parent( local_cxy,
     143                                 INODE_TYPE_DEV,
     144                                 FS_TYPE_DEVFS,
     145                                 internal_inode_xp,
     146                                 "mmc",
     147                                 GET_PTR( chdev_xp ),
     148                                 &inode_xp );
     149    }
    262150
    263151    // create DMA chdev inodes (one DMA channel per core)
    264     for( channel = 0 ; channel < cluster->cores_nr ; channel++ )
    265     {
    266         chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.dma[channel] );
    267         snprintf( node_name , 16 , "dma_%d" , channel );
    268         devfs_register_chdev( chdev_ptr,
    269                               node_name,
    270                               (vfs_inode_t *)GET_PTR( internal_inode_xp ),
    271                               &chdev_inode_xp );
    272     }
    273 
    274     ///// step 4 : cluster_io creates "external" directory and chdevs /////
    275 
    276     // TODO check device existence : (chdev_xp != XPTR_NULL) in chdev_dir
    277 
    278     if( local_cxy == cluster->io_cxy )
    279     {
    280         devfs_create_directory( "external",
    281                                 root_inode_xp,
    282                                 &external_inode_xp );
    283 
    284         // create IOB chdev inode
    285         chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.iob );
    286         devfs_register_chdev( chdev_ptr,
    287                               "iob",
    288                               (vfs_inode_t *)GET_PTR( external_inode_xp ),
    289                               &chdev_inode_xp );
     152    for( channel = 0 ; channel < LOCAL_CLUSTER->cores_nr ; channel++ )
     153    {
     154        chdev_xp = chdev_dir.dma[channel];
     155        if( chdev_xp != XPTR_NULL)
     156        {
     157            snprintf( node_name , 16 , "dma_%d" , channel );
     158            vfs_add_child_in_parent( local_cxy,
     159                                     INODE_TYPE_DEV,
     160                                     FS_TYPE_DEVFS,
     161                                     internal_inode_xp,
     162                                     node_name,
     163                                     GET_PTR( chdev_xp ),
     164                                     &inode_xp );
     165        }
     166    }
     167
     168    // create an IOB inode in cluster containing IOB chdev
     169    chdev_xp = chdev_dir.iob;
     170    if( chdev_xp != XPTR_NULL )
     171    {
     172        chdev_cxy = GET_CXY( chdev_xp );
     173        if( chdev_cxy == local_cxy )
     174        {
     175            vfs_add_child_in_parent( local_cxy,
     176                                     INODE_TYPE_DEV,
     177                                     FS_TYPE_DEVFS,
     178                                     devfs_external_inode_xp,
     179                                     "iob",
     180                                     GET_PTR( chdev_xp ),
     181                                     &inode_xp );
     182        }
     183    }
    290184       
    291         // create PIC chdev inode
    292         chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.pic );
    293         devfs_register_chdev( chdev_ptr,
    294                               "pic",
    295                               (vfs_inode_t *)GET_PTR( external_inode_xp ),
    296                               &chdev_inode_xp );
    297 
    298         // create TXT chdev inodes
    299         for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
    300         {
    301             chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.txt[channel] );
    302             snprintf( node_name , 16 , "txt_%d" , channel );
    303             devfs_register_chdev( chdev_ptr,
    304                                   node_name,
    305                                   (vfs_inode_t *)GET_PTR( external_inode_xp ),
    306                                   &chdev_inode_xp );
    307         }
    308 
    309         // create IOC chdev inodes
    310         for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
    311         {
    312             chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.ioc[channel] );
    313             snprintf( node_name , 16 , "ioc_%d" , channel );
    314             devfs_register_chdev( chdev_ptr,
    315                                   node_name,
    316                                   (vfs_inode_t *)GET_PTR( external_inode_xp ),
    317                                   &chdev_inode_xp );
    318         }
    319 
    320         // create FBF chdev inodes
    321         for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
    322         {
    323             chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.ioc[channel] );
    324             snprintf( node_name , 16 , "fbf_%d" , channel );
    325             devfs_register_chdev( chdev_ptr,
    326                                   node_name,
    327                                   (vfs_inode_t *)GET_PTR( external_inode_xp ),
    328                                   &chdev_inode_xp );
    329         }
    330 
    331         // create NIC_RX chdevs
    332         for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
    333         {
    334             chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_rx[channel] );
    335             snprintf( node_name , 16 , "nic_rx_%d" , channel );
    336             devfs_register_chdev( chdev_ptr,
    337                                   node_name,
    338                                   (vfs_inode_t *)GET_PTR( external_inode_xp ),
    339                                   &chdev_inode_xp );
    340         }
    341 
    342         // create NIC_TX chdev inodes
    343         for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
    344         {
    345             chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_tx[channel] );
    346             snprintf( node_name , 16 , "nic_tx_%d" , channel );
    347             devfs_register_chdev( chdev_ptr,
    348                                   node_name,
    349                                   (vfs_inode_t *)GET_PTR( external_inode_xp ),
    350                                   &chdev_inode_xp );
    351         }
    352     }
    353 
    354     // synchronize all clusters
    355     remote_barrier( barrier_xp , nb_clusters );
    356 
    357     return 0;
    358 
    359 }  // end devfs_init()
    360 
    361 
    362 ////////////////////////////////////////////
    363 error_t devfs_ctx_init( vfs_ctx_t * vfs_ctx,
    364                         xptr_t      root_inode_xp )
    365 {
    366     vfs_ctx->type    = FS_TYPE_DEVFS;
    367     vfs_ctx->attr    = 0;                // not READ_ONLY / not SYNC
    368     vfs_ctx->count   = 0;                // unused for DEVFS
    369     vfs_ctx->blksize = 0;                // unused for DEVFS
    370     vfs_ctx->root_xp = root_inode_xp;
    371     vfs_ctx->extend  = NULL;             // unused for DEVFS
    372 
    373     spinlock_init( &vfs_ctx->lock );
    374 
    375     bitmap_init( vfs_ctx->bitmap , CONFIG_VFS_MAX_INODES );
    376 
    377     return 0;
    378 }
    379 
    380 
    381 ////////////////////////////////////////////////////
    382 error_t devfs_inode_create( vfs_inode_t * vfs_inode,
    383                             chdev_t     * chdev )
    384 {
    385     kmem_req_t      req;
    386     devfs_inode_t * devfs_inode;
    387 
    388     // allocate memory for FATFS inode extension
    389         req.type    = KMEM_DEVFS_INODE;
    390         req.size    = sizeof(devfs_inode_t);
    391     req.flags   = AF_KERNEL | AF_ZERO;
    392         devfs_inode = (devfs_inode_t *)kmem_alloc( &req );
    393 
    394     if( devfs_inode == NULL ) return ENOMEM;
    395 
    396     // link DEVFS inode to VFS inode
    397     vfs_inode->extend = devfs_inode;
    398 
    399     // initialise DEVFS inode 
    400     devfs_inode->chdev = chdev;
    401  
    402     return 0;
    403 }
    404 
    405 ///////////////////////////////////////////////////
    406 void devfs_inode_destroy( vfs_inode_t * vfs_inode )
    407 {
    408     kmem_req_t      req;
    409     devfs_inode_t * devfs_inode;
    410 
    411     // get pointer on DEVFS inode
    412     devfs_inode = (devfs_inode_t *)vfs_inode->extend;
    413 
    414     req.type = KMEM_DEVFS_INODE;
    415     req.ptr  = devfs_inode;
    416     kmem_free( &req );
    417 
    418         vfs_inode->extend = NULL;
    419 }
    420 
    421 
    422 /* deprecated [AG]
    423 
    424 error_t devfs_open_file( vfs_file_t * file,
    425                          void       * extend );
    426 {
    427         error_t err;
    428         register struct devfs_context_s *ctx;
    429         register struct devfs_file_s *info;
    430         chdev_t       * chdev;
    431         vfs_inode_t   * inode;
    432         dev_request_t   rq;
    433         kmem_req_t      req;
    434 
    435         inode = file->inode;
    436 
    437         info = file->fr_pv;
    438         ctx  = (struct devfs_context_s *)&inode->i_ctx->ctx_devfs;
    439 
    440         if(!(inode->i_attr & VFS_DIR))
    441         {
    442                 dev = (struct device_s*)inode->i_pv;
    443    
    444                 if(dev->type == DEV_INTERNAL)
    445                         return EPERM;
    446 
    447                 if(dev->type == DEV_BLK)
    448                         VFS_SET(inode->i_attr,VFS_DEV_BLK);
    449                 else
    450                         VFS_SET(inode->i_attr,VFS_DEV_CHR);
    451  
    452                 if(dev->op.dev.open != NULL)
    453                 {
    454                         rq.fremote = file;
    455                         if((err=dev->op.dev.open(dev, &rq)))
    456                                 return err;
    457                 }
    458 
    459                 priv->dev = (void*)dev;
    460 
    461                 return 0;
    462         }
    463 
    464         if(info == NULL)
    465         {
    466                 req.type  = KMEM_DEVFS_FILE;
    467                 req.size  = sizeof(*info);
    468                 req.flags = AF_KERNEL;
    469                 info      = kmem_alloc(&req);
    470         }
    471 
    472         if(info == NULL) return ENOMEM;
    473 
    474         metafs_iter_init(&devfs_db.root, &info->iter);
    475         info->ctx  = ctx;
    476         file->fr_pv = info;
    477  
    478         metafs_print(&devfs_db.root);
    479         return 0;
    480 }
    481 
    482 #define TMP_BUFF_SZ 512
    483 
    484 //FIXME:
    485 //add a "while" loop for the case where the
    486 //buffer TMP_BUFF_SZ is smaller than
    487 //buffer->size
    488 //////////////////////////////
    489 devfs_read( vfs_file_t * file,
    490             char       * buffer )
    491 {
    492         chdev_t       * chdev;
    493         dev_request_t   rq;
    494         uint32_t        count;
    495     uint8_t         buff[TMP_BUFF_SZ];
    496 
    497     // get pointer on chdev
    498         chdev = (chdev_t *)file->extend;
    499 
    500     if( chdev->func == DEV_FUNC_TXT )
    501     {
    502     }
    503     if( chdev->func == DEV_FUNC_IOC )
    504     {
    505     }
    506     else
    507     {
    508         printk("\n[PANIC] in %s : illegal device functionnal type
    509 
    510         rq.dst   = &buff[0];
    511         rq.count = TMP_BUFF_SZ;
    512         rq.flags = 0;
    513         rq.file  = file;
    514 
    515         if((count = dev->op.dev.read(dev, &rq)) < 0)
    516                 return count;
    517 
    518         buffer->scpy_to_buff(buffer, &buff[0], count);
    519         return count;
    520 }
    521 
    522 //FIXME: To improve this an avoid the extra copy,
    523 //we could set along with the buffer(src and dest)
    524 //the functions to manipulate them, such as in
    525 //do_exec.c
    526 ///////////////////////////////
    527 devfs_write( vfs_file_t * file,
    528              char       * buffer )
    529 {
    530         register struct device_s *dev;
    531         uint8_t buff[TMP_BUFF_SZ];
    532         dev_request_t rq;
    533        
    534         dev = (struct device_s*)file->f_private.dev;
    535        
    536         //FIXME avoid the extra copy ?
    537         buffer->scpy_from_buff(buffer, (void*)&buff[0], TMP_BUFF_SZ);
    538         rq.src   = (void*)&buff[0];
    539         rq.count = buffer->size;
    540         rq.flags = 0;
    541         rq.file  = file;
    542  
    543         return dev->op.dev.write(dev, &rq);
    544 }
    545 
    546 VFS_LSEEK_FILE(devfs_lseek)
    547 {
    548         register struct device_s *dev;
    549         dev_request_t rq;
    550 
    551         dev = (struct device_s*)file->fr_inode->i_pv;
    552 
    553         if(dev->op.dev.lseek == NULL)
    554                 return VFS_ENOTUSED;
    555  
    556         rq.fremote = file;
    557         return dev->op.dev.lseek(dev, &rq);
    558 }
    559 
    560 VFS_CLOSE_FILE(devfs_close)
    561 {
    562         register struct device_s *dev;
    563         dev_request_t rq;
    564 
    565         if(file->fr_inode->i_attr & VFS_DIR)
    566                 return 0;
    567 
    568         dev = (struct device_s*)file->fr_inode->i_pv;
    569 
    570         if(dev->op.dev.close == NULL)
    571                 return 0;
    572  
    573         rq.fremote = file;
    574         return dev->op.dev.close(dev, &rq);
    575 }
    576 
    577 VFS_RELEASE_FILE(devfs_release)
    578 
    579         kmem_req_t req;
    580 
    581         if(file->fr_pv == NULL)
    582                 return 0;
    583  
    584         req.type = KMEM_DEVFS_FILE;
    585         req.ptr  = file->fr_pv;
    586         kmem_free(&req);
    587 
    588         file->fr_pv = NULL;
    589         return 0;
    590 }
    591 
    592 VFS_READ_DIR(devfs_readdir)
    593 {
    594         register struct devfs_file_s *info;
    595         register struct metafs_s *current;
    596         register struct device_s *current_dev;
    597  
    598         info = file->fr_pv;
    599  
    600         if(file->fr_pv == NULL)
    601                 return ENOTDIR;
    602 
    603         if((current = metafs_lookup_next(&devfs_db.root, &info->iter)) == NULL)
    604                 return EEODIR;
    605 
    606         current_dev    = metafs_container(current, struct device_s, node);
    607         dirent->u_attr = (current_dev->type == DEV_BLK) ? VFS_DEV_BLK : VFS_DEV_CHR;
    608 
    609         strcpy((char*)dirent->u_name, metafs_get_name(current));
    610 
    611         dirent->u_ino = (uint_t) current_dev->base_paddr;
    612 
    613         return 0;
    614 }
    615 
    616 VFS_MMAP_FILE(devfs_mmap)
    617 {
    618         register struct device_s *dev;
    619         dev_request_t rq;
    620  
    621         dev = (struct device_s*)file->f_private.dev;
    622 
    623         if(dev->op.dev.mmap == NULL)
    624                 return ENODEV;
    625 
    626         rq.flags  = 0;
    627         rq.file   = file;
    628         rq.region = region;
    629 
    630         return dev->op.dev.mmap(dev, &rq);
    631 }
    632 
    633 VFS_MMAP_FILE(devfs_munmap)
    634 {
    635         register struct device_s *dev;
    636         dev_request_t rq;
    637 
    638         dev = (struct device_s*)file->f_private.dev;
    639 
    640         if(dev->op.dev.munmap == NULL)
    641                 return ENODEV;
    642 
    643         rq.flags  = 0;
    644         rq.file   = file;
    645         rq.region = region;
    646 
    647         return dev->op.dev.munmap(dev, &rq);
    648 }
    649 
    650 
    651 */
    652 
    653 
     185    // create a PIC inode in cluster containing PIC chdev
     186    chdev_xp = chdev_dir.pic;
     187    if( chdev_xp != XPTR_NULL )
     188    {
     189        chdev_cxy = GET_CXY( chdev_xp );
     190        if( chdev_cxy == local_cxy )
     191        {
     192            vfs_add_child_in_parent( local_cxy,
     193                                     INODE_TYPE_DEV,
     194                                     FS_TYPE_DEVFS,
     195                                     devfs_external_inode_xp,
     196                                     "pic",
     197                                     GET_PTR( chdev_xp ),
     198                                     &inode_xp );
     199        }
     200    }
     201
     202    // create a TXT inode in each cluster containing a TXT chdev
     203    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
     204    {
     205        chdev_xp = chdev_dir.txt[channel];
     206        if( chdev_xp != XPTR_NULL )
     207        {
     208            chdev_cxy = GET_CXY( chdev_xp );
     209            if( chdev_cxy == local_cxy )
     210            {
     211                snprintf( node_name , 16 , "txt_%d" , channel );
     212                vfs_add_child_in_parent( local_cxy,
     213                                         INODE_TYPE_DEV,
     214                                         FS_TYPE_DEVFS,
     215                                         devfs_external_inode_xp,
     216                                         node_name,
     217                                         GET_PTR( chdev_xp ),
     218                                         &inode_xp );
     219            }
     220        }
     221    }
     222
     223    // create an IOC inode in each cluster containing an IOC chdev
     224    for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
     225    {
     226        chdev_xp = chdev_dir.ioc[channel];
     227        if( chdev_xp != XPTR_NULL )
     228        {
     229            chdev_cxy = GET_CXY( chdev_xp );
     230            if( chdev_cxy == local_cxy )
     231            {
     232                snprintf( node_name , 16 , "ioc_%d" , channel );
     233                vfs_add_child_in_parent( local_cxy,
     234                                         INODE_TYPE_DEV,
     235                                         FS_TYPE_DEVFS,
     236                                         devfs_external_inode_xp,
     237                                         node_name,
     238                                         GET_PTR( chdev_xp ),
     239                                         &inode_xp );
     240            }
     241        }
     242    }
     243
     244    // create a FBF inode in each cluster containing a FBF chdev
     245    for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
     246    {
     247        chdev_xp = chdev_dir.fbf[channel];
     248        if( chdev_xp != XPTR_NULL )
     249        {
     250            chdev_cxy = GET_CXY( chdev_xp );
     251            if( chdev_cxy == local_cxy )
     252            {
     253                snprintf( node_name , 16 , "fbf_%d" , channel );
     254                vfs_add_child_in_parent( local_cxy,
     255                                         INODE_TYPE_DEV,
     256                                         FS_TYPE_DEVFS,
     257                                         devfs_external_inode_xp,
     258                                         node_name,
     259                                         GET_PTR( chdev_xp ),
     260                                         &inode_xp );
     261            }
     262        }
     263    }
     264
     265    // create a NIC_RX inode in each cluster containing a NIC_RX chdev
     266    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
     267    {
     268        chdev_xp = chdev_dir.nic_rx[channel];
     269        if( chdev_xp != XPTR_NULL )
     270        {
     271            chdev_cxy = GET_CXY( chdev_xp );
     272            if( chdev_cxy == local_cxy )
     273            {
     274                snprintf( node_name , 16 , "nic_rx_%d" , channel );
     275                vfs_add_child_in_parent( local_cxy,
     276                                         INODE_TYPE_DEV,
     277                                         FS_TYPE_DEVFS,
     278                                         devfs_external_inode_xp,
     279                                         node_name,
     280                                         GET_PTR( chdev_xp ),
     281                                         &inode_xp );
     282            }
     283        }
     284    }
     285
     286    // create a NIC_TX inode in each cluster containing a NIC_TX chdev
     287    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
     288    {
     289        chdev_xp = chdev_dir.nic_tx[channel];
     290        if( chdev_xp != XPTR_NULL )
     291        {
     292            chdev_cxy = GET_CXY( chdev_xp );
     293            if( chdev_cxy == local_cxy )
     294            {
     295                snprintf( node_name , 16 , "nic_tx_%d" , channel );
     296                vfs_add_child_in_parent( local_cxy,
     297                                         INODE_TYPE_DEV,
     298                                         FS_TYPE_DEVFS,
     299                                         devfs_external_inode_xp,
     300                                         node_name,
     301                                         GET_PTR( chdev_xp ),
     302                                         &inode_xp );
     303            }
     304        }
     305    }
     306}  // end devfs_local_init()
     307
Note: See TracChangeset for help on using the changeset viewer.