]> git.proxmox.com Git - mirror_edk2.git/blob - FatPkg/EnhancedFatDxe/Fat.c
0dcb3bcb432b6234a3ebf7c2c06b08320151954a
[mirror_edk2.git] / FatPkg / EnhancedFatDxe / Fat.c
1 /*++
2
3 Copyright (c) 2005 - 2013, 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
144 Status = gBS->LocateHandleBuffer (
145 AllHandles,
146 NULL,
147 NULL,
148 &DeviceHandleCount,
149 &DeviceHandleBuffer
150 );
151 if (!EFI_ERROR (Status)) {
152 for (Index = 0; Index < DeviceHandleCount; Index++) {
153 Status = gBS->DisconnectController (
154 DeviceHandleBuffer[Index],
155 ImageHandle,
156 NULL
157 );
158 }
159
160 if (DeviceHandleBuffer != NULL) {
161 FreePool (DeviceHandleBuffer);
162 }
163 }
164
165 return Status;
166 }
167
168 EFI_STATUS
169 EFIAPI
170 FatDriverBindingSupported (
171 IN EFI_DRIVER_BINDING_PROTOCOL *This,
172 IN EFI_HANDLE ControllerHandle,
173 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
174 )
175 /*++
176
177 Routine Description:
178
179 Test to see if this driver can add a file system to ControllerHandle.
180 ControllerHandle must support both Disk IO and Block IO protocols.
181
182 Arguments:
183
184 This - Protocol instance pointer.
185 ControllerHandle - Handle of device to test.
186 RemainingDevicePath - Not used.
187
188 Returns:
189
190 EFI_SUCCESS - This driver supports this device.
191 EFI_ALREADY_STARTED - This driver is already running on this device.
192 other - This driver does not support this device.
193
194 --*/
195 {
196 EFI_STATUS Status;
197 EFI_DISK_IO_PROTOCOL *DiskIo;
198
199 //
200 // Open the IO Abstraction(s) needed to perform the supported test
201 //
202 Status = gBS->OpenProtocol (
203 ControllerHandle,
204 &gEfiDiskIoProtocolGuid,
205 (VOID **) &DiskIo,
206 This->DriverBindingHandle,
207 ControllerHandle,
208 EFI_OPEN_PROTOCOL_BY_DRIVER
209 );
210
211 if (EFI_ERROR (Status)) {
212 return Status;
213 }
214 //
215 // Close the I/O Abstraction(s) used to perform the supported test
216 //
217 gBS->CloseProtocol (
218 ControllerHandle,
219 &gEfiDiskIoProtocolGuid,
220 This->DriverBindingHandle,
221 ControllerHandle
222 );
223
224 //
225 // Open the IO Abstraction(s) needed to perform the supported test
226 //
227 Status = gBS->OpenProtocol (
228 ControllerHandle,
229 &gEfiBlockIoProtocolGuid,
230 NULL,
231 This->DriverBindingHandle,
232 ControllerHandle,
233 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
234 );
235
236 return Status;
237 }
238
239 EFI_STATUS
240 EFIAPI
241 FatDriverBindingStart (
242 IN EFI_DRIVER_BINDING_PROTOCOL *This,
243 IN EFI_HANDLE ControllerHandle,
244 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
245 )
246 /*++
247
248 Routine Description:
249
250 Start this driver on ControllerHandle by opening a Block IO and Disk IO
251 protocol, reading Device Path. Add a Simple File System protocol to
252 ControllerHandle if the media contains a valid file system.
253
254 Arguments:
255
256 This - Protocol instance pointer.
257 ControllerHandle - Handle of device to bind driver to.
258 RemainingDevicePath - Not used.
259
260 Returns:
261
262 EFI_SUCCESS - This driver is added to DeviceHandle.
263 EFI_ALREADY_STARTED - This driver is already running on DeviceHandle.
264 EFI_OUT_OF_RESOURCES - Can not allocate the memory.
265 other - This driver does not support this device.
266
267 --*/
268 {
269 EFI_STATUS Status;
270 EFI_BLOCK_IO_PROTOCOL *BlockIo;
271 EFI_DISK_IO_PROTOCOL *DiskIo;
272 EFI_DISK_IO2_PROTOCOL *DiskIo2;
273 BOOLEAN LockedByMe;
274
275 LockedByMe = FALSE;
276 //
277 // Acquire the lock.
278 // If caller has already acquired the lock, cannot lock it again.
279 //
280 Status = FatAcquireLockOrFail ();
281 if (!EFI_ERROR (Status)) {
282 LockedByMe = TRUE;
283 }
284
285 Status = InitializeUnicodeCollationSupport (This->DriverBindingHandle);
286 if (EFI_ERROR (Status)) {
287 goto Exit;
288 }
289 //
290 // Open our required BlockIo and DiskIo
291 //
292 Status = gBS->OpenProtocol (
293 ControllerHandle,
294 &gEfiBlockIoProtocolGuid,
295 (VOID **) &BlockIo,
296 This->DriverBindingHandle,
297 ControllerHandle,
298 EFI_OPEN_PROTOCOL_GET_PROTOCOL
299 );
300 if (EFI_ERROR (Status)) {
301 goto Exit;
302 }
303
304 Status = gBS->OpenProtocol (
305 ControllerHandle,
306 &gEfiDiskIoProtocolGuid,
307 (VOID **) &DiskIo,
308 This->DriverBindingHandle,
309 ControllerHandle,
310 EFI_OPEN_PROTOCOL_BY_DRIVER
311 );
312 if (EFI_ERROR (Status)) {
313 goto Exit;
314 }
315
316 Status = gBS->OpenProtocol (
317 ControllerHandle,
318 &gEfiDiskIo2ProtocolGuid,
319 (VOID **) &DiskIo2,
320 This->DriverBindingHandle,
321 ControllerHandle,
322 EFI_OPEN_PROTOCOL_BY_DRIVER
323 );
324 if (EFI_ERROR (Status)) {
325 DiskIo2 = NULL;
326 }
327
328 //
329 // Allocate Volume structure. In FatAllocateVolume(), Resources
330 // are allocated with protocol installed and cached initialized
331 //
332 Status = FatAllocateVolume (ControllerHandle, DiskIo, DiskIo2, BlockIo);
333
334 //
335 // When the media changes on a device it will Reinstall the BlockIo interaface.
336 // This will cause a call to our Stop(), and a subsequent reentrant call to our
337 // Start() successfully. We should leave the device open when this happen.
338 //
339 if (EFI_ERROR (Status)) {
340 Status = gBS->OpenProtocol (
341 ControllerHandle,
342 &gEfiSimpleFileSystemProtocolGuid,
343 NULL,
344 This->DriverBindingHandle,
345 ControllerHandle,
346 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
347 );
348 if (EFI_ERROR (Status)) {
349 gBS->CloseProtocol (
350 ControllerHandle,
351 &gEfiDiskIoProtocolGuid,
352 This->DriverBindingHandle,
353 ControllerHandle
354 );
355 gBS->CloseProtocol (
356 ControllerHandle,
357 &gEfiDiskIo2ProtocolGuid,
358 This->DriverBindingHandle,
359 ControllerHandle
360 );
361 }
362 }
363
364 Exit:
365 //
366 // Unlock if locked by myself.
367 //
368 if (LockedByMe) {
369 FatReleaseLock ();
370 }
371 return Status;
372 }
373
374 EFI_STATUS
375 EFIAPI
376 FatDriverBindingStop (
377 IN EFI_DRIVER_BINDING_PROTOCOL *This,
378 IN EFI_HANDLE ControllerHandle,
379 IN UINTN NumberOfChildren,
380 IN EFI_HANDLE *ChildHandleBuffer
381 )
382 /*++
383
384 Routine Description:
385 Stop this driver on ControllerHandle.
386
387 Arguments:
388 This - Protocol instance pointer.
389 ControllerHandle - Handle of device to stop driver on.
390 NumberOfChildren - Not used.
391 ChildHandleBuffer - Not used.
392
393 Returns:
394 EFI_SUCCESS - This driver is removed DeviceHandle.
395 other - This driver was not removed from this device.
396
397 --*/
398 {
399 EFI_STATUS Status;
400 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
401 FAT_VOLUME *Volume;
402 EFI_DISK_IO2_PROTOCOL *DiskIo2;
403
404 DiskIo2 = NULL;
405 //
406 // Get our context back
407 //
408 Status = gBS->OpenProtocol (
409 ControllerHandle,
410 &gEfiSimpleFileSystemProtocolGuid,
411 (VOID **) &FileSystem,
412 This->DriverBindingHandle,
413 ControllerHandle,
414 EFI_OPEN_PROTOCOL_GET_PROTOCOL
415 );
416
417 if (!EFI_ERROR (Status)) {
418 Volume = VOLUME_FROM_VOL_INTERFACE (FileSystem);
419 DiskIo2 = Volume->DiskIo2;
420 Status = FatAbandonVolume (Volume);
421 }
422
423 if (!EFI_ERROR (Status)) {
424 if (DiskIo2 != NULL) {
425 Status = gBS->CloseProtocol (
426 ControllerHandle,
427 &gEfiDiskIo2ProtocolGuid,
428 This->DriverBindingHandle,
429 ControllerHandle
430 );
431 ASSERT_EFI_ERROR (Status);
432 }
433 Status = gBS->CloseProtocol (
434 ControllerHandle,
435 &gEfiDiskIoProtocolGuid,
436 This->DriverBindingHandle,
437 ControllerHandle
438 );
439 ASSERT_EFI_ERROR (Status);
440 }
441
442 return Status;
443 }