ata fixes for 7.2-rc2

- Quirk the Phison PS3111-S11 SSD with NOLPM due to its defective link
    power management (Bryam).
 
  - Strengthen checks on a device concurrent positioning range
    information to make sure to reject any invalid report (Bryam).
 
  - Fix probe error handling in the pata_pxa and sata_gemini drivers
    (Myeonghun, Wentao).
 
  - Limit buffer size of replies from translated commands to what libata
    actually generated (Karuna)
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQSRPv8tYSvhwAzJdzjdoc3SxdoYdgUCakc/rAAKCRDdoc3SxdoY
 dp4BAQC5DDPG9r9/fitNLy+Sm8lJtFMhjd2JTY405ZghCNUoOQD+KaBwFmK7/rny
 QuD0UtF9SV4swbQka2n83ZGCTLmIrgA=
 =x7nY
 -----END PGP SIGNATURE-----

Merge tag 'ata-7.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux

Pull ata fixes from Damien Le Moal:

 - Quirk the Phison PS3111-S11 SSD with NOLPM due to its defective
   link power management (Bryam)

 - Strengthen checks on a device concurrent positioning range
   information to make sure to reject any invalid report (Bryam)

 - Fix probe error handling in the pata_pxa and sata_gemini
   drivers (Myeonghun, Wentao)

 - Limit buffer size of replies from translated commands to what
   libata actually generated (Karuna)

* tag 'ata-7.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux:
  ata: libata-scsi: limit simulated SCSI command copy to response length
  ata: pata_pxa: Fix DMA channel leak on probe error
  ata: sata_gemini: unwind clocks on IDE pinctrl errors
  ata: libata-core: Reject an invalid concurrent positioning ranges count
  ata: libata-core: Add NOLPM quirk for PNY CS900 1TB SSD
This commit is contained in:
Linus Torvalds 2026-07-02 20:05:43 -10:00
commit c85167c926
5 changed files with 38 additions and 4 deletions

View File

@ -2847,6 +2847,24 @@ static void ata_dev_config_cpr(struct ata_device *dev)
if (!nr_cpr)
goto out;
/*
* The device reports the number of CPR descriptors independently of the
* log size, and that count is also used to emit VPD page B9h into the
* fixed-size rbuf. Reject a count larger than what that buffer can hold
* (ATA_DEV_MAX_CPR) or larger than the log the device actually returned.
*/
if (nr_cpr > ATA_DEV_MAX_CPR) {
ata_dev_warn(dev,
"Too many concurrent positioning ranges\n");
goto out;
}
if (buf_len < 64 + (size_t)nr_cpr * 32) {
ata_dev_warn(dev,
"Invalid number of concurrent positioning ranges\n");
goto out;
}
cpr_log = kzalloc_flex(*cpr_log, cpr, nr_cpr);
if (!cpr_log)
goto out;
@ -4295,6 +4313,9 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = {
/* Apacer models with LPM issues */
{ "Apacer AS340*", NULL, ATA_QUIRK_NOLPM },
/* PNY CS900 (Phison PS3111-S11, DRAM-less) drops the link on DIPM */
{ "PNY CS900 1TB SSD", NULL, ATA_QUIRK_NOLPM },
/* Silicon Motion models with LPM issues */
{ "MD619HXCLDE3TC", "TCVAID", ATA_QUIRK_NOLPM },
{ "MD619GXCLDE3TC", "TCV35D", ATA_QUIRK_NOLPM },

View File

@ -37,8 +37,6 @@
#include "libata.h"
#include "libata-transport.h"
#define ATA_SCSI_RBUF_SIZE 2048
static DEFINE_SPINLOCK(ata_scsi_rbuf_lock);
static u8 ata_scsi_rbuf[ATA_SCSI_RBUF_SIZE];
@ -1933,8 +1931,13 @@ static void ata_scsi_rbuf_fill(struct ata_device *dev, struct scsi_cmnd *cmd,
memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE);
len = actor(dev, cmd, ata_scsi_rbuf);
if (len) {
if (WARN_ON(len > ATA_SCSI_RBUF_SIZE)) {
ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0);
spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags);
return;
}
sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE);
ata_scsi_rbuf, len);
cmd->result = SAM_STAT_GOOD;
if (scsi_bufflen(cmd) > len)
scsi_set_resid(cmd, scsi_bufflen(cmd) - len);

View File

@ -149,6 +149,15 @@ static inline bool ata_acpi_dev_manage_restart(struct ata_device *dev) { return
#endif
/* libata-scsi.c */
#define ATA_SCSI_RBUF_SIZE 2048
/*
* Maximum number of concurrent positioning ranges (CPR) supported. The ACS
* specifications allow up to 255, but we limit this to the number of CPR
* descriptors that fit in the rbuf buffer used to emit VPD page B9h.
*/
#define ATA_DEV_MAX_CPR min(255, ((ATA_SCSI_RBUF_SIZE - 64) / 32))
extern struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
const struct scsi_device *scsidev);
extern int ata_scsi_add_hosts(struct ata_host *host,

View File

@ -286,6 +286,7 @@ static int pxa_ata_probe(struct platform_device *pdev)
ret = dmaengine_slave_config(data->dma_chan, &config);
if (ret < 0) {
dev_err(&pdev->dev, "dma configuration failed: %d\n", ret);
dma_release_channel(data->dma_chan);
return ret;
}

View File

@ -353,7 +353,7 @@ static int gemini_sata_probe(struct platform_device *pdev)
if (sg->ide_pins) {
ret = gemini_setup_ide_pins(dev);
if (ret)
return ret;
goto out_unprep_clk;
}
dev_info(dev, "set up the Gemini IDE/SATA nexus\n");