• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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