📄 fsmplr.c
字号:
### If the designated sector is not found, the function returns ERR_NOTEXIST.
### Otherwise, the function returns ERR_NONE.
###
*/
static uint32 DfsPlrEntryDeleting(
uint32 first_lsn,
uint32 entry_sector_psn,
uint16 entry_num,
uint32 * Psn2LsnP,
FsmDevObjHdrT * pDev,
uint32 block_size,
uint32 block_num
)
{
uint32 sector_size;
uint32 max_psn;
uint16 block_sectors;
uint32 psn;
uint32 lsn;
uint32 sector_addr;
uint16 sector_status;
uint16 sector_type;
uint32 entry_addr;
uint16 entry_status;
uint8 end_flag;
uint32 hw_status;
DEV_WRITE_FUNCPTR DevWrite = pDev->DevDrvP->FsmDevWrite;
DEV_READ_FUNCPTR DevRead = pDev->DevDrvP->FsmDevRead;
#ifdef DEBUG_FSM
MonPrintf("Enter Interface DfsPlrEntryDeleting!\n");
#endif
block_sectors = ((FsmFlashMediaT *)(pDev->MediaObjP))->SectorsPerBlock;
sector_size = ((FsmFlashMediaT *)(pDev->MediaObjP))->SectorSize;
max_psn = ((FsmFlashMediaT *)(pDev->MediaObjP))->MaxPsn;
lsn = first_lsn;
end_flag = 0;
while(lsn != (uint32)(-1))
{
end_flag = 0;
/* search the sector linked to the entry in ENTRY_DELETING status. */
for(psn = 0; psn < max_psn; psn++)
{
if(Psn2LsnP[psn] == lsn)
{
end_flag = 1;
break;
}
}
if(end_flag == 0)
return ERR_NOTEXIST;
sector_addr = DfsGetAddr(psn, block_sectors, block_size, sector_size);
hw_status = DevRead(pDev,
(uint8 *)§or_status,
sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
FIELD_SIZE(FsmFlashSectorHdrT, Status)
);
if(hw_status != HW_ERR_NONE)
return ERR_READ;
/* set sector status to SECTOR_DELETING and read nextlsn for searching the next sector in link. */
if(sector_status == SECTOR_VALID)
{
sector_status = SECTOR_DELETING;
hw_status = DevWrite(pDev,
(uint8 *)§or_status,
sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
FIELD_SIZE(FsmFlashSectorHdrT, Status)
);
if(hw_status != HW_ERR_NONE)
return ERR_WRITE;
}
else if(sector_status != SECTOR_DELETING)
return ERR_EXIST;
hw_status = DevRead(pDev,
(uint8 *)&lsn,
sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn),
FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
);
if(hw_status != HW_ERR_NONE)
return ERR_READ;
}
/* read sector type to judge the entry is for file or for item. */
sector_addr = DfsGetAddr(entry_sector_psn, block_sectors, block_size, sector_size);
hw_status = DevRead(pDev,
(uint8 *)§or_type,
sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Type),
FIELD_SIZE(FsmFlashSectorHdrT, Type)
);
if(hw_status != HW_ERR_NONE)
return ERR_READ;
/* invalidate directory entry. */
entry_status = ENTRY_INVALID;
if(sector_type == SECTOR_TYPE_FDE)
{
entry_addr = sector_addr + sizeof(FsmFlashSectorHdrT)
+ entry_num * sizeof(FsmFileDirEntryT);
hw_status = DevWrite(pDev,
(uint8 *)&entry_status,
entry_addr + FIELD_OFFSET(FsmFileDirEntryT, Status),
FIELD_SIZE(FsmFileDirEntryT, Status)
);
if(hw_status != HW_ERR_NONE)
return ERR_WRITE;
}
else
{
entry_addr = sector_addr + sizeof(FsmFlashSectorHdrT)
+ entry_num * sizeof(FsmItemDirEntryT);
hw_status = DevWrite(pDev,
(uint8 *)&entry_status,
entry_addr + FIELD_OFFSET(FsmItemDirEntryT, Status),
FIELD_SIZE(FsmItemDirEntryT, Status)
);
if(hw_status != HW_ERR_NONE)
return ERR_WRITE;
}
/* invalidate old sectors linked to the directory entry. */
sector_status = SECTOR_INVALID;
lsn = first_lsn;
while(lsn != (uint32)(-1))
{
end_flag = 0;
for(psn = 0; psn < max_psn; psn++)
{
if(Psn2LsnP[psn] == lsn)
{
end_flag = 1;
break;
}
}
if(end_flag == 0)
return ERR_NOTEXIST;
sector_addr = DfsGetAddr(psn, block_sectors, block_size, sector_size);
hw_status = DevWrite(pDev,
(uint8 *)§or_status,
sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
FIELD_SIZE(FsmFlashSectorHdrT, Status)
);
if(hw_status != HW_ERR_NONE)
return ERR_WRITE;
Psn2LsnP[psn] = DIRTYLSN;
hw_status = DevRead(pDev,
(uint8 *)&lsn,
sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn),
FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
);
if(hw_status != HW_ERR_NONE)
return ERR_READ;
}
#ifdef DEBUG_FSM
MonPrintf("Exit Interface DfsPlrEntryDeleting successfully!\n");
#endif
return ERR_NONE;
}
/*#############################################################################
### DfsPlrEntryUpdating
###
### DESCRIPTION:
### Validate all sectors linked to the entry in ENTRY_UPDATING status.
###
### PARAMETERS:
### IN: first_lsn - first sector lsn linked to the directory entry in
### ENTRY_ALLOCATED status.
### Psn2LsnP - pointer to the Psn2Lsn map.
### pDev - poiter to designated FsmDevObjHdrT of data file system.
### block_size - flash block size.
### block_num - flash block number.
### OUT:
###
### RETURNS:
### If read operation is not successful, the function returns ERR_READ.
### If write operation is not successful, the funciton returns ERR_WRITE.
### If the designated sector found is not in correct status, the function returns ERR_EXIST.
### If the designated sector is not found, the function returns ERR_NOTEXIST.
### Otherwise, the function returns ERR_NONE.
###
*/
static uint32 DfsPlrEntryUpdating(
uint32 first_lsn,
uint32 * Psn2LsnP,
FsmDevObjHdrT * pDev,
uint32 block_size,
uint32 block_num
)
{
uint32 max_psn;
uint32 sector_size;
uint16 block_sectors;
uint32 psn, old_psn, new_psn;
uint32 lsn;
uint16 sector_status;
uint8 new_flag, old_flag;
uint32 sector_addr;
uint32 err_status;
uint32 hw_status;
DEV_READ_FUNCPTR DevRead = pDev->DevDrvP->FsmDevRead;
#ifdef DEBUG_FSM
MonPrintf("Enter Interface DfsPlrEntryUpdating!\n");
#endif
block_sectors = ((FsmFlashMediaT *)(pDev->MediaObjP))->SectorsPerBlock;
sector_size = ((FsmFlashMediaT *)(pDev->MediaObjP))->SectorSize;
max_psn = ((FsmFlashMediaT *)(pDev->MediaObjP))->MaxPsn;
lsn = first_lsn;
while(lsn != (uint32)(-1))
{
new_flag = 0;
old_flag = 0;
/* search the sector linked to the entry. */
for(psn = 0; psn < max_psn; psn++)
{
if(Psn2LsnP[psn] == lsn)
{
sector_addr = DfsGetAddr(psn, block_sectors, block_size, sector_size);
hw_status = DevRead(pDev,
(uint8 *)§or_status,
sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
FIELD_SIZE(FsmFlashSectorHdrT, Status)
);
if(hw_status != HW_ERR_NONE)
return ERR_READ;
if(sector_status == SECTOR_VALID)
{
old_psn = psn;
old_flag = 1;
}
else if(sector_status == SECTOR_APPENDING)
{
new_psn = psn;
new_flag = 1;
}
}
}
if(new_flag == 1)
{
/* validate all new sectors linked to the entry. */
err_status = DfsPlrSecAppending(new_psn, Psn2LsnP, pDev, block_size, block_num);
if(err_status != ERR_NONE)
return err_status;
break;
}
else
{
if(old_flag == 1)
{
sector_addr = DfsGetAddr(old_psn, block_sectors, block_size, sector_size);
hw_status = DevRead(pDev,
(uint8 *)&lsn,
sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn),
FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
);
if(hw_status != HW_ERR_NONE)
return ERR_READ;
}
else
return ERR_NOTEXIST;
}
}
#ifdef DEBUG_FSM
MonPrintf("Exit Interface DfsPlrEntryUpdating successfully!\n");
#endif
return ERR_NONE;
}
/*#############################################################################
### DfsPlrItemEntry
###
### DESCRIPTION:
### Search old item directory entry whose firstlsn is the same with the
### firstlsn of the item directory entry in ENTRY_UPDATING status.If the
### designated entry is found, its status will be modified to ENTRY_INVALID.
###
### PARAMETERS:
### IN: first_lsn - firstlsn information of the item directory entry in
### ENTRY_UPDATING status.
### Psn2LsnP - pointer to the Psn2Lsn map.
### pDev - poiter to designated FsmDevObjHdrT of data file system.
### block_size - flash block size.
### block_num - flash block number.
### OUT:
###
### RETURNS:
### If read operation is not successful, the function returns ERR_READ.
### If write operation is not successful, the funciton returns ERR_WRITE.
### Otherwise, the function returns ERR_NONE.
###
*/
static uint32 DfsPlrItemEntry(
uint32 first_lsn,
uint32 * Psn2LsnP,
FsmDevObjHdrT * pDev,
uint32 block_size,
uint32 block_num
)
{
uint32 max_psn;
uint32 sector_size;
uint16 block_sectors;
uint32 max_entry;
uint32 psn, lsn;
uint32 sector_addr;
uint16 sector_type;
uint16 sector_status;
uint32 i;
uint32 entry_addr;
uint16 entry_status;
uint16 entry_status_msk;
uint32 entry_first_lsn;
uint32 hw_status;
uint8 end_flag;
DEV_WRITE_FUNCPTR DevWrite = pDev->DevDrvP->FsmDevWrite;
DEV_READ_FUNCPTR DevRead = pDev->DevDrvP->FsmDevRead;
#ifdef DEBUG_FSM
MonPrintf("Enter Interface DfsPlrItemEntry!\n");
#endif
block_sectors = ((FsmFlashMediaT *)(pDev->MediaObjP))->SectorsPerBlock;
sector_size = ((FsmFlashMediaT *)(pDev->MediaObjP))->SectorSize;
max_psn = ((FsmFlashMediaT *)(pDev->MediaObjP))->MaxPsn;
/* maximum item entries in a sector. */
max_entry = sector_size / sizeof(FsmItemDirEntryT);
end_flag = 0;
for(psn = 0; psn < max_psn; psn++)
{
lsn = Psn2LsnP[psn];
if((lsn == EMPTYLSN) || (lsn == DIRTYLSN))
continue;
sector_addr = DfsGetAddr(psn, block_sectors, block_size, sector_size);
hw_status = DevRead(pDev,
(uint8 *)§or_type,
sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Type),
FIELD_SIZE(FsmFlashSectorHdrT, Type)
);
if(hw_status != HW_ERR_NONE)
return ERR_READ;
if(sector_type == SECTOR_TYPE_IDE)
{
hw_status = DevRead(pDev,
(uint8 *)§or_status,
sector_addr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
FIELD_SIZE(FsmFlashSectorHdrT, Status)
);
if(hw_status != HW_ERR_NONE)
return ERR_READ;
if(sector_status != SECTOR_VALID)
continue;
for(i = 0; i < max_entry; i++)
{
entry_addr = sector_addr + sizeof(FsmFlashSectorHdrT)
+ i * sizeof(FsmItemDirEntryT);
hw_status = DevRead(pDev,
(uint8 *)&entry_status,
entry_addr+ FIELD_OFFSET(FsmItemDirEntryT, Status) ,
FIELD_SIZE(FsmItemDirEntryT, Status)
);
if(hw_status != HW_ERR_NONE)
return ERR_READ;
/* fix entry status to predefined value. */
if((entry_status_msk = VALID_ENTRY_STATE(entry_status)) != 0)
{
entry_status = FIX_ENTRY_STATE(entry_status_msk, entry_status);
}
if(entry_status == ENTRY_EMPTY)
break;
else if(entry_status == ENTRY_VALID)
{
hw_status = DevRead(pDev,
(uint8 *)&entry_first_lsn,
entry_addr + FIELD_OFFSET(FsmItemDirEntryT, FirstLsn),
FIELD_SIZE(FsmItemDirEntryT, FirstLsn)
);
if(hw_status != HW_ERR_NONE)
return ERR_READ;
if(entry_first_lsn == first_lsn)
{
entry_status = ENTRY_INVALID;
hw_status = DevWrite(pDev,
(uint8 *)&entry_status,
entry_addr + FIELD_OFFSET(FsmItemDirEntryT, Status),
FIELD_SIZE(FsmItemDirEntryT, Status)
);
if(hw_status != HW_ERR_NONE)
return ERR_WRITE;
end_flag = 1;
break;
}
} /* end if ENTRY_VALID. */
} /* end for (i = 0; i < max_entry; i++) */
} /* if(sector_type == SECTOR_TYPE_IDE) */
if(end_flag == 1)
break;
} /* end for(psn = 0; psn < max_psn; psn++). */
#ifdef DEBUG_FSM
MonPrintf("Exit Interface DfsPlrItemEntry successfully!\n");
#endif
return ERR_NONE;
}
/*#############################################################################
### DfsPlrFileEntry
###
### DESCRIPTION:
### Search old file directory entry whose firstlsn is the same with the
### firstlsn of the file directory entry in ENTRY_UPDATING status.If the
### designated entry is found, its status will be modified to ENTRY_INVALID.
###
### PARAMETERS:
### IN: first_lsn - firstlsn information of the file directory entry in
### ENT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -