usbh_msc_filex.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /***************************************************************************
  2. * Copyright (c) 2024 Microsoft Corporation
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the MIT License which is available at
  6. * https://opensource.org/licenses/MIT.
  7. *
  8. * SPDX-License-Identifier: MIT
  9. **************************************************************************/
  10. /**************************************************************************/
  11. /**************************************************************************/
  12. /** */
  13. /** FileX Component */
  14. /** */
  15. /** RAM Disk Driver */
  16. /** */
  17. /**************************************************************************/
  18. /**************************************************************************/
  19. /* Include necessary system files. */
  20. #include "fx_api.h"
  21. #include "usbh_core.h"
  22. #include "usbh_msc.h"
  23. /* The RAM driver relies on the fx_media_format call to be made prior to
  24. the fx_media_open call. The following call will format the default
  25. 32KB RAM drive, with a sector size of 128 bytes per sector.
  26. fx_media_format(&ram_disk,
  27. _fx_usbh_msc_driver, // Driver entry
  28. NULL, // RAM disk memory pointer
  29. media_memory, // Media buffer pointer
  30. sizeof(media_memory), // Media buffer size
  31. "MY_RAM_DISK", // Volume Name
  32. 2, // Number of FATs
  33. 128, // Directory Entries
  34. 0, // Hidden sectors
  35. 256, // Total sectors
  36. 128, // Sector size
  37. 1, // Sectors per cluster
  38. 1, // Heads
  39. 1); // Sectors per track
  40. */
  41. VOID _fx_usbh_msc_driver(FX_MEDIA *media_ptr);
  42. /**************************************************************************/
  43. /* */
  44. /* FUNCTION RELEASE */
  45. /* */
  46. /* _fx_ram_driver PORTABLE C */
  47. /* 6.1.5 */
  48. /* AUTHOR */
  49. /* */
  50. /* William E. Lamie, Microsoft Corporation */
  51. /* */
  52. /* DESCRIPTION */
  53. /* */
  54. /* This function is the entry point to the generic RAM disk driver */
  55. /* that is delivered with all versions of FileX. The format of the */
  56. /* RAM disk is easily modified by calling fx_media_format prior */
  57. /* to opening the media. */
  58. /* */
  59. /* This driver also serves as a template for developing FileX drivers */
  60. /* for actual devices. Simply replace the read/write sector logic with */
  61. /* calls to read/write from the appropriate physical device */
  62. /* */
  63. /* FileX RAM/FLASH structures look like the following: */
  64. /* */
  65. /* Physical Sector Contents */
  66. /* */
  67. /* 0 Boot record */
  68. /* 1 FAT Area Start */
  69. /* +FAT Sectors Root Directory Start */
  70. /* +Directory Sectors Data Sector Start */
  71. /* */
  72. /* */
  73. /* INPUT */
  74. /* */
  75. /* media_ptr Media control block pointer */
  76. /* */
  77. /* OUTPUT */
  78. /* */
  79. /* None */
  80. /* */
  81. /* CALLS */
  82. /* */
  83. /* _fx_utility_memory_copy Copy sector memory */
  84. /* _fx_utility_16_unsigned_read Read 16-bit unsigned */
  85. /* */
  86. /* CALLED BY */
  87. /* */
  88. /* FileX System Functions */
  89. /* */
  90. /* RELEASE HISTORY */
  91. /* */
  92. /* DATE NAME DESCRIPTION */
  93. /* */
  94. /* 05-19-2020 William E. Lamie Initial Version 6.0 */
  95. /* 09-30-2020 William E. Lamie Modified comment(s), */
  96. /* resulting in version 6.1 */
  97. /* 03-02-2021 William E. Lamie Modified comment(s), */
  98. /* resulting in version 6.1.5 */
  99. /* */
  100. /**************************************************************************/
  101. VOID _fx_usbh_msc_driver(FX_MEDIA *media_ptr)
  102. {
  103. struct usbh_msc *msc_class;
  104. int ret;
  105. /* There are several useful/important pieces of information contained in
  106. the media structure, some of which are supplied by FileX and others
  107. are for the driver to setup. The following is a summary of the
  108. necessary FX_MEDIA structure members:
  109. FX_MEDIA Member Meaning
  110. fx_media_driver_request FileX request type. Valid requests from
  111. FileX are as follows:
  112. FX_DRIVER_READ
  113. FX_DRIVER_WRITE
  114. FX_DRIVER_FLUSH
  115. FX_DRIVER_ABORT
  116. FX_DRIVER_INIT
  117. FX_DRIVER_BOOT_READ
  118. FX_DRIVER_RELEASE_SECTORS
  119. FX_DRIVER_BOOT_WRITE
  120. FX_DRIVER_UNINIT
  121. fx_media_driver_status This value is RETURNED by the driver.
  122. If the operation is successful, this
  123. field should be set to FX_SUCCESS for
  124. before returning. Otherwise, if an
  125. error occurred, this field should be
  126. set to FX_IO_ERROR.
  127. fx_media_driver_buffer Pointer to buffer to read or write
  128. sector data. This is supplied by
  129. FileX.
  130. fx_media_driver_logical_sector Logical sector FileX is requesting.
  131. fx_media_driver_sectors Number of sectors FileX is requesting.
  132. The following is a summary of the optional FX_MEDIA structure members:
  133. FX_MEDIA Member Meaning
  134. fx_media_driver_info Pointer to any additional information
  135. or memory. This is optional for the
  136. driver use and is setup from the
  137. fx_media_open call. The RAM disk uses
  138. this pointer for the RAM disk memory
  139. itself.
  140. fx_media_driver_write_protect The DRIVER sets this to FX_TRUE when
  141. media is write protected. This is
  142. typically done in initialization,
  143. but can be done anytime.
  144. fx_media_driver_free_sector_update The DRIVER sets this to FX_TRUE when
  145. it needs to know when clusters are
  146. released. This is important for FLASH
  147. wear-leveling drivers.
  148. fx_media_driver_system_write FileX sets this flag to FX_TRUE if the
  149. sector being written is a system sector,
  150. e.g., a boot, FAT, or directory sector.
  151. The driver may choose to use this to
  152. initiate error recovery logic for greater
  153. fault tolerance.
  154. fx_media_driver_data_sector_read FileX sets this flag to FX_TRUE if the
  155. sector(s) being read are file data sectors,
  156. i.e., NOT system sectors.
  157. fx_media_driver_sector_type FileX sets this variable to the specific
  158. type of sector being read or written. The
  159. following sector types are identified:
  160. FX_UNKNOWN_SECTOR
  161. FX_BOOT_SECTOR
  162. FX_FAT_SECTOR
  163. FX_DIRECTORY_SECTOR
  164. FX_DATA_SECTOR
  165. */
  166. /* Process the driver request specified in the media control block. */
  167. switch (media_ptr->fx_media_driver_request) {
  168. case FX_DRIVER_READ: {
  169. msc_class = (struct usbh_msc *)media_ptr->fx_media_driver_info;
  170. ret = usbh_msc_scsi_read10(msc_class, media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors, media_ptr->fx_media_driver_buffer,
  171. media_ptr->fx_media_driver_sectors);
  172. if (ret < 0) {
  173. media_ptr->fx_media_driver_status = FX_IO_ERROR;
  174. return;
  175. }
  176. /* Successful driver request. */
  177. media_ptr->fx_media_driver_status = FX_SUCCESS;
  178. break;
  179. }
  180. case FX_DRIVER_WRITE: {
  181. msc_class = (struct usbh_msc *)media_ptr->fx_media_driver_info;
  182. ret = usbh_msc_scsi_write10(msc_class, media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors,
  183. media_ptr->fx_media_driver_buffer, media_ptr->fx_media_driver_sectors);
  184. if (ret < 0) {
  185. media_ptr->fx_media_driver_status = FX_IO_ERROR;
  186. return;
  187. }
  188. /* Successful driver request. */
  189. media_ptr->fx_media_driver_status = FX_SUCCESS;
  190. break;
  191. }
  192. case FX_DRIVER_FLUSH: {
  193. /* Return driver success. */
  194. media_ptr->fx_media_driver_status = FX_SUCCESS;
  195. break;
  196. }
  197. case FX_DRIVER_ABORT: {
  198. /* Return driver success. */
  199. media_ptr->fx_media_driver_status = FX_SUCCESS;
  200. break;
  201. }
  202. case FX_DRIVER_INIT: {
  203. msc_class = usbh_find_class_instance(media_ptr->fx_media_name);
  204. if (!msc_class) {
  205. USB_LOG_ERR("No instance found for %s", media_ptr->fx_media_name);
  206. media_ptr->fx_media_driver_status = FX_MEDIA_INVALID;
  207. return;
  208. }
  209. if (usbh_msc_scsi_init(msc_class) < 0) {
  210. media_ptr->fx_media_driver_status = FX_MEDIA_INVALID;
  211. return;
  212. }
  213. media_ptr->fx_media_driver_info = msc_class;
  214. /* Successful driver request. */
  215. media_ptr->fx_media_driver_status = FX_SUCCESS;
  216. break;
  217. }
  218. case FX_DRIVER_UNINIT: {
  219. /* There is nothing to do in this case for the RAM driver. For actual
  220. devices some shutdown processing may be necessary. */
  221. /* Successful driver request. */
  222. media_ptr->fx_media_driver_status = FX_SUCCESS;
  223. break;
  224. }
  225. case FX_DRIVER_BOOT_READ: {
  226. msc_class = (struct usbh_msc *)media_ptr->fx_media_driver_info;
  227. ret = usbh_msc_scsi_read10(msc_class, 0, media_ptr->fx_media_driver_buffer, 1);
  228. if (ret < 0) {
  229. media_ptr->fx_media_driver_status = FX_IO_ERROR;
  230. return;
  231. }
  232. /* Successful driver request. */
  233. media_ptr->fx_media_driver_status = FX_SUCCESS;
  234. break;
  235. }
  236. case FX_DRIVER_BOOT_WRITE: {
  237. msc_class = (struct usbh_msc *)media_ptr->fx_media_driver_info;
  238. ret = usbh_msc_scsi_write10(msc_class, 0, media_ptr->fx_media_driver_buffer, 1);
  239. if (ret < 0) {
  240. media_ptr->fx_media_driver_status = FX_IO_ERROR;
  241. return;
  242. }
  243. /* Successful driver request. */
  244. media_ptr->fx_media_driver_status = FX_SUCCESS;
  245. break;
  246. }
  247. default: {
  248. /* Invalid driver request. */
  249. media_ptr->fx_media_driver_status = FX_IO_ERROR;
  250. break;
  251. }
  252. }
  253. }