TianoCore EDK2 master
Loading...
Searching...
No Matches
NvmExpress.c
Go to the documentation of this file.
1
11#include "NvmExpress.h"
12
13//
14// NVM Express Driver Binding Protocol Instance
15//
16EFI_DRIVER_BINDING_PROTOCOL gNvmExpressDriverBinding = {
20 0x10,
21 NULL,
22 NULL
23};
24
25//
26// NVM Express EFI Driver Supported EFI Version Protocol Instance
27//
28EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gNvmExpressDriverSupportedEfiVersion = {
29 sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of Protocol structure.
30 0 // Version number to be filled at start up.
31};
32
33//
34// Template for NVM Express Pass Thru Mode data structure.
35//
37 EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL |
38 EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_LOGICAL |
39 EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_NONBLOCKIO |
40 EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_CMD_SET_NVM,
41 sizeof (UINTN),
42 0x10100
43};
44
61 UINT32 NamespaceId
62 )
63{
64 NVME_ADMIN_NAMESPACE_DATA *NamespaceData;
65 EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;
66 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
67 EFI_HANDLE DeviceHandle;
68 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
69 EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
71 EFI_STATUS Status;
72 UINT32 Lbads;
73 UINT32 Flbas;
74 UINT32 LbaFmtIdx;
75 UINT8 Sn[21];
76 UINT8 Mn[41];
77 VOID *DummyInterface;
78
79 NewDevicePathNode = NULL;
80 DevicePath = NULL;
81 Device = NULL;
82
83 //
84 // Allocate a buffer for Identify Namespace data
85 //
86 NamespaceData = AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA));
87 if (NamespaceData == NULL) {
88 return EFI_OUT_OF_RESOURCES;
89 }
90
91 ParentDevicePath = Private->ParentDevicePath;
92 //
93 // Identify Namespace
94 //
95 Status = NvmeIdentifyNamespace (
96 Private,
97 NamespaceId,
98 (VOID *)NamespaceData
99 );
100 if (EFI_ERROR (Status)) {
101 goto Exit;
102 }
103
104 //
105 // Validate Namespace
106 //
107 if (NamespaceData->Ncap == 0) {
108 Status = EFI_DEVICE_ERROR;
109 } else {
110 //
111 // allocate device private data for each discovered namespace
112 //
113 Device = AllocateZeroPool (sizeof (NVME_DEVICE_PRIVATE_DATA));
114 if (Device == NULL) {
115 Status = EFI_OUT_OF_RESOURCES;
116 goto Exit;
117 }
118
119 //
120 // Initialize SSD namespace instance data
121 //
122 Device->Signature = NVME_DEVICE_PRIVATE_DATA_SIGNATURE;
123 Device->NamespaceId = NamespaceId;
124 Device->NamespaceUuid = NamespaceData->Eui64;
125
126 Device->ControllerHandle = Private->ControllerHandle;
127 Device->DriverBindingHandle = Private->DriverBindingHandle;
128 Device->Controller = Private;
129
130 //
131 // Build BlockIo media structure
132 //
133 Device->Media.MediaId = 0;
134 Device->Media.RemovableMedia = FALSE;
135 Device->Media.MediaPresent = TRUE;
136 Device->Media.LogicalPartition = FALSE;
137 Device->Media.ReadOnly = FALSE;
138 Device->Media.WriteCaching = FALSE;
139 Device->Media.IoAlign = Private->PassThruMode.IoAlign;
140
141 Flbas = NamespaceData->Flbas;
142 LbaFmtIdx = Flbas & 0xF;
143
144 //
145 // Currently this NVME driver only suport Metadata Size == 0
146 //
147 if (NamespaceData->LbaFormat[LbaFmtIdx].Ms != 0) {
148 DEBUG ((
149 DEBUG_ERROR,
150 "NVME IDENTIFY NAMESPACE [%d] Ms(%d) is not supported.\n",
151 NamespaceId,
152 NamespaceData->LbaFormat[LbaFmtIdx].Ms
153 ));
154 Status = EFI_UNSUPPORTED;
155 goto Exit;
156 }
157
158 Lbads = NamespaceData->LbaFormat[LbaFmtIdx].Lbads;
159 Device->Media.BlockSize = (UINT32)1 << Lbads;
160
161 Device->Media.LastBlock = NamespaceData->Nsze - 1;
162 Device->Media.LogicalBlocksPerPhysicalBlock = 1;
163 Device->Media.LowestAlignedLba = 1;
164
165 //
166 // Create BlockIo Protocol instance
167 //
168 Device->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2;
169 Device->BlockIo.Media = &Device->Media;
170 Device->BlockIo.Reset = NvmeBlockIoReset;
171 Device->BlockIo.ReadBlocks = NvmeBlockIoReadBlocks;
172 Device->BlockIo.WriteBlocks = NvmeBlockIoWriteBlocks;
173 Device->BlockIo.FlushBlocks = NvmeBlockIoFlushBlocks;
174
175 //
176 // Create BlockIo2 Protocol instance
177 //
178 Device->BlockIo2.Media = &Device->Media;
179 Device->BlockIo2.Reset = NvmeBlockIoResetEx;
180 Device->BlockIo2.ReadBlocksEx = NvmeBlockIoReadBlocksEx;
181 Device->BlockIo2.WriteBlocksEx = NvmeBlockIoWriteBlocksEx;
182 Device->BlockIo2.FlushBlocksEx = NvmeBlockIoFlushBlocksEx;
183 InitializeListHead (&Device->AsyncQueue);
184
185 //
186 // Create Media Sanitize Protocol instance
187 //
188 Device->MediaSanitize.Revision = MEDIA_SANITIZE_PROTOCOL_REVISION;
189 Device->MediaSanitize.Media = &Device->Media;
190 Device->MediaSanitize.MediaClear = NvmExpressMediaClear;
191 Device->MediaSanitize.MediaPurge = NvmExpressMediaPurge;
192 Device->MediaSanitize.MediaFormat = NvmExpressMediaFormat;
193
194 ASSERT (
195 sizeof (Device->MediaSanitize.SanitizeCapabilities) ==
196 sizeof (Device->Controller->ControllerData->Sanicap)
197 );
198
199 CopyMem (
200 &(Device->MediaSanitize.SanitizeCapabilities),
201 &(Device->Controller->ControllerData->Sanicap),
202 sizeof (Device->MediaSanitize.SanitizeCapabilities)
203 );
204
205 //
206 // Create StorageSecurityProtocol Instance
207 //
208 Device->StorageSecurity.ReceiveData = NvmeStorageSecurityReceiveData;
209 Device->StorageSecurity.SendData = NvmeStorageSecuritySendData;
210
211 //
212 // Create DiskInfo Protocol instance
213 //
214 CopyMem (&Device->NamespaceData, NamespaceData, sizeof (NVME_ADMIN_NAMESPACE_DATA));
215 InitializeDiskInfo (Device);
216
217 //
218 // Create a Nvm Express Namespace Device Path Node
219 //
220 Status = Private->Passthru.BuildDevicePath (
221 &Private->Passthru,
222 Device->NamespaceId,
223 &NewDevicePathNode
224 );
225
226 if (EFI_ERROR (Status)) {
227 goto Exit;
228 }
229
230 //
231 // Append the SSD node to the controller's device path
232 //
233 DevicePath = AppendDevicePathNode (ParentDevicePath, NewDevicePathNode);
234 if (DevicePath == NULL) {
235 Status = EFI_OUT_OF_RESOURCES;
236 goto Exit;
237 }
238
239 DeviceHandle = NULL;
240 RemainingDevicePath = DevicePath;
241 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);
242 if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd (RemainingDevicePath)) {
243 Status = EFI_ALREADY_STARTED;
244 FreePool (DevicePath);
245 goto Exit;
246 }
247
248 Device->DevicePath = DevicePath;
249
250 //
251 // Make sure the handle is NULL so we create a new handle
252 //
253 Device->DeviceHandle = NULL;
254
255 Status = gBS->InstallMultipleProtocolInterfaces (
256 &Device->DeviceHandle,
257 &gEfiDevicePathProtocolGuid,
258 Device->DevicePath,
259 &gEfiBlockIoProtocolGuid,
260 &Device->BlockIo,
261 &gEfiBlockIo2ProtocolGuid,
262 &Device->BlockIo2,
263 &gEfiDiskInfoProtocolGuid,
264 &Device->DiskInfo,
265 &gMediaSanitizeProtocolGuid,
266 &Device->MediaSanitize,
267 NULL
268 );
269
270 if (EFI_ERROR (Status)) {
271 goto Exit;
272 }
273
274 //
275 // Check if the NVMe controller supports the Security Send and Security Receive commands
276 //
277 if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) != 0) {
278 Status = gBS->InstallProtocolInterface (
279 &Device->DeviceHandle,
280 &gEfiStorageSecurityCommandProtocolGuid,
282 &Device->StorageSecurity
283 );
284 if (EFI_ERROR (Status)) {
285 gBS->UninstallMultipleProtocolInterfaces (
286 Device->DeviceHandle,
287 &gEfiDevicePathProtocolGuid,
288 Device->DevicePath,
289 &gEfiBlockIoProtocolGuid,
290 &Device->BlockIo,
291 &gEfiBlockIo2ProtocolGuid,
292 &Device->BlockIo2,
293 &gEfiDiskInfoProtocolGuid,
294 &Device->DiskInfo,
295 &gMediaSanitizeProtocolGuid,
296 &Device->MediaSanitize,
297 NULL
298 );
299 goto Exit;
300 }
301 }
302
303 gBS->OpenProtocol (
304 Private->ControllerHandle,
305 &gEfiNvmExpressPassThruProtocolGuid,
306 (VOID **)&DummyInterface,
307 Private->DriverBindingHandle,
308 Device->DeviceHandle,
309 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
310 );
311
312 //
313 // Dump NvmExpress Identify Namespace Data
314 //
315 DEBUG ((DEBUG_INFO, " == NVME IDENTIFY NAMESPACE [%d] DATA ==\n", NamespaceId));
316 DEBUG ((DEBUG_INFO, " NSZE : 0x%lx\n", NamespaceData->Nsze));
317 DEBUG ((DEBUG_INFO, " NCAP : 0x%lx\n", NamespaceData->Ncap));
318 DEBUG ((DEBUG_INFO, " NUSE : 0x%lx\n", NamespaceData->Nuse));
319 DEBUG ((DEBUG_INFO, " LBAF0.LBADS : 0x%x\n", (NamespaceData->LbaFormat[0].Lbads)));
320
321 //
322 // Build controller name for Component Name (2) protocol.
323 //
324 CopyMem (Sn, Private->ControllerData->Sn, sizeof (Private->ControllerData->Sn));
325 Sn[20] = 0;
326 CopyMem (Mn, Private->ControllerData->Mn, sizeof (Private->ControllerData->Mn));
327 Mn[40] = 0;
328 UnicodeSPrintAsciiFormat (Device->ModelName, sizeof (Device->ModelName), "%a-%a-%lx", Sn, Mn, NamespaceData->Eui64);
329
331 "eng",
332 gNvmExpressComponentName.SupportedLanguages,
333 &Device->ControllerNameTable,
334 Device->ModelName,
335 TRUE
336 );
337
339 "en",
340 gNvmExpressComponentName2.SupportedLanguages,
341 &Device->ControllerNameTable,
342 Device->ModelName,
343 FALSE
344 );
345 }
346
347Exit:
348 if (NamespaceData != NULL) {
349 FreePool (NamespaceData);
350 }
351
352 if (NewDevicePathNode != NULL) {
353 FreePool (NewDevicePathNode);
354 }
355
356 if (EFI_ERROR (Status) && (Device != NULL) && (Device->DevicePath != NULL)) {
357 FreePool (Device->DevicePath);
358 }
359
360 if (EFI_ERROR (Status) && (Device != NULL)) {
361 FreePool (Device);
362 }
363
364 return Status;
365}
366
380 )
381{
382 EFI_STATUS Status;
383 UINT32 NamespaceId;
385
386 NamespaceId = 0xFFFFFFFF;
387 Passthru = &Private->Passthru;
388
389 while (TRUE) {
390 Status = Passthru->GetNextNamespace (
391 Passthru,
392 (UINT32 *)&NamespaceId
393 );
394
395 if (EFI_ERROR (Status)) {
396 break;
397 }
398
400 Private,
401 NamespaceId
402 );
403
404 if (EFI_ERROR (Status)) {
405 continue;
406 }
407 }
408
409 return EFI_SUCCESS;
410}
411
429 IN EFI_HANDLE Controller,
430 IN EFI_HANDLE Handle
431 )
432{
433 EFI_STATUS Status;
434 EFI_BLOCK_IO_PROTOCOL *BlockIo;
437 BOOLEAN IsEmpty;
438 EFI_TPL OldTpl;
439 VOID *DummyInterface;
440
441 BlockIo = NULL;
442
443 Status = gBS->OpenProtocol (
444 Handle,
445 &gEfiBlockIoProtocolGuid,
446 (VOID **)&BlockIo,
447 This->DriverBindingHandle,
448 Controller,
449 EFI_OPEN_PROTOCOL_GET_PROTOCOL
450 );
451 if (EFI_ERROR (Status)) {
452 return Status;
453 }
454
455 Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (BlockIo);
456
457 //
458 // Wait for the device's asynchronous I/O queue to become empty.
459 //
460 while (TRUE) {
461 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
462 IsEmpty = IsListEmpty (&Device->AsyncQueue);
463 gBS->RestoreTPL (OldTpl);
464
465 if (IsEmpty) {
466 break;
467 }
468
469 gBS->Stall (100);
470 }
471
472 //
473 // Close the child handle
474 //
475 gBS->CloseProtocol (
476 Controller,
477 &gEfiNvmExpressPassThruProtocolGuid,
478 This->DriverBindingHandle,
479 Handle
480 );
481
482 //
483 // The Nvm Express driver installs the BlockIo and DiskInfo in the DriverBindingStart().
484 // Here should uninstall both of them.
485 //
486 Status = gBS->UninstallMultipleProtocolInterfaces (
487 Handle,
488 &gEfiDevicePathProtocolGuid,
489 Device->DevicePath,
490 &gEfiBlockIoProtocolGuid,
491 &Device->BlockIo,
492 &gEfiBlockIo2ProtocolGuid,
493 &Device->BlockIo2,
494 &gEfiDiskInfoProtocolGuid,
495 &Device->DiskInfo,
496 &gMediaSanitizeProtocolGuid,
497 &Device->MediaSanitize,
498 NULL
499 );
500
501 if (EFI_ERROR (Status)) {
502 gBS->OpenProtocol (
503 Controller,
504 &gEfiNvmExpressPassThruProtocolGuid,
505 (VOID **)&DummyInterface,
506 This->DriverBindingHandle,
507 Handle,
508 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
509 );
510 return Status;
511 }
512
513 //
514 // If Storage Security Command Protocol is installed, then uninstall this protocol.
515 //
516 Status = gBS->OpenProtocol (
517 Handle,
518 &gEfiStorageSecurityCommandProtocolGuid,
519 (VOID **)&StorageSecurity,
520 This->DriverBindingHandle,
521 Controller,
522 EFI_OPEN_PROTOCOL_GET_PROTOCOL
523 );
524
525 if (!EFI_ERROR (Status)) {
526 Status = gBS->UninstallProtocolInterface (
527 Handle,
528 &gEfiStorageSecurityCommandProtocolGuid,
529 &Device->StorageSecurity
530 );
531 if (EFI_ERROR (Status)) {
532 gBS->OpenProtocol (
533 Controller,
534 &gEfiNvmExpressPassThruProtocolGuid,
535 (VOID **)&DummyInterface,
536 This->DriverBindingHandle,
537 Handle,
538 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
539 );
540 return Status;
541 }
542 }
543
544 if (Device->DevicePath != NULL) {
545 FreePool (Device->DevicePath);
546 }
547
548 if (Device->ControllerNameTable != NULL) {
549 FreeUnicodeStringTable (Device->ControllerNameTable);
550 }
551
552 FreePool (Device);
553
554 return EFI_SUCCESS;
555}
556
565VOID
566EFIAPI
568 IN EFI_EVENT Event,
569 IN VOID *Context
570 )
571{
573 EFI_PCI_IO_PROTOCOL *PciIo;
574 NVME_CQ *Cq;
575 UINT16 QueueId;
576 UINT32 Data;
577 LIST_ENTRY *Link;
578 LIST_ENTRY *NextLink;
579 NVME_PASS_THRU_ASYNC_REQ *AsyncRequest;
580 NVME_BLKIO2_SUBTASK *Subtask;
581 NVME_BLKIO2_REQUEST *BlkIo2Request;
582 EFI_BLOCK_IO2_TOKEN *Token;
583 BOOLEAN HasNewItem;
584 EFI_STATUS Status;
585
586 Private = (NVME_CONTROLLER_PRIVATE_DATA *)Context;
587 QueueId = 2;
588 Cq = Private->CqBuffer[QueueId] + Private->CqHdbl[QueueId].Cqh;
589 HasNewItem = FALSE;
590 PciIo = Private->PciIo;
591
592 //
593 // Submit asynchronous subtasks to the NVMe Submission Queue
594 //
595 for (Link = GetFirstNode (&Private->UnsubmittedSubtasks);
596 !IsNull (&Private->UnsubmittedSubtasks, Link);
597 Link = NextLink)
598 {
599 NextLink = GetNextNode (&Private->UnsubmittedSubtasks, Link);
600 Subtask = NVME_BLKIO2_SUBTASK_FROM_LINK (Link);
601 BlkIo2Request = Subtask->BlockIo2Request;
602 Token = BlkIo2Request->Token;
603 RemoveEntryList (Link);
604 BlkIo2Request->UnsubmittedSubtaskNum--;
605
606 //
607 // If any previous subtask fails, do not process subsequent ones.
608 //
609 if (Token->TransactionStatus != EFI_SUCCESS) {
610 if (IsListEmpty (&BlkIo2Request->SubtasksQueue) &&
611 BlkIo2Request->LastSubtaskSubmitted &&
612 (BlkIo2Request->UnsubmittedSubtaskNum == 0))
613 {
614 //
615 // Remove the BlockIo2 request from the device asynchronous queue.
616 //
617 RemoveEntryList (&BlkIo2Request->Link);
618 FreePool (BlkIo2Request);
619 gBS->SignalEvent (Token->Event);
620 }
621
622 FreePool (Subtask->CommandPacket->NvmeCmd);
623 FreePool (Subtask->CommandPacket->NvmeCompletion);
624 FreePool (Subtask->CommandPacket);
625 FreePool (Subtask);
626
627 continue;
628 }
629
630 Status = Private->Passthru.PassThru (
631 &Private->Passthru,
632 Subtask->NamespaceId,
633 Subtask->CommandPacket,
634 Subtask->Event
635 );
636 if (Status == EFI_NOT_READY) {
637 InsertHeadList (&Private->UnsubmittedSubtasks, Link);
638 BlkIo2Request->UnsubmittedSubtaskNum++;
639 break;
640 } else if (EFI_ERROR (Status)) {
641 Token->TransactionStatus = EFI_DEVICE_ERROR;
642
643 if (IsListEmpty (&BlkIo2Request->SubtasksQueue) &&
644 Subtask->IsLast)
645 {
646 //
647 // Remove the BlockIo2 request from the device asynchronous queue.
648 //
649 RemoveEntryList (&BlkIo2Request->Link);
650 FreePool (BlkIo2Request);
651 gBS->SignalEvent (Token->Event);
652 }
653
654 FreePool (Subtask->CommandPacket->NvmeCmd);
655 FreePool (Subtask->CommandPacket->NvmeCompletion);
656 FreePool (Subtask->CommandPacket);
657 FreePool (Subtask);
658 } else {
659 InsertTailList (&BlkIo2Request->SubtasksQueue, Link);
660 if (Subtask->IsLast) {
661 BlkIo2Request->LastSubtaskSubmitted = TRUE;
662 }
663 }
664 }
665
666 while (Cq->Pt != Private->Pt[QueueId]) {
667 ASSERT (Cq->Sqid == QueueId);
668
669 HasNewItem = TRUE;
670
671 //
672 // Find the command with given Command Id.
673 //
674 for (Link = GetFirstNode (&Private->AsyncPassThruQueue);
675 !IsNull (&Private->AsyncPassThruQueue, Link);
676 Link = NextLink)
677 {
678 NextLink = GetNextNode (&Private->AsyncPassThruQueue, Link);
679 AsyncRequest = NVME_PASS_THRU_ASYNC_REQ_FROM_THIS (Link);
680 if (AsyncRequest->CommandId == Cq->Cid) {
681 //
682 // Copy the Respose Queue entry for this command to the callers
683 // response buffer.
684 //
685 CopyMem (
686 AsyncRequest->Packet->NvmeCompletion,
687 Cq,
689 );
690
691 //
692 // Free the resources allocated before cmd submission
693 //
694 if (AsyncRequest->MapData != NULL) {
695 PciIo->Unmap (PciIo, AsyncRequest->MapData);
696 }
697
698 if (AsyncRequest->MapMeta != NULL) {
699 PciIo->Unmap (PciIo, AsyncRequest->MapMeta);
700 }
701
702 if (AsyncRequest->MapPrpList != NULL) {
703 PciIo->Unmap (PciIo, AsyncRequest->MapPrpList);
704 }
705
706 if (AsyncRequest->PrpListHost != NULL) {
707 PciIo->FreeBuffer (
708 PciIo,
709 AsyncRequest->PrpListNo,
710 AsyncRequest->PrpListHost
711 );
712 }
713
714 RemoveEntryList (Link);
715 gBS->SignalEvent (AsyncRequest->CallerEvent);
716 FreePool (AsyncRequest);
717
718 //
719 // Update submission queue head.
720 //
721 Private->AsyncSqHead = Cq->Sqhd;
722 break;
723 }
724 }
725
726 Private->CqHdbl[QueueId].Cqh++;
727 if (Private->CqHdbl[QueueId].Cqh > MIN (NVME_ASYNC_CCQ_SIZE, Private->Cap.Mqes)) {
728 Private->CqHdbl[QueueId].Cqh = 0;
729 Private->Pt[QueueId] ^= 1;
730 }
731
732 Cq = Private->CqBuffer[QueueId] + Private->CqHdbl[QueueId].Cqh;
733 }
734
735 if (HasNewItem) {
736 Data = ReadUnaligned32 ((UINT32 *)&Private->CqHdbl[QueueId]);
737 PciIo->Mem.Write (
738 PciIo,
739 EfiPciIoWidthUint32,
740 NVME_BAR,
741 NVME_CQHDBL_OFFSET (QueueId, Private->Cap.Dstrd),
742 1,
743 &Data
744 );
745 }
746}
747
791EFIAPI
794 IN EFI_HANDLE Controller,
795 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
796 )
797{
798 EFI_STATUS Status;
799 EFI_DEV_PATH_PTR DevicePathNode;
800 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
801 EFI_PCI_IO_PROTOCOL *PciIo;
802 UINT8 ClassCode[3];
803
804 //
805 // Check whether device path is valid
806 //
807 if (RemainingDevicePath != NULL) {
808 //
809 // Check if RemainingDevicePath is the End of Device Path Node,
810 // if yes, go on checking other conditions
811 //
812 if (!IsDevicePathEnd (RemainingDevicePath)) {
813 //
814 // If RemainingDevicePath isn't the End of Device Path Node,
815 // check its validation
816 //
817 DevicePathNode.DevPath = RemainingDevicePath;
818
819 if ((DevicePathNode.DevPath->Type != MESSAGING_DEVICE_PATH) ||
820 (DevicePathNode.DevPath->SubType != MSG_NVME_NAMESPACE_DP) ||
821 (DevicePathNodeLength (DevicePathNode.DevPath) != sizeof (NVME_NAMESPACE_DEVICE_PATH)))
822 {
823 return EFI_UNSUPPORTED;
824 }
825 }
826 }
827
828 //
829 // Open the EFI Device Path protocol needed to perform the supported test
830 //
831 Status = gBS->OpenProtocol (
832 Controller,
833 &gEfiDevicePathProtocolGuid,
834 (VOID **)&ParentDevicePath,
835 This->DriverBindingHandle,
836 Controller,
837 EFI_OPEN_PROTOCOL_BY_DRIVER
838 );
839 if (Status == EFI_ALREADY_STARTED) {
840 return EFI_SUCCESS;
841 }
842
843 if (EFI_ERROR (Status)) {
844 return Status;
845 }
846
847 //
848 // Close protocol, don't use device path protocol in the Support() function
849 //
850 gBS->CloseProtocol (
851 Controller,
852 &gEfiDevicePathProtocolGuid,
853 This->DriverBindingHandle,
854 Controller
855 );
856
857 //
858 // Attempt to Open PCI I/O Protocol
859 //
860 Status = gBS->OpenProtocol (
861 Controller,
862 &gEfiPciIoProtocolGuid,
863 (VOID **)&PciIo,
864 This->DriverBindingHandle,
865 Controller,
866 EFI_OPEN_PROTOCOL_BY_DRIVER
867 );
868 if (Status == EFI_ALREADY_STARTED) {
869 return EFI_SUCCESS;
870 }
871
872 if (EFI_ERROR (Status)) {
873 return Status;
874 }
875
876 //
877 // Now further check the PCI header: Base class (offset 0x0B) and Sub Class (offset 0x0A).
878 // This controller should be a Nvm Express controller.
879 //
880 Status = PciIo->Pci.Read (
881 PciIo,
882 EfiPciIoWidthUint8,
883 PCI_CLASSCODE_OFFSET,
884 sizeof (ClassCode),
885 ClassCode
886 );
887 if (EFI_ERROR (Status)) {
888 goto Done;
889 }
890
891 //
892 // Examine Nvm Express controller PCI Configuration table fields
893 //
894 if ((ClassCode[0] != PCI_IF_NVMHCI) || (ClassCode[1] != PCI_CLASS_MASS_STORAGE_NVM) || (ClassCode[2] != PCI_CLASS_MASS_STORAGE)) {
895 Status = EFI_UNSUPPORTED;
896 }
897
898Done:
899 gBS->CloseProtocol (
900 Controller,
901 &gEfiPciIoProtocolGuid,
902 This->DriverBindingHandle,
903 Controller
904 );
905
906 return Status;
907}
908
945EFIAPI
948 IN EFI_HANDLE Controller,
949 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
950 )
951{
952 EFI_STATUS Status;
953 EFI_PCI_IO_PROTOCOL *PciIo;
955 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
956 UINT32 NamespaceId;
957 EFI_PHYSICAL_ADDRESS MappedAddr;
958 UINTN Bytes;
960
961 DEBUG ((DEBUG_INFO, "NvmExpressDriverBindingStart: start\n"));
962
963 Private = NULL;
964 Passthru = NULL;
965 ParentDevicePath = NULL;
966
967 Status = gBS->OpenProtocol (
968 Controller,
969 &gEfiDevicePathProtocolGuid,
970 (VOID **)&ParentDevicePath,
971 This->DriverBindingHandle,
972 Controller,
973 EFI_OPEN_PROTOCOL_BY_DRIVER
974 );
975 if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
976 return Status;
977 }
978
979 Status = gBS->OpenProtocol (
980 Controller,
981 &gEfiPciIoProtocolGuid,
982 (VOID **)&PciIo,
983 This->DriverBindingHandle,
984 Controller,
985 EFI_OPEN_PROTOCOL_BY_DRIVER
986 );
987
988 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
989 return Status;
990 }
991
992 //
993 // Check EFI_ALREADY_STARTED to reuse the original NVME_CONTROLLER_PRIVATE_DATA.
994 //
995 if (Status != EFI_ALREADY_STARTED) {
997
998 if (Private == NULL) {
999 DEBUG ((DEBUG_ERROR, "NvmExpressDriverBindingStart: allocating pool for Nvme Private Data failed!\n"));
1000 Status = EFI_OUT_OF_RESOURCES;
1001 goto Exit;
1002 }
1003
1004 //
1005 // Save original PCI attributes
1006 //
1007 Status = PciIo->Attributes (
1008 PciIo,
1010 0,
1011 &Private->PciAttributes
1012 );
1013
1014 if (EFI_ERROR (Status)) {
1015 return Status;
1016 }
1017
1018 //
1019 // Enable 64-bit DMA support in the PCI layer.
1020 //
1021 Status = PciIo->Attributes (
1022 PciIo,
1025 NULL
1026 );
1027 if (EFI_ERROR (Status)) {
1028 DEBUG ((DEBUG_WARN, "NvmExpressDriverBindingStart: failed to enable 64-bit DMA (%r)\n", Status));
1029 }
1030
1031 //
1032 // 6 x 4kB aligned buffers will be carved out of this buffer.
1033 // 1st 4kB boundary is the start of the admin submission queue.
1034 // 2nd 4kB boundary is the start of the admin completion queue.
1035 // 3rd 4kB boundary is the start of I/O submission queue #1.
1036 // 4th 4kB boundary is the start of I/O completion queue #1.
1037 // 5th 4kB boundary is the start of I/O submission queue #2.
1038 // 6th 4kB boundary is the start of I/O completion queue #2.
1039 //
1040 // Allocate 6 pages of memory, then map it for bus master read and write.
1041 //
1042 Status = PciIo->AllocateBuffer (
1043 PciIo,
1046 6,
1047 (VOID **)&Private->Buffer,
1048 0
1049 );
1050 if (EFI_ERROR (Status)) {
1051 goto Exit;
1052 }
1053
1054 Bytes = EFI_PAGES_TO_SIZE (6);
1055 Status = PciIo->Map (
1056 PciIo,
1058 Private->Buffer,
1059 &Bytes,
1060 &MappedAddr,
1061 &Private->Mapping
1062 );
1063
1064 if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (6))) {
1065 goto Exit;
1066 }
1067
1068 Private->BufferPciAddr = (UINT8 *)(UINTN)MappedAddr;
1069
1070 Private->Signature = NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE;
1071 Private->ControllerHandle = Controller;
1072 Private->ImageHandle = This->DriverBindingHandle;
1073 Private->DriverBindingHandle = This->DriverBindingHandle;
1074 Private->PciIo = PciIo;
1075 Private->ParentDevicePath = ParentDevicePath;
1076 Private->Passthru.Mode = &Private->PassThruMode;
1077 Private->Passthru.PassThru = NvmExpressPassThru;
1078 Private->Passthru.GetNextNamespace = NvmExpressGetNextNamespace;
1079 Private->Passthru.BuildDevicePath = NvmExpressBuildDevicePath;
1080 Private->Passthru.GetNamespace = NvmExpressGetNamespace;
1081 CopyMem (&Private->PassThruMode, &gEfiNvmExpressPassThruMode, sizeof (EFI_NVM_EXPRESS_PASS_THRU_MODE));
1082 InitializeListHead (&Private->AsyncPassThruQueue);
1083 InitializeListHead (&Private->UnsubmittedSubtasks);
1084
1085 Status = NvmeControllerInit (Private);
1086 if (EFI_ERROR (Status)) {
1087 goto Exit;
1088 }
1089
1090 //
1091 // Start the asynchronous I/O completion monitor
1092 //
1093 Status = gBS->CreateEvent (
1094 EVT_TIMER | EVT_NOTIFY_SIGNAL,
1095 TPL_NOTIFY,
1097 Private,
1098 &Private->TimerEvent
1099 );
1100 if (EFI_ERROR (Status)) {
1101 goto Exit;
1102 }
1103
1104 Status = gBS->SetTimer (
1105 Private->TimerEvent,
1107 NVME_HC_ASYNC_TIMER
1108 );
1109 if (EFI_ERROR (Status)) {
1110 goto Exit;
1111 }
1112
1113 Status = gBS->InstallMultipleProtocolInterfaces (
1114 &Controller,
1115 &gEfiNvmExpressPassThruProtocolGuid,
1116 &Private->Passthru,
1117 NULL
1118 );
1119 if (EFI_ERROR (Status)) {
1120 goto Exit;
1121 }
1122
1124 } else {
1125 Status = gBS->OpenProtocol (
1126 Controller,
1127 &gEfiNvmExpressPassThruProtocolGuid,
1128 (VOID **)&Passthru,
1129 This->DriverBindingHandle,
1130 Controller,
1131 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1132 );
1133 if (EFI_ERROR (Status)) {
1134 goto Exit;
1135 }
1136
1137 Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (Passthru);
1138 }
1139
1140 if (RemainingDevicePath == NULL) {
1141 //
1142 // Enumerate all NVME namespaces in the controller
1143 //
1144 Status = DiscoverAllNamespaces (
1145 Private
1146 );
1147 } else if (!IsDevicePathEnd (RemainingDevicePath)) {
1148 //
1149 // Enumerate the specified NVME namespace
1150 //
1151 Status = Private->Passthru.GetNamespace (
1152 &Private->Passthru,
1153 RemainingDevicePath,
1154 &NamespaceId
1155 );
1156
1157 if (!EFI_ERROR (Status)) {
1158 Status = EnumerateNvmeDevNamespace (
1159 Private,
1160 NamespaceId
1161 );
1162 }
1163 }
1164
1165 DEBUG ((DEBUG_INFO, "NvmExpressDriverBindingStart: end successfully\n"));
1166 return EFI_SUCCESS;
1167
1168Exit:
1169 if ((Private != NULL) && (Private->Mapping != NULL)) {
1170 PciIo->Unmap (PciIo, Private->Mapping);
1171 }
1172
1173 if ((Private != NULL) && (Private->Buffer != NULL)) {
1174 PciIo->FreeBuffer (PciIo, 6, Private->Buffer);
1175 }
1176
1177 if ((Private != NULL) && (Private->ControllerData != NULL)) {
1178 FreePool (Private->ControllerData);
1179 }
1180
1181 if (Private != NULL) {
1182 if (Private->TimerEvent != NULL) {
1183 gBS->CloseEvent (Private->TimerEvent);
1184 }
1185
1186 FreePool (Private);
1187 }
1188
1189 gBS->CloseProtocol (
1190 Controller,
1191 &gEfiPciIoProtocolGuid,
1192 This->DriverBindingHandle,
1193 Controller
1194 );
1195
1196 gBS->CloseProtocol (
1197 Controller,
1198 &gEfiDevicePathProtocolGuid,
1199 This->DriverBindingHandle,
1200 Controller
1201 );
1202
1203 DEBUG ((DEBUG_INFO, "NvmExpressDriverBindingStart: end with %r\n", Status));
1204
1205 return Status;
1206}
1207
1235EFIAPI
1238 IN EFI_HANDLE Controller,
1239 IN UINTN NumberOfChildren,
1240 IN EFI_HANDLE *ChildHandleBuffer
1241 )
1242{
1243 EFI_STATUS Status;
1244 BOOLEAN AllChildrenStopped;
1245 UINTN Index;
1248 BOOLEAN IsEmpty;
1249 EFI_TPL OldTpl;
1250
1251 if (NumberOfChildren == 0) {
1252 Status = gBS->OpenProtocol (
1253 Controller,
1254 &gEfiNvmExpressPassThruProtocolGuid,
1255 (VOID **)&PassThru,
1256 This->DriverBindingHandle,
1257 Controller,
1258 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1259 );
1260
1261 if (!EFI_ERROR (Status)) {
1262 Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (PassThru);
1263
1264 //
1265 // Wait for the asynchronous PassThru queue to become empty.
1266 //
1267 while (TRUE) {
1268 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1269 IsEmpty = IsListEmpty (&Private->AsyncPassThruQueue) &&
1270 IsListEmpty (&Private->UnsubmittedSubtasks);
1271 gBS->RestoreTPL (OldTpl);
1272
1273 if (IsEmpty) {
1274 break;
1275 }
1276
1277 gBS->Stall (100);
1278 }
1279
1280 gBS->UninstallMultipleProtocolInterfaces (
1281 Controller,
1282 &gEfiNvmExpressPassThruProtocolGuid,
1283 PassThru,
1284 NULL
1285 );
1286
1287 if (Private->TimerEvent != NULL) {
1288 gBS->CloseEvent (Private->TimerEvent);
1289 }
1290
1291 if (Private->Mapping != NULL) {
1292 Private->PciIo->Unmap (Private->PciIo, Private->Mapping);
1293 }
1294
1295 if (Private->Buffer != NULL) {
1296 Private->PciIo->FreeBuffer (Private->PciIo, 6, Private->Buffer);
1297 }
1298
1299 FreePool (Private->ControllerData);
1300 FreePool (Private);
1301 }
1302
1303 gBS->CloseProtocol (
1304 Controller,
1305 &gEfiPciIoProtocolGuid,
1306 This->DriverBindingHandle,
1307 Controller
1308 );
1309 gBS->CloseProtocol (
1310 Controller,
1311 &gEfiDevicePathProtocolGuid,
1312 This->DriverBindingHandle,
1313 Controller
1314 );
1315
1317
1318 return EFI_SUCCESS;
1319 }
1320
1321 AllChildrenStopped = TRUE;
1322
1323 for (Index = 0; Index < NumberOfChildren; Index++) {
1324 Status = UnregisterNvmeNamespace (This, Controller, ChildHandleBuffer[Index]);
1325 if (EFI_ERROR (Status)) {
1326 AllChildrenStopped = FALSE;
1327 }
1328 }
1329
1330 if (!AllChildrenStopped) {
1331 return EFI_DEVICE_ERROR;
1332 }
1333
1334 return EFI_SUCCESS;
1335}
1336
1350EFIAPI
1352 IN EFI_HANDLE ImageHandle
1353 )
1354{
1355 EFI_STATUS Status;
1356 EFI_HANDLE *DeviceHandleBuffer;
1357 UINTN DeviceHandleCount;
1358 UINTN Index;
1359 EFI_COMPONENT_NAME_PROTOCOL *ComponentName;
1360 EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;
1361
1362 //
1363 // Get the list of the device handles managed by this driver.
1364 // If there is an error getting the list, then means the driver
1365 // doesn't manage any device. At this way, we would only close
1366 // those protocols installed at image handle.
1367 //
1368 DeviceHandleBuffer = NULL;
1369 Status = gBS->LocateHandleBuffer (
1370 ByProtocol,
1371 &gEfiNvmExpressPassThruProtocolGuid,
1372 NULL,
1373 &DeviceHandleCount,
1374 &DeviceHandleBuffer
1375 );
1376
1377 if (!EFI_ERROR (Status)) {
1378 //
1379 // Disconnect the driver specified by ImageHandle from all
1380 // the devices in the handle database.
1381 //
1382 for (Index = 0; Index < DeviceHandleCount; Index++) {
1383 Status = gBS->DisconnectController (
1384 DeviceHandleBuffer[Index],
1385 ImageHandle,
1386 NULL
1387 );
1388 if (EFI_ERROR (Status)) {
1389 goto EXIT;
1390 }
1391 }
1392 }
1393
1394 //
1395 // Uninstall all the protocols installed in the driver entry point
1396 //
1397 Status = gBS->UninstallMultipleProtocolInterfaces (
1398 ImageHandle,
1399 &gEfiDriverBindingProtocolGuid,
1400 &gNvmExpressDriverBinding,
1401 &gEfiDriverSupportedEfiVersionProtocolGuid,
1402 &gNvmExpressDriverSupportedEfiVersion,
1403 NULL
1404 );
1405
1406 if (EFI_ERROR (Status)) {
1407 goto EXIT;
1408 }
1409
1410 //
1411 // Note we have to one by one uninstall the following protocols.
1412 // It's because some of them are optionally installed based on
1413 // the following PCD settings.
1414 // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable
1415 // gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable
1416 // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable
1417 // gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable
1418 //
1419 Status = gBS->HandleProtocol (
1420 ImageHandle,
1421 &gEfiComponentNameProtocolGuid,
1422 (VOID **)&ComponentName
1423 );
1424 if (!EFI_ERROR (Status)) {
1425 gBS->UninstallProtocolInterface (
1426 ImageHandle,
1427 &gEfiComponentNameProtocolGuid,
1428 ComponentName
1429 );
1430 }
1431
1432 Status = gBS->HandleProtocol (
1433 ImageHandle,
1434 &gEfiComponentName2ProtocolGuid,
1435 (VOID **)&ComponentName2
1436 );
1437 if (!EFI_ERROR (Status)) {
1438 gBS->UninstallProtocolInterface (
1439 ImageHandle,
1440 &gEfiComponentName2ProtocolGuid,
1441 ComponentName2
1442 );
1443 }
1444
1445 Status = EFI_SUCCESS;
1446
1447EXIT:
1448 //
1449 // Free the buffer containing the list of handles from the handle database
1450 //
1451 if (DeviceHandleBuffer != NULL) {
1452 gBS->FreePool (DeviceHandleBuffer);
1453 }
1454
1455 return Status;
1456}
1457
1469EFIAPI
1471 IN EFI_HANDLE ImageHandle,
1472 IN EFI_SYSTEM_TABLE *SystemTable
1473 )
1474{
1475 EFI_STATUS Status;
1476
1478 ImageHandle,
1479 SystemTable,
1480 &gNvmExpressDriverBinding,
1481 ImageHandle,
1482 &gNvmExpressComponentName,
1483 &gNvmExpressComponentName2
1484 );
1485 ASSERT_EFI_ERROR (Status);
1486
1487 //
1488 // Install EFI Driver Supported EFI Version Protocol required for
1489 // EFI drivers that are on PCI and other plug in cards.
1490 //
1491 gNvmExpressDriverSupportedEfiVersion.FirmwareVersion = 0x00020028;
1492 Status = gBS->InstallMultipleProtocolInterfaces (
1493 &ImageHandle,
1494 &gEfiDriverSupportedEfiVersionProtocolGuid,
1495 &gNvmExpressDriverSupportedEfiVersion,
1496 NULL
1497 );
1498 ASSERT_EFI_ERROR (Status);
1499 return Status;
1500}
UINT64 UINTN
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:218
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
UINT32 EFIAPI ReadUnaligned32(IN CONST UINT32 *Buffer)
Definition: Unaligned.c:145
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define MSG_NVME_NAMESPACE_DP
Definition: DevicePath.h:833
#define MESSAGING_DEVICE_PATH
Definition: DevicePath.h:321
UINTN EFIAPI DevicePathNodeLength(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
struct _EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
UINTN EFIAPI UnicodeSPrintAsciiFormat(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
Definition: PrintLib.c:583
#define NULL
Definition: Base.h:319
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
Clear for PCI controllers that can not genrate a DAC.
Definition: PciIo.h:64
@ EfiPciIoAttributeOperationGet
Definition: PciIo.h:103
@ EfiPciIoAttributeOperationEnable
Definition: PciIo.h:111
@ EfiPciIoOperationBusMasterCommonBuffer
Definition: PciIo.h:90
EFI_STATUS EFIAPI NvmExpressDriverEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: NvmExpress.c:1470
EFI_STATUS EnumerateNvmeDevNamespace(IN NVME_CONTROLLER_PRIVATE_DATA *Private, UINT32 NamespaceId)
Definition: NvmExpress.c:59
EFI_STATUS EFIAPI NvmExpressDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: NvmExpress.c:946
EFI_STATUS DiscoverAllNamespaces(IN NVME_CONTROLLER_PRIVATE_DATA *Private)
Definition: NvmExpress.c:378
EFI_STATUS UnregisterNvmeNamespace(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_HANDLE Handle)
Definition: NvmExpress.c:427
EFI_STATUS EFIAPI NvmExpressUnload(IN EFI_HANDLE ImageHandle)
Definition: NvmExpress.c:1351
EFI_STATUS EFIAPI NvmExpressDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: NvmExpress.c:792
VOID EFIAPI ProcessAsyncTaskList(IN EFI_EVENT Event, IN VOID *Context)
Definition: NvmExpress.c:567
EFI_STATUS EFIAPI NvmExpressDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: NvmExpress.c:1236
EFI_STATUS EFIAPI NvmExpressPassThru(IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, IN UINT32 NamespaceId, IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet, IN EFI_EVENT Event OPTIONAL)
EFI_STATUS EFIAPI NvmExpressGetNamespace(IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT UINT32 *NamespaceId)
EFI_STATUS EFIAPI NvmExpressBuildDevicePath(IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, IN UINT32 NamespaceId, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath)
VOID NvmeRegisterShutdownNotification(VOID)
EFI_STATUS EFIAPI NvmExpressGetNextNamespace(IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, IN OUT UINT32 *NamespaceId)
VOID NvmeUnregisterShutdownNotification(VOID)
EFI_STATUS EFIAPI NvmeBlockIoWriteBlocks(IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, IN UINTN BufferSize, IN VOID *Buffer)
EFI_STATUS EFIAPI NvmeBlockIoResetEx(IN EFI_BLOCK_IO2_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
EFI_STATUS EFIAPI NvmeBlockIoReset(IN EFI_BLOCK_IO_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
EFI_STATUS EFIAPI NvmeBlockIoReadBlocksEx(IN EFI_BLOCK_IO2_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, IN OUT EFI_BLOCK_IO2_TOKEN *Token, IN UINTN BufferSize, OUT VOID *Buffer)
EFI_STATUS EFIAPI NvmeStorageSecuritySendData(IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Timeout, IN UINT8 SecurityProtocolId, IN UINT16 SecurityProtocolSpecificData, IN UINTN PayloadBufferSize, IN VOID *PayloadBuffer)
EFI_STATUS EFIAPI NvmeBlockIoReadBlocks(IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, IN UINTN BufferSize, OUT VOID *Buffer)
EFI_STATUS EFIAPI NvmeStorageSecurityReceiveData(IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Timeout, IN UINT8 SecurityProtocolId, IN UINT16 SecurityProtocolSpecificData, IN UINTN PayloadBufferSize, OUT VOID *PayloadBuffer, OUT UINTN *PayloadTransferSize)
EFI_STATUS EFIAPI NvmeBlockIoWriteBlocksEx(IN EFI_BLOCK_IO2_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, IN OUT EFI_BLOCK_IO2_TOKEN *Token, IN UINTN BufferSize, IN VOID *Buffer)
EFI_STATUS EFIAPI NvmeBlockIoFlushBlocksEx(IN EFI_BLOCK_IO2_PROTOCOL *This, IN OUT EFI_BLOCK_IO2_TOKEN *Token)
EFI_STATUS EFIAPI NvmeBlockIoFlushBlocks(IN EFI_BLOCK_IO_PROTOCOL *This)
VOID InitializeDiskInfo(IN NVME_DEVICE_PRIVATE_DATA *Device)
EFI_STATUS NvmeIdentifyNamespace(IN NVME_CONTROLLER_PRIVATE_DATA *Private, IN UINT32 NamespaceId, IN VOID *Buffer)
EFI_STATUS NvmeControllerInit(IN NVME_CONTROLLER_PRIVATE_DATA *Private)
VOID EFIAPI Exit(IN EFI_STATUS Status)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI AddUnicodeString2(IN CONST CHAR8 *Language, IN CONST CHAR8 *SupportedLanguages, IN OUT EFI_UNICODE_STRING_TABLE **UnicodeStringTable, IN CONST CHAR16 *UnicodeString, IN BOOLEAN Iso639Language)
Definition: UefiLib.c:1087
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_STATUS EFIAPI FreeUnicodeStringTable(IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable)
Definition: UefiLib.c:1257
@ EfiBootServicesData
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
@ TimerPeriodic
Definition: UefiSpec.h:535
@ ByProtocol
Definition: UefiSpec.h:1518
@ AllocateAnyPages
Definition: UefiSpec.h:33
EFI_BLOCK_IO_MEDIA * Media
Definition: BlockIo2.h:187
EFI_BLOCK_IO_MEDIA * Media
Definition: BlockIo.h:224
EFI_BLOCK_IO_MEDIA * Media
EFI_EVENT Event
Definition: BlockIo2.h:34
EFI_STATUS TransactionStatus
Definition: BlockIo2.h:39
BOOLEAN RemovableMedia
Definition: BlockIo.h:137
UINT32 LogicalBlocksPerPhysicalBlock
Definition: BlockIo.h:192
BOOLEAN LogicalPartition
Definition: BlockIo.h:150
UINT32 BlockSize
Definition: BlockIo.h:167
EFI_LBA LastBlock
Definition: BlockIo.h:178
BOOLEAN WriteCaching
Definition: BlockIo.h:161
BOOLEAN MediaPresent
Definition: BlockIo.h:144
BOOLEAN ReadOnly
Definition: BlockIo.h:156
EFI_LBA LowestAlignedLba
Definition: BlockIo.h:185
EFI_PCI_IO_PROTOCOL_IO_MEM Write
Definition: PciIo.h:197
EFI_PCI_IO_PROTOCOL_CONFIG Read
Definition: PciIo.h:232
Definition: Nvme.h:901