]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/.../IdeMode: correctly report length of returned data
authorPaolo Bonzini <pbonzini@redhat.com>
Mon, 25 Jan 2016 11:33:37 +0000 (11:33 +0000)
committerlersek <lersek@Edk2>
Mon, 25 Jan 2016 11:33:37 +0000 (11:33 +0000)
For some SCSI commands, notably INQUIRY, it's relatively common for
the device to provide less data than we intended to read, and for
this reason EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET makes
InTransferLength and OutTransferLength read-write.  Make ATAPI
aware of this.

This makes it possible to handle EFI_NOT_READY always, not just
for read as done in r19685.

I've chosen to use a break statement instead of calling
CheckStatusRegister directly; the break statement reaches a
pre-existing call the CheckStatusRegister function.  This
ensures that the assignment to *ByteCount is not missed, and
adds a further sanity check to DRQClear.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-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@19737 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Ata/AtaAtapiPassThru/IdeMode.c

index 320ee90828bbc050f1c1eaef93634830e881e7cd..6478f7be07ddd1260ce9d321dab19e4d798617dd 100644 (file)
@@ -1936,7 +1936,7 @@ AtaPacketReadWrite (
   IN     EFI_PCI_IO_PROTOCOL       *PciIo,\r
   IN     EFI_IDE_REGISTERS         *IdeRegisters,\r
   IN OUT VOID                      *Buffer,\r
-  IN     UINT64                    ByteCount,\r
+  IN OUT UINT32                    *ByteCount,\r
   IN     BOOLEAN                   Read,\r
   IN     UINT64                    Timeout\r
   )\r
@@ -1947,17 +1947,18 @@ AtaPacketReadWrite (
   EFI_STATUS  Status;\r
   UINT16      *PtrBuffer;\r
 \r
+  PtrBuffer         = Buffer;\r
+  RequiredWordCount = *ByteCount >> 1;\r
+\r
   //\r
   // No data transfer is premitted.\r
   //\r
-  if (ByteCount == 0) {\r
+  if (RequiredWordCount == 0) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  PtrBuffer         = Buffer;\r
-  RequiredWordCount = (UINT32)RShiftU64(ByteCount, 1);\r
   //\r
-  // ActuralWordCount means the word count of data really transferred.\r
+  // ActualWordCount means the word count of data really transferred.\r
   //\r
   ActualWordCount = 0;\r
 \r
@@ -1967,14 +1968,16 @@ AtaPacketReadWrite (
     // to see whether indicates device is ready to transfer data.\r
     //\r
     Status = DRQReady2 (PciIo, IdeRegisters, Timeout);\r
-    if ((Status == EFI_NOT_READY) && Read) {\r
-      //\r
-      // Device provided less data than we intended to read -- exit early.\r
-      //\r
-      return CheckStatusRegister (PciIo, IdeRegisters);\r
-    }\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      if (Status == EFI_NOT_READY) {\r
+        //\r
+        // Device provided less data than we intended to read, or wanted less\r
+        // data than we intended to write, but it may still be successful.\r
+        //\r
+        break;\r
+      } else {\r
+        return Status;\r
+      }\r
     }\r
 \r
     //\r
@@ -2040,6 +2043,7 @@ AtaPacketReadWrite (
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
+  *ByteCount = ActualWordCount << 1;\r
   return Status;\r
 }\r
 \r
@@ -2138,7 +2142,7 @@ AtaPacketCommandExecute (
                PciIo,\r
                IdeRegisters,\r
                Packet->InDataBuffer,\r
-               Packet->InTransferLength,\r
+               &Packet->InTransferLength,\r
                TRUE,\r
                Packet->Timeout\r
                );\r
@@ -2147,7 +2151,7 @@ AtaPacketCommandExecute (
                PciIo,\r
                IdeRegisters,\r
                Packet->OutDataBuffer,\r
-               Packet->OutTransferLength,\r
+               &Packet->OutTransferLength,\r
                FALSE,\r
                Packet->Timeout\r
                );\r