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