<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/drivers/ata/libata.h, branch v6.18.21</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v6.18.21</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v6.18.21'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2026-03-04T12:20:28+00:00</updated>
<entry>
<title>ata: libata: avoid long timeouts on hot-unplugged SATA DAS</title>
<updated>2026-03-04T12:20:28+00:00</updated>
<author>
<name>Henry Tseng</name>
<email>henrytseng@qnap.com</email>
</author>
<published>2025-12-01T09:46:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/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:46+00:00</updated>
<author>
<name>Damien Le Moal</name>
<email>dlemoal@kernel.org</email>
</author>
<published>2025-12-17T07:40:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/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-eh: Simplify reset operation management</title>
<updated>2025-07-16T07:31:43+00:00</updated>
<author>
<name>Damien Le Moal</name>
<email>dlemoal@kernel.org</email>
</author>
<published>2025-07-16T02:03:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=a4daf088a77323154514eb1f8626bbdf9329cfd4'/>
<id>urn:sha1:a4daf088a77323154514eb1f8626bbdf9329cfd4</id>
<content type='text'>
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 &lt;cassel@kernel.org&gt;
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: Hannes Reinecke &lt;hare@suse.de&gt;
Link: https://lore.kernel.org/r/20250716020315.235457-3-dlemoal@kernel.org
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata: Introduce ata_port_eh_scheduled()</title>
<updated>2025-07-07T10:40:56+00:00</updated>
<author>
<name>Damien Le Moal</name>
<email>dlemoal@kernel.org</email>
</author>
<published>2025-07-04T10:46:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=7aae547bbe442affc4afe176b157fab820a12437'/>
<id>urn:sha1:7aae547bbe442affc4afe176b157fab820a12437</id>
<content type='text'>
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 &lt;dlemoal@kernel.org&gt;
Reviewed-by: Niklas Cassel &lt;cassel@kernel.org&gt;
Link: https://lore.kernel.org/r/20250704104601.310643-1-dlemoal@kernel.org
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata-eh: Rename and make ata_set_mode() static</title>
<updated>2025-07-04T08:36:00+00:00</updated>
<author>
<name>Damien Le Moal</name>
<email>dlemoal@kernel.org</email>
</author>
<published>2025-07-03T10:36:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=6ba4d05c1425fe220d95395b4485443ce895bb95'/>
<id>urn:sha1:6ba4d05c1425fe220d95395b4485443ce895bb95</id>
<content type='text'>
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 &lt;dlemoal@kernel.org&gt;
Reviewed-by: Niklas Cassel &lt;cassel@kernel.org&gt;
Link: https://lore.kernel.org/r/20250703103622.291272-4-dlemoal@kernel.org
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata-core: Make ata_dev_cleanup_cdl_resources() static</title>
<updated>2025-07-04T08:36:00+00:00</updated>
<author>
<name>Damien Le Moal</name>
<email>dlemoal@kernel.org</email>
</author>
<published>2025-07-03T10:36:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=6cbd989626b5695ec083e2a419372f10d0125900'/>
<id>urn:sha1:6cbd989626b5695ec083e2a419372f10d0125900</id>
<content type='text'>
The function ata_dev_cleanup_cdl_resources() is called only from
ata_dev_init_cdl_resources() and ata_dev_free_resources() which are
both defined in drivers/ata/libata-core.c. So there is no need for
ata_dev_cleanup_cdl_resources() to be visible from outside of this
file. Change this function definition to be a static function.

No functional changes.

Signed-off-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Reviewed-by: Niklas Cassel &lt;cassel@kernel.org&gt;
Link: https://lore.kernel.org/r/20250703103622.291272-3-dlemoal@kernel.org
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata-scsi: Cleanup ata_scsi_offline_dev()</title>
<updated>2025-06-30T01:25:45+00:00</updated>
<author>
<name>Damien Le Moal</name>
<email>dlemoal@kernel.org</email>
</author>
<published>2025-06-19T00:57:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=cb45e3ff431f96e905462313cb52c27b7c830709'/>
<id>urn:sha1:cb45e3ff431f96e905462313cb52c27b7c830709</id>
<content type='text'>
Change the function ata_scsi_offline_dev() to return a bool and change
this function kdoc comment to have the correct mention of its call site.
No functional changes.

