// SPDX-License-Identifier: GPL-2.0
/*
 * Hwmon client for disk and solid state drives with temperature sensors
 * Copyright (C) 2019 Zodiac Inflight Innovations
 *
 * With input from:
 *    Hwmon client for S.M.A.R.T. hard disk drives with temperature sensors.
 *    (C) 2018 Linus Walleij
 *
 *    hwmon: Driver for SCSI/ATA temperature sensors
 *    by Constantin Baranov <const@mimas.ru>, submitted September 2009
 *
 * This drive supports reporting the temperature of SATA drives. It can be
 * easily extended to report the temperature of SCSI drives.
 *
 * The primary means to read drive temperatures and temperature limits
 * for ATA drives is the SCT Command Transport feature set as specified in
 * ATA8-ACS.
 * It can be used to read the current drive temperature, temperature limits,
 * and historic minimum and maximum temperatures. The SCT Command Transport
 * feature set is documented in "AT Attachment 8 - ATA/ATAPI Command Set
 * (ATA8-ACS)".
 *
 * If the SCT Command Transport feature set is not available, drive temperatures
 * may be readable through SMART attributes. Since SMART attributes are not well
 * defined, this method is only used as fallback mechanism.
 *
 * There are three SMART attributes which may report drive temperatures.
 * Those are defined as follows (from
 * http://www.cropel.com/library/smart-attribute-list.aspx).
 *
 * 190	Temperature	Temperature, monitored by a sensor somewhere inside
 *			the drive. Raw value typicaly holds the actual
 *			temperature (hexadecimal) in its rightmost two digits.
 *
 * 194	Temperature	Temperature, monitored by a sensor somewhere inside
 *			the drive. Raw value typicaly holds the actual
 *			temperature (hexadecimal) in its rightmost two digits.
 *
 * 231	Temperature	Temperature, monitored by a sensor somewhere inside
 *			the drive. Raw value typicaly holds the actual
 *			temperature (hexadecimal) in its rightmost two digits.
 *
 * Wikipedia defines attributes a bit differently.
 *
 * 190	Temperature	Value is equal to (100-temp. °C), allowing manufacturer
 *	Difference or	to set a minimum threshold which corresponds to a
 *	Airflow		maximum temperature. This also follows the convention of
 *	Temperature	100 being a best-case value and lower values being
 *			undesirable. However, some older drives may instead
 *			report raw Temperature (identical to 0xC2) or
 *			Temperature minus 50 here.
 * 194	Temperature or	Indicates the device temperature, if the appropriate
 *	Temperature	sensor is fitted. Lowest byte of the raw value contains
 *	Celsius		the exact temperature value (Celsius degrees).
 * 231	Life Left	Indicates the approximate SSD life left, in terms of
 *	(SSDs) or	program/erase cycles or available reserved blocks.
 *	Temperature	A normalized value of 100 represents a new drive, with
 *			a threshold value at 10 indicating a need for
 *			replacement. A value of 0 may mean that the drive is
 *			operating in read-only mode to allow data recovery.
 *			Previously (pre-2010) occasionally used for Drive
 *			Temperature (more typically reported at 0xC2).
 *
 * Common denominator is that the first raw byte reports the temperature
 * in degrees C on almost all drives. Some drives may report a fractional
 * temperature in the second raw byte.
 *
 * Known exceptions (from libatasmart):
 * - SAMSUNG SV0412H and SAMSUNG SV1204H) report the temperature in 10th
 *   degrees C in the first two raw bytes.
 * - A few Maxtor drives report an unknown or bad value in attribute 194.
 * - Certain Apple SSD drives report an unknown value in attribute 190.
 *   Only certain firmware versions are affected.
 *
 * Those exceptions affect older ATA drives and are currently ignored.
 * Also, the second raw byte (possibly reporting the fractional temperature)
 * is currently ignored.
 *
 * Many drives also report temperature limits in additional SMART data raw
 * bytes. The format of those is not well defined and varies widely.
 * The driver does not currently attempt to report those limits.
 *
 * According to data in smartmontools, attribute 231 is rarely used to report
 * drive temperatures. At the same time, several drives report SSD life left
 * in attribute 231, but do not support temperature sensors. For this reason,
 * attribute 231 is currently ignored.
 *
 * Following above definitions, temperatures are reported as follows.
 *   If SCT Command Transport is supported, it is used to read the
 *   temperature and, if available, temperature limits.
 * - Otherwise, if SMART attribute 194 is supported, it is used to read
 *   the temperature.
 * - Otherwise, if SMART attribute 190 is supported, it is used to read
 *   the temperature.
 */

