NVM Express specification.\r
\r
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
- Copyright (c) 2013 - 2017, 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
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include <Library/MemoryAllocationLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
\r
-typedef struct _NVME_CONTROLLER_PRIVATE_DATA NVME_CONTROLLER_PRIVATE_DATA;\r
-typedef struct _NVME_DEVICE_PRIVATE_DATA NVME_DEVICE_PRIVATE_DATA;\r
+typedef struct _NVME_CONTROLLER_PRIVATE_DATA NVME_CONTROLLER_PRIVATE_DATA;\r
+typedef struct _NVME_DEVICE_PRIVATE_DATA NVME_DEVICE_PRIVATE_DATA;\r
\r
#include "NvmExpressBlockIo.h"\r
#include "NvmExpressDiskInfo.h"\r
extern EFI_COMPONENT_NAME2_PROTOCOL gNvmExpressComponentName2;\r
extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gNvmExpressDriverSupportedEfiVersion;\r
\r
-#define PCI_CLASS_MASS_STORAGE_NVM 0x08 // mass storage sub-class non-volatile memory.\r
-#define PCI_IF_NVMHCI 0x02 // mass storage programming interface NVMHCI.\r
+#define PCI_CLASS_MASS_STORAGE_NVM 0x08 // mass storage sub-class non-volatile memory.\r
+#define PCI_IF_NVMHCI 0x02 // mass storage programming interface NVMHCI.\r
\r
-#define NVME_ASQ_SIZE 1 // Number of admin submission queue entries, which is 0-based\r
-#define NVME_ACQ_SIZE 1 // Number of admin completion queue entries, which is 0-based\r
+#define NVME_ASQ_SIZE 1 // Number of admin submission queue entries, which is 0-based\r
+#define NVME_ACQ_SIZE 1 // Number of admin completion queue entries, which is 0-based\r
\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
+#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
//\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
+#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
+#define NVME_ASYNC_CCQ_SIZE 255\r
\r
-#define NVME_MAX_QUEUES 3 // Number of queues supported by the driver\r
+#define NVME_MAX_QUEUES 3 // Number of queues supported by the driver\r
\r
-#define NVME_CONTROLLER_ID 0\r
+#define NVME_CONTROLLER_ID 0\r
\r
//\r
// Time out value for Nvme transaction execution\r
//\r
-#define NVME_GENERIC_TIMEOUT EFI_TIMER_PERIOD_SECONDS (5)\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
+#define NVME_HC_ASYNC_TIMER EFI_TIMER_PERIOD_MILLISECONDS (1)\r
\r
//\r
// Unique signature for private data structure.\r
//\r
-#define NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('N','V','M','E')\r
+#define NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('N','V','M','E')\r
\r
//\r
// Nvme private data structure.\r
//\r
struct _NVME_CONTROLLER_PRIVATE_DATA {\r
- UINT32 Signature;\r
+ UINT32 Signature;\r
\r
- EFI_HANDLE ControllerHandle;\r
- EFI_HANDLE ImageHandle;\r
- EFI_HANDLE DriverBindingHandle;\r
+ EFI_HANDLE ControllerHandle;\r
+ EFI_HANDLE ImageHandle;\r
+ EFI_HANDLE DriverBindingHandle;\r
\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT64 PciAttributes;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT64 PciAttributes;\r
\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
\r
- EFI_NVM_EXPRESS_PASS_THRU_MODE PassThruMode;\r
- EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL Passthru;\r
+ EFI_NVM_EXPRESS_PASS_THRU_MODE PassThruMode;\r
+ EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL Passthru;\r
\r
//\r
// pointer to identify controller data\r
//\r
- NVME_ADMIN_CONTROLLER_DATA *ControllerData;\r
+ NVME_ADMIN_CONTROLLER_DATA *ControllerData;\r
\r
//\r
// 6 x 4kB aligned buffers will be carved out of this buffer.\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
+ UINT8 *Buffer;\r
+ UINT8 *BufferPciAddr;\r
\r
//\r
// Pointers to 4kB aligned submission & completion queues.\r
//\r
- NVME_SQ *SqBuffer[NVME_MAX_QUEUES];\r
- NVME_CQ *CqBuffer[NVME_MAX_QUEUES];\r
- NVME_SQ *SqBufferPciAddr[NVME_MAX_QUEUES];\r
- NVME_CQ *CqBufferPciAddr[NVME_MAX_QUEUES];\r
+ NVME_SQ *SqBuffer[NVME_MAX_QUEUES];\r
+ NVME_CQ *CqBuffer[NVME_MAX_QUEUES];\r
+ NVME_SQ *SqBufferPciAddr[NVME_MAX_QUEUES];\r
+ NVME_CQ *CqBufferPciAddr[NVME_MAX_QUEUES];\r
\r
//\r
// Submission and completion queue indices.\r
//\r
- NVME_SQTDBL SqTdbl[NVME_MAX_QUEUES];\r
- NVME_CQHDBL CqHdbl[NVME_MAX_QUEUES];\r
- UINT16 AsyncSqHead;\r
+ NVME_SQTDBL SqTdbl[NVME_MAX_QUEUES];\r
+ NVME_CQHDBL CqHdbl[NVME_MAX_QUEUES];\r
+ UINT16 AsyncSqHead;\r
+\r
+ //\r
+ // Flag to indicate internal IO queue creation.\r
+ //\r
+ BOOLEAN CreateIoQueue;\r
\r
- UINT8 Pt[NVME_MAX_QUEUES];\r
- UINT16 Cid[NVME_MAX_QUEUES];\r
+ UINT8 Pt[NVME_MAX_QUEUES];\r
+ UINT16 Cid[NVME_MAX_QUEUES];\r
\r
//\r
// Nvme controller capabilities\r
//\r
- NVME_CAP Cap;\r
+ NVME_CAP Cap;\r
\r
- VOID *Mapping;\r
+ VOID *Mapping;\r
\r
//\r
// For Non-blocking operations.\r
//\r
- EFI_EVENT TimerEvent;\r
- LIST_ENTRY AsyncPassThruQueue;\r
- LIST_ENTRY UnsubmittedSubtasks;\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
// Unique signature for private data structure.\r
//\r
-#define NVME_DEVICE_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('X','S','S','D')\r
+#define NVME_DEVICE_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('X','S','S','D')\r
\r
//\r
// Nvme device private data structure\r
NVME_ADMIN_NAMESPACE_DATA NamespaceData;\r
\r
NVME_CONTROLLER_PRIVATE_DATA *Controller;\r
-\r
};\r
\r
//\r
NVME_DEVICE_PRIVATE_DATA_SIGNATURE \\r
)\r
\r
-#define NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY(a)\\r
+#define NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY(a) \\r
CR (a, \\r
NVME_DEVICE_PRIVATE_DATA, \\r
StorageSecurity, \\r
//\r
// Nvme block I/O 2 request.\r
//\r
-#define NVME_BLKIO2_REQUEST_SIGNATURE SIGNATURE_32 ('N', 'B', '2', '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
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
\r
- EFI_BLOCK_IO2_TOKEN *Token;\r
- UINTN UnsubmittedSubtaskNum;\r
- BOOLEAN LastSubtaskSubmitted;\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
+ 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
+#define NVME_BLKIO2_SUBTASK_SIGNATURE SIGNATURE_32 ('N', 'B', '2', 'S')\r
\r
typedef struct {\r
- UINT32 Signature;\r
- LIST_ENTRY Link;\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
+ 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_REQUEST *BlockIo2Request;\r
} NVME_BLKIO2_SUBTASK;\r
\r
#define NVME_BLKIO2_SUBTASK_FROM_LINK(a) \\r
//\r
// Nvme asynchronous passthru request.\r
//\r
-#define NVME_PASS_THRU_ASYNC_REQ_SIG SIGNATURE_32 ('N', 'P', 'A', '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
- VOID *MapPrpList;\r
- UINTN PrpListNo;\r
- VOID *PrpListHost;\r
- VOID *MapData;\r
- VOID *MapMeta;\r
- EFI_EVENT CallerEvent;\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet;\r
+ UINT16 CommandId;\r
+ VOID *MapPrpList;\r
+ UINTN PrpListNo;\r
+ VOID *PrpListHost;\r
+ VOID *MapData;\r
+ VOID *MapMeta;\r
+ EFI_EVENT CallerEvent;\r
} NVME_PASS_THRU_ASYNC_REQ;\r
\r
#define NVME_PASS_THRU_ASYNC_REQ_FROM_THIS(a) \\r
EFI_STATUS\r
EFIAPI\r
NvmExpressComponentNameGetControllerName (\r
- IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL,\r
- IN CHAR8 *Language,\r
- OUT CHAR16 **ControllerName\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
);\r
\r
/**\r
EFI_STATUS\r
EFIAPI\r
NvmExpressDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
);\r
\r
/**\r
EFI_STATUS\r
EFIAPI\r
NvmExpressPassThru (\r
- IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,\r
- IN UINT32 NamespaceId,\r
- IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet,\r
- IN EFI_EVENT Event OPTIONAL\r
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,\r
+ IN UINT32 NamespaceId,\r
+ IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet,\r
+ IN EFI_EVENT Event OPTIONAL\r
);\r
\r
/**\r
EFI_STATUS\r
EFIAPI\r
NvmExpressGetNextNamespace (\r
- IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,\r
- IN OUT UINT32 *NamespaceId\r
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,\r
+ IN OUT UINT32 *NamespaceId\r
);\r
\r
/**\r
EFI_STATUS\r
EFIAPI\r
NvmExpressGetNamespace (\r
- IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- OUT UINT32 *NamespaceId\r
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ OUT UINT32 *NamespaceId\r
);\r
\r
/**\r
EFI_STATUS\r
EFIAPI\r
NvmExpressBuildDevicePath (\r
- IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,\r
- IN UINT32 NamespaceId,\r
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,\r
+ IN UINT32 NamespaceId,\r
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
);\r
\r
/**\r
**/\r
VOID\r
NvmeDumpStatus (\r
- IN NVME_CQ *Cq\r
+ IN NVME_CQ *Cq\r
);\r
\r
/**\r