18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <linux/kernel.h> 38c2ecf20Sopenharmony_ci#include <linux/ide.h> 48c2ecf20Sopenharmony_ci#include <linux/slab.h> 58c2ecf20Sopenharmony_ci#include <linux/export.h> 68c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include "ide-disk.h" 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_cistatic int smart_enable(ide_drive_t *drive) 118c2ecf20Sopenharmony_ci{ 128c2ecf20Sopenharmony_ci struct ide_cmd cmd; 138c2ecf20Sopenharmony_ci struct ide_taskfile *tf = &cmd.tf; 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci memset(&cmd, 0, sizeof(cmd)); 168c2ecf20Sopenharmony_ci tf->feature = ATA_SMART_ENABLE; 178c2ecf20Sopenharmony_ci tf->lbam = ATA_SMART_LBAM_PASS; 188c2ecf20Sopenharmony_ci tf->lbah = ATA_SMART_LBAH_PASS; 198c2ecf20Sopenharmony_ci tf->command = ATA_CMD_SMART; 208c2ecf20Sopenharmony_ci cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; 218c2ecf20Sopenharmony_ci cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci return ide_no_data_taskfile(drive, &cmd); 248c2ecf20Sopenharmony_ci} 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistatic int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) 278c2ecf20Sopenharmony_ci{ 288c2ecf20Sopenharmony_ci struct ide_cmd cmd; 298c2ecf20Sopenharmony_ci struct ide_taskfile *tf = &cmd.tf; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci memset(&cmd, 0, sizeof(cmd)); 328c2ecf20Sopenharmony_ci tf->feature = sub_cmd; 338c2ecf20Sopenharmony_ci tf->nsect = 0x01; 348c2ecf20Sopenharmony_ci tf->lbam = ATA_SMART_LBAM_PASS; 358c2ecf20Sopenharmony_ci tf->lbah = ATA_SMART_LBAH_PASS; 368c2ecf20Sopenharmony_ci tf->command = ATA_CMD_SMART; 378c2ecf20Sopenharmony_ci cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; 388c2ecf20Sopenharmony_ci cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; 398c2ecf20Sopenharmony_ci cmd.protocol = ATA_PROT_PIO; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci return ide_raw_taskfile(drive, &cmd, buf, 1); 428c2ecf20Sopenharmony_ci} 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistatic int idedisk_cache_proc_show(struct seq_file *m, void *v) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci ide_drive_t *drive = (ide_drive_t *) m->private; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci if (drive->dev_flags & IDE_DFLAG_ID_READ) 498c2ecf20Sopenharmony_ci seq_printf(m, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2); 508c2ecf20Sopenharmony_ci else 518c2ecf20Sopenharmony_ci seq_printf(m, "(none)\n"); 528c2ecf20Sopenharmony_ci return 0; 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic int idedisk_capacity_proc_show(struct seq_file *m, void *v) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci ide_drive_t*drive = (ide_drive_t *)m->private; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci seq_printf(m, "%llu\n", (long long)ide_gd_capacity(drive)); 608c2ecf20Sopenharmony_ci return 0; 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic int __idedisk_proc_show(struct seq_file *m, ide_drive_t *drive, u8 sub_cmd) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci u8 *buf; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci buf = kmalloc(SECTOR_SIZE, GFP_KERNEL); 688c2ecf20Sopenharmony_ci if (!buf) 698c2ecf20Sopenharmony_ci return -ENOMEM; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci (void)smart_enable(drive); 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci if (get_smart_data(drive, buf, sub_cmd) == 0) { 748c2ecf20Sopenharmony_ci __le16 *val = (__le16 *)buf; 758c2ecf20Sopenharmony_ci int i; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci for (i = 0; i < SECTOR_SIZE / 2; i++) { 788c2ecf20Sopenharmony_ci seq_printf(m, "%04x%c", le16_to_cpu(val[i]), 798c2ecf20Sopenharmony_ci (i % 8) == 7 ? '\n' : ' '); 808c2ecf20Sopenharmony_ci } 818c2ecf20Sopenharmony_ci } 828c2ecf20Sopenharmony_ci kfree(buf); 838c2ecf20Sopenharmony_ci return 0; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic int idedisk_sv_proc_show(struct seq_file *m, void *v) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci return __idedisk_proc_show(m, m->private, ATA_SMART_READ_VALUES); 898c2ecf20Sopenharmony_ci} 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistatic int idedisk_st_proc_show(struct seq_file *m, void *v) 928c2ecf20Sopenharmony_ci{ 938c2ecf20Sopenharmony_ci return __idedisk_proc_show(m, m->private, ATA_SMART_READ_THRESHOLDS); 948c2ecf20Sopenharmony_ci} 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ciide_proc_entry_t ide_disk_proc[] = { 978c2ecf20Sopenharmony_ci { "cache", S_IFREG|S_IRUGO, idedisk_cache_proc_show }, 988c2ecf20Sopenharmony_ci { "capacity", S_IFREG|S_IRUGO, idedisk_capacity_proc_show }, 998c2ecf20Sopenharmony_ci { "geometry", S_IFREG|S_IRUGO, ide_geometry_proc_show }, 1008c2ecf20Sopenharmony_ci { "smart_values", S_IFREG|S_IRUSR, idedisk_sv_proc_show }, 1018c2ecf20Sopenharmony_ci { "smart_thresholds", S_IFREG|S_IRUSR, idedisk_st_proc_show }, 1028c2ecf20Sopenharmony_ci {} 1038c2ecf20Sopenharmony_ci}; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ciide_devset_rw_field(bios_cyl, bios_cyl); 1068c2ecf20Sopenharmony_ciide_devset_rw_field(bios_head, bios_head); 1078c2ecf20Sopenharmony_ciide_devset_rw_field(bios_sect, bios_sect); 1088c2ecf20Sopenharmony_ciide_devset_rw_field(failures, failures); 1098c2ecf20Sopenharmony_ciide_devset_rw_field(lun, lun); 1108c2ecf20Sopenharmony_ciide_devset_rw_field(max_failures, max_failures); 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ciconst struct ide_proc_devset ide_disk_settings[] = { 1138c2ecf20Sopenharmony_ci IDE_PROC_DEVSET(acoustic, 0, 254), 1148c2ecf20Sopenharmony_ci IDE_PROC_DEVSET(address, 0, 2), 1158c2ecf20Sopenharmony_ci IDE_PROC_DEVSET(bios_cyl, 0, 65535), 1168c2ecf20Sopenharmony_ci IDE_PROC_DEVSET(bios_head, 0, 255), 1178c2ecf20Sopenharmony_ci IDE_PROC_DEVSET(bios_sect, 0, 63), 1188c2ecf20Sopenharmony_ci IDE_PROC_DEVSET(failures, 0, 65535), 1198c2ecf20Sopenharmony_ci IDE_PROC_DEVSET(lun, 0, 7), 1208c2ecf20Sopenharmony_ci IDE_PROC_DEVSET(max_failures, 0, 65535), 1218c2ecf20Sopenharmony_ci IDE_PROC_DEVSET(multcount, 0, 16), 1228c2ecf20Sopenharmony_ci IDE_PROC_DEVSET(nowerr, 0, 1), 1238c2ecf20Sopenharmony_ci IDE_PROC_DEVSET(wcache, 0, 1), 1248c2ecf20Sopenharmony_ci { NULL }, 1258c2ecf20Sopenharmony_ci}; 126