#include <linux/ata.h>
#include <linux/bits.h>
#include <linux/device.h>
#include <linux/hwmon.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_proto.h>

struct drivetemp_data {
	struct list_head list;		/* list of instantiated devices */
	struct mutex lock;		/* protect data buffer accesses */
	struct scsi_device *sdev;	/* SCSI device */
	struct device *dev;		/* instantiating device */
	struct device *hwdev;		/* hardware monitoring device */
	u8 smartdata[ATA_SECT_SIZE];	/* local buffer */
	int (*get_temp)(struct drivetemp_data *st, u32 attr, long *val);
	bool have_temp_lowest;		/* lowest temp in SCT status */
	bool have_temp_highest;		/* highest temp in SCT status */
	bool have_temp_min;		/* have min temp */
	bool have_temp_max;		/* have max temp */
	bool have_temp_lcrit;		/* have lower critical limit */
	bool have_temp_crit;		/* have critical limit */
	int temp_min;			/* min temp */
	int temp_max;			/* max temp */
	int temp_lcrit;			/* lower critical limit */
	int temp_crit;			/* critical limit */
};

static LIST_HEAD(drivetemp_devlist);

#define ATA_MAX_SMART_ATTRS	30
#define SMART_TEMP_PROP_190	190
#define SMART_TEMP_PROP_194	194

#define SCT_STATUS_REQ_ADDR	0xe0
#define  SCT_STATUS_VERSION_LOW		0	/* log byte offsets */
#define  SCT_STATUS_VERSION_HIGH	1
#define  SCT_STATUS_TEMP		200
#define  SCT_STATUS_TEMP_LOWEST		201
#define  SCT_STATUS_TEMP_HIGHEST	202
#define SCT_READ_LOG_ADDR	0xe1
#define  SMART_READ_LOG			0xd5
#define  SMART_WRITE_LOG		0xd6

#define INVALID_TEMP		0x80

#define temp_is_valid(temp)	((temp) != INVALID_TEMP)
#define temp_from_sct(temp)	(((s8)(temp)) * 1000)

static inline bool ata_id_smart_supported(u16 *id)
{
	return id[ATA_ID_COMMAND_SET_1] & BIT(0);
}

static inline bool ata_id_smart_enabled(u16 *id)
{
	return id[ATA_ID_CFS_ENABLE_1] & BIT(0);
}

static int drivetemp_scsi_command(struct drivetemp_data *st,
				 u8 ata_command, u8 feature,
				 u8 lba_low, u8 lba_mid, u8 lba_high)
{
	u8 scsi_cmd[MAX_COMMAND_SIZE];
	int data_dir;

	memset(scsi_cmd, 0, sizeof(scsi_cmd));
	scsi_cmd[0] = ATA_16;
	if (ata_command == ATA_CMD_SMART && feature == SMART_WRITE_LOG) {
		scsi_cmd[1] = (5 << 1);	/* PIO Data-out */
		/*
		 * No off.line or cc, write to dev, block count in sector count
		 * field.
		 */
		scsi_cmd[2] = 0x06;
		data_dir = DMA_TO_DEVICE;
	} else {
		scsi_cmd[1] = (4 << 1);	/* PIO Data-in */
		/*
		 * No off.line or cc, read from dev, block count in sector count
		 * field.
		 */
		scsi_cmd[2] = 0x0e;
		data_dir = DMA_FROM_DEVICE;
	}
	scsi_cmd[4] = feature;
	scsi_cmd[6] = 1;	/* 1 sector */
	scsi_cmd[8] = lba_low;
	scsi_cmd[10] = lba_mid;
	scsi_cmd[12] = lba_high;
	scsi_cmd[14] = ata_command;

	return scsi_execute_req(st->sdev, scsi_cmd, data_dir,
				st->smartdata, ATA_SECT_SIZE, NULL, HZ, 5,
				NULL);
}

