^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Hwmon client for disk and solid state drives with temperature sensors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2019 Zodiac Inflight Innovations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * With input from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Hwmon client for S.M.A.R.T. hard disk drives with temperature sensors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * (C) 2018 Linus Walleij
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * hwmon: Driver for SCSI/ATA temperature sensors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * by Constantin Baranov <const@mimas.ru>, submitted September 2009
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This drive supports reporting the temperatire of SATA drives. It can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * easily extended to report the temperature of SCSI drives.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * The primary means to read drive temperatures and temperature limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * for ATA drives is the SCT Command Transport feature set as specified in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * ATA8-ACS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * It can be used to read the current drive temperature, temperature limits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * and historic minimum and maximum temperatures. The SCT Command Transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * feature set is documented in "AT Attachment 8 - ATA/ATAPI Command Set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * (ATA8-ACS)".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * If the SCT Command Transport feature set is not available, drive temperatures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * may be readable through SMART attributes. Since SMART attributes are not well
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * defined, this method is only used as fallback mechanism.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * There are three SMART attributes which may report drive temperatures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Those are defined as follows (from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * http://www.cropel.com/library/smart-attribute-list.aspx).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * 190 Temperature Temperature, monitored by a sensor somewhere inside
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * the drive. Raw value typicaly holds the actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * temperature (hexadecimal) in its rightmost two digits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * 194 Temperature Temperature, monitored by a sensor somewhere inside
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * the drive. Raw value typicaly holds the actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * temperature (hexadecimal) in its rightmost two digits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * 231 Temperature Temperature, monitored by a sensor somewhere inside
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * the drive. Raw value typicaly holds the actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * temperature (hexadecimal) in its rightmost two digits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * Wikipedia defines attributes a bit differently.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * 190 Temperature Value is equal to (100-temp. °C), allowing manufacturer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * Difference or to set a minimum threshold which corresponds to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * Airflow maximum temperature. This also follows the convention of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Temperature 100 being a best-case value and lower values being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * undesirable. However, some older drives may instead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * report raw Temperature (identical to 0xC2) or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Temperature minus 50 here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * 194 Temperature or Indicates the device temperature, if the appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Temperature sensor is fitted. Lowest byte of the raw value contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * Celsius the exact temperature value (Celsius degrees).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * 231 Life Left Indicates the approximate SSD life left, in terms of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * (SSDs) or program/erase cycles or available reserved blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Temperature A normalized value of 100 represents a new drive, with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * a threshold value at 10 indicating a need for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * replacement. A value of 0 may mean that the drive is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * operating in read-only mode to allow data recovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * Previously (pre-2010) occasionally used for Drive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Temperature (more typically reported at 0xC2).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * Common denominator is that the first raw byte reports the temperature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * in degrees C on almost all drives. Some drives may report a fractional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * temperature in the second raw byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * Known exceptions (from libatasmart):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * - SAMSUNG SV0412H and SAMSUNG SV1204H) report the temperature in 10th
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * degrees C in the first two raw bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * - A few Maxtor drives report an unknown or bad value in attribute 194.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * - Certain Apple SSD drives report an unknown value in attribute 190.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Only certain firmware versions are affected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * Those exceptions affect older ATA drives and are currently ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Also, the second raw byte (possibly reporting the fractional temperature)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * is currently ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Many drives also report temperature limits in additional SMART data raw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * bytes. The format of those is not well defined and varies widely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * The driver does not currently attempt to report those limits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * According to data in smartmontools, attribute 231 is rarely used to report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * drive temperatures. At the same time, several drives report SSD life left
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * in attribute 231, but do not support temperature sensors. For this reason,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * attribute 231 is currently ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * Following above definitions, temperatures are reported as follows.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * If SCT Command Transport is supported, it is used to read the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * temperature and, if available, temperature limits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * - Otherwise, if SMART attribute 194 is supported, it is used to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * the temperature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * - Otherwise, if SMART attribute 190 is supported, it is used to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * the temperature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #include <linux/ata.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #include <linux/bits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #include <scsi/scsi_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #include <scsi/scsi_proto.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct drivetemp_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct list_head list; /* list of instantiated devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct mutex lock; /* protect data buffer accesses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct scsi_device *sdev; /* SCSI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct device *dev; /* instantiating device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct device *hwdev; /* hardware monitoring device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u8 smartdata[ATA_SECT_SIZE]; /* local buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int (*get_temp)(struct drivetemp_data *st, u32 attr, long *val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) bool have_temp_lowest; /* lowest temp in SCT status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) bool have_temp_highest; /* highest temp in SCT status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) bool have_temp_min; /* have min temp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) bool have_temp_max; /* have max temp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) bool have_temp_lcrit; /* have lower critical limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) bool have_temp_crit; /* have critical limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int temp_min; /* min temp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int temp_max; /* max temp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int temp_lcrit; /* lower critical limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int temp_crit; /* critical limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static LIST_HEAD(drivetemp_devlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define ATA_MAX_SMART_ATTRS 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define SMART_TEMP_PROP_190 190
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define SMART_TEMP_PROP_194 194
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define SCT_STATUS_REQ_ADDR 0xe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define SCT_STATUS_VERSION_LOW 0 /* log byte offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define SCT_STATUS_VERSION_HIGH 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define SCT_STATUS_TEMP 200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define SCT_STATUS_TEMP_LOWEST 201
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define SCT_STATUS_TEMP_HIGHEST 202
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define SCT_READ_LOG_ADDR 0xe1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define SMART_READ_LOG 0xd5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define SMART_WRITE_LOG 0xd6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define INVALID_TEMP 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define temp_is_valid(temp) ((temp) != INVALID_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define temp_from_sct(temp) (((s8)(temp)) * 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static inline bool ata_id_smart_supported(u16 *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return id[ATA_ID_COMMAND_SET_1] & BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static inline bool ata_id_smart_enabled(u16 *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return id[ATA_ID_CFS_ENABLE_1] & BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int drivetemp_scsi_command(struct drivetemp_data *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u8 ata_command, u8 feature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u8 lba_low, u8 lba_mid, u8 lba_high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) u8 scsi_cmd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int data_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) memset(scsi_cmd, 0, sizeof(scsi_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) scsi_cmd[0] = ATA_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (ata_command == ATA_CMD_SMART && feature == SMART_WRITE_LOG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) scsi_cmd[1] = (5 << 1); /* PIO Data-out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * No off.line or cc, write to dev, block count in sector count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) scsi_cmd[2] = 0x06;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) data_dir = DMA_TO_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) scsi_cmd[1] = (4 << 1); /* PIO Data-in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * No off.line or cc, read from dev, block count in sector count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) scsi_cmd[2] = 0x0e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) data_dir = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) scsi_cmd[4] = feature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) scsi_cmd[6] = 1; /* 1 sector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) scsi_cmd[8] = lba_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) scsi_cmd[10] = lba_mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) scsi_cmd[12] = lba_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) scsi_cmd[14] = ata_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return scsi_execute_req(st->sdev, scsi_cmd, data_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) st->smartdata, ATA_SECT_SIZE, NULL, HZ, 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int drivetemp_ata_command(struct drivetemp_data *st, u8 feature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u8 select)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return drivetemp_scsi_command(st, ATA_CMD_SMART, feature, select,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ATA_SMART_LBAM_PASS, ATA_SMART_LBAH_PASS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static int drivetemp_get_smarttemp(struct drivetemp_data *st, u32 attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) long *temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) u8 *buf = st->smartdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) bool have_temp = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u8 temp_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u8 csum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) err = drivetemp_ata_command(st, ATA_SMART_READ_VALUES, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* Checksum the read value table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) csum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) for (i = 0; i < ATA_SECT_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) csum += buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (csum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) dev_dbg(&st->sdev->sdev_gendev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) "checksum error reading SMART values\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) for (i = 0; i < ATA_MAX_SMART_ATTRS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) u8 *attr = buf + i * 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int id = attr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (id == SMART_TEMP_PROP_190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) temp_raw = attr[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) have_temp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (id == SMART_TEMP_PROP_194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) temp_raw = attr[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) have_temp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (have_temp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *temp = temp_raw * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int drivetemp_get_scttemp(struct drivetemp_data *st, u32 attr, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) u8 *buf = st->smartdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) err = drivetemp_ata_command(st, SMART_READ_LOG, SCT_STATUS_REQ_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) case hwmon_temp_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (!temp_is_valid(buf[SCT_STATUS_TEMP]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) *val = temp_from_sct(buf[SCT_STATUS_TEMP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case hwmon_temp_lowest:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (!temp_is_valid(buf[SCT_STATUS_TEMP_LOWEST]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) *val = temp_from_sct(buf[SCT_STATUS_TEMP_LOWEST]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) case hwmon_temp_highest:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (!temp_is_valid(buf[SCT_STATUS_TEMP_HIGHEST]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *val = temp_from_sct(buf[SCT_STATUS_TEMP_HIGHEST]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static const char * const sct_avoid_models[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * These drives will have WRITE FPDMA QUEUED command timeouts and sometimes just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * freeze until power-cycled under heavy write loads when their temperature is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * getting polled in SCT mode. The SMART mode seems to be fine, though.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * While only the 3 TB model (DT01ACA3) was actually caught exhibiting the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * problem let's play safe here to avoid data corruption and ban the whole
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * DT01ACAx family.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * The models from this array are prefix-matched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) "TOSHIBA DT01ACA",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static bool drivetemp_sct_avoid(struct drivetemp_data *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct scsi_device *sdev = st->sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) unsigned int ctr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (!sdev->model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * The "model" field contains just the raw SCSI INQUIRY response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * "product identification" field, which has a width of 16 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * This field is space-filled, but is NOT NULL-terminated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) for (ctr = 0; ctr < ARRAY_SIZE(sct_avoid_models); ctr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (!strncmp(sdev->model, sct_avoid_models[ctr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) strlen(sct_avoid_models[ctr])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static int drivetemp_identify_sata(struct drivetemp_data *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct scsi_device *sdev = st->sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) u8 *buf = st->smartdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct scsi_vpd *vpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) bool is_ata, is_sata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) bool have_sct_data_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) bool have_sct_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) bool have_smart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) bool have_sct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) u16 *ata_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) u16 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) long temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* SCSI-ATA Translation present? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) vpd = rcu_dereference(sdev->vpd_pg89);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * Verify that ATA IDENTIFY DEVICE data is included in ATA Information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * VPD and that the drive implements the SATA protocol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (!vpd || vpd->len < 572 || vpd->data[56] != ATA_CMD_ID_ATA ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) vpd->data[36] != 0x34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ata_id = (u16 *)&vpd->data[60];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) is_ata = ata_id_is_ata(ata_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) is_sata = ata_id_is_sata(ata_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) have_sct = ata_id_sct_supported(ata_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) have_sct_data_table = ata_id_sct_data_tables(ata_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) have_smart = ata_id_smart_supported(ata_id) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ata_id_smart_enabled(ata_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* bail out if this is not a SATA device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (!is_ata || !is_sata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (have_sct && drivetemp_sct_avoid(st)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) dev_notice(&sdev->sdev_gendev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) "will avoid using SCT for temperature monitoring\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) have_sct = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!have_sct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) goto skip_sct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) err = drivetemp_ata_command(st, SMART_READ_LOG, SCT_STATUS_REQ_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) goto skip_sct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) version = (buf[SCT_STATUS_VERSION_HIGH] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) buf[SCT_STATUS_VERSION_LOW];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (version != 2 && version != 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) goto skip_sct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) have_sct_temp = temp_is_valid(buf[SCT_STATUS_TEMP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (!have_sct_temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) goto skip_sct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) st->have_temp_lowest = temp_is_valid(buf[SCT_STATUS_TEMP_LOWEST]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) st->have_temp_highest = temp_is_valid(buf[SCT_STATUS_TEMP_HIGHEST]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (!have_sct_data_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) goto skip_sct_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /* Request and read temperature history table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) memset(buf, '\0', sizeof(st->smartdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) buf[0] = 5; /* data table command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) buf[2] = 1; /* read table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) buf[4] = 2; /* temperature history table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) err = drivetemp_ata_command(st, SMART_WRITE_LOG, SCT_STATUS_REQ_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) goto skip_sct_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) err = drivetemp_ata_command(st, SMART_READ_LOG, SCT_READ_LOG_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) goto skip_sct_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * Temperature limits per AT Attachment 8 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * ATA/ATAPI Command Set (ATA8-ACS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) st->have_temp_max = temp_is_valid(buf[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) st->have_temp_crit = temp_is_valid(buf[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) st->have_temp_min = temp_is_valid(buf[8]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) st->have_temp_lcrit = temp_is_valid(buf[9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) st->temp_max = temp_from_sct(buf[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) st->temp_crit = temp_from_sct(buf[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) st->temp_min = temp_from_sct(buf[8]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) st->temp_lcrit = temp_from_sct(buf[9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) skip_sct_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (have_sct_temp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) st->get_temp = drivetemp_get_scttemp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) skip_sct:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (!have_smart)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) st->get_temp = drivetemp_get_smarttemp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return drivetemp_get_smarttemp(st, hwmon_temp_input, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static int drivetemp_identify(struct drivetemp_data *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct scsi_device *sdev = st->sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /* Bail out immediately if there is no inquiry data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (!sdev->inquiry || sdev->inquiry_len < 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /* Disk device? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (sdev->type != TYPE_DISK && sdev->type != TYPE_ZBC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return drivetemp_identify_sata(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static int drivetemp_read(struct device *dev, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) u32 attr, int channel, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct drivetemp_data *st = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (type != hwmon_temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) case hwmon_temp_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) case hwmon_temp_lowest:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) case hwmon_temp_highest:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) mutex_lock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) err = st->get_temp(st, attr, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case hwmon_temp_lcrit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) *val = st->temp_lcrit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) case hwmon_temp_min:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) *val = st->temp_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) case hwmon_temp_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) *val = st->temp_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) case hwmon_temp_crit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) *val = st->temp_crit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static umode_t drivetemp_is_visible(const void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) u32 attr, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) const struct drivetemp_data *st = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) case hwmon_temp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) case hwmon_temp_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) case hwmon_temp_lowest:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (st->have_temp_lowest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) case hwmon_temp_highest:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (st->have_temp_highest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) case hwmon_temp_min:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (st->have_temp_min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) case hwmon_temp_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (st->have_temp_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) case hwmon_temp_lcrit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (st->have_temp_lcrit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) case hwmon_temp_crit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (st->have_temp_crit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static const struct hwmon_channel_info *drivetemp_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) HWMON_CHANNEL_INFO(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) HWMON_C_REGISTER_TZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) HWMON_T_LOWEST | HWMON_T_HIGHEST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) HWMON_T_MIN | HWMON_T_MAX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) HWMON_T_LCRIT | HWMON_T_CRIT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static const struct hwmon_ops drivetemp_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .is_visible = drivetemp_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .read = drivetemp_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static const struct hwmon_chip_info drivetemp_chip_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .ops = &drivetemp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .info = drivetemp_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * The device argument points to sdev->sdev_dev. Its parent is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * sdev->sdev_gendev, which we can use to get the scsi_device pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static int drivetemp_add(struct device *dev, struct class_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct scsi_device *sdev = to_scsi_device(dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) struct drivetemp_data *st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) st = kzalloc(sizeof(*st), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (!st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) st->sdev = sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) st->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) mutex_init(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (drivetemp_identify(st)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) st->hwdev = hwmon_device_register_with_info(dev->parent, "drivetemp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) st, &drivetemp_chip_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (IS_ERR(st->hwdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) err = PTR_ERR(st->hwdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) list_add(&st->list, &drivetemp_devlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) kfree(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static void drivetemp_remove(struct device *dev, struct class_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct drivetemp_data *st, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) list_for_each_entry_safe(st, tmp, &drivetemp_devlist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (st->dev == dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) list_del(&st->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) hwmon_device_unregister(st->hwdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) kfree(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static struct class_interface drivetemp_interface = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) .add_dev = drivetemp_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) .remove_dev = drivetemp_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static int __init drivetemp_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return scsi_register_interface(&drivetemp_interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static void __exit drivetemp_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) scsi_unregister_interface(&drivetemp_interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) module_init(drivetemp_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) module_exit(drivetemp_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) MODULE_AUTHOR("Guenter Roeck <linus@roeck-us.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) MODULE_DESCRIPTION("Hard drive temperature monitor");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) MODULE_LICENSE("GPL");