lb_misc.c
上传用户:yj_qqy
上传日期:2017-01-28
资源大小:2911k
文件大小:11k
源码类别:

uCOS

开发平台:

C/C++

  1. /*
  2. **********************************************************************
  3. *                          Micrium, Inc.
  4. *                      949 Crestview Circle
  5. *                     Weston,  FL 33327-1848
  6. *
  7. *                            uC/FS
  8. *
  9. *             (c) Copyright 2001 - 2003, Micrium, Inc.
  10. *                      All rights reserved.
  11. *
  12. ***********************************************************************
  13. ----------------------------------------------------------------------
  14. File        : lb_misc.c
  15. Purpose     : Logical Block Layer
  16. ----------------------------------------------------------------------
  17. Known problems or limitations with current version
  18. ----------------------------------------------------------------------
  19. None.
  20. ---------------------------END-OF-HEADER------------------------------
  21. */
  22. /*********************************************************************
  23. *
  24. *             #include Section
  25. *
  26. **********************************************************************
  27. */
  28. #include "fs_port.h"
  29. #include "fs_conf.h"
  30. #include "fs_dev.h"
  31. #include "fs_api.h"
  32. #include "fs_lbl.h"
  33. #include "fs_os.h"
  34. #include "fs_fsl.h"
  35. #include "fs_int.h"
  36. #include "fs_clib.h"
  37. /*********************************************************************
  38. *
  39. *             Local functions
  40. *
  41. **********************************************************************
  42. */
  43. #if FS_USE_LB_READCACHE
  44. /*********************************************************************
  45. *
  46. *             _FS_LB_GetDriverIndex
  47. *
  48.   Description:
  49.   FS internal function. Get index of a driver in the device information
  50.   table referred by FS__pDevInfo.
  51.   Parameters:
  52.   pDriver     - Pointer to a device driver structure
  53.  
  54.   Return value:
  55.   =>0         - Index of pDriver in the device information table.
  56.   <0          - An error has occured.
  57. */
  58. static int _FS_LB_GetDriverIndex(const FS__device_type *pDriver) {
  59.   unsigned int i;
  60.   i = 0;
  61.   while (1) {
  62.     if (i >= FS__maxdev) {
  63.       break;  /* Driver not found */
  64.     }
  65.     if (FS__pDevInfo[i].devdriver == pDriver) {
  66.       break;  /* Driver found */
  67.     }
  68.     i++;
  69.   }
  70.   if (i >= FS__maxdev) {
  71.     return -1;
  72.   }
  73.   return i;
  74. }
  75. /*********************************************************************
  76. *
  77. *             _FS_LB_GetFromCache
  78. *
  79.   Description:
  80.   FS internal function. Copy sector from cache, if available.
  81.   Parameters:
  82.   pDriver     - Pointer to a device driver structure.
  83.   Unit        - Unit number.
  84.   Sector      - Sector to be read from the device's cache.
  85.   pBuffer     - Pointer to a data buffer for storing data of the cache. 
  86.  
  87.   Return value:
  88.   ==0         - Sector is in cache and has been copied to pBuffer.
  89.   <0          - An error has occured.
  90. */
  91. static int _FS_LB_GetFromCache(const FS__device_type *pDriver, FS_u32 Unit, FS_u32 Sector, void *pBuffer) {
  92.   int i;
  93.   int idx;
  94.   idx = _FS_LB_GetDriverIndex(pDriver);
  95.   if (idx < 0) {
  96.     return -1;
  97.   }
  98.   if (FS__pDevInfo[idx].pDevCacheInfo) {
  99.     i = 0;
  100.     while (1) {
  101.       if (i >= FS__pDevInfo[idx].pDevCacheInfo[Unit].MaxCacheNum) {
  102.         break;  /* Sector not in cache */
  103.       }
  104.       if (Sector == FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[i].BlockId) {
  105.         break;  /* Sector found */
  106.       }
  107.       i++;
  108.     }
  109.     if (i < FS__pDevInfo[idx].pDevCacheInfo[Unit].MaxCacheNum) {
  110.       FS__CLIB_memcpy(pBuffer, FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[i].aBlockData, FS_LB_BLOCKSIZE);
  111.       return 0;
  112.     }
  113.   }
  114.   return -1;  
  115. }
  116. /*********************************************************************
  117. *
  118. *             _FS_LB_CopyToCache
  119. *
  120.   Description:
  121.   FS internal function. Copy a sector to the cache of the device.
  122.   Parameters:
  123.   pDriver     - Pointer to a device driver structure.
  124.   Unit        - Unit number.
  125.   Sector      - Sector to be copied to the device's cache.
  126.   pBuffer     - Pointer to a data buffer to be stored in the cache. 
  127.  
  128.   Return value:
  129.   None.
  130. */
  131. static void _FS_LB_CopyToCache(const FS__device_type *pDriver, FS_u32 Unit, FS_u32 Sector, void *pBuffer) {
  132.   int idx;
  133.   idx = _FS_LB_GetDriverIndex(pDriver);
  134.   if (idx < 0) {
  135.     return;
  136.   }
  137.   if (FS__pDevInfo[idx].pDevCacheInfo) {
  138.     FS__CLIB_memcpy(FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[FS__pDevInfo[idx].pDevCacheInfo[Unit].CacheIndex].aBlockData,
  139.             pBuffer, FS_LB_BLOCKSIZE);
  140.     FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[FS__pDevInfo[idx].pDevCacheInfo[Unit].CacheIndex].BlockId = Sector;
  141.     FS__pDevInfo[idx].pDevCacheInfo[Unit].CacheIndex++;
  142.     if (FS__pDevInfo[idx].pDevCacheInfo[Unit].CacheIndex >= FS__pDevInfo[idx].pDevCacheInfo[Unit].MaxCacheNum) {
  143.       FS__pDevInfo[idx].pDevCacheInfo[Unit].CacheIndex = 0;
  144.     }
  145.   }
  146. }
  147. /*********************************************************************
  148. *
  149. *             _FS_LB_UpdateInCache
  150. *
  151.   Description:
  152.   FS internal function. Update sector in cache, if it is there.
  153.   Parameters:
  154.   pDriver     - Pointer to a device driver structure.
  155.   Unit        - Unit number.
  156.   Sector      - Sector to be updated in the device's cache.
  157.   pBuffer     - Pointer to a data buffer to be stored in the cache. 
  158.  
  159.   Return value:
  160.   None.
  161. */
  162. static void _FS_LB_UpdateInCache(const FS__device_type *pDriver, FS_u32 Unit, FS_u32 Sector, void *pBuffer) {
  163.   int i;
  164.   int idx;
  165.   idx = _FS_LB_GetDriverIndex(pDriver);
  166.   if (idx < 0) {
  167.     return;
  168.   }
  169.   if (FS__pDevInfo[idx].pDevCacheInfo) {
  170.     i = 0;
  171.     while (1) {
  172.       if (i >= FS__pDevInfo[idx].pDevCacheInfo[Unit].MaxCacheNum) {
  173.         break; /* Sector not in cache */
  174.       }
  175.       if (Sector == FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[i].BlockId) {
  176.         break; /* Sector found */
  177.       }
  178.       i++;
  179.     }
  180.     if (i < FS__pDevInfo[idx].pDevCacheInfo[Unit].MaxCacheNum) {
  181.       FS__CLIB_memcpy(FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[i].aBlockData, pBuffer, FS_LB_BLOCKSIZE);
  182.     }
  183.   }
  184. }
  185. /*********************************************************************
  186. *
  187. *             _FS_LB_ClearCache
  188. *
  189.   Description:
  190.   FS internal function. Clear cache of a device.
  191.   Parameters:
  192.   pDriver     - Pointer to a device driver structure.
  193.   Unit        - Unit number.
  194.  
  195.   Return value:
  196.   None.
  197. */
  198. static void _FS_LB_ClearCache(const FS__device_type *pDriver, FS_u32 Unit) {
  199.   int i;
  200.   int idx;
  201.   idx = _FS_LB_GetDriverIndex(pDriver);
  202.   if (idx<0) {
  203.     return;
  204.   }
  205.   if (FS__pDevInfo[idx].pDevCacheInfo) {
  206.     FS__pDevInfo[idx].pDevCacheInfo[Unit].CacheIndex = 0;
  207.     for (i = 0; i < FS__pDevInfo[idx].pDevCacheInfo[Unit].MaxCacheNum; i++) {
  208.       FS__pDevInfo[idx].pDevCacheInfo[Unit].pCache[i].BlockId = 0xffffffffUL;
  209.     }
  210.   }
  211. }
  212. #endif  /* FS_USE_LB_READCACHE */
  213. /*********************************************************************
  214. *
  215. *             Global functions
  216. *
  217. **********************************************************************
  218.   Functions here are global, although their names indicate a local
  219.   scope. They should not be called by user application.
  220. */
  221. /*********************************************************************
  222. *
  223. *             FS__lb_status
  224. *
  225.   Description:
  226.   FS internal function. Get status of a device.
  227.   Parameters:
  228.   pDriver     - Pointer to a device driver structure.
  229.   Unit        - Unit number.
  230.  
  231.   Return value:
  232.   ==1 (FS_LBL_MEDIACHANGED) - The media of the device has changed.
  233.   ==0                       - Device okay and ready for operation.
  234.   <0                        - An error has occured.
  235. */
  236. int FS__lb_status(const FS__device_type *pDriver, FS_u32 Unit) {
  237.   int x;
  238.   if (pDriver->dev_status) {
  239.     FS_X_OS_LockDeviceOp(pDriver, Unit);
  240.     x = (pDriver->dev_status)(Unit);
  241. #if FS_USE_LB_READCACHE
  242.     if (x != 0) {
  243.       _FS_LB_ClearCache(pDriver, Unit);
  244.     }
  245. #endif  /* FS_USE_LB_READCACHE */
  246.     FS_X_OS_UnlockDeviceOp(pDriver, Unit);
  247.     return x;
  248.   }
  249.   return -1;
  250. }
  251. /*********************************************************************
  252. *
  253. *             FS__lb_read
  254. *
  255.   Description:
  256.   FS internal function. Read sector from device.
  257.   Parameters:
  258.   pDriver     - Pointer to a device driver structure.
  259.   Unit        - Unit number.
  260.   Sector      - Sector to be read from the device.
  261.   pBuffer     - Pointer to buffer for storing the data.
  262.  
  263.   Return value:
  264.   ==0         - Sector has been read and copied to pBuffer.
  265.   <0          - An error has occured.
  266. */
  267. int FS__lb_read(const FS__device_type *pDriver, FS_u32 Unit, FS_u32 Sector, void *pBuffer) {
  268.   int x;
  269.   if (pDriver->dev_read) {
  270.     FS_X_OS_LockDeviceOp(pDriver, Unit);
  271. #if FS_USE_LB_READCACHE
  272.     x = _FS_LB_GetFromCache(pDriver, Unit, Sector, pBuffer);
  273.     if (x != 0) {
  274.       x = (pDriver->dev_read)(Unit, Sector, pBuffer);
  275.       if (x == 0) {
  276.         _FS_LB_CopyToCache(pDriver, Unit, Sector, pBuffer);
  277.       }
  278.     }
  279. #else
  280.     x = (pDriver->dev_read)(Unit, Sector, pBuffer);
  281. #endif  /* FS_USE_LB_READCACHE */
  282.     FS_X_OS_UnlockDeviceOp(pDriver, Unit);
  283.     return  x;
  284.   }
  285.   return -1;
  286. }
  287. /*********************************************************************
  288. *
  289. *             FS__lb_write
  290. *
  291.   Description:
  292.   FS internal function. Write sector to device.
  293.   Parameters:
  294.   pDriver     - Pointer to a device driver structure.
  295.   Unit        - Unit number.
  296.   Sector      - Sector to be written to the device.
  297.   pBuffer     - Pointer to data to be stored.
  298.  
  299.   Return value:
  300.   ==0         - Sector has been written to the device.
  301.   <0          - An error has occured.
  302. */
  303. int FS__lb_write(const FS__device_type *pDriver, FS_u32 Unit, FS_u32 Sector, void *pBuffer) {
  304.   int x;
  305.   if (pDriver->dev_write) {
  306.     FS_X_OS_LockDeviceOp(pDriver, Unit);
  307.     x = (pDriver->dev_write)(Unit, Sector, pBuffer);
  308. #if FS_USE_LB_READCACHE
  309.     if (x==0) {
  310.       _FS_LB_UpdateInCache(pDriver, Unit, Sector, pBuffer);
  311.     }
  312.     else {
  313.       _FS_LB_ClearCache(pDriver, Unit);
  314.     }
  315. #endif  /* FS_USE_LB_READCACHE */
  316.     FS_X_OS_UnlockDeviceOp(pDriver, Unit);
  317.     return x;
  318.   }
  319.   return -1;
  320. }
  321. /*********************************************************************
  322. *
  323. *             FS__lb_ioctl
  324. *
  325.   Description:
  326.   FS internal function. Execute device command.
  327.   Parameters:
  328.   pDriver     - Pointer to a device driver structure.
  329.   Unit        - Unit number.
  330.   Cmd         - Command to be executed.
  331.   Aux         - Parameter depending on command.
  332.   pBuffer     - Pointer to a buffer used for the command.
  333.  
  334.   Return value:
  335.   Command specific. In general a negative value means an error.
  336. */
  337. int FS__lb_ioctl(const FS__device_type *pDriver, FS_u32 Unit, FS_i32 Cmd, FS_i32 Aux, void *pBuffer) {
  338.   int x;
  339.   if (pDriver->dev_ioctl) {
  340.     FS_X_OS_LockDeviceOp(pDriver, Unit);
  341.     x = (pDriver->dev_ioctl)(Unit, Cmd, Aux, pBuffer);
  342.     FS_X_OS_UnlockDeviceOp(pDriver, Unit);
  343.     return x;
  344.   }
  345.   return -1;
  346. }