Skip to content

Commit 2132df1

Browse files
damien-lemoalmartinkpetersen
authored andcommitted
scsi: core: ata: Do no try to probe for CDL on old drives
Some old drives (e.g. an Ultra320 SCSI disk as reported by John) do not seem to execute MAINTENANCE_IN / MI_REPORT_SUPPORTED_OPERATION_CODES commands correctly and hang when a non-zero service action is specified (one command format with service action case in scsi_report_opcode()). Currently, CDL probing with scsi_cdl_check_cmd() is the only caller using a non zero service action for scsi_report_opcode(). To avoid issues with these old drives, do not attempt CDL probe if the device reports support for an SPC version lower than 5 (CDL was introduced in SPC-5). To keep things working with ATA devices which probe for the CDL T2A and T2B pages introduced with SPC-6, modify ata_scsiop_inq_std() to claim SPC-6 version compatibility for ATA drives supporting CDL. SPC-6 standard version number is defined as Dh (= 13) in SPC-6 r09. Fix scsi_probe_lun() to correctly capture this value by changing the bit mask for the second byte of the INQUIRY response from 0x7 to 0xf. include/scsi/scsi.h is modified to add the definition SCSI_SPC_6 with the value 14 (Dh + 1). The missing definitions for the SCSI_SPC_4 and SCSI_SPC_5 versions are also added. Reported-by: John David Anglin <dave.anglin@bell.net> Fixes: 6248852 ("scsi: core: Detect support for command duration limits") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20230915022034.678121-1-dlemoal@kernel.org Tested-by: David Gow <david@davidgow.net> Reviewed-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent dae40be commit 2132df1

File tree

4 files changed

+18
-1
lines changed

4 files changed

+18
-1
lines changed

drivers/ata/libata-scsi.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,6 +1835,9 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
18351835
hdr[2] = 0x7; /* claim SPC-5 version compatibility */
18361836
}
18371837

1838+
if (args->dev->flags & ATA_DFLAG_CDL)
1839+
hdr[2] = 0xd; /* claim SPC-6 version compatibility */
1840+
18381841
memcpy(rbuf, hdr, sizeof(hdr));
18391842
memcpy(&rbuf[8], "ATA ", 8);
18401843
ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16);

drivers/scsi/scsi.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,17 @@ void scsi_cdl_check(struct scsi_device *sdev)
613613
bool cdl_supported;
614614
unsigned char *buf;
615615

616+
/*
617+
* Support for CDL was defined in SPC-5. Ignore devices reporting an
618+
* lower SPC version. This also avoids problems with old drives choking
619+
* on MAINTENANCE_IN / MI_REPORT_SUPPORTED_OPERATION_CODES with a
620+
* service action specified, as done in scsi_cdl_check_cmd().
621+
*/
622+
if (sdev->scsi_level < SCSI_SPC_5) {
623+
sdev->cdl_supported = 0;
624+
return;
625+
}
626+
616627
buf = kmalloc(SCSI_CDL_CHECK_BUF_LEN, GFP_KERNEL);
617628
if (!buf) {
618629
sdev->cdl_supported = 0;

drivers/scsi/scsi_scan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
822822
* device is attached at LUN 0 (SCSI_SCAN_TARGET_PRESENT) so
823823
* non-zero LUNs can be scanned.
824824
*/
825-
sdev->scsi_level = inq_result[2] & 0x07;
825+
sdev->scsi_level = inq_result[2] & 0x0f;
826826
if (sdev->scsi_level >= 2 ||
827827
(sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1))
828828
sdev->scsi_level++;

include/scsi/scsi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ enum scsi_disposition {
157157
#define SCSI_3 4 /* SPC */
158158
#define SCSI_SPC_2 5
159159
#define SCSI_SPC_3 6
160+
#define SCSI_SPC_4 7
161+
#define SCSI_SPC_5 8
162+
#define SCSI_SPC_6 14
160163

161164
/*
162165
* INQ PERIPHERAL QUALIFIERS

0 commit comments

Comments
 (0)