]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/NvmExpressDxe: Fix some bugs
authorFeng Tian <feng.tian@intel.com>
Wed, 11 Sep 2013 06:57:53 +0000 (06:57 +0000)
committererictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 11 Sep 2013 06:57:53 +0000 (06:57 +0000)
1) The Queue size field in create I/O submission/completion queue cmds is 0-based. the current code is 1-based.
2) a typo on allocated memory page size. it's inconsistent that some places is using 4 pages, but a place is using 6 pages.
3) a typo on PRP/SGL mechanism judgment. should directly use Psdt field rather than Opc field.
4) some platforms may not support UINT64 width access on MMIO register. Fix it to use two 32-bit width access.

Signed-off-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Kinney Michael <michael.d.kinney@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14657 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressBlockIo.c
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c

index b6729ce711b311a116efd59a3aed2ffbdbe8d3e3..ed1c4bf391a962b3f72b46b3d7bef0b5801aad68 100644 (file)
@@ -214,6 +214,15 @@ EnumerateNvmeDevNamespace (
            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
            );\r
 \r
+    //\r
+    // Dump NvmExpress Identify Namespace Data\r
+    //\r
+    DEBUG ((EFI_D_INFO, " == NVME IDENTIFY NAMESPACE [%d] DATA ==\n", NamespaceId));\r
+    DEBUG ((EFI_D_INFO, "    NSZE        : 0x%x\n", NamespaceData->Nsze));\r
+    DEBUG ((EFI_D_INFO, "    NCAP        : 0x%x\n", NamespaceData->Ncap));\r
+    DEBUG ((EFI_D_INFO, "    NUSE        : 0x%x\n", NamespaceData->Nuse));\r
+    DEBUG ((EFI_D_INFO, "    LBAF0.LBADS : 0x%x\n", (NamespaceData->LbaFormat[0].Lbads)));\r
+\r
     //\r
     // Build controller name for Component Name (2) protocol.\r
     //\r
@@ -657,7 +666,7 @@ NvmExpressDriverBindingStart (
                       PciIo,\r
                       AllocateAnyPages,\r
                       EfiBootServicesData,\r
-                      6,\r
+                      4,\r
                       (VOID**)&Private->Buffer,\r
                       0\r
                       );\r
index d39b62e102de2ff72385259a59fd31023513982c..79ab927edb60b40ea5022a0868d773db5e3dd404 100644 (file)
@@ -56,11 +56,11 @@ extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL  gNvmExpressDriverSupportedEfiV
 #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                             2     // Number of admin submission queue entries\r
-#define NVME_ACQ_SIZE                             2     // Number of admin completion queue entries\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                             2     // Number of I/O submission queue entries\r
-#define NVME_CCQ_SIZE                             2     // Number of I/O completion queue entries\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_IO_QUEUES                        2     // Number of I/O queues supported by the driver\r
 \r
index 458afd232b22a108d0a6198b14b9b401ffe5fbbe..c1aad6b8138e304f1831631354f24fd6b0c28e9c 100644 (file)
@@ -172,10 +172,12 @@ NvmeRead (
   UINT32                           BlockSize;\r
   NVME_CONTROLLER_PRIVATE_DATA     *Controller;\r
   UINT32                           MaxTransferBlocks;\r
+  UINTN                            OrginalBlocks;\r
 \r
-  Status     = EFI_SUCCESS;\r
-  Controller = Device->Controller;\r
-  BlockSize  = Device->Media.BlockSize;\r
+  Status        = EFI_SUCCESS;\r
+  Controller    = Device->Controller;\r
+  BlockSize     = Device->Media.BlockSize;\r
+  OrginalBlocks = Blocks;\r
 \r
   if (Controller->ControllerData->Mdts != 0) {\r
     MaxTransferBlocks = (1 << (Controller->ControllerData->Mdts)) * (1 << (Controller->Cap.Mpsmin + 12)) / BlockSize;\r
@@ -200,7 +202,7 @@ NvmeRead (
     }\r
   }\r
 \r
-  DEBUG ((EFI_D_INFO, "NvmeRead()  Lba = %8d, Blocks = %8d, BlockSize = %d Status = %r\n", Lba, Blocks, BlockSize, Status));\r
+  DEBUG ((EFI_D_INFO, "NvmeRead()  Lba = 0x%08x, Original = 0x%08x, Remaining = 0x%08x, BlockSize = 0x%x Status = %r\n", Lba, OrginalBlocks, Blocks, BlockSize, Status));\r
 \r
   return Status;\r
 }\r
