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