/** Called by FatDriverBindingStop(), Abandon the volume. @param Volume - The volume to be abandoned. @retval EFI_SUCCESS - Abandoned the volume successfully. @return Others - Can not uninstall the protocol interfaces. **/ EFI_STATUS FatAbandonVolume ( IN FAT_VOLUME *Volume ) { EFI_STATUS Status; BOOLEAN LockedByMe; // // Uninstall the protocol interface. // if (Volume->Handle != NULL) { Status = gBS->UninstallMultipleProtocolInterfaces ( Volume->Handle, &gEfiSimpleFileSystemProtocolGuid, &Volume->VolumeInterface, NULL ); if (EFI_ERROR (Status)) { return Status; } } LockedByMe = FALSE; // // Acquire the lock. // If the caller has already acquired the lock (which // means we are in the process of some Fat operation), // we can not acquire again. // Status = FatAcquireLockOrFail (); if (!EFI_ERROR (Status)) { LockedByMe = TRUE; } // // The volume is still being used. Hence, set error flag for all OFiles still in // use. In two cases, we could get here. One is EFI_MEDIA_CHANGED, the other is // EFI_NO_MEDIA. // if (Volume->Root != NULL) { FatSetVolumeError ( Volume->Root, Volume->BlockIo->Media->MediaPresent ? EFI_MEDIA_CHANGED : EFI_NO_MEDIA ); } Volume->Valid = FALSE; // // Release the lock. // If locked by me, this means DriverBindingStop is NOT // called within an on-going Fat operation, so we should // take responsibility to cleanup and free the volume. // Otherwise, the DriverBindingStop is called within an on-going // Fat operation, we shouldn't check reference, so just let outer // FatCleanupVolume do the task. // if (LockedByMe) { FatCleanupVolume (Volume, NULL, EFI_SUCCESS, NULL); FatReleaseLock (); } return EFI_SUCCESS; }
EFI_STATUS EFIAPI FatDriverBindingStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) /*++ Routine Description: 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. Arguments: This - Protocol instance pointer. ControllerHandle - Handle of device to bind driver to. RemainingDevicePath - Not used. Returns: EFI_SUCCESS - This driver is added to DeviceHandle. EFI_ALREADY_STARTED - This driver is already running on DeviceHandle. EFI_OUT_OF_RESOURCES - Can not allocate the memory. other - This driver does not support this device. --*/ { EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_DISK_IO_PROTOCOL *DiskIo; 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; } // // Allocate Volume structure. In FatAllocateVolume(), Resources // are allocated with protocol installed and cached initialized // Status = FatAllocateVolume (ControllerHandle, DiskIo, 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 ); } } Exit: // // Unlock if locked by myself. // if (LockedByMe) { FatReleaseLock (); } return Status; }