@@ -229,10 +231,12 @@ NvmeWrite (
   UINT32                           BlockSize;\r
   NVME_CONTROLLER_PRIVATE_DATA     *Controller;\r
   UINT32                           MaxTransferBlocks;\r
+  UINTN                            OrginalBlocks;\r
 \r
-  Status     = EFI_SUCCESS;\r
-  Controller = Device->Controller;\r
-  BlockSize  = Device->Media.BlockSize;\r
+  Status        = EFI_SUCCESS;\r
+  Controller    = Device->Controller;\r
+  BlockSize     = Device->Media.BlockSize;\r
+  OrginalBlocks = Blocks;\r
 \r
   if (Controller->ControllerData->Mdts != 0) {\r
     MaxTransferBlocks = (1 << (Controller->ControllerData->Mdts)) * (1 << (Controller->Cap.Mpsmin + 12)) / BlockSize;\r
@@ -257,7 +261,7 @@ NvmeWrite (
     }\r
   }\r
 \r
-  DEBUG ((EFI_D_INFO, "NvmeWrite() Lba = %8d, Blocks = %8d, BlockSize = %d Status = %r\n", Lba, Blocks, BlockSize, Status));\r
+  DEBUG ((EFI_D_INFO, "NvmeWrite() Lba = 0x%08x, Original = 0x%08x, Remaining = 0x%08x, BlockSize = 0x%x Status = %r\n", Lba, OrginalBlocks, Blocks, BlockSize, Status));\r
 \r
   return Status;\r
 }\r
