<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/drivers/ata/libata-scsi.c, branch linux-rolling-lts</title>
<subtitle>Hosts the 0x221E linux distro kernel.</subtitle>
<id>https://universe.0xinfinity.dev/distro/kernel/atom?h=linux-rolling-lts</id>
<link rel='self' href='https://universe.0xinfinity.dev/distro/kernel/atom?h=linux-rolling-lts'/>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/'/>
<updated>2026-03-13T16:23:30Z</updated>
<entry>
<title>ata: libata: cancel pending work after clearing deferred_qc</title>
<updated>2026-03-13T16:23:30Z</updated>
<author>
<name>Niklas Cassel</name>
<email>cassel@kernel.org</email>
</author>
<published>2026-03-03T10:03:42Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=6c5e8f16b5e8e614e829aaf38619bdd79107bb0a'/>
<id>urn:sha1:6c5e8f16b5e8e614e829aaf38619bdd79107bb0a</id>
<content type='text'>
commit aac9b27f7c1f2b2cf7f50a9ca633ecbbcaf22af9 upstream.

Syzbot reported a WARN_ON() in ata_scsi_deferred_qc_work(), caused by
ap-&gt;ops-&gt;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-&gt;ops-&gt;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-&gt;ops-&gt;qc_defer() returns
non-zero.

While we hold the ap-&gt;lock both when assigning and clearing deferred_qc,
and the work itself holds the ap-&gt;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-&gt;deferred_qc.
3) Last NCQ command gets completed, work is queued to issue the deferred
   qc.
4) Timeout or error happens, ap-&gt;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-&gt;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-&gt;deferred_qc was
cleared in 4). Thus, ensure that we always cancel the work after clearing
ap-&gt;deferred_qc.

