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 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
9 This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 // Look up table (UdmaValid, IsWrite) for EFI_ATA_PASS_THRU_CMD_PROTOCOL
25 EFI_ATA_PASS_THRU_CMD_PROTOCOL mAtaPassThruCmdProtocols
[][2] = {
27 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN
,
28 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT
31 EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN
,
32 EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT
,
37 // Look up table (UdmaValid, Lba48Bit, IsIsWrite) for ATA_CMD
39 UINT8 mAtaCommands
[][2][2] = {
42 ATA_CMD_READ_SECTORS
, // 28-bit LBA; PIO read
43 ATA_CMD_WRITE_SECTORS
// 28-bit LBA; PIO write
46 ATA_CMD_READ_SECTORS_EXT
, // 48-bit LBA; PIO read
47 ATA_CMD_WRITE_SECTORS_EXT
// 48-bit LBA; PIO write
52 ATA_CMD_READ_DMA
, // 28-bit LBA; DMA read
53 ATA_CMD_WRITE_DMA
// 28-bit LBA; DMA write
56 ATA_CMD_READ_DMA_EXT
, // 48-bit LBA; DMA read
57 ATA_CMD_WRITE_DMA_EXT
// 48-bit LBA; DMA write
63 // Look up table (Lba48Bit) for maximum transfer block number
65 UINTN mMaxTransferBlockNumber
[] = {
66 MAX_28BIT_TRANSFER_BLOCK_NUM
,
67 MAX_48BIT_TRANSFER_BLOCK_NUM
72 Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
74 This function wraps the PassThru() invocation for ATA pass through function
75 for an ATA device. It assembles the ATA pass through command packet for ATA
78 @param[in, out] AtaDevice The ATA child device involved for the operation.
79 @param[in, out] TaskPacket Pointer to a Pass Thru Command Packet. Optional,
80 if it is NULL, blocking mode, and use the packet
81 in AtaDevice. If it is not NULL, non blocking mode,
82 and pass down this Packet.
83 @param[in] Event If Event is NULL, then blocking I/O is performed.
84 If Event is not NULL and non-blocking I/O is
85 supported,then non-blocking I/O is performed,
86 and Event will be signaled when the write
89 @return The return status from EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
94 IN OUT ATA_DEVICE
*AtaDevice
,
95 IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET
*TaskPacket
, OPTIONAL
96 IN OUT EFI_EVENT Event OPTIONAL
100 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
101 EFI_ATA_PASS_THRU_COMMAND_PACKET
*Packet
;
104 // Assemble packet. If it is non blocking mode, the Ata driver should keep each
105 // subtask and clean them when the event is signaled.
107 if (TaskPacket
!= NULL
) {
109 Packet
->Asb
= AllocateAlignedBuffer (AtaDevice
, sizeof (*AtaDevice
->Asb
));
110 CopyMem (Packet
->Asb
, AtaDevice
->Asb
, sizeof (*AtaDevice
->Asb
));
111 Packet
->Acb
= AllocateCopyPool(sizeof (EFI_ATA_COMMAND_BLOCK
), &AtaDevice
->Acb
);
113 Packet
= &AtaDevice
->Packet
;
114 Packet
->Asb
= AtaDevice
->Asb
;
115 Packet
->Acb
= &AtaDevice
->Acb
;
118 AtaPassThru
= AtaDevice
->AtaBusDriverData
->AtaPassThru
;
120 Status
= AtaPassThru
->PassThru (
123 AtaDevice
->PortMultiplierPort
,
128 // Ensure ATA pass through caller and callee have the same
129 // interpretation of ATA pass through protocol.
131 ASSERT (Status
!= EFI_INVALID_PARAMETER
);
132 ASSERT (Status
!= EFI_BAD_BUFFER_SIZE
);
139 Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.ResetDevice().
141 This function wraps the ResetDevice() invocation for ATA pass through function
144 @param AtaDevice The ATA child device involved for the operation.
146 @return The return status from EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
151 IN ATA_DEVICE
*AtaDevice
154 EFI_ATA_PASS_THRU_PROTOCOL
*AtaPassThru
;
156 AtaPassThru
= AtaDevice
->AtaBusDriverData
->AtaPassThru
;
158 return AtaPassThru
->ResetDevice (
161 AtaDevice
->PortMultiplierPort
167 Prints ATA model name to ATA device structure.
169 This function converts ATA device model name from ATA identify data
170 to a string in ATA device structure. It needs to change the character
171 order in the original model name string.
173 @param AtaDevice The ATA child device involved for the operation.
178 IN OUT ATA_DEVICE
*AtaDevice
185 Source
= AtaDevice
->IdentifyData
->ModelName
;
186 Destination
= AtaDevice
->ModelName
;
189 // Swap the byte order in the original module name.
191 for (Index
= 0; Index
< MAX_MODEL_NAME_LEN
; Index
+= 2) {
192 Destination
[Index
] = Source
[Index
+ 1];
193 Destination
[Index
+ 1] = Source
[Index
];
195 AtaDevice
->ModelName
[MAX_MODEL_NAME_LEN
] = L
'\0';
200 Gets ATA device Capacity according to ATA 6.
202 This function returns the capacity of the ATA device if it follows
203 ATA 6 to support 48 bit addressing.
205 @param AtaDevice The ATA child device involved for the operation.
207 @return The capacity of the ATA device or 0 if the device does not support
208 48-bit addressing defined in ATA 6.
213 IN ATA_DEVICE
*AtaDevice
219 ATA_IDENTIFY_DATA
*IdentifyData
;
221 IdentifyData
= AtaDevice
->IdentifyData
;
222 if ((IdentifyData
->command_set_supported_83
& BIT10
) == 0) {
224 // The device doesn't support 48 bit addressing
230 // 48 bit address feature set is supported, get maximum capacity
233 for (Index
= 0; Index
< 4; Index
++) {
235 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
237 TmpLba
= IdentifyData
->maximum_lba_for_48bit_addressing
[Index
];
238 Capacity
|= LShiftU64 (TmpLba
, 16 * Index
);
246 Identifies ATA device via the Identify data.
248 This function identifies the ATA device and initializes the Media information in
249 Block IO protocol interface.
251 @param AtaDevice The ATA child device involved for the operation.
253 @retval EFI_UNSUPPORTED The device is not a valid ATA device (hard disk).
254 @retval EFI_SUCCESS The device is successfully identified and Media information
255 is correctly initialized.
260 IN OUT ATA_DEVICE
*AtaDevice
263 ATA_IDENTIFY_DATA
*IdentifyData
;
264 EFI_BLOCK_IO_MEDIA
*BlockMedia
;
266 UINT16 PhyLogicSectorSupport
;
269 IdentifyData
= AtaDevice
->IdentifyData
;
271 if ((IdentifyData
->config
& BIT15
) != 0) {
273 // This is not an hard disk
275 return EFI_UNSUPPORTED
;
278 DEBUG ((EFI_D_INFO
, "AtaBus - Identify Device (%x %x)\n", (UINTN
)AtaDevice
->Port
, (UINTN
)AtaDevice
->PortMultiplierPort
));
281 // Check whether the WORD 88 (supported UltraDMA by drive) is valid
283 if ((IdentifyData
->field_validity
& BIT2
) != 0) {
284 UdmaMode
= IdentifyData
->ultra_dma_mode
;
285 if ((UdmaMode
& (BIT0
| BIT1
| BIT2
| BIT3
| BIT4
| BIT5
| BIT6
)) != 0) {
287 // If BIT0~BIT6 is selected, then UDMA is supported
289 AtaDevice
->UdmaValid
= TRUE
;
293 Capacity
= GetAtapi6Capacity (AtaDevice
);
294 if (Capacity
> MAX_28BIT_ADDRESSING_CAPACITY
) {
296 // Capacity exceeds 120GB. 48-bit addressing is really needed
298 AtaDevice
->Lba48Bit
= TRUE
;
301 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
303 Capacity
= ((UINT32
)IdentifyData
->user_addressable_sectors_hi
<< 16) | IdentifyData
->user_addressable_sectors_lo
;
304 AtaDevice
->Lba48Bit
= FALSE
;
308 // Block Media Information:
310 BlockMedia
= &AtaDevice
->BlockMedia
;
311 BlockMedia
->LastBlock
= Capacity
- 1;
312 BlockMedia
->IoAlign
= AtaDevice
->AtaBusDriverData
->AtaPassThru
->Mode
->IoAlign
;
314 // Check whether Long Physical Sector Feature is supported
316 PhyLogicSectorSupport
= IdentifyData
->phy_logic_sector_support
;
317 if ((PhyLogicSectorSupport
& (BIT14
| BIT15
)) == BIT14
) {
319 // Check whether one physical block contains multiple physical blocks
321 if ((PhyLogicSectorSupport
& BIT13
) != 0) {
322 BlockMedia
->LogicalBlocksPerPhysicalBlock
= (UINT32
) (1 << (PhyLogicSectorSupport
& 0x000f));
324 // Check lowest alignment of logical blocks within physical block
326 if ((IdentifyData
->alignment_logic_in_phy_blocks
& (BIT14
| BIT15
)) == BIT14
) {
327 BlockMedia
->LowestAlignedLba
= (EFI_LBA
) ((BlockMedia
->LogicalBlocksPerPhysicalBlock
- ((UINT32
)IdentifyData
->alignment_logic_in_phy_blocks
& 0x3fff)) %
328 BlockMedia
->LogicalBlocksPerPhysicalBlock
);
332 // Check logical block size
334 if ((PhyLogicSectorSupport
& BIT12
) != 0) {
335 BlockMedia
->BlockSize
= (UINT32
) (((IdentifyData
->logic_sector_size_hi
<< 16) | IdentifyData
->logic_sector_size_lo
) * sizeof (UINT16
));
337 AtaDevice
->BlockIo
.Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION2
;
340 // Get ATA model name from identify data structure.
342 PrintAtaModelName (AtaDevice
);
349 Discovers whether it is a valid ATA device.
351 This function issues ATA_CMD_IDENTIFY_DRIVE command to the ATA device to identify it.
352 If the command is executed successfully, it then identifies it and initializes
353 the Media information in Block IO protocol interface.
355 @param AtaDevice The ATA child device involved for the operation.
357 @retval EFI_SUCCESS The device is successfully identified and Media information
358 is correctly initialized.
359 @return others Some error occurs when discovering the ATA device.
364 IN OUT ATA_DEVICE
*AtaDevice
368 EFI_ATA_COMMAND_BLOCK
*Acb
;
369 EFI_ATA_PASS_THRU_COMMAND_PACKET
*Packet
;
373 // Prepare for ATA command block.
375 Acb
= ZeroMem (&AtaDevice
->Acb
, sizeof (*Acb
));
376 Acb
->AtaCommand
= ATA_CMD_IDENTIFY_DRIVE
;
377 Acb
->AtaDeviceHead
= (UINT8
) (BIT7
| BIT6
| BIT5
| (AtaDevice
->PortMultiplierPort
<< 4));
380 // Prepare for ATA pass through packet.
382 Packet
= ZeroMem (&AtaDevice
->Packet
, sizeof (*Packet
));
383 Packet
->InDataBuffer
= AtaDevice
->IdentifyData
;
384 Packet
->InTransferLength
= sizeof (*AtaDevice
->IdentifyData
);
385 Packet
->Protocol
= EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN
;
386 Packet
->Length
= EFI_ATA_PASS_THRU_LENGTH_BYTES
| EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT
;
387 Packet
->Timeout
= ATA_TIMEOUT
;
389 Retry
= MAX_RETRY_TIMES
;
391 Status
= AtaDevicePassThru (AtaDevice
, NULL
, NULL
);
392 if (!EFI_ERROR (Status
)) {
394 // The command is issued successfully
396 Status
= IdentifyAtaDevice (AtaDevice
);
397 if (!EFI_ERROR (Status
)) {
401 } while (Retry
-- > 0);
407 Transfer data from ATA device.
409 This function performs one ATA pass through transaction to transfer data from/to
410 ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
411 interface of ATA pass through.
413 @param[in, out] AtaDevice The ATA child device involved for the operation.
414 @param[in, out] TaskPacket Pointer to a Pass Thru Command Packet. Optional,
415 if it is NULL, blocking mode, and use the packet
416 in AtaDevice. If it is not NULL, non blocking mode,
417 and pass down this Packet.
418 @param[in, out] Buffer The pointer to the current transaction buffer.
419 @param[in] StartLba The starting logical block address to be accessed.
420 @param[in] TransferLength The block number or sector count of the transfer.
421 @param[in] IsWrite Indicates whether it is a write operation.
422 @param[in] Event If Event is NULL, then blocking I/O is performed.
423 If Event is not NULL and non-blocking I/O is
424 supported,then non-blocking I/O is performed,
425 and Event will be signaled when the write
426 request is completed.
428 @retval EFI_SUCCESS The data transfer is complete successfully.
429 @return others Some error occurs when transferring data.
434 IN OUT ATA_DEVICE
*AtaDevice
,
435 IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET
*TaskPacket
, OPTIONAL
438 IN UINT32 TransferLength
,
440 IN EFI_EVENT Event OPTIONAL
443 EFI_ATA_COMMAND_BLOCK
*Acb
;
444 EFI_ATA_PASS_THRU_COMMAND_PACKET
*Packet
;
447 // Ensure AtaDevice->UdmaValid, AtaDevice->Lba48Bit and IsWrite are valid boolean values
449 ASSERT ((UINTN
) AtaDevice
->UdmaValid
< 2);
450 ASSERT ((UINTN
) AtaDevice
->Lba48Bit
< 2);
451 ASSERT ((UINTN
) IsWrite
< 2);
453 // Prepare for ATA command block.
455 Acb
= ZeroMem (&AtaDevice
->Acb
, sizeof (*Acb
));
456 Acb
->AtaCommand
= mAtaCommands
[AtaDevice
->UdmaValid
][AtaDevice
->Lba48Bit
][IsWrite
];
457 Acb
->AtaSectorNumber
= (UINT8
) StartLba
;
458 Acb
->AtaCylinderLow
= (UINT8
) RShiftU64 (StartLba
, 8);
459 Acb
->AtaCylinderHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
460 Acb
->AtaDeviceHead
= (UINT8
) (BIT7
| BIT6
| BIT5
| (AtaDevice
->PortMultiplierPort
<< 4));
461 Acb
->AtaSectorCount
= (UINT8
) TransferLength
;
462 if (AtaDevice
->Lba48Bit
) {
463 Acb
->AtaSectorNumberExp
= (UINT8
) RShiftU64 (StartLba
, 24);
464 Acb
->AtaCylinderLowExp
= (UINT8
) RShiftU64 (StartLba
, 32);
465 Acb
->AtaCylinderHighExp
= (UINT8
) RShiftU64 (StartLba
, 40);
466 Acb
->AtaSectorCountExp
= (UINT8
) (TransferLength
>> 8);
468 Acb
->AtaDeviceHead
= (UINT8
) (Acb
->AtaDeviceHead
| RShiftU64 (StartLba
, 24));
472 // Prepare for ATA pass through packet.
474 if (TaskPacket
!= NULL
) {
475 Packet
= ZeroMem (TaskPacket
, sizeof (*Packet
));
477 Packet
= ZeroMem (&AtaDevice
->Packet
, sizeof (*Packet
));
481 Packet
->OutDataBuffer
= Buffer
;
482 Packet
->OutTransferLength
= TransferLength
;
484 Packet
->InDataBuffer
= Buffer
;
485 Packet
->InTransferLength
= TransferLength
;
488 Packet
->Protocol
= mAtaPassThruCmdProtocols
[AtaDevice
->UdmaValid
][IsWrite
];
489 Packet
->Length
= EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT
;
490 Packet
->Timeout
= ATA_TIMEOUT
;
492 return AtaDevicePassThru (AtaDevice
, TaskPacket
, Event
);
498 @param[in, out] Task Pointer to task to be freed.
504 IN ATA_BUS_ASYN_TASK
*Task
507 if (Task
->Packet
.Asb
!= NULL
) {
508 FreeAlignedBuffer (Task
->Packet
.Asb
, sizeof (Task
->Packet
.Asb
));
510 if (Task
->Packet
.Acb
!= NULL
) {
511 FreePool (Task
->Packet
.Acb
);
518 Call back funtion when the event is signaled.
520 @param[in] Event The Event this notify function registered to.
521 @param[in] Context Pointer to the context data registerd to the
527 AtaNonBlockingCallBack (
532 ATA_BUS_ASYN_TASK
*Task
;
534 Task
= (ATA_BUS_ASYN_TASK
*) Context
;
535 gBS
->CloseEvent (Event
);
538 // Check the command status.
539 // If there is error during the sub task source allocation, the error status
540 // should be returned to the caller directly, so here the Task->Token may already
541 // be deleted by the caller and no need to update the status.
543 if ((!(*Task
->IsError
)) && (Task
->Packet
.Asb
->AtaStatus
& 0x01) == 0x01) {
544 Task
->Token
->TransactionStatus
= EFI_DEVICE_ERROR
;
548 "NON-BLOCKING EVENT FINISHED!- STATUS = %r\n",
549 Task
->Token
->TransactionStatus
553 // Reduce the SubEventCount, till it comes to zero.
555 (*Task
->UnsignalledEventCount
) --;
556 DEBUG ((DEBUG_INFO
, "UnsignalledEventCount = %x\n", *Task
->UnsignalledEventCount
));
559 // Remove the SubTask from the Task list.
561 RemoveEntryList (&Task
->TaskEntry
);
562 if ((*Task
->UnsignalledEventCount
) == 0) {
564 // All Sub tasks are done, then signal the upper layyer event.
565 // Except there is error during the sub task source allocation.
567 if (!(*Task
->IsError
)) {
568 gBS
->SignalEvent (Task
->Token
->Event
);
569 DEBUG ((DEBUG_INFO
, "Signal Up Level Event UnsignalledEventCount = %x!\n", *Task
->UnsignalledEventCount
));
572 FreePool (Task
->UnsignalledEventCount
);
573 FreePool (Task
->IsError
);
578 "PACKET INFO: Write=%s, Lenght=%x, LowCylinder=%x, HighCylinder=%x,SectionNumber=%x",
579 Task
->Packet
.OutDataBuffer
!= NULL
? L
"YES" : L
"NO",
580 Task
->Packet
.OutDataBuffer
!= NULL
? Task
->Packet
.OutTransferLength
: Task
->Packet
.InTransferLength
,
581 Task
->Packet
.Acb
->AtaCylinderLow
,
582 Task
->Packet
.Acb
->AtaCylinderHigh
,
583 Task
->Packet
.Acb
->AtaSectorCount
587 // Free the buffer of SubTask.
589 FreeAtaSubTask (Task
);
593 Read or write a number of blocks from ATA device.
595 This function performs ATA pass through transactions to read/write data from/to
596 ATA device. It may separate the read/write request into several ATA pass through
599 @param[in, out] AtaDevice The ATA child device involved for the operation.
600 @param[in, out] Buffer The pointer to the current transaction buffer.
601 @param[in] StartLba The starting logical block address to be accessed.
602 @param[in] NumberOfBlocks The block number or sector count of the transfer.
603 @param[in] IsWrite Indicates whether it is a write operation.
604 @param[in, out] Token A pointer to the token associated with the transaction.
606 @retval EFI_SUCCESS The data transfer is complete successfully.
607 @return others Some error occurs when transferring data.
612 IN OUT ATA_DEVICE
*AtaDevice
,
613 IN OUT UINT8
*Buffer
,
615 IN UINTN NumberOfBlocks
,
617 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
621 UINTN MaxTransferBlockNumber
;
622 UINTN TransferBlockNumber
;
626 ATA_BUS_ASYN_TASK
*Task
;
634 Status
= EFI_SUCCESS
;
636 EventCount
= AllocateZeroPool (sizeof (UINTN
));
637 if (EventCount
== NULL
) {
638 return EFI_OUT_OF_RESOURCES
;
641 IsError
= AllocateZeroPool (sizeof (BOOLEAN
));
642 if (IsError
== NULL
) {
648 // Initial the return status for Non Blocking.
650 if (Token
!= NULL
&& Token
->Event
!= NULL
) {
651 Token
->TransactionStatus
= EFI_SUCCESS
;
654 // Ensure AtaDevice->Lba48Bit is a valid boolean value
656 ASSERT ((UINTN
) AtaDevice
->Lba48Bit
< 2);
657 MaxTransferBlockNumber
= mMaxTransferBlockNumber
[AtaDevice
->Lba48Bit
];
658 BlockSize
= AtaDevice
->BlockMedia
.BlockSize
;
660 TempCount
= (NumberOfBlocks
+ MaxTransferBlockNumber
- 1) / MaxTransferBlockNumber
;
661 *EventCount
= TempCount
;
665 if (NumberOfBlocks
> MaxTransferBlockNumber
) {
666 TransferBlockNumber
= MaxTransferBlockNumber
;
667 NumberOfBlocks
-= MaxTransferBlockNumber
;
669 TransferBlockNumber
= NumberOfBlocks
;
674 // Create sub event for the sub Ata task. Non-Blocking Mode.
676 if (Token
!= NULL
&& Token
->Event
!= NULL
) {
677 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
678 Task
= AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK
));
681 // If resource allocation fail, reduce the total sub event counts.
683 *EventCount
= (*EventCount
) - (TempCount
- Index
);
685 Token
->TransactionStatus
= EFI_OUT_OF_RESOURCES
;
686 Status
= EFI_OUT_OF_RESOURCES
;
688 gBS
->RestoreTPL (OldTpl
);
692 Task
->UnsignalledEventCount
= EventCount
;
694 Task
->IsError
= IsError
;
696 InsertTailList (&AtaDevice
->AtaTaskList
, &Task
->TaskEntry
);
698 Status
= gBS
->CreateEvent (
701 AtaNonBlockingCallBack
,
706 // If resource allocation fail, the un-signalled event count should equal to
707 // the original one minus the unassigned subtasks number.
709 if (EFI_ERROR (Status
)) {
710 *EventCount
= (*EventCount
) - (TempCount
- Index
);
712 gBS
->RestoreTPL (OldTpl
);
716 gBS
->RestoreTPL (OldTpl
);
718 DEBUG ((EFI_D_INFO
, "NON-BLOCKING SET EVENT START: WRITE = %d\n", IsWrite
));
719 Status
= TransferAtaDevice (AtaDevice
, &Task
->Packet
, Buffer
, StartLba
, (UINT32
) TransferBlockNumber
, IsWrite
, SubEvent
);
722 "NON-BLOCKING SET EVENT END:StartLba=%x, TransferBlockNumbers=%x, Status=%r\n",
731 DEBUG ((EFI_D_INFO
, "BLOCKING BLOCK I/O START: WRITE = %d\n", IsWrite
));
732 Status
= TransferAtaDevice (AtaDevice
, NULL
, Buffer
, StartLba
, (UINT32
) TransferBlockNumber
, IsWrite
, NULL
);
735 "BLOCKING BLOCK I/O FINISHE - StartLba = %x; TransferBlockNumbers = %x, status = %r\n",
742 if (EFI_ERROR (Status
)) {
746 StartLba
+= TransferBlockNumber
;
747 Buffer
+= TransferBlockNumber
* BlockSize
;
748 } while (NumberOfBlocks
> 0);
752 if (*EventCount
== 0) {
753 FreePool (EventCount
);