index 157e10127aa76675ef38b981253ed5d0849f3093..7b46870d5ad33d922fbe2f2205098098a974d4d1 100644 (file)
@@ -33,21 +33,23 @@ ReadNvmeControllerCapabilities (
 {\r
   EFI_PCI_IO_PROTOCOL   *PciIo;\r
   EFI_STATUS            Status;\r
+  UINT64                Data;\r
 \r
   PciIo  = Private->PciIo;\r
   Status = PciIo->Mem.Read (\r
                         PciIo,\r
-                        EfiPciIoWidthUint64,\r
+                        EfiPciIoWidthUint32,\r
                         NVME_BAR,\r
                         NVME_CAP_OFFSET,\r
-                        1,\r
-                        Cap\r
+                        2,\r
+                        &Data\r
                         );\r
 \r
   if (EFI_ERROR(Status)) {\r
     return Status;\r
   }\r
 \r
+  WriteUnaligned64 ((UINT64*)Cap, Data);\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -69,6 +71,7 @@ ReadNvmeControllerConfiguration (
 {\r
   EFI_PCI_IO_PROTOCOL   *PciIo;\r
   EFI_STATUS            Status;\r
+  UINT32                Data;\r
 \r
   PciIo  = Private->PciIo;\r
   Status = PciIo->Mem.Read (\r
@@ -77,13 +80,14 @@ ReadNvmeControllerConfiguration (
                         NVME_BAR,\r
                         NVME_CC_OFFSET,\r
                         1,\r
-                        Cc\r
+                        &Data\r
                         );\r
 \r
   if (EFI_ERROR(Status)) {\r
     return Status;\r
   }\r
 \r
+  WriteUnaligned32 ((UINT32*)Cc, Data);\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -105,15 +109,17 @@ WriteNvmeControllerConfiguration (
 {\r
   EFI_PCI_IO_PROTOCOL   *PciIo;\r
   EFI_STATUS            Status;\r
+  UINT32                Data;\r
 \r
   PciIo  = Private->PciIo;\r
+  Data   = ReadUnaligned32 ((UINT32*)Cc);\r
   Status = PciIo->Mem.Write (\r
                         PciIo,\r
                         EfiPciIoWidthUint32,\r
                         NVME_BAR,\r
                         NVME_CC_OFFSET,\r
                         1,\r
-                        Cc\r
+                        &Data\r
                         );\r
 \r
   if (EFI_ERROR(Status)) {\r
@@ -149,6 +155,7 @@ ReadNvmeControllerStatus (
 {\r
   EFI_PCI_IO_PROTOCOL   *PciIo;\r
   EFI_STATUS            Status;\r
+  UINT32                Data;\r
 \r
   PciIo  = Private->PciIo;\r
   Status = PciIo->Mem.Read (\r
@@ -157,13 +164,14 @@ ReadNvmeControllerStatus (
                         NVME_BAR,\r
                         NVME_CSTS_OFFSET,\r
                         1,\r
-                        Csts\r
+                        &Data\r
                         );\r
 \r
   if (EFI_ERROR(Status)) {\r
     return Status;\r
   }\r
 \r
+  WriteUnaligned32 ((UINT32*)Csts, Data);\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -185,6 +193,7 @@ ReadNvmeAdminQueueAttributes (
 {\r
   EFI_PCI_IO_PROTOCOL   *PciIo;\r
   EFI_STATUS            Status;\r
+  UINT32                Data;\r
 \r
   PciIo  = Private->PciIo;\r
   Status = PciIo->Mem.Read (\r
@@ -193,13 +202,14 @@ ReadNvmeAdminQueueAttributes (
                         NVME_BAR,\r
                         NVME_AQA_OFFSET,\r
                         1,\r
-                        Aqa\r
+                        &Data\r
                         );\r
 \r
   if (EFI_ERROR(Status)) {\r
     return Status;\r
   }\r
 \r
+  WriteUnaligned32 ((UINT32*)Aqa, Data);\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -221,15 +231,17 @@ WriteNvmeAdminQueueAttributes (
 {\r
   EFI_PCI_IO_PROTOCOL   *PciIo;\r
   EFI_STATUS            Status;\r
+  UINT32                Data;\r
 \r
   PciIo  = Private->PciIo;\r
+  Data   = ReadUnaligned32 ((UINT32*)Aqa);\r
   Status = PciIo->Mem.Write (\r
                         PciIo,\r
                         EfiPciIoWidthUint32,\r
                         NVME_BAR,\r
                         NVME_AQA_OFFSET,\r
                         1,\r
-                        Aqa\r
+                        &Data\r
                         );\r
 \r
   if (EFI_ERROR(Status)) {\r
@@ -260,21 +272,23 @@ ReadNvmeAdminSubmissionQueueBaseAddress (
 {\r
   EFI_PCI_IO_PROTOCOL   *PciIo;\r
   EFI_STATUS            Status;\r
+  UINT64                Data;\r
 \r
   PciIo  = Private->PciIo;\r
   Status = PciIo->Mem.Read (\r
                         PciIo,\r
-                        EfiPciIoWidthUint64,\r
+                        EfiPciIoWidthUint32,\r
                         NVME_BAR,\r
                         NVME_ASQ_OFFSET,\r
-                        1,\r
-                        Asq\r
+                        2,\r
+                        &Data\r
                         );\r
 \r
   if (EFI_ERROR(Status)) {\r
     return Status;\r
   }\r
 \r
+  WriteUnaligned64 ((UINT64*)Asq, Data);\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -296,15 +310,18 @@ WriteNvmeAdminSubmissionQueueBaseAddress (
 {\r
   EFI_PCI_IO_PROTOCOL   *PciIo;\r
   EFI_STATUS            Status;\r
+  UINT64                Data;\r
 \r
   PciIo  = Private->PciIo;\r
+  Data   = ReadUnaligned64 ((UINT64*)Asq);\r
+\r
   Status = PciIo->Mem.Write (\r
                         PciIo,\r
-                        EfiPciIoWidthUint64,\r
+                        EfiPciIoWidthUint32,\r
                         NVME_BAR,\r
                         NVME_ASQ_OFFSET,\r
-                        1,\r
-                        Asq\r
+                        2,\r
+                        &Data\r
                         );\r
 \r
   if (EFI_ERROR(Status)) {\r
@@ -334,21 +351,24 @@ ReadNvmeAdminCompletionQueueBaseAddress (
 {\r
   EFI_PCI_IO_PROTOCOL   *PciIo;\r
   EFI_STATUS            Status;\r
+  UINT64                Data;\r
 \r
   PciIo  = Private->PciIo;\r
+\r
   Status = PciIo->Mem.Read (\r
                         PciIo,\r
-                        EfiPciIoWidthUint64,\r
+                        EfiPciIoWidthUint32,\r
                         NVME_BAR,\r
                         NVME_ACQ_OFFSET,\r
-                        1,\r
-                        Acq\r
+                        2,\r
+                        &Data\r
                         );\r
 \r
   if (EFI_ERROR(Status)) {\r
     return Status;\r
   }\r
 \r
+  WriteUnaligned64 ((UINT64*)Acq, Data);\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -370,15 +390,18 @@ WriteNvmeAdminCompletionQueueBaseAddress (
 {\r
   EFI_PCI_IO_PROTOCOL   *PciIo;\r
   EFI_STATUS            Status;\r
+  UINT64                Data;\r
 \r
   PciIo  = Private->PciIo;\r
+  Data   = ReadUnaligned64 ((UINT64*)Acq);\r
+\r
   Status = PciIo->Mem.Write (\r
                         PciIo,\r
-                        EfiPciIoWidthUint64,\r
+                        EfiPciIoWidthUint32,\r
                         NVME_BAR,\r
                         NVME_ACQ_OFFSET,\r
-                        1,\r
-                        Acq\r
+                        2,\r
+                        &Data\r
                         );\r
 \r
   if (EFI_ERROR(Status)) {\r
@@ -921,6 +944,25 @@ NvmeControllerInit (
     Private->ControllerData = NULL;\r
     return EFI_NOT_FOUND;\r
   }\r
+\r
+  //\r
+  // Dump NvmExpress Identify Controller Data\r
+  //\r
+  Private->ControllerData->Sn[19] = 0;\r
+  Private->ControllerData->Mn[39] = 0;\r
+  DEBUG ((EFI_D_INFO, " == NVME IDENTIFY CONTROLLER DATA ==\n"));\r
+  DEBUG ((EFI_D_INFO, "    PCI VID   : 0x%x\n", Private->ControllerData->Vid));\r
+  DEBUG ((EFI_D_INFO, "    PCI SSVID : 0x%x\n", Private->ControllerData->Ssvid));\r
+  DEBUG ((EFI_D_INFO, "    SN        : %a\n",   (CHAR8 *)(Private->ControllerData->Sn)));\r
+  DEBUG ((EFI_D_INFO, "    MN        : %a\n",   (CHAR8 *)(Private->ControllerData->Mn)));\r
+  DEBUG ((EFI_D_INFO, "    FR        : 0x%x\n", *((UINT64*)Private->ControllerData->Fr)));\r
+  DEBUG ((EFI_D_INFO, "    RAB       : 0x%x\n", Private->ControllerData->Rab));\r
+  DEBUG ((EFI_D_INFO, "    IEEE      : 0x%x\n", *(UINT32*)Private->ControllerData->Ieee_oiu));\r
+  DEBUG ((EFI_D_INFO, "    AERL      : 0x%x\n", Private->ControllerData->Aerl));\r
+  DEBUG ((EFI_D_INFO, "    SQES      : 0x%x\n", Private->ControllerData->Sqes));\r
+  DEBUG ((EFI_D_INFO, "    CQES      : 0x%x\n", Private->ControllerData->Cqes));\r
+  DEBUG ((EFI_D_INFO, "    NN        : 0x%x\n", Private->ControllerData->Nn));\r
+\r
   return Status;\r
 }\r
 \r
index d1231aca89af01ce4b37317f7857d7b947f71096..4320549ed4f48a9f51baf28c8b36658edcddf1ed 100644 (file)
@@ -387,6 +387,7 @@ NvmExpressPassThru (
   UINT64                        *Prp;\r
   VOID                          *PrpListHost;\r
   UINTN                         PrpListNo;\r
+  UINT32                        Data;\r
 \r
   //\r
   // check the data fields in Packet parameter.\r
@@ -431,8 +432,8 @@ NvmExpressPassThru (
   //\r
   // Currently we only support PRP for data transfer, SGL is NOT supported.\r
   //\r
-  ASSERT ((Sq->Opc & BIT15) == 0);\r
-  if ((Sq->Opc & BIT15) != 0) {\r
+  ASSERT (Sq->Psdt == 0);\r
+  if (Sq->Psdt != 0) {\r
     DEBUG ((EFI_D_ERROR, "NvmExpressPassThru: doesn't support SGL mechanism\n"));\r
     return EFI_UNSUPPORTED;\r
   }\r
@@ -534,14 +535,14 @@ NvmExpressPassThru (
   // Ring the submission queue doorbell.\r
   //\r
   Private->SqTdbl[Qid].Sqt ^= 1;\r
-\r
+  Data = ReadUnaligned32 ((UINT32*)&Private->SqTdbl[Qid]);\r
   PciIo->Mem.Write (\r
                PciIo,\r
                EfiPciIoWidthUint32,\r
                NVME_BAR,\r
                NVME_SQTDBL_OFFSET(Qid, Private->Cap.Dstrd),\r
                1,\r
-               &Private->SqTdbl[Qid]\r
+               &Data\r
                );\r
 \r
   Status = gBS->CreateEvent (\r
@@ -591,13 +592,14 @@ NvmExpressPassThru (
     NvmeDumpStatus(Cq);\r
   DEBUG_CODE_END();\r
 \r
+  Data = ReadUnaligned32 ((UINT32*)&Private->CqHdbl[Qid]);\r
   PciIo->Mem.Write (\r
                PciIo,\r
                EfiPciIoWidthUint32,\r
                NVME_BAR,\r
                NVME_CQHDBL_OFFSET(Qid, Private->Cap.Dstrd),\r
                1,\r
-               &Private->CqHdbl[Qid]\r
+               &Data\r
                );\r
 \r
 EXIT:\r