NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows\r
NVM Express specification.\r
\r
- Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
#include <Protocol/PciIo.h>\r
#include <Protocol/NvmExpressPassthru.h>\r
#include <Protocol/BlockIo.h>\r
+#include <Protocol/BlockIo2.h>\r
#include <Protocol/DiskInfo.h>\r
#include <Protocol/DriverSupportedEfiVersion.h>\r
#include <Protocol/StorageSecurityCommand.h>\r
#define NVME_CSQ_SIZE 1 // Number of I/O submission queue entries, which is 0-based\r
#define NVME_CCQ_SIZE 1 // Number of I/O completion queue entries, which is 0-based\r
\r
-#define NVME_MAX_QUEUES 2 // Number of queues supported by the driver\r
+//\r
+// Number of asynchronous I/O submission queue entries, which is 0-based.\r
+// The asynchronous I/O submission queue size is 4kB in total.\r
+//\r
+#define NVME_ASYNC_CSQ_SIZE 63\r
+//\r
+// Number of asynchronous I/O completion queue entries, which is 0-based.\r
+// The asynchronous I/O completion queue size is 4kB in total.\r
+//\r
+#define NVME_ASYNC_CCQ_SIZE 255\r
+\r
+#define NVME_MAX_QUEUES 3 // Number of queues supported by the driver\r
\r
#define NVME_CONTROLLER_ID 0\r
\r
//\r
#define NVME_GENERIC_TIMEOUT EFI_TIMER_PERIOD_SECONDS (5)\r
\r
+//\r
+// Nvme async transfer timer interval, set by experience.\r
+//\r
+#define NVME_HC_ASYNC_TIMER EFI_TIMER_PERIOD_MILLISECONDS (1)\r
+\r
//\r
// Unique signature for private data structure.\r
//\r
//\r
// 6 x 4kB aligned buffers will be carved out of this buffer.\r
// 1st 4kB boundary is the start of the admin submission queue.\r
- // 2nd 4kB boundary is the start of the I/O submission queue #1.\r
- // 3rd 4kB boundary is the start of the admin completion queue.\r
- // 4th 4kB boundary is the start of the I/O completion queue #1.\r
- // 5th 4kB boundary is the start of the first PRP list page.\r
- // 6th 4kB boundary is the start of the second PRP list page.\r
+ // 2nd 4kB boundary is the start of the admin completion queue.\r
+ // 3rd 4kB boundary is the start of I/O submission queue #1.\r
+ // 4th 4kB boundary is the start of I/O completion queue #1.\r
+ // 5th 4kB boundary is the start of I/O submission queue #2.\r
+ // 6th 4kB boundary is the start of I/O completion queue #2.\r
//\r
UINT8 *Buffer;\r
UINT8 *BufferPciAddr;\r
//\r
NVME_SQTDBL SqTdbl[NVME_MAX_QUEUES];\r
NVME_CQHDBL CqHdbl[NVME_MAX_QUEUES];\r
+ UINT16 AsyncSqHead;\r
\r
UINT8 Pt[NVME_MAX_QUEUES];\r
UINT16 Cid[NVME_MAX_QUEUES];\r
NVME_CAP Cap;\r
\r
VOID *Mapping;\r
+\r
+ //\r
+ // For Non-blocking operations.\r
+ //\r
+ EFI_EVENT TimerEvent;\r
+ LIST_ENTRY AsyncPassThruQueue;\r
+ LIST_ENTRY UnsubmittedSubtasks;\r
};\r
\r
#define NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU(a) \\r
\r
EFI_BLOCK_IO_MEDIA Media;\r
EFI_BLOCK_IO_PROTOCOL BlockIo;\r
+ EFI_BLOCK_IO2_PROTOCOL BlockIo2;\r
EFI_DISK_INFO_PROTOCOL DiskInfo;\r
EFI_STORAGE_SECURITY_COMMAND_PROTOCOL StorageSecurity;\r
\r
+ LIST_ENTRY AsyncQueue;\r
+\r
EFI_LBA NumBlocks;\r
\r
CHAR16 ModelName[80];\r
NVME_DEVICE_PRIVATE_DATA_SIGNATURE \\r
)\r
\r
+#define NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2(a) \\r
+ CR (a, \\r
+ NVME_DEVICE_PRIVATE_DATA, \\r
+ BlockIo2, \\r
+ NVME_DEVICE_PRIVATE_DATA_SIGNATURE \\r
+ )\r
+\r
#define NVME_DEVICE_PRIVATE_DATA_FROM_DISK_INFO(a) \\r
CR (a, \\r
NVME_DEVICE_PRIVATE_DATA, \\r
NVME_DEVICE_PRIVATE_DATA_SIGNATURE \\r
)\r
\r
+//\r
+// Nvme block I/O 2 request.\r
+//\r
+#define NVME_BLKIO2_REQUEST_SIGNATURE SIGNATURE_32 ('N', 'B', '2', 'R')\r
+\r
+typedef struct {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ EFI_BLOCK_IO2_TOKEN *Token;\r
+ UINTN UnsubmittedSubtaskNum;\r
+ BOOLEAN LastSubtaskSubmitted;\r
+ //\r
+ // The queue for Nvme read/write sub-tasks of a BlockIo2 request.\r
+ //\r
+ LIST_ENTRY SubtasksQueue;\r
+} NVME_BLKIO2_REQUEST;\r
+\r
+#define NVME_BLKIO2_REQUEST_FROM_LINK(a) \\r
+ CR (a, NVME_BLKIO2_REQUEST, Link, NVME_BLKIO2_REQUEST_SIGNATURE)\r
+\r
+#define NVME_BLKIO2_SUBTASK_SIGNATURE SIGNATURE_32 ('N', 'B', '2', 'S')\r
+\r
+typedef struct {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ BOOLEAN IsLast;\r
+ UINT32 NamespaceId;\r
+ EFI_EVENT Event;\r
+ EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *CommandPacket;\r
+ //\r
+ // The BlockIo2 request this subtask belongs to\r
+ //\r
+ NVME_BLKIO2_REQUEST *BlockIo2Request;\r
+} NVME_BLKIO2_SUBTASK;\r
+\r
+#define NVME_BLKIO2_SUBTASK_FROM_LINK(a) \\r
+ CR (a, NVME_BLKIO2_SUBTASK, Link, NVME_BLKIO2_SUBTASK_SIGNATURE)\r
+\r
+//\r
+// Nvme asynchronous passthru request.\r
+//\r
+#define NVME_PASS_THRU_ASYNC_REQ_SIG SIGNATURE_32 ('N', 'P', 'A', 'R')\r
+\r
+typedef struct {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet;\r
+ UINT16 CommandId;\r
+ EFI_EVENT CallerEvent;\r
+} NVME_PASS_THRU_ASYNC_REQ;\r
+\r
+#define NVME_PASS_THRU_ASYNC_REQ_FROM_THIS(a) \\r
+ CR (a, \\r
+ NVME_PASS_THRU_ASYNC_REQ, \\r
+ Link, \\r
+ NVME_PASS_THRU_ASYNC_REQ_SIG \\r
+ )\r
+\r
/**\r
Retrieves a Unicode string that is the user readable name of the driver.\r
\r
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
);\r
\r
+/**\r
+ Dump the execution status from a given completion queue entry.\r
+\r
+ @param[in] Cq A pointer to the NVME_CQ item.\r
+\r
+**/\r
+VOID\r
+NvmeDumpStatus (\r
+ IN NVME_CQ *Cq\r
+ );\r
+\r
#endif\r