TianoCore EDK2 master
Loading...
Searching...
No Matches
NvmExpressBlockIo.c
Go to the documentation of this file.
1
10#include "NvmExpress.h"
11
27 IN UINT64 Buffer,
28 IN UINT64 Lba,
29 IN UINT32 Blocks
30 )
31{
33 UINT32 Bytes;
37 EFI_STATUS Status;
38 UINT32 BlockSize;
39
40 Private = Device->Controller;
41 BlockSize = Device->Media.BlockSize;
42 Bytes = Blocks * BlockSize;
43
44 ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
45 ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND));
46 ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION));
47
48 CommandPacket.NvmeCmd = &Command;
49 CommandPacket.NvmeCompletion = &Completion;
50
51 CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_READ_OPC;
52 CommandPacket.NvmeCmd->Nsid = Device->NamespaceId;
53 CommandPacket.TransferBuffer = (VOID *)(UINTN)Buffer;
54
55 CommandPacket.TransferLength = Bytes;
56 CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
57 CommandPacket.QueueType = NVME_IO_QUEUE;
58
59 CommandPacket.NvmeCmd->Cdw10 = (UINT32)Lba;
60 CommandPacket.NvmeCmd->Cdw11 = (UINT32)RShiftU64 (Lba, 32);
61 CommandPacket.NvmeCmd->Cdw12 = (Blocks - 1) & 0xFFFF;
62
63 CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID;
64
65 Status = Private->Passthru.PassThru (
66 &Private->Passthru,
67 Device->NamespaceId,
68 &CommandPacket,
69 NULL
70 );
71
72 return Status;
73}
74
90 IN UINT64 Buffer,
91 IN UINT64 Lba,
92 IN UINT32 Blocks
93 )
94{
99 EFI_STATUS Status;
100 UINT32 Bytes;
101 UINT32 BlockSize;
102
103 Private = Device->Controller;
104 BlockSize = Device->Media.BlockSize;
105 Bytes = Blocks * BlockSize;
106
107 ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
108 ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND));
109 ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION));
110
111 CommandPacket.NvmeCmd = &Command;
112 CommandPacket.NvmeCompletion = &Completion;
113
114 CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_WRITE_OPC;
115 CommandPacket.NvmeCmd->Nsid = Device->NamespaceId;
116 CommandPacket.TransferBuffer = (VOID *)(UINTN)Buffer;
117
118 CommandPacket.TransferLength = Bytes;
119 CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
120 CommandPacket.QueueType = NVME_IO_QUEUE;
121
122 CommandPacket.NvmeCmd->Cdw10 = (UINT32)Lba;
123 CommandPacket.NvmeCmd->Cdw11 = (UINT32)RShiftU64 (Lba, 32);
124 //
125 // Set Force Unit Access bit (bit 30) to use write-through behaviour
126 //
127 CommandPacket.NvmeCmd->Cdw12 = ((Blocks - 1) & 0xFFFF) | BIT30;
128
129 CommandPacket.MetadataBuffer = NULL;
130 CommandPacket.MetadataLength = 0;
131
132 CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID;
133
134 Status = Private->Passthru.PassThru (
135 &Private->Passthru,
136 Device->NamespaceId,
137 &CommandPacket,
138 NULL
139 );
140
141 return Status;
142}
143
159 OUT VOID *Buffer,
160 IN UINT64 Lba,
161 IN UINTN Blocks
162 )
163{
164 EFI_STATUS Status;
165 UINT32 BlockSize;
167 UINT32 MaxTransferBlocks;
168 UINTN OrginalBlocks;
169 BOOLEAN IsEmpty;
170 EFI_TPL OldTpl;
171
172 //
173 // Wait for the device's asynchronous I/O queue to become empty.
174 //
175 while (TRUE) {
176 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
177 IsEmpty = IsListEmpty (&Device->AsyncQueue);
178 gBS->RestoreTPL (OldTpl);
179
180 if (IsEmpty) {
181 break;
182 }
183
184 gBS->Stall (100);
185 }
186
187 Status = EFI_SUCCESS;
188 Private = Device->Controller;
189 BlockSize = Device->Media.BlockSize;
190 OrginalBlocks = Blocks;
191
192 if (Private->ControllerData->Mdts != 0) {
193 MaxTransferBlocks = (1 << (Private->ControllerData->Mdts)) * (1 << (Private->Cap.Mpsmin + 12)) / BlockSize;
194 } else {
195 MaxTransferBlocks = 1024;
196 }
197
198 while (Blocks > 0) {
199 if (Blocks > MaxTransferBlocks) {
200 Status = ReadSectors (Device, (UINT64)(UINTN)Buffer, Lba, MaxTransferBlocks);
201
202 Blocks -= MaxTransferBlocks;
203 Buffer = (VOID *)(UINTN)((UINT64)(UINTN)Buffer + MaxTransferBlocks * BlockSize);
204 Lba += MaxTransferBlocks;
205 } else {
206 Status = ReadSectors (Device, (UINT64)(UINTN)Buffer, Lba, (UINT32)Blocks);
207 Blocks = 0;
208 }
209
210 if (EFI_ERROR (Status)) {
211 break;
212 }
213 }
214
215 DEBUG ((
216 DEBUG_BLKIO,
217 "%a: Lba = 0x%08Lx, Original = 0x%08Lx, "
218 "Remaining = 0x%08Lx, BlockSize = 0x%x, Status = %r\n",
219 __func__,
220 Lba,
221 (UINT64)OrginalBlocks,
222 (UINT64)Blocks,
223 BlockSize,
224 Status
225 ));
226
227 return Status;
228}
229
245 IN VOID *Buffer,
246 IN UINT64 Lba,
247 IN UINTN Blocks
248 )
249{
250 EFI_STATUS Status;
251 UINT32 BlockSize;
253 UINT32 MaxTransferBlocks;
254 UINTN OrginalBlocks;
255 BOOLEAN IsEmpty;
256 EFI_TPL OldTpl;
257
258 //
259 // Wait for the device's asynchronous I/O queue to become empty.
260 //
261 while (TRUE) {
262 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
263 IsEmpty = IsListEmpty (&Device->AsyncQueue);
264 gBS->RestoreTPL (OldTpl);
265
266 if (IsEmpty) {
267 break;
268 }
269
270 gBS->Stall (100);
271 }
272
273 Status = EFI_SUCCESS;
274 Private = Device->Controller;
275 BlockSize = Device->Media.BlockSize;
276 OrginalBlocks = Blocks;
277
278 if (Private->ControllerData->Mdts != 0) {
279 MaxTransferBlocks = (1 << (Private->ControllerData->Mdts)) * (1 << (Private->Cap.Mpsmin + 12)) / BlockSize;
280 } else {
281 MaxTransferBlocks = 1024;
282 }
283
284 while (Blocks > 0) {
285 if (Blocks > MaxTransferBlocks) {
286 Status = WriteSectors (Device, (UINT64)(UINTN)Buffer, Lba, MaxTransferBlocks);
287
288 Blocks -= MaxTransferBlocks;
289 Buffer = (VOID *)(UINTN)((UINT64)(UINTN)Buffer + MaxTransferBlocks * BlockSize);
290 Lba += MaxTransferBlocks;
291 } else {
292 Status = WriteSectors (Device, (UINT64)(UINTN)Buffer, Lba, (UINT32)Blocks);
293 Blocks = 0;
294 }
295
296 if (EFI_ERROR (Status)) {
297 break;
298 }
299 }
300
301 DEBUG ((
302 DEBUG_BLKIO,
303 "%a: Lba = 0x%08Lx, Original = 0x%08Lx, "
304 "Remaining = 0x%08Lx, BlockSize = 0x%x, Status = %r\n",
305 __func__,
306 Lba,
307 (UINT64)OrginalBlocks,
308 (UINT64)Blocks,
309 BlockSize,
310 Status
311 ));
312
313 return Status;
314}
315
328 )
329{
334 EFI_STATUS Status;
335
336 Private = Device->Controller;
337
338 ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
339 ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND));
340 ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION));
341
342 CommandPacket.NvmeCmd = &Command;
343 CommandPacket.NvmeCompletion = &Completion;
344
345 CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_FLUSH_OPC;
346 CommandPacket.NvmeCmd->Nsid = Device->NamespaceId;
347 CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
348 CommandPacket.QueueType = NVME_IO_QUEUE;
349
350 Status = Private->Passthru.PassThru (
351 &Private->Passthru,
352 Device->NamespaceId,
353 &CommandPacket,
354 NULL
355 );
356
357 return Status;
358}
359
368VOID
369EFIAPI
371 IN EFI_EVENT Event,
372 IN VOID *Context
373 )
374{
375 NVME_BLKIO2_SUBTASK *Subtask;
376 NVME_BLKIO2_REQUEST *Request;
377 NVME_CQ *Completion;
378 EFI_BLOCK_IO2_TOKEN *Token;
379
380 gBS->CloseEvent (Event);
381
382 Subtask = (NVME_BLKIO2_SUBTASK *)Context;
383 Completion = (NVME_CQ *)Subtask->CommandPacket->NvmeCompletion;
384 Request = Subtask->BlockIo2Request;
385 Token = Request->Token;
386
387 if (Token->TransactionStatus == EFI_SUCCESS) {
388 //
389 // If previous subtask already fails, do not check the result of
390 // subsequent subtasks.
391 //
392 if ((Completion->Sct != 0) || (Completion->Sc != 0)) {
393 Token->TransactionStatus = EFI_DEVICE_ERROR;
394
395 //
396 // Dump completion entry status for debugging.
397 //
399 NvmeDumpStatus (Completion);
401 }
402 }
403
404 //
405 // Remove the subtask from the BlockIo2 subtasks list.
406 //
407 RemoveEntryList (&Subtask->Link);
408
409 if (IsListEmpty (&Request->SubtasksQueue) && Request->LastSubtaskSubmitted) {
410 //
411 // Remove the BlockIo2 request from the device asynchronous queue.
412 //
413 RemoveEntryList (&Request->Link);
414 FreePool (Request);
415 gBS->SignalEvent (Token->Event);
416 }
417
418 FreePool (Subtask->CommandPacket->NvmeCmd);
419 FreePool (Subtask->CommandPacket->NvmeCompletion);
420 FreePool (Subtask->CommandPacket);
421 FreePool (Subtask);
422}
423
442 IN NVME_BLKIO2_REQUEST *Request,
443 IN UINT64 Buffer,
444 IN UINT64 Lba,
445 IN UINT32 Blocks,
446 IN BOOLEAN IsLast
447 )
448{
450 UINT32 Bytes;
451 NVME_BLKIO2_SUBTASK *Subtask;
454 EFI_NVM_EXPRESS_COMPLETION *Completion;
455 EFI_STATUS Status;
456 UINT32 BlockSize;
457 EFI_TPL OldTpl;
458
459 Private = Device->Controller;
460 BlockSize = Device->Media.BlockSize;
461 Bytes = Blocks * BlockSize;
462 CommandPacket = NULL;
463 Command = NULL;
464 Completion = NULL;
465
466 Subtask = AllocateZeroPool (sizeof (NVME_BLKIO2_SUBTASK));
467 if (Subtask == NULL) {
468 Status = EFI_OUT_OF_RESOURCES;
469 goto ErrorExit;
470 }
471
472 Subtask->Signature = NVME_BLKIO2_SUBTASK_SIGNATURE;
473 Subtask->IsLast = IsLast;
474 Subtask->NamespaceId = Device->NamespaceId;
475 Subtask->BlockIo2Request = Request;
476
478 if (CommandPacket == NULL) {
479 Status = EFI_OUT_OF_RESOURCES;
480 goto ErrorExit;
481 } else {
482 Subtask->CommandPacket = CommandPacket;
483 }
484
485 Command = AllocateZeroPool (sizeof (EFI_NVM_EXPRESS_COMMAND));
486 if (Command == NULL) {
487 Status = EFI_OUT_OF_RESOURCES;
488 goto ErrorExit;
489 }
490
491 Completion = AllocateZeroPool (sizeof (EFI_NVM_EXPRESS_COMPLETION));
492 if (Completion == NULL) {
493 Status = EFI_OUT_OF_RESOURCES;
494 goto ErrorExit;
495 }
496
497 //
498 // Create Event
499 //
500 Status = gBS->CreateEvent (
501 EVT_NOTIFY_SIGNAL,
502 TPL_NOTIFY,
504 Subtask,
505 &Subtask->Event
506 );
507 if (EFI_ERROR (Status)) {
508 goto ErrorExit;
509 }
510
511 CommandPacket->NvmeCmd = Command;
512 CommandPacket->NvmeCompletion = Completion;
513
514 CommandPacket->NvmeCmd->Cdw0.Opcode = NVME_IO_READ_OPC;
515 CommandPacket->NvmeCmd->Nsid = Device->NamespaceId;
516 CommandPacket->TransferBuffer = (VOID *)(UINTN)Buffer;
517
518 CommandPacket->TransferLength = Bytes;
519 CommandPacket->CommandTimeout = NVME_GENERIC_TIMEOUT;
520 CommandPacket->QueueType = NVME_IO_QUEUE;
521
522 CommandPacket->NvmeCmd->Cdw10 = (UINT32)Lba;
523 CommandPacket->NvmeCmd->Cdw11 = (UINT32)RShiftU64 (Lba, 32);
524 CommandPacket->NvmeCmd->Cdw12 = (Blocks - 1) & 0xFFFF;
525
526 CommandPacket->NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID;
527
528 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
529 InsertTailList (&Private->UnsubmittedSubtasks, &Subtask->Link);
530 Request->UnsubmittedSubtaskNum++;
531 gBS->RestoreTPL (OldTpl);
532
533 return EFI_SUCCESS;
534
535ErrorExit:
536 //
537 // Resource cleanup if asynchronous read request has not been queued.
538 //
539 if (Completion != NULL) {
540 FreePool (Completion);
541 }
542
543 if (Command != NULL) {
544 FreePool (Command);
545 }
546
547 if (CommandPacket != NULL) {
548 FreePool (CommandPacket);
549 }
550
551 if (Subtask != NULL) {
552 if (Subtask->Event != NULL) {
553 gBS->CloseEvent (Subtask->Event);
554 }
555
556 FreePool (Subtask);
557 }
558
559 return Status;
560}
561
581 IN NVME_BLKIO2_REQUEST *Request,
582 IN UINT64 Buffer,
583 IN UINT64 Lba,
584 IN UINT32 Blocks,
585 IN BOOLEAN IsLast
586 )
587{
589 UINT32 Bytes;
590 NVME_BLKIO2_SUBTASK *Subtask;
593 EFI_NVM_EXPRESS_COMPLETION *Completion;
594 EFI_STATUS Status;
595 UINT32 BlockSize;
596 EFI_TPL OldTpl;
597
598 Private = Device->Controller;
599 BlockSize = Device->Media.BlockSize;
600 Bytes = Blocks * BlockSize;
601 CommandPacket = NULL;
602 Command = NULL;
603 Completion = NULL;
604
605 Subtask = AllocateZeroPool (sizeof (NVME_BLKIO2_SUBTASK));
606 if (Subtask == NULL) {
607 Status = EFI_OUT_OF_RESOURCES;
608 goto ErrorExit;
609 }
610
611 Subtask->Signature = NVME_BLKIO2_SUBTASK_SIGNATURE;
612 Subtask->IsLast = IsLast;
613 Subtask->NamespaceId = Device->NamespaceId;
614 Subtask->BlockIo2Request = Request;
615
617 if (CommandPacket == NULL) {
618 Status = EFI_OUT_OF_RESOURCES;
619 goto ErrorExit;
620 } else {
621 Subtask->CommandPacket = CommandPacket;
622 }
623
624 Command = AllocateZeroPool (sizeof (EFI_NVM_EXPRESS_COMMAND));
625 if (Command == NULL) {
626 Status = EFI_OUT_OF_RESOURCES;
627 goto ErrorExit;
628 }
629
630 Completion = AllocateZeroPool (sizeof (EFI_NVM_EXPRESS_COMPLETION));
631 if (Completion == NULL) {
632 Status = EFI_OUT_OF_RESOURCES;
633 goto ErrorExit;
634 }
635
636 //
637 // Create Event
638 //
639 Status = gBS->CreateEvent (
640 EVT_NOTIFY_SIGNAL,
641 TPL_NOTIFY,
643 Subtask,
644 &Subtask->Event
645 );
646 if (EFI_ERROR (Status)) {
647 goto ErrorExit;
648 }
649
650 CommandPacket->NvmeCmd = Command;
651 CommandPacket->NvmeCompletion = Completion;
652
653 CommandPacket->NvmeCmd->Cdw0.Opcode = NVME_IO_WRITE_OPC;
654 CommandPacket->NvmeCmd->Nsid = Device->NamespaceId;
655 CommandPacket->TransferBuffer = (VOID *)(UINTN)Buffer;
656
657 CommandPacket->TransferLength = Bytes;
658 CommandPacket->CommandTimeout = NVME_GENERIC_TIMEOUT;
659 CommandPacket->QueueType = NVME_IO_QUEUE;
660
661 CommandPacket->NvmeCmd->Cdw10 = (UINT32)Lba;
662 CommandPacket->NvmeCmd->Cdw11 = (UINT32)RShiftU64 (Lba, 32);
663 //
664 // Set Force Unit Access bit (bit 30) to use write-through behaviour
665 //
666 CommandPacket->NvmeCmd->Cdw12 = ((Blocks - 1) & 0xFFFF) | BIT30;
667
668 CommandPacket->NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID;
669
670 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
671 InsertTailList (&Private->UnsubmittedSubtasks, &Subtask->Link);
672 Request->UnsubmittedSubtaskNum++;
673 gBS->RestoreTPL (OldTpl);
674
675 return EFI_SUCCESS;
676
677ErrorExit:
678 //
679 // Resource cleanup if asynchronous read request has not been queued.
680 //
681 if (Completion != NULL) {
682 FreePool (Completion);
683 }
684
685 if (Command != NULL) {
686 FreePool (Command);
687 }
688
689 if (CommandPacket != NULL) {
690 FreePool (CommandPacket);
691 }
692
693 if (Subtask != NULL) {
694 if (Subtask->Event != NULL) {
695 gBS->CloseEvent (Subtask->Event);
696 }
697
698 FreePool (Subtask);
699 }
700
701 return Status;
702}
703
721 OUT VOID *Buffer,
722 IN UINT64 Lba,
723 IN UINTN Blocks,
725 )
726{
727 EFI_STATUS Status;
728 UINT32 BlockSize;
730 NVME_BLKIO2_REQUEST *BlkIo2Req;
731 UINT32 MaxTransferBlocks;
732 UINTN OrginalBlocks;
733 BOOLEAN IsEmpty;
734 EFI_TPL OldTpl;
735
736 Status = EFI_SUCCESS;
737 Private = Device->Controller;
738 BlockSize = Device->Media.BlockSize;
739 OrginalBlocks = Blocks;
740 BlkIo2Req = AllocateZeroPool (sizeof (NVME_BLKIO2_REQUEST));
741 if (BlkIo2Req == NULL) {
742 return EFI_OUT_OF_RESOURCES;
743 }
744
745 BlkIo2Req->Signature = NVME_BLKIO2_REQUEST_SIGNATURE;
746 BlkIo2Req->Token = Token;
747
748 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
749 InsertTailList (&Device->AsyncQueue, &BlkIo2Req->Link);
750 gBS->RestoreTPL (OldTpl);
751
752 InitializeListHead (&BlkIo2Req->SubtasksQueue);
753
754 if (Private->ControllerData->Mdts != 0) {
755 MaxTransferBlocks = (1 << (Private->ControllerData->Mdts)) * (1 << (Private->Cap.Mpsmin + 12)) / BlockSize;
756 } else {
757 MaxTransferBlocks = 1024;
758 }
759
760 while (Blocks > 0) {
761 if (Blocks > MaxTransferBlocks) {
762 Status = AsyncReadSectors (
763 Device,
764 BlkIo2Req,
765 (UINT64)(UINTN)Buffer,
766 Lba,
767 MaxTransferBlocks,
768 FALSE
769 );
770
771 Blocks -= MaxTransferBlocks;
772 Buffer = (VOID *)(UINTN)((UINT64)(UINTN)Buffer + MaxTransferBlocks * BlockSize);
773 Lba += MaxTransferBlocks;
774 } else {
775 Status = AsyncReadSectors (
776 Device,
777 BlkIo2Req,
778 (UINT64)(UINTN)Buffer,
779 Lba,
780 (UINT32)Blocks,
781 TRUE
782 );
783
784 Blocks = 0;
785 }
786
787 if (EFI_ERROR (Status)) {
788 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
789 IsEmpty = IsListEmpty (&BlkIo2Req->SubtasksQueue) &&
790 (BlkIo2Req->UnsubmittedSubtaskNum == 0);
791
792 if (IsEmpty) {
793 //
794 // Remove the BlockIo2 request from the device asynchronous queue.
795 //
796 RemoveEntryList (&BlkIo2Req->Link);
797 FreePool (BlkIo2Req);
798 Status = EFI_DEVICE_ERROR;
799 } else {
800 //
801 // There are previous BlockIo2 subtasks still running, EFI_SUCCESS
802 // should be returned to make sure that the caller does not free
803 // resources still using by these requests.
804 //
805 Status = EFI_SUCCESS;
806 Token->TransactionStatus = EFI_DEVICE_ERROR;
807 BlkIo2Req->LastSubtaskSubmitted = TRUE;
808 }
809
810 gBS->RestoreTPL (OldTpl);
811
812 break;
813 }
814 }
815
816 DEBUG ((
817 DEBUG_BLKIO,
818 "%a: Lba = 0x%08Lx, Original = 0x%08Lx, "
819 "Remaining = 0x%08Lx, BlockSize = 0x%x, Status = %r\n",
820 __func__,
821 Lba,
822 (UINT64)OrginalBlocks,
823 (UINT64)Blocks,
824 BlockSize,
825 Status
826 ));
827
828 return Status;
829}
830
849 IN VOID *Buffer,
850 IN UINT64 Lba,
851 IN UINTN Blocks,
853 )
854{
855 EFI_STATUS Status;
856 UINT32 BlockSize;
858 NVME_BLKIO2_REQUEST *BlkIo2Req;
859 UINT32 MaxTransferBlocks;
860 UINTN OrginalBlocks;
861 BOOLEAN IsEmpty;
862 EFI_TPL OldTpl;
863
864 Status = EFI_SUCCESS;
865 Private = Device->Controller;
866 BlockSize = Device->Media.BlockSize;
867 OrginalBlocks = Blocks;
868 BlkIo2Req = AllocateZeroPool (sizeof (NVME_BLKIO2_REQUEST));
869 if (BlkIo2Req == NULL) {
870 return EFI_OUT_OF_RESOURCES;
871 }
872
873 BlkIo2Req->Signature = NVME_BLKIO2_REQUEST_SIGNATURE;
874 BlkIo2Req->Token = Token;
875
876 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
877 InsertTailList (&Device->AsyncQueue, &BlkIo2Req->Link);
878 gBS->RestoreTPL (OldTpl);
879
880 InitializeListHead (&BlkIo2Req->SubtasksQueue);
881
882 if (Private->ControllerData->Mdts != 0) {
883 MaxTransferBlocks = (1 << (Private->ControllerData->Mdts)) * (1 << (Private->Cap.Mpsmin + 12)) / BlockSize;
884 } else {
885 MaxTransferBlocks = 1024;
886 }
887
888 while (Blocks > 0) {
889 if (Blocks > MaxTransferBlocks) {
890 Status = AsyncWriteSectors (
891 Device,
892 BlkIo2Req,
893 (UINT64)(UINTN)Buffer,
894 Lba,
895 MaxTransferBlocks,
896 FALSE
897 );
898
899 Blocks -= MaxTransferBlocks;
900 Buffer = (VOID *)(UINTN)((UINT64)(UINTN)Buffer + MaxTransferBlocks * BlockSize);
901 Lba += MaxTransferBlocks;
902 } else {
903 Status = AsyncWriteSectors (
904 Device,
905 BlkIo2Req,
906 (UINT64)(UINTN)Buffer,
907 Lba,
908 (UINT32)Blocks,
909 TRUE
910 );
911
912 Blocks = 0;
913 }
914
915 if (EFI_ERROR (Status)) {
916 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
917 IsEmpty = IsListEmpty (&BlkIo2Req->SubtasksQueue) &&
918 (BlkIo2Req->UnsubmittedSubtaskNum == 0);
919
920 if (IsEmpty) {
921 //
922 // Remove the BlockIo2 request from the device asynchronous queue.
923 //
924 RemoveEntryList (&BlkIo2Req->Link);
925 FreePool (BlkIo2Req);
926 Status = EFI_DEVICE_ERROR;
927 } else {
928 //
929 // There are previous BlockIo2 subtasks still running, EFI_SUCCESS
930 // should be returned to make sure that the caller does not free
931 // resources still using by these requests.
932 //
933 Status = EFI_SUCCESS;
934 Token->TransactionStatus = EFI_DEVICE_ERROR;
935 BlkIo2Req->LastSubtaskSubmitted = TRUE;
936 }
937
938 gBS->RestoreTPL (OldTpl);
939
940 break;
941 }
942 }
943
944 DEBUG ((
945 DEBUG_BLKIO,
946 "%a: Lba = 0x%08Lx, Original = 0x%08Lx, "
947 "Remaining = 0x%08Lx, BlockSize = 0x%x, Status = %r\n",
948 __func__,
949 Lba,
950 (UINT64)OrginalBlocks,
951 (UINT64)Blocks,
952 BlockSize,
953 Status
954 ));
955
956 return Status;
957}
958
971EFIAPI
974 IN BOOLEAN ExtendedVerification
975 )
976{
977 EFI_TPL OldTpl;
980 EFI_STATUS Status;
981
982 if (This == NULL) {
983 return EFI_INVALID_PARAMETER;
984 }
985
986 //
987 // For Nvm Express subsystem, reset block device means reset controller.
988 //
989 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
990
991 Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This);
992
993 Private = Device->Controller;
994
995 Status = NvmeControllerInit (Private);
996
997 if (EFI_ERROR (Status)) {
998 Status = EFI_DEVICE_ERROR;
999 }
1000
1001 gBS->RestoreTPL (OldTpl);
1002
1003 return Status;
1004}
1005
1026EFIAPI
1029 IN UINT32 MediaId,
1030 IN EFI_LBA Lba,
1031 IN UINTN BufferSize,
1032 OUT VOID *Buffer
1033 )
1034{
1036 EFI_STATUS Status;
1037 EFI_BLOCK_IO_MEDIA *Media;
1038 UINTN BlockSize;
1039 UINTN NumberOfBlocks;
1040 UINTN IoAlign;
1041 EFI_TPL OldTpl;
1042
1043 //
1044 // Check parameters.
1045 //
1046 if (This == NULL) {
1047 return EFI_INVALID_PARAMETER;
1048 }
1049
1050 Media = This->Media;
1051
1052 if (MediaId != Media->MediaId) {
1053 return EFI_MEDIA_CHANGED;
1054 }
1055
1056 if (Buffer == NULL) {
1057 return EFI_INVALID_PARAMETER;
1058 }
1059
1060 if (BufferSize == 0) {
1061 return EFI_SUCCESS;
1062 }
1063
1064 BlockSize = Media->BlockSize;
1065 if ((BufferSize % BlockSize) != 0) {
1066 return EFI_BAD_BUFFER_SIZE;
1067 }
1068
1069 NumberOfBlocks = BufferSize / BlockSize;
1070 if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
1071 return EFI_INVALID_PARAMETER;
1072 }
1073
1074 IoAlign = Media->IoAlign;
1075 if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) {
1076 return EFI_INVALID_PARAMETER;
1077 }
1078
1079 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1080
1081 Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This);
1082
1083 Status = NvmeRead (Device, Buffer, Lba, NumberOfBlocks);
1084
1085 gBS->RestoreTPL (OldTpl);
1086 return Status;
1087}
1088
1110EFIAPI
1113 IN UINT32 MediaId,
1114 IN EFI_LBA Lba,
1115 IN UINTN BufferSize,
1116 IN VOID *Buffer
1117 )
1118{
1120 EFI_STATUS Status;
1121 EFI_BLOCK_IO_MEDIA *Media;
1122 UINTN BlockSize;
1123 UINTN NumberOfBlocks;
1124 UINTN IoAlign;
1125 EFI_TPL OldTpl;
1126
1127 //
1128 // Check parameters.
1129 //
1130 if (This == NULL) {
1131 return EFI_INVALID_PARAMETER;
1132 }
1133
1134 Media = This->Media;
1135
1136 if (MediaId != Media->MediaId) {
1137 return EFI_MEDIA_CHANGED;
1138 }
1139
1140 if (Buffer == NULL) {
1141 return EFI_INVALID_PARAMETER;
1142 }
1143
1144 if (BufferSize == 0) {
1145 return EFI_SUCCESS;
1146 }
1147
1148 BlockSize = Media->BlockSize;
1149 if ((BufferSize % BlockSize) != 0) {
1150 return EFI_BAD_BUFFER_SIZE;
1151 }
1152
1153 NumberOfBlocks = BufferSize / BlockSize;
1154 if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
1155 return EFI_INVALID_PARAMETER;
1156 }
1157
1158 IoAlign = Media->IoAlign;
1159 if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) {
1160 return EFI_INVALID_PARAMETER;
1161 }
1162
1163 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1164
1165 Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This);
1166
1167 Status = NvmeWrite (Device, Buffer, Lba, NumberOfBlocks);
1168
1169 gBS->RestoreTPL (OldTpl);
1170
1171 return Status;
1172}
1173
1185EFIAPI
1188 )
1189{
1191 EFI_STATUS Status;
1192 EFI_TPL OldTpl;
1193
1194 //
1195 // Check parameters.
1196 //
1197 if (This == NULL) {
1198 return EFI_INVALID_PARAMETER;
1199 }
1200
1201 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1202
1203 Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This);
1204
1205 Status = NvmeFlush (Device);
1206
1207 gBS->RestoreTPL (OldTpl);
1208
1209 return Status;
1210}
1211
1226EFIAPI
1229 IN BOOLEAN ExtendedVerification
1230 )
1231{
1232 EFI_STATUS Status;
1235 BOOLEAN IsEmpty;
1236 EFI_TPL OldTpl;
1237
1238 if (This == NULL) {
1239 return EFI_INVALID_PARAMETER;
1240 }
1241
1242 Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This);
1243 Private = Device->Controller;
1244
1245 //
1246 // Wait for the asynchronous PassThru queue to become empty.
1247 //
1248 while (TRUE) {
1249 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1250 IsEmpty = IsListEmpty (&Private->AsyncPassThruQueue) &&
1251 IsListEmpty (&Private->UnsubmittedSubtasks);
1252 gBS->RestoreTPL (OldTpl);
1253
1254 if (IsEmpty) {
1255 break;
1256 }
1257
1258 gBS->Stall (100);
1259 }
1260
1261 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1262
1263 Status = NvmeControllerInit (Private);
1264
1265 if (EFI_ERROR (Status)) {
1266 Status = EFI_DEVICE_ERROR;
1267 }
1268
1269 gBS->RestoreTPL (OldTpl);
1270
1271 return Status;
1272}
1273
1312EFIAPI
1315 IN UINT32 MediaId,
1316 IN EFI_LBA Lba,
1317 IN OUT EFI_BLOCK_IO2_TOKEN *Token,
1318 IN UINTN BufferSize,
1319 OUT VOID *Buffer
1320 )
1321{
1323 EFI_STATUS Status;
1324 EFI_BLOCK_IO_MEDIA *Media;
1325 UINTN BlockSize;
1326 UINTN NumberOfBlocks;
1327 UINTN IoAlign;
1328 EFI_TPL OldTpl;
1329
1330 //
1331 // Check parameters.
1332 //
1333 if (This == NULL) {
1334 return EFI_INVALID_PARAMETER;
1335 }
1336
1337 Media = This->Media;
1338
1339 if (MediaId != Media->MediaId) {
1340 return EFI_MEDIA_CHANGED;
1341 }
1342
1343 if (Buffer == NULL) {
1344 return EFI_INVALID_PARAMETER;
1345 }
1346
1347 if (BufferSize == 0) {
1348 if ((Token != NULL) && (Token->Event != NULL)) {
1349 Token->TransactionStatus = EFI_SUCCESS;
1350 gBS->SignalEvent (Token->Event);
1351 }
1352
1353 return EFI_SUCCESS;
1354 }
1355
1356 BlockSize = Media->BlockSize;
1357 if ((BufferSize % BlockSize) != 0) {
1358 return EFI_BAD_BUFFER_SIZE;
1359 }
1360
1361 NumberOfBlocks = BufferSize / BlockSize;
1362 if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
1363 return EFI_INVALID_PARAMETER;
1364 }
1365
1366 IoAlign = Media->IoAlign;
1367 if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) {
1368 return EFI_INVALID_PARAMETER;
1369 }
1370
1371 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1372
1373 Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This);
1374
1375 if ((Token != NULL) && (Token->Event != NULL)) {
1376 Token->TransactionStatus = EFI_SUCCESS;
1377 Status = NvmeAsyncRead (Device, Buffer, Lba, NumberOfBlocks, Token);
1378 } else {
1379 Status = NvmeRead (Device, Buffer, Lba, NumberOfBlocks);
1380 }
1381
1382 gBS->RestoreTPL (OldTpl);
1383 return Status;
1384}
1385
1425EFIAPI
1428 IN UINT32 MediaId,
1429 IN EFI_LBA Lba,
1430 IN OUT EFI_BLOCK_IO2_TOKEN *Token,
1431 IN UINTN BufferSize,
1432 IN VOID *Buffer
1433 )
1434{
1436 EFI_STATUS Status;
1437 EFI_BLOCK_IO_MEDIA *Media;
1438 UINTN BlockSize;
1439 UINTN NumberOfBlocks;
1440 UINTN IoAlign;
1441 EFI_TPL OldTpl;
1442
1443 //
1444 // Check parameters.
1445 //
1446 if (This == NULL) {
1447 return EFI_INVALID_PARAMETER;
1448 }
1449
1450 Media = This->Media;
1451
1452 if (MediaId != Media->MediaId) {
1453 return EFI_MEDIA_CHANGED;
1454 }
1455
1456 if (Buffer == NULL) {
1457 return EFI_INVALID_PARAMETER;
1458 }
1459
1460 if (BufferSize == 0) {
1461 if ((Token != NULL) && (Token->Event != NULL)) {
1462 Token->TransactionStatus = EFI_SUCCESS;
1463 gBS->SignalEvent (Token->Event);
1464 }
1465
1466 return EFI_SUCCESS;
1467 }
1468
1469 BlockSize = Media->BlockSize;
1470 if ((BufferSize % BlockSize) != 0) {
1471 return EFI_BAD_BUFFER_SIZE;
1472 }
1473
1474 NumberOfBlocks = BufferSize / BlockSize;
1475 if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
1476 return EFI_INVALID_PARAMETER;
1477 }
1478
1479 IoAlign = Media->IoAlign;
1480 if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) {
1481 return EFI_INVALID_PARAMETER;
1482 }
1483
1484 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1485
1486 Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This);
1487
1488 if ((Token != NULL) && (Token->Event != NULL)) {
1489 Token->TransactionStatus = EFI_SUCCESS;
1490 Status = NvmeAsyncWrite (Device, Buffer, Lba, NumberOfBlocks, Token);
1491 } else {
1492 Status = NvmeWrite (Device, Buffer, Lba, NumberOfBlocks);
1493 }
1494
1495 gBS->RestoreTPL (OldTpl);
1496 return Status;
1497}
1498
1524EFIAPI
1528 )
1529{
1531 BOOLEAN IsEmpty;
1532 EFI_TPL OldTpl;
1533
1534 //
1535 // Check parameters.
1536 //
1537 if (This == NULL) {
1538 return EFI_INVALID_PARAMETER;
1539 }
1540
1541 Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This);
1542
1543 //
1544 // Wait for the asynchronous I/O queue to become empty.
1545 //
1546 while (TRUE) {
1547 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1548 IsEmpty = IsListEmpty (&Device->AsyncQueue);
1549 gBS->RestoreTPL (OldTpl);
1550
1551 if (IsEmpty) {
1552 break;
1553 }
1554
1555 gBS->Stall (100);
1556 }
1557
1558 //
1559 // Signal caller event
1560 //
1561 if ((Token != NULL) && (Token->Event != NULL)) {
1562 Token->TransactionStatus = EFI_SUCCESS;
1563 gBS->SignalEvent (Token->Event);
1564 }
1565
1566 return EFI_SUCCESS;
1567}
1568
1599 IN OUT VOID *Buffer,
1600 IN UINT8 SecurityProtocolId,
1601 IN UINT16 SecurityProtocolSpecificData,
1602 IN UINTN TransferLength,
1603 IN BOOLEAN IsTrustSend,
1604 IN UINT64 Timeout,
1605 OUT UINTN *TransferLengthOut
1606 )
1607{
1610 EFI_NVM_EXPRESS_COMPLETION Completion;
1611 EFI_STATUS Status;
1612 UINT16 SpecificData;
1613
1614 ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
1615 ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND));
1616 ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION));
1617
1618 CommandPacket.NvmeCmd = &Command;
1619 CommandPacket.NvmeCompletion = &Completion;
1620
1621 //
1622 // Change Endianness of SecurityProtocolSpecificData
1623 //
1624 SpecificData = (((SecurityProtocolSpecificData << 8) & 0xFF00) | (SecurityProtocolSpecificData >> 8));
1625
1626 if (IsTrustSend) {
1627 Command.Cdw0.Opcode = NVME_ADMIN_SECURITY_SEND_CMD;
1628 CommandPacket.TransferBuffer = Buffer;
1629 CommandPacket.TransferLength = (UINT32)TransferLength;
1630 CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId << 24) | (SpecificData << 8));
1631 CommandPacket.NvmeCmd->Cdw11 = (UINT32)TransferLength;
1632 } else {
1633 Command.Cdw0.Opcode = NVME_ADMIN_SECURITY_RECEIVE_CMD;
1634 CommandPacket.TransferBuffer = Buffer;
1635 CommandPacket.TransferLength = (UINT32)TransferLength;
1636 CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId << 24) | (SpecificData << 8));
1637 CommandPacket.NvmeCmd->Cdw11 = (UINT32)TransferLength;
1638 }
1639
1640 CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
1641 CommandPacket.NvmeCmd->Nsid = NVME_CONTROLLER_ID;
1642 CommandPacket.CommandTimeout = Timeout;
1643 CommandPacket.QueueType = NVME_ADMIN_QUEUE;
1644
1645 Status = Private->Passthru.PassThru (
1646 &Private->Passthru,
1647 NVME_CONTROLLER_ID,
1648 &CommandPacket,
1649 NULL
1650 );
1651
1652 if (!IsTrustSend) {
1653 if (EFI_ERROR (Status)) {
1654 *TransferLengthOut = 0;
1655 } else {
1656 *TransferLengthOut = (UINTN)TransferLength;
1657 }
1658 }
1659
1660 return Status;
1661}
1662
1738EFIAPI
1741 IN UINT32 MediaId,
1742 IN UINT64 Timeout,
1743 IN UINT8 SecurityProtocolId,
1744 IN UINT16 SecurityProtocolSpecificData,
1745 IN UINTN PayloadBufferSize,
1746 OUT VOID *PayloadBuffer,
1747 OUT UINTN *PayloadTransferSize
1748 )
1749{
1750 EFI_STATUS Status;
1752
1753 Status = EFI_SUCCESS;
1754
1755 if ((PayloadBuffer == NULL) || (PayloadTransferSize == NULL) || (PayloadBufferSize == 0)) {
1756 return EFI_INVALID_PARAMETER;
1757 }
1758
1759 Device = NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY (This);
1760
1761 if (MediaId != Device->BlockIo.Media->MediaId) {
1762 return EFI_MEDIA_CHANGED;
1763 }
1764
1765 if (!Device->BlockIo.Media->MediaPresent) {
1766 return EFI_NO_MEDIA;
1767 }
1768
1769 Status = TrustTransferNvmeDevice (
1770 Device->Controller,
1771 PayloadBuffer,
1772 SecurityProtocolId,
1773 SecurityProtocolSpecificData,
1774 PayloadBufferSize,
1775 FALSE,
1776 Timeout,
1777 PayloadTransferSize
1778 );
1779
1780 return Status;
1781}
1782
1847EFIAPI
1850 IN UINT32 MediaId,
1851 IN UINT64 Timeout,
1852 IN UINT8 SecurityProtocolId,
1853 IN UINT16 SecurityProtocolSpecificData,
1854 IN UINTN PayloadBufferSize,
1855 IN VOID *PayloadBuffer
1856 )
1857{
1858 EFI_STATUS Status;
1860
1861 Status = EFI_SUCCESS;
1862
1863 if ((PayloadBuffer == NULL) && (PayloadBufferSize != 0)) {
1864 return EFI_INVALID_PARAMETER;
1865 }
1866
1867 Device = NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY (This);
1868
1869 if (MediaId != Device->BlockIo.Media->MediaId) {
1870 return EFI_MEDIA_CHANGED;
1871 }
1872
1873 if (!Device->BlockIo.Media->MediaPresent) {
1874 return EFI_NO_MEDIA;
1875 }
1876
1877 Status = TrustTransferNvmeDevice (
1878 Device->Controller,
1879 PayloadBuffer,
1880 SecurityProtocolId,
1881 SecurityProtocolSpecificData,
1882 PayloadBufferSize,
1883 TRUE,
1884 Timeout,
1885 NULL
1886 );
1887
1888 return Status;
1889}
UINT64 UINTN
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
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
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
VOID NvmeDumpStatus(IN NVME_CQ *Cq)
EFI_STATUS TrustTransferNvmeDevice(IN OUT NVME_CONTROLLER_PRIVATE_DATA *Private, IN OUT VOID *Buffer, IN UINT8 SecurityProtocolId, IN UINT16 SecurityProtocolSpecificData, IN UINTN TransferLength, IN BOOLEAN IsTrustSend, IN UINT64 Timeout, OUT UINTN *TransferLengthOut)
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 ReadSectors(IN NVME_DEVICE_PRIVATE_DATA *Device, IN UINT64 Buffer, IN UINT64 Lba, IN UINT32 Blocks)
EFI_STATUS NvmeWrite(IN NVME_DEVICE_PRIVATE_DATA *Device, IN VOID *Buffer, IN UINT64 Lba, IN UINTN Blocks)
EFI_STATUS AsyncReadSectors(IN NVME_DEVICE_PRIVATE_DATA *Device, IN NVME_BLKIO2_REQUEST *Request, IN UINT64 Buffer, IN UINT64 Lba, IN UINT32 Blocks, IN BOOLEAN IsLast)
EFI_STATUS WriteSectors(IN NVME_DEVICE_PRIVATE_DATA *Device, IN UINT64 Buffer, IN UINT64 Lba, IN UINT32 Blocks)
EFI_STATUS EFIAPI NvmeBlockIoResetEx(IN EFI_BLOCK_IO2_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
EFI_STATUS NvmeFlush(IN NVME_DEVICE_PRIVATE_DATA *Device)
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 NvmeRead(IN NVME_DEVICE_PRIVATE_DATA *Device, OUT VOID *Buffer, IN UINT64 Lba, IN UINTN Blocks)
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 NvmeAsyncWrite(IN NVME_DEVICE_PRIVATE_DATA *Device, IN VOID *Buffer, IN UINT64 Lba, IN UINTN Blocks, IN EFI_BLOCK_IO2_TOKEN *Token)
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 NvmeAsyncRead(IN NVME_DEVICE_PRIVATE_DATA *Device, OUT VOID *Buffer, IN UINT64 Lba, IN UINTN Blocks, IN EFI_BLOCK_IO2_TOKEN *Token)
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)
EFI_STATUS AsyncWriteSectors(IN NVME_DEVICE_PRIVATE_DATA *Device, IN NVME_BLKIO2_REQUEST *Request, IN UINT64 Buffer, IN UINT64 Lba, IN UINT32 Blocks, IN BOOLEAN IsLast)
VOID EFIAPI AsyncIoCallback(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS NvmeControllerInit(IN NVME_CONTROLLER_PRIVATE_DATA *Private)
UINT64 EFI_LBA
Definition: UefiBaseType.h:45
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_BLOCK_IO_MEDIA * Media
Definition: BlockIo.h:224
EFI_EVENT Event
Definition: BlockIo2.h:34
EFI_STATUS TransactionStatus
Definition: BlockIo2.h:39
UINT32 BlockSize
Definition: BlockIo.h:167
EFI_LBA LastBlock
Definition: BlockIo.h:178
BOOLEAN MediaPresent
Definition: BlockIo.h:144
Definition: Nvme.h:901