]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg NvmExpressDxe: Fix invalid queue size when creating IO queues
authorHao Wu <hao.a.wu@intel.com>
Wed, 1 Jun 2016 08:32:03 +0000 (16:32 +0800)
committerHao Wu <hao.a.wu@intel.com>
Thu, 2 Jun 2016 08:40:17 +0000 (16:40 +0800)
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 <feng.tian@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Feng Tian <feng.tian@Intel.com>
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c

index 4f83a92a364aeb266960fec7566dd73f8cc99966..a173504cdf4d3a46004df0c62a94816f8e705ed2 100644 (file)
@@ -683,6 +683,7 @@ NvmeCreateIoCompletionQueue (
   EFI_STATUS                               Status;\r
   NVME_ADMIN_CRIOCQ                        CrIoCq;\r
   UINT32                                   Index;\r
   EFI_STATUS                               Status;\r
   NVME_ADMIN_CRIOCQ                        CrIoCq;\r
   UINT32                                   Index;\r
+  UINT16                                   QueueSize;\r
 \r
   Status = EFI_SUCCESS;\r
 \r
 \r
   Status = EFI_SUCCESS;\r
 \r
@@ -701,8 +702,18 @@ NvmeCreateIoCompletionQueue (
     CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
     CommandPacket.QueueType      = NVME_ADMIN_QUEUE;\r
 \r
     CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
     CommandPacket.QueueType      = NVME_ADMIN_QUEUE;\r
 \r
+    if (Index == 1) {\r
+      QueueSize = NVME_CCQ_SIZE;\r
+    } else {\r
+      if (Private->Cap.Mqes > NVME_ASYNC_CCQ_SIZE) {\r
+        QueueSize = NVME_ASYNC_CCQ_SIZE;\r
+      } else {\r
+        QueueSize = Private->Cap.Mqes;\r
+      }\r
+    }\r
+\r
     CrIoCq.Qid   = Index;\r
     CrIoCq.Qid   = Index;\r
-    CrIoCq.Qsize = (Index == 1) ? NVME_CCQ_SIZE : NVME_ASYNC_CCQ_SIZE;\r
+    CrIoCq.Qsize = QueueSize;\r
     CrIoCq.Pc    = 1;\r
     CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof (NVME_ADMIN_CRIOCQ));\r
     CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;\r
     CrIoCq.Pc    = 1;\r
     CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof (NVME_ADMIN_CRIOCQ));\r
     CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;\r
@@ -741,6 +752,7 @@ NvmeCreateIoSubmissionQueue (
   EFI_STATUS                               Status;\r
   NVME_ADMIN_CRIOSQ                        CrIoSq;\r
   UINT32                                   Index;\r
   EFI_STATUS                               Status;\r
   NVME_ADMIN_CRIOSQ                        CrIoSq;\r
   UINT32                                   Index;\r
+  UINT16                                   QueueSize;\r
 \r
   Status = EFI_SUCCESS;\r
 \r
 \r
   Status = EFI_SUCCESS;\r
 \r
@@ -759,8 +771,18 @@ NvmeCreateIoSubmissionQueue (
     CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
     CommandPacket.QueueType      = NVME_ADMIN_QUEUE;\r
 \r
     CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;\r
     CommandPacket.QueueType      = NVME_ADMIN_QUEUE;\r
 \r
+    if (Index == 1) {\r
+      QueueSize = NVME_CSQ_SIZE;\r
+    } else {\r
+      if (Private->Cap.Mqes > NVME_ASYNC_CSQ_SIZE) {\r
+        QueueSize = NVME_ASYNC_CSQ_SIZE;\r
+      } else {\r
+        QueueSize = Private->Cap.Mqes;\r
+      }\r
+    }\r
+\r
     CrIoSq.Qid   = Index;\r
     CrIoSq.Qid   = Index;\r
-    CrIoSq.Qsize = (Index == 1) ? NVME_CSQ_SIZE : NVME_ASYNC_CSQ_SIZE;\r
+    CrIoSq.Qsize = QueueSize;\r
     CrIoSq.Pc    = 1;\r
     CrIoSq.Cqid  = Index;\r
     CrIoSq.Qprio = 0;\r
     CrIoSq.Pc    = 1;\r
     CrIoSq.Cqid  = Index;\r
     CrIoSq.Qprio = 0;\r