static int drivetemp_ata_command(struct drivetemp_data *st, u8 feature,
				 u8 select)
{
	return drivetemp_scsi_command(st, ATA_CMD_SMART, feature, select,
				     ATA_SMART_LBAM_PASS, ATA_SMART_LBAH_PASS);
}

static int drivetemp_get_smarttemp(struct drivetemp_data *st, u32 attr,
				  long *temp)
{
	u8 *buf = st->smartdata;
	bool have_temp = false;
	u8 temp_raw;
	u8 csum;
	int err;
	int i;

	err = drivetemp_ata_command(st, ATA_SMART_READ_VALUES, 0);
	if (err)
		return err;

	/* Checksum the read value table */
	csum = 0;
	for (i = 0; i < ATA_SECT_SIZE; i++)
		csum += buf[i];
	if (csum) {
		dev_dbg(&st->sdev->sdev_gendev,
			"checksum error reading SMART values\n");
		return -EIO;
	}

	for (i = 0; i < ATA_MAX_SMART_ATTRS; i++) {
		u8 *attr = buf + i * 12;
		int id = attr[2];

		if (!id)
			continue;

		if (id == SMART_TEMP_PROP_190) {
			temp_raw = attr[7];
			have_temp = true;
		}
		if (id == SMART_TEMP_PROP_194) {
			temp_raw = attr[7];
			have_temp = true;
			break;
		}
	}

	if (have_temp) {
		*temp = temp_raw * 1000;
		return 0;
	}

	return -ENXIO;
}