Another potential fix would have been to let ata_scsi_deferred_qc_work() do
nothing if ap-&gt;ops-&gt;qc_defer() returns non-zero. However, canceling the
work when clearing ap-&gt;deferred_qc seems slightly more logical, as we hold
the ap-&gt;lock when clearing ap-&gt;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-&gt;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 &lt;ipylypiv@google.com&gt;
Reviewed-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ata: libata: avoid long timeouts on hot-unplugged SATA DAS</title>
<updated>2026-03-04T12:20:28Z</updated>
<author>
<name>Henry Tseng</name>
<email>henrytseng@qnap.com</email>
</author>
<published>2025-12-01T09:46:22Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=9443fe6d05d119f2224d1c3d1d8aa6e68ca89911'/>
<id>urn:sha1:9443fe6d05d119f2224d1c3d1d8aa6e68ca89911</id>
<content type='text'>
[ 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-&gt;ops-&gt;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 &lt;dlemoal@kernel.org&gt;
Signed-off-by: Henry Tseng &lt;henrytseng@qnap.com&gt;
Signed-off-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata-scsi: avoid Non-NCQ command starvation</title>
<updated>2026-02-26T22:59:46Z</updated>
<author>
<name>Damien Le Moal</name>
<email>dlemoal@kernel.org</email>
</author>
<published>2025-12-17T07:40:48Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=888cd7e40adb2ef4af1b4d3b6e2e83ad409ae8c2'/>
<id>urn:sha1:888cd7e40adb2ef4af1b4d3b6e2e83ad409ae8c2</id>
<content type='text'>
commit 0ea84089dbf62a92dc7889c79e6b18fc89260808 upstream.

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 &lt;yangxingui@huawei.com&gt;
Reported-by: Igor Pylypiv &lt;ipylypiv@google.com&gt;
Fixes: bdb01301f3ea ("scsi: Add host and host template flag 'host_tagset'")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Reviewed-by: Niklas Cassel &lt;cassel@kernel.org&gt;
Reviewed-by: Martin K. Petersen &lt;martin.petersen@oracle.com&gt;
Reviewed-by: John Garry &lt;john.g.garry@oracle.com&gt;
Tested-by: Igor Pylypiv &lt;ipylypiv@google.com&gt;
Tested-by: Xingui Yang &lt;yangxingui@huawei.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ata: libata-scsi: refactor ata_scsi_translate()</title>
<updated>2026-02-26T22:59:46Z</updated>
<author>
<name>Damien Le Moal</name>
<email>dlemoal@kernel.org</email>
</author>
<published>2025-12-17T05:05:25Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=410336fc82ac9e1a294af56b9ede0e0e0910ba61'/>
<id>urn:sha1:410336fc82ac9e1a294af56b9ede0e0e0910ba61</id>
<content type='text'>
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 &lt;dlemoal@kernel.org&gt;
Reviewed-by: Niklas Cassel &lt;cassel@kernel.org&gt;
Reviewed-by: Martin K. Petersen &lt;martin.petersen@oracle.com&gt;
Reviewed-by: John Garry &lt;john.g.garry@oracle.com&gt;
Reviewed-by: Igor Pylypiv &lt;ipylypiv@google.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ata: libata-scsi: Fix system suspend for a security locked drive</title>
<updated>2025-11-20T12:37:17Z</updated>
<author>
<name>Niklas Cassel</name>
<email>cassel@kernel.org</email>
</author>
<published>2025-11-19T14:13:14Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=b11890683380a36b8488229f818d5e76e8204587'/>
<id>urn:sha1:b11890683380a36b8488229f818d5e76e8204587</id>
<content type='text'>
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 &lt;qwelias@gmail.com&gt;
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 &lt;hare@suse.de&gt;
Reviewed-by: Martin K. Petersen &lt;martin.petersen@oracle.com&gt;
Reviewed-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata-scsi: Add missing scsi_device_put() in ata_scsi_dev_rescan()</title>
<updated>2025-11-20T12:12:26Z</updated>
<author>
<name>Yihang Li</name>
<email>liyihang9@h-partners.com</email>
</author>
<published>2025-11-20T03:50:23Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=b32cc17d607e8ae7af037303fe101368cb4dc44c'/>
<id>urn:sha1:b32cc17d607e8ae7af037303fe101368cb4dc44c</id>
<content type='text'>
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 &lt;liyihang9@h-partners.com&gt;
Reviewed-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>Merge tag 'pull-getgeo' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs into for-6.18/block</title>
<updated>2025-09-03T21:15:43Z</updated>
<author>
<name>Jens Axboe</name>
<email>axboe@kernel.dk</email>
</author>
<published>2025-09-03T21:15:43Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=4dbe13c78447450ee133fc3399ebcabe27a62164'/>
<id>urn:sha1:4dbe13c78447450ee133fc3399ebcabe27a62164</id>
<content type='text'>
Pull struct block_device getgeo changes from Al.

"switching -&gt;getgeo() from struct block_device to struct gendisk

 Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;"

* tag 'pull-getgeo' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  block: switch -&gt;getgeo() to struct gendisk
  scsi: switch -&gt;bios_param() to passing gendisk
  scsi: switch scsi_bios_ptable() and scsi_partsize() to gendisk
</content>
</entry>
<entry>
<title>ata: libata-scsi: Fix CDL control</title>
<updated>2025-08-14T09:58:12Z</updated>
<author>
<name>Igor Pylypiv</name>
<email>ipylypiv@google.com</email>
</author>
<published>2025-08-14T02:22:56Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=58768b0563916ddcb73d8ed26ede664915f8df31'/>
<id>urn:sha1:58768b0563916ddcb73d8ed26ede664915f8df31</id>
<content type='text'>
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 &lt;ipylypiv@google.com&gt;
Reviewed-by: Niklas Cassel &lt;cassel@kernel.org&gt;
Signed-off-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
</content>
</entry>
<entry>
<title>scsi: switch -&gt;bios_param() to passing gendisk</title>
<updated>2025-08-13T06:59:28Z</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2024-05-22T03:22:01Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=3eb50369c09efb0f668a7f568a7e6f7cf4194cde'/>
<id>urn:sha1:3eb50369c09efb0f668a7f568a7e6f7cf4194cde</id>
<content type='text'>
Instances are passed struct block_device *bdev argument; the only thing
it is used for (if it's used in the first place) is bdev-&gt;bd_disk.
Might as well pass that in the first place...

Reviewed-by: Martin K. Petersen &lt;martin.petersen@oracle.com&gt;
Reviewed-by: Christoph Hellwig &lt;hch@lst.de&gt;
Acked-by: Jens Axboe &lt;axboe@kernel.dk&gt;
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</content>
</entry>
<entry>
<title>ata: libata-scsi: Return aborted command when missing sense and result TF</title>
<updated>2025-07-31T03:56:11Z</updated>
<author>
<name>Damien Le Moal</name>
<email>dlemoal@kernel.org</email>
</author>
<published>2025-07-29T10:37:12Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=d2be9ea9a75550a35c5127a6c2633658bc38c76b'/>
<id>urn:sha1:d2be9ea9a75550a35c5127a6c2633658bc38c76b</id>
<content type='text'>
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-&gt;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 &lt;dlemoal@kernel.org&gt;
Reviewed-by: Hannes Reinecke &lt;hare@suse.de&gt;
Reviewed-by: Martin K. Petersen &lt;martin.petersen@oracle.com&gt;
</content>
</entry>
</feed>
