On 03/28/20 20:18, Liran Alon wrote: > Sorry for the spam but I think I eventually figured it out.
It's not spam; thank you for the thorough investigation! > 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. On a tangent... Since you mention ScsiDiskWriteSectors(), let me mention commit 5abc2a70da4f ("MdeModulePkg: ScsiDiskDxe: adapt SectorCount when shortening transfers", 2015-09-10), and the related mailing list discussion (this is what I referred to before, when I mentioned that Paolo had looked at the VirtioScsiDxe code twice -- this is the second occasion, from September 2015): http://mid.mail-archive.com/1441390936-27763-1-git-send-email-lersek@redhat.com > 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. Sounds OK. > 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. OK, thanks. > 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. OK. > ** If device returned PvScsiBtStatDatarun: Just set HostAdapterStatus > to EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN and return > EFI_SUCCESS. Again I'm not familiar with PvScsiBtStatDataUnderrun / PvScsiBtStatDatarun (let alone their differences); I'm OK with this too. Thanks! Laszlo -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#56623): https://edk2.groups.io/g/devel/message/56623 Mute This Topic: https://groups.io/mt/72544127/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-