static int drivetemp_get_scttemp(struct drivetemp_data *st, u32 attr, long *val)
{
	u8 *buf = st->smartdata;
	int err;

	err = drivetemp_ata_command(st, SMART_READ_LOG, SCT_STATUS_REQ_ADDR);
	if (err)
		return err;
	switch (attr) {
	case hwmon_temp_input:
		if (!temp_is_valid(buf[SCT_STATUS_TEMP]))
			return -ENODATA;
		*val = temp_from_sct(buf[SCT_STATUS_TEMP]);
		break;
	case hwmon_temp_lowest:
		if (!temp_is_valid(buf[SCT_STATUS_TEMP_LOWEST]))
			return -ENODATA;
		*val = temp_from_sct(buf[SCT_STATUS_TEMP_LOWEST]);
		break;
	case hwmon_temp_highest:
		if (!temp_is_valid(buf[SCT_STATUS_TEMP_HIGHEST]))
			return -ENODATA;
		*val = temp_from_sct(buf[SCT_STATUS_TEMP_HIGHEST]);
		break;
	default:
		err = -EINVAL;
		break;
	}
	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;
	u8 *buf = st->smartdata;
	struct scsi_vpd *vpd;
	bool is_ata, is_sata;
	bool have_sct_data_table;
	bool have_sct_temp;
	bool have_smart;
	bool have_sct;
	u16 *ata_id;
	u16 version;
	long temp;
	int err;

	/* SCSI-ATA Translation present? */
	rcu_read_lock();
	vpd = rcu_dereference(sdev->vpd_pg89);

	/*
	 * Verify that ATA IDENTIFY DEVICE data is included in ATA Information
	 * VPD and that the drive implements the SATA protocol.
	 */
	if (!vpd || vpd->len < 572 || vpd->data[56] != ATA_CMD_ID_ATA ||
	    vpd->data[36] != 0x34) {
		rcu_read_unlock();
		return -ENODEV;
	}
	ata_id = (u16 *)&vpd->data[60];
	is_ata = ata_id_is_ata(ata_id);
	is_sata = ata_id_is_sata(ata_id);
	have_sct = ata_id_sct_supported(ata_id);
	have_sct_data_table = ata_id_sct_data_tables(ata_id);
	have_smart = ata_id_smart_supported(ata_id) &&
				ata_id_smart_enabled(ata_id);

	rcu_read_unlock();

	/* 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;

	err = drivetemp_ata_command(st, SMART_READ_LOG, SCT_STATUS_REQ_ADDR);
	if (err)
		goto skip_sct;

	version = (buf[SCT_STATUS_VERSION_HIGH] << 8) |
		  buf[SCT_STATUS_VERSION_LOW];
	if (version != 2 && version != 3)
		goto skip_sct;

	have_sct_temp = temp_is_valid(buf[SCT_STATUS_TEMP]);
	if (!have_sct_temp)
		goto skip_sct;

	st->have_temp_lowest = temp_is_valid(buf[SCT_STATUS_TEMP_LOWEST]);
	st->have_temp_highest = temp_is_valid(buf[SCT_STATUS_TEMP_HIGHEST]);

	if (!have_sct_data_table)
		goto skip_sct_data;

	/* Request and read temperature history table */
	memset(buf, '\0', sizeof(st->smartdata));
	buf[0] = 5;	/* data table command */
	buf[2] = 1;	/* read table */
	buf[4] = 2;	/* temperature history table */

	err = drivetemp_ata_command(st, SMART_WRITE_LOG, SCT_STATUS_REQ_ADDR);
	if (err)
		goto skip_sct_data;

	err = drivetemp_ata_command(st, SMART_READ_LOG, SCT_READ_LOG_ADDR);
	if (err)
		goto skip_sct_data;

	/*
	 * Temperature limits per AT Attachment 8 -
	 * ATA/ATAPI Command Set (ATA8-ACS)
	 */
	st->have_temp_max = temp_is_valid(buf[6]);
	st->have_temp_crit = temp_is_valid(buf[7]);
	st->have_temp_min = temp_is_valid(buf[8]);
	st->have_temp_lcrit = temp_is_valid(buf[9]);

	st->temp_max = temp_from_sct(buf[6]);
	st->temp_crit = temp_from_sct(buf[7]);
	st->temp_min = temp_from_sct(buf[8]);
	st->temp_lcrit = temp_from_sct(buf[9]);

skip_sct_data:
	if (have_sct_temp) {
		st->get_temp = drivetemp_get_scttemp;
		return 0;
	}
skip_sct:
	if (!have_smart)
		return -ENODEV;
	st->get_temp = drivetemp_get_smarttemp;
	return drivetemp_get_smarttemp(st, hwmon_temp_input, &temp);
}

static int drivetemp_identify(struct drivetemp_data *st)
{
	struct scsi_device *sdev = st->sdev;

	/* Bail out immediately if there is no inquiry data */
	if (!sdev->inquiry || sdev->inquiry_len < 16)
		return -ENODEV;

	/* Disk device? */
	if (sdev->type != TYPE_DISK && sdev->type != TYPE_ZBC)
		return -ENODEV;

	return drivetemp_identify_sata(st);
}

static int drivetemp_read(struct device *dev, enum hwmon_sensor_types type,
			 u32 attr, int channel, long *val)
{
	struct drivetemp_data *st = dev_get_drvdata(dev);
	int err = 0;

	if (type != hwmon_temp)
		return -EINVAL;

	switch (attr) {
	case hwmon_temp_input:
	case hwmon_temp_lowest:
	case hwmon_temp_highest:
		mutex_lock(&st->lock);
		err = st->get_temp(st, attr, val);
		mutex_unlock(&st->lock);
		break;
	case hwmon_temp_lcrit:
		*val = st->temp_lcrit;
		break;
	case hwmon_temp_min:
		*val = st->temp_min;
		break;
	case hwmon_temp_max:
		*val = st->temp_max;
		break;
	case hwmon_temp_crit:
		*val = st->temp_crit;
		break;
	default:
		err = -EINVAL;
		break;
	}
	return err;
}

