mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/.../IdeMode: report early finish of packet read as success
SVN r19611 (git commit7cac240163
), "MdeModulePkg/Ide: return correct status when DRQ is not ready for ATAPI", changed the behavior of AtaPacketReadWrite(), when DRQReady2() reported an error. The previous logic had been to: (a) terminate the transfer loop, (b) check the status register with CheckStatusRegister(), and determine AtaPacketReadWrite()'s return code directly from that. Action (a) had been correct, but action (b) had masked genuine errors. For example, when DRQReady2() reported EFI_TIMEOUT -- because the BSY bit had not been cleared within the allotted time --, CheckStatusRegister() would report EFI_SUCCESS, simply *because* BSY was still set, and the rest of the status bits could not be evaluated. SVN r19611 (git commit7cac240163
) intended to fix action (b) by directly propagating the error code of DRQReady2() from AtaPacketReadWrite(), eliminating the CheckStatusRegister() call. This was the right thing for most of the errors reported by DRQReady2() -- timeout, command abort, other device error --, but there was one exception: the "read" sub-case of EFI_NOT_READY, which stands for "'read' complete, with less data available than the requested amount". Regarding the "write" sub-case of EFI_NOT_READY: the AtaPacketCommandExecute() function programs the full transfer length into the IDE device before it calls AtaPacketReadWrite(), and AtaPacketReadWrite() only uses CylinderLsb and CylinderMsb for "chunking" (as requested by the device). Therefore the device cannot justifiedly clear DRQ earlier than seeing the entire data, when writing. However, when reading from the device, a "short read" is a successful operation. (The actual read length will be decoded by the higher level protocols.) And "short reads" had been handled correctly by the logic before git7cac240163
. Namely, when DRQReady2() returns EFI_NOT_READY, the BSY bit is already clear, and we can call CheckStatusRegister() to investigate all the other bits it cares about. Therefore restore the logic from before git7cac240163
, but only for the "read" sub-case of EFI_NOT_READY. This problem was encountered with OVMF running on QEMU's i440fx IDE emulation. Many thanks to John Snow for analyzing QEMU's behavior, and pointing out that it adhered to the relevant specs. Cc: Feng Tian <feng.tian@intel.com> Cc: Star Zeng <star.zeng@intel.com> Cc: John Snow <jsnow@redhat.com> Reference: https://github.com/tianocore/edk2/issues/43 Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Feng Tian <feng.tian@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19685 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
dfc229f6a6
commit
0368497524
|
@ -1967,6 +1967,12 @@ AtaPacketReadWrite (
|
|||
// to see whether indicates device is ready to transfer data.
|
||||
//
|
||||
Status = DRQReady2 (PciIo, IdeRegisters, Timeout);
|
||||
if ((Status == EFI_NOT_READY) && Read) {
|
||||
//
|
||||
// Device provided less data than we intended to read -- exit early.
|
||||
//
|
||||
return CheckStatusRegister (PciIo, IdeRegisters);
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue