123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525 |
- /** @file
- Fat File System driver routines that support EFI driver model.
- Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "Fat.h"
- /**
- Register Driver Binding protocol for this driver.
- @param ImageHandle - Handle for the image of this driver.
- @param SystemTable - Pointer to the EFI System Table.
- @retval EFI_SUCCESS - Driver loaded.
- @return other - Driver not loaded.
- **/
- EFI_STATUS
- EFIAPI
- FatEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
- /**
- Unload function for this image. Uninstall DriverBinding protocol.
- @param ImageHandle - Handle for the image of this driver.
- @retval EFI_SUCCESS - Driver unloaded successfully.
- @return other - Driver can not unloaded.
- **/
- EFI_STATUS
- EFIAPI
- FatUnload (
- IN EFI_HANDLE ImageHandle
- );
- /**
- Test to see if this driver can add a file system to ControllerHandle.
- ControllerHandle must support both Disk IO and Block IO protocols.
- @param This - Protocol instance pointer.
- @param ControllerHandle - Handle of device to test.
- @param RemainingDevicePath - Not used.
- @retval EFI_SUCCESS - This driver supports this device.
- @retval EFI_ALREADY_STARTED - This driver is already running on this device.
- @return other - This driver does not support this device.
- **/
- EFI_STATUS
- EFIAPI
- FatDriverBindingSupported (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- );
- /**
- Start this driver on ControllerHandle by opening a Block IO and Disk IO
- protocol, reading Device Path. Add a Simple File System protocol to
- ControllerHandle if the media contains a valid file system.
- @param This - Protocol instance pointer.
- @param ControllerHandle - Handle of device to bind driver to.
- @param RemainingDevicePath - Not used.
- @retval EFI_SUCCESS - This driver is added to DeviceHandle.
- @retval EFI_ALREADY_STARTED - This driver is already running on DeviceHandle.
- @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory.
- @return other - This driver does not support this device.
- **/
- EFI_STATUS
- EFIAPI
- FatDriverBindingStart (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- );
- /**
- Stop this driver on ControllerHandle.
- @param This - Protocol instance pointer.
- @param ControllerHandle - Handle of device to stop driver on.
- @param NumberOfChildren - Not used.
- @param ChildHandleBuffer - Not used.
- @retval EFI_SUCCESS - This driver is removed DeviceHandle.
- @return other - This driver was not removed from this device.
- **/
- EFI_STATUS
- EFIAPI
- FatDriverBindingStop (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN UINTN NumberOfChildren,
- IN EFI_HANDLE *ChildHandleBuffer
- );
- //
- // DriverBinding protocol instance
- //
- EFI_DRIVER_BINDING_PROTOCOL gFatDriverBinding = {
- FatDriverBindingSupported,
- FatDriverBindingStart,
- FatDriverBindingStop,
- 0xa,
- NULL,
- NULL
- };
- /**
- Register Driver Binding protocol for this driver.
- @param ImageHandle - Handle for the image of this driver.
- @param SystemTable - Pointer to the EFI System Table.
- @retval EFI_SUCCESS - Driver loaded.
- @return other - Driver not loaded.
- **/
- EFI_STATUS
- EFIAPI
- FatEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
- //
- // Initialize the EFI Driver Library
- //
- Status = EfiLibInstallDriverBindingComponentName2 (
- ImageHandle,
- SystemTable,
- &gFatDriverBinding,
- ImageHandle,
- &gFatComponentName,
- &gFatComponentName2
- );
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- /**
- Unload function for this image. Uninstall DriverBinding protocol.
- @param ImageHandle - Handle for the image of this driver.
- @retval EFI_SUCCESS - Driver unloaded successfully.
- @return other - Driver can not unloaded.
- **/
- EFI_STATUS
- EFIAPI
- FatUnload (
- IN EFI_HANDLE ImageHandle
- )
- {
- EFI_STATUS Status;
- EFI_HANDLE *DeviceHandleBuffer;
- UINTN DeviceHandleCount;
- UINTN Index;
- VOID *ComponentName;
- VOID *ComponentName2;
- Status = gBS->LocateHandleBuffer (
- AllHandles,
- NULL,
- NULL,
- &DeviceHandleCount,
- &DeviceHandleBuffer
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- for (Index = 0; Index < DeviceHandleCount; Index++) {
- Status = EfiTestManagedDevice (DeviceHandleBuffer[Index], ImageHandle, &gEfiDiskIoProtocolGuid);
- if (!EFI_ERROR (Status)) {
- Status = gBS->DisconnectController (
- DeviceHandleBuffer[Index],
- ImageHandle,
- NULL
- );
- if (EFI_ERROR (Status)) {
- break;
- }
- }
- }
- if (Index == DeviceHandleCount) {
- //
- // Driver is stopped successfully.
- //
- Status = gBS->HandleProtocol (ImageHandle, &gEfiComponentNameProtocolGuid, &ComponentName);
- if (EFI_ERROR (Status)) {
- ComponentName = NULL;
- }
- Status = gBS->HandleProtocol (ImageHandle, &gEfiComponentName2ProtocolGuid, &ComponentName2);
- if (EFI_ERROR (Status)) {
- ComponentName2 = NULL;
- }
- if (ComponentName == NULL) {
- if (ComponentName2 == NULL) {
- Status = gBS->UninstallMultipleProtocolInterfaces (
- ImageHandle,
- &gEfiDriverBindingProtocolGuid, &gFatDriverBinding,
- NULL
- );
- } else {
- Status = gBS->UninstallMultipleProtocolInterfaces (
- ImageHandle,
- &gEfiDriverBindingProtocolGuid, &gFatDriverBinding,
- &gEfiComponentName2ProtocolGuid, ComponentName2,
- NULL
- );
- }
- } else {
- if (ComponentName2 == NULL) {
- Status = gBS->UninstallMultipleProtocolInterfaces (
- ImageHandle,
- &gEfiDriverBindingProtocolGuid, &gFatDriverBinding,
- &gEfiComponentNameProtocolGuid, ComponentName,
- NULL
- );
- } else {
- Status = gBS->UninstallMultipleProtocolInterfaces (
- ImageHandle,
- &gEfiDriverBindingProtocolGuid, &gFatDriverBinding,
- &gEfiComponentNameProtocolGuid, ComponentName,
- &gEfiComponentName2ProtocolGuid, ComponentName2,
- NULL
- );
- }
- }
- }
- if (DeviceHandleBuffer != NULL) {
- FreePool (DeviceHandleBuffer);
- }
- return Status;
- }
- /**
- Test to see if this driver can add a file system to ControllerHandle.
- ControllerHandle must support both Disk IO and Block IO protocols.
- @param This - Protocol instance pointer.
- @param ControllerHandle - Handle of device to test.
- @param RemainingDevicePath - Not used.
- @retval EFI_SUCCESS - This driver supports this device.
- @retval EFI_ALREADY_STARTED - This driver is already running on this device.
- @return other - This driver does not support this device.
- **/
- EFI_STATUS
- EFIAPI
- FatDriverBindingSupported (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
- {
- EFI_STATUS Status;
- EFI_DISK_IO_PROTOCOL *DiskIo;
- //
- // Open the IO Abstraction(s) needed to perform the supported test
- //
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiDiskIoProtocolGuid,
- (VOID **) &DiskIo,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Close the I/O Abstraction(s) used to perform the supported test
- //
- gBS->CloseProtocol (
- ControllerHandle,
- &gEfiDiskIoProtocolGuid,
- This->DriverBindingHandle,
- ControllerHandle
- );
- //
- // Open the IO Abstraction(s) needed to perform the supported test
- //
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiBlockIoProtocolGuid,
- NULL,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL
- );
- return Status;
- }
- /**
- Start this driver on ControllerHandle by opening a Block IO and Disk IO
- protocol, reading Device Path. Add a Simple File System protocol to
- ControllerHandle if the media contains a valid file system.
- @param This - Protocol instance pointer.
- @param ControllerHandle - Handle of device to bind driver to.
- @param RemainingDevicePath - Not used.
- @retval EFI_SUCCESS - This driver is added to DeviceHandle.
- @retval EFI_ALREADY_STARTED - This driver is already running on DeviceHandle.
- @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory.
- @return other - This driver does not support this device.
- **/
- EFI_STATUS
- EFIAPI
- FatDriverBindingStart (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
- {
- EFI_STATUS Status;
- EFI_BLOCK_IO_PROTOCOL *BlockIo;
- EFI_DISK_IO_PROTOCOL *DiskIo;
- EFI_DISK_IO2_PROTOCOL *DiskIo2;
- BOOLEAN LockedByMe;
- LockedByMe = FALSE;
- //
- // Acquire the lock.
- // If caller has already acquired the lock, cannot lock it again.
- //
- Status = FatAcquireLockOrFail ();
- if (!EFI_ERROR (Status)) {
- LockedByMe = TRUE;
- }
- Status = InitializeUnicodeCollationSupport (This->DriverBindingHandle);
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
- //
- // Open our required BlockIo and DiskIo
- //
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiBlockIoProtocolGuid,
- (VOID **) &BlockIo,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiDiskIoProtocolGuid,
- (VOID **) &DiskIo,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiDiskIo2ProtocolGuid,
- (VOID **) &DiskIo2,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (Status)) {
- DiskIo2 = NULL;
- }
- //
- // Allocate Volume structure. In FatAllocateVolume(), Resources
- // are allocated with protocol installed and cached initialized
- //
- Status = FatAllocateVolume (ControllerHandle, DiskIo, DiskIo2, BlockIo);
- //
- // When the media changes on a device it will Reinstall the BlockIo interaface.
- // This will cause a call to our Stop(), and a subsequent reentrant call to our
- // Start() successfully. We should leave the device open when this happen.
- //
- if (EFI_ERROR (Status)) {
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiSimpleFileSystemProtocolGuid,
- NULL,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- gBS->CloseProtocol (
- ControllerHandle,
- &gEfiDiskIoProtocolGuid,
- This->DriverBindingHandle,
- ControllerHandle
- );
- gBS->CloseProtocol (
- ControllerHandle,
- &gEfiDiskIo2ProtocolGuid,
- This->DriverBindingHandle,
- ControllerHandle
- );
- }
- }
- Exit:
- //
- // Unlock if locked by myself.
- //
- if (LockedByMe) {
- FatReleaseLock ();
- }
- return Status;
- }
- /**
- Stop this driver on ControllerHandle.
- @param This - Protocol instance pointer.
- @param ControllerHandle - Handle of device to stop driver on.
- @param NumberOfChildren - Not used.
- @param ChildHandleBuffer - Not used.
- @retval EFI_SUCCESS - This driver is removed DeviceHandle.
- @return other - This driver was not removed from this device.
- **/
- EFI_STATUS
- EFIAPI
- FatDriverBindingStop (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN UINTN NumberOfChildren,
- IN EFI_HANDLE *ChildHandleBuffer
- )
- {
- EFI_STATUS Status;
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
- FAT_VOLUME *Volume;
- EFI_DISK_IO2_PROTOCOL *DiskIo2;
- DiskIo2 = NULL;
- //
- // Get our context back
- //
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiSimpleFileSystemProtocolGuid,
- (VOID **) &FileSystem,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (!EFI_ERROR (Status)) {
- Volume = VOLUME_FROM_VOL_INTERFACE (FileSystem);
- DiskIo2 = Volume->DiskIo2;
- Status = FatAbandonVolume (Volume);
- }
- if (!EFI_ERROR (Status)) {
- if (DiskIo2 != NULL) {
- Status = gBS->CloseProtocol (
- ControllerHandle,
- &gEfiDiskIo2ProtocolGuid,
- This->DriverBindingHandle,
- ControllerHandle
- );
- ASSERT_EFI_ERROR (Status);
- }
- Status = gBS->CloseProtocol (
- ControllerHandle,
- &gEfiDiskIoProtocolGuid,
- This->DriverBindingHandle,
- ControllerHandle
- );
- ASSERT_EFI_ERROR (Status);
- }
- return Status;
- }
|