Fat.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. /** @file
  2. Fat File System driver routines that support EFI driver model.
  3. Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "Fat.h"
  7. /**
  8. Register Driver Binding protocol for this driver.
  9. @param ImageHandle - Handle for the image of this driver.
  10. @param SystemTable - Pointer to the EFI System Table.
  11. @retval EFI_SUCCESS - Driver loaded.
  12. @return other - Driver not loaded.
  13. **/
  14. EFI_STATUS
  15. EFIAPI
  16. FatEntryPoint (
  17. IN EFI_HANDLE ImageHandle,
  18. IN EFI_SYSTEM_TABLE *SystemTable
  19. );
  20. /**
  21. Unload function for this image. Uninstall DriverBinding protocol.
  22. @param ImageHandle - Handle for the image of this driver.
  23. @retval EFI_SUCCESS - Driver unloaded successfully.
  24. @return other - Driver can not unloaded.
  25. **/
  26. EFI_STATUS
  27. EFIAPI
  28. FatUnload (
  29. IN EFI_HANDLE ImageHandle
  30. );
  31. /**
  32. Test to see if this driver can add a file system to ControllerHandle.
  33. ControllerHandle must support both Disk IO and Block IO protocols.
  34. @param This - Protocol instance pointer.
  35. @param ControllerHandle - Handle of device to test.
  36. @param RemainingDevicePath - Not used.
  37. @retval EFI_SUCCESS - This driver supports this device.
  38. @retval EFI_ALREADY_STARTED - This driver is already running on this device.
  39. @return other - This driver does not support this device.
  40. **/
  41. EFI_STATUS
  42. EFIAPI
  43. FatDriverBindingSupported (
  44. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  45. IN EFI_HANDLE Controller,
  46. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  47. );
  48. /**
  49. Start this driver on ControllerHandle by opening a Block IO and Disk IO
  50. protocol, reading Device Path. Add a Simple File System protocol to
  51. ControllerHandle if the media contains a valid file system.
  52. @param This - Protocol instance pointer.
  53. @param ControllerHandle - Handle of device to bind driver to.
  54. @param RemainingDevicePath - Not used.
  55. @retval EFI_SUCCESS - This driver is added to DeviceHandle.
  56. @retval EFI_ALREADY_STARTED - This driver is already running on DeviceHandle.
  57. @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory.
  58. @return other - This driver does not support this device.
  59. **/
  60. EFI_STATUS
  61. EFIAPI
  62. FatDriverBindingStart (
  63. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  64. IN EFI_HANDLE Controller,
  65. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  66. );
  67. /**
  68. Stop this driver on ControllerHandle.
  69. @param This - Protocol instance pointer.
  70. @param ControllerHandle - Handle of device to stop driver on.
  71. @param NumberOfChildren - Not used.
  72. @param ChildHandleBuffer - Not used.
  73. @retval EFI_SUCCESS - This driver is removed DeviceHandle.
  74. @return other - This driver was not removed from this device.
  75. **/
  76. EFI_STATUS
  77. EFIAPI
  78. FatDriverBindingStop (
  79. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  80. IN EFI_HANDLE Controller,
  81. IN UINTN NumberOfChildren,
  82. IN EFI_HANDLE *ChildHandleBuffer
  83. );
  84. //
  85. // DriverBinding protocol instance
  86. //
  87. EFI_DRIVER_BINDING_PROTOCOL gFatDriverBinding = {
  88. FatDriverBindingSupported,
  89. FatDriverBindingStart,
  90. FatDriverBindingStop,
  91. 0xa,
  92. NULL,
  93. NULL
  94. };
  95. /**
  96. Register Driver Binding protocol for this driver.
  97. @param ImageHandle - Handle for the image of this driver.
  98. @param SystemTable - Pointer to the EFI System Table.
  99. @retval EFI_SUCCESS - Driver loaded.
  100. @return other - Driver not loaded.
  101. **/
  102. EFI_STATUS
  103. EFIAPI
  104. FatEntryPoint (
  105. IN EFI_HANDLE ImageHandle,
  106. IN EFI_SYSTEM_TABLE *SystemTable
  107. )
  108. {
  109. EFI_STATUS Status;
  110. //
  111. // Initialize the EFI Driver Library
  112. //
  113. Status = EfiLibInstallDriverBindingComponentName2 (
  114. ImageHandle,
  115. SystemTable,
  116. &gFatDriverBinding,
  117. ImageHandle,
  118. &gFatComponentName,
  119. &gFatComponentName2
  120. );
  121. ASSERT_EFI_ERROR (Status);
  122. return Status;
  123. }
  124. /**
  125. Unload function for this image. Uninstall DriverBinding protocol.
  126. @param ImageHandle - Handle for the image of this driver.
  127. @retval EFI_SUCCESS - Driver unloaded successfully.
  128. @return other - Driver can not unloaded.
  129. **/
  130. EFI_STATUS
  131. EFIAPI
  132. FatUnload (
  133. IN EFI_HANDLE ImageHandle
  134. )
  135. {
  136. EFI_STATUS Status;
  137. EFI_HANDLE *DeviceHandleBuffer;
  138. UINTN DeviceHandleCount;
  139. UINTN Index;
  140. VOID *ComponentName;
  141. VOID *ComponentName2;
  142. Status = gBS->LocateHandleBuffer (
  143. AllHandles,
  144. NULL,
  145. NULL,
  146. &DeviceHandleCount,
  147. &DeviceHandleBuffer
  148. );
  149. if (EFI_ERROR (Status)) {
  150. return Status;
  151. }
  152. for (Index = 0; Index < DeviceHandleCount; Index++) {
  153. Status = EfiTestManagedDevice (DeviceHandleBuffer[Index], ImageHandle, &gEfiDiskIoProtocolGuid);
  154. if (!EFI_ERROR (Status)) {
  155. Status = gBS->DisconnectController (
  156. DeviceHandleBuffer[Index],
  157. ImageHandle,
  158. NULL
  159. );
  160. if (EFI_ERROR (Status)) {
  161. break;
  162. }
  163. }
  164. }
  165. if (Index == DeviceHandleCount) {
  166. //
  167. // Driver is stopped successfully.
  168. //
  169. Status = gBS->HandleProtocol (ImageHandle, &gEfiComponentNameProtocolGuid, &ComponentName);
  170. if (EFI_ERROR (Status)) {
  171. ComponentName = NULL;
  172. }
  173. Status = gBS->HandleProtocol (ImageHandle, &gEfiComponentName2ProtocolGuid, &ComponentName2);
  174. if (EFI_ERROR (Status)) {
  175. ComponentName2 = NULL;
  176. }
  177. if (ComponentName == NULL) {
  178. if (ComponentName2 == NULL) {
  179. Status = gBS->UninstallMultipleProtocolInterfaces (
  180. ImageHandle,
  181. &gEfiDriverBindingProtocolGuid, &gFatDriverBinding,
  182. NULL
  183. );
  184. } else {
  185. Status = gBS->UninstallMultipleProtocolInterfaces (
  186. ImageHandle,
  187. &gEfiDriverBindingProtocolGuid, &gFatDriverBinding,
  188. &gEfiComponentName2ProtocolGuid, ComponentName2,
  189. NULL
  190. );
  191. }
  192. } else {
  193. if (ComponentName2 == NULL) {
  194. Status = gBS->UninstallMultipleProtocolInterfaces (
  195. ImageHandle,
  196. &gEfiDriverBindingProtocolGuid, &gFatDriverBinding,
  197. &gEfiComponentNameProtocolGuid, ComponentName,
  198. NULL
  199. );
  200. } else {
  201. Status = gBS->UninstallMultipleProtocolInterfaces (
  202. ImageHandle,
  203. &gEfiDriverBindingProtocolGuid, &gFatDriverBinding,
  204. &gEfiComponentNameProtocolGuid, ComponentName,
  205. &gEfiComponentName2ProtocolGuid, ComponentName2,
  206. NULL
  207. );
  208. }
  209. }
  210. }
  211. if (DeviceHandleBuffer != NULL) {
  212. FreePool (DeviceHandleBuffer);
  213. }
  214. return Status;
  215. }
  216. /**
  217. Test to see if this driver can add a file system to ControllerHandle.
  218. ControllerHandle must support both Disk IO and Block IO protocols.
  219. @param This - Protocol instance pointer.
  220. @param ControllerHandle - Handle of device to test.
  221. @param RemainingDevicePath - Not used.
  222. @retval EFI_SUCCESS - This driver supports this device.
  223. @retval EFI_ALREADY_STARTED - This driver is already running on this device.
  224. @return other - This driver does not support this device.
  225. **/
  226. EFI_STATUS
  227. EFIAPI
  228. FatDriverBindingSupported (
  229. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  230. IN EFI_HANDLE ControllerHandle,
  231. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  232. )
  233. {
  234. EFI_STATUS Status;
  235. EFI_DISK_IO_PROTOCOL *DiskIo;
  236. //
  237. // Open the IO Abstraction(s) needed to perform the supported test
  238. //
  239. Status = gBS->OpenProtocol (
  240. ControllerHandle,
  241. &gEfiDiskIoProtocolGuid,
  242. (VOID **) &DiskIo,
  243. This->DriverBindingHandle,
  244. ControllerHandle,
  245. EFI_OPEN_PROTOCOL_BY_DRIVER
  246. );
  247. if (EFI_ERROR (Status)) {
  248. return Status;
  249. }
  250. //
  251. // Close the I/O Abstraction(s) used to perform the supported test
  252. //
  253. gBS->CloseProtocol (
  254. ControllerHandle,
  255. &gEfiDiskIoProtocolGuid,
  256. This->DriverBindingHandle,
  257. ControllerHandle
  258. );
  259. //
  260. // Open the IO Abstraction(s) needed to perform the supported test
  261. //
  262. Status = gBS->OpenProtocol (
  263. ControllerHandle,
  264. &gEfiBlockIoProtocolGuid,
  265. NULL,
  266. This->DriverBindingHandle,
  267. ControllerHandle,
  268. EFI_OPEN_PROTOCOL_TEST_PROTOCOL
  269. );
  270. return Status;
  271. }
  272. /**
  273. Start this driver on ControllerHandle by opening a Block IO and Disk IO
  274. protocol, reading Device Path. Add a Simple File System protocol to
  275. ControllerHandle if the media contains a valid file system.
  276. @param This - Protocol instance pointer.
  277. @param ControllerHandle - Handle of device to bind driver to.
  278. @param RemainingDevicePath - Not used.
  279. @retval EFI_SUCCESS - This driver is added to DeviceHandle.
  280. @retval EFI_ALREADY_STARTED - This driver is already running on DeviceHandle.
  281. @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory.
  282. @return other - This driver does not support this device.
  283. **/
  284. EFI_STATUS
  285. EFIAPI
  286. FatDriverBindingStart (
  287. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  288. IN EFI_HANDLE ControllerHandle,
  289. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  290. )
  291. {
  292. EFI_STATUS Status;
  293. EFI_BLOCK_IO_PROTOCOL *BlockIo;
  294. EFI_DISK_IO_PROTOCOL *DiskIo;
  295. EFI_DISK_IO2_PROTOCOL *DiskIo2;
  296. BOOLEAN LockedByMe;
  297. LockedByMe = FALSE;
  298. //
  299. // Acquire the lock.
  300. // If caller has already acquired the lock, cannot lock it again.
  301. //
  302. Status = FatAcquireLockOrFail ();
  303. if (!EFI_ERROR (Status)) {
  304. LockedByMe = TRUE;
  305. }
  306. Status = InitializeUnicodeCollationSupport (This->DriverBindingHandle);
  307. if (EFI_ERROR (Status)) {
  308. goto Exit;
  309. }
  310. //
  311. // Open our required BlockIo and DiskIo
  312. //
  313. Status = gBS->OpenProtocol (
  314. ControllerHandle,
  315. &gEfiBlockIoProtocolGuid,
  316. (VOID **) &BlockIo,
  317. This->DriverBindingHandle,
  318. ControllerHandle,
  319. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  320. );
  321. if (EFI_ERROR (Status)) {
  322. goto Exit;
  323. }
  324. Status = gBS->OpenProtocol (
  325. ControllerHandle,
  326. &gEfiDiskIoProtocolGuid,
  327. (VOID **) &DiskIo,
  328. This->DriverBindingHandle,
  329. ControllerHandle,
  330. EFI_OPEN_PROTOCOL_BY_DRIVER
  331. );
  332. if (EFI_ERROR (Status)) {
  333. goto Exit;
  334. }
  335. Status = gBS->OpenProtocol (
  336. ControllerHandle,
  337. &gEfiDiskIo2ProtocolGuid,
  338. (VOID **) &DiskIo2,
  339. This->DriverBindingHandle,
  340. ControllerHandle,
  341. EFI_OPEN_PROTOCOL_BY_DRIVER
  342. );
  343. if (EFI_ERROR (Status)) {
  344. DiskIo2 = NULL;
  345. }
  346. //
  347. // Allocate Volume structure. In FatAllocateVolume(), Resources
  348. // are allocated with protocol installed and cached initialized
  349. //
  350. Status = FatAllocateVolume (ControllerHandle, DiskIo, DiskIo2, BlockIo);
  351. //
  352. // When the media changes on a device it will Reinstall the BlockIo interaface.
  353. // This will cause a call to our Stop(), and a subsequent reentrant call to our
  354. // Start() successfully. We should leave the device open when this happen.
  355. //
  356. if (EFI_ERROR (Status)) {
  357. Status = gBS->OpenProtocol (
  358. ControllerHandle,
  359. &gEfiSimpleFileSystemProtocolGuid,
  360. NULL,
  361. This->DriverBindingHandle,
  362. ControllerHandle,
  363. EFI_OPEN_PROTOCOL_TEST_PROTOCOL
  364. );
  365. if (EFI_ERROR (Status)) {
  366. gBS->CloseProtocol (
  367. ControllerHandle,
  368. &gEfiDiskIoProtocolGuid,
  369. This->DriverBindingHandle,
  370. ControllerHandle
  371. );
  372. gBS->CloseProtocol (
  373. ControllerHandle,
  374. &gEfiDiskIo2ProtocolGuid,
  375. This->DriverBindingHandle,
  376. ControllerHandle
  377. );
  378. }
  379. }
  380. Exit:
  381. //
  382. // Unlock if locked by myself.
  383. //
  384. if (LockedByMe) {
  385. FatReleaseLock ();
  386. }
  387. return Status;
  388. }
  389. /**
  390. Stop this driver on ControllerHandle.
  391. @param This - Protocol instance pointer.
  392. @param ControllerHandle - Handle of device to stop driver on.
  393. @param NumberOfChildren - Not used.
  394. @param ChildHandleBuffer - Not used.
  395. @retval EFI_SUCCESS - This driver is removed DeviceHandle.
  396. @return other - This driver was not removed from this device.
  397. **/
  398. EFI_STATUS
  399. EFIAPI
  400. FatDriverBindingStop (
  401. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  402. IN EFI_HANDLE ControllerHandle,
  403. IN UINTN NumberOfChildren,
  404. IN EFI_HANDLE *ChildHandleBuffer
  405. )
  406. {
  407. EFI_STATUS Status;
  408. EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
  409. FAT_VOLUME *Volume;
  410. EFI_DISK_IO2_PROTOCOL *DiskIo2;
  411. DiskIo2 = NULL;
  412. //
  413. // Get our context back
  414. //
  415. Status = gBS->OpenProtocol (
  416. ControllerHandle,
  417. &gEfiSimpleFileSystemProtocolGuid,
  418. (VOID **) &FileSystem,
  419. This->DriverBindingHandle,
  420. ControllerHandle,
  421. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  422. );
  423. if (!EFI_ERROR (Status)) {
  424. Volume = VOLUME_FROM_VOL_INTERFACE (FileSystem);
  425. DiskIo2 = Volume->DiskIo2;
  426. Status = FatAbandonVolume (Volume);
  427. }
  428. if (!EFI_ERROR (Status)) {
  429. if (DiskIo2 != NULL) {
  430. Status = gBS->CloseProtocol (
  431. ControllerHandle,
  432. &gEfiDiskIo2ProtocolGuid,
  433. This->DriverBindingHandle,
  434. ControllerHandle
  435. );
  436. ASSERT_EFI_ERROR (Status);
  437. }
  438. Status = gBS->CloseProtocol (
  439. ControllerHandle,
  440. &gEfiDiskIoProtocolGuid,
  441. This->DriverBindingHandle,
  442. ControllerHandle
  443. );
  444. ASSERT_EFI_ERROR (Status);
  445. }
  446. return Status;
  447. }