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
31EFI_ATA_PASS_THRU_CMD_PROTOCOL mAtaPassThruCmdProtocols[][2] = {
33 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN,
34 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT
37 EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN,
38 EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT,
45UINT8 mAtaCommands[][2][2] = {
71UINT8 mAtaTrustCommands[2][2] = {
73 ATA_CMD_TRUST_RECEIVE,
77 ATA_CMD_TRUST_RECEIVE_DMA,
78 ATA_CMD_TRUST_SEND_DMA
85UINTN mMaxTransferBlockNumber[] = {
86 MAX_28BIT_TRANSFER_BLOCK_NUM,
87 MAX_48BIT_TRANSFER_BLOCK_NUM
126 if (TaskPacket !=
NULL) {
130 return EFI_OUT_OF_RESOURCES;
136 Packet = &AtaDevice->Packet;
137 Packet->
Asb = AtaDevice->Asb;
138 Packet->
Acb = &AtaDevice->Acb;
141 AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
143 Status = AtaPassThru->PassThru (
146 AtaDevice->PortMultiplierPort,
154 ASSERT (Status != EFI_INVALID_PARAMETER);
155 ASSERT (Status != EFI_BAD_BUFFER_SIZE);
178 AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
185 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),
186 AtaDevice->AtaBusDriverData->ParentDevicePath
189 return AtaPassThru->ResetDevice (
192 AtaDevice->PortMultiplierPort
215 Source = AtaDevice->IdentifyData->ModelName;
216 Destination = AtaDevice->ModelName;
221 for (Index = 0; Index < MAX_MODEL_NAME_LEN; Index += 2) {
222 Destination[Index] = Source[Index + 1];
223 Destination[Index + 1] = Source[Index];
226 AtaDevice->ModelName[MAX_MODEL_NAME_LEN] = L
'\0';
251 IdentifyData = AtaDevice->IdentifyData;
263 for (Index = 0; Index < 4; Index++) {
268 Capacity |=
LShiftU64 (TmpLba, 16 * Index);
295 UINT16 PhyLogicSectorSupport;
298 IdentifyData = AtaDevice->IdentifyData;
300 if ((IdentifyData->
config & BIT15) != 0) {
304 return EFI_UNSUPPORTED;
307 DEBUG ((DEBUG_INFO,
"AtaBus - Identify Device: Port %x PortMultiplierPort %x\n", AtaDevice->Port, AtaDevice->PortMultiplierPort));
312 if ((IdentifyData->field_validity & BIT2) != 0) {
314 if ((UdmaMode & (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6)) != 0) {
318 AtaDevice->UdmaValid =
TRUE;
323 if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {
327 AtaDevice->Lba48Bit =
TRUE;
332 Capacity = ((UINT32)IdentifyData->user_addressable_sectors_hi << 16) | IdentifyData->user_addressable_sectors_lo;
333 AtaDevice->Lba48Bit =
FALSE;
339 BlockMedia = &AtaDevice->BlockMedia;
341 BlockMedia->
IoAlign = AtaDevice->AtaBusDriverData->AtaPassThru->Mode->IoAlign;
346 if ((PhyLogicSectorSupport & (BIT14 | BIT15)) == BIT14) {
350 if ((PhyLogicSectorSupport & BIT13) != 0) {
364 if ((PhyLogicSectorSupport & BIT12) != 0) {
368 AtaDevice->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2;
408 Acb->AtaDeviceHead = (UINT8)(BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort == 0xFFFF ? 0 : (AtaDevice->PortMultiplierPort << 4)));
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;
420 Retry = MAX_RETRY_TIMES;
423 if (!EFI_ERROR (Status)) {
430 }
while (Retry-- > 0);
467 IN UINT32 TransferLength,
478 ASSERT ((
UINTN)AtaDevice->UdmaValid < 2);
479 ASSERT ((
UINTN)AtaDevice->Lba48Bit < 2);
480 ASSERT ((
UINTN)IsWrite < 2);
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);
497 Acb->AtaDeviceHead = (UINT8)(Acb->AtaDeviceHead |
RShiftU64 (StartLba, 24));
503 if (TaskPacket !=
NULL) {
517 Packet->
Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsWrite];
518 Packet->
Length = EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
540 if (AtaDevice->UdmaValid) {
567 if (Task->Packet.Asb !=
NULL) {
571 if (Task->Packet.Acb !=
NULL) {
594 BOOLEAN SubTaskEmpty;
600 OldTpl =
gBS->RaiseTPL (TPL_NOTIFY);
604 AtaDevice->Abort =
TRUE;
606 List = &AtaDevice->AtaTaskList;
608 AtaTask = ATA_ASYN_TASK_FROM_ENTRY (Entry);
610 gBS->SignalEvent (AtaTask->Token->
Event);
616 gBS->RestoreTPL (OldTpl);
619 OldTpl =
gBS->RaiseTPL (TPL_NOTIFY);
623 SubTaskEmpty =
IsListEmpty (&AtaDevice->AtaSubTaskList);
624 gBS->RestoreTPL (OldTpl);
625 }
while (!SubTaskEmpty);
630 OldTpl =
gBS->RaiseTPL (TPL_NOTIFY);
631 AtaDevice->Abort =
FALSE;
632 gBS->RestoreTPL (OldTpl);
657 gBS->CloseEvent (Event);
659 AtaDevice = Task->AtaDevice;
667 if ((!(*Task->IsError)) && ((Task->Packet.
Asb->AtaStatus & 0x01) == 0x01)) {
671 if (AtaDevice->Abort) {
677 "NON-BLOCKING EVENT FINISHED!- STATUS = %r\n",
684 (*Task->UnsignalledEventCount)--;
685 DEBUG ((DEBUG_BLKIO,
"UnsignalledEventCount = %d\n", *Task->UnsignalledEventCount));
691 if ((*Task->UnsignalledEventCount) == 0) {
696 if (!(*Task->IsError)) {
697 gBS->SignalEvent (Task->Token->
Event);
698 DEBUG ((DEBUG_BLKIO,
"Signal the upper layer event!\n"));
701 FreePool (Task->UnsignalledEventCount);
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));
716 AtaTask->NumberOfBlocks,
720 if (EFI_ERROR (Status)) {
722 gBS->SignalEvent (AtaTask->Token->
Event);
732 "PACKET INFO: Write=%s, Length=%x, LowCylinder=%x, HighCylinder=%x, SectionNumber=%x\n",
735 Task->Packet.
Acb->AtaCylinderLow,
736 Task->Packet.
Acb->AtaCylinderHigh,
737 Task->Packet.
Acb->AtaSectorCount
767 IN OUT UINT8 *Buffer,
775 UINTN MaxTransferBlockNumber;
776 UINTN TransferBlockNumber;
799 ASSERT ((
UINTN)AtaDevice->Lba48Bit < 2);
800 MaxTransferBlockNumber = mMaxTransferBlockNumber[AtaDevice->Lba48Bit];
801 BlockSize = AtaDevice->BlockMedia.BlockSize;
806 if ((Token !=
NULL) && (Token->Event !=
NULL)) {
807 OldTpl =
gBS->RaiseTPL (TPL_NOTIFY);
811 if (AtaTask ==
NULL) {
812 gBS->RestoreTPL (OldTpl);
813 return EFI_OUT_OF_RESOURCES;
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;
825 gBS->RestoreTPL (OldTpl);
829 gBS->RestoreTPL (OldTpl);
833 if (EventCount ==
NULL) {
834 return EFI_OUT_OF_RESOURCES;
838 if (IsError ==
NULL) {
840 return EFI_OUT_OF_RESOURCES;
843 DEBUG ((DEBUG_BLKIO,
"Allocation IsError Addr=%x\n", IsError));
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));
860 if (NumberOfBlocks > MaxTransferBlockNumber) {
861 TransferBlockNumber = MaxTransferBlockNumber;
862 NumberOfBlocks -= MaxTransferBlockNumber;
864 TransferBlockNumber = NumberOfBlocks;
871 if ((Token !=
NULL) && (Token->Event !=
NULL)) {
876 if (SubTask ==
NULL) {
877 Status = EFI_OUT_OF_RESOURCES;
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;
888 gBS->RestoreTPL (OldTpl);
890 Status =
gBS->CreateEvent (
901 if (EFI_ERROR (Status)) {
902 Status = EFI_OUT_OF_RESOURCES;
906 Status =
TransferAtaDevice (AtaDevice, &SubTask->Packet, Buffer, StartLba, (UINT32)TransferBlockNumber, IsWrite, SubEvent);
911 DEBUG ((DEBUG_BLKIO,
"Blocking AccessAtaDevice, TransferBlockNumber=%x; StartLba = %x\n", TransferBlockNumber, StartLba));
915 if (EFI_ERROR (Status)) {
920 StartLba += TransferBlockNumber;
921 Buffer += TransferBlockNumber * BlockSize;
922 }
while (NumberOfBlocks > 0);
925 if ((Token !=
NULL) && (Token->Event !=
NULL)) {
929 if (EFI_ERROR (Status)) {
930 OldTpl =
gBS->RaiseTPL (TPL_NOTIFY);
931 Token->TransactionStatus = Status;
932 *EventCount = (*EventCount) - (TempCount - Index);
935 if (*EventCount == 0) {
940 if (SubTask !=
NULL) {
945 if (SubEvent !=
NULL) {
946 gBS->CloseEvent (SubEvent);
949 gBS->RestoreTPL (OldTpl);
990 IN UINT8 SecurityProtocolId,
991 IN UINT16 SecurityProtocolSpecificData,
993 IN BOOLEAN IsTrustSend,
1007 ASSERT ((
UINTN)AtaDevice->UdmaValid < 2);
1008 ASSERT ((
UINTN)IsTrustSend < 2);
1013 if (TransferLength == 0) {
1014 Acb->AtaCommand = ATA_CMD_TRUST_NON_DATA;
1016 Acb->AtaCommand = mAtaTrustCommands[AtaDevice->UdmaValid][IsTrustSend];
1019 Acb->AtaFeatures = SecurityProtocolId;
1020 Acb->AtaSectorCount = (UINT8)(TransferLength / 512);
1021 Acb->AtaSectorNumber = (UINT8)((TransferLength / 512) >> 8);
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)));
1034 if (TransferLength == 0) {
1037 Packet->
Protocol = EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA;
1038 }
else if (IsTrustSend) {
1042 AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
1043 if ((AtaPassThru->Mode->IoAlign > 1) && !
ADDRESS_IS_ALIGNED (Buffer, AtaPassThru->Mode->IoAlign)) {
1045 if (NewBuffer ==
NULL) {
1046 return EFI_OUT_OF_RESOURCES;
1049 CopyMem (NewBuffer, Buffer, TransferLength);
1056 Packet->
Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsTrustSend];
1060 Packet->
Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsTrustSend];
1063 Packet->
Length = EFI_ATA_PASS_THRU_LENGTH_BYTES;
1067 if (TransferLengthOut !=
NULL) {
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
VOID FreeAlignedBuffer(IN VOID *Buffer, IN UINTN BufferSize)
VOID * AllocateAlignedBuffer(IN ATA_DEVICE *AtaDevice, IN UINTN BufferSize)
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
#define ATA_CMD_WRITE_DMA
defined from ATA-1
#define ATA_CMD_READ_DMA_EXT
defined from ATA-6
#define ATA_CMD_READ_SECTORS
defined from ATA-1
#define ATA_CMD_IDENTIFY_DRIVE
defined from ATA-3
#define ATA_CMD_WRITE_SECTORS_EXT
defined from ATA-6
#define ATA_CMD_READ_SECTORS_EXT
defined from ATA-6
#define ATA_CMD_WRITE_SECTORS
defined from ATA-1
#define ATA_CMD_READ_DMA
defined from ATA-1
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
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 ADDRESS_IS_ALIGNED(Address, Alignment)
#define DEBUG(Expression)
#define REPORT_STATUS_CODE_WITH_DEVICE_PATH(Type, Value, DevicePathParameter)
#define EFI_PROGRESS_CODE
#define EFI_TIMER_PERIOD_SECONDS(Seconds)
UINT16 ultra_dma_mode
word 88
UINT16 maximum_lba_for_48bit_addressing[4]
word 100~103
UINT16 config
General Configuration.
UINT16 alignment_logic_in_phy_blocks
word 209
UINT16 command_set_supported_83
word 83
UINT16 logic_sector_size_lo
word 117
UINT16 phy_logic_sector_support
word 106
UINT16 logic_sector_size_hi
word 118
EFI_ATA_STATUS_BLOCK * Asb
EFI_ATA_PASS_THRU_LENGTH Length
EFI_ATA_PASS_THRU_CMD_PROTOCOL Protocol
EFI_ATA_COMMAND_BLOCK * Acb
EFI_STATUS TransactionStatus
UINT32 LogicalBlocksPerPhysicalBlock