Changeset 188 for trunk/kernel/vfs/devfs.c
- Timestamp:
- Jul 12, 2017, 8:12:41 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/vfs/devfs.c
r50 r188 26 26 #include <hal_special.h> 27 27 #include <printk.h> 28 #include <chdev.h> 29 #include <cluster.h> 30 #include <vfs.h> 28 31 #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>35 32 #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 38 extern vfs_ctx_t fs_context[]; // allocated in kernel_init.c 39 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 40 41 /////////////////////////////// 42 devfs_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 ///////////////////////////////////////////// 54 void 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 ///////////////////////////////////////////////// 65 void 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 /////////////////////////////////////////////////// 75 void devfs_global_init( xptr_t parent_inode_xp, 76 xptr_t * devfs_root_inode_xp, 77 xptr_t * devfs_external_inode_xp ) 136 78 { 137 79 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 ////////////////////////////////////////////////// 105 void devfs_local_init( xptr_t devfs_root_inode_xp, 106 xptr_t devfs_external_inode_xp ) 107 { 201 108 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; 202 113 uint32_t channel; 203 114 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" 243 116 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 ); 248 124 249 125 // 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 } 255 137 256 138 // 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 } 262 150 263 151 // 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 } 290 184 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.