📄 lb_misc.c
字号:
/*
**********************************************************************
* Micrium, Inc.
* 949 Crestview Circle
* Weston, FL 33327-1848
*
* uC/FS
*
* (c) Copyright 2001 - 2003, Micrium, Inc.
* All rights reserved.
*
***********************************************************************
----------------------------------------------------------------------
File : lb_misc.c
Purpose : Logical Block Layer
----------------------------------------------------------------------
Known problems or limitations with current version
----------------------------------------------------------------------
None.
---------------------------END-OF-HEADER------------------------------
*/
/*********************************************************************
*
* #include Section
*
**********************************************************************
*/
#include "fs_port.h"
#include "fs_conf.h"
#include "fs_dev.h"
#include "fs_api.h"
#include "fs_lbl.h"
#include "fs_os.h"
#include "fs_fsl.h"
#include "fs_int.h"
#include "fs_clib.h"
/*********************************************************************
*
* Local functions
*
**********************************************************************
*/
#if FS_USE_LB_READCACHE
/*********************************************************************
*
* _FS_LB_GetDriverIndex
*
Description:
FS internal function. Get index of a driver in the device information
table referred by FS__pDevInfo.
Parameters:
pDriver - Pointer to a device driver structure
Return value:
=>0 - Index of pDriver in the device information table.
<0 - An error has occured.
*/
static int _FS_LB_GetDriverIndex(const FS__device_type *pDriver) {
unsigned int i;
i = 0;
while (1) {
if (i >= FS__maxdev) {
break; /* Driver not found */
}
if (FS__pDevInfo[i].devdriver == pDriver) {
break; /* Driver found */
}
i++;
}
if (i >= FS__maxdev) {
return -1;
}
return i;
}
/*********************************************************************
*
* _FS_LB_GetFromCache
*
Description:
FS internal function. Copy sector from cache, if available.
Parameters:
pDriver - Pointer to a device driver structure.
Unit - Unit number.
Sector - Sector to be read from the device's cache.
pBuffer - Pointer to a data buffer for storing data of the cache.
Return value:
==0 - Sector is in cache and has been copied to pBuffer.
<0 - An error has occured.
*/
static int _FS_LB_GetFromCache(const FS__device_type *pDriver, FS_u32 Unit, FS_u32 Sector, void *pBuffer) {
int i;
int idx;
idx = _FS_LB_GetDriverIndex(pDriver);
if (idx < 0) {
return -1;
}
if (FS__pDevInfo[idx].pDevCacheInfo) {
i = 0;
while (1) {
if (i >= FS__pDevInfo[idx].pDevCacheInfo[Unit].MaxCacheNum) {
break; /* Sector not in cache */
}
if (Sector == FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[i].BlockId) {
break; /* Sector found */
}
i++;
}
if (i < FS__pDevInfo[idx].pDevCacheInfo[Unit].MaxCacheNum) {
FS__CLIB_memcpy(pBuffer, FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[i].aBlockData, FS_LB_BLOCKSIZE);
return 0;
}
}
return -1;
}
/*********************************************************************
*
* _FS_LB_CopyToCache
*
Description:
FS internal function. Copy a sector to the cache of the device.
Parameters:
pDriver - Pointer to a device driver structure.
Unit - Unit number.
Sector - Sector to be copied to the device's cache.
pBuffer - Pointer to a data buffer to be stored in the cache.
Return value:
None.
*/
static void _FS_LB_CopyToCache(const FS__device_type *pDriver, FS_u32 Unit, FS_u32 Sector, void *pBuffer) {
int idx;
idx = _FS_LB_GetDriverIndex(pDriver);
if (idx < 0) {
return;
}
if (FS__pDevInfo[idx].pDevCacheInfo) {
FS__CLIB_memcpy(FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[FS__pDevInfo[idx].pDevCacheInfo[Unit].CacheIndex].aBlockData,
pBuffer, FS_LB_BLOCKSIZE);
FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[FS__pDevInfo[idx].pDevCacheInfo[Unit].CacheIndex].BlockId = Sector;
FS__pDevInfo[idx].pDevCacheInfo[Unit].CacheIndex++;
if (FS__pDevInfo[idx].pDevCacheInfo[Unit].CacheIndex >= FS__pDevInfo[idx].pDevCacheInfo[Unit].MaxCacheNum) {
FS__pDevInfo[idx].pDevCacheInfo[Unit].CacheIndex = 0;
}
}
}
/*********************************************************************
*
* _FS_LB_UpdateInCache
*
Description:
FS internal function. Update sector in cache, if it is there.
Parameters:
pDriver - Pointer to a device driver structure.
Unit - Unit number.
Sector - Sector to be updated in the device's cache.
pBuffer - Pointer to a data buffer to be stored in the cache.
Return value:
None.
*/
static void _FS_LB_UpdateInCache(const FS__device_type *pDriver, FS_u32 Unit, FS_u32 Sector, void *pBuffer) {
int i;
int idx;
idx = _FS_LB_GetDriverIndex(pDriver);
if (idx < 0) {
return;
}
if (FS__pDevInfo[idx].pDevCacheInfo) {
i = 0;
while (1) {
if (i >= FS__pDevInfo[idx].pDevCacheInfo[Unit].MaxCacheNum) {
break; /* Sector not in cache */
}
if (Sector == FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[i].BlockId) {
break; /* Sector found */
}
i++;
}
if (i < FS__pDevInfo[idx].pDevCacheInfo[Unit].MaxCacheNum) {
FS__CLIB_memcpy(FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[i].aBlockData, pBuffer, FS_LB_BLOCKSIZE);
}
}
}
/*********************************************************************
*
* _FS_LB_ClearCache
*
Description:
FS internal function. Clear cache of a device.
Parameters:
pDriver - Pointer to a device driver structure.
Unit - Unit number.
Return value:
None.
*/
static void _FS_LB_ClearCache(const FS__device_type *pDriver, FS_u32 Unit) {
int i;
int idx;
idx = _FS_LB_GetDriverIndex(pDriver);
if (idx<0) {
return;
}
if (FS__pDevInfo[idx].pDevCacheInfo) {
FS__pDevInfo[idx].pDevCacheInfo[Unit].CacheIndex = 0;
for (i = 0; i < FS__pDevInfo[idx].pDevCacheInfo[Unit].MaxCacheNum; i++) {
FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[i].BlockId = 0xffffffffUL;
}
}
}
#endif /* FS_USE_LB_READCACHE */
/*********************************************************************
*
* Global functions
*
**********************************************************************
Functions here are global, although their names indicate a local
scope. They should not be called by user application.
*/
/*********************************************************************
*
* FS__lb_status
*
Description:
FS internal function. Get status of a device.
Parameters:
pDriver - Pointer to a device driver structure.
Unit - Unit number.
Return value:
==1 (FS_LBL_MEDIACHANGED) - The media of the device has changed.
==0 - Device okay and ready for operation.
<0 - An error has occured.
*/
int FS__lb_status(const FS__device_type *pDriver, FS_u32 Unit) {
int x;
if (pDriver->dev_status) {
FS_X_OS_LockDeviceOp(pDriver, Unit);
x = (pDriver->dev_status)(Unit);
#if FS_USE_LB_READCACHE
if (x != 0) {
_FS_LB_ClearCache(pDriver, Unit);
}
#endif /* FS_USE_LB_READCACHE */
FS_X_OS_UnlockDeviceOp(pDriver, Unit);
return x;
}
return -1;
}
/*********************************************************************
*
* FS__lb_read
*
Description:
FS internal function. Read sector from device.
Parameters:
pDriver - Pointer to a device driver structure.
Unit - Unit number.
Sector - Sector to be read from the device.
pBuffer - Pointer to buffer for storing the data.
Return value:
==0 - Sector has been read and copied to pBuffer.
<0 - An error has occured.
*/
int FS__lb_read(const FS__device_type *pDriver, FS_u32 Unit, FS_u32 Sector, void *pBuffer) {
int x;
if (pDriver->dev_read) {
FS_X_OS_LockDeviceOp(pDriver, Unit);
#if FS_USE_LB_READCACHE
x = _FS_LB_GetFromCache(pDriver, Unit, Sector, pBuffer);
if (x != 0) {
x = (pDriver->dev_read)(Unit, Sector, pBuffer);
if (x == 0) {
_FS_LB_CopyToCache(pDriver, Unit, Sector, pBuffer);
}
}
#else
x = (pDriver->dev_read)(Unit, Sector, pBuffer);
#endif /* FS_USE_LB_READCACHE */
FS_X_OS_UnlockDeviceOp(pDriver, Unit);
return x;
}
return -1;
}
/*********************************************************************
*
* FS__lb_write
*
Description:
FS internal function. Write sector to device.
Parameters:
pDriver - Pointer to a device driver structure.
Unit - Unit number.
Sector - Sector to be written to the device.
pBuffer - Pointer to data to be stored.
Return value:
==0 - Sector has been written to the device.
<0 - An error has occured.
*/
int FS__lb_write(const FS__device_type *pDriver, FS_u32 Unit, FS_u32 Sector, void *pBuffer) {
int x;
if (pDriver->dev_write) {
FS_X_OS_LockDeviceOp(pDriver, Unit);
x = (pDriver->dev_write)(Unit, Sector, pBuffer);
#if FS_USE_LB_READCACHE
if (x==0) {
_FS_LB_UpdateInCache(pDriver, Unit, Sector, pBuffer);
}
else {
_FS_LB_ClearCache(pDriver, Unit);
}
#endif /* FS_USE_LB_READCACHE */
FS_X_OS_UnlockDeviceOp(pDriver, Unit);
return x;
}
return -1;
}
/*********************************************************************
*
* FS__lb_ioctl
*
Description:
FS internal function. Execute device command.
Parameters:
pDriver - Pointer to a device driver structure.
Unit - Unit number.
Cmd - Command to be executed.
Aux - Parameter depending on command.
pBuffer - Pointer to a buffer used for the command.
Return value:
Command specific. In general a negative value means an error.
*/
int FS__lb_ioctl(const FS__device_type *pDriver, FS_u32 Unit, FS_i32 Cmd, FS_i32 Aux, void *pBuffer) {
int x;
if (pDriver->dev_ioctl) {
FS_X_OS_LockDeviceOp(pDriver, Unit);
x = (pDriver->dev_ioctl)(Unit, Cmd, Aux, pBuffer);
FS_X_OS_UnlockDeviceOp(pDriver, Unit);
return x;
}
return -1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -