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 - 2013, Intel Corporation. All rights reserved.<BR>
14 This program and the accompanying materials
15 are licensed and made available under the terms and conditions of the BSD License
16 which accompanies this distribution. The full text of the license may be found at
17 http://opensource.org/licenses/bsd-license.php
19 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
20 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
27 #define ATA_CMD_TRUST_NON_DATA 0x5B
28 #define ATA_CMD_TRUST_RECEIVE 0x5C
29 #define ATA_CMD_TRUST_RECEIVE_DMA 0x5D
30 #define ATA_CMD_TRUST_SEND 0x5E
31 #define ATA_CMD_TRUST_SEND_DMA 0x5F
34 // Look up table (UdmaValid, IsWrite) for EFI_ATA_PASS_THRU_CMD_PROTOCOL
36 EFI_ATA_PASS_THRU_CMD_PROTOCOL mAtaPassThruCmdProtocols
[][2] = {
38 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN
,
39 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT
42 EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN
,
43 EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT
,
48 // Look up table (UdmaValid, Lba48Bit, IsIsWrite) for ATA_CMD
50 UINT8 mAtaCommands
[][2][2] = {
53 ATA_CMD_READ_SECTORS
, // 28-bit LBA; PIO read
54 ATA_CMD_WRITE_SECTORS
// 28-bit LBA; PIO write
57 ATA_CMD_READ_SECTORS_EXT
, // 48-bit LBA; PIO read
58 ATA_CMD_WRITE_SECTORS_EXT
// 48-bit LBA; PIO write
63 ATA_CMD_READ_DMA
, // 28-bit LBA; DMA read
64 ATA_CMD_WRITE_DMA
// 28-bit LBA; DMA write
67 ATA_CMD_READ_DMA_EXT
, // 48-bit LBA; DMA read
68 ATA_CMD_WRITE_DMA_EXT
// 48-bit LBA; DMA write
74 // Look up table (UdmaValid, IsTrustSend) for ATA_CMD
76 UINT8 mAtaTrustCommands
[2][2] = {
78 ATA_CMD_TRUST_RECEIVE
, // PIO read
79 ATA_CMD_TRUST_SEND
// PIO write
82 ATA_CMD_TRUST_RECEIVE_DMA
, // DMA read
83 ATA_CMD_TRUST_SEND_DMA
// DMA write
89 // Look up table (Lba48Bit) for maximum transfer block number
91 UINTN mMaxTransferBlockNumber
[] = {
92 MAX_28BIT_TRANSFER_BLOCK_NUM
,
93 MAX_48BIT_TRANSFER_BLOCK_NUM
98 Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
100 This function wraps the PassThru() invocation for ATA pass through function
101 for an ATA device. It assembles the ATA pass through command packet for ATA
104 @param[in, out] AtaDevice The ATA child device involved for the operation.
105 @param[in, out] TaskPacket Pointer to a Pass Thru Command Packet. Optional,
106 if it is NULL, blocking mode, and use the packet
107 in AtaDevice. If it is not NULL, non blocking mode,
108 and pass down this Packet.
109 @param[in, out] Event If Event is NULL, then blocking I/O is performed.
110 If Event is not NULL and non-blocking I/O is
111 supported,then non-blocking I/O is performed,
112 and Event will be signaled when the write
113 request is completed.
115 @return The return status from EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
120 IN OUT ATA_DEVICE
*AtaDevice
,
121 IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET
*TaskPacket
, OPTIONAL
122 IN OUT EFI_EVENT Event OPTIONAL
126 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
127 EFI_ATA_PASS_THRU_COMMAND_PACKET
*Packet
;
130 // Assemble packet. If it is non blocking mode, the Ata driver should keep each
131 // subtask and clean them when the event is signaled.
133 if (TaskPacket
!= NULL
) {
135 Packet
->Asb
= AllocateAlignedBuffer (AtaDevice
, sizeof (EFI_ATA_STATUS_BLOCK
));
136 if (Packet
->Asb
== NULL
) {
137 return EFI_OUT_OF_RESOURCES
;
140 CopyMem (Packet
->Asb
, AtaDevice
->Asb
, sizeof (EFI_ATA_STATUS_BLOCK
));
141 Packet
->Acb
= AllocateCopyPool (sizeof (EFI_ATA_COMMAND_BLOCK
), &AtaDevice
->Acb
);
143 Packet
= &AtaDevice
->Packet
;
144 Packet
->Asb
= AtaDevice
->Asb
;
145 Packet
->Acb
= &AtaDevice
->Acb
;
148 AtaPassThru
= AtaDevice
->AtaBusDriverData
->AtaPassThru
;
150 Status
= AtaPassThru
->PassThru (
153 AtaDevice
->PortMultiplierPort
,
158 // Ensure ATA pass through caller and callee have the same
159 // interpretation of ATA pass through protocol.
161 ASSERT (Status
!= EFI_INVALID_PARAMETER
);
162 ASSERT (Status
!= EFI_BAD_BUFFER_SIZE
);
169 Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.ResetDevice().
171 This function wraps the ResetDevice() invocation for ATA pass through function
174 @param AtaDevice The ATA child device involved for the operation.
176 @return The return status from EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
181 IN ATA_DEVICE
*AtaDevice
184 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
186 AtaPassThru
= AtaDevice
->AtaBusDriverData
->AtaPassThru
;
189 // Report Status Code to indicate reset happens
191 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
193 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_PC_RESET
),
194 AtaDevice
->AtaBusDriverData
->ParentDevicePath
197 return AtaPassThru
->ResetDevice (
200 AtaDevice
->PortMultiplierPort
206 Prints ATA model name to ATA device structure.
208 This function converts ATA device model name from ATA identify data
209 to a string in ATA device structure. It needs to change the character
210 order in the original model name string.
212 @param AtaDevice The ATA child device involved for the operation.
217 IN OUT ATA_DEVICE
*AtaDevice
224 Source
= AtaDevice
->IdentifyData
->ModelName
;
225 Destination
= AtaDevice
->ModelName
;
228 // Swap the byte order in the original module name.
230 for (Index
= 0; Index
< MAX_MODEL_NAME_LEN
; Index
+= 2) {
231 Destination
[Index
] = Source
[Index
+ 1];
232 Destination
[Index
+ 1] = Source
[Index
];
234 AtaDevice
->ModelName
[MAX_MODEL_NAME_LEN
] = L
'\0';
239 Gets ATA device Capacity according to ATA 6.
241 This function returns the capacity of the ATA device if it follows
242 ATA 6 to support 48 bit addressing.
244 @param AtaDevice The ATA child device involved for the operation.
246 @return The capacity of the ATA device or 0 if the device does not support
247 48-bit addressing defined in ATA 6.
252 IN ATA_DEVICE
*AtaDevice
258 ATA_IDENTIFY_DATA
*IdentifyData
;
260 IdentifyData
= AtaDevice
->IdentifyData
;
261 if ((IdentifyData
->command_set_supported_83
& BIT10
) == 0) {
263 // The device doesn't support 48 bit addressing
269 // 48 bit address feature set is supported, get maximum capacity
272 for (Index
= 0; Index
< 4; Index
++) {
274 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
276 TmpLba
= IdentifyData
->maximum_lba_for_48bit_addressing
[Index
];
277 Capacity
|= LShiftU64 (TmpLba
, 16 * Index
);
285 Identifies ATA device via the Identify data.
287 This function identifies the ATA device and initializes the Media information in
288 Block IO protocol interface.
290 @param AtaDevice The ATA child device involved for the operation.
292 @retval EFI_UNSUPPORTED The device is not a valid ATA device (hard disk).
293 @retval EFI_SUCCESS The device is successfully identified and Media information
294 is correctly initialized.
299 IN OUT ATA_DEVICE
*AtaDevice
302 ATA_IDENTIFY_DATA
*IdentifyData
;
303 EFI_BLOCK_IO_MEDIA
*BlockMedia
;
305 UINT16 PhyLogicSectorSupport
;
308 IdentifyData
= AtaDevice
->IdentifyData
;
310 if ((IdentifyData
->config
& BIT15
) != 0) {
312 // This is not an hard disk
314 return EFI_UNSUPPORTED
;
317 DEBUG ((EFI_D_INFO
, "AtaBus - Identify Device: Port %x PortMultiplierPort %x\n", AtaDevice
->Port
, AtaDevice
->PortMultiplierPort
));
320 // Check whether the WORD 88 (supported UltraDMA by drive) is valid
322 if ((IdentifyData
->field_validity
& BIT2
) != 0) {
323 UdmaMode
= IdentifyData
->ultra_dma_mode
;
324 if ((UdmaMode
& (BIT0
| BIT1
| BIT2
| BIT3
| BIT4
| BIT5
| BIT6
)) != 0) {
326 // If BIT0~BIT6 is selected, then UDMA is supported
328 AtaDevice
->UdmaValid
= TRUE
;
332 Capacity
= GetAtapi6Capacity (AtaDevice
);
333 if (Capacity
> MAX_28BIT_ADDRESSING_CAPACITY
) {
335 // Capacity exceeds 120GB. 48-bit addressing is really needed
337 AtaDevice
->Lba48Bit
= TRUE
;
340 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
342 Capacity
= ((UINT32
)IdentifyData
->user_addressable_sectors_hi
<< 16) | IdentifyData
->user_addressable_sectors_lo
;
343 AtaDevice
->Lba48Bit
= FALSE
;
347 // Block Media Information:
349 BlockMedia
= &AtaDevice
->BlockMedia
;
350 BlockMedia
->LastBlock
= Capacity
- 1;
351 BlockMedia
->IoAlign
= AtaDevice
->AtaBusDriverData
->AtaPassThru
->Mode
->IoAlign
;
353 // Check whether Long Physical Sector Feature is supported
355 PhyLogicSectorSupport
= IdentifyData
->phy_logic_sector_support
;
356 if ((PhyLogicSectorSupport
& (BIT14
| BIT15
)) == BIT14
) {
358 // Check whether one physical block contains multiple physical blocks
360 if ((PhyLogicSectorSupport
& BIT13
) != 0) {
361 BlockMedia
->LogicalBlocksPerPhysicalBlock
= (UINT32
) (1 << (PhyLogicSectorSupport
& 0x000f));
363 // Check lowest alignment of logical blocks within physical block
365 if ((IdentifyData
->alignment_logic_in_phy_blocks
& (BIT14
| BIT15
)) == BIT14
) {
366 BlockMedia
->LowestAlignedLba
= (EFI_LBA
) ((BlockMedia
->LogicalBlocksPerPhysicalBlock
- ((UINT32
)IdentifyData
->alignment_logic_in_phy_blocks
& 0x3fff)) %
367 BlockMedia
->LogicalBlocksPerPhysicalBlock
);
371 // Check logical block size
373 if ((PhyLogicSectorSupport
& BIT12
) != 0) {
374 BlockMedia
->BlockSize
= (UINT32
) (((IdentifyData
->logic_sector_size_hi
<< 16) | IdentifyData
->logic_sector_size_lo
) * sizeof (UINT16
));
376 AtaDevice
->BlockIo
.Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION2
;
379 // Get ATA model name from identify data structure.
381 PrintAtaModelName (AtaDevice
);
388 Discovers whether it is a valid ATA device.
390 This function issues ATA_CMD_IDENTIFY_DRIVE command to the ATA device to identify it.
391 If the command is executed successfully, it then identifies it and initializes
392 the Media information in Block IO protocol interface.
394 @param AtaDevice The ATA child device involved for the operation.
396 @retval EFI_SUCCESS The device is successfully identified and Media information
397 is correctly initialized.
398 @return others Some error occurs when discovering the ATA device.
403 IN OUT ATA_DEVICE
*AtaDevice
407 EFI_ATA_COMMAND_BLOCK
*Acb
;
408 EFI_ATA_PASS_THRU_COMMAND_PACKET
*Packet
;
412 // Prepare for ATA command block.
414 Acb
= ZeroMem (&AtaDevice
->Acb
, sizeof (EFI_ATA_COMMAND_BLOCK
));
415 Acb
->AtaCommand
= ATA_CMD_IDENTIFY_DRIVE
;
416 Acb
->AtaDeviceHead
= (UINT8
) (BIT7
| BIT6
| BIT5
| (AtaDevice
->PortMultiplierPort
<< 4));
419 // Prepare for ATA pass through packet.
421 Packet
= ZeroMem (&AtaDevice
->Packet
, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET
));
422 Packet
->InDataBuffer
= AtaDevice
->IdentifyData
;
423 Packet
->InTransferLength
= sizeof (ATA_IDENTIFY_DATA
);
424 Packet
->Protocol
= EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN
;
425 Packet
->Length
= EFI_ATA_PASS_THRU_LENGTH_BYTES
| EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT
;
426 Packet
->Timeout
= ATA_TIMEOUT
;
428 Retry
= MAX_RETRY_TIMES
;
430 Status
= AtaDevicePassThru (AtaDevice
, NULL
, NULL
);
431 if (!EFI_ERROR (Status
)) {
433 // The command is issued successfully
435 Status
= IdentifyAtaDevice (AtaDevice
);
438 } while (Retry
-- > 0);
444 Transfer data from ATA device.
446 This function performs one ATA pass through transaction to transfer data from/to
447 ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
448 interface of ATA pass through.
450 @param[in, out] AtaDevice The ATA child device involved for the operation.
451 @param[in, out] TaskPacket Pointer to a Pass Thru Command Packet. Optional,
452 if it is NULL, blocking mode, and use the packet
453 in AtaDevice. If it is not NULL, non blocking mode,
454 and pass down this Packet.
455 @param[in, out] Buffer The pointer to the current transaction buffer.
456 @param[in] StartLba The starting logical block address to be accessed.
457 @param[in] TransferLength The block number or sector count of the transfer.
458 @param[in] IsWrite Indicates whether it is a write operation.
459 @param[in] Event If Event is NULL, then blocking I/O is performed.
460 If Event is not NULL and non-blocking I/O is
461 supported,then non-blocking I/O is performed,
462 and Event will be signaled when the write
463 request is completed.
465 @retval EFI_SUCCESS The data transfer is complete successfully.
466 @return others Some error occurs when transferring data.
471 IN OUT ATA_DEVICE
*AtaDevice
,
472 IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET
*TaskPacket
, OPTIONAL
475 IN UINT32 TransferLength
,
477 IN EFI_EVENT Event OPTIONAL
480 EFI_ATA_COMMAND_BLOCK
*Acb
;
481 EFI_ATA_PASS_THRU_COMMAND_PACKET
*Packet
;
484 // Ensure AtaDevice->UdmaValid, AtaDevice->Lba48Bit and IsWrite are valid boolean values
486 ASSERT ((UINTN
) AtaDevice
->UdmaValid
< 2);
487 ASSERT ((UINTN
) AtaDevice
->Lba48Bit
< 2);
488 ASSERT ((UINTN
) IsWrite
< 2);
490 // Prepare for ATA command block.
492 Acb
= ZeroMem (&AtaDevice
->Acb
, sizeof (EFI_ATA_COMMAND_BLOCK
));
493 Acb
->AtaCommand
= mAtaCommands
[AtaDevice
->UdmaValid
][AtaDevice
->Lba48Bit
][IsWrite
];
494 Acb
->AtaSectorNumber
= (UINT8
) StartLba
;
495 Acb
->AtaCylinderLow
= (UINT8
) RShiftU64 (StartLba
, 8);
496 Acb
->AtaCylinderHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
497 Acb
->AtaDeviceHead
= (UINT8
) (BIT7
| BIT6
| BIT5
| (AtaDevice
->PortMultiplierPort
<< 4));
498 Acb
->AtaSectorCount
= (UINT8
) TransferLength
;
499 if (AtaDevice
->Lba48Bit
) {
500 Acb
->AtaSectorNumberExp
= (UINT8
) RShiftU64 (StartLba
, 24);
501 Acb
->AtaCylinderLowExp
= (UINT8
) RShiftU64 (StartLba
, 32);
502 Acb
->AtaCylinderHighExp
= (UINT8
) RShiftU64 (StartLba
, 40);
503 Acb
->AtaSectorCountExp
= (UINT8
) (TransferLength
>> 8);
505 Acb
->AtaDeviceHead
= (UINT8
) (Acb
->AtaDeviceHead
| RShiftU64 (StartLba
, 24));
509 // Prepare for ATA pass through packet.
511 if (TaskPacket
!= NULL
) {
512 Packet
= ZeroMem (TaskPacket
, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET
));
514 Packet
= ZeroMem (&AtaDevice
->Packet
, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET
));
518 Packet
->OutDataBuffer
= Buffer
;
519 Packet
->OutTransferLength
= TransferLength
;
521 Packet
->InDataBuffer
= Buffer
;
522 Packet
->InTransferLength
= TransferLength
;
525 Packet
->Protocol
= mAtaPassThruCmdProtocols
[AtaDevice
->UdmaValid
][IsWrite
];
526 Packet
->Length
= EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT
;
528 // |------------------------|-----------------|------------------------|-----------------|
529 // | ATA PIO Transfer Mode | Transfer Rate | ATA DMA Transfer Mode | Transfer Rate |
530 // |------------------------|-----------------|------------------------|-----------------|
531 // | PIO Mode 0 | 3.3Mbytes/sec | Single-word DMA Mode 0 | 2.1Mbytes/sec |
532 // |------------------------|-----------------|------------------------|-----------------|
533 // | PIO Mode 1 | 5.2Mbytes/sec | Single-word DMA Mode 1 | 4.2Mbytes/sec |
534 // |------------------------|-----------------|------------------------|-----------------|
535 // | PIO Mode 2 | 8.3Mbytes/sec | Single-word DMA Mode 2 | 8.4Mbytes/sec |
536 // |------------------------|-----------------|------------------------|-----------------|
537 // | PIO Mode 3 | 11.1Mbytes/sec | Multi-word DMA Mode 0 | 4.2Mbytes/sec |
538 // |------------------------|-----------------|------------------------|-----------------|
539 // | PIO Mode 4 | 16.6Mbytes/sec | Multi-word DMA Mode 1 | 13.3Mbytes/sec |
540 // |------------------------|-----------------|------------------------|-----------------|
542 // As AtaBus is used to manage ATA devices, we have to use the lowest transfer rate to
543 // calculate the possible maximum timeout value for each read/write operation.
544 // The timout value is rounded up to nearest integar and here an additional 30s is added
545 // to follow ATA spec in which it mentioned that the device may take up to 30s to respond
546 // commands in the Standby/Idle mode.
548 if (AtaDevice
->UdmaValid
) {
550 // Calculate the maximum timeout value for DMA read/write operation.
552 Packet
->Timeout
= EFI_TIMER_PERIOD_SECONDS (DivU64x32 (MultU64x32 (TransferLength
, AtaDevice
->BlockMedia
.BlockSize
), 2100000) + 31);
555 // Calculate the maximum timeout value for PIO read/write operation
557 Packet
->Timeout
= EFI_TIMER_PERIOD_SECONDS (DivU64x32 (MultU64x32 (TransferLength
, AtaDevice
->BlockMedia
.BlockSize
), 3300000) + 31);
560 return AtaDevicePassThru (AtaDevice
, TaskPacket
, Event
);
566 @param[in, out] Task Pointer to task to be freed.
572 IN OUT ATA_BUS_ASYN_SUB_TASK
*Task
575 if (Task
->Packet
.Asb
!= NULL
) {
576 FreeAlignedBuffer (Task
->Packet
.Asb
, sizeof (EFI_ATA_STATUS_BLOCK
));
578 if (Task
->Packet
.Acb
!= NULL
) {
579 FreePool (Task
->Packet
.Acb
);
586 Call back funtion when the event is signaled.
588 @param[in] Event The Event this notify function registered to.
589 @param[in] Context Pointer to the context data registered to the
595 AtaNonBlockingCallBack (
600 ATA_BUS_ASYN_SUB_TASK
*Task
;
601 ATA_BUS_ASYN_TASK
*AtaTask
;
602 ATA_DEVICE
*AtaDevice
;
606 Task
= (ATA_BUS_ASYN_SUB_TASK
*) Context
;
607 gBS
->CloseEvent (Event
);
609 AtaDevice
= Task
->AtaDevice
;
612 // Check the command status.
613 // If there is error during the sub task source allocation, the error status
614 // should be returned to the caller directly, so here the Task->Token may already
615 // be deleted by the caller and no need to update the status.
617 if ((!(*Task
->IsError
)) && ((Task
->Packet
.Asb
->AtaStatus
& 0x01) == 0x01)) {
618 Task
->Token
->TransactionStatus
= EFI_DEVICE_ERROR
;
622 "NON-BLOCKING EVENT FINISHED!- STATUS = %r\n",
623 Task
->Token
->TransactionStatus
627 // Reduce the SubEventCount, till it comes to zero.
629 (*Task
->UnsignalledEventCount
) --;
630 DEBUG ((EFI_D_BLKIO
, "UnsignalledEventCount = %d\n", *Task
->UnsignalledEventCount
));
633 // Remove the SubTask from the Task list.
635 RemoveEntryList (&Task
->TaskEntry
);
636 if ((*Task
->UnsignalledEventCount
) == 0) {
638 // All Sub tasks are done, then signal the upper layer event.
639 // Except there is error during the sub task source allocation.
641 if (!(*Task
->IsError
)) {
642 gBS
->SignalEvent (Task
->Token
->Event
);
643 DEBUG ((EFI_D_BLKIO
, "Signal the upper layer event!\n"));
646 FreePool (Task
->UnsignalledEventCount
);
647 FreePool (Task
->IsError
);
651 // Finish all subtasks and move to the next task in AtaTaskList.
653 if (!IsListEmpty (&AtaDevice
->AtaTaskList
)) {
654 Entry
= GetFirstNode (&AtaDevice
->AtaTaskList
);
655 AtaTask
= ATA_AYNS_TASK_FROM_ENTRY (Entry
);
656 DEBUG ((EFI_D_BLKIO
, "Start to embark a new Ata Task\n"));
657 DEBUG ((EFI_D_BLKIO
, "AtaTask->NumberOfBlocks = %x; AtaTask->Token=%x\n", AtaTask
->NumberOfBlocks
, AtaTask
->Token
));
658 Status
= AccessAtaDevice (
662 AtaTask
->NumberOfBlocks
,
666 if (EFI_ERROR (Status
)) {
667 AtaTask
->Token
->TransactionStatus
= Status
;
668 gBS
->SignalEvent (AtaTask
->Token
->Event
);
670 RemoveEntryList (Entry
);
677 "PACKET INFO: Write=%s, Length=%x, LowCylinder=%x, HighCylinder=%x, SectionNumber=%x\n",
678 Task
->Packet
.OutDataBuffer
!= NULL
? L
"YES" : L
"NO",
679 Task
->Packet
.OutDataBuffer
!= NULL
? Task
->Packet
.OutTransferLength
: Task
->Packet
.InTransferLength
,
680 Task
->Packet
.Acb
->AtaCylinderLow
,
681 Task
->Packet
.Acb
->AtaCylinderHigh
,
682 Task
->Packet
.Acb
->AtaSectorCount
686 // Free the buffer of SubTask.
688 FreeAtaSubTask (Task
);
692 Read or write a number of blocks from ATA device.
694 This function performs ATA pass through transactions to read/write data from/to
695 ATA device. It may separate the read/write request into several ATA pass through
698 @param[in, out] AtaDevice The ATA child device involved for the operation.
699 @param[in, out] Buffer The pointer to the current transaction buffer.
700 @param[in] StartLba The starting logical block address to be accessed.
701 @param[in] NumberOfBlocks The block number or sector count of the transfer.
702 @param[in] IsWrite Indicates whether it is a write operation.
703 @param[in, out] Token A pointer to the token associated with the transaction.
705 @retval EFI_SUCCESS The data transfer is complete successfully.
706 @return others Some error occurs when transferring data.
711 IN OUT ATA_DEVICE
*AtaDevice
,
712 IN OUT UINT8
*Buffer
,
714 IN UINTN NumberOfBlocks
,
716 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
720 UINTN MaxTransferBlockNumber
;
721 UINTN TransferBlockNumber
;
723 ATA_BUS_ASYN_SUB_TASK
*SubTask
;
726 ATA_BUS_ASYN_TASK
*AtaTask
;
733 Status
= EFI_SUCCESS
;
742 // Ensure AtaDevice->Lba48Bit is a valid boolean value
744 ASSERT ((UINTN
) AtaDevice
->Lba48Bit
< 2);
745 MaxTransferBlockNumber
= mMaxTransferBlockNumber
[AtaDevice
->Lba48Bit
];
746 BlockSize
= AtaDevice
->BlockMedia
.BlockSize
;
749 // Initial the return status and shared account for Non Blocking.
751 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
752 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
753 if (!IsListEmpty (&AtaDevice
->AtaSubTaskList
)) {
754 AtaTask
= AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK
));
755 if (AtaTask
== NULL
) {
756 gBS
->RestoreTPL (OldTpl
);
757 return EFI_OUT_OF_RESOURCES
;
759 AtaTask
->AtaDevice
= AtaDevice
;
760 AtaTask
->Buffer
= Buffer
;
761 AtaTask
->IsWrite
= IsWrite
;
762 AtaTask
->NumberOfBlocks
= NumberOfBlocks
;
763 AtaTask
->Signature
= ATA_TASK_SIGNATURE
;
764 AtaTask
->StartLba
= StartLba
;
765 AtaTask
->Token
= Token
;
767 InsertTailList (&AtaDevice
->AtaTaskList
, &AtaTask
->TaskEntry
);
768 gBS
->RestoreTPL (OldTpl
);
771 gBS
->RestoreTPL (OldTpl
);
773 Token
->TransactionStatus
= EFI_SUCCESS
;
774 EventCount
= AllocateZeroPool (sizeof (UINTN
));
775 if (EventCount
== NULL
) {
776 return EFI_OUT_OF_RESOURCES
;
779 IsError
= AllocateZeroPool (sizeof (BOOLEAN
));
780 if (IsError
== NULL
) {
781 FreePool (EventCount
);
782 return EFI_OUT_OF_RESOURCES
;
784 DEBUG ((EFI_D_BLKIO
, "Allocation IsError Addr=%x\n", IsError
));
786 TempCount
= (NumberOfBlocks
+ MaxTransferBlockNumber
- 1) / MaxTransferBlockNumber
;
787 *EventCount
= TempCount
;
788 DEBUG ((EFI_D_BLKIO
, "AccessAtaDevice, NumberOfBlocks=%x\n", NumberOfBlocks
));
789 DEBUG ((EFI_D_BLKIO
, "AccessAtaDevice, MaxTransferBlockNumber=%x\n", MaxTransferBlockNumber
));
790 DEBUG ((EFI_D_BLKIO
, "AccessAtaDevice, EventCount=%x\n", TempCount
));
792 while (!IsListEmpty (&AtaDevice
->AtaTaskList
) || !IsListEmpty (&AtaDevice
->AtaSubTaskList
)) {
796 MicroSecondDelay (100);
801 if (NumberOfBlocks
> MaxTransferBlockNumber
) {
802 TransferBlockNumber
= MaxTransferBlockNumber
;
803 NumberOfBlocks
-= MaxTransferBlockNumber
;
805 TransferBlockNumber
= NumberOfBlocks
;
810 // Create sub event for the sub ata task. Non-blocking mode.
812 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
816 SubTask
= AllocateZeroPool (sizeof (ATA_BUS_ASYN_SUB_TASK
));
817 if (SubTask
== NULL
) {
818 Status
= EFI_OUT_OF_RESOURCES
;
822 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
823 SubTask
->UnsignalledEventCount
= EventCount
;
824 SubTask
->Signature
= ATA_SUB_TASK_SIGNATURE
;
825 SubTask
->AtaDevice
= AtaDevice
;
826 SubTask
->Token
= Token
;
827 SubTask
->IsError
= IsError
;
828 InsertTailList (&AtaDevice
->AtaSubTaskList
, &SubTask
->TaskEntry
);
829 gBS
->RestoreTPL (OldTpl
);
831 Status
= gBS
->CreateEvent (
834 AtaNonBlockingCallBack
,
839 // If resource allocation fail, the un-signalled event count should equal to
840 // the original one minus the unassigned subtasks number.
842 if (EFI_ERROR (Status
)) {
843 Status
= EFI_OUT_OF_RESOURCES
;
847 Status
= TransferAtaDevice (AtaDevice
, &SubTask
->Packet
, Buffer
, StartLba
, (UINT32
) TransferBlockNumber
, IsWrite
, SubEvent
);
852 DEBUG ((EFI_D_BLKIO
, "Blocking AccessAtaDevice, TransferBlockNumber=%x; StartLba = %x\n", TransferBlockNumber
, StartLba
));
853 Status
= TransferAtaDevice (AtaDevice
, NULL
, Buffer
, StartLba
, (UINT32
) TransferBlockNumber
, IsWrite
, NULL
);
856 if (EFI_ERROR (Status
)) {
861 StartLba
+= TransferBlockNumber
;
862 Buffer
+= TransferBlockNumber
* BlockSize
;
863 } while (NumberOfBlocks
> 0);
866 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
868 // Release resource at non-blocking mode.
870 if (EFI_ERROR (Status
)) {
871 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
872 Token
->TransactionStatus
= Status
;
873 *EventCount
= (*EventCount
) - (TempCount
- Index
);
876 if (*EventCount
== 0) {
877 FreePool (EventCount
);
881 if (SubTask
!= NULL
) {
882 RemoveEntryList (&SubTask
->TaskEntry
);
883 FreeAtaSubTask (SubTask
);
886 if (SubEvent
!= NULL
) {
887 gBS
->CloseEvent (SubEvent
);
889 gBS
->RestoreTPL (OldTpl
);
897 Trust transfer data from/to ATA device.
899 This function performs one ATA pass through transaction to do a trust transfer from/to
900 ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
901 interface of ATA pass through.
903 @param AtaDevice The ATA child device involved for the operation.
904 @param Buffer The pointer to the current transaction buffer.
905 @param SecurityProtocolId The value of the "Security Protocol" parameter of
906 the security protocol command to be sent.
907 @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
908 of the security protocol command to be sent.
909 @param TransferLength The block number or sector count of the transfer.
910 @param IsTrustSend Indicates whether it is a trust send operation or not.
911 @param Timeout The timeout, in 100ns units, to use for the execution
912 of the security protocol command. A Timeout value of 0
913 means that this function will wait indefinitely for the
914 security protocol command to execute. If Timeout is greater
915 than zero, then this function will return EFI_TIMEOUT
916 if the time required to execute the receive data command
917 is greater than Timeout.
918 @param TransferLengthOut A pointer to a buffer to store the size in bytes of the data
919 written to the buffer. Ignore it when IsTrustSend is TRUE.
921 @retval EFI_SUCCESS The data transfer is complete successfully.
922 @return others Some error occurs when transferring data.
927 TrustTransferAtaDevice (
928 IN OUT ATA_DEVICE
*AtaDevice
,
930 IN UINT8 SecurityProtocolId
,
931 IN UINT16 SecurityProtocolSpecificData
,
932 IN UINTN TransferLength
,
933 IN BOOLEAN IsTrustSend
,
935 OUT UINTN
*TransferLengthOut
938 EFI_ATA_COMMAND_BLOCK
*Acb
;
939 EFI_ATA_PASS_THRU_COMMAND_PACKET
*Packet
;
942 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
945 // Ensure AtaDevice->UdmaValid and IsTrustSend are valid boolean values
947 ASSERT ((UINTN
) AtaDevice
->UdmaValid
< 2);
948 ASSERT ((UINTN
) IsTrustSend
< 2);
950 // Prepare for ATA command block.
952 Acb
= ZeroMem (&AtaDevice
->Acb
, sizeof (EFI_ATA_COMMAND_BLOCK
));
953 if (TransferLength
== 0) {
954 Acb
->AtaCommand
= ATA_CMD_TRUST_NON_DATA
;
956 Acb
->AtaCommand
= mAtaTrustCommands
[AtaDevice
->UdmaValid
][IsTrustSend
];
958 Acb
->AtaFeatures
= SecurityProtocolId
;
959 Acb
->AtaSectorCount
= (UINT8
) (TransferLength
/ 512);
960 Acb
->AtaSectorNumber
= (UINT8
) ((TransferLength
/ 512) >> 8);
962 // NOTE: ATA Spec has no explicitly definition for Security Protocol Specific layout.
963 // Here use big endian for Cylinder register.
965 Acb
->AtaCylinderHigh
= (UINT8
) SecurityProtocolSpecificData
;
966 Acb
->AtaCylinderLow
= (UINT8
) (SecurityProtocolSpecificData
>> 8);
967 Acb
->AtaDeviceHead
= (UINT8
) (BIT7
| BIT6
| BIT5
| (AtaDevice
->PortMultiplierPort
<< 4));
970 // Prepare for ATA pass through packet.
972 Packet
= ZeroMem (&AtaDevice
->Packet
, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET
));
973 if (TransferLength
== 0) {
974 Packet
->InTransferLength
= 0;
975 Packet
->OutTransferLength
= 0;
976 Packet
->Protocol
= EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA
;
977 } else if (IsTrustSend
) {
979 // Check the alignment of the incoming buffer prior to invoking underlying ATA PassThru
981 AtaPassThru
= AtaDevice
->AtaBusDriverData
->AtaPassThru
;
982 if ((AtaPassThru
->Mode
->IoAlign
> 1) && !IS_ALIGNED (Buffer
, AtaPassThru
->Mode
->IoAlign
)) {
983 NewBuffer
= AllocateAlignedBuffer (AtaDevice
, TransferLength
);
984 if (NewBuffer
== NULL
) {
985 return EFI_OUT_OF_RESOURCES
;
988 CopyMem (NewBuffer
, Buffer
, TransferLength
);
992 Packet
->OutDataBuffer
= Buffer
;
993 Packet
->OutTransferLength
= (UINT32
) TransferLength
;
994 Packet
->Protocol
= mAtaPassThruCmdProtocols
[AtaDevice
->UdmaValid
][IsTrustSend
];
996 Packet
->InDataBuffer
= Buffer
;
997 Packet
->InTransferLength
= (UINT32
) TransferLength
;
998 Packet
->Protocol
= mAtaPassThruCmdProtocols
[AtaDevice
->UdmaValid
][IsTrustSend
];
1000 Packet
->Length
= EFI_ATA_PASS_THRU_LENGTH_BYTES
;
1001 Packet
->Timeout
= Timeout
;
1003 Status
= AtaDevicePassThru (AtaDevice
, NULL
, NULL
);
1004 if (TransferLengthOut
!= NULL
) {
1005 if (! IsTrustSend
) {
1006 *TransferLengthOut
= Packet
->InTransferLength
;