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