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