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>
EFI_STATUS Status;\r
NVME_ADMIN_CRIOCQ CrIoCq;\r
UINT32 Index;\r
EFI_STATUS Status;\r
NVME_ADMIN_CRIOCQ CrIoCq;\r
UINT32 Index;\r
\r
Status = EFI_SUCCESS;\r
\r
\r
Status = EFI_SUCCESS;\r
\r
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.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
EFI_STATUS Status;\r
NVME_ADMIN_CRIOSQ CrIoSq;\r
UINT32 Index;\r
EFI_STATUS Status;\r
NVME_ADMIN_CRIOSQ CrIoSq;\r
UINT32 Index;\r
\r
Status = EFI_SUCCESS;\r
\r
\r
Status = EFI_SUCCESS;\r
\r
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.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