From: "Liran Alon" <liran.alon@oracle.com>
To: Laszlo Ersek <lersek@redhat.com>, devel@edk2.groups.io
Cc: nikita.leshchenko@oracle.com, aaron.young@oracle.com,
jordan.l.justen@intel.com, ard.biesheuvel@linaro.org
Subject: Re: [edk2-devel] [PATCH v2 15/17] OvmfPkg/PvScsiDxe: Support sending SCSI request and receive response
Date: Sat, 28 Mar 2020 22:18:47 +0300 [thread overview]
Message-ID: <9bbdb66f-9fdb-bd5a-74b8-6dc31015dc8a@oracle.com> (raw)
In-Reply-To: <65eb2511-e2f5-d2b5-4470-278b06a0e077@oracle.com>
On 28/03/2020 1:17, Liran Alon wrote:
>
> On 28/03/2020 1:04, Liran Alon wrote:
>>
>> On 28/03/2020 0:05, Laszlo Ersek wrote:
>>> On 03/27/20 14:04, Liran Alon wrote:
>>>> On 27/03/2020 14:26, Laszlo Ersek wrote:
>>>>> On 03/25/20 17:10, Liran Alon wrote:
>>>>>> + Packet->HostAdapterStatus =
>>>>>> + EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;
>>>>>> + return EFI_BAD_BUFFER_SIZE;
>>>>> I think EFI_BAD_BUFFER_SIZE is invalid here. According to the UEFI
>>>>> spec,
>>>>> EFI_BAD_BUFFER_SIZE means "The SCSI Request Packet was not executed".
>>>>> But that's not the case here -- we do have a partially completed
>>>>> transfer.
>>>> Hmm... According to the documentation above
>>>> EFI_SCSI_PASS_THRU_PASSTHRU
>>>> in MdePkg/Include/Protocol/ScsiPassThru.h:
>>>>
>>>> @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was
>>>> executed, but the
>>>> entire DataBuffer could not be
>>>> transferred.
>>>> The actual number of bytes
>>>> transferred is returned
>>>> in TransferLength. See
>>>> HostAdapterStatus,
>>>> TargetStatus, SenseDataLength,
>>>> and
>>>> SenseData in
>>>> that order for additional status
>>>> information.
>>>>
>>>> So I don't know who to believe... It does seem to me that this
>>>> documentation in the code makes more sense
>>>> and then my current code is correct. What do you think?
>>> You are looking at the wrong protocol header file.
>> Oops. You are right.
>>> The top of this
>>> header file bears the comment
>>>
>>> SCSI Pass Through protocol as defined in EFI 1.1.
>>>
>>> and the UEFI-2.8 spec does not define EFI_SCSI_PASS_THRU_PROTOCOL; it
>>> only refers to Mantis ticket 845
>>> <https://urldefense.com/v3/__https://mantis.uefi.org/mantis/view.php?id=845__;!!GqivPVa7Brio!M5o2BC3kQvh7gEgQh98Kb7YJeFCM_ajknF8iRXjDer3Ir8hUy6dHOReS12oCRvE$
>>> > with subject
>>> "EFI_SCSI_PASS_THRU_PROTOCOL replacement".
>>>
>>> Instead, please consult EFI_EXT_SCSI_PASS_THRU_PASSTHRU in
>>> "MdePkg/Include/Protocol/ScsiPassThruExt.h". There, the
>>> EFI_BAD_BUFFER_SIZE return value conforms to the UEFI 2.8 spec ("The
>>> SCSI Request Packet was not executed").
>>
>> Honestly, I'm not sure if this is not a bug in UEFI-2.8 spec and
>> ScsiPassThruExt.h header file. It doesn't make sense.
>> In the new header file, there is no way for PassThru() to indicate to
>> caller that a partial data-transfer have occurred.
>> Which seems to be a quite standard functionality. Almost all SCSI
>> devices are able to return information on partial data-transfer
>> completions.
>>
>> Looking at QEMU's virtio-scsi.c virtio_scsi_command_complete()
>> implementation, we can see how it handles partial data-transfer
>> completions.
>> It sets Response->Response to VIRTIO_SCSI_S_OK and Response->Residual
>> accordingly.
>> Looking at EDK2 VirtioScsi driver, function ParseResponse(), this
>> will be handled by updating Packet->InTransferLength and
>> Packet->OutTransferLength based on Response->Residual,
>> but then setting Packet->HostAdapterStatus to
>> EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK and returning EFI_SUCCESS.
>> (In contrast to your suggestion for me to return EFI_DEVICE_ERROR in
>> this case).
>>
>> The documentation of PassThru in ScsiPassThruExt.h for EFI_SUCCESS
>> specifies:
>>
>> @retval EFI_SUCCESS The SCSI Request Packet was sent by
>> the host. For bi-directional
>> commands, InTransferLength bytes were
>> transferred from
>> InDataBuffer. For write and
>> bi-directional commands,
>> OutTransferLength bytes were
>> transferred by
>> OutDataBuffer.
>>
>> But it seems to reference the InTransferLength and OutTransferLength
>> *before* the call to PassThru().
>>
>> In contrast to old header file, ScsiPassThru.h, which for
>> EFI_BAD_BUFFER_SIZE specifies explicitly:
>>
>> @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was
>> executed, but the
>> entire DataBuffer could not be
>> transferred.
>> The actual number of bytes
>> transferred is returned
>> in TransferLength. See
>> HostAdapterStatus,
>> TargetStatus, SenseDataLength,
>> and SenseData in
>> that order for additional status
>> information.
>>
>> In addition, looking at EDK2 iSCSI ScsiPassThru driver
>> (NetworkPkg/IScsiDxe/IScsiExtScsiPassThru.c), one can see it use
>> EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
>> (Which matches the new header file ScsiPassThruExt.h and not the old
>> ScsiPassThru.h).
>> If you would have a look at how IScsiOnScsiRspRcvd() handles
>> SCSI_RSP_PDU_FLAG_BI_READ_OVERFLOW and SCSI_RSP_PDU_FLAG_OVERFLOW
>> bits, it seems to always
>> set Status to EFI_BAD_BUFFER_SIZE as I have done. After updating
>> Packet->InTransferLength / Packet->OutTransferLength.
>>
>> What do you think? Do you have any further insights? This is quite
>> confusing to me.
>>
>> -Liran
>>
> Furthermore, I have later found ScsiExecuteSCSICommand() in
> MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c to be the one that calls
> the PassThru() method.
> Looking at it's "if (ScsiIoDevice->ExtScsiSupport)" branch (Which is
> relevant to us), one can see it just simply executes the PassThru()
> device and returns.
> Examining ScsiExecuteSCSICommand() documentation specifies for
> EFI_BAD_BUFFER_SIZE:
>
> @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed,
> but the entire DataBuffer could not be
> transferred.
> The actual number of bytes transferred
> is returned
> in TransferLength. See HostAdapterStatus,
> TargetStatus, SenseDataLength, and
> SenseData in
> that order for additional status
> information.
>
> Which again seems to align to what I have done in my PvScsi driver...
>
> -Liran
>
Sorry for the spam but I think I eventually figured it out.
The call-chain in EDK2 looks like this:
ScsiDiskWriteSectors() (MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c)
ScsiDiskWrite16() (MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c)
ScsiWrite16Command() (MdePkg/Library/UefiScsiLib/UefiScsiLib.c)
ScsiExecuteSCSICommand() (MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c)
ExtScsiPassThru->PassThru()
It can be seen that:
* ScsiExecuteSCSICommand() just passes Packet to
ExtScsiPassThru->PassThru() and returns it's return value.
* ScsiWrite16Command() always updates DataLength with
Packet->OutTransferLength and returns ScsiExecuteSCSICommand() return value.
* In ScsiDiskWrite16():
** If EFI_BAD_BUFFER_SIZE is returned, NeedRetry is set to TRUE and
EFI_DEVICE_ERROR is returned.
** Otherwise, if EFI_SUCCESS is returned but HostAdapterStatus is set
to EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN, then again
NeedRetry is set to TRUE and EFI_DEVICE_ERROR is returned.
** Otherwise, just return EFI_SUCCESS to caller.
* In ScsiDiskWriteSectors() we finally see the logic we were looking for:
** If ScsiDiskWrite16() returned EFI_SUCCESS, then we break out of
retry loop and indeed take into account ByteCount. (Which was updated
from Packet->OutTransferLength).
** Otherwise, (e.g. EFI_BAD_BUFFER_SIZE was returned), if NeedRetry
is set to TRUE, then next request retry is updated to be done with
ByteCount (Which was updated from Packet->OutTransferLength).
So it seems the UEFI-2.8 spec is right and a lot of EDK2 function
documentation is out-of-date.
Therefore, I will update my code accordingly. i.e.:
1) Change PvScsi.c PopulateRequest() such that in case TransferLength is
too big for DMA communication buffer Data field, we update
TransferLength and return EFI_BAD_BUFFER_SIZE.
But in addition, for completion, we should also set
HostAdapterStatus to
EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN and TargetStatus
to EFI_EXT_SCSI_STATUS_TARGET_GOOD
and SenseDataLength to 0 as done in VirtioScsi.c PopulateRequest()
in case it returns EFI_BAD_BUFFER_SIZE.
2) Change PvScsi.c HandleResponse() such that:
** If device returned PvScsiBtStatDataUnderrun: Update TransferLength
with Response->DataLen, set HostAdapterStatus to
EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN and return
EFI_SUCCESS.
** If device returned PvScsiBtStatDatarun: Just set HostAdapterStatus
to EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN and return
EFI_SUCCESS.
Regards,
-Liran
next prev parent reply other threads:[~2020-03-28 19:18 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-25 16:09 [PATCH v2 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
2020-03-25 16:09 ` [PATCH v2 01/17] OvmfPkg/PvScsiDxe: Create empty driver Liran Alon
2020-03-26 14:44 ` [edk2-devel] " Laszlo Ersek
2020-03-25 16:09 ` [PATCH v2 02/17] OvmfPkg/PvScsiDxe: Install DriverBinding protocol Liran Alon
2020-03-25 16:09 ` [PATCH v2 03/17] OvmfPkg/PvScsiDxe: Report name of driver Liran Alon
2020-03-25 16:09 ` [PATCH v2 04/17] OvmfPkg/PvScsiDxe: Probe PCI devices and look for PvScsi Liran Alon
2020-03-25 16:09 ` [PATCH v2 05/17] OvmfPkg/PvScsiDxe: Install stubbed EXT_SCSI_PASS_THRU Liran Alon
2020-03-25 16:09 ` [PATCH v2 06/17] OvmfPkg/PvScsiDxe: Report the number of targets and LUNs Liran Alon
2020-03-25 16:09 ` [PATCH v2 07/17] OvmfPkg/PvScsiDxe: Translate Target & LUN to/from DevicePath Liran Alon
2020-03-25 16:09 ` [PATCH v2 08/17] OvmfPkg/PvScsiDxe: Open PciIo protocol for later use Liran Alon
2020-03-25 16:09 ` [PATCH v2 09/17] OvmfPkg/PvScsiDxe: Backup/Restore PCI attributes on Init/UnInit Liran Alon
2020-03-26 17:04 ` [edk2-devel] " Laszlo Ersek
2020-03-25 16:09 ` [PATCH v2 10/17] OvmfPkg/PvScsiDxe: Enable MMIO-Space & Bus-Mastering in PCI attributes Liran Alon
2020-03-26 17:12 ` Laszlo Ersek
2020-03-25 16:09 ` [PATCH v2 11/17] OvmfPkg/PvScsiDxe: Define device interface structures and constants Liran Alon
2020-03-26 17:19 ` [edk2-devel] " Laszlo Ersek
2020-03-25 16:10 ` [PATCH v2 12/17] OvmfPkg/PvScsiDxe: Reset adapter on init Liran Alon
2020-03-26 18:25 ` [edk2-devel] " Laszlo Ersek
2020-03-25 16:10 ` [PATCH v2 13/17] OvmfPkg/PvScsiDxe: Setup requests and completions rings Liran Alon
2020-03-26 20:51 ` Laszlo Ersek
2020-03-25 16:10 ` [PATCH v2 14/17] OvmfPkg/PvScsiDxe: Introduce DMA communication buffer Liran Alon
2020-03-26 22:17 ` Laszlo Ersek
2020-03-27 0:05 ` Liran Alon
2020-03-27 13:35 ` Laszlo Ersek
2020-03-27 21:31 ` Liran Alon
2020-03-30 11:29 ` Laszlo Ersek
2020-03-25 16:10 ` [PATCH v2 15/17] OvmfPkg/PvScsiDxe: Support sending SCSI request and receive response Liran Alon
2020-03-27 11:26 ` [edk2-devel] " Laszlo Ersek
2020-03-27 13:04 ` Liran Alon
2020-03-27 13:20 ` Liran Alon
2020-03-27 21:05 ` Laszlo Ersek
2020-03-27 21:05 ` Laszlo Ersek
2020-03-27 22:04 ` Liran Alon
2020-03-27 22:17 ` Liran Alon
2020-03-28 19:18 ` Liran Alon [this message]
2020-03-30 11:23 ` Laszlo Ersek
2020-03-30 11:12 ` Laszlo Ersek
2020-03-30 10:30 ` Laszlo Ersek
2020-03-25 16:10 ` [PATCH v2 16/17] OvmfPkg/PvScsiDxe: Reset device on ExitBootServices() Liran Alon
2020-03-25 16:10 ` [PATCH v2 17/17] OvmfPkg/PvScsiDxe: Enable device 64-bit DMA addresses Liran Alon
2020-03-26 22:29 ` [edk2-devel] " Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9bbdb66f-9fdb-bd5a-74b8-6dc31015dc8a@oracle.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox