drivetemp.c 17 KB

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