static umode_t drivetemp_is_visible(const void *data,
				   enum hwmon_sensor_types type,
				   u32 attr, int channel)
{
	const struct drivetemp_data *st = data;

	switch (type) {
	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_input:
			return 0444;
		case hwmon_temp_lowest:
			if (st->have_temp_lowest)
				return 0444;
			break;
		case hwmon_temp_highest:
			if (st->have_temp_highest)
				return 0444;
			break;
		case hwmon_temp_min:
			if (st->have_temp_min)
				return 0444;
			break;
		case hwmon_temp_max:
			if (st->have_temp_max)
				return 0444;
			break;
		case hwmon_temp_lcrit:
			if (st->have_temp_lcrit)
				return 0444;
			break;
		case hwmon_temp_crit:
			if (st->have_temp_crit)
				return 0444;
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}
	return 0;
}

static const struct hwmon_channel_info *drivetemp_info[] = {
	HWMON_CHANNEL_INFO(chip,
			   HWMON_C_REGISTER_TZ),
	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT |
			   HWMON_T_LOWEST | HWMON_T_HIGHEST |
			   HWMON_T_MIN | HWMON_T_MAX |
			   HWMON_T_LCRIT | HWMON_T_CRIT),
	NULL
};

static const struct hwmon_ops drivetemp_ops = {
	.is_visible = drivetemp_is_visible,
	.read = drivetemp_read,
};

static const struct hwmon_chip_info drivetemp_chip_info = {
	.ops = &drivetemp_ops,
	.info = drivetemp_info,
};

/*
 * The device argument points to sdev->sdev_dev. Its parent is
 * sdev->sdev_gendev, which we can use to get the scsi_device pointer.
 */
static int drivetemp_add(struct device *dev, struct class_interface *intf)
{
	struct scsi_device *sdev = to_scsi_device(dev->parent);
	struct drivetemp_data *st;
	int err;

	st = kzalloc(sizeof(*st), GFP_KERNEL);
	if (!st)
		return -ENOMEM;

	st->sdev = sdev;
	st->dev = dev;
	mutex_init(&st->lock);

	if (drivetemp_identify(st)) {
		err = -ENODEV;
		goto abort;
	}

	st->hwdev = hwmon_device_register_with_info(dev->parent, "drivetemp",
						    st, &drivetemp_chip_info,
						    NULL);
	if (IS_ERR(st->hwdev)) {
		err = PTR_ERR(st->hwdev);
		goto abort;
	}

	list_add(&st->list, &drivetemp_devlist);
	return 0;

abort:
	kfree(st);
	return err;
}

static void drivetemp_remove(struct device *dev, struct class_interface *intf)
{
	struct drivetemp_data *st, *tmp;

	list_for_each_entry_safe(st, tmp, &drivetemp_devlist, list) {
		if (st->dev == dev) {
			list_del(&st->list);
			hwmon_device_unregister(st->hwdev);
			kfree(st);
			break;
		}
	}
}

static struct class_interface drivetemp_interface = {
	.add_dev = drivetemp_add,
	.remove_dev = drivetemp_remove,
};

static int __init drivetemp_init(void)
{
	return scsi_register_interface(&drivetemp_interface);
}

static void __exit drivetemp_exit(void)
{
	scsi_unregister_interface(&drivetemp_interface);
}

module_init(drivetemp_init);
module_exit(drivetemp_exit);

MODULE_AUTHOR("Guenter Roeck <linus@roeck-us.net>");
MODULE_DESCRIPTION("Hard drive temperature monitor");
MODULE_LICENSE("GPL");
