2 This file implements ATA pass through transaction for ATA bus driver.
4 This file implements the low level execution of ATA pass through transaction.
5 It transforms the high level identity, read/write, reset command to ATA pass
6 through command and protocol.
8 NOTE: This file also implements the StorageSecurityCommandProtocol(SSP). For input
9 parameter SecurityProtocolSpecificData, ATA spec has no explicitly definition
10 for Security Protocol Specific layout. This implementation uses big endian for
13 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
14 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
15 SPDX-License-Identifier: BSD-2-Clause-Patent
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
29 // Look up table (UdmaValid, IsWrite) for EFI_ATA_PASS_THRU_CMD_PROTOCOL
31 EFI_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
,
43 // Look up table (UdmaValid, Lba48Bit, IsIsWrite) for ATA_CMD
45 UINT8 mAtaCommands
[][2][2] = {
48 ATA_CMD_READ_SECTORS
, // 28-bit LBA; PIO read
49 ATA_CMD_WRITE_SECTORS
// 28-bit LBA; PIO write
52 ATA_CMD_READ_SECTORS_EXT
, // 48-bit LBA; PIO read
53 ATA_CMD_WRITE_SECTORS_EXT
// 48-bit LBA; PIO write
58 ATA_CMD_READ_DMA
, // 28-bit LBA; DMA read
59 ATA_CMD_WRITE_DMA
// 28-bit LBA; DMA write
62 ATA_CMD_READ_DMA_EXT
, // 48-bit LBA; DMA read
63 ATA_CMD_WRITE_DMA_EXT
// 48-bit LBA; DMA write
69 // Look up table (UdmaValid, IsTrustSend) for ATA_CMD
71 UINT8 mAtaTrustCommands
[2][2] = {
73 ATA_CMD_TRUST_RECEIVE
, // PIO read
74 ATA_CMD_TRUST_SEND
// PIO write
77 ATA_CMD_TRUST_RECEIVE_DMA
, // DMA read
78 ATA_CMD_TRUST_SEND_DMA
// DMA write
84 // Look up table (Lba48Bit) for maximum transfer block number
86 UINTN mMaxTransferBlockNumber
[] = {
87 MAX_28BIT_TRANSFER_BLOCK_NUM
,
88 MAX_48BIT_TRANSFER_BLOCK_NUM
93 Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
95 This function wraps the PassThru() invocation for ATA pass through function
96 for an ATA device. It assembles the ATA pass through command packet for ATA
99 @param[in, out] AtaDevice The ATA child device involved for the operation.
100 @param[in, out] TaskPacket Pointer to a Pass Thru Command Packet. Optional,
101 if it is NULL, blocking mode, and use the packet
102 in AtaDevice. If it is not NULL, non blocking mode,
103 and pass down this Packet.
104 @param[in, out] Event If Event is NULL, then blocking I/O is performed.
105 If Event is not NULL and non-blocking I/O is
106 supported,then non-blocking I/O is performed,
107 and Event will be signaled when the write
108 request is completed.
110 @return The return status from EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
115 IN OUT ATA_DEVICE
*AtaDevice
,
116 IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET
*TaskPacket
, OPTIONAL
117 IN OUT EFI_EVENT Event OPTIONAL
121 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
122 EFI_ATA_PASS_THRU_COMMAND_PACKET
*Packet
;
125 // Assemble packet. If it is non blocking mode, the Ata driver should keep each
126 // subtask and clean them when the event is signaled.
128 if (TaskPacket
!= NULL
) {
130 Packet
->Asb
= AllocateAlignedBuffer (AtaDevice
, sizeof (EFI_ATA_STATUS_BLOCK
));
131 if (Packet
->Asb
== NULL
) {
132 return EFI_OUT_OF_RESOURCES
;
135 CopyMem (Packet
->Asb
, AtaDevice
->Asb
, sizeof (EFI_ATA_STATUS_BLOCK
));
136 Packet
->Acb
= AllocateCopyPool (sizeof (EFI_ATA_COMMAND_BLOCK
), &AtaDevice
->Acb
);
138 Packet
= &AtaDevice
->Packet
;
139 Packet
->Asb
= AtaDevice
->Asb
;
140 Packet
->Acb
= &AtaDevice
->Acb
;
143 AtaPassThru
= AtaDevice
->AtaBusDriverData
->AtaPassThru
;
145 Status
= AtaPassThru
->PassThru (
148 AtaDevice
->PortMultiplierPort
,
153 // Ensure ATA pass through caller and callee have the same
154 // interpretation of ATA pass through protocol.
156 ASSERT (Status
!= EFI_INVALID_PARAMETER
);
157 ASSERT (Status
!= EFI_BAD_BUFFER_SIZE
);
164 Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.ResetDevice().
166 This function wraps the ResetDevice() invocation for ATA pass through function
169 @param AtaDevice The ATA child device involved for the operation.
171 @return The return status from EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
176 IN ATA_DEVICE
*AtaDevice
179 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
181 AtaPassThru
= AtaDevice
->AtaBusDriverData
->AtaPassThru
;
184 // Report Status Code to indicate reset happens
186 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
188 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_PC_RESET
),
189 AtaDevice
->AtaBusDriverData
->ParentDevicePath
192 return AtaPassThru
->ResetDevice (
195 AtaDevice
->PortMultiplierPort
201 Prints ATA model name to ATA device structure.
203 This function converts ATA device model name from ATA identify data
204 to a string in ATA device structure. It needs to change the character
205 order in the original model name string.
207 @param AtaDevice The ATA child device involved for the operation.
212 IN OUT ATA_DEVICE
*AtaDevice
219 Source
= AtaDevice
->IdentifyData
->ModelName
;
220 Destination
= AtaDevice
->ModelName
;
223 // Swap the byte order in the original module name.
225 for (Index
= 0; Index
< MAX_MODEL_NAME_LEN
; Index
+= 2) {
226 Destination
[Index
] = Source
[Index
+ 1];
227 Destination
[Index
+ 1] = Source
[Index
];
229 AtaDevice
->ModelName
[MAX_MODEL_NAME_LEN
] = L
'\0';
234 Gets ATA device Capacity according to ATA 6.
236 This function returns the capacity of the ATA device if it follows
237 ATA 6 to support 48 bit addressing.
239 @param AtaDevice The ATA child device involved for the operation.
241 @return The capacity of the ATA device or 0 if the device does not support
242 48-bit addressing defined in ATA 6.
247 IN ATA_DEVICE
*AtaDevice
253 ATA_IDENTIFY_DATA
*IdentifyData
;
255 IdentifyData
= AtaDevice
->IdentifyData
;
256 if ((IdentifyData
->command_set_supported_83
& BIT10
) == 0) {
258 // The device doesn't support 48 bit addressing
264 // 48 bit address feature set is supported, get maximum capacity
267 for (Index
= 0; Index
< 4; Index
++) {
269 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
271 TmpLba
= IdentifyData
->maximum_lba_for_48bit_addressing
[Index
];
272 Capacity
|= LShiftU64 (TmpLba
, 16 * Index
);
280 Identifies ATA device via the Identify data.
282 This function identifies the ATA device and initializes the Media information in
283 Block IO protocol interface.
285 @param AtaDevice The ATA child device involved for the operation.
287 @retval EFI_UNSUPPORTED The device is not a valid ATA device (hard disk).
288 @retval EFI_SUCCESS The device is successfully identified and Media information
289 is correctly initialized.
294 IN OUT ATA_DEVICE
*AtaDevice
297 ATA_IDENTIFY_DATA
*IdentifyData
;
298 EFI_BLOCK_IO_MEDIA
*BlockMedia
;
300 UINT16 PhyLogicSectorSupport
;
303 IdentifyData
= AtaDevice
->IdentifyData
;
305 if ((IdentifyData
->config
& BIT15
) != 0) {
307 // This is not an hard disk
309 return EFI_UNSUPPORTED
;
312 DEBUG ((EFI_D_INFO
, "AtaBus - Identify Device: Port %x PortMultiplierPort %x\n", AtaDevice
->Port
, AtaDevice
->PortMultiplierPort
));
315 // Check whether the WORD 88 (supported UltraDMA by drive) is valid
317 if ((IdentifyData
->field_validity
& BIT2
) != 0) {
318 UdmaMode
= IdentifyData
->ultra_dma_mode
;
319 if ((UdmaMode
& (BIT0
| BIT1
| BIT2
| BIT3
| BIT4
| BIT5
| BIT6
)) != 0) {
321 // If BIT0~BIT6 is selected, then UDMA is supported
323 AtaDevice
->UdmaValid
= TRUE
;
327 Capacity
= GetAtapi6Capacity (AtaDevice
);
328 if (Capacity
> MAX_28BIT_ADDRESSING_CAPACITY
) {
330 // Capacity exceeds 120GB. 48-bit addressing is really needed
332 AtaDevice
->Lba48Bit
= TRUE
;
335 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
337 Capacity
= ((UINT32
)IdentifyData
->user_addressable_sectors_hi
<< 16) | IdentifyData
->user_addressable_sectors_lo
;
338 AtaDevice
->Lba48Bit
= FALSE
;
342 // Block Media Information:
344 BlockMedia
= &AtaDevice
->BlockMedia
;
345 BlockMedia
->LastBlock
= Capacity
- 1;
346 BlockMedia
->IoAlign
= AtaDevice
->AtaBusDriverData
->AtaPassThru
->Mode
->IoAlign
;
348 // Check whether Long Physical Sector Feature is supported
350 PhyLogicSectorSupport
= IdentifyData
->phy_logic_sector_support
;
351 if ((PhyLogicSectorSupport
& (BIT14
| BIT15
)) == BIT14
) {
353 // Check whether one physical block contains multiple physical blocks
355 if ((PhyLogicSectorSupport
& BIT13
) != 0) {
356 BlockMedia
->LogicalBlocksPerPhysicalBlock
= (UINT32
) (1 << (PhyLogicSectorSupport
& 0x000f));
358 // Check lowest alignment of logical blocks within physical block
360 if ((IdentifyData
->alignment_logic_in_phy_blocks
& (BIT14
| BIT15
)) == BIT14
) {
361 BlockMedia
->LowestAlignedLba
= (EFI_LBA
) ((BlockMedia
->LogicalBlocksPerPhysicalBlock
- ((UINT32
)IdentifyData
->alignment_logic_in_phy_blocks
& 0x3fff)) %
362 BlockMedia
->LogicalBlocksPerPhysicalBlock
);
366 // Check logical block size
368 if ((PhyLogicSectorSupport
& BIT12
) != 0) {
369 BlockMedia
->BlockSize
= (UINT32
) (((IdentifyData
->logic_sector_size_hi
<< 16) | IdentifyData
->logic_sector_size_lo
) * sizeof (UINT16
));
371 AtaDevice
->BlockIo
.Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION2
;
374 // Get ATA model name from identify data structure.
376 PrintAtaModelName (AtaDevice
);
383 Discovers whether it is a valid ATA device.
385 This function issues ATA_CMD_IDENTIFY_DRIVE command to the ATA device to identify it.
386 If the command is executed successfully, it then identifies it and initializes
387 the Media information in Block IO protocol interface.
389 @param AtaDevice The ATA child device involved for the operation.
391 @retval EFI_SUCCESS The device is successfully identified and Media information
392 is correctly initialized.
393 @return others Some error occurs when discovering the ATA device.
398 IN OUT ATA_DEVICE
*AtaDevice
402 EFI_ATA_COMMAND_BLOCK
*Acb
;
403 EFI_ATA_PASS_THRU_COMMAND_PACKET
*Packet
;
407 // Prepare for ATA command block.
409 Acb
= ZeroMem (&AtaDevice
->Acb
, sizeof (EFI_ATA_COMMAND_BLOCK
));
410 Acb
->AtaCommand
= ATA_CMD_IDENTIFY_DRIVE
;
411 Acb
->AtaDeviceHead
= (UINT8
) (BIT7
| BIT6
| BIT5
| (AtaDevice
->PortMultiplierPort
== 0xFFFF ? 0 : (AtaDevice
->PortMultiplierPort
<< 4)));
414 // Prepare for ATA pass through packet.
416 Packet
= ZeroMem (&AtaDevice
->Packet
, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET
));
417 Packet
->InDataBuffer
= AtaDevice
->IdentifyData
;
418 Packet
->InTransferLength
= sizeof (ATA_IDENTIFY_DATA
);
419 Packet
->Protocol
= EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN
;
420 Packet
->Length
= EFI_ATA_PASS_THRU_LENGTH_BYTES
| EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT
;
421 Packet
->Timeout
= ATA_TIMEOUT
;
423 Retry
= MAX_RETRY_TIMES
;
425 Status
= AtaDevicePassThru (AtaDevice
, NULL
, NULL
);
426 if (!EFI_ERROR (Status
)) {
428 // The command is issued successfully
430 Status
= IdentifyAtaDevice (AtaDevice
);
433 } while (Retry
-- > 0);
439 Transfer data from ATA device.
441 This function performs one ATA pass through transaction to transfer data from/to
442 ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
443 interface of ATA pass through.
445 @param[in, out] AtaDevice The ATA child device involved for the operation.
446 @param[in, out] TaskPacket Pointer to a Pass Thru Command Packet. Optional,
447 if it is NULL, blocking mode, and use the packet
448 in AtaDevice. If it is not NULL, non blocking mode,
449 and pass down this Packet.
450 @param[in, out] Buffer The pointer to the current transaction buffer.
451 @param[in] StartLba The starting logical block address to be accessed.
452 @param[in] TransferLength The block number or sector count of the transfer.
453 @param[in] IsWrite Indicates whether it is a write operation.
454 @param[in] Event If Event is NULL, then blocking I/O is performed.
455 If Event is not NULL and non-blocking I/O is
456 supported,then non-blocking I/O is performed,
457 and Event will be signaled when the write
458 request is completed.
460 @retval EFI_SUCCESS The data transfer is complete successfully.
461 @return others Some error occurs when transferring data.
466 IN OUT ATA_DEVICE
*AtaDevice
,
467 IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET
*TaskPacket
, OPTIONAL
470 IN UINT32 TransferLength
,
472 IN EFI_EVENT Event OPTIONAL
475 EFI_ATA_COMMAND_BLOCK
*Acb
;
476 EFI_ATA_PASS_THRU_COMMAND_PACKET
*Packet
;
479 // Ensure AtaDevice->UdmaValid, AtaDevice->Lba48Bit and IsWrite are valid boolean values
481 ASSERT ((UINTN
) AtaDevice
->UdmaValid
< 2);
482 ASSERT ((UINTN
) AtaDevice
->Lba48Bit
< 2);
483 ASSERT ((UINTN
) IsWrite
< 2);
485 // Prepare for ATA command block.
487 Acb
= ZeroMem (&AtaDevice
->Acb
, sizeof (EFI_ATA_COMMAND_BLOCK
));
488 Acb
->AtaCommand
= mAtaCommands
[AtaDevice
->UdmaValid
][AtaDevice
->Lba48Bit
][IsWrite
];
489 Acb
->AtaSectorNumber
= (UINT8
) StartLba
;
490 Acb
->AtaCylinderLow
= (UINT8
) RShiftU64 (StartLba
, 8);
491 Acb
->AtaCylinderHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
492 Acb
->AtaDeviceHead
= (UINT8
) (BIT7
| BIT6
| BIT5
| (AtaDevice
->PortMultiplierPort
== 0xFFFF ? 0 : (AtaDevice
->PortMultiplierPort
<< 4)));
493 Acb
->AtaSectorCount
= (UINT8
) TransferLength
;
494 if (AtaDevice
->Lba48Bit
) {
495 Acb
->AtaSectorNumberExp
= (UINT8
) RShiftU64 (StartLba
, 24);
496 Acb
->AtaCylinderLowExp
= (UINT8
) RShiftU64 (StartLba
, 32);
497 Acb
->AtaCylinderHighExp
= (UINT8
) RShiftU64 (StartLba
, 40);
498 Acb
->AtaSectorCountExp
= (UINT8
) (TransferLength
>> 8);
500 Acb
->AtaDeviceHead
= (UINT8
) (Acb
->AtaDeviceHead
| RShiftU64 (StartLba
, 24));
504 // Prepare for ATA pass through packet.
506 if (TaskPacket
!= NULL
) {
507 Packet
= ZeroMem (TaskPacket
, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET
));
509 Packet
= ZeroMem (&AtaDevice
->Packet
, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET
));
513 Packet
->OutDataBuffer
= Buffer
;
514 Packet
->OutTransferLength
= TransferLength
;
516 Packet
->InDataBuffer
= Buffer
;
517 Packet
->InTransferLength
= TransferLength
;
520 Packet
->Protocol
= mAtaPassThruCmdProtocols
[AtaDevice
->UdmaValid
][IsWrite
];
521 Packet
->Length
= EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT
;
523 // |------------------------|-----------------|------------------------|-----------------|
524 // | ATA PIO Transfer Mode | Transfer Rate | ATA DMA Transfer Mode | Transfer Rate |
525 // |------------------------|-----------------|------------------------|-----------------|
526 // | PIO Mode 0 | 3.3Mbytes/sec | Single-word DMA Mode 0 | 2.1Mbytes/sec |
527 // |------------------------|-----------------|------------------------|-----------------|
528 // | PIO Mode 1 | 5.2Mbytes/sec | Single-word DMA Mode 1 | 4.2Mbytes/sec |
529 // |------------------------|-----------------|------------------------|-----------------|
530 // | PIO Mode 2 | 8.3Mbytes/sec | Single-word DMA Mode 2 | 8.4Mbytes/sec |
531 // |------------------------|-----------------|------------------------|-----------------|
532 // | PIO Mode 3 | 11.1Mbytes/sec | Multi-word DMA Mode 0 | 4.2Mbytes/sec |
533 // |------------------------|-----------------|------------------------|-----------------|
534 // | PIO Mode 4 | 16.6Mbytes/sec | Multi-word DMA Mode 1 | 13.3Mbytes/sec |
535 // |------------------------|-----------------|------------------------|-----------------|
537 // As AtaBus is used to manage ATA devices, we have to use the lowest transfer rate to
538 // calculate the possible maximum timeout value for each read/write operation.
539 // The timout value is rounded up to nearest integar and here an additional 30s is added
540 // to follow ATA spec in which it mentioned that the device may take up to 30s to respond
541 // commands in the Standby/Idle mode.
543 if (AtaDevice
->UdmaValid
) {
545 // Calculate the maximum timeout value for DMA read/write operation.
547 Packet
->Timeout
= EFI_TIMER_PERIOD_SECONDS (DivU64x32 (MultU64x32 (TransferLength
, AtaDevice
->BlockMedia
.BlockSize
), 2100000) + 31);
550 // Calculate the maximum timeout value for PIO read/write operation
552 Packet
->Timeout
= EFI_TIMER_PERIOD_SECONDS (DivU64x32 (MultU64x32 (TransferLength
, AtaDevice
->BlockMedia
.BlockSize
), 3300000) + 31);
555 return AtaDevicePassThru (AtaDevice
, TaskPacket
, Event
);
561 @param[in, out] Task Pointer to task to be freed.
567 IN OUT ATA_BUS_ASYN_SUB_TASK
*Task
570 if (Task
->Packet
.Asb
!= NULL
) {
571 FreeAlignedBuffer (Task
->Packet
.Asb
, sizeof (EFI_ATA_STATUS_BLOCK
));
573 if (Task
->Packet
.Acb
!= NULL
) {
574 FreePool (Task
->Packet
.Acb
);
581 Terminate any in-flight non-blocking I/O requests by signaling an EFI_ABORTED
582 in the TransactionStatus member of the EFI_BLOCK_IO2_TOKEN for the non-blocking
583 I/O. After that it is safe to free any Token or Buffer data structures that
584 were allocated to initiate the non-blockingI/O requests that were in-flight for
587 @param[in] AtaDevice The ATA child device involved for the operation.
592 AtaTerminateNonBlockingTask (
593 IN ATA_DEVICE
*AtaDevice
596 BOOLEAN SubTaskEmpty
;
598 ATA_BUS_ASYN_TASK
*AtaTask
;
602 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
604 // Abort all executing tasks from now.
606 AtaDevice
->Abort
= TRUE
;
608 List
= &AtaDevice
->AtaTaskList
;
609 for (Entry
= GetFirstNode (List
); !IsNull (List
, Entry
);) {
610 AtaTask
= ATA_ASYN_TASK_FROM_ENTRY (Entry
);
611 AtaTask
->Token
->TransactionStatus
= EFI_ABORTED
;
612 gBS
->SignalEvent (AtaTask
->Token
->Event
);
614 Entry
= RemoveEntryList (Entry
);
617 gBS
->RestoreTPL (OldTpl
);
620 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
622 // Wait for executing subtasks done.
624 SubTaskEmpty
= IsListEmpty (&AtaDevice
->AtaSubTaskList
);
625 gBS
->RestoreTPL (OldTpl
);
626 } while (!SubTaskEmpty
);
629 // Aborting operation has been done. From now on, don't need to abort normal operation.
631 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
632 AtaDevice
->Abort
= FALSE
;
633 gBS
->RestoreTPL (OldTpl
);
637 Call back funtion when the event is signaled.
639 @param[in] Event The Event this notify function registered to.
640 @param[in] Context Pointer to the context data registered to the
646 AtaNonBlockingCallBack (
651 ATA_BUS_ASYN_SUB_TASK
*Task
;
652 ATA_BUS_ASYN_TASK
*AtaTask
;
653 ATA_DEVICE
*AtaDevice
;
657 Task
= (ATA_BUS_ASYN_SUB_TASK
*) Context
;
658 gBS
->CloseEvent (Event
);
660 AtaDevice
= Task
->AtaDevice
;
663 // Check the command status.
664 // If there is error during the sub task source allocation, the error status
665 // should be returned to the caller directly, so here the Task->Token may already
666 // be deleted by the caller and no need to update the status.
668 if ((!(*Task
->IsError
)) && ((Task
->Packet
.Asb
->AtaStatus
& 0x01) == 0x01)) {
669 Task
->Token
->TransactionStatus
= EFI_DEVICE_ERROR
;
672 if (AtaDevice
->Abort
) {
673 Task
->Token
->TransactionStatus
= EFI_ABORTED
;
678 "NON-BLOCKING EVENT FINISHED!- STATUS = %r\n",
679 Task
->Token
->TransactionStatus
683 // Reduce the SubEventCount, till it comes to zero.
685 (*Task
->UnsignalledEventCount
) --;
686 DEBUG ((EFI_D_BLKIO
, "UnsignalledEventCount = %d\n", *Task
->UnsignalledEventCount
));
689 // Remove the SubTask from the Task list.
691 RemoveEntryList (&Task
->TaskEntry
);
692 if ((*Task
->UnsignalledEventCount
) == 0) {
694 // All Sub tasks are done, then signal the upper layer event.
695 // Except there is error during the sub task source allocation.
697 if (!(*Task
->IsError
)) {
698 gBS
->SignalEvent (Task
->Token
->Event
);
699 DEBUG ((EFI_D_BLKIO
, "Signal the upper layer event!\n"));
702 FreePool (Task
->UnsignalledEventCount
);
703 FreePool (Task
->IsError
);
707 // Finish all subtasks and move to the next task in AtaTaskList.
709 if (!IsListEmpty (&AtaDevice
->AtaTaskList
)) {
710 Entry
= GetFirstNode (&AtaDevice
->AtaTaskList
);
711 AtaTask
= ATA_ASYN_TASK_FROM_ENTRY (Entry
);
712 DEBUG ((EFI_D_BLKIO
, "Start to embark a new Ata Task\n"));
713 DEBUG ((EFI_D_BLKIO
, "AtaTask->NumberOfBlocks = %x; AtaTask->Token=%x\n", AtaTask
->NumberOfBlocks
, AtaTask
->Token
));
714 Status
= AccessAtaDevice (
718 AtaTask
->NumberOfBlocks
,
722 if (EFI_ERROR (Status
)) {
723 AtaTask
->Token
->TransactionStatus
= Status
;
724 gBS
->SignalEvent (AtaTask
->Token
->Event
);
726 RemoveEntryList (Entry
);
733 "PACKET INFO: Write=%s, Length=%x, LowCylinder=%x, HighCylinder=%x, SectionNumber=%x\n",
734 Task
->Packet
.OutDataBuffer
!= NULL
? L
"YES" : L
"NO",
735 Task
->Packet
.OutDataBuffer
!= NULL
? Task
->Packet
.OutTransferLength
: Task
->Packet
.InTransferLength
,
736 Task
->Packet
.Acb
->AtaCylinderLow
,
737 Task
->Packet
.Acb
->AtaCylinderHigh
,
738 Task
->Packet
.Acb
->AtaSectorCount
742 // Free the buffer of SubTask.
744 FreeAtaSubTask (Task
);
748 Read or write a number of blocks from ATA device.
750 This function performs ATA pass through transactions to read/write data from/to
751 ATA device. It may separate the read/write request into several ATA pass through
754 @param[in, out] AtaDevice The ATA child device involved for the operation.
755 @param[in, out] Buffer The pointer to the current transaction buffer.
756 @param[in] StartLba The starting logical block address to be accessed.
757 @param[in] NumberOfBlocks The block number or sector count of the transfer.
758 @param[in] IsWrite Indicates whether it is a write operation.
759 @param[in, out] Token A pointer to the token associated with the transaction.
761 @retval EFI_SUCCESS The data transfer is complete successfully.
762 @return others Some error occurs when transferring data.
767 IN OUT ATA_DEVICE
*AtaDevice
,
768 IN OUT UINT8
*Buffer
,
770 IN UINTN NumberOfBlocks
,
772 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
776 UINTN MaxTransferBlockNumber
;
777 UINTN TransferBlockNumber
;
779 ATA_BUS_ASYN_SUB_TASK
*SubTask
;
782 ATA_BUS_ASYN_TASK
*AtaTask
;
789 Status
= EFI_SUCCESS
;
798 // Ensure AtaDevice->Lba48Bit is a valid boolean value
800 ASSERT ((UINTN
) AtaDevice
->Lba48Bit
< 2);
801 MaxTransferBlockNumber
= mMaxTransferBlockNumber
[AtaDevice
->Lba48Bit
];
802 BlockSize
= AtaDevice
->BlockMedia
.BlockSize
;
805 // Initial the return status and shared account for Non Blocking.
807 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
808 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
810 if (!IsListEmpty (&AtaDevice
->AtaSubTaskList
)) {
811 AtaTask
= AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK
));
812 if (AtaTask
== NULL
) {
813 gBS
->RestoreTPL (OldTpl
);
814 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
;
824 InsertTailList (&AtaDevice
->AtaTaskList
, &AtaTask
->TaskEntry
);
825 gBS
->RestoreTPL (OldTpl
);
828 gBS
->RestoreTPL (OldTpl
);
830 Token
->TransactionStatus
= EFI_SUCCESS
;
831 EventCount
= AllocateZeroPool (sizeof (UINTN
));
832 if (EventCount
== NULL
) {
833 return EFI_OUT_OF_RESOURCES
;
836 IsError
= AllocateZeroPool (sizeof (BOOLEAN
));
837 if (IsError
== NULL
) {
838 FreePool (EventCount
);
839 return EFI_OUT_OF_RESOURCES
;
841 DEBUG ((EFI_D_BLKIO
, "Allocation IsError Addr=%x\n", IsError
));
843 TempCount
= (NumberOfBlocks
+ MaxTransferBlockNumber
- 1) / MaxTransferBlockNumber
;
844 *EventCount
= TempCount
;
845 DEBUG ((EFI_D_BLKIO
, "AccessAtaDevice, NumberOfBlocks=%x\n", NumberOfBlocks
));
846 DEBUG ((EFI_D_BLKIO
, "AccessAtaDevice, MaxTransferBlockNumber=%x\n", MaxTransferBlockNumber
));
847 DEBUG ((EFI_D_BLKIO
, "AccessAtaDevice, EventCount=%x\n", TempCount
));
849 while (!IsListEmpty (&AtaDevice
->AtaTaskList
) || !IsListEmpty (&AtaDevice
->AtaSubTaskList
)) {
853 MicroSecondDelay (100);
858 if (NumberOfBlocks
> MaxTransferBlockNumber
) {
859 TransferBlockNumber
= MaxTransferBlockNumber
;
860 NumberOfBlocks
-= MaxTransferBlockNumber
;
862 TransferBlockNumber
= NumberOfBlocks
;
867 // Create sub event for the sub ata task. Non-blocking mode.
869 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
873 SubTask
= AllocateZeroPool (sizeof (ATA_BUS_ASYN_SUB_TASK
));
874 if (SubTask
== NULL
) {
875 Status
= EFI_OUT_OF_RESOURCES
;
879 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
880 SubTask
->UnsignalledEventCount
= EventCount
;
881 SubTask
->Signature
= ATA_SUB_TASK_SIGNATURE
;
882 SubTask
->AtaDevice
= AtaDevice
;
883 SubTask
->Token
= Token
;
884 SubTask
->IsError
= IsError
;
885 InsertTailList (&AtaDevice
->AtaSubTaskList
, &SubTask
->TaskEntry
);
886 gBS
->RestoreTPL (OldTpl
);
888 Status
= gBS
->CreateEvent (
891 AtaNonBlockingCallBack
,
896 // If resource allocation fail, the un-signalled event count should equal to
897 // the original one minus the unassigned subtasks number.
899 if (EFI_ERROR (Status
)) {
900 Status
= EFI_OUT_OF_RESOURCES
;
904 Status
= TransferAtaDevice (AtaDevice
, &SubTask
->Packet
, Buffer
, StartLba
, (UINT32
) TransferBlockNumber
, IsWrite
, SubEvent
);
909 DEBUG ((EFI_D_BLKIO
, "Blocking AccessAtaDevice, TransferBlockNumber=%x; StartLba = %x\n", TransferBlockNumber
, StartLba
));
910 Status
= TransferAtaDevice (AtaDevice
, NULL
, Buffer
, StartLba
, (UINT32
) TransferBlockNumber
, IsWrite
, NULL
);
913 if (EFI_ERROR (Status
)) {
918 StartLba
+= TransferBlockNumber
;
919 Buffer
+= TransferBlockNumber
* BlockSize
;
920 } while (NumberOfBlocks
> 0);
923 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
925 // Release resource at non-blocking mode.
927 if (EFI_ERROR (Status
)) {
928 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
929 Token
->TransactionStatus
= Status
;
930 *EventCount
= (*EventCount
) - (TempCount
- Index
);
933 if (*EventCount
== 0) {
934 FreePool (EventCount
);
938 if (SubTask
!= NULL
) {
939 RemoveEntryList (&SubTask
->TaskEntry
);
940 FreeAtaSubTask (SubTask
);
943 if (SubEvent
!= NULL
) {
944 gBS
->CloseEvent (SubEvent
);
946 gBS
->RestoreTPL (OldTpl
);
954 Trust transfer data from/to ATA device.
956 This function performs one ATA pass through transaction to do a trust transfer from/to
957 ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
958 interface of ATA pass through.
960 @param AtaDevice The ATA child device involved for the operation.
961 @param Buffer The pointer to the current transaction buffer.
962 @param SecurityProtocolId The value of the "Security Protocol" parameter of
963 the security protocol command to be sent.
964 @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
965 of the security protocol command to be sent.
966 @param TransferLength The block number or sector count of the transfer.
967 @param IsTrustSend Indicates whether it is a trust send operation or not.
968 @param Timeout The timeout, in 100ns units, to use for the execution
969 of the security protocol command. A Timeout value of 0
970 means that this function will wait indefinitely for the
971 security protocol command to execute. If Timeout is greater
972 than zero, then this function will return EFI_TIMEOUT
973 if the time required to execute the receive data command
974 is greater than Timeout.
975 @param TransferLengthOut A pointer to a buffer to store the size in bytes of the data
976 written to the buffer. Ignore it when IsTrustSend is TRUE.
978 @retval EFI_SUCCESS The data transfer is complete successfully.
979 @return others Some error occurs when transferring data.
984 TrustTransferAtaDevice (
985 IN OUT ATA_DEVICE
*AtaDevice
,
987 IN UINT8 SecurityProtocolId
,
988 IN UINT16 SecurityProtocolSpecificData
,
989 IN UINTN TransferLength
,
990 IN BOOLEAN IsTrustSend
,
992 OUT UINTN
*TransferLengthOut
995 EFI_ATA_COMMAND_BLOCK
*Acb
;
996 EFI_ATA_PASS_THRU_COMMAND_PACKET
*Packet
;
999 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
1002 // Ensure AtaDevice->UdmaValid and IsTrustSend are valid boolean values
1004 ASSERT ((UINTN
) AtaDevice
->UdmaValid
< 2);
1005 ASSERT ((UINTN
) IsTrustSend
< 2);
1007 // Prepare for ATA command block.
1009 Acb
= ZeroMem (&AtaDevice
->Acb
, sizeof (EFI_ATA_COMMAND_BLOCK
));
1010 if (TransferLength
== 0) {
1011 Acb
->AtaCommand
= ATA_CMD_TRUST_NON_DATA
;
1013 Acb
->AtaCommand
= mAtaTrustCommands
[AtaDevice
->UdmaValid
][IsTrustSend
];
1015 Acb
->AtaFeatures
= SecurityProtocolId
;
1016 Acb
->AtaSectorCount
= (UINT8
) (TransferLength
/ 512);
1017 Acb
->AtaSectorNumber
= (UINT8
) ((TransferLength
/ 512) >> 8);
1019 // NOTE: ATA Spec has no explicitly definition for Security Protocol Specific layout.
1020 // Here use big endian for Cylinder register.
1022 Acb
->AtaCylinderHigh
= (UINT8
) SecurityProtocolSpecificData
;
1023 Acb
->AtaCylinderLow
= (UINT8
) (SecurityProtocolSpecificData
>> 8);
1024 Acb
->AtaDeviceHead
= (UINT8
) (BIT7
| BIT6
| BIT5
| (AtaDevice
->PortMultiplierPort
== 0xFFFF ? 0 : (AtaDevice
->PortMultiplierPort
<< 4)));
1027 // Prepare for ATA pass through packet.
1029 Packet
= ZeroMem (&AtaDevice
->Packet
, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET
));
1030 if (TransferLength
== 0) {
1031 Packet
->InTransferLength
= 0;
1032 Packet
->OutTransferLength
= 0;
1033 Packet
->Protocol
= EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA
;
1034 } else if (IsTrustSend
) {
1036 // Check the alignment of the incoming buffer prior to invoking underlying ATA PassThru
1038 AtaPassThru
= AtaDevice
->AtaBusDriverData
->AtaPassThru
;
1039 if ((AtaPassThru
->Mode
->IoAlign
> 1) && !IS_ALIGNED (Buffer
, AtaPassThru
->Mode
->IoAlign
)) {
1040 NewBuffer
= AllocateAlignedBuffer (AtaDevice
, TransferLength
);
1041 if (NewBuffer
== NULL
) {
1042 return EFI_OUT_OF_RESOURCES
;
1045 CopyMem (NewBuffer
, Buffer
, TransferLength
);
1049 Packet
->OutDataBuffer
= Buffer
;
1050 Packet
->OutTransferLength
= (UINT32
) TransferLength
;
1051 Packet
->Protocol
= mAtaPassThruCmdProtocols
[AtaDevice
->UdmaValid
][IsTrustSend
];
1053 Packet
->InDataBuffer
= Buffer
;
1054 Packet
->InTransferLength
= (UINT32
) TransferLength
;
1055 Packet
->Protocol
= mAtaPassThruCmdProtocols
[AtaDevice
->UdmaValid
][IsTrustSend
];
1057 Packet
->Length
= EFI_ATA_PASS_THRU_LENGTH_BYTES
;
1058 Packet
->Timeout
= Timeout
;
1060 Status
= AtaDevicePassThru (AtaDevice
, NULL
, NULL
);
1061 if (TransferLengthOut
!= NULL
) {
1062 if (! IsTrustSend
) {
1063 *TransferLengthOut
= Packet
->InTransferLength
;