]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
scsi: core: Remember if a device is an ATA device
authorDamien Le Moal <dlemoal@kernel.org>
Wed, 11 Jun 2025 09:34:21 +0000 (18:34 +0900)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 16 Jun 2025 18:29:59 +0000 (14:29 -0400)
scsi_add_lun() tests the device vendor string of SCSI devices to detect
if a SCSI device is in fact an ATA device, in order to correctly handle
SATL power management. The function scsi_cdl_enable() also requires
knowing if a SCSI device is an ATA device to control the state of the
device CDL feature but this function does that by testing for the
presence of the VPD page 89h (ATA INFORMATION page).
sd_read_write_same() also has a similar test.

Simplify these different methods by adding the is_ata field to struct
scsi_device to remember that a SCSI device is in fact an ATA one based
on the device vendor name test. This field can also allow low level
SCSI host adapter drivers to take special actions for ATA devices
(e.g. to better handle ATA NCQ errors).

With this, simplify scsi_cdl_enable() and sd_read_write_same().

Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Link: https://lore.kernel.org/r/20250611093421.2901633-1-dlemoal@kernel.org
Reviewed-by: Igor Pylypiv <ipylypiv@google.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi.c
drivers/scsi/scsi_scan.c
drivers/scsi/sd.c
include/scsi/scsi_device.h

index 518a252eb6aa0546b832232cad4a22e92d48cd62..534310224e8f8479b9d9589ae01c641e219d518c 100644 (file)
@@ -708,20 +708,15 @@ void scsi_cdl_check(struct scsi_device *sdev)
 int scsi_cdl_enable(struct scsi_device *sdev, bool enable)
 {
        char buf[64];
-       bool is_ata;
        int ret;
 
        if (!sdev->cdl_supported)
                return -EOPNOTSUPP;
 
-       rcu_read_lock();
-       is_ata = rcu_dereference(sdev->vpd_pg89);
-       rcu_read_unlock();
-
        /*
         * For ATA devices, CDL needs to be enabled with a SET FEATURES command.
         */
-       if (is_ata) {
+       if (sdev->is_ata) {
                struct scsi_mode_data data;
                struct scsi_sense_hdr sshdr;
                char *buf_data;
index 4833b8fe251b885d6edfcbdbd6bfcb3f16975fdd..160c2f74c7e7aeaf1ec9bd4965fff0f948aa97cd 100644 (file)
@@ -909,7 +909,8 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
        sdev->model = (char *) (sdev->inquiry + 16);
        sdev->rev = (char *) (sdev->inquiry + 32);
 
-       if (strncmp(sdev->vendor, "ATA     ", 8) == 0) {
+       sdev->is_ata = strncmp(sdev->vendor, "ATA     ", 8) == 0;
+       if (sdev->is_ata) {
                /*
                 * sata emulation layer device.  This is a hack to work around
                 * the SATL power management specifications which state that
index 3f6e87705b62e59a5bf599d414f9ae7b3a61c3cb..daddef2e9e875e43b5605ec7d4041b1ce06ffd33 100644 (file)
@@ -3459,19 +3459,14 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
        }
 
        if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY, 0) < 0) {
-               struct scsi_vpd *vpd;
-
                sdev->no_report_opcodes = 1;
 
-               /* Disable WRITE SAME if REPORT SUPPORTED OPERATION
-                * CODES is unsupported and the device has an ATA
-                * Information VPD page (SAT).
+               /*
+                * Disable WRITE SAME if REPORT SUPPORTED OPERATION CODES is
+                * unsupported and this is an ATA device.
                 */
-               rcu_read_lock();
-               vpd = rcu_dereference(sdev->vpd_pg89);
-               if (vpd)
+               if (sdev->is_ata)
                        sdev->no_write_same = 1;
-               rcu_read_unlock();
        }
 
        if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, WRITE_SAME_16, 0) == 1)
index 68dd49947d041d1656a74fac9bb496abacfc3c75..6d6500148c4b746c3b364bc8ed4adce649c12233 100644 (file)
@@ -184,6 +184,11 @@ struct scsi_device {
         */
        unsigned force_runtime_start_on_system_start:1;
 
+       /*
+        * Set if the device is an ATA device.
+        */
+       unsigned is_ata:1;
+
        unsigned removable:1;
        unsigned changed:1;     /* Data invalid due to media change */
        unsigned busy:1;        /* Used to prevent races */