mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/NvmExpressDxe: Fix wrong queue size for async IO queues
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2118 When a packet is queued/completed for the asynchronous IO queue, the logic to roll over to the front of the queue doesn't account for actual size of the IO Submission/Completion queue. This causes a device to hang due to doorbell being outside of visible queue. An example would be if an NVMe drive only supported a queue size of 128 while the driver supports 256. Cc: Jian J Wang <jian.j.wang@intel.com> Signed-off-by: Sean Brogan <sean.brogan@microsoft.com> Signed-off-by: Hao A Wu <hao.a.wu@intel.com> Acked-by: Ray Ni <ray.ni@intel.com>
This commit is contained in:
parent
0b9ad0bc03
commit
7607174192
|
@ -672,7 +672,7 @@ ProcessAsyncTaskList (
|
|||
}
|
||||
|
||||
Private->CqHdbl[QueueId].Cqh++;
|
||||
if (Private->CqHdbl[QueueId].Cqh > NVME_ASYNC_CCQ_SIZE) {
|
||||
if (Private->CqHdbl[QueueId].Cqh > MIN (NVME_ASYNC_CCQ_SIZE, Private->Cap.Mqes)) {
|
||||
Private->CqHdbl[QueueId].Cqh = 0;
|
||||
Private->Pt[QueueId] ^= 1;
|
||||
}
|
||||
|
|
|
@ -452,6 +452,7 @@ NvmExpressPassThru (
|
|||
NVME_SQ *Sq;
|
||||
NVME_CQ *Cq;
|
||||
UINT16 QueueId;
|
||||
UINT16 QueueSize;
|
||||
UINT32 Bytes;
|
||||
UINT16 Offset;
|
||||
EFI_EVENT TimerEvent;
|
||||
|
@ -540,6 +541,7 @@ NvmExpressPassThru (
|
|||
Prp = NULL;
|
||||
TimerEvent = NULL;
|
||||
Status = EFI_SUCCESS;
|
||||
QueueSize = MIN (NVME_ASYNC_CSQ_SIZE, Private->Cap.Mqes) + 1;
|
||||
|
||||
if (Packet->QueueType == NVME_ADMIN_QUEUE) {
|
||||
QueueId = 0;
|
||||
|
@ -552,7 +554,7 @@ NvmExpressPassThru (
|
|||
//
|
||||
// Submission queue full check.
|
||||
//
|
||||
if ((Private->SqTdbl[QueueId].Sqt + 1) % (NVME_ASYNC_CSQ_SIZE + 1) ==
|
||||
if ((Private->SqTdbl[QueueId].Sqt + 1) % QueueSize ==
|
||||
Private->AsyncSqHead) {
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
|
@ -701,7 +703,7 @@ NvmExpressPassThru (
|
|||
//
|
||||
if ((Event != NULL) && (QueueId != 0)) {
|
||||
Private->SqTdbl[QueueId].Sqt =
|
||||
(Private->SqTdbl[QueueId].Sqt + 1) % (NVME_ASYNC_CSQ_SIZE + 1);
|
||||
(Private->SqTdbl[QueueId].Sqt + 1) % QueueSize;
|
||||
} else {
|
||||
Private->SqTdbl[QueueId].Sqt ^= 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue