summaryrefslogtreecommitdiff
path: root/drivers/ata
AgeCommit message (Collapse)AuthorFilesLines
2026-03-25ata: libata-scsi: report correct sense field pointer in ata_scsiop_maint_in()Damien Le Moal1-1/+1
[ Upstream commit e6d7eba23b666d85cacee0643be280d6ce1ebffc ] Commit 4ab7bb976343 ("ata: libata-scsi: Refactor ata_scsiop_maint_in()") modified ata_scsiop_maint_in() to directly call ata_scsi_set_invalid_field() to set the field pointer of the sense data of a failed MAINTENANCE IN command. However, in the case of an invalid command format, the sense data field incorrectly indicates byte 1 of the CDB. Fix this to indicate byte 2 of the command. Reported-by: Guenter Roeck <linux@roeck-us.net> Fixes: 4ab7bb976343 ("ata: libata-scsi: Refactor ata_scsiop_maint_in()") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-03-25ata: libata-scsi: Return residual for emulated SCSI commandsDamien Le Moal1-34/+47
[ Upstream commit 5251ae224d8d3caa21b28d12408062b6e75cffad ] The function ata_scsi_rbuf_fill() used to fill the reply buffer of emulated SCSI commands always copies the ATA reply buffer (ata_scsi_rbuf) up to the size of the SCSI command buffer (the transfer length for the command), even if the reply is shorter than the SCSI command buffer. This leads to issuers of the SCSI command to always get a result without any residual (resid is always 0) despite the potentially shorter reply for the command. Modify all fill actors used by ata_scsi_rbuf_fill() to return the number of bytes filled for the reply and 0 in case of error. Using this value, add a call to scsi_set_resid() in ata_scsi_rbuf_fill() to set the correct residual for the SCSI command when the reply length is shorter than the command buffer. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20241022024537.251905-7-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Stable-dep-of: e6d7eba23b66 ("ata: libata-scsi: report correct sense field pointer in ata_scsiop_maint_in()") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-03-25ata: libata-core: disable LPM on ADATA SU680 SSDDamien Le Moal1-0/+3
commit ce5ae93d1a216680460040c7c0465a6e3b629dec upstream. ADATA SU680 SSDs suffer from NCQ read and write commands timeouts or bus errors when link power management (LPM) is enabled. Flag these devices with the ATA_QUIRK_NOLPM quirk to prevent the use of LPM and avoid these command failures. Reported-by: Mohammad Khaled Bayan <mhd.khaled.bayan@gmail.com> Closes: https://bugs.launchpad.net/ubuntu/+source/linux-hwe-6.17/+bug/2144060 Cc: stable@vger.kernel.org Tested-by: Mohammad-Khaled Bayan <mhd.khaled.bayan@gmail.com> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-03-25ata: libata-core: Disable LPM on ST1000DM010-2EP102Maximilian Pezzullo1-0/+1
commit b3b1d3ae1d87bc9398fb715c945968bf4c75a09a upstream. According to a user report, the ST1000DM010-2EP102 has problems with LPM, causing random system freezes. The drive belongs to the same BarraCuda family as the ST2000DM008-2FR102 which has the same issue. Cc: stable@vger.kernel.org Fixes: 7627a0edef54 ("ata: ahci: Drop low power policy board type") Reported-by: Filippo Baiamonte <filippo.ba03@bugzilla.kernel.org> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221163 Signed-off-by: Maximilian Pezzullo <maximilianpezzullo@gmail.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-03-25ata: libata-core: Add BRIDGE_OK quirk for QEMU drivesPedro Falcato1-0/+1
commit b92b0075ee1870f78f59ab1f7da7dbfdd718ad7a upstream. Currently, whenever you boot with a QEMU drive over an AHCI interface, you get: [ 1.632121] ata1.00: applying bridge limits This happens due to the kernel not believing the given drive is SATA, since word 93 of IDENTIFY (ATA_ID_HW_CONFIG) is non-zero. The result is a pretty severe limit in max_hw_sectors_kb, which limits our IO sizes. QEMU has set word 93 erroneously for SATA drives but does not, in any way, emulate any of these real hardware details. There is no PATA drive and no SATA cable. As such, add a BRIDGE_OK quirk for QEMU HARDDISK. Special care is taken to limit this quirk to "2.5+", to allow for fixed future versions. This results in the max_hw_sectors being limited solely by the controller interface's limits. Which, for AHCI controllers, takes it from 128KB to 32767KB. Cc: stable@vger.kernel.org Signed-off-by: Pedro Falcato <pfalcato@suse.de> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-03-13ata: libata-eh: Fix detection of deferred qc timeoutsGuenter Roeck1-1/+1
commit ee0e6e69a772d601e152e5368a1da25d656122a8 upstream. If the ata_qc_for_each_raw() loop finishes without finding a matching SCSI command for any QC, the variable qc will hold a pointer to the last element examined, which has the tag i == ATA_MAX_QUEUE - 1. This qc can match the port deferred QC (ap->deferred_qc). If that happens, the condition qc == ap->deferred_qc evaluates to true despite the loop not breaking with a match on the SCSI command for this QC. In that case, the error handler mistakenly intercepts a command that has not been issued yet and that has not timed out, and thus erroneously returning a timeout error. Fix the problem by checking for i < ATA_MAX_QUEUE in addition to qc == ap->deferred_qc. The problem was found by an experimental code review agent based on gemini-3.1-pro while reviewing backports into v6.18.y. Assisted-by: Gemini:gemini-3.1-pro Fixes: eddb98ad9364 ("ata: libata-eh: correctly handle deferred qc timeouts") Signed-off-by: Guenter Roeck <linux@roeck-us.net> [cassel: modified commit log as suggested by Damien] Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-03-13ata: libata: cancel pending work after clearing deferred_qcNiklas Cassel2-0/+2
commit aac9b27f7c1f2b2cf7f50a9ca633ecbbcaf22af9 upstream. Syzbot reported a WARN_ON() in ata_scsi_deferred_qc_work(), caused by ap->ops->qc_defer() returning non-zero before issuing the deferred qc. ata_scsi_schedule_deferred_qc() is called during each command completion. This function will check if there is a deferred QC, and if ap->ops->qc_defer() returns zero, meaning that it is possible to queue the deferred qc at this time (without being deferred), then it will queue the work which will issue the deferred qc. Once the work get to run, which can potentially be a very long time after the work was scheduled, there is a WARN_ON() if ap->ops->qc_defer() returns non-zero. While we hold the ap->lock both when assigning and clearing deferred_qc, and the work itself holds the ap->lock, the code currently does not cancel the work after clearing the deferred qc. This means that the following scenario can happen: 1) One or several NCQ commands are queued. 2) A non-NCQ command is queued, gets stored in ap->deferred_qc. 3) Last NCQ command gets completed, work is queued to issue the deferred qc. 4) Timeout or error happens, ap->deferred_qc is cleared. The queued work is currently NOT canceled. 5) Port is reset. 6) One or several NCQ commands are queued. 7) A non-NCQ command is queued, gets stored in ap->deferred_qc. 8) Work is finally run. Yet at this time, there is still NCQ commands in flight. The work in 8) really belongs to the non-NCQ command in 2), not to the non-NCQ command in 7). The reason why the work is executed when it is not supposed to, is because it was never canceled when ap->deferred_qc was cleared in 4). Thus, ensure that we always cancel the work after clearing ap->deferred_qc. Another potential fix would have been to let ata_scsi_deferred_qc_work() do nothing if ap->ops->qc_defer() returns non-zero. However, canceling the work when clearing ap->deferred_qc seems slightly more logical, as we hold the ap->lock when clearing ap->deferred_qc, so we know that the work cannot be holding the lock. (The function could be waiting for the lock, but that is okay since it will do nothing if ap->deferred_qc is not set.) Reported-by: syzbot+bcaf842a1e8ead8dfb89@syzkaller.appspotmail.com Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation") Fixes: eddb98ad9364 ("ata: libata-eh: correctly handle deferred qc timeouts") Reviewed-by: Igor Pylypiv <ipylypiv@google.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-03-13ata: libata-eh: correctly handle deferred qc timeoutsDamien Le Moal1-3/+19
commit eddb98ad9364b4e778768785d46cfab04ce52100 upstream. A deferred qc may timeout while waiting for the device queue to drain to be submitted. In such case, since the qc is not active, ata_scsi_cmd_error_handler() ends up calling scsi_eh_finish_cmd(), which frees the qc. But as the port deferred_qc field still references this finished/freed qc, the deferred qc work may eventually attempt to call ata_qc_issue() against this invalid qc, leading to errors such as reported by UBSAN (syzbot run): UBSAN: shift-out-of-bounds in drivers/ata/libata-core.c:5166:24 shift exponent 4210818301 is too large for 64-bit type 'long long unsigned int' ... Call Trace: <TASK> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120 ubsan_epilogue+0xa/0x30 lib/ubsan.c:233 __ubsan_handle_shift_out_of_bounds+0x279/0x2a0 lib/ubsan.c:494 ata_qc_issue.cold+0x38/0x9f drivers/ata/libata-core.c:5166 ata_scsi_deferred_qc_work+0x154/0x1f0 drivers/ata/libata-scsi.c:1679 process_one_work+0x9d7/0x1920 kernel/workqueue.c:3275 process_scheduled_works kernel/workqueue.c:3358 [inline] worker_thread+0x5da/0xe40 kernel/workqueue.c:3439 kthread+0x370/0x450 kernel/kthread.c:467 ret_from_fork+0x754/0xd80 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 </TASK> Fix this by checking if the qc of a timed out SCSI command is a deferred one, and in such case, clear the port deferred_qc field and finish the SCSI command with DID_TIME_OUT. Reported-by: syzbot+1f77b8ca15336fff21ff@syzkaller.appspotmail.com Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation") Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Igor Pylypiv <ipylypiv@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-03-13ata: libata-core: fix cancellation of a port deferred qc workDamien Le Moal1-5/+3
commit 55db009926634b20955bd8abbee921adbc8d2cb4 upstream. cancel_work_sync() is a sleeping function so it cannot be called with the spin lock of a port being held. Move the call to this function in ata_port_detach() after EH completes, with the port lock released, together with other work cancellation calls. Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation") Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Igor Pylypiv <ipylypiv@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-03-13ata: libata-scsi: avoid Non-NCQ command starvationDamien Le Moal4-0/+106
[ Upstream commit 0ea84089dbf62a92dc7889c79e6b18fc89260808 ] When a non-NCQ command is issued while NCQ commands are being executed, ata_scsi_qc_issue() indicates to the SCSI layer that the command issuing should be deferred by returning SCSI_MLQUEUE_XXX_BUSY. This command deferring is correct and as mandated by the ACS specifications since NCQ and non-NCQ commands cannot be mixed. However, in the case of a host adapter using multiple submission queues, when the target device is under a constant load of NCQ commands, there are no guarantees that requeueing the non-NCQ command will be executed later and it may be deferred again repeatedly as other submission queues can constantly issue NCQ commands from different CPUs ahead of the non-NCQ command. This can lead to very long delays for the execution of non-NCQ commands, and even complete starvation for these commands in the worst case scenario. Since the block layer and the SCSI layer do not distinguish between queueable (NCQ) and non queueable (non-NCQ) commands, libata-scsi SAT implementation must ensure forward progress for non-NCQ commands in the presence of NCQ command traffic. This is similar to what SAS HBAs with a hardware/firmware based SAT implementation do. Implement such forward progress guarantee by limiting requeueing of non-NCQ commands from ata_scsi_qc_issue(): when a non-NCQ command is received and NCQ commands are in-flight, do not force a requeue of the non-NCQ command by returning SCSI_MLQUEUE_XXX_BUSY and instead return 0 to indicate that the command was accepted but hold on to the qc using the new deferred_qc field of struct ata_port. This deferred qc will be issued using the work item deferred_qc_work running the function ata_scsi_deferred_qc_work() once all in-flight commands complete, which is checked with the port qc_defer() callback return value indicating that no further delay is necessary. This check is done using the helper function ata_scsi_schedule_deferred_qc() which is called from ata_scsi_qc_complete(). This thus excludes this mechanism from all internal non-NCQ commands issued by ATA EH. When a port deferred_qc is non NULL, that is, the port has a command waiting for the device queue to drain, the issuing of all incoming commands (both NCQ and non-NCQ) is deferred using the regular busy mechanism. This simplifies the code and also avoids potential denial of service problems if a user issues too many non-NCQ commands. Finally, whenever ata EH is scheduled, regardless of the reason, a deferred qc is always requeued so that it can be retried once EH completes. This is done by calling the function ata_scsi_requeue_deferred_qc() from ata_eh_set_pending(). This avoids the need for any special processing for the deferred qc in case of NCQ error, link or device reset, or device timeout. Reported-by: Xingui Yang <yangxingui@huawei.com> Reported-by: Igor Pylypiv <ipylypiv@google.com> Fixes: bdb01301f3ea ("scsi: Add host and host template flag 'host_tagset'") Cc: stable@vger.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: John Garry <john.g.garry@oracle.com> Tested-by: Igor Pylypiv <ipylypiv@google.com> Tested-by: Xingui Yang <yangxingui@huawei.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-03-13ata: libata: Introduce ata_port_eh_scheduled()Damien Le Moal3-3/+9
[ Upstream commit 7aae547bbe442affc4afe176b157fab820a12437 ] 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> Stable-dep-of: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation") Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-03-13ata: libata: Remove ATA_DFLAG_ZAC device flagDamien Le Moal3-15/+10
[ Upstream commit a0f26fcc383965e0522b81269062a9278bc802fe ] The ATA device flag ATA_DFLAG_ZAC is used to indicate if a devie is a host managed or host aware zoned device. However, this flag is not used in the hot path and only used during device scanning/revalidation and for inquiry and sense SCSI command translation. Save one bit from struct ata_device flags field by replacing this flag with the internal helper function ata_dev_is_zac(). This function returns true if the device class is ATA_DEV_ZAC (host managed ZAC device case) or if its identify data reports it supports the zoned command set (host aware ZAC device case). Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Niklas Cassel <cassel@kernel.org> Stable-dep-of: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation") Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-03-13ata: libata-scsi: Remove struct ata_scsi_argsDamien Le Moal1-114/+127
[ Upstream commit 2365278e03916b6b9a65df91e9f7c7afe5a6cf2e ] The data structure struct ata_scsi_args is used to pass the target ATA device, the SCSI command to simulate and the device identification data to ata_scsi_rbuf_fill() and to its actor function. This method of passing information does not improve the code in any way and in fact increases the number of pointer dereferences for no gains. Drop this data structure by modifying the interface of ata_scsi_rbuf_fill() and its actor function to take an ATA device and a SCSI command as argument. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20241022024537.251905-6-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Stable-dep-of: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation") Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-03-13ata: libata-scsi: Document all VPD page inquiry actorsDamien Le Moal1-0/+54
[ Upstream commit 47000e84b3d0630d7d86eeb115894205be68035d ] Add the missing kdoc comments for the ata_scsiop_inq_XX functions used to emulate access to VPD pages. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20241022024537.251905-5-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Stable-dep-of: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation") Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-03-13ata: libata-scsi: Refactor ata_scsiop_maint_in()Damien Le Moal1-9/+11
[ Upstream commit 4ab7bb97634351914a18f3c4533992c99eb6edb6 ] Move the check for MI_REPORT_SUPPORTED_OPERATION_CODES from ata_scsi_simulate() into ata_scsiop_maint_in() to simplify ata_scsi_simulate() code. Furthermore, since an rbuff fill actor function returning a non-zero value causes no data to be returned for the command, directly return an error (return 1) for invalid command formt after setting the invalid field in cdb error. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20241022024537.251905-4-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Stable-dep-of: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation") Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-03-13ata: libata-scsi: Refactor ata_scsiop_read_cap()Damien Le Moal1-41/+46
[ Upstream commit 44bdde151a6f5b34993c570a8f6508e2e00b56e1 ] Move the check for the scsi command service action being SAI_READ_CAPACITY_16 from ata_scsi_simulate() into ata_scsiop_read_cap() to simplify ata_scsi_simulate() for processing capacity reading commands (READ_CAPACITY and SERVICE_ACTION_IN_16). Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20241022024537.251905-3-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Stable-dep-of: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation") Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-03-13ata: libata-scsi: Refactor ata_scsi_simulate()Damien Le Moal1-43/+63
[ Upstream commit b055e3be63bebc3c50d0fb1830de9bf4f2be388d ] Factor out the code handling the INQUIRY command in ata_scsi_simulate() using the function ata_scsi_rbuf_fill() with the new actor ata_scsiop_inquiry(). This new actor function calls the existing actors to handle the standard inquiry as well as extended inquiry (VPD page access). Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20241022024537.251905-2-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Stable-dep-of: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation") Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-03-04ata: libata: avoid long timeouts on hot-unplugged SATA DASHenry Tseng4-1/+30
[ Upstream commit 151cabd140322205e27dae5c4bbf261ede0056e3 ] When a SATA DAS enclosure is connected behind a Thunderbolt PCIe switch, hot-unplugging the whole enclosure causes pciehp to tear down the PCI hierarchy before the SCSI layer issues SYNCHRONIZE CACHE and START STOP UNIT for the disks. libata still queues these commands and the AHCI driver tries to access the HBA registers even though the PCI channel is already offline. This results in a series of timeouts and error recovery attempts, e.g.: [ 824.778346] pcieport 0000:00:07.0: pciehp: Slot(14): Link Down [ 891.612720] ata8.00: qc timeout after 5000 msecs (cmd 0xec) [ 902.876501] ata8.00: qc timeout after 10000 msecs (cmd 0xec) [ 934.107998] ata8.00: qc timeout after 30000 msecs (cmd 0xec) [ 936.206431] sd 7:0:0:0: [sda] Synchronize Cache(10) failed: Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK ... [ 1006.298356] ata1.00: qc timeout after 5000 msecs (cmd 0xec) [ 1017.561926] ata1.00: qc timeout after 10000 msecs (cmd 0xec) [ 1048.791790] ata1.00: qc timeout after 30000 msecs (cmd 0xec) [ 1050.890035] sd 0:0:0:0: [sdb] Synchronize Cache(10) failed: Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK With this patch applied, the same hot-unplug looks like: [ 59.965496] pcieport 0000:00:07.0: pciehp: Slot(14): Link Down [ 60.002502] sd 7:0:0:0: [sda] Synchronize Cache(10) failed: Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK ... [ 60.103050] sd 0:0:0:0: [sdb] Synchronize Cache(10) failed: Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK In this test setup with two disks, the hot-unplug sequence shrinks from about 226 seconds (~3.8 minutes) between the Link Down event and the last SYNCHRONIZE CACHE failure to under a second. Without this patch the total delay grows roughly with the number of disks, because each disk gets its own SYNCHRONIZE CACHE and qc timeout series. If the underlying PCI device is already gone, these commands cannot succeed anyway. Avoid issuing them by introducing ata_adapter_is_online(), which checks pci_channel_offline() for PCI-based hosts. It is used from ata_scsi_find_dev() to return NULL, causing the SCSI layer to fail new commands with DID_BAD_TARGET immediately, and from ata_qc_issue() to bail out before touching the HBA registers. Since such failures would otherwise trigger libata error handling, ata_adapter_is_online() is also consulted from ata_scsi_port_error_handler(). When the adapter is offline, libata skips ap->ops->error_handler(ap) and completes error handling using the existing path, rather than running a full EH sequence against a dead adapter. With this change, SYNCHRONIZE CACHE and START STOP UNIT commands issued during hot-unplug fail quickly once the PCI channel is offline, without qc timeout spam or long libata EH delays. Suggested-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Henry Tseng <henrytseng@qnap.com> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-03-04ata: libata-scsi: refactor ata_scsi_translate()Damien Le Moal1-31/+50
commit bb3a8154b1a1dc2c86d037482c0a2cf9186829ed upstream. Factor out of ata_scsi_translate() the code handling queued command deferral using the port qc_defer callback and issuing the queued command with ata_qc_issue() into the new function ata_scsi_qc_issue(), and simplify the goto used in ata_scsi_translate(). While at it, also add a lockdep annotation to check that the port lock is held when ata_scsi_translate() is called. No functional changes. Cc: stable@vger.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: John Garry <john.g.garry@oracle.com> Reviewed-by: Igor Pylypiv <ipylypiv@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-03-04ata: pata_ftide010: Fix some DMA timingsLinus Walleij1-3/+3
commit ff4a46c278ac6a4b3f39be1492a4568b6dcc6105 upstream. The FTIDE010 has been missing some timing settings since its inception, since the upstream OpenWrt patch was missing these. The community has since come up with the appropriate timings. Fixes: be4e456ed3a5 ("ata: Add driver for Faraday Technology FTIDE010") Cc: stable@vger.kernel.org Signed-off-by: Linus Walleij <linusw@kernel.org> Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-01-30ata: libata: Print features also for ATAPI devicesNiklas Cassel1-0/+3
[ Upstream commit c8c6fb886f57d5bf71fb6de6334a143608d35707 ] Commit d633b8a702ab ("libata: print feature list on device scan") added a print of the features supported by the device for ATA_DEV_ATA and ATA_DEV_ZAC devices, but not for ATA_DEV_ATAPI devices. Fix this by printing the features also for ATAPI devices. Before changes: ata1.00: ATAPI: Slimtype DVD A DU8AESH, 6C2M, max UDMA/133 After changes: ata1.00: ATAPI: Slimtype DVD A DU8AESH, 6C2M, max UDMA/133 ata1.00: Features: Dev-Attention HIPM DIPM Fixes: d633b8a702ab ("libata: print feature list on device scan") Signed-off-by: Niklas Cassel <cassel@kernel.org> Tested-by: Wolf <wolf@yoxt.cc> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-01-30ata: libata: Call ata_dev_config_lpm() for ATAPI devicesNiklas Cassel1-0/+2
[ Upstream commit 8f3fb33f8f3f825c708ece800c921977c157f9b6 ] Commit d360121832d8 ("ata: libata-core: Introduce ata_dev_config_lpm()") introduced ata_dev_config_lpm(). However, it only called this function for ATA_DEV_ATA and ATA_DEV_ZAC devices, not for ATA_DEV_ATAPI devices. Additionally, commit d99a9142e782 ("ata: libata-core: Move device LPM quirk settings to ata_dev_config_lpm()") moved the LPM quirk application from ata_dev_configure() to ata_dev_config_lpm(), causing LPM quirks for ATAPI devices to no longer be applied. Call ata_dev_config_lpm() also for ATAPI devices, such that LPM quirks are applied for ATAPI devices with an entry in __ata_dev_quirks once again. Fixes: d360121832d8 ("ata: libata-core: Introduce ata_dev_config_lpm()") Fixes: d99a9142e782 ("ata: libata-core: Move device LPM quirk settings to ata_dev_config_lpm()") Signed-off-by: Niklas Cassel <cassel@kernel.org> Tested-by: Wolf <wolf@yoxt.cc> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Stable-dep-of: c8c6fb886f57 ("ata: libata: Print features also for ATAPI devices") Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-01-30ata: libata-core: Introduce ata_dev_config_lpm()Damien Le Moal1-0/+25
[ Upstream commit d360121832d8a36871249271df5b9ff05f835f62 ] If the port of a device does not support Device Initiated Power Management (DIPM), that is, the port is flagged with ATA_FLAG_NO_DIPM, the DIPM feature of a device should not be used. Though DIPM is disabled by default on a device, the "Software Settings Preservation feature" may keep DIPM enabled or DIPM may have been enabled by the system firmware. Introduce the function ata_dev_config_lpm() to always disable DIPM on a device that supports this feature if the port of the device is flagged with ATA_FLAG_NO_DIPM. ata_dev_config_lpm() is called from ata_dev_configure(), ensuring that a device DIPM feature is disabled when it cannot be used. 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-2-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Stable-dep-of: c8c6fb886f57 ("ata: libata: Print features also for ATAPI devices") Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-01-30ata: libata: Add cpr_log to ata_dev_print_features() early returnNiklas Cassel1-1/+1
[ Upstream commit a6bee5e5243ad02cae575becc4c83df66fc29573 ] ata_dev_print_features() is supposed to return early and not print anything if there are no features supported. However, commit fe22e1c2f705 ("libata: support concurrent positioning ranges log") added another feature to ata_dev_print_features() without updating the early return conditional. Add the missing feature to the early return conditional. Fixes: fe22e1c2f705 ("libata: support concurrent positioning ranges log") Signed-off-by: Niklas Cassel <cassel@kernel.org> Tested-by: Wolf <wolf@yoxt.cc> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-01-30ata: libata-sata: Improve link_power_management_supported sysfs attributeNiklas Cassel1-1/+1
[ Upstream commit ce83767ea323baf8509a75eb0c783cd203e14789 ] The link_power_management_supported sysfs attribute is currently set as true even for ata ports that lack a .set_lpm() callback, e.g. dummy ports. This is a bit silly, because while writing to the link_power_management_policy sysfs attribute will make ata_scsi_lpm_store() update ap->target_lpm_policy (thus sysfs will reflect the new value) and call ata_port_schedule_eh() for the port, it is essentially a no-op. This is because for a port without a .set_lpm() callback, once EH gets to run, the ata_eh_link_set_lpm() will simply return, since the port does not provide a .set_lpm() callback. Thus, make sure that the link_power_management_supported sysfs attribute is set to false for ports that lack a .set_lpm() callback. This way the link_power_management_policy sysfs attribute will no longer be writable, so we will no longer be misleading users to think that their sysfs write actually does something. Fixes: 0060beec0bfa ("ata: libata-sata: Add link_power_management_supported sysfs attribute") Signed-off-by: Niklas Cassel <cassel@kernel.org> Tested-by: Wolf <wolf@yoxt.cc> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-01-30ata: ahci: Do not read the per port area for unimplemented portsNiklas Cassel1-5/+5
[ Upstream commit ea4d4ea6d10a561043922d285f1765c7e4bfd32a ] An AHCI HBA specifies the number of ports it supports using CAP.NP. The HBA is free to only make a subset of the number of ports available using the PI (Ports Implemented) register. libata currently creates dummy ports for HBA ports that are provided by the HBA, but which are marked as "unavailable" using the PI register. Each port will have a per port area of registers in the HBA, regardless if the port is marked as "unavailable" or not. ahci_mark_external_port() currently reads this per port area of registers using readl() to see if the port is marked as external/hotplug-capable. However, AHCI 1.3.1, section "3.1.4 Offset 0Ch: PI – Ports Implemented" states: "Software must not read or write to registers within unavailable ports." Thus, make sure that we only call ahci_mark_external_port() and ahci_update_initial_lpm_policy() for ports that are implemented. From a libata perspective, this should not change anything related to LPM, as dummy ports do not provide any ap->ops (they do not have a .set_lpm() callback), so even if EH were to call .set_lpm() on a dummy port, it was already a no-op. Fixes: f7131935238d ("ata: ahci: move marking of external port earlier") Signed-off-by: Niklas Cassel <cassel@kernel.org> Tested-by: Wolf <wolf@yoxt.cc> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-01-17ata: libata-core: Disable LPM on ST2000DM008-2FR102Niklas Cassel1-0/+3
[ Upstream commit ba624ba88d9f5c3e2ace9bb6697dbeb05b2dbc44 ] According to a user report, the ST2000DM008-2FR102 has problems with LPM. Reported-by: Emerson Pinter <e@pinter.dev> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220693 Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-12-01ata: libata-scsi: Add missing scsi_device_put() in ata_scsi_dev_rescan()Yihang Li1-1/+3
commit b32cc17d607e8ae7af037303fe101368cb4dc44c upstream. Call scsi_device_put() in ata_scsi_dev_rescan() if the device or its queue are not running. Fixes: 0c76106cb975 ("scsi: sd: Fix TCG OPAL unlock on system resume") Cc: stable@vger.kernel.org Signed-off-by: Yihang Li <liyihang9@h-partners.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-12-01ata: libata-scsi: Fix system suspend for a security locked driveNiklas Cassel1-0/+7
commit b11890683380a36b8488229f818d5e76e8204587 upstream. Commit cf3fc037623c ("ata: libata-scsi: Fix ata_to_sense_error() status handling") fixed ata_to_sense_error() to properly generate sense key ABORTED COMMAND (without any additional sense code), instead of the previous bogus sense key ILLEGAL REQUEST with the additional sense code UNALIGNED WRITE COMMAND, for a failed command. However, this broke suspend for Security locked drives (drives that have Security enabled, and have not been Security unlocked by boot firmware). The reason for this is that the SCSI disk driver, for the Synchronize Cache command only, treats any sense data with sense key ILLEGAL REQUEST as a successful command (regardless of ASC / ASCQ). After commit cf3fc037623c ("ata: libata-scsi: Fix ata_to_sense_error() status handling") the code that treats any sense data with sense key ILLEGAL REQUEST as a successful command is no longer applicable, so the command fails, which causes the system suspend to be aborted: sd 1:0:0:0: PM: dpm_run_callback(): scsi_bus_suspend returns -5 sd 1:0:0:0: PM: failed to suspend async: error -5 PM: Some devices failed to suspend, or early wake event detected To make suspend work once again, for a Security locked device only, return sense data LOGICAL UNIT ACCESS NOT AUTHORIZED, the actual sense data which a real SCSI device would have returned if locked. The SCSI disk driver treats this sense data as a successful command. Cc: stable@vger.kernel.org Reported-by: Ilia Baryshnikov <qwelias@gmail.com> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220704 Fixes: cf3fc037623c ("ata: libata-scsi: Fix ata_to_sense_error() status handling") Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-08-28ata: libata-scsi: Return aborted command when missing sense and result TFDamien Le Moal1-12/+15
commit d2be9ea9a75550a35c5127a6c2633658bc38c76b upstream. ata_gen_ata_sense() is always called for a failed qc missing sense data so that a sense key, code and code qualifier can be generated using ata_to_sense_error() from the qc status and error fields of its result task file. However, if the qc does not have its result task file filled, ata_gen_ata_sense() returns early without setting a sense key. Improve this by defaulting to returning ABORTED COMMAND without any additional sense code, since we do not know the reason for the failure. The same fix is also applied in ata_gen_passthru_sense() with the additional check that the qc failed (qc->err_mask is set). Fixes: 816be86c7993 ("ata: libata-scsi: Check ATA_QCFLAG_RTF_FILLED before using result_tf") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-08-28ata: libata-scsi: Fix CDL controlIgor Pylypiv1-8/+3
commit 58768b0563916ddcb73d8ed26ede664915f8df31 upstream. Delete extra checks for the ATA_DFLAG_CDL_ENABLED flag that prevent SET FEATURES command from being issued to a drive when NCQ commands are active. ata_mselect_control_ata_feature() sets / clears the ATA_DFLAG_CDL_ENABLED flag during the translation of MODE SELECT to SET FEATURES. If SET FEATURES gets deferred due to outstanding NCQ commands, the original MODE SELECT command will be re-queued. When the re-queued MODE SELECT goes through the ata_mselect_control_ata_feature() translation again, SET FEATURES will not be issued because ATA_DFLAG_CDL_ENABLED has been already set or cleared by the initial translation of MODE SELECT. The ATA_DFLAG_CDL_ENABLED checks in ata_mselect_control_ata_feature() are safe to remove because scsi_cdl_enable() implements a similar logic that avoids enabling CDL if it has been enabled already. Fixes: 17e897a45675 ("ata: libata-scsi: Improve CDL control") Cc: stable@vger.kernel.org Signed-off-by: Igor Pylypiv <ipylypiv@google.com> Reviewed-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-08-28ata: libata-scsi: Fix ata_to_sense_error() status handlingDamien Le Moal1-12/+8
commit cf3fc037623c54de48d2ec1a1ee686e2d1de2d45 upstream. Commit 8ae720449fca ("libata: whitespace fixes in ata_to_sense_error()") inadvertantly added the entry 0x40 (ATA_DRDY) to the stat_table array in the function ata_to_sense_error(). This entry ties a failed qc which has a status filed equal to ATA_DRDY to the sense key ILLEGAL REQUEST with the additional sense code UNALIGNED WRITE COMMAND. This entry will be used to generate a failed qc sense key and sense code when the qc is missing sense data and there is no match for the qc error field in the sense_table array of ata_to_sense_error(). As a result, for a failed qc for which we failed to get sense data (e.g. read log 10h failed if qc is an NCQ command, or REQUEST SENSE EXT command failed for the non-ncq case, the user very often end up seeing the completely misleading "unaligned write command" error, even if qc was not a write command. E.g.: sd 0:0:0:0: [sda] tag#12 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=0s sd 0:0:0:0: [sda] tag#12 Sense Key : Illegal Request [current] sd 0:0:0:0: [sda] tag#12 Add. Sense: Unaligned write command sd 0:0:0:0: [sda] tag#12 CDB: Read(10) 28 00 00 00 10 00 00 00 08 00 I/O error, dev sda, sector 4096 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 0 Fix this by removing the ATA_DRDY entry from the stat_table array so that we default to always returning ABORTED COMMAND without any additional sense code, since we do not know any better. The entry 0x08 (ATA_DRQ) is also removed since signaling ABORTED COMMAND with a parity error is also misleading (as a parity error would likely be signaled through a bus error). So for this case, also default to returning ABORTED COMMAND without any additional sense code. With this, the previous example error case becomes: sd 0:0:0:0: [sda] tag#17 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=0s sd 0:0:0:0: [sda] tag#17 Sense Key : Aborted Command [current] sd 0:0:0:0: [sda] tag#17 Add. Sense: No additional sense information sd 0:0:0:0: [sda] tag#17 CDB: Read(10) 28 00 00 00 10 00 00 00 08 00 I/O error, dev sda, sector 4096 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 0 Together with these fixes, refactor stat_table to make it more readable by putting the entries comments in front of the entries and using the defined status bits macros instead of hardcoded values. Reported-by: Lorenz Brun <lorenz@brun.one> Reported-by: Brandon Schwartz <Brandon.Schwartz@wdc.com> Fixes: 8ae720449fca ("libata: whitespace fixes in ata_to_sense_error()") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-08-28ata: Fix SATA_MOBILE_LPM_POLICY description in KconfigDamien Le Moal1-10/+26
commit ed62a62a18bc144f73eadf866ae46842e8f6606e upstream. Improve the description of the possible default SATA link power management policies and add the missing description for policy 5. No functional changes. Fixes: a5ec5a7bfd1f ("ata: ahci: Support state with min power but Partial low power state") Cc: stable@vger.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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-08-20ata: libata-sata: Add link_power_management_supported sysfs attributeDamien Le Moal3-12/+43
commit 0060beec0bfa647c4b510df188b1c4673a197839 upstream. A port link power management (LPM) policy can be controlled using the link_power_management_policy sysfs host attribute. However, this attribute exists also for hosts that do not support LPM and in such case, attempting to change the LPM policy for the host (port) will fail with -EOPNOTSUPP. Introduce the new sysfs link_power_management_supported host attribute to indicate to the user if a the port and the devices connected to the port for the host support LPM, which implies that the link_power_management_policy attribute can be used. Since checking that a port and its devices support LPM is common between the new ata_scsi_lpm_supported_show() function and the existing ata_scsi_lpm_store() function, the new helper ata_scsi_lpm_supported() is introduced. Fixes: 413e800cadbf ("ata: libata-sata: Disallow changing LPM state if not supported") Reported-by: Borah, Chaitanya Kumar <chaitanya.kumar.borah@intel.com> Reported-by: kernel test robot <oliver.sang@intel.com> Closes: https://lore.kernel.org/oe-lkp/202507251014.a5becc3b-lkp@intel.com Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-08-20ata: libata-sata: Disallow changing LPM state if not supportedDamien Le Moal1-0/+5
[ Upstream commit 413e800cadbf67550d76c77c230b2ecd96bce83a ] Modify ata_scsi_lpm_store() to return an error if a user attempts to set a link power management policy for a port that does not support LPM, that is, ports flagged with ATA_FLAG_NO_LPM. 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-6-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-08-20ata: ahci: Disable DIPM if host lacks supportDamien Le Moal1-0/+7
[ Upstream commit f7870e8d345cdabfb94bcbdcba6a07e050f8705e ] The AHCI specification version 1.3.1 section 8.3.1.4 (Software Requirements and Precedence) states that: If CAP.SSC or CAP.PSC is cleared to ‘0’, software should disable device-initiated power management by issuing the appropriate SET FEATURES command to the device. To satisfy this constraint and force ata_dev_configure to disable the device DIPM feature, modify ahci_update_initial_lpm_policy() to set the ATA_FLAG_NO_DIPM flag on ports that have a host with either the ATA_HOST_NO_PART flag set or the ATA_HOST_NO_SSC flag set. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Hannes Reinecke <hare@suse.de.> Link: https://lore.kernel.org/r/20250701125321.69496-7-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-08-20ata: ahci: Disallow LPM policy control if not supportedDamien Le Moal1-1/+4
[ Upstream commit 65b2c92f69d3df81422d27e5be012e357e733241 ] Commit fa997b0576c9 ("ata: ahci: Do not enable LPM if no LPM states are supported by the HBA") introduced an early return in ahci_update_initial_lpm_policy() to ensure that the target_lpm_policy of ports belonging to a host that does not support the Partial, Slumber and DevSleep power states is unchanged and remains set to ATA_LPM_UNKNOWN and thus prevents the execution of ata_eh_link_set_lpm(). However, a user or a system daemon (e.g. systemd-udevd) may still attempt changing the LPM policy through the sysfs link_power_management_policy of the host. Improve this to prevent sysfs LPM policy changes by setting the flag ATA_FLAG_NO_LPM for the port of such host, and initialize the port target_lpm_policy to ATA_LPM_MAX_POWER to guarantee that no unsupported low power state is being used on the port and its link. 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/20250701125321.69496-9-dlemoal@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-07-10ata: pata_cs5536: fix build on 32-bit UMLJohannes Berg1-1/+1
[ Upstream commit fe5b391fc56f77cf3c22a9dd4f0ce20db0e3533f ] On 32-bit ARCH=um, CONFIG_X86_32 is still defined, so it doesn't indicate building on real X86 machines. There's no MSR on UML though, so add a check for CONFIG_X86. Reported-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Link: https://lore.kernel.org/r/20250606090110.15784-2-johannes@sipsolutions.net Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-07-10ata: libata-acpi: Do not assume 40 wire cable if no devices are enabledTasos Sahanidis2-12/+18
[ Upstream commit 33877220b8641b4cde474a4229ea92c0e3637883 ] On at least an ASRock 990FX Extreme 4 with a VIA VT6330, the devices have not yet been enabled by the first time ata_acpi_cbl_80wire() is called. This means that the ata_for_each_dev loop is never entered, and a 40 wire cable is assumed. The VIA controller on this board does not report the cable in the PCI config space, thus having to fall back to ACPI even though no SATA bridge is present. The _GTM values are correctly reported by the firmware through ACPI, which has already set up faster transfer modes, but due to the above the controller is forced down to a maximum of UDMA/33. Resolve this by modifying ata_acpi_cbl_80wire() to directly return the cable type. First, an unknown cable is assumed which preserves the mode set by the firmware, and then on subsequent calls when the devices have been enabled, an 80 wire cable is correctly detected. Since the function now directly returns the cable type, it is renamed to ata_acpi_cbl_pata_type(). Signed-off-by: Tasos Sahanidis <tasos@tasossah.com> Link: https://lore.kernel.org/r/20250519085945.1399466-1-tasos@tasossah.com Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-07-06ata: ahci: Use correct DMI identifier for ASUSPRO-D840SA LPM quirkNiklas Cassel1-1/+1
commit 3e0809b1664b9dc650d9dbca9a2d3ac690d4f661 upstream. ASUS store the board name in DMI_PRODUCT_NAME rather than DMI_PRODUCT_VERSION. (Apparently it is only Lenovo that stores the model-name in DMI_PRODUCT_VERSION.) Use the correct DMI identifier, DMI_PRODUCT_NAME, to match the ASUSPRO-D840SA board, such that the quirk actually gets applied. Cc: stable@vger.kernel.org Reported-by: Andy Yang <andyybtc79@gmail.com> Tested-by: Andy Yang <andyybtc79@gmail.com> Closes: https://lore.kernel.org/linux-ide/aFb3wXAwJSSJUB7o@ryzen/ Fixes: b5acc3628898 ("ata: ahci: Disallow LPM for ASUSPRO-D840SA motherboard") Reviewed-by: Hans de Goede <hansg@kernel.org> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20250624074029.963028-2-cassel@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-06-27ata: ahci: Disallow LPM for Asus B550-F motherboardMikko Korhonen1-1/+17
commit a7b3b77fd111d49f8e25624e4ea1046322a57baf upstream. Asus ROG STRIX B550-F GAMING (WI-FI) motherboard has problems on some SATA ports with at least one hard drive model (WDC WD20EFAX-68FB5N0) when LPM is enabled. Disabling LPM solves the issue. Cc: stable@vger.kernel.org Fixes: 7627a0edef54 ("ata: ahci: Drop low power policy board type") Signed-off-by: Mikko Korhonen <mjkorhon@gmail.com> Link: https://lore.kernel.org/r/20250617062055.784827-1-mjkorhon@gmail.com [cassel: more detailed comment, make single line comments consistent] Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-06-27ata: ahci: Disallow LPM for ASUSPRO-D840SA motherboardNiklas Cassel1-1/+18
commit b5acc3628898baa63658bc4125f9525f9b3dd4f3 upstream. A user has bisected a regression which causes graphical corruptions on his screen to commit 7627a0edef54 ("ata: ahci: Drop low power policy board type"). Simply reverting commit 7627a0edef54 ("ata: ahci: Drop low power policy board type") makes the graphical corruptions on his screen to go away. (Note: there are no visible messages in dmesg that indicates a problem with AHCI.) The user also reports that the problem occurs regardless if there is an HDD or an SSD connected via AHCI, so the problem is not device related. The devices also work fine on other motherboards, so it seems specific to the ASUSPRO-D840SA motherboard. While enabling low power modes for AHCI is not supposed to affect completely unrelated hardware, like a graphics card, it does however allow the system to enter deeper PC-states, which could expose ACPI issues that were previously not visible (because the system never entered these lower power states before). There are previous examples where enabling LPM exposed serious BIOS/ACPI bugs, see e.g. commit 240630e61870 ("ahci: Disable LPM on Lenovo 50 series laptops with a too old BIOS"). Since there hasn't been any BIOS update in years for the ASUSPRO-D840SA motherboard, disable LPM for this board, in order to avoid entering lower PC-states, which triggers graphical corruptions. Cc: stable@vger.kernel.org Reported-by: Andy Yang <andyybtc79@gmail.com> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220111 Fixes: 7627a0edef54 ("ata: ahci: Drop low power policy board type") Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hans de Goede <hansg@kernel.org> Link: https://lore.kernel.org/r/20250612141750.2108342-2-cassel@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-06-27ata: pata_via: Force PIO for ATAPI devices on VT6415/VT6330Tasos Sahanidis1-1/+2
commit d29fc02caad7f94b62d56ee1b01c954f9c961ba7 upstream. The controller has a hardware bug that can hard hang the system when doing ATAPI DMAs without any trace of what happened. Depending on the device attached, it can also prevent the system from booting. In this case, the system hangs when reading the ATIP from optical media with cdrecord -vvv -atip on an _NEC DVD_RW ND-4571A 1-01 and an Optiarc DVD RW AD-7200A 1.06 attached to an ASRock 990FX Extreme 4, running at UDMA/33. The issue can be reproduced by running the same command with a cygwin build of cdrecord on WinXP, although it requires more attempts to cause it. The hang in that case is also resolved by forcing PIO. It doesn't appear that VIA has produced any drivers for that OS, thus no known workaround exists. HDDs attached to the controller do not suffer from any DMA issues. Cc: stable@vger.kernel.org Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/916677 Signed-off-by: Tasos Sahanidis <tasos@tasossah.com> Link: https://lore.kernel.org/r/20250519085508.1398701-1-tasos@tasossah.com Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-05-02ata: libata-scsi: Fix ata_msense_control_ata_feature()Damien Le Moal1-2/+2
commit 88474ad734fb2000805c63e01cc53ea930adf2c7 upstream. For the ATA features subpage of the control mode page, the T10 SAT-6 specifications state that: For a MODE SENSE command, the SATL shall return the CDL_CTRL field value that was last set by an application client. However, the function ata_msense_control_ata_feature() always sets the CDL_CTRL field to the 0x02 value to indicate support for the CDL T2A and T2B pages. This is thus incorrect and the value 0x02 must be reported only after the user enables the CDL feature, which is indicated with the ATA_DFLAG_CDL_ENABLED device flag. When this flag is not set, the CDL_CTRL field of the ATA feature subpage of the control mode page must report a value of 0x00. Fix ata_msense_control_ata_feature() to report the correct values for the CDL_CTRL field, according to the enable/disable state of the device CDL feature. Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Igor Pylypiv <ipylypiv@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-05-02ata: libata-scsi: Fix ata_mselect_control_ata_feature() return typeDamien Le Moal1-4/+3
commit db91586b1e8f36122a9e5b8fbced11741488dd22 upstream. The function ata_mselect_control_ata_feature() has a return type defined as unsigned int but this function may return negative error codes, which are correctly propagated up the call chain as integers. Fix ata_mselect_control_ata_feature() to have the correct int return type. While at it, also fix a typo in this function description comment. Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Igor Pylypiv <ipylypiv@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-05-02ata: libata-scsi: Improve CDL controlDamien Le Moal1-2/+12
commit 17e897a456752ec9c2d7afb3d9baf268b442451b upstream. With ATA devices supporting the CDL feature, using CDL requires that the feature be enabled with a SET FEATURES command. This command is issued as the translated command for the MODE SELECT command issued by scsi_cdl_enable() when the user enables CDL through the device cdl_enable sysfs attribute. Currently, ata_mselect_control_ata_feature() always translates a MODE SELECT command for the ATA features subpage of the control mode page to a SET FEATURES command to enable or disable CDL based on the cdl_ctrl field. However, there is no need to issue the SET FEATURES command if: 1) The MODE SELECT command requests disabling CDL and CDL is already disabled. 2) The MODE SELECT command requests enabling CDL and CDL is already enabled. Fix ata_mselect_control_ata_feature() to issue the SET FEATURES command only when necessary. Since enabling CDL also implies a reset of the CDL statistics log page, avoiding useless CDL enable operations also avoids clearing the CDL statistics log. Also add debug messages to clearly signal when CDL is being enabled or disabled using a SET FEATURES command. Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Igor Pylypiv <ipylypiv@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-04-25ata: libata-sata: Save all fields from sense data descriptorNiklas Cassel1-0/+15
[ Upstream commit 399eab7f92fb73ffe621294a2d6bec8fc9f3b36b ] When filling the taskfile result for a successful NCQ command, we use the SDB FIS from the FIS Receive Area, see e.g. ahci_qc_ncq_fill_rtf(). However, the SDB FIS only has fields STATUS and ERROR. For a successful NCQ command that has sense data, we will have a successful sense data descriptor, in the Sense Data for Successful NCQ Commands log. Since we have access to additional taskfile result fields, fill in these additional fields in qc->result_tf. This matches how for failing/aborted NCQ commands, we will use e.g. ahci_qc_fill_rtf() to fill in some fields, but then for the command that actually caused the NCQ error, we will use ata_eh_read_log_10h(), which provides additional fields, saving additional fields/overriding the qc->result_tf that was fetched using ahci_qc_fill_rtf(). Fixes: 18bd7718b5c4 ("scsi: ata: libata: Handle completion of CDL commands using policy 0xD") Signed-off-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Igor Pylypiv <ipylypiv@google.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-04-20ahci: Marvell 88SE9215 controllers prefer DMA for ATAPIHuacai Chen3-1/+15
[ Upstream commit 0507c777f5d8f9e34b137d28ee263599a7b81242 ] We use CD/DVD drives under Marvell 88SE9215 SATA controller on many Loongson-based machines. We found its PIO doesn't work well, and on the opposite its DMA seems work very well. We don't know the detail of the 88SE9215 SATA controller, but we have tested different CD/DVD drives and they all have problems under 88SE9215 (but they all work well under an Intel SATA controller). So, we consider this problem is bound to 88SE9215 SATA controller rather than bound to CD/DVD drives. As a solution, we define a new dedicated AHCI board id which is named board_ahci_yes_fbs_atapi_dma for 88SE9215, and for this id we set the AHCI_HFLAG_ATAPI_DMA_QUIRK and ATA_QUIRK_ATAPI_MOD16_DMA flags on the SATA controller in order to prefer ATAPI DMA. Reported-by: Yuli Wang <wangyuli@uniontech.com> Tested-by: Jie Fan <fanjie@uniontech.com> Tested-by: Erpeng Xu <xuerpeng@uniontech.com> Tested-by: Yuli Wang <wangyuli@uniontech.com> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> Link: https://lore.kernel.org/r/20250318104314.2160526-1-chenhuacai@loongson.cn Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-04-20ahci: add PCI ID for Marvell 88SE9215 SATA ControllerDaniel Kral1-0/+2
[ Upstream commit 885251dc35767b1c992f6909532ca366c830814a ] Add support for Marvell Technology Group Ltd. 88SE9215 SATA 6 Gb/s controller, which is e.g. used in the DAWICONTROL DC-614e RAID bus controller and was not automatically recognized before. Tested with a DAWICONTROL DC-614e RAID bus controller. Signed-off-by: Daniel Kral <d.kral@proxmox.com> Link: https://lore.kernel.org/r/20250304092030.37108-1-d.kral@proxmox.com Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-04-20ata: libata-eh: Do not use ATAPI DMA for a device limited to PIO modeNiklas Cassel1-2/+9
[ Upstream commit 91ec84f8eaddbc93d7c62e363d68aeb7b89879c7 ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>