On 9/10/24 00:42, Niklas Cassel wrote: > When ata_qc_complete() schedules a command for EH using > ata_qc_schedule_eh(), blk_abort_request() will be called, which leads to > req->q->mq_ops->timeout() / scsi_timeout() being called. > > scsi_timeout(), if the LLDD has no abort handler (libata has no abort > handler), will set host byte to DID_TIME_OUT, and then call > scsi_eh_scmd_add() to add the command to EH. > > Thus, when commands first enter libata's EH strategy_handler, all the > commands that have been added to EH will have DID_TIME_OUT set. > > libata has its own flag (AC_ERR_TIMEOUT), that it sets for commands that > have not received a completion at the time of entering EH. > > Thus, libata doesn't really care about DID_TIME_OUT at all, and currently > clears the host byte at the end of EH, in ata_scsi_qc_complete(), before > scsi_eh_finish_cmd() is called. > > However, this clearing in ata_scsi_qc_complete() is currently only done > for commands that are not ATA passthrough commands. > > Since the host byte is visible in the completion that we return to user > space for ATA passthrough commands, for ATA passthrough commands that got > completed via EH (commands with sense data), the user will incorrectly see: > ATA pass-through(16): transport error: Host_status=0x03 [DID_TIME_OUT] > > Fix this by moving the clearing of the host byte (which is currently only > done for commands that are not ATA passthrough commands) from > ata_scsi_qc_complete() to the start of EH (regardless if the command is > ATA passthrough or not). > > While at it, use the proper helper function to clear the host byte, rather > than open coding the clearing. > > This will make sure that we: > -Correctly clear DID_TIME_OUT for both ATA passthrough commands and > commands that are not ATA passthrough commands. > -Do not needlessly clear the host byte for commands that did not go via EH. > ata_scsi_qc_complete() is called both for commands that are completed > normally (without going via EH), and for commands that went via EH, > however, only commands that went via EH will have DID_TIME_OUT set. > > Fixes: 24aeebbf8ea9 ("scsi: ata: libata: Change ata_eh_request_sense() to not set CHECK_CONDITION") > Reported-by: Igor Pylypiv <ipylypiv@xxxxxxxxxx> > Closes: https://lore.kernel.org/linux-ide/ZttIN8He8TOZ7Lct@xxxxxxxxxx/ > Signed-off-by: Niklas Cassel <cassel@xxxxxxxxxx> Applied to for-6.12. Thanks ! -- Damien Le Moal Western Digital Research