wd_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        : wd_misc.c
  15. Purpose     : Device Driver using Windows I/O function for logical sector
  16.               access.
  17. ----------------------------------------------------------------------
  18. Known problems or limitations with current version
  19. ----------------------------------------------------------------------
  20. None.
  21. ---------------------------END-OF-HEADER------------------------------
  22. */
  23. /*********************************************************************
  24. *
  25. *             #include Section
  26. *
  27. **********************************************************************
  28. */
  29. #include "fs_port.h"
  30. #include "fs_dev.h" 
  31. #include "fs_lbl.h" 
  32. #include "fs_conf.h"
  33. #include "fs_api.h"
  34. #include "fs_clib.h"
  35. #if FS_USE_WINDRIVE_DRIVER
  36. #ifndef _WIN32
  37. #error Driver requires Windows API
  38. #endif /* _WIN32 */
  39. #include <windows.h>
  40. /*********************************************************************
  41. *
  42. *             Local data types
  43. *
  44. **********************************************************************
  45. */
  46. typedef struct {
  47.   FS_u32 block;
  48.   char buffer[FS_WD_BLOCKSIZE];
  49. } _FS_wd_cachetype;
  50. /*********************************************************************
  51. *
  52. *             Local variables        
  53. *
  54. **********************************************************************
  55. */
  56. static unsigned char      _workbuffer[512];
  57. static HANDLE             _hdrive[FS_WD_MAXUNIT];
  58. static _FS_wd_cachetype   _FS_wd_cache[FS_WD_MAXUNIT][FS_WD_CACHENUM];
  59. static int                _FS_wd_cache_index[FS_WD_MAXUNIT];
  60. static _FS_wd_cachetype   _FS_wd_wbuffer[FS_WD_MAXUNIT][FS_WD_WBUFFNUM];
  61. static int                _online[FS_WD_MAXUNIT];
  62. /*********************************************************************
  63. *
  64. *             Local functions
  65. *
  66. **********************************************************************
  67. */
  68. /*********************************************************************
  69. *
  70. *             _FS_WD_DevStatus
  71. *
  72.   Description:
  73.   FS driver function. Get status of the media.
  74.   Parameters:
  75.   Unit        - Unit number.
  76.  
  77.   Return value:
  78.   ==1 (FS_LBL_MEDIACHANGED) - The media of the device has changed.
  79.   ==0                       - Device okay and ready for operation.
  80.   <0                        - An error has occured.
  81. */
  82. static int _FS_WD_DevStatus(FS_u32 Unit) {
  83.   int i;
  84.   if (!_online[Unit]) {
  85.     _online[Unit] = 1;
  86.     if (Unit == 0) {
  87.       _hdrive[Unit] = CreateFile(FS_WD_DEV0NAME, 
  88.                                   GENERIC_READ | GENERIC_WRITE,
  89.                                   FILE_SHARE_READ | FILE_SHARE_WRITE,
  90.                                   NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  91.                                   NULL);
  92.     }
  93.     else {
  94.       _hdrive[Unit] = CreateFile(FS_WD_DEV1NAME, 
  95.                                   GENERIC_READ | GENERIC_WRITE,
  96.                                   FILE_SHARE_READ | FILE_SHARE_WRITE,
  97.                                   NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  98.                                   NULL);
  99.     }
  100.     for (i = 0; i < FS_WD_CACHENUM; i++) {
  101.       _FS_wd_cache[Unit][i].block = -1;
  102.     }
  103.     _FS_wd_cache_index[Unit] = 0;
  104.     for (i = 0; i < FS_WD_WBUFFNUM; i++) {
  105.       _FS_wd_wbuffer[Unit][i].block = -1;
  106.     }
  107.     return FS_LBL_MEDIACHANGED;
  108.   }
  109.   return 0;
  110. }
  111. /*********************************************************************
  112. *
  113. *             _FS_WD_DevRead
  114. *
  115.   Description:
  116.   FS driver function. Read a sector from the media.
  117.   Parameters:
  118.   Unit        - Unit number.
  119.   Sector      - Sector to be read from the device.
  120.   pBuffer     - Pointer to buffer for storing the data.
  121.  
  122.   Return value:
  123.   ==0         - Sector has been read and copied to pBuffer.
  124.   <0          - An error has occured.
  125. */
  126. static int _FS_WD_DevRead(FS_u32 Unit, FS_u32 Sector, void *pBuffer) {
  127.   DWORD bytenum;
  128.   BOOL success;
  129.   int i;
  130.   int x;
  131.   x = 0;
  132.   /* check if pBuffer in wbuffer */
  133.   i = 0;
  134.   while (i < FS_WD_WBUFFNUM) {
  135.     if (_FS_wd_wbuffer[Unit][i].block == Sector) {
  136.       FS__CLIB_memcpy(pBuffer, _FS_wd_wbuffer[Unit][i].buffer, 512);
  137.       return 0;
  138.     }
  139.     i++;
  140.   }
  141.   for (i = 0; i < FS_WD_CACHENUM; i++) {
  142.     if (_FS_wd_cache[Unit][i].block == Sector) {
  143.       FS__CLIB_memcpy(pBuffer, _FS_wd_cache[Unit][i].buffer, 512);
  144.       return 0;
  145.     }
  146.   }
  147.   SetFilePointer(_hdrive[Unit],Sector * 512, 0, FILE_BEGIN);
  148.   success = ReadFile(_hdrive[Unit], pBuffer, 512, &bytenum, NULL);
  149.   if (!success) {
  150.     x = -1;
  151.   }
  152.   _FS_wd_cache[Unit][_FS_wd_cache_index[Unit]].block = Sector;
  153.   FS__CLIB_memcpy(_FS_wd_cache[Unit][_FS_wd_cache_index[Unit]].buffer, pBuffer, 512);
  154.   _FS_wd_cache_index[Unit]++;
  155.   if (_FS_wd_cache_index[Unit] >= FS_WD_CACHENUM) {
  156.     _FS_wd_cache_index[Unit] = 0;
  157.   }
  158.   return x;
  159. }
  160. /*********************************************************************
  161. *
  162. *             _FS_WD_DevWrite
  163. *
  164.   Description:
  165.   FS driver function. Write sector to the media.
  166.   Parameters:
  167.   Unit        - Unit number.
  168.   Sector      - Sector to be written to the device.
  169.   pBuffer     - Pointer to data to be stored.
  170.  
  171.   Return value:
  172.   ==0         - Sector has been written to the device.
  173.   <0          - An error has occured.
  174. */
  175. static int _FS_WD_DevWrite(FS_u32 Unit, FS_u32 Sector, void *pBuffer) {
  176.   DWORD bytenum;
  177.   BOOL success;
  178.   int i;
  179.   int j;
  180.   int x;
  181.   x = 0;
  182.   /* clear in read cache */
  183.   for (i = 0; i < FS_WD_CACHENUM; i++) {
  184.     if (_FS_wd_cache[Unit][i].block == Sector) {
  185.       _FS_wd_cache[Unit][i].block = -1;
  186.     }
  187.   }
  188.   /* check if pBuffer in wbuffer */
  189.   i = 0;
  190.   while (i < FS_WD_WBUFFNUM) {
  191.     if (_FS_wd_wbuffer[Unit][i].block == Sector) {
  192.       FS__CLIB_memcpy(_FS_wd_wbuffer[Unit][i].buffer, pBuffer, 512);
  193.       return 0;
  194.     }
  195.     i++;
  196.   }
  197.   /* check for free wbuffer */
  198.   i = 0;
  199.   while (i < FS_WD_WBUFFNUM) {
  200.     if (_FS_wd_wbuffer[Unit][i].block == -1) {
  201.       FS__CLIB_memcpy(_FS_wd_wbuffer[Unit][i].buffer, pBuffer, 512);
  202.       _FS_wd_wbuffer[Unit][i].block = Sector;
  203.       return 0;
  204.     }
  205.     i++;
  206.   }
  207.   /* write back complete cache  */
  208.   i = 0;
  209.   while (1) {
  210.     if (i >= FS_WD_WBUFFNUM) {
  211.       break;  /* End of cache reached */
  212.     }
  213.     if (_FS_wd_wbuffer[Unit][i].block != -1) {
  214.       break;  /* Valid cache entry found */
  215.     }
  216.     i++;
  217.   }
  218.   while (i < FS_WD_WBUFFNUM) {
  219.     for (j = 0; j < FS_WD_WBUFFNUM; j++) {
  220.       if (_FS_wd_wbuffer[Unit][j].block != -1) {
  221.         if (_FS_wd_wbuffer[Unit][j].block < _FS_wd_wbuffer[Unit][i].block) {
  222.           i = j;
  223.         }
  224.       }
  225.     }
  226.     if (_FS_wd_wbuffer[Unit][i].block != -1) {
  227.       SetFilePointer(_hdrive[Unit], _FS_wd_wbuffer[Unit][i].block * 512, 0, FILE_BEGIN);
  228.       success = WriteFile(_hdrive[Unit], _FS_wd_wbuffer[Unit][i].buffer, 512, &bytenum, NULL);
  229.       if (!success) {
  230.         x = -1;
  231.       }
  232.       _FS_wd_wbuffer[Unit][i].block = -1;
  233.     }
  234.     i = 0;
  235.     while (1) {
  236.       if (i >= FS_WD_WBUFFNUM) {
  237.         break;  /* End of cache reached. */
  238.       }
  239.       if (_FS_wd_wbuffer[Unit][i].block != -1) {
  240.         break;  /* Valid entry found */
  241.       }
  242.       i++;
  243.     }
  244.   } 
  245.   FS__CLIB_memcpy(_FS_wd_wbuffer[Unit][0].buffer, pBuffer, 512);
  246.   _FS_wd_wbuffer[Unit][0].block = Sector;
  247.   return x;
  248. }
  249. /*********************************************************************
  250. *
  251. *             _FS_WD_DevIoCtl
  252. *
  253.   Description:
  254.   FS driver function. Execute device command.
  255.   Parameters:
  256.   Unit        - Unit number.
  257.   Cmd         - Command to be executed.
  258.   Aux         - Parameter depending on command.
  259.   pBuffer     - Pointer to a buffer used for the command.
  260.  
  261.   Return value:
  262.   Command specific. In general a negative value means an error.
  263. */
  264. static int _FS_WD_DevIoCtl(FS_u32 Unit, FS_i32 Cmd, FS_i32 Aux, void *pBuffer) {
  265.   FS_u32 *info;
  266.   DWORD bytenum;
  267.   BOOL success;
  268.   int i;
  269.   int x;
  270.   int lexp;
  271.   x = 0;
  272.   if (Cmd == FS_CMD_FLUSH_CACHE) {
  273.     if (_online[Unit]) {
  274.       i = 0;
  275.       while (i < FS_WD_WBUFFNUM) {
  276.         if (_FS_wd_wbuffer[Unit][i].block != -1) {
  277.           SetFilePointer(_hdrive[Unit], _FS_wd_wbuffer[Unit][i].block * 512, 0, FILE_BEGIN);
  278.           success = WriteFile(_hdrive[Unit], _FS_wd_wbuffer[Unit][i].buffer, 512, &bytenum, NULL);
  279.           if (!success) {
  280.             x = -1;
  281.           }
  282.           _FS_wd_wbuffer[Unit][i].block = -1;
  283.         }
  284.         i++;
  285.       }
  286.       CloseHandle(_hdrive[Unit]);
  287.       _online[Unit] = 0;
  288.     }
  289.   }
  290.   else if (Cmd == FS_CMD_GET_DEVINFO)  {
  291.     if (!pBuffer) {
  292.       return -1;
  293.     }
  294.     if (!_online[Unit]) {
  295.       if (Unit == 0) {
  296.         _hdrive[Unit] = CreateFile(FS_WD_DEV0NAME, 
  297.                             GENERIC_READ | GENERIC_WRITE,
  298.                             FILE_SHARE_READ | FILE_SHARE_WRITE,
  299.                             NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  300.                             NULL);
  301.       }
  302.       else {
  303.         _hdrive[Unit] = CreateFile(FS_WD_DEV1NAME, 
  304.                             GENERIC_READ | GENERIC_WRITE,
  305.                             FILE_SHARE_READ | FILE_SHARE_WRITE,
  306.                             NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  307.                             NULL);
  308.       }
  309.     }
  310.     SetFilePointer(_hdrive[Unit], 0, 0, FILE_BEGIN);
  311.     success = ReadFile(_hdrive[Unit], _workbuffer, 512, &bytenum, NULL);
  312.     lexp = !success;
  313.     lexp = lexp || (_workbuffer[510] != 0x55);
  314.     lexp = lexp || (_workbuffer[511] != 0xaa);
  315.     if (lexp) {
  316.       if (!_online[Unit]) {
  317.         CloseHandle(_hdrive[Unit]);
  318.       }
  319.       return -1;
  320.     }
  321.     info = pBuffer;
  322.     /* hidden */
  323.     *info = (FS_u32)_workbuffer[28] + 0x100UL * _workbuffer[29] + 0x10000UL * _workbuffer[30] + 0x1000000UL * _workbuffer[31];
  324.     info++;
  325.     /* headnum */
  326.     *info = (FS_u32)_workbuffer[26] + 0x100UL * _workbuffer[27];
  327.     info++;
  328.     /* secpertrk */
  329.     *info = (FS_u32)_workbuffer[24] + 0x100UL * _workbuffer[25];
  330.     info++;
  331.     /* total sectors */
  332.     *info = (FS_u32)_workbuffer[32] + 0x100UL * _workbuffer[33] + 0x10000UL * _workbuffer[34] + 0x1000000UL * _workbuffer[35]
  333.             + _workbuffer[19] + 0x100UL * _workbuffer[20];
  334.     if (!_online[Unit]) {
  335.       CloseHandle(_hdrive[Unit]);
  336.     }
  337.   }
  338.   return x;
  339. }
  340. /*********************************************************************
  341. *
  342. *             Global variables        
  343. *
  344. **********************************************************************
  345. */
  346. const FS__device_type FS__windrive_driver = {
  347.   "Windrive driver",
  348.   _FS_WD_DevStatus,
  349.   _FS_WD_DevRead,
  350.   _FS_WD_DevWrite,
  351.   _FS_WD_DevIoCtl
  352. };
  353. #endif /* FS_USE_WINDRIVE_DRIVER */