📄 fsinit.c
字号:
return -1;
}
break;
}
/*-------------------------------------------------------------*/
/* Check header sector (last one) contains only signature. */
/*-------------------------------------------------------------*/
if (Flash->read_sector(Flash->tmp_sect, sect + i))
{
set_errno(EIO);
return -1;
}
/*-------------------------------------------------------------*/
/* Check that non-sinature bytes are all 0xFF. */
/*-------------------------------------------------------------*/
for (j = 0; j < Flash->sect_sz - RES_BYTES; ++j)
if (Flash->tmp_sect[j] != 0xFF)
{
if (Flash->erase_block_wrapper(addr))
{
set_errno(EIO);
return -1;
}
break;
}
if (j < Flash->sect_sz - RES_BYTES)
break;
/*-------------------------------------------------------------*/
/* Check the signature bytes. */
/*-------------------------------------------------------------*/
if (Flash->tmp_sect[j] != NOR_BYTE1 ||
Flash->tmp_sect[j + 1] != NOR_BYTE2 ||
Flash->tmp_sect[j + 2] != NOR_BYTE3 ||
Flash->tmp_sect[j + 3] != NOR_BYTE4)
{
if (Flash->erase_block_wrapper(addr))
{
set_errno(EIO);
return -1;
}
break;
}
}
}
}
return 0;
}
/***********************************************************************/
/* FfsModule: Flash file system interface to software object manager */
/* */
/* Input: req = module request code */
/* ... = additional parameters specific to request */
/* */
/***********************************************************************/
void *FfsModule(int req, ...)
{
void *r_value = NULL;
va_list ap;
char *path;
ui32 i, j;
FlashGlob *vol;
switch (req)
{
case kInitMod:
{
char sem_name[9];
/*---------------------------------------------------------------*/
/* Initialize the FAT semaphores. */
/*---------------------------------------------------------------*/
FlashSem = semCreate("FLASH_SEM", 1, OS_FIFO);
if (FlashSem == NULL)
return (void *)-1;
for (i = 0; i < NUM_FFS_VOLS; ++i)
{
sprintf(sem_name, "FFS_%04d", i);
FlashGlobals[i].sem = semCreate(sem_name, 1, OS_FIFO);
if (FlashGlobals[i].sem == NULL)
{
while (i--)
semDelete(&FlashGlobals[i].sem);
semDelete(&FlashSem);
return (void *)-1;
}
}
return r_value;
}
/*-----------------------------------------------------------------*/
/* Handle the unformat function call. */
/*-----------------------------------------------------------------*/
case kUnformat:
{
int do_unmount = FALSE;
ui32 block, addr;
/*---------------------------------------------------------------*/
/* Use the va_arg mechanism to fetch the path for unformat. */
/*---------------------------------------------------------------*/
va_start(ap, req);
path = va_arg(ap, char *);
va_end(ap);
/*---------------------------------------------------------------*/
/* Go through all the existing unmounted volumes and if any has */
/* the given name, unformat it. */
/*---------------------------------------------------------------*/
for (i = 0; i < NUM_FFS_VOLS; ++i)
{
/*-------------------------------------------------------------*/
/* Set pointer to the current entry in the array. */
/*-------------------------------------------------------------*/
vol = &FlashGlobals[i];
/*-------------------------------------------------------------*/
/* If this entry contains a valid volume and names match, then */
/* unformat the volume. */
/*-------------------------------------------------------------*/
if (vol->num_sects && !strcmp(path, vol->sys.name))
{
/*-----------------------------------------------------------*/
/* Acquire exclusive access to volume and flash file system. */
/*-----------------------------------------------------------*/
semPend(vol->sem, WAIT_FOREVER);
semPend(FlashSem, WAIT_FOREVER);
Flash = vol;
/*-----------------------------------------------------------*/
/* If volume is mounted, remember to unmount, else do a semi */
/* mount (i.e. read control up to bad block information. */
/*-----------------------------------------------------------*/
if (Flash->sys.next || Flash->sys.prev ||
&Flash->sys == MountedList.head)
do_unmount = TRUE;
else
{
/*---------------------------------------------------------*/
/* Assign memory to hold bad block info. */
/*---------------------------------------------------------*/
Flash->blocks = malloc(Flash->num_blocks * sizeof(FFSBlock));
if (Flash->blocks == NULL)
{
semPost(FlashSem);
semPost(vol->sem);
return (void *)-1;
}
/*---------------------------------------------------------*/
/* Attempt to do a semi mount based on control from flash. */
/*---------------------------------------------------------*/
if (FlashSemiMount())
{
free(Flash->blocks);
Flash->blocks = NULL;
semPost(FlashSem);
semPost(vol->sem);
return (void *)1;
}
}
/*-----------------------------------------------------------*/
/* Release exclusive access to the flash file system. */
/*-----------------------------------------------------------*/
semPost(FlashSem);
/*-----------------------------------------------------------*/
/* Walk the blocks list erasing all non-bad ones. */
/*-----------------------------------------------------------*/
for (block = 0; block < vol->num_blocks; ++block)
if (!vol->blocks[block].bad_block)
{
addr = vol->mem_base + block * vol->block_size;
if (vol->type == FFS_NAND)
(void)vol->driver.nand.erase_block(addr, vol->vol);
else
(void)vol->driver.nor.erase_block(addr, vol->vol);
}
/*-----------------------------------------------------------*/
/* Release exclusive access to volume. */
/*-----------------------------------------------------------*/
semPost(vol->sem);
/*-----------------------------------------------------------*/
/* Do an unmount if necessary. */
/*-----------------------------------------------------------*/
if (do_unmount)
FlashIoctl(NULL, UNMOUNT, vol->sys.volume, FALSE);
else
{
free(vol->blocks);
vol->blocks = NULL;
}
return (void *)1;
}
}
break;
}
/*-----------------------------------------------------------------*/
/* Handle the format function call. */
/*-----------------------------------------------------------------*/
case kFormat:
{
char *name;
FileSys *fsys;
int unmount_volume = FALSE;
int fresh_format = FALSE;
/*---------------------------------------------------------------*/
/* Use the va_arg mechanism to fetch the path for format. */
/*---------------------------------------------------------------*/
va_start(ap, req);
path = va_arg(ap, char *);
va_end(ap);
/*---------------------------------------------------------------*/
/* Go through all the existing volumes (mounted and not mounted) */
/* and if any has the given name, format it. */
/*---------------------------------------------------------------*/
for (i = 0; i < NUM_FFS_VOLS; ++i)
{
/*-------------------------------------------------------------*/
/* Set pointer to the current entry in the array. */
/*-------------------------------------------------------------*/
vol = &FlashGlobals[i];
/*-------------------------------------------------------------*/
/* If this entry contains a valid volume and the names match, */
/* format the volume. */
/*-------------------------------------------------------------*/
if (vol->num_sects && !strcmp(path, vol->sys.name))
{
/*-----------------------------------------------------------*/
/* If the volume is mounted, prepare it for erase operation. */
/*-----------------------------------------------------------*/
if (vol->sys.next || vol->sys.prev ||
(&vol->sys == MountedList.head))
{
/*---------------------------------------------------------*/
/* If sector freeing fails, return error. */
/*---------------------------------------------------------*/
if (prepare_mounted_for_format(vol))
return (void *)-1;
}
/*-----------------------------------------------------------*/
/* Else (volume not mounted) we have to mount the volume. */
/*-----------------------------------------------------------*/
else
{
/*---------------------------------------------------------*/
/* Try mounting the volume if possible. */
/*---------------------------------------------------------*/
fsys = FfsModule(kMount, path, /*lint !e416 !e415 */
&name, TRUE);
if (fsys != (FileSys *)-1)
{
/*-------------------------------------------------------*/
/* If sector freeing fails, unmount with error. */
/*-------------------------------------------------------*/
if (prepare_mounted_for_format(vol))
{
FlashIoctl(NULL, UNMOUNT, fsys->volume, FALSE);
return (void *)-1;
}
unmount_volume = TRUE;
}
/*---------------------------------------------------------*/
/* Else set up unformatted volume for mounting. */
/*---------------------------------------------------------*/
else
{
/*-------------------------------------------------------*/
/* Acquire access to volume and flash file system. */
/*-------------------------------------------------------*/
semPend(vol->sem, WAIT_FOREVER);
semPend(FlashSem, WAIT_FOREVER);
Flash = vol;
/*-------------------------------------------------------*/
/* Set up volume as if empty. */
/*-------------------------------------------------------*/
if (init_volume())
{
semPost(FlashSem);
semPost(vol->sem);
return (void *)-1;
}
/*-------------------------------------------------------*/
/* Call volume specific code. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -