mirror of https://github.com/acidanthera/audk.git
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 <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>
This commit is contained in:
parent
6535266574
commit
05bf4747dd
|
@ -683,6 +683,7 @@ NvmeCreateIoCompletionQueue (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
NVME_ADMIN_CRIOCQ CrIoCq;
|
NVME_ADMIN_CRIOCQ CrIoCq;
|
||||||
UINT32 Index;
|
UINT32 Index;
|
||||||
|
UINT16 QueueSize;
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
@ -701,8 +702,18 @@ NvmeCreateIoCompletionQueue (
|
||||||
CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
|
CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
|
||||||
CommandPacket.QueueType = NVME_ADMIN_QUEUE;
|
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.Qid = Index;
|
||||||
CrIoCq.Qsize = (Index == 1) ? NVME_CCQ_SIZE : NVME_ASYNC_CCQ_SIZE;
|
CrIoCq.Qsize = QueueSize;
|
||||||
CrIoCq.Pc = 1;
|
CrIoCq.Pc = 1;
|
||||||
CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof (NVME_ADMIN_CRIOCQ));
|
CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof (NVME_ADMIN_CRIOCQ));
|
||||||
CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
|
CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
|
||||||
|
@ -741,6 +752,7 @@ NvmeCreateIoSubmissionQueue (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
NVME_ADMIN_CRIOSQ CrIoSq;
|
NVME_ADMIN_CRIOSQ CrIoSq;
|
||||||
UINT32 Index;
|
UINT32 Index;
|
||||||
|
UINT16 QueueSize;
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
@ -759,8 +771,18 @@ NvmeCreateIoSubmissionQueue (
|
||||||
CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
|
CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
|
||||||
CommandPacket.QueueType = NVME_ADMIN_QUEUE;
|
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.Qid = Index;
|
||||||
CrIoSq.Qsize = (Index == 1) ? NVME_CSQ_SIZE : NVME_ASYNC_CSQ_SIZE;
|
CrIoSq.Qsize = QueueSize;
|
||||||
CrIoSq.Pc = 1;
|
CrIoSq.Pc = 1;
|
||||||
CrIoSq.Cqid = Index;
|
CrIoSq.Cqid = Index;
|
||||||
CrIoSq.Qprio = 0;
|
CrIoSq.Qprio = 0;
|
||||||
|
|
Loading…
Reference in New Issue