From: Hao Wu Date: Wed, 1 Jun 2016 08:32:03 +0000 (+0800) Subject: MdeModulePkg NvmExpressDxe: Fix invalid queue size when creating IO queues X-Git-Tag: edk2-stable201903~6902 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=05bf4747dd8e412d10fccbe35346aa2597b4167b MdeModulePkg NvmExpressDxe: Fix invalid queue size when creating IO queues The Maximum Queue Entries Supported (MQES) field in the CAP (Controller Capabilities) register for a NVMe controller restrict the maximum individual queue size that the controller supports. The origin code does not check this value and always uses a hardcode value when creating I/O submission/completion queues for asynchronous transmission. The hardcode value might be larger than the MQES field, this will lead to an 'Invalid Queue Size' error when creating I/O submission/completion queues. The patch will add checks to make sure proper queue size is passed when creating I/O submission/completion queues. Cc: Feng Tian Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Hao Wu Reviewed-by: Feng Tian --- diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c index 4f83a92a36..a173504cdf 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c @@ -683,6 +683,7 @@ NvmeCreateIoCompletionQueue ( EFI_STATUS Status; NVME_ADMIN_CRIOCQ CrIoCq; UINT32 Index; + UINT16 QueueSize; Status = EFI_SUCCESS; @@ -701,8 +702,18 @@ NvmeCreateIoCompletionQueue ( CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; CommandPacket.QueueType = NVME_ADMIN_QUEUE; + if (Index == 1) { + QueueSize = NVME_CCQ_SIZE; + } else { + if (Private->Cap.Mqes > NVME_ASYNC_CCQ_SIZE) { + QueueSize = NVME_ASYNC_CCQ_SIZE; + } else { + QueueSize = Private->Cap.Mqes; + } + } + CrIoCq.Qid = Index; - CrIoCq.Qsize = (Index == 1) ? NVME_CCQ_SIZE : NVME_ASYNC_CCQ_SIZE; + CrIoCq.Qsize = QueueSize; CrIoCq.Pc = 1; CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof (NVME_ADMIN_CRIOCQ)); CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID; @@ -741,6 +752,7 @@ NvmeCreateIoSubmissionQueue ( EFI_STATUS Status; NVME_ADMIN_CRIOSQ CrIoSq; UINT32 Index; + UINT16 QueueSize; Status = EFI_SUCCESS; @@ -759,8 +771,18 @@ NvmeCreateIoSubmissionQueue ( CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; CommandPacket.QueueType = NVME_ADMIN_QUEUE; + if (Index == 1) { + QueueSize = NVME_CSQ_SIZE; + } else { + if (Private->Cap.Mqes > NVME_ASYNC_CSQ_SIZE) { + QueueSize = NVME_ASYNC_CSQ_SIZE; + } else { + QueueSize = Private->Cap.Mqes; + } + } + CrIoSq.Qid = Index; - CrIoSq.Qsize = (Index == 1) ? NVME_CSQ_SIZE : NVME_ASYNC_CSQ_SIZE; + CrIoSq.Qsize = QueueSize; CrIoSq.Pc = 1; CrIoSq.Cqid = Index; CrIoSq.Qprio = 0;