summaryrefslogtreecommitdiff
path: root/drivers/ata/libata-eh.c
AgeCommit message (Collapse)Author
2025-07-16ata: libata-eh: Simplify reset operation managementDamien Le Moal
Introduce struct ata_reset_operations to aggregate in a single structure the definitions of the 4 reset methods (prereset, softreset, hardreset and postreset) for a port. This new structure is used in struct ata_port to define the reset methods for a regular port (reset field) and for a port-multiplier port (pmp_reset field). A pointer to either of these fields replaces the 4 reset method arguments passed to ata_eh_recover() and ata_eh_reset(). The definition of the reset methods for all drivers is changed to use the reset and pmp_reset fields in struct ata_port_operations. A large number of files is modifed, but no functional changes are introduced. Suggested-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Link: https://lore.kernel.org/r/20250716020315.235457-3-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
2025-07-16ata: libata-eh: Remove ata_do_eh()Damien Le Moal
The only reason for ata_do_eh() to exist is that the two caller sites, ata_std_error_handler() and ata_sff_error_handler() may pass it a NULL hardreset operation so that the built-in (generic) hardreset operation for a driver is ignored if the adapter SCR access is not available. However, ata_std_error_handler() and ata_sff_error_handler() modifications of the hardreset port operation can easily be combined as they are mutually exclusive. That is, a driver using sata_std_hardreset() as its hardreset operation cannot use sata_sff_hardreset() and vice-versa. With this observation, ata_do_eh() can be removed and its code moved to ata_std_error_handler(). The condition used to ignore the built-in hardreset port operation is modified to be the one that was used in ata_sff_error_handler(). This requires defining a stub for the function sata_sff_hardreset() to avoid compilation errors when CONFIG_ATA_SFF is not enabled. Furthermore, instead of modifying the local hardreset operation definition, set the ATA_LFLAG_NO_HRST link flag to prevent the use of built-in hardreset methods for ports without a valid scr_read function. This flag is checked in ata_eh_reset() and if set, the hardreset method is ignored. This change simplifies ata_sff_error_handler() as this function now only needs to call ata_std_error_handler(). No functional changes. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Link: https://lore.kernel.org/r/20250716020315.235457-2-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
2025-07-11ata: libata-eh: Make ata_eh_followup_srst_needed() return a boolDamien Le Moal
ata_eh_followup_srst_needed() returns an integer used as a boolean. So change this function to return that type. No functional changes. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Niklas Cassel <cassel@kernel.org> Link: https://lore.kernel.org/r/20250711082158.220047-1-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
2025-07-07ata: libata-eh: use bool for fastdrain in ata_eh_set_pending()Damien Le Moal
Use the bool type for the fastdrain argument of ata_eh_set_pending(), as it should be. No functional changes. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Link: https://lore.kernel.org/r/20250704104552.310630-1-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
2025-07-07ata: libata: Introduce ata_port_eh_scheduled()Damien Le Moal
Introduce the inline helper function ata_port_eh_scheduled() to test if EH is pending (ATA_PFLAG_EH_PENDING port flag is set) or running (ATA_PFLAG_EH_IN_PROGRESS port flag is set) for a port. Use this helper in ata_port_wait_eh() and __ata_scsi_queuecmd() to replace the hardcoded port flag tests. No functional changes. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Link: https://lore.kernel.org/r/20250704104601.310643-1-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
2025-07-04ata: libata-core: Rename ata_do_set_mode()Damien Le Moal
With the renaming of libata-eh ata_set_mode() function to ata_eh_set_mode(), libata-core function ata_do_set_mode() can now be renamed to the simpler ata_set_mode(). All the call sites of the former ata_do_set_mode() are updated to use the new function name. No functional changes. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Link: https://lore.kernel.org/r/20250703103622.291272-5-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
2025-07-04ata: libata-eh: Rename and make ata_set_mode() staticDamien Le Moal
The function ata_set_mode() is defined and used only in libata-eh.c. Make this function static and rename it ata_eh_set_mode() to make it clear where its definition is. No functional changes. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Link: https://lore.kernel.org/r/20250703103622.291272-4-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
2025-07-02ata: libata_eh: Add debug messages to ata_eh_link_set_lpm()Damien Le Moal
To facilitate field debugging of link power management related issues, add a debug message to ata_eh_link_set_lpm() to easily track LPM policy changes done from EH context, that is, during device scan and revalidation, error handling, and when a policy change is issued through a host sysfs link_power_management_policy attribute. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Link: https://lore.kernel.org/r/20250701125321.69496-11-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
2025-07-02ata: libata-eh: Avoid unnecessary resets when revalidating devicesDamien Le Moal
In ata_eh_revalidate_and_attach(), a link LPM policy is always set to ATA_LPM_MAX_POWER before calling ata_dev_revalidate() to ensure that the call to ata_phys_link_offline() does not return true, thus causing an unnecessary device reset. This change was introduced with commit 71d7b6e51ad3 ("ata: libata-eh: avoid needless hard reset when revalidating link"). However, setting the link LPM policy to ATA_LPM_MAX_POWER may be visible only after some time, depending on the power state the link was in. E.g. transitioning out of the Partial state should take no longer than a few microseconds, but transitioning out of the Slumber or DevSleep state may take several milliseconds. So despite the changes introduced with commit 71d7b6e51ad3 ("ata: libata-eh: avoid needless hard reset when revalidating link"), we can still endup with ata_phys_link_offline() seeing a link SCR_STATUS register signaling that the device is present (DET is equal to 1h) but that the link PHY is still in a low power mode (e.g. IPM is 2h, signaling "Interface in Partial power management state"). In such cases, ata_phys_link_offline() returns true, causing an EIO return for ata_eh_revalidate_and_attach() and a device reset. Avoid such unnecessary device resets by introducing a relaxed version of the link offline test implemented by ata_phys_link_offline() with the new helper function ata_eh_link_established(). This functions returns true if for the link SCR_STATUS register we see that: - A device is still present, that is, the DET field is 1h (Device presence detected but Phy communication not established) or 3h (Device presence detected and Phy communication established). - Communication is established, that is, the IPM field is not 0h, indicating that the PHY is online or in a low power state. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Link: https://lore.kernel.org/r/20250701125321.69496-5-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
2025-06-30ata: libata-eh: Move and rename ata_eh_set_lpm()Damien Le Moal
Move the definition of the function ata_eh_set_lpm() to avoid its unnecessary forward declaration and rename the function to ata_eh_link_set_lpm() to clarify that it acts on a link. No functional changes. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Niklas Cassel <cassel@kernel.org>
2025-06-08treewide, timers: Rename from_timer() to timer_container_of()Ingo Molnar
Move this API to the canonical timer_*() namespace. [ tglx: Redone against pre rc1 ] Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/all/aB2X0jCKQO56WdMt@gmail.com
2025-05-20ata: libata-eh: Keep DIPM disabled while modifying the allowed LPM statesNiklas Cassel
Currently, it is possible that LPM is enabled while calling the set_lpm() callback. The current code performs a SET FEATURES command to disable DIPM if policy < ATA_LPM_MED_POWER_WITH_DIPM, this means that it will currently disable DIPM for policies: ATA_LPM_UNKNOWN, ATA_LPM_MAX_POWER, ATA_LPM_MED_POWER (but not for policy ATA_LPM_MED_POWER_WITH_DIPM). The code called after calling the set_lpm() callback will later perform a SET FEATURES command to enable DIPM, if policy >= ATA_LPM_MED_POWER_WITH_DIPM. As we can see DIPM will not be disabled before calling set_lpm() if the LPM policy is: ATA_LPM_MED_POWER_WITH_DIPM, ATA_LPM_MIN_POWER_WITH_PARTIAL, or ATA_LPM_MIN_POWER. Make sure that we always disable DIPM before calling the set_lpm() callback. This is because the set_lpm() callback is the function (for AHCI) that sets the proper bits in PxSCTL.IPM, reflecting the support of the HBA. PxSCTL.IPM controls the LPM states that the device is allowed to enter. If the device tries to enter a state disabled by PxSCTL.IPM, the host will NAK the transition. If we do not disable DIPM before modifying PxSCTL.IPM, it is possible that DIPM will try (and will be allowed to) enter a LPM state that the HBA does not support (since we have not yet written PxSCTL.IPM, the HBA wasn't able to NAK the transition). While at it, remove the guard of host support for DIPM around the disabling of DIPM. While it makes sense to take host support for DIPM into account when enabling DIPM, it makes zero sense to take host support into account when disabling DIPM. If the host does not support DIPM, that is an even bigger reason why DIPM should be disabled on the device side. Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2025-05-20ata: libata-eh: Rename no_dipm variable to be more clearNiklas Cassel
Rename the no_dipm variable to host_has_dipm, by inverting the expression, and and also having a clearer name. No functional change. Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2025-05-20ata: libata-eh: Rename hipm and dipm variablesNiklas Cassel
Rename the hipm and dipm variables to have a clearer name. Also fold in the usage of no_dipm, as that is required in order to give the dipm variable a more descriptive name. No functional change. Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2025-05-20ata: libata-eh: Add ata_eh_set_lpm() WARN_ON_ONCENiklas Cassel
link->lpm_policy is initialized to ATA_LPM_UNKNOWN in ata_eh_reset(). ata_eh_set_lpm() is then only called if link->lpm_policy != ap->target_lpm_policy (after reset) and then only if link->lpm_policy > ATA_LPM_MAX_POWER (before revalidation). This means that ata_eh_set_lpm() is currently never called with policy == ATA_LPM_UNKNOWN. Add a WARN_ON_ONCE so that it is more obvious from reading the code that this function is never called with policy == ATA_LPM_UNKNOWN. Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2025-05-20ata: libata-eh: Update DIPM comments to reflect realityNiklas Cassel
The comments describing which LPM policies that has DIPM enabled predates the introduction of the LPM policies ATA_LPM_MIN_POWER_WITH_PARTIAL and ATA_LPM_MED_POWER_WITH_DIPM. Update the DIPM comments to reflect reality. Also remove the sentence that claims that "Order device and link configurations such that the host always allows DIPM requests." This comment is written before 24e0e61db3cb ("ata: libata: disallow dev-initiated LPM transitions to unsupported states"). Even though the set_lpm() call is done before enabling DIPM, the host will not always allow DIPM requests. For all LPM polcies where DIPM is enabled, only DIPM requests to LPM states that are supported by the HBA will be allowed. Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2025-04-05treewide: Switch/rename to timer_delete[_sync]()Thomas Gleixner
timer_delete[_sync]() replaces del_timer[_sync](). Convert the whole tree over and remove the historical wrapper inlines. Conversion was done with coccinelle plus manual fixups where necessary. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@kernel.org>
2025-02-21ata: libata-eh: Do not use ATAPI DMA for a device limited to PIO modeNiklas Cassel
atapi_eh_request_sense() currently uses ATAPI DMA if the SATA controller has ATA_FLAG_PIO_DMA (PIO cmds via DMA) set. However, ATA_FLAG_PIO_DMA is a flag that can be set by a low-level driver on a port at initialization time, before any devices are scanned. If a controller detects a connected device that only supports PIO, we set the flag ATA_DFLAG_PIO. Modify atapi_eh_request_sense() to not use ATAPI DMA if the connected device only supports PIO. Reported-by: Philip Pemberton <lists@philpem.me.uk> Closes: https://lore.kernel.org/linux-ide/c6722ee8-5e21-4169-af59-cbbae9edc02f@philpem.me.uk/ Tested-by: Philip Pemberton <lists@philpem.me.uk> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20250221015422.20687-2-cassel@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
2024-10-24ata: libata: Set DID_TIME_OUT for commands that actually timed outNiklas Cassel
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. Commit e5dd410acb34 ("ata: libata: Clear DID_TIME_OUT for ATA PT commands with sense data") clears this bogus DID_TIME_OUT flag for all commands that reached libata's EH strategy_handler. 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. ata_eh_worth_retry() has no special handling for AC_ERR_TIMEOUT, so by default timed out commands will get flag ATA_QCFLAG_RETRY set, and will be retried after the port has been reset (ata_eh_link_autopsy() always triggers a port reset if any command has AC_ERR_TIMEOUT set). For a command that has ATA_QCFLAG_RETRY set, while also having an error flag set (e.g. AC_ERR_TIMEOUT), ata_eh_finish() will not increment scmd->allowed, so the command will at most be retried scmd->allowed number of times (which by default is set to 3). However, scsi_eh_flush_done_q() will only retry commands for which scsi_noretry_cmd() returns false. For a command that has DID_TIME_OUT set, while also having either the FAILFAST flag set, or the command being a passthrough command, scsi_noretry_cmd() will return true. Thus, such a command will never be retried. Thus, make sure that libata sets SCSI's DID_TIME_OUT flag for commands that actually timed out (libata's AC_ERR_TIMEOUT flag), such that timed out commands will once again not be retried if they are also a FAILFAST or passthrough command. Cc: stable@vger.kernel.org Fixes: e5dd410acb34 ("ata: libata: Clear DID_TIME_OUT for ATA PT commands with sense data") Reported-by: Lai, Yi <yi1.lai@linux.intel.com> Closes: https://lore.kernel.org/linux-ide/ZxYz871I3Blsi30F@ly-workstation/ Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20241023105540.1070012-2-cassel@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
2024-10-09ata: libata: avoid superfluous disk spin down + spin up during hibernationNiklas Cassel
A user reported that commit aa3998dbeb3a ("ata: libata-scsi: Disable scsi device manage_system_start_stop") introduced a spin down + immediate spin up of the disk both when entering and when resuming from hibernation. This behavior was not there before, and causes an increased latency both when entering and when resuming from hibernation. Hibernation is done by three consecutive PM events, in the following order: 1) PM_EVENT_FREEZE 2) PM_EVENT_THAW 3) PM_EVENT_HIBERNATE Commit aa3998dbeb3a ("ata: libata-scsi: Disable scsi device manage_system_start_stop") modified ata_eh_handle_port_suspend() to call ata_dev_power_set_standby() (which spins down the disk), for both event PM_EVENT_FREEZE and event PM_EVENT_HIBERNATE. Documentation/driver-api/pm/devices.rst, section "Entering Hibernation", explicitly mentions that PM_EVENT_FREEZE does not have to be put the device in a low-power state, and actually recommends not doing so. Thus, let's not spin down the disk on PM_EVENT_FREEZE. (The disk will instead be spun down during the subsequent PM_EVENT_HIBERNATE event.) This way, PM_EVENT_FREEZE will behave as it did before commit aa3998dbeb3a ("ata: libata-scsi: Disable scsi device manage_system_start_stop"), while PM_EVENT_HIBERNATE will continue to spin down the disk. This will avoid the superfluous spin down + spin up when entering and resuming from hibernation, while still making sure that the disk is spun down before actually entering hibernation. Cc: stable@vger.kernel.org # v6.6+ Fixes: aa3998dbeb3a ("ata: libata-scsi: Disable scsi device manage_system_start_stop") Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20241008135843.1266244-2-cassel@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
2024-09-11ata: libata: Clear DID_TIME_OUT for ATA PT commands with sense dataNiklas Cassel
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@google.com> Closes: https://lore.kernel.org/linux-ide/ZttIN8He8TOZ7Lct@google.com/ Signed-off-by: Niklas Cassel <cassel@kernel.org> Tested-by: Igor Pylypiv <ipylypiv@google.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2024-09-07ata: libata: Introduce ata_dev_free_resourcesDamien Le Moal
Introduce the function ata_dev_free_resources() to free the resources allocated to support a device features. For now, this function is reduced to calling zpodd_exit() for devices that have this feature enabled. ata_dev_free_resources() is called from ata_eh_dev_disable() as this function is always called for all devices attached to a port that is being detached and for devices that are being disabled due to being removed (detached) from the system or due to errors. With this change, the call to zpodd_exit() done in ata_port_detach() and ata_scsi_handle_link_detach() are removed as these functions remove all devices attached to the link or port using libata EH, thus resulting in ata_eh_dev_disable() being called and the zpodd_exit() function being executed. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org>
2024-09-07ata: libata: Move sector_buf from struct ata_port to struct ata_deviceDamien Le Moal
The 512B buffer sector_buf field of struct ata_port is used for scanning devices as well as during error recovery with ata EH. This buffer is thus useless if a port does not have a device connected to it. And also given that commands using this buffer are issued to devices, and not to ports, move this buffer definition from struct ata_port to struct ata_device. This change slightly increases system memory usage for systems using a port-multiplier as in that case we do not need a per-device buffer for scanning devices (PMP does not allow parallel scanning) nor for EH (as when entering EH we are guaranteed that all commands to all devices connected to the PMP have completed or have been aborted). However, this change reduces memory usage on systems that have many ports with only few devices rives connected, which is a much more common use case than the PMP use case. Suggested-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Niklas Cassel <cassel@kernel.org>
2024-09-07ata: libata: Rename ata_eh_read_sense_success_ncq_log()Damien Le Moal
The function ata_eh_read_sense_success_ncq_log() does more that just reading the sense data for successful NCQ commands log page as it also sets the sense data for all commands listed in the log page. Rename this function to ata_eh_get_ncq_success_sense() to better describe what the function does. Furthermore, since this function is only called from ata_eh_get_success_sense() in libata-eh.c, there is no need to export it and its declaration can be moved to drivers/ata/libata.h. To be consistent with this change, the function ata_eh_read_sense_success_non_ncq() is also renamed to ata_eh_get_non_ncq_success_sense(). Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de>
2024-08-29ata: libata: Add helper ata_eh_decide_disposition()Niklas Cassel
Every time I see libata code calling scsi_check_sense(), I get confused why the code path that is working fine for SCSI code, is not sufficient for libata code. The reason is that SCSI usually gets the sense data as part of the completion, and will thus automatically call scsi_check_sense(), which will set the SCSI ML byte (if any). However, for libata queued commands, we always need to fetch the sense data via SCSI EH, and thus do not get the luxury of having scsi_check_sense() called automatically. Add a new helper, ata_eh_decide_disposition(), that has a ata_eh_ prefix to more clearly highlight that this is only needed for code called by EH, while also having a similar name to scsi_decide_disposition(), such that it is easier to compare the libata code with the equivalent SCSI code. Also add a big kdoc comment explaining why this helper is called/needed in the first place. Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2024-03-25scsi: sd: Fix TCG OPAL unlock on system resumeDamien Le Moal
Commit 3cc2ffe5c16d ("scsi: sd: Differentiate system and runtime start/stop management") introduced the manage_system_start_stop scsi_device flag to allow libata to indicate to the SCSI disk driver that nothing should be done when resuming a disk on system resume. This change turned the execution of sd_resume() into a no-op for ATA devices on system resume. While this solved deadlock issues during device resume, this change also wrongly removed the execution of opal_unlock_from_suspend(). As a result, devices with TCG OPAL locking enabled remain locked and inaccessible after a system resume from sleep. To fix this issue, introduce the SCSI driver resume method and implement it with the sd_resume() function calling opal_unlock_from_suspend(). The former sd_resume() function is renamed to sd_resume_common() and modified to call the new sd_resume() function. For non-ATA devices, this result in no functional changes. In order for libata to explicitly execute sd_resume() when a device is resumed during system restart, the function scsi_resume_device() is introduced. libata calls this function from the revalidation work executed on devie resume, a state that is indicated with the new device flag ATA_DFLAG_RESUMING. Doing so, locked TCG OPAL enabled devices are unlocked on resume, allowing normal operation. Fixes: 3cc2ffe5c16d ("scsi: sd: Differentiate system and runtime start/stop management") Link: https://bugzilla.kernel.org/show_bug.cgi?id=218538 Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20240319071209.1179257-1-dlemoal@kernel.org Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-10-13ata: libata-eh: Spinup disk on resume after revalidationDamien Le Moal
Move the call to ata_dev_power_set_active() to transition a disk in standby power mode to the active power mode from ata_eh_revalidate_and_attach() before doing revalidation to the end of ata_eh_recover(), after the link speed for the device is reconfigured (if that was necessary). This is safer as this ensure that the VERIFY command executed to spinup the disk is executed with the drive properly reconfigured first. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
2023-10-03ata: libata-eh: Reduce "disable device" message verbosityDamien Le Moal
There is no point in warning about a device being disabled when we expect it to be, that is, on suspend, shutdown or when detaching the device. Suppress the message "disable device" for these cases by introducing the EH static function ata_eh_dev_disable() and by using it in ata_eh_unload() and ata_eh_detach_dev(). ata_dev_disable() code is modified to call this new function after printing the "disable device" message. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Tested-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-10-03ata: libata-eh: Improve reset error messagesDamien Le Moal
Some drives are really slow to spinup on resume, resulting is a very slow response to COMRESET and to error messages such as: ata1: COMRESET failed (errno=-16) ata1: link is slow to respond, please be patient (ready=0) ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300) ata1.00: configured for UDMA/133 Given that the slowness of the response is indicated with the message "link is slow to respond..." and that resets are retried until the device is detected as online after up to 1min (ata_eh_reset_timeouts), there is no point in printing the "COMRESET failed" error message. Let's not scare the user with non fatal errors and only warn about reset failures in ata_eh_reset() when all reset retries have been exhausted. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Tested-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-09-28ata: libata-eh: Fix compilation warning in ata_eh_link_report()Damien Le Moal
The 6 bytes length of the tries_buf string in ata_eh_link_report() is too short and results in a gcc compilation warning with W-!: drivers/ata/libata-eh.c: In function ‘ata_eh_link_report’: drivers/ata/libata-eh.c:2371:59: warning: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size 4 [-Wformat-truncation=] 2371 | snprintf(tries_buf, sizeof(tries_buf), " t%d", | ^~ drivers/ata/libata-eh.c:2371:56: note: directive argument in the range [-2147483648, 4] 2371 | snprintf(tries_buf, sizeof(tries_buf), " t%d", | ^~~~~~ drivers/ata/libata-eh.c:2371:17: note: ‘snprintf’ output between 4 and 14 bytes into a destination of size 6 2371 | snprintf(tries_buf, sizeof(tries_buf), " t%d", | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2372 | ap->eh_tries); | ~~~~~~~~~~~~~ Avoid this warning by increasing the string size to 16B. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-09-28ata: libata-scsi: Disable scsi device manage_system_start_stopDamien Le Moal
The introduction of a device link to create a consumer/supplier relationship between the scsi device of an ATA device and the ATA port of that ATA device fixes the ordering of system suspend and resume operations. For suspend, the scsi device is suspended first and the ata port after it. This is fine as this allows the synchronize cache and START STOP UNIT commands issued by the scsi disk driver to be executed before the ata port is disabled. For resume operations, the ata port is resumed first, followed by the scsi device. This allows having the request queue of the scsi device to be unfrozen after the ata port resume is scheduled in EH, thus avoiding to see new requests prematurely issued to the ATA device. Since libata sets manage_system_start_stop to 1, the scsi disk resume operation also results in issuing a START STOP UNIT command to the device being resumed so that the device exits standby power mode. However, restoring the ATA device to the active power mode must be synchronized with libata EH processing of the port resume operation to avoid either 1) seeing the start stop unit command being received too early when the port is not yet resumed and ready to accept commands, or after the port resume process issues commands such as IDENTIFY to revalidate the device. In this last case, the risk is that the device revalidation fails with timeout errors as the drive is still spun down. Commit 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume") disabled issuing the START STOP UNIT command to avoid issues with it. But this is incorrect as transitioning a device to the active power mode from the standby power mode set on suspend requires a media access command. The IDENTIFY, READ LOG and SET FEATURES commands executed in libata EH context triggered by the ata port resume operation may thus fail. Fix these synchronization issues is by handling a device power mode transitions for system suspend and resume directly in libata EH context, without relying on the scsi disk driver management triggered with the manage_system_start_stop flag. To do this, the following libata helper functions are introduced: 1) ata_dev_power_set_standby(): This function issues a STANDBY IMMEDIATE command to transitiom a device to the standby power mode. For HDDs, this spins down the disks. This function applies only to ATA and ZAC devices and does nothing otherwise. This function also does nothing for devices that have the ATA_FLAG_NO_POWEROFF_SPINDOWN or ATA_FLAG_NO_HIBERNATE_SPINDOWN flag set. For suspend, call ata_dev_power_set_standby() in ata_eh_handle_port_suspend() before the port is disabled and frozen. ata_eh_unload() is also modified to transition all enabled devices to the standby power mode when the system is shutdown or devices removed. 2) ata_dev_power_set_active() and This function applies to ATA or ZAC devices and issues a VERIFY command for 1 sector at LBA 0 to transition the device to the active power mode. For HDDs, since this function will complete only once the disk spin up. Its execution uses the same timeouts as for reset, to give the drive enough time to complete spinup without triggering a command timeout. For resume, call ata_dev_power_set_active() in ata_eh_revalidate_and_attach() after the port has been enabled and before any other command is issued to the device. With these changes, the manage_system_start_stop and no_start_on_resume scsi device flags do not need to be set in ata_scsi_dev_config(). The flag manage_runtime_start_stop is still set to allow the sd driver to spinup/spindown a disk through the sd runtime operations. Fixes: 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-09-16ata: libata-eh: do not thaw the port twice in ata_eh_reset()Niklas Cassel
commit 1e641060c4b5 ("libata: clear eh_info on reset completion") added a workaround that broke the retry mechanism in ATA EH. Tejun himself suggested to remove this workaround when it was identified to cause additional problems: https://lore.kernel.org/linux-ide/20110426135027.GI878@htj.dyndns.org/ He even said: "Hmm... it seems I wasn't thinking straight when I added that work around." https://lore.kernel.org/linux-ide/20110426155229.GM878@htj.dyndns.org/ While removing the workaround solved the issue, however, the workaround was kept to avoid "spurious hotplug events during reset", and instead another workaround was added on top of the existing workaround in commit 8c56cacc724c ("libata: fix unexpectedly frozen port after ata_eh_reset()"). Because these IRQs happened when the port was frozen, we know that they were actually a side effect of PxIS and IS.IPS(x) not being cleared before the COMRESET. This is now done in commit 94152042eaa9 ("ata: libahci: clear pending interrupt status"), so these workarounds can now be removed. Since commit 1e641060c4b5 ("libata: clear eh_info on reset completion") has now been reverted, the ATA EH retry mechanism is functional again, so there is once again no need to thaw the port more than once in ata_eh_reset(). This reverts "the workaround on top of the workaround" introduced in commit 8c56cacc724c ("libata: fix unexpectedly frozen port after ata_eh_reset()"). Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2023-09-16ata: libata-eh: do not clear ATA_PFLAG_EH_PENDING in ata_eh_reset()Niklas Cassel
ata_scsi_port_error_handler() starts off by clearing ATA_PFLAG_EH_PENDING, before calling ap->ops->error_handler() (without holding the ap->lock). If an error IRQ is received while ap->ops->error_handler() is running, the irq handler will set ATA_PFLAG_EH_PENDING. Once ap->ops->error_handler() returns, ata_scsi_port_error_handler() checks if ATA_PFLAG_EH_PENDING is set, and if it is, another iteration of ATA EH is performed. The problem is that ATA_PFLAG_EH_PENDING is not only cleared by ata_scsi_port_error_handler(), it is also cleared by ata_eh_reset(). ata_eh_reset() is called by ap->ops->error_handler(). This additional clearing done by ata_eh_reset() breaks the whole retry logic in ata_scsi_port_error_handler(). Thus, if an error IRQ is received while ap->ops->error_handler() is running, the port will currently remain frozen and will never get re-enabled. The additional clearing in ata_eh_reset() was introduced in commit 1e641060c4b5 ("libata: clear eh_info on reset completion"). Looking at the original error report: https://marc.info/?l=linux-ide&m=124765325828495&w=2 We can see the following happening: [ 1.074659] ata3: XXX port freeze [ 1.074700] ata3: XXX hardresetting link, stopping engine [ 1.074746] ata3: XXX flipping SControl [ 1.411471] ata3: XXX irq_stat=400040 CONN|PHY [ 1.411475] ata3: XXX port freeze [ 1.420049] ata3: XXX starting engine [ 1.420096] ata3: XXX rc=0, class=1 [ 1.420142] ata3: XXX clearing IRQs for thawing [ 1.420188] ata3: XXX port thawed [ 1.420234] ata3: SATA link up 3.0 Gbps (SStatus 123 SControl 300) We are not supposed to be able to receive an error IRQ while the port is frozen (PxIE is set to 0, i.e. all IRQs for the port are disabled). AHCI 1.3.1 section 10.7.1.1 First Tier (IS Register) states: "Each bit location can be thought of as reporting a '1' if the virtual "interrupt line" for that port is indicating it wishes to generate an interrupt. That is, if a port has one or more interrupt status bit set, and the enables for those status bits are set, then this bit shall be set." Additionally, AHCI state P:ComInit clearly shows that the state machine will only jump to P:ComInitSetIS (which sets IS.IPS(x) to '1'), if PxIE.PCE is set to '1'. In our case, PxIE is set to 0, so IS.IPS(x) won't get set. So IS.IPS(x) only gets set if PxIS and PxIE is set. AHCI 1.3.1 section 10.7.1.1 First Tier (IS Register) also states: "The bits in this register are read/write clear. It is set by the level of the virtual interrupt line being a set, and cleared by a write of '1' from the software." So if IS.IPS(x) is set, you need to explicitly clear it by writing a 1 to IS.IPS(x) for that port. Since PxIE is cleared, the only way to get an interrupt while the port is frozen, is if IS.IPS(x) is set, and the only way IS.IPS(x) can be set when the port is frozen, is if it was set before the port was frozen. However, since commit 737dd811a3db ("ata: libahci: clear pending interrupt status"), we clear both PxIS and IS.IPS(x) after freezing the port, but before the COMRESET, so the problem that commit 1e641060c4b5 ("libata: clear eh_info on reset completion") fixed can no longer happen. Thus, revert commit 1e641060c4b5 ("libata: clear eh_info on reset completion"), so that the retry logic in ata_scsi_port_error_handler() works once again. (The retry logic is still needed, since we can still get an error IRQ _after_ the port has been thawed, but before ata_scsi_port_error_handler() takes the ap->lock in order to check if ATA_PFLAG_EH_PENDING is set.) Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2023-08-02ata: libata: remove references to non-existing error_handler()Hannes Reinecke
With commit 65a15d6560df ("scsi: ipr: Remove SATA support") all libata drivers now have the error_handler() callback provided, so we can stop checking for non-existing error_handler callback. Signed-off-by: Hannes Reinecke <hare@suse.de> [niklas: fixed review comments, rebased, solved conflicts during rebase, fixed bug that unconditionally dumped all QCs, removed the now unused function ata_dump_status(), removed the now unreachable failure paths in atapi_qc_complete(), removed the non-EH function to request ATAPI sense] Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Reviewed-by: John Garry <john.g.garry@oracle.com> Reviewed-by: Jason Yan <yanaijie@huawei.com> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2023-08-02ata: libata-eh: fix reset timeout typeSergey Shtylyov
ata_eh_reset_timeouts[] stores 'unsigned long' timeouts in ms, while ata_eh_reset() passes these values to ata_deadline() that takes just 'unsigned int timeout_msecs' parameter. Change the reset timeout table element's type to 'unsigned int' -- all timeouts fit into 'unsigned int' but we have to change ULONG_MAX to UINT_MAX... Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2023-06-30Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsiLinus Torvalds
Pull SCSI updates from James Bottomley: "Updates to the usual drivers (ufs, pm80xx, libata-scsi, smartpqi, lpfc, qla2xxx). We have a couple of major core changes impacting other systems: - Command Duration Limits, which spills into block and ATA - block level Persistent Reservation Operations, which touches block, nvme, target and dm Both of these are added with merge commits containing a cover letter explaining what's going on" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (187 commits) scsi: core: Improve warning message in scsi_device_block() scsi: core: Replace scsi_target_block() with scsi_block_targets() scsi: core: Don't wait for quiesce in scsi_device_block() scsi: core: Don't wait for quiesce in scsi_stop_queue() scsi: core: Merge scsi_internal_device_block() and device_block() scsi: sg: Increase number of devices scsi: bsg: Increase number of devices scsi: qla2xxx: Remove unused nvme_ls_waitq wait queue scsi: ufs: ufs-pci: Add support for Intel Arrow Lake scsi: sd: sd_zbc: Use PAGE_SECTORS_SHIFT scsi: ufs: wb: Add explicit flush_threshold sysfs attribute scsi: ufs: ufs-qcom: Switch to the new ICE API scsi: ufs: dt-bindings: qcom: Add ICE phandle scsi: ufs: ufs-mediatek: Set UFSHCD_QUIRK_MCQ_BROKEN_RTC quirk scsi: ufs: ufs-mediatek: Set UFSHCD_QUIRK_MCQ_BROKEN_INTR quirk scsi: ufs: core: Add host quirk UFSHCD_QUIRK_MCQ_BROKEN_RTC scsi: ufs: core: Add host quirk UFSHCD_QUIRK_MCQ_BROKEN_INTR scsi: ufs: core: Remove dedicated hwq for dev command scsi: ufs: core: mcq: Fix the incorrect OCS value for the device command scsi: ufs: dt-bindings: samsung,exynos: Drop unneeded quotes ...
2023-06-30Merge tag 'ata-6.5-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata Pull ata updates from Damien Le Moal: - Add support for the .remove_new callback to the ata_platform code to simplify device removal interface (Uwe) - Code simplification in ata_dev_revalidate() (Yahu) - Fix code indentation and coding style in the pata_parport protocol modules to avoid warnings from static code analyzers (me) - Clarify ata_eh_qc_retry() behavior with better comments (Niklas) - Simplify and improve ata_change_queue_depth() behavior to have a consistent behavior between libsas managed devices and libata managed devices (e.g. AHCI connected devices) (me) - Cleanup libata-scsi and libata-eh code to use the ata_ncq_enabled() and ata_ncq_supported() helpers instead of open coding flags tests (me) - Cleanup ahci_reset_controller() code (me) - Change the pata_octeon_cf and sata_svw drivers to use of_property_read_reg() to simplify the code (Rob, me) - Remove unnecessary include files from ahci_octeon driver (me) - Modify the DesignWare ahci dt bindings to add support for the Rockchip RK3588 AHCI (Sebastian) * tag 'ata-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata: (29 commits) dt-bindings: phy: rockchip: rk3588 has two reset lines dt-bindings: ata: dwc-ahci: add Rockchip RK3588 dt-bindings: ata: dwc-ahci: add PHY clocks ata: ahci_octeon: Remove unnecessary include ata: pata_octeon_cf: Add missing header include ata: ahci: Cleanup ahci_reset_controller() ata: Use of_property_read_reg() to parse "reg" ata: libata-scsi: Use ata_ncq_supported in ata_scsi_dev_config() ata: libata-eh: Use ata_ncq_enabled() in ata_eh_speed_down() ata: libata-sata: Improve ata_change_queue_depth() ata: libata-sata: Simplify ata_change_queue_depth() ata: libata-eh: Clarify ata_eh_qc_retry() behavior at call site ata: pata_parport: Fix on26 module code indentation and style ata: pata_parport: Fix on20 module code indentation and style ata: pata_parport: Fix ktti module code indentation and style ata: pata_parport: Fix kbic module code indentation and style ata: pata_parport: Fix friq module code indentation and style ata: pata_parport: Fix fit3 module code indentation and style ata: pata_parport: Fix fit2 module code indentation and style ata: pata_parport: Fix epia module code indentation and style ...
2023-06-18ata: libata-scsi: Avoid deadlock on rescan after device resumeDamien Le Moal
When an ATA port is resumed from sleep, the port is reset and a power management request issued to libata EH to reset the port and rescanning the device(s) attached to the port. Device rescanning is done by scheduling an ata_scsi_dev_rescan() work, which will execute scsi_rescan_device(). However, scsi_rescan_device() takes the generic device lock, which is also taken by dpm_resume() when the SCSI device is resumed as well. If a device rescan execution starts before the completion of the SCSI device resume, the rcu locking used to refresh the cached VPD pages of the device, combined with the generic device locking from scsi_rescan_device() and from dpm_resume() can cause a deadlock. Avoid this situation by changing struct ata_port scsi_rescan_task to be a delayed work instead of a simple work_struct. ata_scsi_dev_rescan() is modified to check if the SCSI device associated with the ATA device that must be rescanned is not suspended. If the SCSI device is still suspended, ata_scsi_dev_rescan() returns early and reschedule itself for execution after an arbitrary delay of 5ms. Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com> Reported-by: Joe Breuer <linux-kernel@jmbreuer.net> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217530 Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management") Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com> Tested-by: Joe Breuer <linux-kernel@jmbreuer.net>
2023-06-05ata: libata-eh: Use ata_ncq_enabled() in ata_eh_speed_down()Damien Le Moal
In ata_eh_speed_down(), instead of hard-coding the test on the device flags to detect if NCQ is supported and enabled, use ata_ncq_enabled(). Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: John Garry <john.g.garry@oracle.com>
2023-06-01ata: libata-eh: Clarify ata_eh_qc_retry() behavior at call siteNiklas Cassel
While the function documentation for ata_eh_qc_retry() is clear, from simply reading the single function that calls ata_eh_qc_retry(), it is not clear that ata_eh_qc_retry() might not retry the command. Add a comment in the single function that calls ata_eh_qc_retry() to clarify the behavior. [Damien] Added curly braces to "if () else" with multi-line comment. Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
2023-05-22scsi: ata: libata: Handle completion of CDL commands using policy 0xDNiklas Cassel
A CDL timeout for policy 0xF is defined as a NCQ error, just with a CDL specific sk/asc/ascq in the sense data. Therefore, the existing code in libata does not need to be modified to handle a policy 0xF CDL timeout. For Command Duration Limits policy 0xD: The device shall complete the command without error with the additional sense code set to DATA CURRENTLY UNAVAILABLE. Since a CDL timeout for policy 0xD is not an error, we cannot use the NCQ Command Error log (10h). Instead, we need to read the Sense Data for Successful NCQ Commands log (0Fh). In the success case, just like in the error case, we cannot simply read a log page from the interrupt handler itself, since reading a log page involves sending a READ LOG DMA EXT or READ LOG EXT command. Therefore, we add a new EH action ATA_EH_GET_SUCCESS_SENSE. When a command completes without error, and when the ATA_SENSE bit is set, this new action is set as pending, and EH is scheduled. This way, similar to the NCQ error case, the log page will be read from EH context. An alternative would have been to add a new kthread or workqueue to handle this. However, extending EH can be done with minimal changes and avoids the need to synchronize a new kthread/workqueue with EH. Co-developed-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Link: https://lore.kernel.org/r/20230511011356.227789-20-nks@flawful.org Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-05-22scsi: ata: libata: Change ata_eh_request_sense() to not set CHECK_CONDITIONNiklas Cassel
Currently, ata_eh_request_sense() unconditionally sets the scsicmd->result to SAM_STAT_CHECK_CONDITION. For Command Duration Limits policy 0xD: The device shall complete the command without error (SAM_STAT_GOOD) with the additional sense code set to DATA CURRENTLY UNAVAILABLE. It is perfectly fine to have sense data for a command that returned completion without error. In order to support for CDL policy 0xD, we have to remove this assumption that having sense data means that the command failed (SAM_STAT_CHECK_CONDITION). Change ata_eh_request_sense() to not set SAM_STAT_CHECK_CONDITION, and instead move the setting of SAM_STAT_CHECK_CONDITION to the single caller that wants SAM_STAT_CHECK_CONDITION set, that way ata_eh_request_sense() can be reused in a follow-up patch that adds support for CDL policy 0xD. The only caller of ata_eh_request_sense() is protected by: if (!(qc->flags & ATA_QCFLAG_SENSE_VALID)), so we can remove this duplicated check from ata_eh_request_sense() itself. Additionally, ata_eh_request_sense() is only called from ata_eh_analyze_tf(), which is only called when iteratating the QCs using ata_qc_for_each_raw(), which does not include the internal tag, so cmd can never be NULL (all non-internal commands have qc->scsicmd set), so remove the !cmd check as well. Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Link: https://lore.kernel.org/r/20230511011356.227789-14-nks@flawful.org Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2023-01-04ata: scsi: rename flag ATA_QCFLAG_FAILED to ATA_QCFLAG_EHNiklas Cassel
The name ATA_QCFLAG_FAILED is misleading since it does not mean that a QC completed in error, or that it didn't complete at all. It means that libata decided to schedule EH for the QC, so the QC is now owned by the libata error handler (EH). The normal execution path is responsible for not accessing a QC owned by EH. libata core enforces the rule by returning NULL from ata_qc_from_tag() for QCs owned by EH. It is quite easy to mistake that a QC marked with ATA_QCFLAG_FAILED was an error. However, a QC that was actually an error is instead indicated by having qc->err_mask set. E.g. when we have a NCQ error, we abort all QCs, which currently will mark all QCs as ATA_QCFLAG_FAILED. However, it will only be a single QC that is an error (i.e. has qc->err_mask set). Rename ATA_QCFLAG_FAILED to ATA_QCFLAG_EH to more clearly highlight that this flag simply means that a QC is now owned by EH. This new name will not mislead to think that the QC was an error (which is instead indicated by having qc->err_mask set). This also makes it more obvious that the EH code skips all QCs that do not have ATA_QCFLAG_EH set (rather than ATA_QCFLAG_FAILED), since the EH code should simply only care about QCs that are owned by EH itself. Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Reviewed-by: John Garry <john.g.garry@oracle.com> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2023-01-04ata: libata-eh: Cleanup ata_scsi_cmd_error_handler()Wenchao Hao
If ap->ops->error_handler is NULL just return. This patch also fixes some comment style issue. Signed-off-by: Wenchao Hao <haowenchao@huawei.com> Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2022-11-19ata: libata: fix commands incorrectly not getting retried during NCQ errorNiklas Cassel
A NCQ error means that the device has aborted processing of all active commands. To get the single NCQ command that caused the NCQ error, host software has to read the NCQ error log, which also takes the device out of error state. When the device encounters a NCQ error, we receive an error interrupt from the HBA, and call ata_do_link_abort() to mark all outstanding commands on the link as ATA_QCFLAG_FAILED (which means that these commands are owned by libata EH), and then call ata_qc_complete() on them. ata_qc_complete() will call fill_result_tf() for all commands marked as ATA_QCFLAG_FAILED. The taskfile is simply the latest status/error as seen from the device's perspective. The taskfile will have ATA_ERR set in the status field and ATA_ABORTED set in the error field. When we fill the current taskfile values for all outstanding commands, that means that qc->result_tf will have ATA_ERR set for all commands owned by libata EH. When ata_eh_link_autopsy() later analyzes all commands owned by libata EH, it will call ata_eh_analyze_tf(), which will check if qc->result_tf has ATA_ERR set, if it does, it will set qc->err_mask (which marks the command as an error). When ata_eh_finish() later calls __ata_qc_complete() on all commands owned by libata EH, it will call qc->complete_fn() (ata_scsi_qc_complete()), ata_scsi_qc_complete() will call ata_gen_ata_sense() to generate sense data if qc->err_mask is set. This means that we will generate sense data for commands that should not have any sense data set. Having sense data set for the non-failed commands will cause SCSI to finish these commands instead of retrying them. While this incorrect behavior has existed for a long time, this first became a problem once we started reading the correct taskfile register in commit 4ba09d202657 ("ata: libahci: read correct status and error field for NCQ commands"). Before this commit, NCQ commands would read the taskfile values received from the last non-NCQ command completion, which most likely did not have ATA_ERR set, since the last non-NCQ command was most likely not an error. Fix this by changing ata_eh_analyze_ncq_error() to mark all non-failed commands as ATA_QCFLAG_RETRY, and change the loop in ata_eh_link_autopsy() to skip commands marked as ATA_QCFLAG_RETRY. While at it, make sure that we clear ATA_ERR and any error bits for all commands except the actual command that caused the NCQ error, so that no other libata code will be able to misinterpret these commands as errors. Fixes: 4ba09d202657 ("ata: libahci: read correct status and error field for NCQ commands") Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2022-10-18ata: make use of ata_port_is_frozen() helperNiklas Cassel
Clean up the code by making use of the newly introduced ata_port_is_frozen() helper function. Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2022-10-17ata: libata: fetch sense data for ATA devices supporting sense reportingNiklas Cassel
Currently, the sense data reporting feature set is enabled for all ATA devices which supports the feature set (ata_id_has_sense_reporting()), see ata_dev_config_sense_reporting(). However, even if sense data reporting is enabled, and the device indicates that sense data is available, the sense data is only fetched for ATA ZAC devices. For regular ATA devices, the available sense data is never fetched, it is simply ignored. Instead, libata will use the ERROR + STATUS fields and map them to a very generic and reduced set of sense data, see ata_gen_ata_sense() and ata_to_sense_error(). When sense data reporting was first implemented, regular ATA devices did fetch the sense data from the device. However, this was restricted to only ATA ZAC devices in commit ca156e006add ("libata: don't request sense data on !ZAC ATA devices"). With recent changes related to sense data and NCQ autosense, we want to, once again, fetch the sense data for all ATA devices supporting sense reporting. ata_gen_ata_sense() should only be used for devices that don't support the sense data reporting feature set. hopefully the features will be more robust this time around. It is not just ZAC, many new ATA features, e.g. Command Duration Limits, relies on working NCQ autosense and sense data. Therefore, it is not really an option to avoid fetching the sense data forever. If we encounter a device that is misbehaving because the sense data is actually fetched, then that device should be quirked such that it never enables the sense data reporting feature set in the first place, since such a device is obviously not compliant with the specification. The order in which we will try to add sense data to a scsi_cmnd: 1) NCQ autosense (if supported) - ata_eh_analyze_ncq_error() 2) REQUEST SENSE DATA EXT (if supported) - ata_eh_request_sense() 3) error + status field translation - ata_gen_ata_sense(), called by ata_scsi_qc_complete() if neither 1) or 2) is supported. Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2022-10-17ata: libata: only set sense valid flag if sense data is validNiklas Cassel
While this shouldn't be needed if all devices that claim that they support NCQ autosense (ata_id_has_ncq_autosense()) and/or the sense data reporting feature (ata_id_has_sense_reporting()), actually supported those features. However, there might be some old ATA devices that either have these bits set, even when they don't support those features, or they simply return malformed data when using those features. These devices should be quirked, but in order to try to minimize the impact for the users of these such devices, it was suggested by Damien Le Moal that it might be a good idea to sanity check the sense data received from the device. If the sense data looks bogus, then the sense data is never added to the scsi_cmnd command. Introduce a new function, ata_scsi_sense_is_valid(), and use it in all places where sense data is received from the device. Suggested-by: Damien Le Moal <damien.lemoal@opensource.wdc.com> Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2022-10-17ata: libata: clarify when ata_eh_request_sense() will be calledNiklas Cassel
ata_eh_request_sense() returns early when flag ATA_QCFLAG_SENSE_VALID is set. However, since the call to ata_eh_request_sense() is guarded by a ATA_SENSE bit conditional, the logical conclusion for the reader is that all checks are performed at the call site. Highlight the fact that the sense data will not be fetched if flag ATA_QCFLAG_SENSE_VALID is already set by adding an additional check to the existing guarding conditional. No functional change. Additionally, add a comment explaining that ata_eh_analyze_tf() will only fetch the sense data if: -It was a non-NCQ command that failed, or -It was a NCQ command that failed, but the sense data was not included in the NCQ command error log (i.e. NCQ autosense is not supported). Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
2022-10-07Merge tag 'ata-6.1-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata Pull ata updates from Damien Le Moal: - Print the timeout value for internal command failures due to a timeout (from Tomas) - Improve parameter names in ata_dev_set_feature() to clarify this function use (from Niklas) - Improve the ahci driver low power mode setting initialization to allow more flexibility for the user (from Rafael) - Several patches to remove redundant variables in libata-core, libata-eh and the pata_macio driver and to fix typos in comments (from Jinpeng, Shaomin, Ye) - Some code simplifications and macro renaming (for clarity) in various functions of libata-core (from me) - Add a missing check for a potential failure of sata_scr_read() in sata_print_link_status() (from Li) - Cleanup of libata Kconfig PATA_PLATFORM and PATA_OF_PLATFORM options (from Lukas) - Cleanups of ata dt-bindings and improvements of libahci_platform, ahci and libahci code (from Serge) - New driver for Synopsys AHCI SATA controllers, based of the generic ahci code (from Serge). One compilation warning fix is added for this driver (from me) - Several fixes to macros used to discover a drive capabilities to be consistent with the ACS specifications (from Niklas) - A couple of simplifcations to some libata functions, removing unnecessary arguments (from Niklas) - An improvements to libata-eh code to avoid unnecessary link reset when revalidating a drive after a failed command. In practice, this extra, unneeded reset, reset does not cause any arm beyond slightly slowing down error recovery (from Niklas) * tag 'ata-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata: (45 commits) ata: libata-eh: avoid needless hard reset when revalidating link ata: libata: drop superfluous ata_eh_analyze_tf() parameter ata: libata: drop superfluous ata_eh_request_sense() parameter ata: fix ata_id_has_dipm() ata: fix ata_id_has_ncq_autosense() ata: fix ata_id_has_devslp() ata: fix ata_id_sense_reporting_enabled() and ata_id_has_sense_reporting() ata: libata-eh: Remove the unneeded result variable ata: ahci_st: Enable compile test ata: ahci_st: Fix compilation warning MAINTAINERS: Add maintainers for DWC AHCI SATA driver ata: ahci-dwc: Add Baikal-T1 AHCI SATA interface support ata: ahci-dwc: Add platform-specific quirks support dt-bindings: ata: ahci: Add Baikal-T1 AHCI SATA controller DT schema ata: ahci: Add DWC AHCI SATA controller support ata: libahci_platform: Add function returning a clock-handle by id dt-bindings: ata: ahci: Add DWC AHCI SATA controller DT schema ata: ahci: Introduce firmware-specific caps initialization ata: ahci: Convert __ahci_port_base to accepting hpriv as arguments ata: libahci: Don't read AHCI version twice in the save-config method ...