Changeset 188 for trunk/kernel/vfs/fatfs.c
- Timestamp:
- Jul 12, 2017, 8:12:41 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/vfs/fatfs.c
r101 r188 46 46 47 47 ////////////////////////////////////////////////////////////////////////////////////////// 48 // FATFS specific functions : these functions cannot be called by the VFS 49 ////////////////////////////////////////////////////////////////////////////////////////// 50 51 ////////////////////////////////////////////////////////// 52 inline uint32_t fatfs_lba_from_cluster( fatfs_ctx_t * ctx, 53 uint32_t cluster ) 48 // FATFS private functions 49 ////////////////////////////////////////////////////////////////////////////////////////// 50 51 ////////////////////////////////////////////////////////////////////////////////////////// 52 // This function returns the LBA of the first sector of a FAT cluster. 53 // This function can be called by any thread running in any cluster. 54 ////////////////////////////////////////////////////////////////////////////////////////// 55 // @ ctx : pointer on FATFS context. 56 // @ cluster : cluster index in FATFS. 57 // @ return the lba value. 58 ////////////////////////////////////////////////////////////////////////////////////////// 59 static inline uint32_t fatfs_lba_from_cluster( fatfs_ctx_t * ctx, 60 uint32_t cluster ) 54 61 { 55 62 return (ctx->cluster_begin_lba + ((cluster - 2) << 3)); … … 200 207 201 208 /////////////////////////////////////////////////////////////////////////////////////// 202 // The following functions are called by the VFS. 209 // Generic API : the following functions are called by the kernel 210 // and must be defined by all supported file systems. 203 211 /////////////////////////////////////////////////////////////////////////////////////// 204 212 205 206 /////////////////// 207 xptr_t fatfs_init() 213 /////////////////////////////// 214 fatfs_ctx_t * fatfs_ctx_alloc() 208 215 { 209 216 kmem_req_t req; 210 fatfs_ctx_t * fatfs_ctx; // local pointer on FATFS context211 vfs_ctx_t * vfs_ctx; // local pointer on VFS context212 xptr_t root_inode_xp; // extended pointer on root inode213 error_t error;214 215 // get local pointer on VFS context for FATFS216 vfs_ctx = &fs_context[FS_TYPE_FATFS];217 218 // get number of kernel instances and extended pointer on global barrier219 cluster_t * cluster = LOCAL_CLUSTER;220 uint32_t nb_clusters = cluster->x_size * cluster->y_size;221 xptr_t barrier_xp = XPTR( cluster->io_cxy , &global_barrier );222 223 ///// step 1 : all clusters allocate memory for FATFS context224 225 // allocate memory for FATFS context extension226 217 req.type = KMEM_FATFS_CTX; 227 218 req.size = sizeof(fatfs_ctx_t); 228 219 req.flags = AF_KERNEL | AF_ZERO; 229 fatfs_ctx = (fatfs_ctx_t *)kmem_alloc( &req ); 230 231 if( fatfs_ctx == NULL ) 232 { 233 printk("\n[PANIC] in %s : no memory for FATFS context\n", __FUNCTION__ ); 234 hal_core_sleep(); 235 } 236 237 ///// step 2 : only cluster_0 access device and creates root inode 238 239 if( local_cxy == 0 ) 240 { 241 // create VFS root inode 242 error = vfs_inode_create( XPTR_NULL, // no parent dentry 243 FS_TYPE_FATFS, 244 INODE_TYPE_DIR, 245 0, // attr 246 0, // rights 247 0, // uid 248 0, // gid 249 &root_inode_xp ); 250 251 assert( (error == 0 ) , __FUNCTION__ , "cannot create VFS root inode" ); 252 253 // initialize VFS context / access device to initialize FATFS context 254 error = fatfs_ctx_init( vfs_ctx, 255 fatfs_ctx, 256 root_inode_xp ); 257 258 // create FATFS root inode 259 error = fatfs_inode_create( GET_PTR( root_inode_xp ) , 260 fatfs_ctx->root_dir_cluster ); 261 262 if( error ) 263 { 264 printk("\n[PANIC] in %s : cannot create FATFS root inode\n", __FUNCTION__ ); 265 hal_core_sleep(); 266 } 267 268 } 269 270 //////////////// synchronize all clusters 271 remote_barrier( barrier_xp , nb_clusters ); 272 273 ///// step 3 : all others clusters initialize both context and extension 274 275 if( local_cxy != 0 ) 276 { 277 // copy VFS context from remote cluster_0 to local cluster 278 hal_remote_memcpy( XPTR( local_cxy , vfs_ctx ), 279 XPTR( 0 , vfs_ctx ), 280 sizeof(vfs_ctx_t) ); 281 282 // copy FATFS context from remote cluster_0 to local cluster 283 hal_remote_memcpy( XPTR( local_cxy , fatfs_ctx ), 284 XPTR( 0 , vfs_ctx->extend ) , 285 sizeof(fatfs_ctx_t) ); 286 287 // update extend field in local copy of VFS context 288 vfs_ctx->extend = fatfs_ctx; 289 } 290 291 return root_inode_xp; 292 293 } // end fatfs_init() 220 221 return (fatfs_ctx_t *)kmem_alloc( &req ); 222 } 294 223 295 224 ////////////////////////////////////////////// 296 error_t fatfs_ctx_init( vfs_ctx_t * vfs_ctx, 297 fatfs_ctx_t * fatfs_ctx, 298 xptr_t root_inode_xp ) 299 { 300 error_t error; 301 uint8_t * buffer; 302 kmem_req_t req; 225 void fatfs_ctx_init( fatfs_ctx_t * fatfs_ctx ) 226 { 227 error_t error; 228 kmem_req_t req; 229 uint8_t * buffer; 230 231 fatfs_dmsg("\n[INFO] %s : enters at cycle %d\n", 232 __FUNCTION__ , hal_get_cycles() ); 233 234 // allocate memory for FATFS context 235 req.type = KMEM_FATFS_CTX; 236 req.size = sizeof(fatfs_ctx_t); 237 req.flags = AF_KERNEL | AF_ZERO; 238 239 fatfs_ctx = (fatfs_ctx_t *)kmem_alloc( &req ); 240 241 nolock_assert( (fatfs_ctx != NULL) , __FUNCTION__ , 242 "cannot allocate memory for FATFS context\n" ); 303 243 304 244 // allocate a 512 bytes buffer to store the boot record … … 306 246 req.flags = AF_KERNEL | AF_ZERO; 307 247 buffer = (uint8_t *)kmem_alloc( &req ); 248 249 nolock_assert( (buffer != NULL) , __FUNCTION__ , 250 "cannot allocate memory for 512 bytes buffer\n" ); 308 251 309 fatfs_dmsg("\n[INFO] %s : enters with buffer = %x\n",310 __FUNCTION__ , (intptr_t)buffer );311 312 252 // load the boot record from device 313 253 // using a synchronous access to IOC device 314 254 error = dev_ioc_sync_read( buffer , 0 , 1 ); 315 255 316 assert( (error == 0) , __FUNCTION__ , "cannot access boot record" ); 256 nolock_assert( (error == 0) , __FUNCTION__ , 257 "cannot access boot record\n" ); 317 258 318 259 #if CONFIG_FATFS_DEBUG … … 336 277 uint32_t sector_size = get_record_from_buffer( BPB_BYTSPERSEC , buffer , 1 ); 337 278 338 assert( (sector_size == 512) , __FUNCTION__ , "sector size must be 512 bytes" ); 279 nolock_assert( (sector_size == 512) , __FUNCTION__ , 280 "sector size must be 512 bytes\n" ); 339 281 340 282 // check cluster size from boot record 341 283 uint32_t nb_sectors = get_record_from_buffer( BPB_SECPERCLUS , buffer , 1 ); 342 284 343 assert( (nb_sectors == 8) , __FUNCTION__ , "cluster size must be 8 sectors" ); 285 nolock_assert( (nb_sectors == 8) , __FUNCTION__ , 286 "cluster size must be 8 sectors\n" ); 344 287 345 288 // check number of FAT copies from boot record 346 289 uint32_t nb_fats = get_record_from_buffer( BPB_NUMFATS , buffer , 1 ); 347 290 348 assert( (nb_fats == 1) , __FUNCTION__ , "number of FAT copies must be 1" ); 291 nolock_assert( (nb_fats == 1) , __FUNCTION__ , 292 "number of FAT copies must be 1\n" ); 349 293 350 294 // get & check number of sectors in FAT from boot record 351 295 uint32_t fat_sectors = get_record_from_buffer( BPB_FAT32_FATSZ32 , buffer , 1 ); 352 296 353 assert( ((fat_sectors & 0xF) == 0) , __FUNCTION__ , "FAT not multiple of 16 sectors"); 297 nolock_assert( ((fat_sectors & 0xF) == 0) , __FUNCTION__ , 298 "FAT not multiple of 16 sectors\n"); 354 299 355 300 // get and check root cluster from boot record 356 301 uint32_t root_cluster = get_record_from_buffer( BPB_FAT32_ROOTCLUS , buffer , 1 ); 357 302 358 assert( (root_cluster == 2) , __FUNCTION__ , "Root cluster index must be 2"); 303 nolock_assert( (root_cluster == 2) , __FUNCTION__ , 304 "root cluster index must be 2\n"); 359 305 360 306 // get FAT lba from boot record … … 375 321 fatfs_ctx->fat_sectors_count = fat_sectors; 376 322 fatfs_ctx->bytes_per_sector = sector_size; 377 fatfs_ctx-> bytes_per_cluster = sector_size *nb_sectors;323 fatfs_ctx->sectors_per_cluster = nb_sectors; 378 324 fatfs_ctx->cluster_begin_lba = fat_lba + fat_sectors; 379 325 fatfs_ctx->root_dir_cluster = 2; … … 396 342 fatfs_ctx->fat_mapper_xp ); 397 343 398 // initialize the VFS context399 vfs_ctx->type = FS_TYPE_FATFS;400 vfs_ctx->attr = 0; // not READ_ONLY / not SYNC401 vfs_ctx->count = fat_sectors << 10; // total number of sectors in data region402 vfs_ctx->blksize = 512; // number of bytes per sector403 vfs_ctx->root_xp = root_inode_xp;404 vfs_ctx->extend = fatfs_ctx;405 406 spinlock_init( &vfs_ctx->lock );407 408 bitmap_init( vfs_ctx->bitmap , CONFIG_VFS_MAX_INODES );409 410 return 0;411 412 344 } // end fatfs_ctx_init() 413 414 415 416 //////////////////////////////////////////////////// 417 void fatfs_ctx_destroy( struct vfs_ctx_s * vfs_ctx ) 345 346 ///////////////////////////////////////////////// 347 void fatfs_ctx_destroy( fatfs_ctx_t * fatfs_ctx ) 418 348 { 419 349 kmem_req_t req; 420 fatfs_ctx_t * fatfs_ctx; 421 422 // get pointer on FATFS context extension 423 fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend; 424 425 req.type = KMEM_FATFS_INODE; 350 req.type = KMEM_FATFS_CTX; 426 351 req.ptr = fatfs_ctx; 427 352 kmem_free( &req ); 428 353 } 429 430 431 ////////////////////////////////////////////////////432 error_t fatfs_inode_create( vfs_inode_t * vfs_inode,433 uint32_t first_cluster )434 {435 kmem_req_t req;436 fatfs_inode_t * fatfs_inode;437 438 // allocate memory for FATFS inode extension439 req.type = KMEM_FATFS_INODE;440 req.size = sizeof(fatfs_inode_t);441 req.flags = AF_KERNEL | AF_ZERO;442 fatfs_inode = (fatfs_inode_t *)kmem_alloc( &req );443 444 if( fatfs_inode == NULL ) return ENOMEM;445 446 // link FATFS inode to VFS inode447 vfs_inode->extend = fatfs_inode;448 449 // initialise FATFS inode450 fatfs_inode->first_cluster = first_cluster;451 452 return 0;453 }454 455 ///////////////////////////////////////////////////456 void fatfs_inode_destroy( vfs_inode_t * vfs_inode )457 {458 kmem_req_t req;459 fatfs_inode_t * fatfs_inode;460 461 // get pointer on FATFS inode462 fatfs_inode = (fatfs_inode_t *)vfs_inode->extend;463 464 req.type = KMEM_FATFS_INODE;465 req.ptr = fatfs_inode;466 kmem_free( &req );467 468 vfs_inode->extend = NULL;469 }470 471 354 472 355 //////////////////////////////////////////////// … … 484 367 vfs_inode_t * vfs_inode = mapper->inode; 485 368 486 // get FATFS inode pointer for VFS inode 487 fatfs_inode_t * fatfs_inode = (fatfs_inode_t *)vfs_inode->extend; 488 489 // get first cluster index from FATFS inode 490 uint32_t first_cluster = fatfs_inode->first_cluster; 491 492 // get FATFS context pointer from FATFS inode 493 fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)vfs_inode->ctx->extend; 369 // get first cluster index from VFS inode 370 uint32_t first_cluster = (uint32_t)(intptr_t)vfs_inode->extend; 371 372 // get FATFS context pointer from VFS context 373 fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)fs_context[FS_TYPE_FATFS].extend; 494 374 495 375 // get number of sectors
Note: See TracChangeset
for help on using the changeset viewer.