Home | History | Annotate | Download | only in NvmExpressDxe
      1 /** @file
      2   NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows
      3   NVM Express specification.
      4 
      5   Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
      6   This program and the accompanying materials
      7   are licensed and made available under the terms and conditions of the BSD License
      8   which accompanies this distribution.  The full text of the license may be found at
      9   http://opensource.org/licenses/bsd-license.php.
     10 
     11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include "NvmExpress.h"
     17 
     18 //
     19 // NVM Express Driver Binding Protocol Instance
     20 //
     21 EFI_DRIVER_BINDING_PROTOCOL gNvmExpressDriverBinding = {
     22   NvmExpressDriverBindingSupported,
     23   NvmExpressDriverBindingStart,
     24   NvmExpressDriverBindingStop,
     25   0x10,
     26   NULL,
     27   NULL
     28 };
     29 
     30 //
     31 // NVM Express EFI Driver Supported EFI Version Protocol Instance
     32 //
     33 EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gNvmExpressDriverSupportedEfiVersion = {
     34   sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of Protocol structure.
     35   0                                                   // Version number to be filled at start up.
     36 };
     37 
     38 //
     39 // Template for NVM Express Pass Thru Mode data structure.
     40 //
     41 GLOBAL_REMOVE_IF_UNREFERENCED EFI_NVM_EXPRESS_PASS_THRU_MODE gEfiNvmExpressPassThruMode = {
     42   EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL   |
     43   EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_LOGICAL    |
     44   EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_NONBLOCKIO |
     45   EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_CMD_SET_NVM,
     46   sizeof (UINTN),
     47   0x10100
     48 };
     49 
     50 /**
     51   Check if the specified Nvm Express device namespace is active, and create child handles
     52   for them with BlockIo and DiskInfo protocol instances.
     53 
     54   @param[in] Private         The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.
     55   @param[in] NamespaceId     The NVM Express namespace ID  for which a device path node is to be
     56                              allocated and built. Caller must set the NamespaceId to zero if the
     57                              device path node will contain a valid UUID.
     58 
     59   @retval EFI_SUCCESS        All the namespaces in the device are successfully enumerated.
     60   @return Others             Some error occurs when enumerating the namespaces.
     61 
     62 **/
     63 EFI_STATUS
     64 EnumerateNvmeDevNamespace (
     65   IN NVME_CONTROLLER_PRIVATE_DATA       *Private,
     66   UINT32                                NamespaceId
     67   )
     68 {
     69   NVME_ADMIN_NAMESPACE_DATA             *NamespaceData;
     70   EFI_DEVICE_PATH_PROTOCOL              *NewDevicePathNode;
     71   EFI_DEVICE_PATH_PROTOCOL              *DevicePath;
     72   EFI_HANDLE                            DeviceHandle;
     73   EFI_DEVICE_PATH_PROTOCOL              *ParentDevicePath;
     74   EFI_DEVICE_PATH_PROTOCOL              *RemainingDevicePath;
     75   NVME_DEVICE_PRIVATE_DATA              *Device;
     76   EFI_STATUS                            Status;
     77   UINT32                                Lbads;
     78   UINT32                                Flbas;
     79   UINT32                                LbaFmtIdx;
     80   UINT8                                 Sn[21];
     81   UINT8                                 Mn[41];
     82   VOID                                  *DummyInterface;
     83 
     84   NewDevicePathNode = NULL;
     85   DevicePath        = NULL;
     86   Device            = NULL;
     87 
     88   //
     89   // Allocate a buffer for Identify Namespace data
     90   //
     91   NamespaceData = AllocateZeroPool(sizeof (NVME_ADMIN_NAMESPACE_DATA));
     92   if(NamespaceData == NULL) {
     93     return EFI_OUT_OF_RESOURCES;
     94   }
     95 
     96   ParentDevicePath = Private->ParentDevicePath;
     97   //
     98   // Identify Namespace
     99   //
    100   Status = NvmeIdentifyNamespace (
    101              Private,
    102              NamespaceId,
    103              (VOID *)NamespaceData
    104              );
    105   if (EFI_ERROR(Status)) {
    106     goto Exit;
    107   }
    108   //
    109   // Validate Namespace
    110   //
    111   if (NamespaceData->Ncap == 0) {
    112     Status = EFI_DEVICE_ERROR;
    113   } else {
    114     //
    115     // allocate device private data for each discovered namespace
    116     //
    117     Device = AllocateZeroPool(sizeof(NVME_DEVICE_PRIVATE_DATA));
    118     if (Device == NULL) {
    119       Status = EFI_OUT_OF_RESOURCES;
    120       goto Exit;
    121     }
    122 
    123     //
    124     // Initialize SSD namespace instance data
    125     //
    126     Device->Signature           = NVME_DEVICE_PRIVATE_DATA_SIGNATURE;
    127     Device->NamespaceId         = NamespaceId;
    128     Device->NamespaceUuid       = NamespaceData->Eui64;
    129 
    130     Device->ControllerHandle    = Private->ControllerHandle;
    131     Device->DriverBindingHandle = Private->DriverBindingHandle;
    132     Device->Controller          = Private;
    133 
    134     //
    135     // Build BlockIo media structure
    136     //
    137     Device->Media.MediaId        = 0;
    138     Device->Media.RemovableMedia = FALSE;
    139     Device->Media.MediaPresent   = TRUE;
    140     Device->Media.LogicalPartition = FALSE;
    141     Device->Media.ReadOnly       = FALSE;
    142     Device->Media.WriteCaching   = FALSE;
    143     Device->Media.IoAlign        = Private->PassThruMode.IoAlign;
    144 
    145     Flbas     = NamespaceData->Flbas;
    146     LbaFmtIdx = Flbas & 0xF;
    147     Lbads     = NamespaceData->LbaFormat[LbaFmtIdx].Lbads;
    148     Device->Media.BlockSize = (UINT32)1 << Lbads;
    149 
    150     Device->Media.LastBlock                     = NamespaceData->Nsze - 1;
    151     Device->Media.LogicalBlocksPerPhysicalBlock = 1;
    152     Device->Media.LowestAlignedLba              = 1;
    153 
    154     //
    155     // Create BlockIo Protocol instance
    156     //
    157     Device->BlockIo.Revision     = EFI_BLOCK_IO_PROTOCOL_REVISION2;
    158     Device->BlockIo.Media        = &Device->Media;
    159     Device->BlockIo.Reset        = NvmeBlockIoReset;
    160     Device->BlockIo.ReadBlocks   = NvmeBlockIoReadBlocks;
    161     Device->BlockIo.WriteBlocks  = NvmeBlockIoWriteBlocks;
    162     Device->BlockIo.FlushBlocks  = NvmeBlockIoFlushBlocks;
    163 
    164     //
    165     // Create BlockIo2 Protocol instance
    166     //
    167     Device->BlockIo2.Media          = &Device->Media;
    168     Device->BlockIo2.Reset          = NvmeBlockIoResetEx;
    169     Device->BlockIo2.ReadBlocksEx   = NvmeBlockIoReadBlocksEx;
    170     Device->BlockIo2.WriteBlocksEx  = NvmeBlockIoWriteBlocksEx;
    171     Device->BlockIo2.FlushBlocksEx  = NvmeBlockIoFlushBlocksEx;
    172     InitializeListHead (&Device->AsyncQueue);
    173 
    174     //
    175     // Create StorageSecurityProtocol Instance
    176     //
    177     Device->StorageSecurity.ReceiveData = NvmeStorageSecurityReceiveData;
    178     Device->StorageSecurity.SendData    = NvmeStorageSecuritySendData;
    179 
    180     //
    181     // Create DiskInfo Protocol instance
    182     //
    183     CopyMem (&Device->NamespaceData, NamespaceData, sizeof (NVME_ADMIN_NAMESPACE_DATA));
    184     InitializeDiskInfo (Device);
    185 
    186     //
    187     // Create a Nvm Express Namespace Device Path Node
    188     //
    189     Status = Private->Passthru.BuildDevicePath (
    190                                  &Private->Passthru,
    191                                  Device->NamespaceId,
    192                                  &NewDevicePathNode
    193                                  );
    194 
    195     if (EFI_ERROR(Status)) {
    196       goto Exit;
    197     }
    198 
    199     //
    200     // Append the SSD node to the controller's device path
    201     //
    202     DevicePath = AppendDevicePathNode (ParentDevicePath, NewDevicePathNode);
    203     if (DevicePath == NULL) {
    204       Status = EFI_OUT_OF_RESOURCES;
    205       goto Exit;
    206     }
    207 
    208     DeviceHandle = NULL;
    209     RemainingDevicePath = DevicePath;
    210     Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);
    211     if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {
    212       Status = EFI_ALREADY_STARTED;
    213       FreePool (DevicePath);
    214       goto Exit;
    215     }
    216 
    217     Device->DevicePath = DevicePath;
    218 
    219     //
    220     // Make sure the handle is NULL so we create a new handle
    221     //
    222     Device->DeviceHandle = NULL;
    223 
    224     Status = gBS->InstallMultipleProtocolInterfaces (
    225                     &Device->DeviceHandle,
    226                     &gEfiDevicePathProtocolGuid,
    227                     Device->DevicePath,
    228                     &gEfiBlockIoProtocolGuid,
    229                     &Device->BlockIo,
    230                     &gEfiBlockIo2ProtocolGuid,
    231                     &Device->BlockIo2,
    232                     &gEfiDiskInfoProtocolGuid,
    233                     &Device->DiskInfo,
    234                     NULL
    235                     );
    236 
    237     if(EFI_ERROR(Status)) {
    238       goto Exit;
    239     }
    240 
    241     //
    242     // Check if the NVMe controller supports the Security Send and Security Receive commands
    243     //
    244     if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) != 0) {
    245       Status = gBS->InstallProtocolInterface (
    246                       &Device->DeviceHandle,
    247                       &gEfiStorageSecurityCommandProtocolGuid,
    248                       EFI_NATIVE_INTERFACE,
    249                       &Device->StorageSecurity
    250                       );
    251       if(EFI_ERROR(Status)) {
    252         gBS->UninstallMultipleProtocolInterfaces (
    253                &Device->DeviceHandle,
    254                &gEfiDevicePathProtocolGuid,
    255                Device->DevicePath,
    256                &gEfiBlockIoProtocolGuid,
    257                &Device->BlockIo,
    258                &gEfiBlockIo2ProtocolGuid,
    259                &Device->BlockIo2,
    260                &gEfiDiskInfoProtocolGuid,
    261                &Device->DiskInfo,
    262                NULL
    263                );
    264         goto Exit;
    265       }
    266     }
    267 
    268     gBS->OpenProtocol (
    269            Private->ControllerHandle,
    270            &gEfiNvmExpressPassThruProtocolGuid,
    271            (VOID **) &DummyInterface,
    272            Private->DriverBindingHandle,
    273            Device->DeviceHandle,
    274            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
    275            );
    276 
    277     //
    278     // Dump NvmExpress Identify Namespace Data
    279     //
    280     DEBUG ((EFI_D_INFO, " == NVME IDENTIFY NAMESPACE [%d] DATA ==\n", NamespaceId));
    281     DEBUG ((EFI_D_INFO, "    NSZE        : 0x%x\n", NamespaceData->Nsze));
    282     DEBUG ((EFI_D_INFO, "    NCAP        : 0x%x\n", NamespaceData->Ncap));
    283     DEBUG ((EFI_D_INFO, "    NUSE        : 0x%x\n", NamespaceData->Nuse));
    284     DEBUG ((EFI_D_INFO, "    LBAF0.LBADS : 0x%x\n", (NamespaceData->LbaFormat[0].Lbads)));
    285 
    286     //
    287     // Build controller name for Component Name (2) protocol.
    288     //
    289     CopyMem (Sn, Private->ControllerData->Sn, sizeof (Private->ControllerData->Sn));
    290     Sn[20] = 0;
    291     CopyMem (Mn, Private->ControllerData->Mn, sizeof (Private->ControllerData->Mn));
    292     Mn[40] = 0;
    293     UnicodeSPrintAsciiFormat (Device->ModelName, sizeof (Device->ModelName), "%a-%a-%x", Sn, Mn, NamespaceData->Eui64);
    294 
    295     AddUnicodeString2 (
    296       "eng",
    297       gNvmExpressComponentName.SupportedLanguages,
    298       &Device->ControllerNameTable,
    299       Device->ModelName,
    300       TRUE
    301       );
    302 
    303     AddUnicodeString2 (
    304       "en",
    305       gNvmExpressComponentName2.SupportedLanguages,
    306       &Device->ControllerNameTable,
    307       Device->ModelName,
    308       FALSE
    309       );
    310   }
    311 
    312 Exit:
    313   if(NamespaceData != NULL) {
    314     FreePool (NamespaceData);
    315   }
    316 
    317   if (NewDevicePathNode != NULL) {
    318     FreePool (NewDevicePathNode);
    319   }
    320 
    321   if(EFI_ERROR(Status) && (Device != NULL) && (Device->DevicePath != NULL)) {
    322     FreePool (Device->DevicePath);
    323   }
    324   if(EFI_ERROR(Status) && (Device != NULL)) {
    325     FreePool (Device);
    326   }
    327   return Status;
    328 }
    329 
    330 /**
    331   Discover all Nvm Express device namespaces, and create child handles for them with BlockIo
    332   and DiskInfo protocol instances.
    333 
    334   @param[in] Private         The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.
    335 
    336   @retval EFI_SUCCESS        All the namespaces in the device are successfully enumerated.
    337   @return Others             Some error occurs when enumerating the namespaces.
    338 
    339 **/
    340 EFI_STATUS
    341 DiscoverAllNamespaces (
    342   IN NVME_CONTROLLER_PRIVATE_DATA       *Private
    343   )
    344 {
    345   EFI_STATUS                            Status;
    346   UINT32                                NamespaceId;
    347   EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL    *Passthru;
    348 
    349   NamespaceId   = 0xFFFFFFFF;
    350   Passthru      = &Private->Passthru;
    351 
    352   while (TRUE) {
    353     Status = Passthru->GetNextNamespace (
    354                          Passthru,
    355                          (UINT32 *)&NamespaceId
    356                          );
    357 
    358     if (EFI_ERROR (Status)) {
    359       break;
    360     }
    361 
    362     Status = EnumerateNvmeDevNamespace (
    363                Private,
    364                NamespaceId
    365                );
    366 
    367     if (EFI_ERROR(Status)) {
    368       continue;
    369     }
    370   }
    371 
    372   return EFI_SUCCESS;
    373 }
    374 
    375 /**
    376   Unregisters a Nvm Express device namespace.
    377 
    378   This function removes the protocols installed on the controller handle and
    379   frees the resources allocated for the namespace.
    380 
    381   @param  This                  The pointer to EFI_DRIVER_BINDING_PROTOCOL instance.
    382   @param  Controller            The controller handle of the namespace.
    383   @param  Handle                The child handle.
    384 
    385   @retval EFI_SUCCESS           The namespace is successfully unregistered.
    386   @return Others                Some error occurs when unregistering the namespace.
    387 
    388 **/
    389 EFI_STATUS
    390 UnregisterNvmeNamespace (
    391   IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
    392   IN  EFI_HANDLE                     Controller,
    393   IN  EFI_HANDLE                     Handle
    394   )
    395 {
    396   EFI_STATUS                               Status;
    397   EFI_BLOCK_IO_PROTOCOL                    *BlockIo;
    398   NVME_DEVICE_PRIVATE_DATA                 *Device;
    399   EFI_STORAGE_SECURITY_COMMAND_PROTOCOL    *StorageSecurity;
    400   BOOLEAN                                  IsEmpty;
    401   EFI_TPL                                  OldTpl;
    402   VOID                                     *DummyInterface;
    403 
    404   BlockIo = NULL;
    405 
    406   Status = gBS->OpenProtocol (
    407                   Handle,
    408                   &gEfiBlockIoProtocolGuid,
    409                   (VOID **) &BlockIo,
    410                   This->DriverBindingHandle,
    411                   Controller,
    412                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    413                   );
    414   if (EFI_ERROR (Status)) {
    415     return Status;
    416   }
    417 
    418   Device  = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (BlockIo);
    419 
    420   //
    421   // Wait for the device's asynchronous I/O queue to become empty.
    422   //
    423   while (TRUE) {
    424     OldTpl  = gBS->RaiseTPL (TPL_NOTIFY);
    425     IsEmpty = IsListEmpty (&Device->AsyncQueue);
    426     gBS->RestoreTPL (OldTpl);
    427 
    428     if (IsEmpty) {
    429       break;
    430     }
    431 
    432     gBS->Stall (100);
    433   }
    434 
    435   //
    436   // Close the child handle
    437   //
    438   gBS->CloseProtocol (
    439          Controller,
    440          &gEfiNvmExpressPassThruProtocolGuid,
    441          This->DriverBindingHandle,
    442          Handle
    443          );
    444 
    445   //
    446   // The Nvm Express driver installs the BlockIo and DiskInfo in the DriverBindingStart().
    447   // Here should uninstall both of them.
    448   //
    449   Status = gBS->UninstallMultipleProtocolInterfaces (
    450                   Handle,
    451                   &gEfiDevicePathProtocolGuid,
    452                   Device->DevicePath,
    453                   &gEfiBlockIoProtocolGuid,
    454                   &Device->BlockIo,
    455                   &gEfiBlockIo2ProtocolGuid,
    456                   &Device->BlockIo2,
    457                   &gEfiDiskInfoProtocolGuid,
    458                   &Device->DiskInfo,
    459                   NULL
    460                   );
    461 
    462   if (EFI_ERROR (Status)) {
    463     gBS->OpenProtocol (
    464            Controller,
    465            &gEfiNvmExpressPassThruProtocolGuid,
    466            (VOID **) &DummyInterface,
    467            This->DriverBindingHandle,
    468            Handle,
    469            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
    470            );
    471     return Status;
    472   }
    473 
    474   //
    475   // If Storage Security Command Protocol is installed, then uninstall this protocol.
    476   //
    477   Status = gBS->OpenProtocol (
    478                   Handle,
    479                   &gEfiStorageSecurityCommandProtocolGuid,
    480                   (VOID **) &StorageSecurity,
    481                   This->DriverBindingHandle,
    482                   Controller,
    483                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    484                   );
    485 
    486   if (!EFI_ERROR (Status)) {
    487     Status = gBS->UninstallProtocolInterface (
    488                     Handle,
    489                     &gEfiStorageSecurityCommandProtocolGuid,
    490                     &Device->StorageSecurity
    491                     );
    492     if (EFI_ERROR (Status)) {
    493       gBS->OpenProtocol (
    494         Controller,
    495         &gEfiNvmExpressPassThruProtocolGuid,
    496         (VOID **) &DummyInterface,
    497         This->DriverBindingHandle,
    498         Handle,
    499         EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
    500         );
    501       return Status;
    502     }
    503   }
    504 
    505   if(Device->DevicePath != NULL) {
    506     FreePool (Device->DevicePath);
    507   }
    508 
    509   if (Device->ControllerNameTable != NULL) {
    510     FreeUnicodeStringTable (Device->ControllerNameTable);
    511   }
    512 
    513   FreePool (Device);
    514 
    515   return EFI_SUCCESS;
    516 }
    517 
    518 /**
    519   Call back function when the timer event is signaled.
    520 
    521   @param[in]  Event     The Event this notify function registered to.
    522   @param[in]  Context   Pointer to the context data registered to the
    523                         Event.
    524 
    525 **/
    526 VOID
    527 EFIAPI
    528 ProcessAsyncTaskList (
    529   IN EFI_EVENT                    Event,
    530   IN VOID*                        Context
    531   )
    532 {
    533   NVME_CONTROLLER_PRIVATE_DATA         *Private;
    534   EFI_PCI_IO_PROTOCOL                  *PciIo;
    535   NVME_CQ                              *Cq;
    536   UINT16                               QueueId;
    537   UINT32                               Data;
    538   LIST_ENTRY                           *Link;
    539   LIST_ENTRY                           *NextLink;
    540   NVME_PASS_THRU_ASYNC_REQ             *AsyncRequest;
    541   NVME_BLKIO2_SUBTASK                  *Subtask;
    542   NVME_BLKIO2_REQUEST                  *BlkIo2Request;
    543   EFI_BLOCK_IO2_TOKEN                  *Token;
    544   BOOLEAN                              HasNewItem;
    545   EFI_STATUS                           Status;
    546 
    547   Private    = (NVME_CONTROLLER_PRIVATE_DATA*)Context;
    548   QueueId    = 2;
    549   Cq         = Private->CqBuffer[QueueId] + Private->CqHdbl[QueueId].Cqh;
    550   HasNewItem = FALSE;
    551 
    552   //
    553   // Submit asynchronous subtasks to the NVMe Submission Queue
    554   //
    555   for (Link = GetFirstNode (&Private->UnsubmittedSubtasks);
    556        !IsNull (&Private->UnsubmittedSubtasks, Link);
    557        Link = NextLink) {
    558     NextLink      = GetNextNode (&Private->UnsubmittedSubtasks, Link);
    559     Subtask       = NVME_BLKIO2_SUBTASK_FROM_LINK (Link);
    560     BlkIo2Request = Subtask->BlockIo2Request;
    561     Token         = BlkIo2Request->Token;
    562     RemoveEntryList (Link);
    563     BlkIo2Request->UnsubmittedSubtaskNum--;
    564 
    565     //
    566     // If any previous subtask fails, do not process subsequent ones.
    567     //
    568     if (Token->TransactionStatus != EFI_SUCCESS) {
    569       if (IsListEmpty (&BlkIo2Request->SubtasksQueue) &&
    570           BlkIo2Request->LastSubtaskSubmitted &&
    571           (BlkIo2Request->UnsubmittedSubtaskNum == 0)) {
    572         //
    573         // Remove the BlockIo2 request from the device asynchronous queue.
    574         //
    575         RemoveEntryList (&BlkIo2Request->Link);
    576         FreePool (BlkIo2Request);
    577         gBS->SignalEvent (Token->Event);
    578       }
    579 
    580       FreePool (Subtask->CommandPacket->NvmeCmd);
    581       FreePool (Subtask->CommandPacket->NvmeCompletion);
    582       FreePool (Subtask->CommandPacket);
    583       FreePool (Subtask);
    584 
    585       continue;
    586     }
    587 
    588     Status = Private->Passthru.PassThru (
    589                                  &Private->Passthru,
    590                                  Subtask->NamespaceId,
    591                                  Subtask->CommandPacket,
    592                                  Subtask->Event
    593                                  );
    594     if (Status == EFI_NOT_READY) {
    595       InsertHeadList (&Private->UnsubmittedSubtasks, Link);
    596       BlkIo2Request->UnsubmittedSubtaskNum++;
    597       break;
    598     } else if (EFI_ERROR (Status)) {
    599       Token->TransactionStatus = EFI_DEVICE_ERROR;
    600 
    601       if (IsListEmpty (&BlkIo2Request->SubtasksQueue) &&
    602           Subtask->IsLast) {
    603         //
    604         // Remove the BlockIo2 request from the device asynchronous queue.
    605         //
    606         RemoveEntryList (&BlkIo2Request->Link);
    607         FreePool (BlkIo2Request);
    608         gBS->SignalEvent (Token->Event);
    609       }
    610 
    611       FreePool (Subtask->CommandPacket->NvmeCmd);
    612       FreePool (Subtask->CommandPacket->NvmeCompletion);
    613       FreePool (Subtask->CommandPacket);
    614       FreePool (Subtask);
    615     } else {
    616       InsertTailList (&BlkIo2Request->SubtasksQueue, Link);
    617       if (Subtask->IsLast) {
    618         BlkIo2Request->LastSubtaskSubmitted = TRUE;
    619       }
    620     }
    621   }
    622 
    623   while (Cq->Pt != Private->Pt[QueueId]) {
    624     ASSERT (Cq->Sqid == QueueId);
    625 
    626     HasNewItem = TRUE;
    627 
    628     //
    629     // Find the command with given Command Id.
    630     //
    631     for (Link = GetFirstNode (&Private->AsyncPassThruQueue);
    632          !IsNull (&Private->AsyncPassThruQueue, Link);
    633          Link = NextLink) {
    634       NextLink = GetNextNode (&Private->AsyncPassThruQueue, Link);
    635       AsyncRequest = NVME_PASS_THRU_ASYNC_REQ_FROM_THIS (Link);
    636       if (AsyncRequest->CommandId == Cq->Cid) {
    637         //
    638         // Copy the Respose Queue entry for this command to the callers
    639         // response buffer.
    640         //
    641         CopyMem (
    642           AsyncRequest->Packet->NvmeCompletion,
    643           Cq,
    644           sizeof(EFI_NVM_EXPRESS_COMPLETION)
    645           );
    646 
    647         RemoveEntryList (Link);
    648         gBS->SignalEvent (AsyncRequest->CallerEvent);
    649         FreePool (AsyncRequest);
    650 
    651         //
    652         // Update submission queue head.
    653         //
    654         Private->AsyncSqHead = Cq->Sqhd;
    655         break;
    656       }
    657     }
    658 
    659     Private->CqHdbl[QueueId].Cqh++;
    660     if (Private->CqHdbl[QueueId].Cqh > NVME_ASYNC_CCQ_SIZE) {
    661       Private->CqHdbl[QueueId].Cqh = 0;
    662       Private->Pt[QueueId] ^= 1;
    663     }
    664 
    665     Cq = Private->CqBuffer[QueueId] + Private->CqHdbl[QueueId].Cqh;
    666   }
    667 
    668   if (HasNewItem) {
    669     PciIo = Private->PciIo;
    670     Data  = ReadUnaligned32 ((UINT32*)&Private->CqHdbl[QueueId]);
    671     PciIo->Mem.Write (
    672                  PciIo,
    673                  EfiPciIoWidthUint32,
    674                  NVME_BAR,
    675                  NVME_CQHDBL_OFFSET(QueueId, Private->Cap.Dstrd),
    676                  1,
    677                  &Data
    678                  );
    679   }
    680 }
    681 
    682 /**
    683   Tests to see if this driver supports a given controller. If a child device is provided,
    684   it further tests to see if this driver supports creating a handle for the specified child device.
    685 
    686   This function checks to see if the driver specified by This supports the device specified by
    687   ControllerHandle. Drivers will typically use the device path attached to
    688   ControllerHandle and/or the services from the bus I/O abstraction attached to
    689   ControllerHandle to determine if the driver supports ControllerHandle. This function
    690   may be called many times during platform initialization. In order to reduce boot times, the tests
    691   performed by this function must be very small, and take as little time as possible to execute. This
    692   function must not change the state of any hardware devices, and this function must be aware that the
    693   device specified by ControllerHandle may already be managed by the same driver or a
    694   different driver. This function must match its calls to AllocatePages() with FreePages(),
    695   AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
    696   Since ControllerHandle may have been previously started by the same driver, if a protocol is
    697   already in the opened state, then it must not be closed with CloseProtocol(). This is required
    698   to guarantee the state of ControllerHandle is not modified by this function.
    699 
    700   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    701   @param[in]  ControllerHandle     The handle of the controller to test. This handle
    702                                    must support a protocol interface that supplies
    703                                    an I/O abstraction to the driver.
    704   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    705                                    parameter is ignored by device drivers, and is optional for bus
    706                                    drivers. For bus drivers, if this parameter is not NULL, then
    707                                    the bus driver must determine if the bus controller specified
    708                                    by ControllerHandle and the child controller specified
    709                                    by RemainingDevicePath are both supported by this
    710                                    bus driver.
    711 
    712   @retval EFI_SUCCESS              The device specified by ControllerHandle and
    713                                    RemainingDevicePath is supported by the driver specified by This.
    714   @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
    715                                    RemainingDevicePath is already being managed by the driver
    716                                    specified by This.
    717   @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
    718                                    RemainingDevicePath is already being managed by a different
    719                                    driver or an application that requires exclusive access.
    720                                    Currently not implemented.
    721   @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
    722                                    RemainingDevicePath is not supported by the driver specified by This.
    723 **/
    724 EFI_STATUS
    725 EFIAPI
    726 NvmExpressDriverBindingSupported (
    727   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    728   IN EFI_HANDLE                   Controller,
    729   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
    730   )
    731 {
    732   EFI_STATUS                Status;
    733   EFI_DEV_PATH_PTR          DevicePathNode;
    734   EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;
    735   EFI_PCI_IO_PROTOCOL       *PciIo;
    736   UINT8                     ClassCode[3];
    737 
    738   //
    739   // Check whether device path is valid
    740   //
    741   if (RemainingDevicePath != NULL) {
    742     //
    743     // Check if RemainingDevicePath is the End of Device Path Node,
    744     // if yes, go on checking other conditions
    745     //
    746     if (!IsDevicePathEnd (RemainingDevicePath)) {
    747       //
    748       // If RemainingDevicePath isn't the End of Device Path Node,
    749       // check its validation
    750       //
    751       DevicePathNode.DevPath = RemainingDevicePath;
    752 
    753       if ((DevicePathNode.DevPath->Type    != MESSAGING_DEVICE_PATH) ||
    754           (DevicePathNode.DevPath->SubType != MSG_NVME_NAMESPACE_DP) ||
    755           (DevicePathNodeLength(DevicePathNode.DevPath) != sizeof(NVME_NAMESPACE_DEVICE_PATH))) {
    756          return EFI_UNSUPPORTED;
    757       }
    758     }
    759   }
    760 
    761   //
    762   // Open the EFI Device Path protocol needed to perform the supported test
    763   //
    764   Status = gBS->OpenProtocol (
    765                   Controller,
    766                   &gEfiDevicePathProtocolGuid,
    767                   (VOID **) &ParentDevicePath,
    768                   This->DriverBindingHandle,
    769                   Controller,
    770                   EFI_OPEN_PROTOCOL_BY_DRIVER
    771                   );
    772   if (Status == EFI_ALREADY_STARTED) {
    773     return EFI_SUCCESS;
    774   }
    775 
    776   if (EFI_ERROR (Status)) {
    777     return Status;
    778   }
    779 
    780   //
    781   // Close protocol, don't use device path protocol in the Support() function
    782   //
    783   gBS->CloseProtocol (
    784          Controller,
    785          &gEfiDevicePathProtocolGuid,
    786          This->DriverBindingHandle,
    787          Controller
    788          );
    789 
    790   //
    791   // Attempt to Open PCI I/O Protocol
    792   //
    793   Status = gBS->OpenProtocol (
    794                   Controller,
    795                   &gEfiPciIoProtocolGuid,
    796                   (VOID **) &PciIo,
    797                   This->DriverBindingHandle,
    798                   Controller,
    799                   EFI_OPEN_PROTOCOL_BY_DRIVER
    800                   );
    801   if (Status == EFI_ALREADY_STARTED) {
    802     return EFI_SUCCESS;
    803   }
    804 
    805   if (EFI_ERROR (Status)) {
    806     return Status;
    807   }
    808 
    809   //
    810   // Now further check the PCI header: Base class (offset 0x0B) and Sub Class (offset 0x0A).
    811   // This controller should be a Nvm Express controller.
    812   //
    813   Status = PciIo->Pci.Read (
    814                         PciIo,
    815                         EfiPciIoWidthUint8,
    816                         PCI_CLASSCODE_OFFSET,
    817                         sizeof (ClassCode),
    818                         ClassCode
    819                         );
    820   if (EFI_ERROR (Status)) {
    821     goto Done;
    822   }
    823 
    824   //
    825   // Examine Nvm Express controller PCI Configuration table fields
    826   //
    827   if ((ClassCode[0] != PCI_IF_NVMHCI) || (ClassCode[1] != PCI_CLASS_MASS_STORAGE_NVM) || (ClassCode[2] != PCI_CLASS_MASS_STORAGE)) {
    828     Status = EFI_UNSUPPORTED;
    829   }
    830 
    831 Done:
    832   gBS->CloseProtocol (
    833          Controller,
    834          &gEfiPciIoProtocolGuid,
    835          This->DriverBindingHandle,
    836          Controller
    837          );
    838 
    839   return Status;
    840 }
    841 
    842 
    843 /**
    844   Starts a device controller or a bus controller.
    845 
    846   The Start() function is designed to be invoked from the EFI boot service ConnectController().
    847   As a result, much of the error checking on the parameters to Start() has been moved into this
    848   common boot service. It is legal to call Start() from other locations,
    849   but the following calling restrictions must be followed or the system behavior will not be deterministic.
    850   1. ControllerHandle must be a valid EFI_HANDLE.
    851   2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
    852      EFI_DEVICE_PATH_PROTOCOL.
    853   3. Prior to calling Start(), the Supported() function for the driver specified by This must
    854      have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
    855 
    856   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    857   @param[in]  ControllerHandle     The handle of the controller to start. This handle
    858                                    must support a protocol interface that supplies
    859                                    an I/O abstraction to the driver.
    860   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    861                                    parameter is ignored by device drivers, and is optional for bus
    862                                    drivers. For a bus driver, if this parameter is NULL, then handles
    863                                    for all the children of Controller are created by this driver.
    864                                    If this parameter is not NULL and the first Device Path Node is
    865                                    not the End of Device Path Node, then only the handle for the
    866                                    child device specified by the first Device Path Node of
    867                                    RemainingDevicePath is created by this driver.
    868                                    If the first Device Path Node of RemainingDevicePath is
    869                                    the End of Device Path Node, no child handle is created by this
    870                                    driver.
    871 
    872   @retval EFI_SUCCESS              The device was started.
    873   @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
    874   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
    875   @retval Others                   The driver failded to start the device.
    876 
    877 **/
    878 EFI_STATUS
    879 EFIAPI
    880 NvmExpressDriverBindingStart (
    881   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    882   IN EFI_HANDLE                   Controller,
    883   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
    884   )
    885 {
    886   EFI_STATUS                          Status;
    887   EFI_PCI_IO_PROTOCOL                 *PciIo;
    888   NVME_CONTROLLER_PRIVATE_DATA        *Private;
    889   EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;
    890   UINT32                              NamespaceId;
    891   EFI_PHYSICAL_ADDRESS                MappedAddr;
    892   UINTN                               Bytes;
    893   EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL  *Passthru;
    894 
    895   DEBUG ((EFI_D_INFO, "NvmExpressDriverBindingStart: start\n"));
    896 
    897   Private          = NULL;
    898   Passthru         = NULL;
    899   ParentDevicePath = NULL;
    900 
    901   Status = gBS->OpenProtocol (
    902                   Controller,
    903                   &gEfiDevicePathProtocolGuid,
    904                   (VOID **) &ParentDevicePath,
    905                   This->DriverBindingHandle,
    906                   Controller,
    907                   EFI_OPEN_PROTOCOL_BY_DRIVER
    908                   );
    909   if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
    910     return Status;
    911   }
    912 
    913   Status = gBS->OpenProtocol (
    914                   Controller,
    915                   &gEfiPciIoProtocolGuid,
    916                   (VOID **) &PciIo,
    917                   This->DriverBindingHandle,
    918                   Controller,
    919                   EFI_OPEN_PROTOCOL_BY_DRIVER
    920                   );
    921 
    922   if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
    923     return Status;
    924   }
    925 
    926   //
    927   // Check EFI_ALREADY_STARTED to reuse the original NVME_CONTROLLER_PRIVATE_DATA.
    928   //
    929   if (Status != EFI_ALREADY_STARTED) {
    930     Private = AllocateZeroPool (sizeof (NVME_CONTROLLER_PRIVATE_DATA));
    931 
    932     if (Private == NULL) {
    933       DEBUG ((EFI_D_ERROR, "NvmExpressDriverBindingStart: allocating pool for Nvme Private Data failed!\n"));
    934       Status = EFI_OUT_OF_RESOURCES;
    935       goto Exit;
    936     }
    937 
    938     //
    939     // 6 x 4kB aligned buffers will be carved out of this buffer.
    940     // 1st 4kB boundary is the start of the admin submission queue.
    941     // 2nd 4kB boundary is the start of the admin completion queue.
    942     // 3rd 4kB boundary is the start of I/O submission queue #1.
    943     // 4th 4kB boundary is the start of I/O completion queue #1.
    944     // 5th 4kB boundary is the start of I/O submission queue #2.
    945     // 6th 4kB boundary is the start of I/O completion queue #2.
    946     //
    947     // Allocate 6 pages of memory, then map it for bus master read and write.
    948     //
    949     Status = PciIo->AllocateBuffer (
    950                       PciIo,
    951                       AllocateAnyPages,
    952                       EfiBootServicesData,
    953                       6,
    954                       (VOID**)&Private->Buffer,
    955                       0
    956                       );
    957     if (EFI_ERROR (Status)) {
    958       goto Exit;
    959     }
    960 
    961     Bytes = EFI_PAGES_TO_SIZE (6);
    962     Status = PciIo->Map (
    963                       PciIo,
    964                       EfiPciIoOperationBusMasterCommonBuffer,
    965                       Private->Buffer,
    966                       &Bytes,
    967                       &MappedAddr,
    968                       &Private->Mapping
    969                       );
    970 
    971     if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (6))) {
    972       goto Exit;
    973     }
    974 
    975     Private->BufferPciAddr = (UINT8 *)(UINTN)MappedAddr;
    976 
    977     Private->Signature = NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE;
    978     Private->ControllerHandle          = Controller;
    979     Private->ImageHandle               = This->DriverBindingHandle;
    980     Private->DriverBindingHandle       = This->DriverBindingHandle;
    981     Private->PciIo                     = PciIo;
    982     Private->ParentDevicePath          = ParentDevicePath;
    983     Private->Passthru.Mode             = &Private->PassThruMode;
    984     Private->Passthru.PassThru         = NvmExpressPassThru;
    985     Private->Passthru.GetNextNamespace = NvmExpressGetNextNamespace;
    986     Private->Passthru.BuildDevicePath  = NvmExpressBuildDevicePath;
    987     Private->Passthru.GetNamespace     = NvmExpressGetNamespace;
    988     CopyMem (&Private->PassThruMode, &gEfiNvmExpressPassThruMode, sizeof (EFI_NVM_EXPRESS_PASS_THRU_MODE));
    989     InitializeListHead (&Private->AsyncPassThruQueue);
    990     InitializeListHead (&Private->UnsubmittedSubtasks);
    991 
    992     Status = NvmeControllerInit (Private);
    993     if (EFI_ERROR(Status)) {
    994       goto Exit;
    995     }
    996 
    997     //
    998     // Start the asynchronous I/O completion monitor
    999     //
   1000     Status = gBS->CreateEvent (
   1001                     EVT_TIMER | EVT_NOTIFY_SIGNAL,
   1002                     TPL_NOTIFY,
   1003                     ProcessAsyncTaskList,
   1004                     Private,
   1005                     &Private->TimerEvent
   1006                     );
   1007     if (EFI_ERROR (Status)) {
   1008       goto Exit;
   1009     }
   1010 
   1011     Status = gBS->SetTimer (
   1012                     Private->TimerEvent,
   1013                     TimerPeriodic,
   1014                     NVME_HC_ASYNC_TIMER
   1015                     );
   1016     if (EFI_ERROR (Status)) {
   1017       goto Exit;
   1018     }
   1019 
   1020     Status = gBS->InstallMultipleProtocolInterfaces (
   1021                     &Controller,
   1022                     &gEfiNvmExpressPassThruProtocolGuid,
   1023                     &Private->Passthru,
   1024                     NULL
   1025                     );
   1026     if (EFI_ERROR (Status)) {
   1027       goto Exit;
   1028     }
   1029   } else {
   1030     Status = gBS->OpenProtocol (
   1031                     Controller,
   1032                     &gEfiNvmExpressPassThruProtocolGuid,
   1033                     (VOID **) &Passthru,
   1034                     This->DriverBindingHandle,
   1035                     Controller,
   1036                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
   1037                     );
   1038     if (EFI_ERROR (Status)) {
   1039       goto Exit;
   1040     }
   1041 
   1042     Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (Passthru);
   1043   }
   1044 
   1045   if (RemainingDevicePath == NULL) {
   1046     //
   1047     // Enumerate all NVME namespaces in the controller
   1048     //
   1049     Status = DiscoverAllNamespaces (
   1050                Private
   1051                );
   1052 
   1053   } else if (!IsDevicePathEnd (RemainingDevicePath)) {
   1054     //
   1055     // Enumerate the specified NVME namespace
   1056     //
   1057     Status = Private->Passthru.GetNamespace (
   1058                                  &Private->Passthru,
   1059                                  RemainingDevicePath,
   1060                                  &NamespaceId
   1061                                  );
   1062 
   1063     if (!EFI_ERROR (Status)) {
   1064       Status = EnumerateNvmeDevNamespace (
   1065                  Private,
   1066                  NamespaceId
   1067                  );
   1068     }
   1069   }
   1070 
   1071   DEBUG ((EFI_D_INFO, "NvmExpressDriverBindingStart: end successfully\n"));
   1072   return EFI_SUCCESS;
   1073 
   1074 Exit:
   1075   if ((Private != NULL) && (Private->Mapping != NULL)) {
   1076     PciIo->Unmap (PciIo, Private->Mapping);
   1077   }
   1078 
   1079   if ((Private != NULL) && (Private->Buffer != NULL)) {
   1080     PciIo->FreeBuffer (PciIo, 6, Private->Buffer);
   1081   }
   1082 
   1083   if ((Private != NULL) && (Private->ControllerData != NULL)) {
   1084     FreePool (Private->ControllerData);
   1085   }
   1086 
   1087   if (Private != NULL) {
   1088     if (Private->TimerEvent != NULL) {
   1089       gBS->CloseEvent (Private->TimerEvent);
   1090     }
   1091 
   1092     FreePool (Private);
   1093   }
   1094 
   1095   gBS->CloseProtocol (
   1096          Controller,
   1097          &gEfiPciIoProtocolGuid,
   1098          This->DriverBindingHandle,
   1099          Controller
   1100          );
   1101 
   1102   gBS->CloseProtocol (
   1103          Controller,
   1104          &gEfiDevicePathProtocolGuid,
   1105          This->DriverBindingHandle,
   1106          Controller
   1107          );
   1108 
   1109   DEBUG ((EFI_D_INFO, "NvmExpressDriverBindingStart: end with %r\n", Status));
   1110 
   1111   return Status;
   1112 }
   1113 
   1114 
   1115 /**
   1116   Stops a device controller or a bus controller.
   1117 
   1118   The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
   1119   As a result, much of the error checking on the parameters to Stop() has been moved
   1120   into this common boot service. It is legal to call Stop() from other locations,
   1121   but the following calling restrictions must be followed or the system behavior will not be deterministic.
   1122   1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
   1123      same driver's Start() function.
   1124   2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
   1125      EFI_HANDLE. In addition, all of these handles must have been created in this driver's
   1126      Start() function, and the Start() function must have called OpenProtocol() on
   1127      ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
   1128 
   1129   @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
   1130   @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
   1131                                 support a bus specific I/O protocol for the driver
   1132                                 to use to stop the device.
   1133   @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
   1134   @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
   1135                                 if NumberOfChildren is 0.
   1136 
   1137   @retval EFI_SUCCESS           The device was stopped.
   1138   @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
   1139 
   1140 **/
   1141 EFI_STATUS
   1142 EFIAPI
   1143 NvmExpressDriverBindingStop (
   1144   IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
   1145   IN  EFI_HANDLE                      Controller,
   1146   IN  UINTN                           NumberOfChildren,
   1147   IN  EFI_HANDLE                      *ChildHandleBuffer
   1148   )
   1149 {
   1150   EFI_STATUS                          Status;
   1151   BOOLEAN                             AllChildrenStopped;
   1152   UINTN                               Index;
   1153   NVME_CONTROLLER_PRIVATE_DATA        *Private;
   1154   EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL  *PassThru;
   1155   BOOLEAN                             IsEmpty;
   1156   EFI_TPL                             OldTpl;
   1157 
   1158   if (NumberOfChildren == 0) {
   1159     Status = gBS->OpenProtocol (
   1160                     Controller,
   1161                     &gEfiNvmExpressPassThruProtocolGuid,
   1162                     (VOID **) &PassThru,
   1163                     This->DriverBindingHandle,
   1164                     Controller,
   1165                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
   1166                     );
   1167 
   1168     if (!EFI_ERROR (Status)) {
   1169       Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (PassThru);
   1170 
   1171       //
   1172       // Wait for the asynchronous PassThru queue to become empty.
   1173       //
   1174       while (TRUE) {
   1175         OldTpl  = gBS->RaiseTPL (TPL_NOTIFY);
   1176         IsEmpty = IsListEmpty (&Private->AsyncPassThruQueue) &&
   1177                   IsListEmpty (&Private->UnsubmittedSubtasks);
   1178         gBS->RestoreTPL (OldTpl);
   1179 
   1180         if (IsEmpty) {
   1181           break;
   1182         }
   1183 
   1184         gBS->Stall (100);
   1185       }
   1186 
   1187       gBS->UninstallMultipleProtocolInterfaces (
   1188             Controller,
   1189             &gEfiNvmExpressPassThruProtocolGuid,
   1190             PassThru,
   1191             NULL
   1192             );
   1193 
   1194       if (Private->TimerEvent != NULL) {
   1195         gBS->CloseEvent (Private->TimerEvent);
   1196       }
   1197 
   1198       if (Private->Mapping != NULL) {
   1199         Private->PciIo->Unmap (Private->PciIo, Private->Mapping);
   1200       }
   1201 
   1202       if (Private->Buffer != NULL) {
   1203         Private->PciIo->FreeBuffer (Private->PciIo, 6, Private->Buffer);
   1204       }
   1205 
   1206       FreePool (Private->ControllerData);
   1207       FreePool (Private);
   1208     }
   1209 
   1210     gBS->CloseProtocol (
   1211           Controller,
   1212           &gEfiPciIoProtocolGuid,
   1213           This->DriverBindingHandle,
   1214           Controller
   1215           );
   1216     gBS->CloseProtocol (
   1217           Controller,
   1218           &gEfiDevicePathProtocolGuid,
   1219           This->DriverBindingHandle,
   1220           Controller
   1221           );
   1222     return EFI_SUCCESS;
   1223   }
   1224 
   1225   AllChildrenStopped = TRUE;
   1226 
   1227   for (Index = 0; Index < NumberOfChildren; Index++) {
   1228     Status = UnregisterNvmeNamespace (This, Controller, ChildHandleBuffer[Index]);
   1229     if (EFI_ERROR (Status)) {
   1230       AllChildrenStopped = FALSE;
   1231     }
   1232   }
   1233 
   1234   if (!AllChildrenStopped) {
   1235     return EFI_DEVICE_ERROR;
   1236   }
   1237 
   1238   return EFI_SUCCESS;
   1239 }
   1240 
   1241 /**
   1242   This is the unload handle for the NVM Express driver.
   1243 
   1244   Disconnect the driver specified by ImageHandle from the NVMe device in the handle database.
   1245   Uninstall all the protocols installed in the driver.
   1246 
   1247   @param[in]  ImageHandle       The drivers' driver image.
   1248 
   1249   @retval EFI_SUCCESS           The image is unloaded.
   1250   @retval Others                Failed to unload the image.
   1251 
   1252 **/
   1253 EFI_STATUS
   1254 EFIAPI
   1255 NvmExpressUnload (
   1256   IN EFI_HANDLE             ImageHandle
   1257   )
   1258 {
   1259   EFI_STATUS                        Status;
   1260   EFI_HANDLE                        *DeviceHandleBuffer;
   1261   UINTN                             DeviceHandleCount;
   1262   UINTN                             Index;
   1263   EFI_COMPONENT_NAME_PROTOCOL       *ComponentName;
   1264   EFI_COMPONENT_NAME2_PROTOCOL      *ComponentName2;
   1265 
   1266   //
   1267   // Get the list of the device handles managed by this driver.
   1268   // If there is an error getting the list, then means the driver
   1269   // doesn't manage any device. At this way, we would only close
   1270   // those protocols installed at image handle.
   1271   //
   1272   DeviceHandleBuffer = NULL;
   1273   Status = gBS->LocateHandleBuffer (
   1274                   ByProtocol,
   1275                   &gEfiNvmExpressPassThruProtocolGuid,
   1276                   NULL,
   1277                   &DeviceHandleCount,
   1278                   &DeviceHandleBuffer
   1279                   );
   1280 
   1281   if (!EFI_ERROR (Status)) {
   1282     //
   1283     // Disconnect the driver specified by ImageHandle from all
   1284     // the devices in the handle database.
   1285     //
   1286     for (Index = 0; Index < DeviceHandleCount; Index++) {
   1287       Status = gBS->DisconnectController (
   1288                       DeviceHandleBuffer[Index],
   1289                       ImageHandle,
   1290                       NULL
   1291                       );
   1292       if (EFI_ERROR (Status)) {
   1293         goto EXIT;
   1294       }
   1295     }
   1296   }
   1297 
   1298   //
   1299   // Uninstall all the protocols installed in the driver entry point
   1300   //
   1301   Status = gBS->UninstallMultipleProtocolInterfaces (
   1302                   ImageHandle,
   1303                   &gEfiDriverBindingProtocolGuid,
   1304                   &gNvmExpressDriverBinding,
   1305                   &gEfiDriverSupportedEfiVersionProtocolGuid,
   1306                   &gNvmExpressDriverSupportedEfiVersion,
   1307                   NULL
   1308                   );
   1309 
   1310   if (EFI_ERROR (Status)) {
   1311     goto EXIT;
   1312   }
   1313 
   1314   //
   1315   // Note we have to one by one uninstall the following protocols.
   1316   // It's because some of them are optionally installed based on
   1317   // the following PCD settings.
   1318   //   gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable
   1319   //   gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable
   1320   //   gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable
   1321   //   gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable
   1322   //
   1323   Status = gBS->HandleProtocol (
   1324                   ImageHandle,
   1325                   &gEfiComponentNameProtocolGuid,
   1326                   (VOID **) &ComponentName
   1327                   );
   1328   if (!EFI_ERROR (Status)) {
   1329     gBS->UninstallProtocolInterface (
   1330            ImageHandle,
   1331            &gEfiComponentNameProtocolGuid,
   1332            ComponentName
   1333            );
   1334   }
   1335 
   1336   Status = gBS->HandleProtocol (
   1337                   ImageHandle,
   1338                   &gEfiComponentName2ProtocolGuid,
   1339                   (VOID **) &ComponentName2
   1340                   );
   1341   if (!EFI_ERROR (Status)) {
   1342     gBS->UninstallProtocolInterface (
   1343            ImageHandle,
   1344            &gEfiComponentName2ProtocolGuid,
   1345            ComponentName2
   1346            );
   1347   }
   1348 
   1349   Status = EFI_SUCCESS;
   1350 
   1351 EXIT:
   1352   //
   1353   // Free the buffer containing the list of handles from the handle database
   1354   //
   1355   if (DeviceHandleBuffer != NULL) {
   1356     gBS->FreePool (DeviceHandleBuffer);
   1357   }
   1358   return Status;
   1359 }
   1360 
   1361 /**
   1362   The entry point for Nvm Express driver, used to install Nvm Express driver on the ImageHandle.
   1363 
   1364   @param  ImageHandle   The firmware allocated handle for this driver image.
   1365   @param  SystemTable   Pointer to the EFI system table.
   1366 
   1367   @retval EFI_SUCCESS   Driver loaded.
   1368   @retval other         Driver not loaded.
   1369 
   1370 **/
   1371 EFI_STATUS
   1372 EFIAPI
   1373 NvmExpressDriverEntry (
   1374   IN EFI_HANDLE        ImageHandle,
   1375   IN EFI_SYSTEM_TABLE  *SystemTable
   1376   )
   1377 {
   1378   EFI_STATUS              Status;
   1379 
   1380   Status = EfiLibInstallDriverBindingComponentName2 (
   1381              ImageHandle,
   1382              SystemTable,
   1383              &gNvmExpressDriverBinding,
   1384              ImageHandle,
   1385              &gNvmExpressComponentName,
   1386              &gNvmExpressComponentName2
   1387              );
   1388   ASSERT_EFI_ERROR (Status);
   1389 
   1390   //
   1391   // Install EFI Driver Supported EFI Version Protocol required for
   1392   // EFI drivers that are on PCI and other plug in cards.
   1393   //
   1394   gNvmExpressDriverSupportedEfiVersion.FirmwareVersion = 0x00020028;
   1395   Status = gBS->InstallMultipleProtocolInterfaces (
   1396                   &ImageHandle,
   1397                   &gEfiDriverSupportedEfiVersionProtocolGuid,
   1398                   &gNvmExpressDriverSupportedEfiVersion,
   1399                   NULL
   1400                   );
   1401   ASSERT_EFI_ERROR (Status);
   1402   return Status;
   1403 }
   1404