summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFeng Tian <feng.tian@intel.com>2015-05-22 06:53:44 +0000
committererictian <erictian@Edk2>2015-05-22 06:53:44 +0000
commite7401ee1af263ff946a57f047124241fa4f01cd5 (patch)
treee89f0bcac133103ea07647a27a6236e12221ff68
parentcbbc454b2ad9ee4359d3a145a3d622c7db22fef6 (diff)
downloadedk2-platforms-e7401ee1af263ff946a57f047124241fa4f01cd5.tar.xz
MdeModulePkg/AtaAtapiPassThruDxe: Support 4K bytes block size HDDs
The original code hard-codes block size to 512. But after ATA 7 spec, the non-512 block size is also supported. The code is updated to dynamically calculate the block size according to IDENTIFY data. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Feng Tian <feng.tian@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17495 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
index 6ccf0a3f01..870900f106 100644
--- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
+++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
@@ -2,7 +2,7 @@
This file implements ATA_PASSTHRU_PROCTOCOL and EXT_SCSI_PASSTHRU_PROTOCOL interfaces
for managed ATA controllers.
- Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -1255,6 +1255,7 @@ AtaPassThruPassThru (
UINT32 MaxSectorCount;
ATA_NONBLOCK_TASK *Task;
EFI_TPL OldTpl;
+ UINT32 BlockSize;
Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
@@ -1280,22 +1281,6 @@ AtaPassThruPassThru (
}
//
- // convert the transfer length from sector count to byte.
- //
- if (((Packet->Length & EFI_ATA_PASS_THRU_LENGTH_BYTES) == 0) &&
- (Packet->InTransferLength != 0)) {
- Packet->InTransferLength = Packet->InTransferLength * 0x200;
- }
-
- //
- // convert the transfer length from sector count to byte.
- //
- if (((Packet->Length & EFI_ATA_PASS_THRU_LENGTH_BYTES) == 0) &&
- (Packet->OutTransferLength != 0)) {
- Packet->OutTransferLength = Packet->OutTransferLength * 0x200;
- }
-
- //
// Check whether this device needs 48-bit addressing (ATAPI-6 ata device).
// Per ATA-6 spec, word83: bit15 is zero and bit14 is one.
// If bit10 is one, it means the ata device support 48-bit addressing.
@@ -1314,13 +1299,39 @@ AtaPassThruPassThru (
}
}
+ BlockSize = 0x200;
+ if ((IdentifyData->AtaData.phy_logic_sector_support & (BIT14 | BIT15)) == BIT14) {
+ //
+ // Check logical block size
+ //
+ if ((IdentifyData->AtaData.phy_logic_sector_support & BIT12) != 0) {
+ BlockSize = (UINT32) (((IdentifyData->AtaData.logic_sector_size_hi << 16) | IdentifyData->AtaData.logic_sector_size_lo) * sizeof (UINT16));
+ }
+ }
+
+ //
+ // convert the transfer length from sector count to byte.
+ //
+ if (((Packet->Length & EFI_ATA_PASS_THRU_LENGTH_BYTES) == 0) &&
+ (Packet->InTransferLength != 0)) {
+ Packet->InTransferLength = Packet->InTransferLength * BlockSize;
+ }
+
+ //
+ // convert the transfer length from sector count to byte.
+ //
+ if (((Packet->Length & EFI_ATA_PASS_THRU_LENGTH_BYTES) == 0) &&
+ (Packet->OutTransferLength != 0)) {
+ Packet->OutTransferLength = Packet->OutTransferLength * BlockSize;
+ }
+
//
// If the data buffer described by InDataBuffer/OutDataBuffer and InTransferLength/OutTransferLength
// is too big to be transferred in a single command, then no data is transferred and EFI_BAD_BUFFER_SIZE
// is returned.
//
- if (((Packet->InTransferLength != 0) && (Packet->InTransferLength > MaxSectorCount * 0x200)) ||
- ((Packet->OutTransferLength != 0) && (Packet->OutTransferLength > MaxSectorCount * 0x200))) {
+ if (((Packet->InTransferLength != 0) && (Packet->InTransferLength > MaxSectorCount * BlockSize)) ||
+ ((Packet->OutTransferLength != 0) && (Packet->OutTransferLength > MaxSectorCount * BlockSize))) {
return EFI_BAD_BUFFER_SIZE;
}
@@ -2074,7 +2085,7 @@ ExtScsiPassThruPassThru (
// no more sense key or number of sense keys exceeds predefined,
// skip the loop.
//
- if ((PtrSenseData->Sense_Key == EFI_SCSI_SK_NO_SENSE) ||
+ if ((PtrSenseData->Sense_Key == EFI_SCSI_SK_NO_SENSE) ||
(SenseDataLen + sizeof (EFI_SCSI_SENSE_DATA) > Packet->SenseDataLength)) {
SenseReq = FALSE;
}