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