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