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>
}\r
\r
Private->CqHdbl[QueueId].Cqh++;\r
- if (Private->CqHdbl[QueueId].Cqh > NVME_ASYNC_CCQ_SIZE) {\r
+ if (Private->CqHdbl[QueueId].Cqh > MIN (NVME_ASYNC_CCQ_SIZE, Private->Cap.Mqes)) {\r
Private->CqHdbl[QueueId].Cqh = 0;\r
Private->Pt[QueueId] ^= 1;\r
}\r
NVME_SQ *Sq;\r
NVME_CQ *Cq;\r
UINT16 QueueId;\r
+ UINT16 QueueSize;\r
UINT32 Bytes;\r
UINT16 Offset;\r
EFI_EVENT TimerEvent;\r
Prp = NULL;\r
TimerEvent = NULL;\r
Status = EFI_SUCCESS;\r
+ QueueSize = MIN (NVME_ASYNC_CSQ_SIZE, Private->Cap.Mqes) + 1;\r
\r
if (Packet->QueueType == NVME_ADMIN_QUEUE) {\r
QueueId = 0;\r
//\r
// Submission queue full check.\r
//\r
- if ((Private->SqTdbl[QueueId].Sqt + 1) % (NVME_ASYNC_CSQ_SIZE + 1) ==\r
+ if ((Private->SqTdbl[QueueId].Sqt + 1) % QueueSize ==\r
Private->AsyncSqHead) {\r
return EFI_NOT_READY;\r
}\r
//\r
if ((Event != NULL) && (QueueId != 0)) {\r
Private->SqTdbl[QueueId].Sqt =\r
- (Private->SqTdbl[QueueId].Sqt + 1) % (NVME_ASYNC_CSQ_SIZE + 1);\r
+ (Private->SqTdbl[QueueId].Sqt + 1) % QueueSize;\r
} else {\r
Private->SqTdbl[QueueId].Sqt ^= 1;\r
}\r