MdeModulePkg/ScsiDisk: Using back-off algorithm to dynamically adjust transfer length in a single SCSI/ATAPI transfer to reach best device compatibility.
Besides this, the patch also fixed: 1) Wrong return value in SenseDataLength field of packet field of EFI_EXT_SCSI_PASS_THRU protocol, it should reflect real sense data length we got. 2) Wrong logic in ScsiDiskRequestSenseKeys that the logic makes SenseData pointer unaligned compared with BlockIo.Media.IoAlign field. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Tian, Feng <feng.tian@intel.com> Reviewed-by: Zeng, Star <star.zeng@intel.com> Reviewed-by: Fu, Siyuan <siyuan.fu@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15491 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
Header file for AHCI mode of ATA host controller.
|
||||
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2014, 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
|
||||
@@ -1941,56 +1941,6 @@ AtaPacketReadWrite (
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Sumbit ATAPI request sense command.
|
||||
|
||||
@param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
|
||||
@param[in] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
|
||||
store the IDE i/o port registers' base addresses
|
||||
@param[in] Channel The channel number of device.
|
||||
@param[in] Device The device number of device.
|
||||
@param[in] SenseData A pointer to store sense data.
|
||||
@param[in] SenseDataLength The sense data length.
|
||||
@param[in] Timeout The timeout value to execute this cmd, uses 100ns as a unit.
|
||||
|
||||
@retval EFI_SUCCESS Send out the ATAPI packet command successfully.
|
||||
@retval EFI_DEVICE_ERROR The device failed to send data.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
AtaPacketRequestSense (
|
||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||
IN EFI_IDE_REGISTERS *IdeRegisters,
|
||||
IN UINT8 Channel,
|
||||
IN UINT8 Device,
|
||||
IN VOID *SenseData,
|
||||
IN UINT8 SenseDataLength,
|
||||
IN UINT64 Timeout
|
||||
)
|
||||
{
|
||||
EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET Packet;
|
||||
UINT8 Cdb[12];
|
||||
EFI_STATUS Status;
|
||||
|
||||
ZeroMem (&Packet, sizeof (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));
|
||||
ZeroMem (Cdb, 12);
|
||||
|
||||
Cdb[0] = ATA_CMD_REQUEST_SENSE;
|
||||
Cdb[4] = SenseDataLength;
|
||||
|
||||
Packet.Timeout = Timeout;
|
||||
Packet.Cdb = Cdb;
|
||||
Packet.CdbLength = 12;
|
||||
Packet.DataDirection = EFI_EXT_SCSI_DATA_DIRECTION_READ;
|
||||
Packet.InDataBuffer = SenseData;
|
||||
Packet.InTransferLength = SenseDataLength;
|
||||
|
||||
Status = AtaPacketCommandExecute (PciIo, IdeRegisters, Channel, Device, &Packet);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This function is used to send out ATAPI commands conforms to the Packet Command
|
||||
with PIO Data In Protocol.
|
||||
@@ -2017,7 +1967,6 @@ AtaPacketCommandExecute (
|
||||
IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
|
||||
)
|
||||
{
|
||||
EFI_STATUS PacketCommandStatus;
|
||||
EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
|
||||
EFI_STATUS Status;
|
||||
UINT8 Count;
|
||||
@@ -2083,56 +2032,26 @@ AtaPacketCommandExecute (
|
||||
// Read/Write the data of ATAPI Command
|
||||
//
|
||||
if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
|
||||
PacketCommandStatus = AtaPacketReadWrite (
|
||||
PciIo,
|
||||
IdeRegisters,
|
||||
Packet->InDataBuffer,
|
||||
Packet->InTransferLength,
|
||||
TRUE,
|
||||
Packet->Timeout
|
||||
);
|
||||
Status = AtaPacketReadWrite (
|
||||
PciIo,
|
||||
IdeRegisters,
|
||||
Packet->InDataBuffer,
|
||||
Packet->InTransferLength,
|
||||
TRUE,
|
||||
Packet->Timeout
|
||||
);
|
||||
} else {
|
||||
PacketCommandStatus = AtaPacketReadWrite (
|
||||
PciIo,
|
||||
IdeRegisters,
|
||||
Packet->OutDataBuffer,
|
||||
Packet->OutTransferLength,
|
||||
FALSE,
|
||||
Packet->Timeout
|
||||
);
|
||||
Status = AtaPacketReadWrite (
|
||||
PciIo,
|
||||
IdeRegisters,
|
||||
Packet->OutDataBuffer,
|
||||
Packet->OutTransferLength,
|
||||
FALSE,
|
||||
Packet->Timeout
|
||||
);
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (PacketCommandStatus)) {
|
||||
return PacketCommandStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// Return SenseData if PacketCommandStatus matches
|
||||
// the following return codes.
|
||||
//
|
||||
if ((PacketCommandStatus == EFI_BAD_BUFFER_SIZE) ||
|
||||
(PacketCommandStatus == EFI_DEVICE_ERROR) ||
|
||||
(PacketCommandStatus == EFI_TIMEOUT)) {
|
||||
|
||||
//
|
||||
// avoid submit request sense command continuously.
|
||||
//
|
||||
if ((Packet->SenseData == NULL) || (((UINT8 *)Packet->Cdb)[0] == ATA_CMD_REQUEST_SENSE)) {
|
||||
return PacketCommandStatus;
|
||||
}
|
||||
|
||||
AtaPacketRequestSense (
|
||||
PciIo,
|
||||
IdeRegisters,
|
||||
Channel,
|
||||
Device,
|
||||
Packet->SenseData,
|
||||
Packet->SenseDataLength,
|
||||
Packet->Timeout
|
||||
);
|
||||
}
|
||||
|
||||
return PacketCommandStatus;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user