Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: core: Make SCSI Status CONDITION MET equivalent to GOOD

The SCSI PRE-FETCH (10 or 16) command is present both on hard disks
and some SSDs. It is useful when the address of the next block(s) to
be read is known but it is not following the LBA of the current READ
(so read-ahead won't help). It returns two "good" SCSI Status values.
If the requested blocks have fitted (or will most likely fit (when
the IMMED bit is set)) into the disk's cache, it returns CONDITION
MET. If it didn't (or will not) fit then it returns GOOD status.

The goal of this patch is to stop the SCSI subsystem treating the
CONDITION MET SCSI status as an error. The current state makes the
PRE-FETCH command effectively unusable via pass-throughs.

Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Douglas Gilbert and committed by
Martin K. Petersen
1875ede0 217c55cd

+13
+11
drivers/scsi/scsi_lib.c
··· 867 867 /* for passthrough error may be set */ 868 868 error = BLK_STS_OK; 869 869 } 870 + /* 871 + * Another corner case: the SCSI status byte is non-zero but 'good'. 872 + * Example: PRE-FETCH command returns SAM_STAT_CONDITION_MET when 873 + * it is able to fit nominated LBs in its cache (and SAM_STAT_GOOD 874 + * if it can't fit). Treat SAM_STAT_CONDITION_MET and the related 875 + * intermediate statuses (both obsolete in SAM-4) as good. 876 + */ 877 + if (status_byte(result) && scsi_status_is_good(result)) { 878 + result = 0; 879 + error = BLK_STS_OK; 880 + } 870 881 871 882 /* 872 883 * special case: failed zero length commands always need to
+2
include/scsi/scsi.h
··· 47 47 */ 48 48 status &= 0xfe; 49 49 return ((status == SAM_STAT_GOOD) || 50 + (status == SAM_STAT_CONDITION_MET) || 51 + /* Next two "intermediate" statuses are obsolete in SAM-4 */ 50 52 (status == SAM_STAT_INTERMEDIATE) || 51 53 (status == SAM_STAT_INTERMEDIATE_CONDITION_MET) || 52 54 /* FIXME: this is obsolete in SAM-3 */