TianoCore EDK2 master
Loading...
Searching...
No Matches
AtaPassThruExecute.c
Go to the documentation of this file.
1
20#include "AtaBus.h"
21
22#define ATA_CMD_TRUST_NON_DATA 0x5B
23#define ATA_CMD_TRUST_RECEIVE 0x5C
24#define ATA_CMD_TRUST_RECEIVE_DMA 0x5D
25#define ATA_CMD_TRUST_SEND 0x5E
26#define ATA_CMD_TRUST_SEND_DMA 0x5F
27
28//
29// Look up table (UdmaValid, IsWrite) for EFI_ATA_PASS_THRU_CMD_PROTOCOL
30//
31EFI_ATA_PASS_THRU_CMD_PROTOCOL mAtaPassThruCmdProtocols[][2] = {
32 {
33 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN,
34 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT
35 },
36 {
37 EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN,
38 EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT,
39 }
40};
41
42//
43// Look up table (UdmaValid, Lba48Bit, IsIsWrite) for ATA_CMD
44//
45UINT8 mAtaCommands[][2][2] = {
46 {
47 {
48 ATA_CMD_READ_SECTORS, // 28-bit LBA; PIO read
49 ATA_CMD_WRITE_SECTORS // 28-bit LBA; PIO write
50 },
51 {
52 ATA_CMD_READ_SECTORS_EXT, // 48-bit LBA; PIO read
53 ATA_CMD_WRITE_SECTORS_EXT // 48-bit LBA; PIO write
54 }
55 },
56 {
57 {
58 ATA_CMD_READ_DMA, // 28-bit LBA; DMA read
59 ATA_CMD_WRITE_DMA // 28-bit LBA; DMA write
60 },
61 {
62 ATA_CMD_READ_DMA_EXT, // 48-bit LBA; DMA read
63 ATA_CMD_WRITE_DMA_EXT // 48-bit LBA; DMA write
64 }
65 }
66};
67
68//
69// Look up table (UdmaValid, IsTrustSend) for ATA_CMD
70//
71UINT8 mAtaTrustCommands[2][2] = {
72 {
73 ATA_CMD_TRUST_RECEIVE, // PIO read
74 ATA_CMD_TRUST_SEND // PIO write
75 },
76 {
77 ATA_CMD_TRUST_RECEIVE_DMA, // DMA read
78 ATA_CMD_TRUST_SEND_DMA // DMA write
79 }
80};
81
82//
83// Look up table (Lba48Bit) for maximum transfer block number
84//
85UINTN mMaxTransferBlockNumber[] = {
86 MAX_28BIT_TRANSFER_BLOCK_NUM,
87 MAX_48BIT_TRANSFER_BLOCK_NUM
88};
89
113 IN OUT ATA_DEVICE *AtaDevice,
114 IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *TaskPacket OPTIONAL,
115 IN OUT EFI_EVENT Event OPTIONAL
116 )
117{
118 EFI_STATUS Status;
119 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
121
122 //
123 // Assemble packet. If it is non blocking mode, the Ata driver should keep each
124 // subtask and clean them when the event is signaled.
125 //
126 if (TaskPacket != NULL) {
127 Packet = TaskPacket;
128 Packet->Asb = AllocateAlignedBuffer (AtaDevice, sizeof (EFI_ATA_STATUS_BLOCK));
129 if (Packet->Asb == NULL) {
130 return EFI_OUT_OF_RESOURCES;
131 }
132
133 CopyMem (Packet->Asb, AtaDevice->Asb, sizeof (EFI_ATA_STATUS_BLOCK));
134 Packet->Acb = AllocateCopyPool (sizeof (EFI_ATA_COMMAND_BLOCK), &AtaDevice->Acb);
135 } else {
136 Packet = &AtaDevice->Packet;
137 Packet->Asb = AtaDevice->Asb;
138 Packet->Acb = &AtaDevice->Acb;
139 }
140
141 AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
142
143 Status = AtaPassThru->PassThru (
144 AtaPassThru,
145 AtaDevice->Port,
146 AtaDevice->PortMultiplierPort,
147 Packet,
148 Event
149 );
150 //
151 // Ensure ATA pass through caller and callee have the same
152 // interpretation of ATA pass through protocol.
153 //
154 ASSERT (Status != EFI_INVALID_PARAMETER);
155 ASSERT (Status != EFI_BAD_BUFFER_SIZE);
156
157 return Status;
158}
159
173 IN ATA_DEVICE *AtaDevice
174 )
175{
176 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
177
178 AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
179
180 //
181 // Report Status Code to indicate reset happens
182 //
185 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),
186 AtaDevice->AtaBusDriverData->ParentDevicePath
187 );
188
189 return AtaPassThru->ResetDevice (
190 AtaPassThru,
191 AtaDevice->Port,
192 AtaDevice->PortMultiplierPort
193 );
194}
195
206VOID
208 IN OUT ATA_DEVICE *AtaDevice
209 )
210{
211 UINTN Index;
212 CHAR8 *Source;
213 CHAR16 *Destination;
214
215 Source = AtaDevice->IdentifyData->ModelName;
216 Destination = AtaDevice->ModelName;
217
218 //
219 // Swap the byte order in the original module name.
220 //
221 for (Index = 0; Index < MAX_MODEL_NAME_LEN; Index += 2) {
222 Destination[Index] = Source[Index + 1];
223 Destination[Index + 1] = Source[Index];
224 }
225
226 AtaDevice->ModelName[MAX_MODEL_NAME_LEN] = L'\0';
227}
228
243 IN ATA_DEVICE *AtaDevice
244 )
245{
246 EFI_LBA Capacity;
247 EFI_LBA TmpLba;
248 UINTN Index;
249 ATA_IDENTIFY_DATA *IdentifyData;
250
251 IdentifyData = AtaDevice->IdentifyData;
252 if ((IdentifyData->command_set_supported_83 & BIT10) == 0) {
253 //
254 // The device doesn't support 48 bit addressing
255 //
256 return 0;
257 }
258
259 //
260 // 48 bit address feature set is supported, get maximum capacity
261 //
262 Capacity = 0;
263 for (Index = 0; Index < 4; Index++) {
264 //
265 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
266 //
267 TmpLba = IdentifyData->maximum_lba_for_48bit_addressing[Index];
268 Capacity |= LShiftU64 (TmpLba, 16 * Index);
269 }
270
271 return Capacity;
272}
273
289 IN OUT ATA_DEVICE *AtaDevice
290 )
291{
292 ATA_IDENTIFY_DATA *IdentifyData;
293 EFI_BLOCK_IO_MEDIA *BlockMedia;
294 EFI_LBA Capacity;
295 UINT16 PhyLogicSectorSupport;
296 UINT16 UdmaMode;
297
298 IdentifyData = AtaDevice->IdentifyData;
299
300 if ((IdentifyData->config & BIT15) != 0) {
301 //
302 // This is not an hard disk
303 //
304 return EFI_UNSUPPORTED;
305 }
306
307 DEBUG ((DEBUG_INFO, "AtaBus - Identify Device: Port %x PortMultiplierPort %x\n", AtaDevice->Port, AtaDevice->PortMultiplierPort));
308
309 //
310 // Check whether the WORD 88 (supported UltraDMA by drive) is valid
311 //
312 if ((IdentifyData->field_validity & BIT2) != 0) {
313 UdmaMode = IdentifyData->ultra_dma_mode;
314 if ((UdmaMode & (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6)) != 0) {
315 //
316 // If BIT0~BIT6 is selected, then UDMA is supported
317 //
318 AtaDevice->UdmaValid = TRUE;
319 }
320 }
321
322 Capacity = GetAtapi6Capacity (AtaDevice);
323 if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {
324 //
325 // Capacity exceeds 120GB. 48-bit addressing is really needed
326 //
327 AtaDevice->Lba48Bit = TRUE;
328 } else {
329 //
330 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
331 //
332 Capacity = ((UINT32)IdentifyData->user_addressable_sectors_hi << 16) | IdentifyData->user_addressable_sectors_lo;
333 AtaDevice->Lba48Bit = FALSE;
334 }
335
336 //
337 // Block Media Information:
338 //
339 BlockMedia = &AtaDevice->BlockMedia;
340 BlockMedia->LastBlock = Capacity - 1;
341 BlockMedia->IoAlign = AtaDevice->AtaBusDriverData->AtaPassThru->Mode->IoAlign;
342 //
343 // Check whether Long Physical Sector Feature is supported
344 //
345 PhyLogicSectorSupport = IdentifyData->phy_logic_sector_support;
346 if ((PhyLogicSectorSupport & (BIT14 | BIT15)) == BIT14) {
347 //
348 // Check whether one physical block contains multiple physical blocks
349 //
350 if ((PhyLogicSectorSupport & BIT13) != 0) {
351 BlockMedia->LogicalBlocksPerPhysicalBlock = (UINT32)(1 << (PhyLogicSectorSupport & 0x000f));
352 //
353 // Check lowest alignment of logical blocks within physical block
354 //
355 if ((IdentifyData->alignment_logic_in_phy_blocks & (BIT14 | BIT15)) == BIT14) {
356 BlockMedia->LowestAlignedLba = (EFI_LBA)((BlockMedia->LogicalBlocksPerPhysicalBlock - ((UINT32)IdentifyData->alignment_logic_in_phy_blocks & 0x3fff)) %
358 }
359 }
360
361 //
362 // Check logical block size
363 //
364 if ((PhyLogicSectorSupport & BIT12) != 0) {
365 BlockMedia->BlockSize = (UINT32)(((UINT32)(IdentifyData->logic_sector_size_hi << 16) | IdentifyData->logic_sector_size_lo) * sizeof (UINT16));
366 }
367
368 AtaDevice->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2;
369 }
370
371 //
372 // Get ATA model name from identify data structure.
373 //
374 PrintAtaModelName (AtaDevice);
375
376 return EFI_SUCCESS;
377}
378
395 IN OUT ATA_DEVICE *AtaDevice
396 )
397{
398 EFI_STATUS Status;
401 UINTN Retry;
402
403 //
404 // Prepare for ATA command block.
405 //
406 Acb = ZeroMem (&AtaDevice->Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
407 Acb->AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
408 Acb->AtaDeviceHead = (UINT8)(BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort == 0xFFFF ? 0 : (AtaDevice->PortMultiplierPort << 4)));
409
410 //
411 // Prepare for ATA pass through packet.
412 //
413 Packet = ZeroMem (&AtaDevice->Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
414 Packet->InDataBuffer = AtaDevice->IdentifyData;
415 Packet->InTransferLength = sizeof (ATA_IDENTIFY_DATA);
416 Packet->Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN;
417 Packet->Length = EFI_ATA_PASS_THRU_LENGTH_BYTES | EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
418 Packet->Timeout = ATA_TIMEOUT;
419
420 Retry = MAX_RETRY_TIMES;
421 do {
422 Status = AtaDevicePassThru (AtaDevice, NULL, NULL);
423 if (!EFI_ERROR (Status)) {
424 //
425 // The command is issued successfully
426 //
427 Status = IdentifyAtaDevice (AtaDevice);
428 return Status;
429 }
430 } while (Retry-- > 0);
431
432 return Status;
433}
434
463 IN OUT ATA_DEVICE *AtaDevice,
464 IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *TaskPacket OPTIONAL,
465 IN OUT VOID *Buffer,
466 IN EFI_LBA StartLba,
467 IN UINT32 TransferLength,
468 IN BOOLEAN IsWrite,
469 IN EFI_EVENT Event OPTIONAL
470 )
471{
474
475 //
476 // Ensure AtaDevice->UdmaValid, AtaDevice->Lba48Bit and IsWrite are valid boolean values
477 //
478 ASSERT ((UINTN)AtaDevice->UdmaValid < 2);
479 ASSERT ((UINTN)AtaDevice->Lba48Bit < 2);
480 ASSERT ((UINTN)IsWrite < 2);
481 //
482 // Prepare for ATA command block.
483 //
484 Acb = ZeroMem (&AtaDevice->Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
485 Acb->AtaCommand = mAtaCommands[AtaDevice->UdmaValid][AtaDevice->Lba48Bit][IsWrite];
486 Acb->AtaSectorNumber = (UINT8)StartLba;
487 Acb->AtaCylinderLow = (UINT8)RShiftU64 (StartLba, 8);
488 Acb->AtaCylinderHigh = (UINT8)RShiftU64 (StartLba, 16);
489 Acb->AtaDeviceHead = (UINT8)(BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort == 0xFFFF ? 0 : (AtaDevice->PortMultiplierPort << 4)));
490 Acb->AtaSectorCount = (UINT8)TransferLength;
491 if (AtaDevice->Lba48Bit) {
492 Acb->AtaSectorNumberExp = (UINT8)RShiftU64 (StartLba, 24);
493 Acb->AtaCylinderLowExp = (UINT8)RShiftU64 (StartLba, 32);
494 Acb->AtaCylinderHighExp = (UINT8)RShiftU64 (StartLba, 40);
495 Acb->AtaSectorCountExp = (UINT8)(TransferLength >> 8);
496 } else {
497 Acb->AtaDeviceHead = (UINT8)(Acb->AtaDeviceHead | RShiftU64 (StartLba, 24));
498 }
499
500 //
501 // Prepare for ATA pass through packet.
502 //
503 if (TaskPacket != NULL) {
504 Packet = ZeroMem (TaskPacket, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
505 } else {
506 Packet = ZeroMem (&AtaDevice->Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
507 }
508
509 if (IsWrite) {
510 Packet->OutDataBuffer = Buffer;
511 Packet->OutTransferLength = TransferLength;
512 } else {
513 Packet->InDataBuffer = Buffer;
514 Packet->InTransferLength = TransferLength;
515 }
516
517 Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsWrite];
518 Packet->Length = EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
519 //
520 // |------------------------|-----------------|------------------------|-----------------|
521 // | ATA PIO Transfer Mode | Transfer Rate | ATA DMA Transfer Mode | Transfer Rate |
522 // |------------------------|-----------------|------------------------|-----------------|
523 // | PIO Mode 0 | 3.3Mbytes/sec | Single-word DMA Mode 0 | 2.1Mbytes/sec |
524 // |------------------------|-----------------|------------------------|-----------------|
525 // | PIO Mode 1 | 5.2Mbytes/sec | Single-word DMA Mode 1 | 4.2Mbytes/sec |
526 // |------------------------|-----------------|------------------------|-----------------|
527 // | PIO Mode 2 | 8.3Mbytes/sec | Single-word DMA Mode 2 | 8.4Mbytes/sec |
528 // |------------------------|-----------------|------------------------|-----------------|
529 // | PIO Mode 3 | 11.1Mbytes/sec | Multi-word DMA Mode 0 | 4.2Mbytes/sec |
530 // |------------------------|-----------------|------------------------|-----------------|
531 // | PIO Mode 4 | 16.6Mbytes/sec | Multi-word DMA Mode 1 | 13.3Mbytes/sec |
532 // |------------------------|-----------------|------------------------|-----------------|
533 //
534 // As AtaBus is used to manage ATA devices, we have to use the lowest transfer rate to
535 // calculate the possible maximum timeout value for each read/write operation.
536 // The timeout value is rounded up to nearest integer and here an additional 30s is added
537 // to follow ATA spec in which it mentioned that the device may take up to 30s to respond
538 // commands in the Standby/Idle mode.
539 //
540 if (AtaDevice->UdmaValid) {
541 //
542 // Calculate the maximum timeout value for DMA read/write operation.
543 //
544 Packet->Timeout = EFI_TIMER_PERIOD_SECONDS (DivU64x32 (MultU64x32 (TransferLength, AtaDevice->BlockMedia.BlockSize), 2100000) + 31);
545 } else {
546 //
547 // Calculate the maximum timeout value for PIO read/write operation
548 //
549 Packet->Timeout = EFI_TIMER_PERIOD_SECONDS (DivU64x32 (MultU64x32 (TransferLength, AtaDevice->BlockMedia.BlockSize), 3300000) + 31);
550 }
551
552 return AtaDevicePassThru (AtaDevice, TaskPacket, Event);
553}
554
561VOID
562EFIAPI
565 )
566{
567 if (Task->Packet.Asb != NULL) {
568 FreeAlignedBuffer (Task->Packet.Asb, sizeof (EFI_ATA_STATUS_BLOCK));
569 }
570
571 if (Task->Packet.Acb != NULL) {
572 FreePool (Task->Packet.Acb);
573 }
574
575 FreePool (Task);
576}
577
588VOID
589EFIAPI
591 IN ATA_DEVICE *AtaDevice
592 )
593{
594 BOOLEAN SubTaskEmpty;
595 EFI_TPL OldTpl;
596 ATA_BUS_ASYN_TASK *AtaTask;
597 LIST_ENTRY *Entry;
598 LIST_ENTRY *List;
599
600 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
601 //
602 // Abort all executing tasks from now.
603 //
604 AtaDevice->Abort = TRUE;
605
606 List = &AtaDevice->AtaTaskList;
607 for (Entry = GetFirstNode (List); !IsNull (List, Entry);) {
608 AtaTask = ATA_ASYN_TASK_FROM_ENTRY (Entry);
609 AtaTask->Token->TransactionStatus = EFI_ABORTED;
610 gBS->SignalEvent (AtaTask->Token->Event);
611
612 Entry = RemoveEntryList (Entry);
613 FreePool (AtaTask);
614 }
615
616 gBS->RestoreTPL (OldTpl);
617
618 do {
619 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
620 //
621 // Wait for executing subtasks done.
622 //
623 SubTaskEmpty = IsListEmpty (&AtaDevice->AtaSubTaskList);
624 gBS->RestoreTPL (OldTpl);
625 } while (!SubTaskEmpty);
626
627 //
628 // Aborting operation has been done. From now on, don't need to abort normal operation.
629 //
630 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
631 AtaDevice->Abort = FALSE;
632 gBS->RestoreTPL (OldTpl);
633}
634
643VOID
644EFIAPI
646 IN EFI_EVENT Event,
647 IN VOID *Context
648 )
649{
651 ATA_BUS_ASYN_TASK *AtaTask;
652 ATA_DEVICE *AtaDevice;
653 LIST_ENTRY *Entry;
654 EFI_STATUS Status;
655
656 Task = (ATA_BUS_ASYN_SUB_TASK *)Context;
657 gBS->CloseEvent (Event);
658
659 AtaDevice = Task->AtaDevice;
660
661 //
662 // Check the command status.
663 // If there is error during the sub task source allocation, the error status
664 // should be returned to the caller directly, so here the Task->Token may already
665 // be deleted by the caller and no need to update the status.
666 //
667 if ((!(*Task->IsError)) && ((Task->Packet.Asb->AtaStatus & 0x01) == 0x01)) {
668 Task->Token->TransactionStatus = EFI_DEVICE_ERROR;
669 }
670
671 if (AtaDevice->Abort) {
672 Task->Token->TransactionStatus = EFI_ABORTED;
673 }
674
675 DEBUG ((
676 DEBUG_BLKIO,
677 "NON-BLOCKING EVENT FINISHED!- STATUS = %r\n",
678 Task->Token->TransactionStatus
679 ));
680
681 //
682 // Reduce the SubEventCount, till it comes to zero.
683 //
684 (*Task->UnsignalledEventCount)--;
685 DEBUG ((DEBUG_BLKIO, "UnsignalledEventCount = %d\n", *Task->UnsignalledEventCount));
686
687 //
688 // Remove the SubTask from the Task list.
689 //
690 RemoveEntryList (&Task->TaskEntry);
691 if ((*Task->UnsignalledEventCount) == 0) {
692 //
693 // All Sub tasks are done, then signal the upper layer event.
694 // Except there is error during the sub task source allocation.
695 //
696 if (!(*Task->IsError)) {
697 gBS->SignalEvent (Task->Token->Event);
698 DEBUG ((DEBUG_BLKIO, "Signal the upper layer event!\n"));
699 }
700
701 FreePool (Task->UnsignalledEventCount);
702 FreePool (Task->IsError);
703
704 //
705 // Finish all subtasks and move to the next task in AtaTaskList.
706 //
707 if (!IsListEmpty (&AtaDevice->AtaTaskList)) {
708 Entry = GetFirstNode (&AtaDevice->AtaTaskList);
709 AtaTask = ATA_ASYN_TASK_FROM_ENTRY (Entry);
710 DEBUG ((DEBUG_BLKIO, "Start to embark a new Ata Task\n"));
711 DEBUG ((DEBUG_BLKIO, "AtaTask->NumberOfBlocks = %x; AtaTask->Token=%x\n", AtaTask->NumberOfBlocks, AtaTask->Token));
712 Status = AccessAtaDevice (
713 AtaTask->AtaDevice,
714 AtaTask->Buffer,
715 AtaTask->StartLba,
716 AtaTask->NumberOfBlocks,
717 AtaTask->IsWrite,
718 AtaTask->Token
719 );
720 if (EFI_ERROR (Status)) {
721 AtaTask->Token->TransactionStatus = Status;
722 gBS->SignalEvent (AtaTask->Token->Event);
723 }
724
725 RemoveEntryList (Entry);
726 FreePool (AtaTask);
727 }
728 }
729
730 DEBUG ((
731 DEBUG_BLKIO,
732 "PACKET INFO: Write=%s, Length=%x, LowCylinder=%x, HighCylinder=%x, SectionNumber=%x\n",
733 Task->Packet.OutDataBuffer != NULL ? L"YES" : L"NO",
734 Task->Packet.OutDataBuffer != NULL ? Task->Packet.OutTransferLength : Task->Packet.InTransferLength,
735 Task->Packet.Acb->AtaCylinderLow,
736 Task->Packet.Acb->AtaCylinderHigh,
737 Task->Packet.Acb->AtaSectorCount
738 ));
739
740 //
741 // Free the buffer of SubTask.
742 //
743 FreeAtaSubTask (Task);
744}
745
766 IN OUT ATA_DEVICE *AtaDevice,
767 IN OUT UINT8 *Buffer,
768 IN EFI_LBA StartLba,
769 IN UINTN NumberOfBlocks,
770 IN BOOLEAN IsWrite,
772 )
773{
774 EFI_STATUS Status;
775 UINTN MaxTransferBlockNumber;
776 UINTN TransferBlockNumber;
777 UINTN BlockSize;
778 ATA_BUS_ASYN_SUB_TASK *SubTask;
779 UINTN *EventCount;
780 UINTN TempCount;
781 ATA_BUS_ASYN_TASK *AtaTask;
782 EFI_EVENT SubEvent;
783 UINTN Index;
784 BOOLEAN *IsError;
785 EFI_TPL OldTpl;
786
787 TempCount = 0;
788 Status = EFI_SUCCESS;
789 EventCount = NULL;
790 IsError = NULL;
791 Index = 0;
792 SubTask = NULL;
793 SubEvent = NULL;
794 AtaTask = NULL;
795
796 //
797 // Ensure AtaDevice->Lba48Bit is a valid boolean value
798 //
799 ASSERT ((UINTN)AtaDevice->Lba48Bit < 2);
800 MaxTransferBlockNumber = mMaxTransferBlockNumber[AtaDevice->Lba48Bit];
801 BlockSize = AtaDevice->BlockMedia.BlockSize;
802
803 //
804 // Initial the return status and shared account for Non Blocking.
805 //
806 if ((Token != NULL) && (Token->Event != NULL)) {
807 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
808
809 if (!IsListEmpty (&AtaDevice->AtaSubTaskList)) {
810 AtaTask = AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK));
811 if (AtaTask == NULL) {
812 gBS->RestoreTPL (OldTpl);
813 return EFI_OUT_OF_RESOURCES;
814 }
815
816 AtaTask->AtaDevice = AtaDevice;
817 AtaTask->Buffer = Buffer;
818 AtaTask->IsWrite = IsWrite;
819 AtaTask->NumberOfBlocks = NumberOfBlocks;
820 AtaTask->Signature = ATA_TASK_SIGNATURE;
821 AtaTask->StartLba = StartLba;
822 AtaTask->Token = Token;
823
824 InsertTailList (&AtaDevice->AtaTaskList, &AtaTask->TaskEntry);
825 gBS->RestoreTPL (OldTpl);
826 return EFI_SUCCESS;
827 }
828
829 gBS->RestoreTPL (OldTpl);
830
831 Token->TransactionStatus = EFI_SUCCESS;
832 EventCount = AllocateZeroPool (sizeof (UINTN));
833 if (EventCount == NULL) {
834 return EFI_OUT_OF_RESOURCES;
835 }
836
837 IsError = AllocateZeroPool (sizeof (BOOLEAN));
838 if (IsError == NULL) {
839 FreePool (EventCount);
840 return EFI_OUT_OF_RESOURCES;
841 }
842
843 DEBUG ((DEBUG_BLKIO, "Allocation IsError Addr=%x\n", IsError));
844 *IsError = FALSE;
845 TempCount = (NumberOfBlocks + MaxTransferBlockNumber - 1) / MaxTransferBlockNumber;
846 *EventCount = TempCount;
847 DEBUG ((DEBUG_BLKIO, "AccessAtaDevice, NumberOfBlocks=%x\n", NumberOfBlocks));
848 DEBUG ((DEBUG_BLKIO, "AccessAtaDevice, MaxTransferBlockNumber=%x\n", MaxTransferBlockNumber));
849 DEBUG ((DEBUG_BLKIO, "AccessAtaDevice, EventCount=%x\n", TempCount));
850 } else {
851 while (!IsListEmpty (&AtaDevice->AtaTaskList) || !IsListEmpty (&AtaDevice->AtaSubTaskList)) {
852 //
853 // Stall for 100us.
854 //
855 MicroSecondDelay (100);
856 }
857 }
858
859 do {
860 if (NumberOfBlocks > MaxTransferBlockNumber) {
861 TransferBlockNumber = MaxTransferBlockNumber;
862 NumberOfBlocks -= MaxTransferBlockNumber;
863 } else {
864 TransferBlockNumber = NumberOfBlocks;
865 NumberOfBlocks = 0;
866 }
867
868 //
869 // Create sub event for the sub ata task. Non-blocking mode.
870 //
871 if ((Token != NULL) && (Token->Event != NULL)) {
872 SubTask = NULL;
873 SubEvent = NULL;
874
875 SubTask = AllocateZeroPool (sizeof (ATA_BUS_ASYN_SUB_TASK));
876 if (SubTask == NULL) {
877 Status = EFI_OUT_OF_RESOURCES;
878 goto EXIT;
879 }
880
881 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
882 SubTask->UnsignalledEventCount = EventCount;
883 SubTask->Signature = ATA_SUB_TASK_SIGNATURE;
884 SubTask->AtaDevice = AtaDevice;
885 SubTask->Token = Token;
886 SubTask->IsError = IsError;
887 InsertTailList (&AtaDevice->AtaSubTaskList, &SubTask->TaskEntry);
888 gBS->RestoreTPL (OldTpl);
889
890 Status = gBS->CreateEvent (
891 EVT_NOTIFY_SIGNAL,
892 TPL_NOTIFY,
894 SubTask,
895 &SubEvent
896 );
897 //
898 // If resource allocation fail, the un-signalled event count should equal to
899 // the original one minus the unassigned subtasks number.
900 //
901 if (EFI_ERROR (Status)) {
902 Status = EFI_OUT_OF_RESOURCES;
903 goto EXIT;
904 }
905
906 Status = TransferAtaDevice (AtaDevice, &SubTask->Packet, Buffer, StartLba, (UINT32)TransferBlockNumber, IsWrite, SubEvent);
907 } else {
908 //
909 // Blocking Mode.
910 //
911 DEBUG ((DEBUG_BLKIO, "Blocking AccessAtaDevice, TransferBlockNumber=%x; StartLba = %x\n", TransferBlockNumber, StartLba));
912 Status = TransferAtaDevice (AtaDevice, NULL, Buffer, StartLba, (UINT32)TransferBlockNumber, IsWrite, NULL);
913 }
914
915 if (EFI_ERROR (Status)) {
916 goto EXIT;
917 }
918
919 Index++;
920 StartLba += TransferBlockNumber;
921 Buffer += TransferBlockNumber * BlockSize;
922 } while (NumberOfBlocks > 0);
923
924EXIT:
925 if ((Token != NULL) && (Token->Event != NULL)) {
926 //
927 // Release resource at non-blocking mode.
928 //
929 if (EFI_ERROR (Status)) {
930 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
931 Token->TransactionStatus = Status;
932 *EventCount = (*EventCount) - (TempCount - Index);
933 *IsError = TRUE;
934
935 if (*EventCount == 0) {
936 FreePool (EventCount);
937 FreePool (IsError);
938 }
939
940 if (SubTask != NULL) {
941 RemoveEntryList (&SubTask->TaskEntry);
942 FreeAtaSubTask (SubTask);
943 }
944
945 if (SubEvent != NULL) {
946 gBS->CloseEvent (SubEvent);
947 }
948
949 gBS->RestoreTPL (OldTpl);
950 }
951 }
952
953 return Status;
954}
955
986EFIAPI
988 IN OUT ATA_DEVICE *AtaDevice,
989 IN OUT VOID *Buffer,
990 IN UINT8 SecurityProtocolId,
991 IN UINT16 SecurityProtocolSpecificData,
992 IN UINTN TransferLength,
993 IN BOOLEAN IsTrustSend,
994 IN UINT64 Timeout,
995 OUT UINTN *TransferLengthOut
996 )
997{
1000 EFI_STATUS Status;
1001 VOID *NewBuffer;
1002 EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
1003
1004 //
1005 // Ensure AtaDevice->UdmaValid and IsTrustSend are valid boolean values
1006 //
1007 ASSERT ((UINTN)AtaDevice->UdmaValid < 2);
1008 ASSERT ((UINTN)IsTrustSend < 2);
1009 //
1010 // Prepare for ATA command block.
1011 //
1012 Acb = ZeroMem (&AtaDevice->Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
1013 if (TransferLength == 0) {
1014 Acb->AtaCommand = ATA_CMD_TRUST_NON_DATA;
1015 } else {
1016 Acb->AtaCommand = mAtaTrustCommands[AtaDevice->UdmaValid][IsTrustSend];
1017 }
1018
1019 Acb->AtaFeatures = SecurityProtocolId;
1020 Acb->AtaSectorCount = (UINT8)(TransferLength / 512);
1021 Acb->AtaSectorNumber = (UINT8)((TransferLength / 512) >> 8);
1022 //
1023 // NOTE: ATA Spec has no explicitly definition for Security Protocol Specific layout.
1024 // Here use big endian for Cylinder register.
1025 //
1026 Acb->AtaCylinderHigh = (UINT8)SecurityProtocolSpecificData;
1027 Acb->AtaCylinderLow = (UINT8)(SecurityProtocolSpecificData >> 8);
1028 Acb->AtaDeviceHead = (UINT8)(BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort == 0xFFFF ? 0 : (AtaDevice->PortMultiplierPort << 4)));
1029
1030 //
1031 // Prepare for ATA pass through packet.
1032 //
1033 Packet = ZeroMem (&AtaDevice->Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
1034 if (TransferLength == 0) {
1035 Packet->InTransferLength = 0;
1036 Packet->OutTransferLength = 0;
1037 Packet->Protocol = EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA;
1038 } else if (IsTrustSend) {
1039 //
1040 // Check the alignment of the incoming buffer prior to invoking underlying ATA PassThru
1041 //
1042 AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
1043 if ((AtaPassThru->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Buffer, AtaPassThru->Mode->IoAlign)) {
1044 NewBuffer = AllocateAlignedBuffer (AtaDevice, TransferLength);
1045 if (NewBuffer == NULL) {
1046 return EFI_OUT_OF_RESOURCES;
1047 }
1048
1049 CopyMem (NewBuffer, Buffer, TransferLength);
1050 FreePool (Buffer);
1051 Buffer = NewBuffer;
1052 }
1053
1054 Packet->OutDataBuffer = Buffer;
1055 Packet->OutTransferLength = (UINT32)TransferLength;
1056 Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsTrustSend];
1057 } else {
1058 Packet->InDataBuffer = Buffer;
1059 Packet->InTransferLength = (UINT32)TransferLength;
1060 Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsTrustSend];
1061 }
1062
1063 Packet->Length = EFI_ATA_PASS_THRU_LENGTH_BYTES;
1064 Packet->Timeout = Timeout;
1065
1066 Status = AtaDevicePassThru (AtaDevice, NULL, NULL);
1067 if (TransferLengthOut != NULL) {
1068 if (!IsTrustSend) {
1069 *TransferLengthOut = Packet->InTransferLength;
1070 }
1071 }
1072
1073 return Status;
1074}
UINT64 UINTN
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
VOID FreeAlignedBuffer(IN VOID *Buffer, IN UINTN BufferSize)
Definition: AtaBus.c:124
VOID * AllocateAlignedBuffer(IN ATA_DEVICE *AtaDevice, IN UINTN BufferSize)
Definition: AtaBus.c:105
EFI_STATUS ResetAtaDevice(IN ATA_DEVICE *AtaDevice)
EFI_STATUS IdentifyAtaDevice(IN OUT ATA_DEVICE *AtaDevice)
EFI_STATUS DiscoverAtaDevice(IN OUT ATA_DEVICE *AtaDevice)
VOID EFIAPI FreeAtaSubTask(IN OUT ATA_BUS_ASYN_SUB_TASK *Task)
VOID EFIAPI AtaTerminateNonBlockingTask(IN ATA_DEVICE *AtaDevice)
EFI_LBA GetAtapi6Capacity(IN ATA_DEVICE *AtaDevice)
EFI_STATUS AtaDevicePassThru(IN OUT ATA_DEVICE *AtaDevice, IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *TaskPacket OPTIONAL, IN OUT EFI_EVENT Event OPTIONAL)
VOID EFIAPI AtaNonBlockingCallBack(IN EFI_EVENT Event, IN VOID *Context)
VOID PrintAtaModelName(IN OUT ATA_DEVICE *AtaDevice)
EFI_STATUS EFIAPI TrustTransferAtaDevice(IN OUT ATA_DEVICE *AtaDevice, IN OUT VOID *Buffer, IN UINT8 SecurityProtocolId, IN UINT16 SecurityProtocolSpecificData, IN UINTN TransferLength, IN BOOLEAN IsTrustSend, IN UINT64 Timeout, OUT UINTN *TransferLengthOut)
EFI_STATUS TransferAtaDevice(IN OUT ATA_DEVICE *AtaDevice, IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *TaskPacket OPTIONAL, IN OUT VOID *Buffer, IN EFI_LBA StartLba, IN UINT32 TransferLength, IN BOOLEAN IsWrite, IN EFI_EVENT Event OPTIONAL)
EFI_STATUS AccessAtaDevice(IN OUT ATA_DEVICE *AtaDevice, IN OUT UINT8 *Buffer, IN EFI_LBA StartLba, IN UINTN NumberOfBlocks, IN BOOLEAN IsWrite, IN OUT EFI_BLOCK_IO2_TOKEN *Token)
#define ATA_CMD_WRITE_DMA_EXT
defined from ATA-6
Definition: Atapi.h:681
#define ATA_CMD_WRITE_DMA
defined from ATA-1
Definition: Atapi.h:679
#define ATA_CMD_READ_DMA_EXT
defined from ATA-6
Definition: Atapi.h:678
#define ATA_CMD_READ_SECTORS
defined from ATA-1
Definition: Atapi.h:544
#define ATA_CMD_IDENTIFY_DRIVE
defined from ATA-3
Definition: Atapi.h:542
#define ATA_CMD_WRITE_SECTORS_EXT
defined from ATA-6
Definition: Atapi.h:563
#define ATA_CMD_READ_SECTORS_EXT
defined from ATA-6
Definition: Atapi.h:548
#define ATA_CMD_WRITE_SECTORS
defined from ATA-1
Definition: Atapi.h:558
#define ATA_CMD_READ_DMA
defined from ATA-1
Definition: Atapi.h:676
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
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
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
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define NULL
Definition: Base.h:319
#define ADDRESS_IS_ALIGNED(Address, Alignment)
Definition: Base.h:923
#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(Expression)
Definition: DebugLib.h:434
#define REPORT_STATUS_CODE_WITH_DEVICE_PATH(Type, Value, DevicePathParameter)
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:43
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
#define EFI_TIMER_PERIOD_SECONDS(Seconds)
Definition: UefiLib.h:98
UINT16 ultra_dma_mode
word 88
Definition: Atapi.h:125
UINT16 maximum_lba_for_48bit_addressing[4]
word 100~103
Definition: Atapi.h:136
UINT16 config
General Configuration.
Definition: Atapi.h:79
UINT16 alignment_logic_in_phy_blocks
word 209
Definition: Atapi.h:161
UINT16 command_set_supported_83
word 83
Definition: Atapi.h:120
UINT16 logic_sector_size_lo
word 117
Definition: Atapi.h:144
UINT16 phy_logic_sector_support
word 106
Definition: Atapi.h:139
UINT16 logic_sector_size_hi
word 118
Definition: Atapi.h:145
EFI_ATA_STATUS_BLOCK * Asb
Definition: AtaPassThru.h:114
EFI_ATA_PASS_THRU_LENGTH Length
Definition: AtaPassThru.h:167
EFI_ATA_PASS_THRU_CMD_PROTOCOL Protocol
Definition: AtaPassThru.h:163
EFI_ATA_COMMAND_BLOCK * Acb
Definition: AtaPassThru.h:119
EFI_EVENT Event
Definition: BlockIo2.h:34
EFI_STATUS TransactionStatus
Definition: BlockIo2.h:39
UINT32 LogicalBlocksPerPhysicalBlock
Definition: BlockIo.h:192
UINT32 BlockSize
Definition: BlockIo.h:167
EFI_LBA LastBlock
Definition: BlockIo.h:178
EFI_LBA LowestAlignedLba
Definition: BlockIo.h:185