diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c index 08ddacd39c2..3284d5fa806 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c @@ -277,34 +277,25 @@ EnumerateNvmeDevNamespace ( goto Exit; } - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - if (NVME_SUPPORT_BLOCKIO2 (Private)) { - // We have multiple data queues, so we can support the BlockIo2 protocol - Status = gBS->InstallMultipleProtocolInterfaces ( - &Device->DeviceHandle, - &gEfiBlockIo2ProtocolGuid, - &Device->BlockIo2, - NULL - ); - - if (EFI_ERROR (Status)) { - gBS->UninstallMultipleProtocolInterfaces ( - Device->DeviceHandle, - &gEfiDevicePathProtocolGuid, - Device->DevicePath, - &gEfiBlockIoProtocolGuid, - &Device->BlockIo, - &gEfiDiskInfoProtocolGuid, - &Device->DiskInfo, - NULL - ); - - DEBUG ((DEBUG_ERROR, "%a: Failed to install BlockIo2 protocol. Error %r\n", __func__, Status)); - ASSERT_EFI_ERROR (Status); - goto Exit; - } - } - + // MU_CHANGE [BEGIN] - Request Number of Queues from Controller + if (NVME_SUPPORT_BLOCKIO2 (Private)) { + // We have multiple data queues, so we can support the BlockIo2 protocol + Status = gBS->InstallMultipleProtocolInterfaces ( + &Device->DeviceHandle, + &gEfiBlockIo2ProtocolGuid, + &Device->BlockIo2, + NULL + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "%a: Failed to install BlockIo2 protocol. Error %r. Continuing with BlockIo only.\n", __func__, Status)); + Device->BlockIo2Installed = FALSE; + Status = EFI_SUCCESS; // Reset status to continue with remaining protocols + } else { + Device->BlockIo2Installed = TRUE; + } + } + // MU_CHANGE [END] - Request Number of Queues from Controller // @@ -333,17 +324,17 @@ EnumerateNvmeDevNamespace ( NULL ); - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - if (NVME_SUPPORT_BLOCKIO2 (Private)) { - // We have multiple data queues, so we need to uninstall the BlockIo2 protocol - gBS->UninstallMultipleProtocolInterfaces ( - Device->DeviceHandle, - &gEfiBlockIo2ProtocolGuid, - &Device->BlockIo2, - NULL - ); - } - + // MU_CHANGE [BEGIN] - Request Number of Queues from Controller + if (NVME_SUPPORT_BLOCKIO2 (Private) && Device->BlockIo2Installed) { + // We have multiple data queues and BlockIo2 was successfully installed, so we need to uninstall it + gBS->UninstallMultipleProtocolInterfaces ( + Device->DeviceHandle, + &gEfiBlockIo2ProtocolGuid, + &Device->BlockIo2, + NULL + ); + } + // MU_CHANGE [END] - Request Number of Queues from Controller goto Exit; @@ -533,23 +524,23 @@ UnregisterNvmeNamespace ( Handle ); - // MU_CHANGE [BEGIN] - Request Number of Queues from Controller - // - // If BlockIo2 is installed, uninstall it. - // - if (NVME_SUPPORT_BLOCKIO2 (Device->Controller)) { - BlockIo2Status = gBS->UninstallMultipleProtocolInterfaces ( - Handle, - &gEfiBlockIo2ProtocolGuid, - &Device->BlockIo2, - NULL - ); - - if (EFI_ERROR (BlockIo2Status)) { - DEBUG ((DEBUG_ERROR, "%a: Failed to uninstall BlockIo2 protocol\n", __func__)); - } - } - + // MU_CHANGE [BEGIN] - Request Number of Queues from Controller + // + // If BlockIo2 is installed, uninstall it. + // + if (NVME_SUPPORT_BLOCKIO2 (Device->Controller) && Device->BlockIo2Installed) { + BlockIo2Status = gBS->UninstallMultipleProtocolInterfaces ( + Handle, + &gEfiBlockIo2ProtocolGuid, + &Device->BlockIo2, + NULL + ); + + if (EFI_ERROR (BlockIo2Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to uninstall BlockIo2 protocol\n", __func__)); + } + } + // MU_CHANGE [END] - Request Number of Queues from Controller // // The Nvm Express driver installs the BlockIo and DiskInfo in the DriverBindingStart(). diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h index e4ec4b40e13..a481eb0acc0 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h @@ -313,13 +313,14 @@ struct _NVME_DEVICE_PRIVATE_DATA { MEDIA_SANITIZE_PROTOCOL MediaSanitize; - LIST_ENTRY AsyncQueue; - - EFI_LBA NumBlocks; - - CHAR16 ModelName[80]; - NVME_ADMIN_NAMESPACE_DATA NamespaceData; - + LIST_ENTRY AsyncQueue; + + EFI_LBA NumBlocks; + BOOLEAN BlockIo2Installed; + + CHAR16 ModelName[80]; + NVME_ADMIN_NAMESPACE_DATA NamespaceData; + NVME_CONTROLLER_PRIVATE_DATA *Controller; };