VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/FatPkg/EnhancedFatDxe/Fat.c@ 77662

Last change on this file since 77662 was 77662, checked in by vboxsync, 6 years ago

EFI: First step in UDK2018 merge. Does not build yet.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette