Skip to content

Commit

Permalink
hwmon: (drivetemp) Avoid SCT usage on Toshiba DT01ACA family drives
Browse files Browse the repository at this point in the history
It has been observed that Toshiba DT01ACA family drives have
WRITE FPDMA QUEUED command timeouts and sometimes just freeze until
power-cycled under heavy write loads when their temperature is getting
polled in SCT mode. The SMART mode seems to be fine, though.

Let's make sure we don't use SCT mode for these drives then.

While only the 3 TB model was actually caught exhibiting the problem let's
play safe here to avoid data corruption and extend the ban to the whole
family.

Fixes: 5b46903 ("hwmon: Driver for disk and solid state drives with temperature sensors")
Cc: [email protected]
Signed-off-by: Maciej S. Szmigiero <[email protected]>
Link: https://lore.kernel.org/r/0cb2e7022b66c6d21d3f189a12a97878d0e7511b.1595075458.git.mail@maciej.szmigiero.name
Signed-off-by: Guenter Roeck <[email protected]>
  • Loading branch information
maciejsszmigiero authored and groeck committed Jul 18, 2020
1 parent 3ce17cd commit c66ef39
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions drivers/hwmon/drivetemp.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,42 @@ static int drivetemp_get_scttemp(struct drivetemp_data *st, u32 attr, long *val)
return err;
}

static const char * const sct_avoid_models[] = {
/*
* These drives will have WRITE FPDMA QUEUED command timeouts and sometimes just
* freeze until power-cycled under heavy write loads when their temperature is
* getting polled in SCT mode. The SMART mode seems to be fine, though.
*
* While only the 3 TB model (DT01ACA3) was actually caught exhibiting the
* problem let's play safe here to avoid data corruption and ban the whole
* DT01ACAx family.
* The models from this array are prefix-matched.
*/
"TOSHIBA DT01ACA",
};

static bool drivetemp_sct_avoid(struct drivetemp_data *st)
{
struct scsi_device *sdev = st->sdev;
unsigned int ctr;

if (!sdev->model)
return false;

/*
* The "model" field contains just the raw SCSI INQUIRY response
* "product identification" field, which has a width of 16 bytes.
* This field is space-filled, but is NOT NULL-terminated.
*/
for (ctr = 0; ctr < ARRAY_SIZE(sct_avoid_models); ctr++)
if (!strncmp(sdev->model, sct_avoid_models[ctr],
strlen(sct_avoid_models[ctr])))
return true;

return false;
}

static int drivetemp_identify_sata(struct drivetemp_data *st)
{
struct scsi_device *sdev = st->sdev;
Expand Down Expand Up @@ -326,6 +362,13 @@ static int drivetemp_identify_sata(struct drivetemp_data *st)
/* bail out if this is not a SATA device */
if (!is_ata || !is_sata)
return -ENODEV;

if (have_sct && drivetemp_sct_avoid(st)) {
dev_notice(&sdev->sdev_gendev,
"will avoid using SCT for temperature monitoring\n");
have_sct = false;
}

if (!have_sct)
goto skip_sct;

Expand Down

0 comments on commit c66ef39

Please sign in to comment.