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   (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
      6   Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
      7   This program and the accompanying materials
      8   are licensed and made available under the terms and conditions of the BSD License
      9   which accompanies this distribution.  The full text of the license may be found at
     10   http://opensource.org/licenses/bsd-license.php.
     11 
     12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 
     15 **/
     16 
     17 #ifndef _EFI_NVM_EXPRESS_H_
     18 #define _EFI_NVM_EXPRESS_H_
     19 
     20 #include <Uefi.h>
     21 
     22 #include <IndustryStandard/Pci.h>
     23 #include <IndustryStandard/Nvme.h>
     24 
     25 #include <Protocol/ComponentName.h>
     26 #include <Protocol/ComponentName2.h>
     27 #include <Protocol/DriverBinding.h>
     28 #include <Protocol/LoadedImage.h>
     29 #include <Protocol/DevicePath.h>
     30 #include <Protocol/PciIo.h>
     31 #include <Protocol/NvmExpressPassthru.h>
     32 #include <Protocol/BlockIo.h>
     33 #include <Protocol/BlockIo2.h>
     34 #include <Protocol/DiskInfo.h>
     35 #include <Protocol/DriverSupportedEfiVersion.h>
     36 #include <Protocol/StorageSecurityCommand.h>
     37 
     38 #include <Library/BaseLib.h>
     39 #include <Library/BaseMemoryLib.h>
     40 #include <Library/DebugLib.h>
     41 #include <Library/PrintLib.h>
     42 #include <Library/UefiLib.h>
     43 #include <Library/DevicePathLib.h>
     44 #include <Library/MemoryAllocationLib.h>
     45 #include <Library/UefiBootServicesTableLib.h>
     46 #include <Library/UefiDriverEntryPoint.h>
     47 
     48 typedef struct _NVME_CONTROLLER_PRIVATE_DATA NVME_CONTROLLER_PRIVATE_DATA;
     49 typedef struct _NVME_DEVICE_PRIVATE_DATA     NVME_DEVICE_PRIVATE_DATA;
     50 
     51 #include "NvmExpressBlockIo.h"
     52 #include "NvmExpressDiskInfo.h"
     53 #include "NvmExpressHci.h"
     54 
     55 extern EFI_DRIVER_BINDING_PROTOCOL                gNvmExpressDriverBinding;
     56 extern EFI_COMPONENT_NAME_PROTOCOL                gNvmExpressComponentName;
     57 extern EFI_COMPONENT_NAME2_PROTOCOL               gNvmExpressComponentName2;
     58 extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL  gNvmExpressDriverSupportedEfiVersion;
     59 
     60 #define PCI_CLASS_MASS_STORAGE_NVM                0x08  // mass storage sub-class non-volatile memory.
     61 #define PCI_IF_NVMHCI                             0x02  // mass storage programming interface NVMHCI.
     62 
     63 #define NVME_ASQ_SIZE                             1     // Number of admin submission queue entries, which is 0-based
     64 #define NVME_ACQ_SIZE                             1     // Number of admin completion queue entries, which is 0-based
     65 
     66 #define NVME_CSQ_SIZE                             1     // Number of I/O submission queue entries, which is 0-based
     67 #define NVME_CCQ_SIZE                             1     // Number of I/O completion queue entries, which is 0-based
     68 
     69 //
     70 // Number of asynchronous I/O submission queue entries, which is 0-based.
     71 // The asynchronous I/O submission queue size is 4kB in total.
     72 //
     73 #define NVME_ASYNC_CSQ_SIZE                       63
     74 //
     75 // Number of asynchronous I/O completion queue entries, which is 0-based.
     76 // The asynchronous I/O completion queue size is 4kB in total.
     77 //
     78 #define NVME_ASYNC_CCQ_SIZE                       255
     79 
     80 #define NVME_MAX_QUEUES                           3     // Number of queues supported by the driver
     81 
     82 #define NVME_CONTROLLER_ID                        0
     83 
     84 //
     85 // Time out value for Nvme transaction execution
     86 //
     87 #define NVME_GENERIC_TIMEOUT                      EFI_TIMER_PERIOD_SECONDS (5)
     88 
     89 //
     90 // Nvme async transfer timer interval, set by experience.
     91 //
     92 #define NVME_HC_ASYNC_TIMER                       EFI_TIMER_PERIOD_MILLISECONDS (1)
     93 
     94 //
     95 // Unique signature for private data structure.
     96 //
     97 #define NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE    SIGNATURE_32 ('N','V','M','E')
     98 
     99 //
    100 // Nvme private data structure.
    101 //
    102 struct _NVME_CONTROLLER_PRIVATE_DATA {
    103   UINT32                              Signature;
    104 
    105   EFI_HANDLE                          ControllerHandle;
    106   EFI_HANDLE                          ImageHandle;
    107   EFI_HANDLE                          DriverBindingHandle;
    108 
    109   EFI_PCI_IO_PROTOCOL                 *PciIo;
    110   UINT64                              PciAttributes;
    111 
    112   EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;
    113 
    114   EFI_NVM_EXPRESS_PASS_THRU_MODE      PassThruMode;
    115   EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL  Passthru;
    116 
    117   //
    118   // pointer to identify controller data
    119   //
    120   NVME_ADMIN_CONTROLLER_DATA          *ControllerData;
    121 
    122   //
    123   // 6 x 4kB aligned buffers will be carved out of this buffer.
    124   // 1st 4kB boundary is the start of the admin submission queue.
    125   // 2nd 4kB boundary is the start of the admin completion queue.
    126   // 3rd 4kB boundary is the start of I/O submission queue #1.
    127   // 4th 4kB boundary is the start of I/O completion queue #1.
    128   // 5th 4kB boundary is the start of I/O submission queue #2.
    129   // 6th 4kB boundary is the start of I/O completion queue #2.
    130   //
    131   UINT8                               *Buffer;
    132   UINT8                               *BufferPciAddr;
    133 
    134   //
    135   // Pointers to 4kB aligned submission & completion queues.
    136   //
    137   NVME_SQ                             *SqBuffer[NVME_MAX_QUEUES];
    138   NVME_CQ                             *CqBuffer[NVME_MAX_QUEUES];
    139   NVME_SQ                             *SqBufferPciAddr[NVME_MAX_QUEUES];
    140   NVME_CQ                             *CqBufferPciAddr[NVME_MAX_QUEUES];
    141 
    142   //
    143   // Submission and completion queue indices.
    144   //
    145   NVME_SQTDBL                         SqTdbl[NVME_MAX_QUEUES];
    146   NVME_CQHDBL                         CqHdbl[NVME_MAX_QUEUES];
    147   UINT16                              AsyncSqHead;
    148 
    149   UINT8                               Pt[NVME_MAX_QUEUES];
    150   UINT16                              Cid[NVME_MAX_QUEUES];
    151 
    152   //
    153   // Nvme controller capabilities
    154   //
    155   NVME_CAP                            Cap;
    156 
    157   VOID                                *Mapping;
    158 
    159   //
    160   // For Non-blocking operations.
    161   //
    162   EFI_EVENT                           TimerEvent;
    163   LIST_ENTRY                          AsyncPassThruQueue;
    164   LIST_ENTRY                          UnsubmittedSubtasks;
    165 };
    166 
    167 #define NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU(a) \
    168   CR (a, \
    169       NVME_CONTROLLER_PRIVATE_DATA, \
    170       Passthru, \
    171       NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE \
    172       )
    173 
    174 //
    175 // Unique signature for private data structure.
    176 //
    177 #define NVME_DEVICE_PRIVATE_DATA_SIGNATURE     SIGNATURE_32 ('X','S','S','D')
    178 
    179 //
    180 // Nvme device private data structure
    181 //
    182 struct _NVME_DEVICE_PRIVATE_DATA {
    183   UINT32                                   Signature;
    184 
    185   EFI_HANDLE                               DeviceHandle;
    186   EFI_HANDLE                               ControllerHandle;
    187   EFI_HANDLE                               DriverBindingHandle;
    188 
    189   EFI_DEVICE_PATH_PROTOCOL                 *DevicePath;
    190 
    191   EFI_UNICODE_STRING_TABLE                 *ControllerNameTable;
    192 
    193   UINT32                                   NamespaceId;
    194   UINT64                                   NamespaceUuid;
    195 
    196   EFI_BLOCK_IO_MEDIA                       Media;
    197   EFI_BLOCK_IO_PROTOCOL                    BlockIo;
    198   EFI_BLOCK_IO2_PROTOCOL                   BlockIo2;
    199   EFI_DISK_INFO_PROTOCOL                   DiskInfo;
    200   EFI_STORAGE_SECURITY_COMMAND_PROTOCOL    StorageSecurity;
    201 
    202   LIST_ENTRY                               AsyncQueue;
    203 
    204   EFI_LBA                                  NumBlocks;
    205 
    206   CHAR16                                   ModelName[80];
    207   NVME_ADMIN_NAMESPACE_DATA                NamespaceData;
    208 
    209   NVME_CONTROLLER_PRIVATE_DATA             *Controller;
    210 
    211 };
    212 
    213 //
    214 // Statments to retrieve the private data from produced protocols.
    215 //
    216 #define NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO(a) \
    217   CR (a, \
    218       NVME_DEVICE_PRIVATE_DATA, \
    219       BlockIo, \
    220       NVME_DEVICE_PRIVATE_DATA_SIGNATURE \
    221       )
    222 
    223 #define NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2(a) \
    224   CR (a, \
    225       NVME_DEVICE_PRIVATE_DATA, \
    226       BlockIo2, \
    227       NVME_DEVICE_PRIVATE_DATA_SIGNATURE \
    228       )
    229 
    230 #define NVME_DEVICE_PRIVATE_DATA_FROM_DISK_INFO(a) \
    231   CR (a, \
    232       NVME_DEVICE_PRIVATE_DATA, \
    233       DiskInfo, \
    234       NVME_DEVICE_PRIVATE_DATA_SIGNATURE \
    235       )
    236 
    237 #define NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY(a)\
    238   CR (a,                                                 \
    239       NVME_DEVICE_PRIVATE_DATA,                          \
    240       StorageSecurity,                                   \
    241       NVME_DEVICE_PRIVATE_DATA_SIGNATURE                 \
    242       )
    243 
    244 //
    245 // Nvme block I/O 2 request.
    246 //
    247 #define NVME_BLKIO2_REQUEST_SIGNATURE      SIGNATURE_32 ('N', 'B', '2', 'R')
    248 
    249 typedef struct {
    250   UINT32                                   Signature;
    251   LIST_ENTRY                               Link;
    252 
    253   EFI_BLOCK_IO2_TOKEN                      *Token;
    254   UINTN                                    UnsubmittedSubtaskNum;
    255   BOOLEAN                                  LastSubtaskSubmitted;
    256   //
    257   // The queue for Nvme read/write sub-tasks of a BlockIo2 request.
    258   //
    259   LIST_ENTRY                               SubtasksQueue;
    260 } NVME_BLKIO2_REQUEST;
    261 
    262 #define NVME_BLKIO2_REQUEST_FROM_LINK(a) \
    263   CR (a, NVME_BLKIO2_REQUEST, Link, NVME_BLKIO2_REQUEST_SIGNATURE)
    264 
    265 #define NVME_BLKIO2_SUBTASK_SIGNATURE      SIGNATURE_32 ('N', 'B', '2', 'S')
    266 
    267 typedef struct {
    268   UINT32                                   Signature;
    269   LIST_ENTRY                               Link;
    270 
    271   BOOLEAN                                  IsLast;
    272   UINT32                                   NamespaceId;
    273   EFI_EVENT                                Event;
    274   EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *CommandPacket;
    275   //
    276   // The BlockIo2 request this subtask belongs to
    277   //
    278   NVME_BLKIO2_REQUEST                      *BlockIo2Request;
    279 } NVME_BLKIO2_SUBTASK;
    280 
    281 #define NVME_BLKIO2_SUBTASK_FROM_LINK(a) \
    282   CR (a, NVME_BLKIO2_SUBTASK, Link, NVME_BLKIO2_SUBTASK_SIGNATURE)
    283 
    284 //
    285 // Nvme asynchronous passthru request.
    286 //
    287 #define NVME_PASS_THRU_ASYNC_REQ_SIG       SIGNATURE_32 ('N', 'P', 'A', 'R')
    288 
    289 typedef struct {
    290   UINT32                                   Signature;
    291   LIST_ENTRY                               Link;
    292 
    293   EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet;
    294   UINT16                                   CommandId;
    295   EFI_EVENT                                CallerEvent;
    296 } NVME_PASS_THRU_ASYNC_REQ;
    297 
    298 #define NVME_PASS_THRU_ASYNC_REQ_FROM_THIS(a) \
    299   CR (a,                                                 \
    300       NVME_PASS_THRU_ASYNC_REQ,                          \
    301       Link,                                              \
    302       NVME_PASS_THRU_ASYNC_REQ_SIG                       \
    303       )
    304 
    305 /**
    306   Retrieves a Unicode string that is the user readable name of the driver.
    307 
    308   This function retrieves the user readable name of a driver in the form of a
    309   Unicode string. If the driver specified by This has a user readable name in
    310   the language specified by Language, then a pointer to the driver name is
    311   returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
    312   by This does not support the language specified by Language,
    313   then EFI_UNSUPPORTED is returned.
    314 
    315   @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
    316                                 EFI_COMPONENT_NAME_PROTOCOL instance.
    317 
    318   @param  Language[in]          A pointer to a Null-terminated ASCII string
    319                                 array indicating the language. This is the
    320                                 language of the driver name that the caller is
    321                                 requesting, and it must match one of the
    322                                 languages specified in SupportedLanguages. The
    323                                 number of languages supported by a driver is up
    324                                 to the driver writer. Language is specified
    325                                 in RFC 4646 or ISO 639-2 language code format.
    326 
    327   @param  DriverName[out]       A pointer to the Unicode string to return.
    328                                 This Unicode string is the name of the
    329                                 driver specified by This in the language
    330                                 specified by Language.
    331 
    332   @retval EFI_SUCCESS           The Unicode string for the Driver specified by
    333                                 This and the language specified by Language was
    334                                 returned in DriverName.
    335 
    336   @retval EFI_INVALID_PARAMETER Language is NULL.
    337 
    338   @retval EFI_INVALID_PARAMETER DriverName is NULL.
    339 
    340   @retval EFI_UNSUPPORTED       The driver specified by This does not support
    341                                 the language specified by Language.
    342 
    343 **/
    344 EFI_STATUS
    345 EFIAPI
    346 NvmExpressComponentNameGetDriverName (
    347   IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
    348   IN  CHAR8                        *Language,
    349   OUT CHAR16                       **DriverName
    350   );
    351 
    352 /**
    353   Retrieves a Unicode string that is the user readable name of the controller
    354   that is being managed by a driver.
    355 
    356   This function retrieves the user readable name of the controller specified by
    357   ControllerHandle and ChildHandle in the form of a Unicode string. If the
    358   driver specified by This has a user readable name in the language specified by
    359   Language, then a pointer to the controller name is returned in ControllerName,
    360   and EFI_SUCCESS is returned.  If the driver specified by This is not currently
    361   managing the controller specified by ControllerHandle and ChildHandle,
    362   then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
    363   support the language specified by Language, then EFI_UNSUPPORTED is returned.
    364 
    365   @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
    366                                 EFI_COMPONENT_NAME_PROTOCOL instance.
    367 
    368   @param  ControllerHandle[in]  The handle of a controller that the driver
    369                                 specified by This is managing.  This handle
    370                                 specifies the controller whose name is to be
    371                                 returned.
    372 
    373   @param  ChildHandle[in]       The handle of the child controller to retrieve
    374                                 the name of.  This is an optional parameter that
    375                                 may be NULL.  It will be NULL for device
    376                                 drivers.  It will also be NULL for a bus drivers
    377                                 that wish to retrieve the name of the bus
    378                                 controller.  It will not be NULL for a bus
    379                                 driver that wishes to retrieve the name of a
    380                                 child controller.
    381 
    382   @param  Language[in]          A pointer to a Null-terminated ASCII string
    383                                 array indicating the language.  This is the
    384                                 language of the driver name that the caller is
    385                                 requesting, and it must match one of the
    386                                 languages specified in SupportedLanguages. The
    387                                 number of languages supported by a driver is up
    388                                 to the driver writer. Language is specified in
    389                                 RFC 4646 or ISO 639-2 language code format.
    390 
    391   @param  ControllerName[out]   A pointer to the Unicode string to return.
    392                                 This Unicode string is the name of the
    393                                 controller specified by ControllerHandle and
    394                                 ChildHandle in the language specified by
    395                                 Language from the point of view of the driver
    396                                 specified by This.
    397 
    398   @retval EFI_SUCCESS           The Unicode string for the user readable name in
    399                                 the language specified by Language for the
    400                                 driver specified by This was returned in
    401                                 DriverName.
    402 
    403   @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
    404 
    405   @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
    406                                 EFI_HANDLE.
    407 
    408   @retval EFI_INVALID_PARAMETER Language is NULL.
    409 
    410   @retval EFI_INVALID_PARAMETER ControllerName is NULL.
    411 
    412   @retval EFI_UNSUPPORTED       The driver specified by This is not currently
    413                                 managing the controller specified by
    414                                 ControllerHandle and ChildHandle.
    415 
    416   @retval EFI_UNSUPPORTED       The driver specified by This does not support
    417                                 the language specified by Language.
    418 
    419 **/
    420 EFI_STATUS
    421 EFIAPI
    422 NvmExpressComponentNameGetControllerName (
    423   IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
    424   IN  EFI_HANDLE                                      ControllerHandle,
    425   IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
    426   IN  CHAR8                                           *Language,
    427   OUT CHAR16                                          **ControllerName
    428   );
    429 
    430 /**
    431   Tests to see if this driver supports a given controller. If a child device is provided,
    432   it further tests to see if this driver supports creating a handle for the specified child device.
    433 
    434   This function checks to see if the driver specified by This supports the device specified by
    435   ControllerHandle. Drivers will typically use the device path attached to
    436   ControllerHandle and/or the services from the bus I/O abstraction attached to
    437   ControllerHandle to determine if the driver supports ControllerHandle. This function
    438   may be called many times during platform initialization. In order to reduce boot times, the tests
    439   performed by this function must be very small, and take as little time as possible to execute. This
    440   function must not change the state of any hardware devices, and this function must be aware that the
    441   device specified by ControllerHandle may already be managed by the same driver or a
    442   different driver. This function must match its calls to AllocatePages() with FreePages(),
    443   AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
    444   Since ControllerHandle may have been previously started by the same driver, if a protocol is
    445   already in the opened state, then it must not be closed with CloseProtocol(). This is required
    446   to guarantee the state of ControllerHandle is not modified by this function.
    447 
    448   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    449   @param[in]  ControllerHandle     The handle of the controller to test. This handle
    450                                    must support a protocol interface that supplies
    451                                    an I/O abstraction to the driver.
    452   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    453                                    parameter is ignored by device drivers, and is optional for bus
    454                                    drivers. For bus drivers, if this parameter is not NULL, then
    455                                    the bus driver must determine if the bus controller specified
    456                                    by ControllerHandle and the child controller specified
    457                                    by RemainingDevicePath are both supported by this
    458                                    bus driver.
    459 
    460   @retval EFI_SUCCESS              The device specified by ControllerHandle and
    461                                    RemainingDevicePath is supported by the driver specified by This.
    462   @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
    463                                    RemainingDevicePath is already being managed by the driver
    464                                    specified by This.
    465   @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
    466                                    RemainingDevicePath is already being managed by a different
    467                                    driver or an application that requires exclusive access.
    468                                    Currently not implemented.
    469   @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
    470                                    RemainingDevicePath is not supported by the driver specified by This.
    471 **/
    472 EFI_STATUS
    473 EFIAPI
    474 NvmExpressDriverBindingSupported (
    475   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    476   IN EFI_HANDLE                   Controller,
    477   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
    478   );
    479 
    480 /**
    481   Starts a device controller or a bus controller.
    482 
    483   The Start() function is designed to be invoked from the EFI boot service ConnectController().
    484   As a result, much of the error checking on the parameters to Start() has been moved into this
    485   common boot service. It is legal to call Start() from other locations,
    486   but the following calling restrictions must be followed or the system behavior will not be deterministic.
    487   1. ControllerHandle must be a valid EFI_HANDLE.
    488   2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
    489      EFI_DEVICE_PATH_PROTOCOL.
    490   3. Prior to calling Start(), the Supported() function for the driver specified by This must
    491      have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
    492 
    493   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    494   @param[in]  ControllerHandle     The handle of the controller to start. This handle
    495                                    must support a protocol interface that supplies
    496                                    an I/O abstraction to the driver.
    497   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    498                                    parameter is ignored by device drivers, and is optional for bus
    499                                    drivers. For a bus driver, if this parameter is NULL, then handles
    500                                    for all the children of Controller are created by this driver.
    501                                    If this parameter is not NULL and the first Device Path Node is
    502                                    not the End of Device Path Node, then only the handle for the
    503                                    child device specified by the first Device Path Node of
    504                                    RemainingDevicePath is created by this driver.
    505                                    If the first Device Path Node of RemainingDevicePath is
    506                                    the End of Device Path Node, no child handle is created by this
    507                                    driver.
    508 
    509   @retval EFI_SUCCESS              The device was started.
    510   @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
    511   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
    512   @retval Others                   The driver failded to start the device.
    513 
    514 **/
    515 EFI_STATUS
    516 EFIAPI
    517 NvmExpressDriverBindingStart (
    518   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    519   IN EFI_HANDLE                   Controller,
    520   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
    521   );
    522 
    523 /**
    524   Stops a device controller or a bus controller.
    525 
    526   The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
    527   As a result, much of the error checking on the parameters to Stop() has been moved
    528   into this common boot service. It is legal to call Stop() from other locations,
    529   but the following calling restrictions must be followed or the system behavior will not be deterministic.
    530   1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
    531      same driver's Start() function.
    532   2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
    533      EFI_HANDLE. In addition, all of these handles must have been created in this driver's
    534      Start() function, and the Start() function must have called OpenProtocol() on
    535      ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
    536 
    537   @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    538   @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
    539                                 support a bus specific I/O protocol for the driver
    540                                 to use to stop the device.
    541   @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
    542   @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
    543                                 if NumberOfChildren is 0.
    544 
    545   @retval EFI_SUCCESS           The device was stopped.
    546   @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
    547 
    548 **/
    549 EFI_STATUS
    550 EFIAPI
    551 NvmExpressDriverBindingStop (
    552   IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
    553   IN  EFI_HANDLE                      Controller,
    554   IN  UINTN                           NumberOfChildren,
    555   IN  EFI_HANDLE                      *ChildHandleBuffer
    556   );
    557 
    558 /**
    559   Sends an NVM Express Command Packet to an NVM Express controller or namespace. This function supports
    560   both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the nonblocking
    561   I/O functionality is optional.
    562 
    563   @param[in]     This                A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance.
    564   @param[in]     NamespaceId         Is a 32 bit Namespace ID to which the Express HCI command packet will be sent.
    565                                      A value of 0 denotes the NVM Express controller, a value of all 0FFh in the namespace
    566                                      ID specifies that the command packet should be sent to all valid namespaces.
    567   @param[in,out] Packet              A pointer to the NVM Express HCI Command Packet to send to the NVMe namespace specified
    568                                      by NamespaceId.
    569   @param[in]     Event               If nonblocking I/O is not supported then Event is ignored, and blocking I/O is performed.
    570                                      If Event is NULL, then blocking I/O is performed. If Event is not NULL and non blocking I/O
    571                                      is supported, then nonblocking I/O is performed, and Event will be signaled when the NVM
    572                                      Express Command Packet completes.
    573 
    574   @retval EFI_SUCCESS                The NVM Express Command Packet was sent by the host. TransferLength bytes were transferred
    575                                      to, or from DataBuffer.
    576   @retval EFI_BAD_BUFFER_SIZE        The NVM Express Command Packet was not executed. The number of bytes that could be transferred
    577                                      is returned in TransferLength.
    578   @retval EFI_NOT_READY              The NVM Express Command Packet could not be sent because the controller is not ready. The caller
    579                                      may retry again later.
    580   @retval EFI_DEVICE_ERROR           A device error occurred while attempting to send the NVM Express Command Packet.
    581   @retval EFI_INVALID_PARAMETER      Namespace, or the contents of EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET are invalid. The NVM
    582                                      Express Command Packet was not sent, so no additional status information is available.
    583   @retval EFI_UNSUPPORTED            The command described by the NVM Express Command Packet is not supported by the host adapter.
    584                                      The NVM Express Command Packet was not sent, so no additional status information is available.
    585   @retval EFI_TIMEOUT                A timeout occurred while waiting for the NVM Express Command Packet to execute.
    586 
    587 **/
    588 EFI_STATUS
    589 EFIAPI
    590 NvmExpressPassThru (
    591   IN     EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL          *This,
    592   IN     UINT32                                      NamespaceId,
    593   IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    *Packet,
    594   IN     EFI_EVENT                                   Event OPTIONAL
    595   );
    596 
    597 /**
    598   Used to retrieve the next namespace ID for this NVM Express controller.
    599 
    600   The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNextNamespace() function retrieves the next valid
    601   namespace ID on this NVM Express controller.
    602 
    603   If on input the value pointed to by NamespaceId is 0xFFFFFFFF, then the first valid namespace
    604   ID defined on the NVM Express controller is returned in the location pointed to by NamespaceId
    605   and a status of EFI_SUCCESS is returned.
    606 
    607   If on input the value pointed to by NamespaceId is an invalid namespace ID other than 0xFFFFFFFF,
    608   then EFI_INVALID_PARAMETER is returned.
    609 
    610   If on input the value pointed to by NamespaceId is a valid namespace ID, then the next valid
    611   namespace ID on the NVM Express controller is returned in the location pointed to by NamespaceId,
    612   and EFI_SUCCESS is returned.
    613 
    614   If the value pointed to by NamespaceId is the namespace ID of the last namespace on the NVM
    615   Express controller, then EFI_NOT_FOUND is returned.
    616 
    617   @param[in]     This           A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance.
    618   @param[in,out] NamespaceId    On input, a pointer to a legal NamespaceId for an NVM Express
    619                                 namespace present on the NVM Express controller. On output, a
    620                                 pointer to the next NamespaceId of an NVM Express namespace on
    621                                 an NVM Express controller. An input value of 0xFFFFFFFF retrieves
    622                                 the first NamespaceId for an NVM Express namespace present on an
    623                                 NVM Express controller.
    624 
    625   @retval EFI_SUCCESS           The Namespace ID of the next Namespace was returned.
    626   @retval EFI_NOT_FOUND         There are no more namespaces defined on this controller.
    627   @retval EFI_INVALID_PARAMETER NamespaceId is an invalid value other than 0xFFFFFFFF.
    628 
    629 **/
    630 EFI_STATUS
    631 EFIAPI
    632 NvmExpressGetNextNamespace (
    633   IN     EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL          *This,
    634   IN OUT UINT32                                      *NamespaceId
    635   );
    636 
    637 /**
    638   Used to translate a device path node to a namespace ID.
    639 
    640   The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNamespace() function determines the namespace ID associated with the
    641   namespace described by DevicePath.
    642 
    643   If DevicePath is a device path node type that the NVM Express Pass Thru driver supports, then the NVM Express
    644   Pass Thru driver will attempt to translate the contents DevicePath into a namespace ID.
    645 
    646   If this translation is successful, then that namespace ID is returned in NamespaceId, and EFI_SUCCESS is returned
    647 
    648   @param[in]  This                A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance.
    649   @param[in]  DevicePath          A pointer to the device path node that describes an NVM Express namespace on
    650                                   the NVM Express controller.
    651   @param[out] NamespaceId         The NVM Express namespace ID contained in the device path node.
    652 
    653   @retval EFI_SUCCESS             DevicePath was successfully translated to NamespaceId.
    654   @retval EFI_INVALID_PARAMETER   If DevicePath or NamespaceId are NULL, then EFI_INVALID_PARAMETER is returned.
    655   @retval EFI_UNSUPPORTED         If DevicePath is not a device path node type that the NVM Express Pass Thru driver
    656                                   supports, then EFI_UNSUPPORTED is returned.
    657   @retval EFI_NOT_FOUND           If DevicePath is a device path node type that the NVM Express Pass Thru driver
    658                                   supports, but there is not a valid translation from DevicePath to a namespace ID,
    659                                   then EFI_NOT_FOUND is returned.
    660 **/
    661 EFI_STATUS
    662 EFIAPI
    663 NvmExpressGetNamespace (
    664   IN     EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL          *This,
    665   IN     EFI_DEVICE_PATH_PROTOCOL                    *DevicePath,
    666      OUT UINT32                                      *NamespaceId
    667   );
    668 
    669 /**
    670   Used to allocate and build a device path node for an NVM Express namespace on an NVM Express controller.
    671 
    672   The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.BuildDevicePath() function allocates and builds a single device
    673   path node for the NVM Express namespace specified by NamespaceId.
    674 
    675   If the NamespaceId is not valid, then EFI_NOT_FOUND is returned.
    676 
    677   If DevicePath is NULL, then EFI_INVALID_PARAMETER is returned.
    678 
    679   If there are not enough resources to allocate the device path node, then EFI_OUT_OF_RESOURCES is returned.
    680 
    681   Otherwise, DevicePath is allocated with the boot service AllocatePool(), the contents of DevicePath are
    682   initialized to describe the NVM Express namespace specified by NamespaceId, and EFI_SUCCESS is returned.
    683 
    684   @param[in]     This                A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance.
    685   @param[in]     NamespaceId         The NVM Express namespace ID  for which a device path node is to be
    686                                      allocated and built. Caller must set the NamespaceId to zero if the
    687                                      device path node will contain a valid UUID.
    688   @param[in,out] DevicePath          A pointer to a single device path node that describes the NVM Express
    689                                      namespace specified by NamespaceId. This function is responsible for
    690                                      allocating the buffer DevicePath with the boot service AllocatePool().
    691                                      It is the caller's responsibility to free DevicePath when the caller
    692                                      is finished with DevicePath.
    693   @retval EFI_SUCCESS                The device path node that describes the NVM Express namespace specified
    694                                      by NamespaceId was allocated and returned in DevicePath.
    695   @retval EFI_NOT_FOUND              The NamespaceId is not valid.
    696   @retval EFI_INVALID_PARAMETER      DevicePath is NULL.
    697   @retval EFI_OUT_OF_RESOURCES       There are not enough resources to allocate the DevicePath node.
    698 
    699 **/
    700 EFI_STATUS
    701 EFIAPI
    702 NvmExpressBuildDevicePath (
    703   IN     EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL          *This,
    704   IN     UINT32                                      NamespaceId,
    705   IN OUT EFI_DEVICE_PATH_PROTOCOL                    **DevicePath
    706   );
    707 
    708 /**
    709   Dump the execution status from a given completion queue entry.
    710 
    711   @param[in]     Cq               A pointer to the NVME_CQ item.
    712 
    713 **/
    714 VOID
    715 NvmeDumpStatus (
    716   IN NVME_CQ             *Cq
    717   );
    718 
    719 #endif
    720