Fat.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  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,
  182. &gFatDriverBinding,
  183. NULL
  184. );
  185. } else {
  186. Status = gBS->UninstallMultipleProtocolInterfaces (
  187. ImageHandle,
  188. &gEfiDriverBindingProtocolGuid,
  189. &gFatDriverBinding,
  190. &gEfiComponentName2ProtocolGuid,
  191. ComponentName2,
  192. NULL
  193. );
  194. }
  195. } else {
  196. if (ComponentName2 == NULL) {
  197. Status = gBS->UninstallMultipleProtocolInterfaces (
  198. ImageHandle,
  199. &gEfiDriverBindingProtocolGuid,
  200. &gFatDriverBinding,
  201. &gEfiComponentNameProtocolGuid,
  202. ComponentName,
  203. NULL
  204. );
  205. } else {
  206. Status = gBS->UninstallMultipleProtocolInterfaces (
  207. ImageHandle,
  208. &gEfiDriverBindingProtocolGuid,
  209. &gFatDriverBinding,
  210. &gEfiComponentNameProtocolGuid,
  211. ComponentName,
  212. &gEfiComponentName2ProtocolGuid,
  213. ComponentName2,
  214. NULL
  215. );
  216. }
  217. }
  218. }
  219. if (DeviceHandleBuffer != NULL) {
  220. FreePool (DeviceHandleBuffer);
  221. }
  222. return Status;
  223. }
  224. /**
  225. Test to see if this driver can add a file system to ControllerHandle.
  226. ControllerHandle must support both Disk IO and Block IO protocols.
  227. @param This - Protocol instance pointer.
  228. @param ControllerHandle - Handle of device to test.
  229. @param RemainingDevicePath - Not used.
  230. @retval EFI_SUCCESS - This driver supports this device.
  231. @retval EFI_ALREADY_STARTED - This driver is already running on this device.
  232. @return other - This driver does not support this device.
  233. **/
  234. EFI_STATUS
  235. EFIAPI
  236. FatDriverBindingSupported (
  237. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  238. IN EFI_HANDLE ControllerHandle,
  239. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  240. )
  241. {
  242. EFI_STATUS Status;
  243. EFI_DISK_IO_PROTOCOL *DiskIo;
  244. //
  245. // Open the IO Abstraction(s) needed to perform the supported test
  246. //
  247. Status = gBS->OpenProtocol (
  248. ControllerHandle,
  249. &gEfiDiskIoProtocolGuid,
  250. (VOID **)&DiskIo,
  251. This->DriverBindingHandle,
  252. ControllerHandle,
  253. EFI_OPEN_PROTOCOL_BY_DRIVER
  254. );
  255. if (EFI_ERROR (Status)) {
  256. return Status;
  257. }
  258. //
  259. // Close the I/O Abstraction(s) used to perform the supported test
  260. //
  261. gBS->CloseProtocol (
  262. ControllerHandle,
  263. &gEfiDiskIoProtocolGuid,
  264. This->DriverBindingHandle,
  265. ControllerHandle
  266. );
  267. //
  268. // Open the IO Abstraction(s) needed to perform the supported test
  269. //
  270. Status = gBS->OpenProtocol (
  271. ControllerHandle,
  272. &gEfiBlockIoProtocolGuid,
  273. NULL,
  274. This->DriverBindingHandle,
  275. ControllerHandle,
  276. EFI_OPEN_PROTOCOL_TEST_PROTOCOL
  277. );
  278. return Status;
  279. }
  280. /**
  281. Start this driver on ControllerHandle by opening a Block IO and Disk IO
  282. protocol, reading Device Path. Add a Simple File System protocol to
  283. ControllerHandle if the media contains a valid file system.
  284. @param This - Protocol instance pointer.
  285. @param ControllerHandle - Handle of device to bind driver to.
  286. @param RemainingDevicePath - Not used.
  287. @retval EFI_SUCCESS - This driver is added to DeviceHandle.
  288. @retval EFI_ALREADY_STARTED - This driver is already running on DeviceHandle.
  289. @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory.
  290. @return other - This driver does not support this device.
  291. **/
  292. EFI_STATUS
  293. EFIAPI
  294. FatDriverBindingStart (
  295. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  296. IN EFI_HANDLE ControllerHandle,
  297. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  298. )
  299. {
  300. EFI_STATUS Status;
  301. EFI_BLOCK_IO_PROTOCOL *BlockIo;
  302. EFI_DISK_IO_PROTOCOL *DiskIo;
  303. EFI_DISK_IO2_PROTOCOL *DiskIo2;
  304. BOOLEAN LockedByMe;
  305. LockedByMe = FALSE;
  306. //
  307. // Acquire the lock.
  308. // If caller has already acquired the lock, cannot lock it again.
  309. //
  310. Status = FatAcquireLockOrFail ();
  311. if (!EFI_ERROR (Status)) {
  312. LockedByMe = TRUE;
  313. }
  314. Status = InitializeUnicodeCollationSupport (This->DriverBindingHandle);
  315. if (EFI_ERROR (Status)) {
  316. goto Exit;
  317. }
  318. //
  319. // Open our required BlockIo and DiskIo
  320. //
  321. Status = gBS->OpenProtocol (
  322. ControllerHandle,
  323. &gEfiBlockIoProtocolGuid,
  324. (VOID **)&BlockIo,
  325. This->DriverBindingHandle,
  326. ControllerHandle,
  327. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  328. );
  329. if (EFI_ERROR (Status)) {
  330. goto Exit;
  331. }
  332. Status = gBS->OpenProtocol (
  333. ControllerHandle,
  334. &gEfiDiskIoProtocolGuid,
  335. (VOID **)&DiskIo,
  336. This->DriverBindingHandle,
  337. ControllerHandle,
  338. EFI_OPEN_PROTOCOL_BY_DRIVER
  339. );
  340. if (EFI_ERROR (Status)) {
  341. goto Exit;
  342. }
  343. Status = gBS->OpenProtocol (
  344. ControllerHandle,
  345. &gEfiDiskIo2ProtocolGuid,
  346. (VOID **)&DiskIo2,
  347. This->DriverBindingHandle,
  348. ControllerHandle,
  349. EFI_OPEN_PROTOCOL_BY_DRIVER
  350. );
  351. if (EFI_ERROR (Status)) {
  352. DiskIo2 = NULL;
  353. }
  354. //
  355. // Allocate Volume structure. In FatAllocateVolume(), Resources
  356. // are allocated with protocol installed and cached initialized
  357. //
  358. Status = FatAllocateVolume (ControllerHandle, DiskIo, DiskIo2, BlockIo);
  359. //
  360. // When the media changes on a device it will Reinstall the BlockIo interface.
  361. // This will cause a call to our Stop(), and a subsequent reentrant call to our
  362. // Start() successfully. We should leave the device open when this happen.
  363. //
  364. if (EFI_ERROR (Status)) {
  365. Status = gBS->OpenProtocol (
  366. ControllerHandle,
  367. &gEfiSimpleFileSystemProtocolGuid,
  368. NULL,
  369. This->DriverBindingHandle,
  370. ControllerHandle,
  371. EFI_OPEN_PROTOCOL_TEST_PROTOCOL
  372. );
  373. if (EFI_ERROR (Status)) {
  374. gBS->CloseProtocol (
  375. ControllerHandle,
  376. &gEfiDiskIoProtocolGuid,
  377. This->DriverBindingHandle,
  378. ControllerHandle
  379. );
  380. gBS->CloseProtocol (
  381. ControllerHandle,
  382. &gEfiDiskIo2ProtocolGuid,
  383. This->DriverBindingHandle,
  384. ControllerHandle
  385. );
  386. }
  387. }
  388. Exit:
  389. //
  390. // Unlock if locked by myself.
  391. //
  392. if (LockedByMe) {
  393. FatReleaseLock ();
  394. }
  395. return Status;
  396. }
  397. /**
  398. Stop this driver on ControllerHandle.
  399. @param This - Protocol instance pointer.
  400. @param ControllerHandle - Handle of device to stop driver on.
  401. @param NumberOfChildren - Not used.
  402. @param ChildHandleBuffer - Not used.
  403. @retval EFI_SUCCESS - This driver is removed DeviceHandle.
  404. @return other - This driver was not removed from this device.
  405. **/
  406. EFI_STATUS
  407. EFIAPI
  408. FatDriverBindingStop (
  409. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  410. IN EFI_HANDLE ControllerHandle,
  411. IN UINTN NumberOfChildren,
  412. IN EFI_HANDLE *ChildHandleBuffer
  413. )
  414. {
  415. EFI_STATUS Status;
  416. EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
  417. FAT_VOLUME *Volume;
  418. EFI_DISK_IO2_PROTOCOL *DiskIo2;
  419. DiskIo2 = NULL;
  420. //
  421. // Get our context back
  422. //
  423. Status = gBS->OpenProtocol (
  424. ControllerHandle,
  425. &gEfiSimpleFileSystemProtocolGuid,
  426. (VOID **)&FileSystem,
  427. This->DriverBindingHandle,
  428. ControllerHandle,
  429. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  430. );
  431. if (!EFI_ERROR (Status)) {
  432. Volume = VOLUME_FROM_VOL_INTERFACE (FileSystem);
  433. DiskIo2 = Volume->DiskIo2;
  434. Status = FatAbandonVolume (Volume);
  435. }
  436. if (!EFI_ERROR (Status)) {
  437. if (DiskIo2 != NULL) {
  438. Status = gBS->CloseProtocol (
  439. ControllerHandle,
  440. &gEfiDiskIo2ProtocolGuid,
  441. This->DriverBindingHandle,
  442. ControllerHandle
  443. );
  444. ASSERT_EFI_ERROR (Status);
  445. }
  446. Status = gBS->CloseProtocol (
  447. ControllerHandle,
  448. &gEfiDiskIoProtocolGuid,
  449. This->DriverBindingHandle,
  450. ControllerHandle
  451. );
  452. ASSERT_EFI_ERROR (Status);
  453. }
  454. return Status;
  455. }