Signed-off-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Reviewed-by: Hannes Reinecke &lt;hare@suse.de&gt;
Reviewed-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata: Remove ATA_DFLAG_ZAC device flag</title>
<updated>2025-06-30T01:25:45+00:00</updated>
<author>
<name>Damien Le Moal</name>
<email>dlemoal@kernel.org</email>
</author>
<published>2025-06-27T00:42:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=a0f26fcc383965e0522b81269062a9278bc802fe'/>
<id>urn:sha1:a0f26fcc383965e0522b81269062a9278bc802fe</id>
<content type='text'>
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 &lt;dlemoal@kernel.org&gt;
Reviewed-by: Hannes Reinecke &lt;hare@suse.de&gt;
Reviewed-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata-scsi: Do not set the INFORMATION field twice for ATA PT</title>
<updated>2025-04-25T01:23:14+00:00</updated>
<author>
<name>Igor Pylypiv</name>
<email>ipylypiv@google.com</email>
</author>
<published>2025-04-22T17:21:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=11533932f5c506f66281a147ff8469b97c108ab4'/>
<id>urn:sha1:11533932f5c506f66281a147ff8469b97c108ab4</id>
<content type='text'>
For ATA PASS-THROUGH + fixed format sense data + NCQ autosense
the INFORMATION sense data field is being written twice:

- 1st write: (redundant)
scsi_set_sense_information() sets the INFORMATION field to ATA LBA.
This is incorrect for ATA PASS-THROUGH.

- 2nd write: (correct)
ata_scsi_set_passthru_sense_fields() sets the INFORMATION field
to ATA ERROR/STATUS/DEVICE/COUNT(7:0) as per SAT spec.

There is no user-visible issue because second write overwrites
the incorrect data from the first write.

This patch eliminates the reduntant write by moving the INFORMATION
sense data field population logic to ata_scsi_qc_complete().

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>ata: libata: Improve CDL resource management</title>
<updated>2024-09-07T01:16:56+00:00</updated>
<author>
<name>Damien Le Moal</name>
<email>dlemoal@kernel.org</email>
</author>
<published>2024-07-17T08:55:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=602bcf212637633d537ee74bf39c6bc5722efb9b'/>
<id>urn:sha1:602bcf212637633d537ee74bf39c6bc5722efb9b</id>
<content type='text'>
The ncq_sense_buf buffer field of struct ata_port is allocated and used
only for devices that support the Command Duration Limits (CDL) feature.
However, the cdl buffer of struct ata_device, which is used to cache the
command duration limits log page for devices supporting CDL is always
allocated as part of struct ata_device, which is wasteful of memory for
devices that do not support this feature.

Clean this up by defining both buffers as part of the new ata_cdl
structure and allocating this structure only for devices that support
the CDL feature. This new structure is attached to struct ata_device
using the cdl pointer.

The functions ata_dev_init_cdl_resources() and
ata_dev_cleanup_cdl_resources() are defined to manage this new structure
allocation, initialization and freeing when a port is removed or a
device disabled. ata_dev_init_cdl_resources() is called from
ata_dev_config_cdl() only for devices that support CDL.
ata_dev_cleanup_cdl_resources() is called from ata_dev_free_resources()
to free the ata_cdl structure when a device is being disabled by EH.

Note that the name of the former cdl log buffer of struct ata_device is
changed to desc_log_buf to make it clearer that it is a buffer for the
limit descriptors log page.

This change reduces the size of struct ata_device, thus reducing memory
usage for ATA devices that do not support the CDL feature.

Signed-off-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Reviewed-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
</feed>
