xref: /openbmc/linux/drivers/hwmon/drivetemp.c (revision 4baf4a2919b2a13a7f67d63f34b03f823ea7c0e8)
15b46903dSGuenter Roeck // SPDX-License-Identifier: GPL-2.0
25b46903dSGuenter Roeck /*
35b46903dSGuenter Roeck  * Hwmon client for disk and solid state drives with temperature sensors
45b46903dSGuenter Roeck  * Copyright (C) 2019 Zodiac Inflight Innovations
55b46903dSGuenter Roeck  *
65b46903dSGuenter Roeck  * With input from:
75b46903dSGuenter Roeck  *    Hwmon client for S.M.A.R.T. hard disk drives with temperature sensors.
85b46903dSGuenter Roeck  *    (C) 2018 Linus Walleij
95b46903dSGuenter Roeck  *
105b46903dSGuenter Roeck  *    hwmon: Driver for SCSI/ATA temperature sensors
115b46903dSGuenter Roeck  *    by Constantin Baranov <const@mimas.ru>, submitted September 2009
125b46903dSGuenter Roeck  *
13bde58ca8SCorentin Labbe  * This drive supports reporting the temperature of SATA drives. It can be
145b46903dSGuenter Roeck  * easily extended to report the temperature of SCSI drives.
155b46903dSGuenter Roeck  *
165b46903dSGuenter Roeck  * The primary means to read drive temperatures and temperature limits
175b46903dSGuenter Roeck  * for ATA drives is the SCT Command Transport feature set as specified in
185b46903dSGuenter Roeck  * ATA8-ACS.
195b46903dSGuenter Roeck  * It can be used to read the current drive temperature, temperature limits,
205b46903dSGuenter Roeck  * and historic minimum and maximum temperatures. The SCT Command Transport
215b46903dSGuenter Roeck  * feature set is documented in "AT Attachment 8 - ATA/ATAPI Command Set
225b46903dSGuenter Roeck  * (ATA8-ACS)".
235b46903dSGuenter Roeck  *
245b46903dSGuenter Roeck  * If the SCT Command Transport feature set is not available, drive temperatures
255b46903dSGuenter Roeck  * may be readable through SMART attributes. Since SMART attributes are not well
265b46903dSGuenter Roeck  * defined, this method is only used as fallback mechanism.
275b46903dSGuenter Roeck  *
285b46903dSGuenter Roeck  * There are three SMART attributes which may report drive temperatures.
295b46903dSGuenter Roeck  * Those are defined as follows (from
305b46903dSGuenter Roeck  * http://www.cropel.com/library/smart-attribute-list.aspx).
315b46903dSGuenter Roeck  *
325b46903dSGuenter Roeck  * 190	Temperature	Temperature, monitored by a sensor somewhere inside
335b46903dSGuenter Roeck  *			the drive. Raw value typicaly holds the actual
345b46903dSGuenter Roeck  *			temperature (hexadecimal) in its rightmost two digits.
355b46903dSGuenter Roeck  *
365b46903dSGuenter Roeck  * 194	Temperature	Temperature, monitored by a sensor somewhere inside
375b46903dSGuenter Roeck  *			the drive. Raw value typicaly holds the actual
385b46903dSGuenter Roeck  *			temperature (hexadecimal) in its rightmost two digits.
395b46903dSGuenter Roeck  *
405b46903dSGuenter Roeck  * 231	Temperature	Temperature, monitored by a sensor somewhere inside
415b46903dSGuenter Roeck  *			the drive. Raw value typicaly holds the actual
425b46903dSGuenter Roeck  *			temperature (hexadecimal) in its rightmost two digits.
435b46903dSGuenter Roeck  *
445b46903dSGuenter Roeck  * Wikipedia defines attributes a bit differently.
455b46903dSGuenter Roeck  *
465b46903dSGuenter Roeck  * 190	Temperature	Value is equal to (100-temp. °C), allowing manufacturer
475b46903dSGuenter Roeck  *	Difference or	to set a minimum threshold which corresponds to a
485b46903dSGuenter Roeck  *	Airflow		maximum temperature. This also follows the convention of
495b46903dSGuenter Roeck  *	Temperature	100 being a best-case value and lower values being
505b46903dSGuenter Roeck  *			undesirable. However, some older drives may instead
515b46903dSGuenter Roeck  *			report raw Temperature (identical to 0xC2) or
525b46903dSGuenter Roeck  *			Temperature minus 50 here.
535b46903dSGuenter Roeck  * 194	Temperature or	Indicates the device temperature, if the appropriate
545b46903dSGuenter Roeck  *	Temperature	sensor is fitted. Lowest byte of the raw value contains
555b46903dSGuenter Roeck  *	Celsius		the exact temperature value (Celsius degrees).
565b46903dSGuenter Roeck  * 231	Life Left	Indicates the approximate SSD life left, in terms of
575b46903dSGuenter Roeck  *	(SSDs) or	program/erase cycles or available reserved blocks.
585b46903dSGuenter Roeck  *	Temperature	A normalized value of 100 represents a new drive, with
595b46903dSGuenter Roeck  *			a threshold value at 10 indicating a need for
605b46903dSGuenter Roeck  *			replacement. A value of 0 may mean that the drive is
615b46903dSGuenter Roeck  *			operating in read-only mode to allow data recovery.
625b46903dSGuenter Roeck  *			Previously (pre-2010) occasionally used for Drive
635b46903dSGuenter Roeck  *			Temperature (more typically reported at 0xC2).
645b46903dSGuenter Roeck  *
655b46903dSGuenter Roeck  * Common denominator is that the first raw byte reports the temperature
665b46903dSGuenter Roeck  * in degrees C on almost all drives. Some drives may report a fractional
675b46903dSGuenter Roeck  * temperature in the second raw byte.
685b46903dSGuenter Roeck  *
695b46903dSGuenter Roeck  * Known exceptions (from libatasmart):
705b46903dSGuenter Roeck  * - SAMSUNG SV0412H and SAMSUNG SV1204H) report the temperature in 10th
715b46903dSGuenter Roeck  *   degrees C in the first two raw bytes.
725b46903dSGuenter Roeck  * - A few Maxtor drives report an unknown or bad value in attribute 194.
735b46903dSGuenter Roeck  * - Certain Apple SSD drives report an unknown value in attribute 190.
745b46903dSGuenter Roeck  *   Only certain firmware versions are affected.
755b46903dSGuenter Roeck  *
765b46903dSGuenter Roeck  * Those exceptions affect older ATA drives and are currently ignored.
775b46903dSGuenter Roeck  * Also, the second raw byte (possibly reporting the fractional temperature)
785b46903dSGuenter Roeck  * is currently ignored.
795b46903dSGuenter Roeck  *
805b46903dSGuenter Roeck  * Many drives also report temperature limits in additional SMART data raw
815b46903dSGuenter Roeck  * bytes. The format of those is not well defined and varies widely.
825b46903dSGuenter Roeck  * The driver does not currently attempt to report those limits.
835b46903dSGuenter Roeck  *
845b46903dSGuenter Roeck  * According to data in smartmontools, attribute 231 is rarely used to report
855b46903dSGuenter Roeck  * drive temperatures. At the same time, several drives report SSD life left
865b46903dSGuenter Roeck  * in attribute 231, but do not support temperature sensors. For this reason,
875b46903dSGuenter Roeck  * attribute 231 is currently ignored.
885b46903dSGuenter Roeck  *
895b46903dSGuenter Roeck  * Following above definitions, temperatures are reported as follows.
905b46903dSGuenter Roeck  *   If SCT Command Transport is supported, it is used to read the
915b46903dSGuenter Roeck  *   temperature and, if available, temperature limits.
925b46903dSGuenter Roeck  * - Otherwise, if SMART attribute 194 is supported, it is used to read
935b46903dSGuenter Roeck  *   the temperature.
945b46903dSGuenter Roeck  * - Otherwise, if SMART attribute 190 is supported, it is used to read
955b46903dSGuenter Roeck  *   the temperature.
965b46903dSGuenter Roeck  */
975b46903dSGuenter Roeck 
985b46903dSGuenter Roeck #include <linux/ata.h>
995b46903dSGuenter Roeck #include <linux/bits.h>
1005b46903dSGuenter Roeck #include <linux/device.h>
1015b46903dSGuenter Roeck #include <linux/hwmon.h>
1025b46903dSGuenter Roeck #include <linux/kernel.h>
1035b46903dSGuenter Roeck #include <linux/list.h>
1045b46903dSGuenter Roeck #include <linux/module.h>
1055b46903dSGuenter Roeck #include <linux/mutex.h>
1065b46903dSGuenter Roeck #include <scsi/scsi_cmnd.h>
1075b46903dSGuenter Roeck #include <scsi/scsi_device.h>
1085b46903dSGuenter Roeck #include <scsi/scsi_driver.h>
1095b46903dSGuenter Roeck #include <scsi/scsi_proto.h>
1105b46903dSGuenter Roeck 
1115b46903dSGuenter Roeck struct drivetemp_data {
1125b46903dSGuenter Roeck 	struct list_head list;		/* list of instantiated devices */
1135b46903dSGuenter Roeck 	struct mutex lock;		/* protect data buffer accesses */
1145b46903dSGuenter Roeck 	struct scsi_device *sdev;	/* SCSI device */
1155b46903dSGuenter Roeck 	struct device *dev;		/* instantiating device */
1165b46903dSGuenter Roeck 	struct device *hwdev;		/* hardware monitoring device */
1175b46903dSGuenter Roeck 	u8 smartdata[ATA_SECT_SIZE];	/* local buffer */
1185b46903dSGuenter Roeck 	int (*get_temp)(struct drivetemp_data *st, u32 attr, long *val);
1195b46903dSGuenter Roeck 	bool have_temp_lowest;		/* lowest temp in SCT status */
1205b46903dSGuenter Roeck 	bool have_temp_highest;		/* highest temp in SCT status */
1215b46903dSGuenter Roeck 	bool have_temp_min;		/* have min temp */
1225b46903dSGuenter Roeck 	bool have_temp_max;		/* have max temp */
1235b46903dSGuenter Roeck 	bool have_temp_lcrit;		/* have lower critical limit */
1245b46903dSGuenter Roeck 	bool have_temp_crit;		/* have critical limit */
1255b46903dSGuenter Roeck 	int temp_min;			/* min temp */
1265b46903dSGuenter Roeck 	int temp_max;			/* max temp */
1275b46903dSGuenter Roeck 	int temp_lcrit;			/* lower critical limit */
1285b46903dSGuenter Roeck 	int temp_crit;			/* critical limit */
1295b46903dSGuenter Roeck };
1305b46903dSGuenter Roeck 
1315b46903dSGuenter Roeck static LIST_HEAD(drivetemp_devlist);
1325b46903dSGuenter Roeck 
1335b46903dSGuenter Roeck #define ATA_MAX_SMART_ATTRS	30
1345b46903dSGuenter Roeck #define SMART_TEMP_PROP_190	190
1355b46903dSGuenter Roeck #define SMART_TEMP_PROP_194	194
1365b46903dSGuenter Roeck 
1375b46903dSGuenter Roeck #define SCT_STATUS_REQ_ADDR	0xe0
1385b46903dSGuenter Roeck #define  SCT_STATUS_VERSION_LOW		0	/* log byte offsets */
1395b46903dSGuenter Roeck #define  SCT_STATUS_VERSION_HIGH	1
1405b46903dSGuenter Roeck #define  SCT_STATUS_TEMP		200
1415b46903dSGuenter Roeck #define  SCT_STATUS_TEMP_LOWEST		201
1425b46903dSGuenter Roeck #define  SCT_STATUS_TEMP_HIGHEST	202
1435b46903dSGuenter Roeck #define SCT_READ_LOG_ADDR	0xe1
1445b46903dSGuenter Roeck #define  SMART_READ_LOG			0xd5
1455b46903dSGuenter Roeck #define  SMART_WRITE_LOG		0xd6
1465b46903dSGuenter Roeck 
1475b46903dSGuenter Roeck #define INVALID_TEMP		0x80
1485b46903dSGuenter Roeck 
1495b46903dSGuenter Roeck #define temp_is_valid(temp)	((temp) != INVALID_TEMP)
1505b46903dSGuenter Roeck #define temp_from_sct(temp)	(((s8)(temp)) * 1000)
1515b46903dSGuenter Roeck 
ata_id_smart_supported(u16 * id)1525b46903dSGuenter Roeck static inline bool ata_id_smart_supported(u16 *id)
1535b46903dSGuenter Roeck {
1545b46903dSGuenter Roeck 	return id[ATA_ID_COMMAND_SET_1] & BIT(0);
1555b46903dSGuenter Roeck }
1565b46903dSGuenter Roeck 
ata_id_smart_enabled(u16 * id)1575b46903dSGuenter Roeck static inline bool ata_id_smart_enabled(u16 *id)
1585b46903dSGuenter Roeck {
1595b46903dSGuenter Roeck 	return id[ATA_ID_CFS_ENABLE_1] & BIT(0);
1605b46903dSGuenter Roeck }
1615b46903dSGuenter Roeck 
drivetemp_scsi_command(struct drivetemp_data * st,u8 ata_command,u8 feature,u8 lba_low,u8 lba_mid,u8 lba_high)1625b46903dSGuenter Roeck static int drivetemp_scsi_command(struct drivetemp_data *st,
1635b46903dSGuenter Roeck 				 u8 ata_command, u8 feature,
1645b46903dSGuenter Roeck 				 u8 lba_low, u8 lba_mid, u8 lba_high)
1655b46903dSGuenter Roeck {
1665b46903dSGuenter Roeck 	u8 scsi_cmd[MAX_COMMAND_SIZE];
16708e95a2bSMike Christie 	enum req_op op;
16853e25b10SDaniil Stas 	int err;
1695b46903dSGuenter Roeck 
1705b46903dSGuenter Roeck 	memset(scsi_cmd, 0, sizeof(scsi_cmd));
1715b46903dSGuenter Roeck 	scsi_cmd[0] = ATA_16;
1725b46903dSGuenter Roeck 	if (ata_command == ATA_CMD_SMART && feature == SMART_WRITE_LOG) {
1735b46903dSGuenter Roeck 		scsi_cmd[1] = (5 << 1);	/* PIO Data-out */
1745b46903dSGuenter Roeck 		/*
1755b46903dSGuenter Roeck 		 * No off.line or cc, write to dev, block count in sector count
1765b46903dSGuenter Roeck 		 * field.
1775b46903dSGuenter Roeck 		 */
1785b46903dSGuenter Roeck 		scsi_cmd[2] = 0x06;
17908e95a2bSMike Christie 		op = REQ_OP_DRV_OUT;
1805b46903dSGuenter Roeck 	} else {
1815b46903dSGuenter Roeck 		scsi_cmd[1] = (4 << 1);	/* PIO Data-in */
1825b46903dSGuenter Roeck 		/*
1835b46903dSGuenter Roeck 		 * No off.line or cc, read from dev, block count in sector count
1845b46903dSGuenter Roeck 		 * field.
1855b46903dSGuenter Roeck 		 */
1865b46903dSGuenter Roeck 		scsi_cmd[2] = 0x0e;
18708e95a2bSMike Christie 		op = REQ_OP_DRV_IN;
1885b46903dSGuenter Roeck 	}
1895b46903dSGuenter Roeck 	scsi_cmd[4] = feature;
1905b46903dSGuenter Roeck 	scsi_cmd[6] = 1;	/* 1 sector */
1915b46903dSGuenter Roeck 	scsi_cmd[8] = lba_low;
1925b46903dSGuenter Roeck 	scsi_cmd[10] = lba_mid;
1935b46903dSGuenter Roeck 	scsi_cmd[12] = lba_high;
1945b46903dSGuenter Roeck 	scsi_cmd[14] = ata_command;
1955b46903dSGuenter Roeck 
19653e25b10SDaniil Stas 	err = scsi_execute_cmd(st->sdev, scsi_cmd, op, st->smartdata,
197*85af156eSRussell Harmon 			       ATA_SECT_SIZE, 10 * HZ, 5, NULL);
19853e25b10SDaniil Stas 	if (err > 0)
19953e25b10SDaniil Stas 		err = -EIO;
20053e25b10SDaniil Stas 	return err;
2015b46903dSGuenter Roeck }
2025b46903dSGuenter Roeck 
drivetemp_ata_command(struct drivetemp_data * st,u8 feature,u8 select)2035b46903dSGuenter Roeck static int drivetemp_ata_command(struct drivetemp_data *st, u8 feature,
2045b46903dSGuenter Roeck 				 u8 select)
2055b46903dSGuenter Roeck {
2065b46903dSGuenter Roeck 	return drivetemp_scsi_command(st, ATA_CMD_SMART, feature, select,
2075b46903dSGuenter Roeck 				     ATA_SMART_LBAM_PASS, ATA_SMART_LBAH_PASS);
2085b46903dSGuenter Roeck }
2095b46903dSGuenter Roeck 
drivetemp_get_smarttemp(struct drivetemp_data * st,u32 attr,long * temp)2105b46903dSGuenter Roeck static int drivetemp_get_smarttemp(struct drivetemp_data *st, u32 attr,
2115b46903dSGuenter Roeck 				  long *temp)
2125b46903dSGuenter Roeck {
2135b46903dSGuenter Roeck 	u8 *buf = st->smartdata;
2145b46903dSGuenter Roeck 	bool have_temp = false;
2155b46903dSGuenter Roeck 	u8 temp_raw;
2165b46903dSGuenter Roeck 	u8 csum;
2175b46903dSGuenter Roeck 	int err;
2185b46903dSGuenter Roeck 	int i;
2195b46903dSGuenter Roeck 
2205b46903dSGuenter Roeck 	err = drivetemp_ata_command(st, ATA_SMART_READ_VALUES, 0);
2215b46903dSGuenter Roeck 	if (err)
2225b46903dSGuenter Roeck 		return err;
2235b46903dSGuenter Roeck 
2245b46903dSGuenter Roeck 	/* Checksum the read value table */
2255b46903dSGuenter Roeck 	csum = 0;
2265b46903dSGuenter Roeck 	for (i = 0; i < ATA_SECT_SIZE; i++)
2275b46903dSGuenter Roeck 		csum += buf[i];
2285b46903dSGuenter Roeck 	if (csum) {
2295b46903dSGuenter Roeck 		dev_dbg(&st->sdev->sdev_gendev,
2305b46903dSGuenter Roeck 			"checksum error reading SMART values\n");
2315b46903dSGuenter Roeck 		return -EIO;
2325b46903dSGuenter Roeck 	}
2335b46903dSGuenter Roeck 
2345b46903dSGuenter Roeck 	for (i = 0; i < ATA_MAX_SMART_ATTRS; i++) {
2355b46903dSGuenter Roeck 		u8 *attr = buf + i * 12;
2365b46903dSGuenter Roeck 		int id = attr[2];
2375b46903dSGuenter Roeck 
2385b46903dSGuenter Roeck 		if (!id)
2395b46903dSGuenter Roeck 			continue;
2405b46903dSGuenter Roeck 
2415b46903dSGuenter Roeck 		if (id == SMART_TEMP_PROP_190) {
2425b46903dSGuenter Roeck 			temp_raw = attr[7];
2435b46903dSGuenter Roeck 			have_temp = true;
2445b46903dSGuenter Roeck 		}
2455b46903dSGuenter Roeck 		if (id == SMART_TEMP_PROP_194) {
2465b46903dSGuenter Roeck 			temp_raw = attr[7];
2475b46903dSGuenter Roeck 			have_temp = true;
2485b46903dSGuenter Roeck 			break;
2495b46903dSGuenter Roeck 		}
2505b46903dSGuenter Roeck 	}
2515b46903dSGuenter Roeck 
2525b46903dSGuenter Roeck 	if (have_temp) {
2535b46903dSGuenter Roeck 		*temp = temp_raw * 1000;
2545b46903dSGuenter Roeck 		return 0;
2555b46903dSGuenter Roeck 	}
2565b46903dSGuenter Roeck 
2575b46903dSGuenter Roeck 	return -ENXIO;
2585b46903dSGuenter Roeck }
2595b46903dSGuenter Roeck 
drivetemp_get_scttemp(struct drivetemp_data * st,u32 attr,long * val)2605b46903dSGuenter Roeck static int drivetemp_get_scttemp(struct drivetemp_data *st, u32 attr, long *val)
2615b46903dSGuenter Roeck {
2625b46903dSGuenter Roeck 	u8 *buf = st->smartdata;
2635b46903dSGuenter Roeck 	int err;
2645b46903dSGuenter Roeck 
2655b46903dSGuenter Roeck 	err = drivetemp_ata_command(st, SMART_READ_LOG, SCT_STATUS_REQ_ADDR);
2665b46903dSGuenter Roeck 	if (err)
2675b46903dSGuenter Roeck 		return err;
2685b46903dSGuenter Roeck 	switch (attr) {
2695b46903dSGuenter Roeck 	case hwmon_temp_input:
270ed08ebb7SGuenter Roeck 		if (!temp_is_valid(buf[SCT_STATUS_TEMP]))
271ed08ebb7SGuenter Roeck 			return -ENODATA;
2725b46903dSGuenter Roeck 		*val = temp_from_sct(buf[SCT_STATUS_TEMP]);
2735b46903dSGuenter Roeck 		break;
2745b46903dSGuenter Roeck 	case hwmon_temp_lowest:
275ed08ebb7SGuenter Roeck 		if (!temp_is_valid(buf[SCT_STATUS_TEMP_LOWEST]))
276ed08ebb7SGuenter Roeck 			return -ENODATA;
2775b46903dSGuenter Roeck 		*val = temp_from_sct(buf[SCT_STATUS_TEMP_LOWEST]);
2785b46903dSGuenter Roeck 		break;
2795b46903dSGuenter Roeck 	case hwmon_temp_highest:
280ed08ebb7SGuenter Roeck 		if (!temp_is_valid(buf[SCT_STATUS_TEMP_HIGHEST]))
281ed08ebb7SGuenter Roeck 			return -ENODATA;
2825b46903dSGuenter Roeck 		*val = temp_from_sct(buf[SCT_STATUS_TEMP_HIGHEST]);
2835b46903dSGuenter Roeck 		break;
2845b46903dSGuenter Roeck 	default:
2855b46903dSGuenter Roeck 		err = -EINVAL;
2865b46903dSGuenter Roeck 		break;
2875b46903dSGuenter Roeck 	}
2885b46903dSGuenter Roeck 	return err;
2895b46903dSGuenter Roeck }
2905b46903dSGuenter Roeck 
291c66ef39eSMaciej S. Szmigiero static const char * const sct_avoid_models[] = {
292c66ef39eSMaciej S. Szmigiero /*
293c66ef39eSMaciej S. Szmigiero  * These drives will have WRITE FPDMA QUEUED command timeouts and sometimes just
294c66ef39eSMaciej S. Szmigiero  * freeze until power-cycled under heavy write loads when their temperature is
295c66ef39eSMaciej S. Szmigiero  * getting polled in SCT mode. The SMART mode seems to be fine, though.
296c66ef39eSMaciej S. Szmigiero  *
297c66ef39eSMaciej S. Szmigiero  * While only the 3 TB model (DT01ACA3) was actually caught exhibiting the
298c66ef39eSMaciej S. Szmigiero  * problem let's play safe here to avoid data corruption and ban the whole
299c66ef39eSMaciej S. Szmigiero  * DT01ACAx family.
300c66ef39eSMaciej S. Szmigiero 
301c66ef39eSMaciej S. Szmigiero  * The models from this array are prefix-matched.
302c66ef39eSMaciej S. Szmigiero  */
303c66ef39eSMaciej S. Szmigiero 	"TOSHIBA DT01ACA",
304c66ef39eSMaciej S. Szmigiero };
305c66ef39eSMaciej S. Szmigiero 
drivetemp_sct_avoid(struct drivetemp_data * st)306c66ef39eSMaciej S. Szmigiero static bool drivetemp_sct_avoid(struct drivetemp_data *st)
307c66ef39eSMaciej S. Szmigiero {
308c66ef39eSMaciej S. Szmigiero 	struct scsi_device *sdev = st->sdev;
309c66ef39eSMaciej S. Szmigiero 	unsigned int ctr;
310c66ef39eSMaciej S. Szmigiero 
311c66ef39eSMaciej S. Szmigiero 	if (!sdev->model)
312c66ef39eSMaciej S. Szmigiero 		return false;
313c66ef39eSMaciej S. Szmigiero 
314c66ef39eSMaciej S. Szmigiero 	/*
315c66ef39eSMaciej S. Szmigiero 	 * The "model" field contains just the raw SCSI INQUIRY response
316c66ef39eSMaciej S. Szmigiero 	 * "product identification" field, which has a width of 16 bytes.
317c66ef39eSMaciej S. Szmigiero 	 * This field is space-filled, but is NOT NULL-terminated.
318c66ef39eSMaciej S. Szmigiero 	 */
319c66ef39eSMaciej S. Szmigiero 	for (ctr = 0; ctr < ARRAY_SIZE(sct_avoid_models); ctr++)
320c66ef39eSMaciej S. Szmigiero 		if (!strncmp(sdev->model, sct_avoid_models[ctr],
321c66ef39eSMaciej S. Szmigiero 			     strlen(sct_avoid_models[ctr])))
322c66ef39eSMaciej S. Szmigiero 			return true;
323c66ef39eSMaciej S. Szmigiero 
324c66ef39eSMaciej S. Szmigiero 	return false;
325c66ef39eSMaciej S. Szmigiero }
326c66ef39eSMaciej S. Szmigiero 
drivetemp_identify_sata(struct drivetemp_data * st)3275b46903dSGuenter Roeck static int drivetemp_identify_sata(struct drivetemp_data *st)
3285b46903dSGuenter Roeck {
3295b46903dSGuenter Roeck 	struct scsi_device *sdev = st->sdev;
3305b46903dSGuenter Roeck 	u8 *buf = st->smartdata;
3315b46903dSGuenter Roeck 	struct scsi_vpd *vpd;
3325b46903dSGuenter Roeck 	bool is_ata, is_sata;
3335b46903dSGuenter Roeck 	bool have_sct_data_table;
3345b46903dSGuenter Roeck 	bool have_sct_temp;
3355b46903dSGuenter Roeck 	bool have_smart;
3365b46903dSGuenter Roeck 	bool have_sct;
3375b46903dSGuenter Roeck 	u16 *ata_id;
3385b46903dSGuenter Roeck 	u16 version;
3395b46903dSGuenter Roeck 	long temp;
3405b46903dSGuenter Roeck 	int err;
3415b46903dSGuenter Roeck 
3425b46903dSGuenter Roeck 	/* SCSI-ATA Translation present? */
3435b46903dSGuenter Roeck 	rcu_read_lock();
3445b46903dSGuenter Roeck 	vpd = rcu_dereference(sdev->vpd_pg89);
3455b46903dSGuenter Roeck 
3465b46903dSGuenter Roeck 	/*
3475b46903dSGuenter Roeck 	 * Verify that ATA IDENTIFY DEVICE data is included in ATA Information
3485b46903dSGuenter Roeck 	 * VPD and that the drive implements the SATA protocol.
3495b46903dSGuenter Roeck 	 */
3505b46903dSGuenter Roeck 	if (!vpd || vpd->len < 572 || vpd->data[56] != ATA_CMD_ID_ATA ||
3515b46903dSGuenter Roeck 	    vpd->data[36] != 0x34) {
3525b46903dSGuenter Roeck 		rcu_read_unlock();
3535b46903dSGuenter Roeck 		return -ENODEV;
3545b46903dSGuenter Roeck 	}
3555b46903dSGuenter Roeck 	ata_id = (u16 *)&vpd->data[60];
3565b46903dSGuenter Roeck 	is_ata = ata_id_is_ata(ata_id);
3575b46903dSGuenter Roeck 	is_sata = ata_id_is_sata(ata_id);
3585b46903dSGuenter Roeck 	have_sct = ata_id_sct_supported(ata_id);
3595b46903dSGuenter Roeck 	have_sct_data_table = ata_id_sct_data_tables(ata_id);
3605b46903dSGuenter Roeck 	have_smart = ata_id_smart_supported(ata_id) &&
3615b46903dSGuenter Roeck 				ata_id_smart_enabled(ata_id);
3625b46903dSGuenter Roeck 
3635b46903dSGuenter Roeck 	rcu_read_unlock();
3645b46903dSGuenter Roeck 
3655b46903dSGuenter Roeck 	/* bail out if this is not a SATA device */
3665b46903dSGuenter Roeck 	if (!is_ata || !is_sata)
3675b46903dSGuenter Roeck 		return -ENODEV;
368c66ef39eSMaciej S. Szmigiero 
369c66ef39eSMaciej S. Szmigiero 	if (have_sct && drivetemp_sct_avoid(st)) {
370c66ef39eSMaciej S. Szmigiero 		dev_notice(&sdev->sdev_gendev,
371c66ef39eSMaciej S. Szmigiero 			   "will avoid using SCT for temperature monitoring\n");
372c66ef39eSMaciej S. Szmigiero 		have_sct = false;
373c66ef39eSMaciej S. Szmigiero 	}
374c66ef39eSMaciej S. Szmigiero 
3755b46903dSGuenter Roeck 	if (!have_sct)
3765b46903dSGuenter Roeck 		goto skip_sct;
3775b46903dSGuenter Roeck 
3785b46903dSGuenter Roeck 	err = drivetemp_ata_command(st, SMART_READ_LOG, SCT_STATUS_REQ_ADDR);
3795b46903dSGuenter Roeck 	if (err)
3805b46903dSGuenter Roeck 		goto skip_sct;
3815b46903dSGuenter Roeck 
3825b46903dSGuenter Roeck 	version = (buf[SCT_STATUS_VERSION_HIGH] << 8) |
3835b46903dSGuenter Roeck 		  buf[SCT_STATUS_VERSION_LOW];
3845b46903dSGuenter Roeck 	if (version != 2 && version != 3)
3855b46903dSGuenter Roeck 		goto skip_sct;
3865b46903dSGuenter Roeck 
3875b46903dSGuenter Roeck 	have_sct_temp = temp_is_valid(buf[SCT_STATUS_TEMP]);
3885b46903dSGuenter Roeck 	if (!have_sct_temp)
3895b46903dSGuenter Roeck 		goto skip_sct;
3905b46903dSGuenter Roeck 
3915b46903dSGuenter Roeck 	st->have_temp_lowest = temp_is_valid(buf[SCT_STATUS_TEMP_LOWEST]);
3925b46903dSGuenter Roeck 	st->have_temp_highest = temp_is_valid(buf[SCT_STATUS_TEMP_HIGHEST]);
3935b46903dSGuenter Roeck 
3945b46903dSGuenter Roeck 	if (!have_sct_data_table)
395bcb543ccSGuenter Roeck 		goto skip_sct_data;
3965b46903dSGuenter Roeck 
3975b46903dSGuenter Roeck 	/* Request and read temperature history table */
3985b46903dSGuenter Roeck 	memset(buf, '\0', sizeof(st->smartdata));
3995b46903dSGuenter Roeck 	buf[0] = 5;	/* data table command */
4005b46903dSGuenter Roeck 	buf[2] = 1;	/* read table */
4015b46903dSGuenter Roeck 	buf[4] = 2;	/* temperature history table */
4025b46903dSGuenter Roeck 
4035b46903dSGuenter Roeck 	err = drivetemp_ata_command(st, SMART_WRITE_LOG, SCT_STATUS_REQ_ADDR);
4045b46903dSGuenter Roeck 	if (err)
4055b46903dSGuenter Roeck 		goto skip_sct_data;
4065b46903dSGuenter Roeck 
4075b46903dSGuenter Roeck 	err = drivetemp_ata_command(st, SMART_READ_LOG, SCT_READ_LOG_ADDR);
4085b46903dSGuenter Roeck 	if (err)
4095b46903dSGuenter Roeck 		goto skip_sct_data;
4105b46903dSGuenter Roeck 
4115b46903dSGuenter Roeck 	/*
4125b46903dSGuenter Roeck 	 * Temperature limits per AT Attachment 8 -
4135b46903dSGuenter Roeck 	 * ATA/ATAPI Command Set (ATA8-ACS)
4145b46903dSGuenter Roeck 	 */
4155b46903dSGuenter Roeck 	st->have_temp_max = temp_is_valid(buf[6]);
4165b46903dSGuenter Roeck 	st->have_temp_crit = temp_is_valid(buf[7]);
4175b46903dSGuenter Roeck 	st->have_temp_min = temp_is_valid(buf[8]);
4185b46903dSGuenter Roeck 	st->have_temp_lcrit = temp_is_valid(buf[9]);
4195b46903dSGuenter Roeck 
4205b46903dSGuenter Roeck 	st->temp_max = temp_from_sct(buf[6]);
4215b46903dSGuenter Roeck 	st->temp_crit = temp_from_sct(buf[7]);
4225b46903dSGuenter Roeck 	st->temp_min = temp_from_sct(buf[8]);
4235b46903dSGuenter Roeck 	st->temp_lcrit = temp_from_sct(buf[9]);
4245b46903dSGuenter Roeck 
4255b46903dSGuenter Roeck skip_sct_data:
4265b46903dSGuenter Roeck 	if (have_sct_temp) {
4275b46903dSGuenter Roeck 		st->get_temp = drivetemp_get_scttemp;
4285b46903dSGuenter Roeck 		return 0;
4295b46903dSGuenter Roeck 	}
4305b46903dSGuenter Roeck skip_sct:
4315b46903dSGuenter Roeck 	if (!have_smart)
4325b46903dSGuenter Roeck 		return -ENODEV;
4335b46903dSGuenter Roeck 	st->get_temp = drivetemp_get_smarttemp;
4345b46903dSGuenter Roeck 	return drivetemp_get_smarttemp(st, hwmon_temp_input, &temp);
4355b46903dSGuenter Roeck }
4365b46903dSGuenter Roeck 
drivetemp_identify(struct drivetemp_data * st)4375b46903dSGuenter Roeck static int drivetemp_identify(struct drivetemp_data *st)
4385b46903dSGuenter Roeck {
4395b46903dSGuenter Roeck 	struct scsi_device *sdev = st->sdev;
4405b46903dSGuenter Roeck 
4415b46903dSGuenter Roeck 	/* Bail out immediately if there is no inquiry data */
4425b46903dSGuenter Roeck 	if (!sdev->inquiry || sdev->inquiry_len < 16)
4435b46903dSGuenter Roeck 		return -ENODEV;
4445b46903dSGuenter Roeck 
4455b46903dSGuenter Roeck 	/* Disk device? */
4465b46903dSGuenter Roeck 	if (sdev->type != TYPE_DISK && sdev->type != TYPE_ZBC)
4475b46903dSGuenter Roeck 		return -ENODEV;
4485b46903dSGuenter Roeck 
4495b46903dSGuenter Roeck 	return drivetemp_identify_sata(st);
4505b46903dSGuenter Roeck }
4515b46903dSGuenter Roeck 
drivetemp_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)4525b46903dSGuenter Roeck static int drivetemp_read(struct device *dev, enum hwmon_sensor_types type,
4535b46903dSGuenter Roeck 			 u32 attr, int channel, long *val)
4545b46903dSGuenter Roeck {
4555b46903dSGuenter Roeck 	struct drivetemp_data *st = dev_get_drvdata(dev);
4565b46903dSGuenter Roeck 	int err = 0;
4575b46903dSGuenter Roeck 
4585b46903dSGuenter Roeck 	if (type != hwmon_temp)
4595b46903dSGuenter Roeck 		return -EINVAL;
4605b46903dSGuenter Roeck 
4615b46903dSGuenter Roeck 	switch (attr) {
4625b46903dSGuenter Roeck 	case hwmon_temp_input:
4635b46903dSGuenter Roeck 	case hwmon_temp_lowest:
4645b46903dSGuenter Roeck 	case hwmon_temp_highest:
4655b46903dSGuenter Roeck 		mutex_lock(&st->lock);
4665b46903dSGuenter Roeck 		err = st->get_temp(st, attr, val);
4675b46903dSGuenter Roeck 		mutex_unlock(&st->lock);
4685b46903dSGuenter Roeck 		break;
4695b46903dSGuenter Roeck 	case hwmon_temp_lcrit:
4705b46903dSGuenter Roeck 		*val = st->temp_lcrit;
4715b46903dSGuenter Roeck 		break;
4725b46903dSGuenter Roeck 	case hwmon_temp_min:
4735b46903dSGuenter Roeck 		*val = st->temp_min;
4745b46903dSGuenter Roeck 		break;
4755b46903dSGuenter Roeck 	case hwmon_temp_max:
4765b46903dSGuenter Roeck 		*val = st->temp_max;
4775b46903dSGuenter Roeck 		break;
4785b46903dSGuenter Roeck 	case hwmon_temp_crit:
4795b46903dSGuenter Roeck 		*val = st->temp_crit;
4805b46903dSGuenter Roeck 		break;
4815b46903dSGuenter Roeck 	default:
4825b46903dSGuenter Roeck 		err = -EINVAL;
4835b46903dSGuenter Roeck 		break;
4845b46903dSGuenter Roeck 	}
4855b46903dSGuenter Roeck 	return err;
4865b46903dSGuenter Roeck }
4875b46903dSGuenter Roeck 
drivetemp_is_visible(const void * data,enum hwmon_sensor_types type,u32 attr,int channel)4885b46903dSGuenter Roeck static umode_t drivetemp_is_visible(const void *data,
4895b46903dSGuenter Roeck 				   enum hwmon_sensor_types type,
4905b46903dSGuenter Roeck 				   u32 attr, int channel)
4915b46903dSGuenter Roeck {
4925b46903dSGuenter Roeck 	const struct drivetemp_data *st = data;
4935b46903dSGuenter Roeck 
4945b46903dSGuenter Roeck 	switch (type) {
4955b46903dSGuenter Roeck 	case hwmon_temp:
4965b46903dSGuenter Roeck 		switch (attr) {
4975b46903dSGuenter Roeck 		case hwmon_temp_input:
4985b46903dSGuenter Roeck 			return 0444;
4995b46903dSGuenter Roeck 		case hwmon_temp_lowest:
5005b46903dSGuenter Roeck 			if (st->have_temp_lowest)
5015b46903dSGuenter Roeck 				return 0444;
5025b46903dSGuenter Roeck 			break;
5035b46903dSGuenter Roeck 		case hwmon_temp_highest:
5045b46903dSGuenter Roeck 			if (st->have_temp_highest)
5055b46903dSGuenter Roeck 				return 0444;
5065b46903dSGuenter Roeck 			break;
5075b46903dSGuenter Roeck 		case hwmon_temp_min:
5085b46903dSGuenter Roeck 			if (st->have_temp_min)
5095b46903dSGuenter Roeck 				return 0444;
5105b46903dSGuenter Roeck 			break;
5115b46903dSGuenter Roeck 		case hwmon_temp_max:
5125b46903dSGuenter Roeck 			if (st->have_temp_max)
5135b46903dSGuenter Roeck 				return 0444;
5145b46903dSGuenter Roeck 			break;
5155b46903dSGuenter Roeck 		case hwmon_temp_lcrit:
5165b46903dSGuenter Roeck 			if (st->have_temp_lcrit)
5175b46903dSGuenter Roeck 				return 0444;
5185b46903dSGuenter Roeck 			break;
5195b46903dSGuenter Roeck 		case hwmon_temp_crit:
5205b46903dSGuenter Roeck 			if (st->have_temp_crit)
5215b46903dSGuenter Roeck 				return 0444;
5225b46903dSGuenter Roeck 			break;
5235b46903dSGuenter Roeck 		default:
5245b46903dSGuenter Roeck 			break;
5255b46903dSGuenter Roeck 		}
5265b46903dSGuenter Roeck 		break;
5275b46903dSGuenter Roeck 	default:
5285b46903dSGuenter Roeck 		break;
5295b46903dSGuenter Roeck 	}
5305b46903dSGuenter Roeck 	return 0;
5315b46903dSGuenter Roeck }
5325b46903dSGuenter Roeck 
533b9adb6b6SKrzysztof Kozlowski static const struct hwmon_channel_info * const drivetemp_info[] = {
5345b46903dSGuenter Roeck 	HWMON_CHANNEL_INFO(chip,
5355b46903dSGuenter Roeck 			   HWMON_C_REGISTER_TZ),
5365b46903dSGuenter Roeck 	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT |
5375b46903dSGuenter Roeck 			   HWMON_T_LOWEST | HWMON_T_HIGHEST |
5385b46903dSGuenter Roeck 			   HWMON_T_MIN | HWMON_T_MAX |
5395b46903dSGuenter Roeck 			   HWMON_T_LCRIT | HWMON_T_CRIT),
5405b46903dSGuenter Roeck 	NULL
5415b46903dSGuenter Roeck };
5425b46903dSGuenter Roeck 
5435b46903dSGuenter Roeck static const struct hwmon_ops drivetemp_ops = {
5445b46903dSGuenter Roeck 	.is_visible = drivetemp_is_visible,
5455b46903dSGuenter Roeck 	.read = drivetemp_read,
5465b46903dSGuenter Roeck };
5475b46903dSGuenter Roeck 
5485b46903dSGuenter Roeck static const struct hwmon_chip_info drivetemp_chip_info = {
5495b46903dSGuenter Roeck 	.ops = &drivetemp_ops,
5505b46903dSGuenter Roeck 	.info = drivetemp_info,
5515b46903dSGuenter Roeck };
5525b46903dSGuenter Roeck 
5535b46903dSGuenter Roeck /*
5545b46903dSGuenter Roeck  * The device argument points to sdev->sdev_dev. Its parent is
5555b46903dSGuenter Roeck  * sdev->sdev_gendev, which we can use to get the scsi_device pointer.
5565b46903dSGuenter Roeck  */
drivetemp_add(struct device * dev)5572243acd5SGreg Kroah-Hartman static int drivetemp_add(struct device *dev)
5585b46903dSGuenter Roeck {
5595b46903dSGuenter Roeck 	struct scsi_device *sdev = to_scsi_device(dev->parent);
5605b46903dSGuenter Roeck 	struct drivetemp_data *st;
5615b46903dSGuenter Roeck 	int err;
5625b46903dSGuenter Roeck 
5635b46903dSGuenter Roeck 	st = kzalloc(sizeof(*st), GFP_KERNEL);
5645b46903dSGuenter Roeck 	if (!st)
5655b46903dSGuenter Roeck 		return -ENOMEM;
5665b46903dSGuenter Roeck 
5675b46903dSGuenter Roeck 	st->sdev = sdev;
5685b46903dSGuenter Roeck 	st->dev = dev;
5695b46903dSGuenter Roeck 	mutex_init(&st->lock);
5705b46903dSGuenter Roeck 
5715b46903dSGuenter Roeck 	if (drivetemp_identify(st)) {
5725b46903dSGuenter Roeck 		err = -ENODEV;
5735b46903dSGuenter Roeck 		goto abort;
5745b46903dSGuenter Roeck 	}
5755b46903dSGuenter Roeck 
5765b46903dSGuenter Roeck 	st->hwdev = hwmon_device_register_with_info(dev->parent, "drivetemp",
5775b46903dSGuenter Roeck 						    st, &drivetemp_chip_info,
5785b46903dSGuenter Roeck 						    NULL);
5795b46903dSGuenter Roeck 	if (IS_ERR(st->hwdev)) {
5805b46903dSGuenter Roeck 		err = PTR_ERR(st->hwdev);
5815b46903dSGuenter Roeck 		goto abort;
5825b46903dSGuenter Roeck 	}
5835b46903dSGuenter Roeck 
5845b46903dSGuenter Roeck 	list_add(&st->list, &drivetemp_devlist);
5855b46903dSGuenter Roeck 	return 0;
5865b46903dSGuenter Roeck 
5875b46903dSGuenter Roeck abort:
5885b46903dSGuenter Roeck 	kfree(st);
5895b46903dSGuenter Roeck 	return err;
5905b46903dSGuenter Roeck }
5915b46903dSGuenter Roeck 
drivetemp_remove(struct device * dev)5922243acd5SGreg Kroah-Hartman static void drivetemp_remove(struct device *dev)
5935b46903dSGuenter Roeck {
5945b46903dSGuenter Roeck 	struct drivetemp_data *st, *tmp;
5955b46903dSGuenter Roeck 
5965b46903dSGuenter Roeck 	list_for_each_entry_safe(st, tmp, &drivetemp_devlist, list) {
5975b46903dSGuenter Roeck 		if (st->dev == dev) {
5985b46903dSGuenter Roeck 			list_del(&st->list);
5995b46903dSGuenter Roeck 			hwmon_device_unregister(st->hwdev);
6005b46903dSGuenter Roeck 			kfree(st);
6015b46903dSGuenter Roeck 			break;
6025b46903dSGuenter Roeck 		}
6035b46903dSGuenter Roeck 	}
6045b46903dSGuenter Roeck }
6055b46903dSGuenter Roeck 
6065b46903dSGuenter Roeck static struct class_interface drivetemp_interface = {
6075b46903dSGuenter Roeck 	.add_dev = drivetemp_add,
6085b46903dSGuenter Roeck 	.remove_dev = drivetemp_remove,
6095b46903dSGuenter Roeck };
6105b46903dSGuenter Roeck 
drivetemp_init(void)6115b46903dSGuenter Roeck static int __init drivetemp_init(void)
6125b46903dSGuenter Roeck {
6135b46903dSGuenter Roeck 	return scsi_register_interface(&drivetemp_interface);
6145b46903dSGuenter Roeck }
6155b46903dSGuenter Roeck 
drivetemp_exit(void)6165b46903dSGuenter Roeck static void __exit drivetemp_exit(void)
6175b46903dSGuenter Roeck {
6185b46903dSGuenter Roeck 	scsi_unregister_interface(&drivetemp_interface);
6195b46903dSGuenter Roeck }
6205b46903dSGuenter Roeck 
6215b46903dSGuenter Roeck module_init(drivetemp_init);
6225b46903dSGuenter Roeck module_exit(drivetemp_exit);
6235b46903dSGuenter Roeck 
6245b46903dSGuenter Roeck MODULE_AUTHOR("Guenter Roeck <linus@roeck-us.net>");
6255b46903dSGuenter Roeck MODULE_DESCRIPTION("Hard drive temperature monitor");
6265b46903dSGuenter Roeck MODULE_LICENSE("GPL");
6275918036cSLinus Walleij MODULE_ALIAS("platform:drivetemp");
628