www.pudn.com > test_megbox_vc.rar > lb_misc.c, change:2003-10-15,size:11013b


/* 
********************************************************************** 
*                          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; 
}