1#include <linux/kernel.h> 2#include <linux/ide.h> 3#include <linux/slab.h> 4#include <linux/seq_file.h> 5 6#include "ide-disk.h" 7 8static int smart_enable(ide_drive_t *drive) 9{ 10 struct ide_cmd cmd; 11 struct ide_taskfile *tf = &cmd.tf; 12 13 memset(&cmd, 0, sizeof(cmd)); 14 tf->feature = ATA_SMART_ENABLE; 15 tf->lbam = ATA_SMART_LBAM_PASS; 16 tf->lbah = ATA_SMART_LBAH_PASS; 17 tf->command = ATA_CMD_SMART; 18 cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; 19 cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; 20 21 return ide_no_data_taskfile(drive, &cmd); 22} 23 24static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) 25{ 26 struct ide_cmd cmd; 27 struct ide_taskfile *tf = &cmd.tf; 28 29 memset(&cmd, 0, sizeof(cmd)); 30 tf->feature = sub_cmd; 31 tf->nsect = 0x01; 32 tf->lbam = ATA_SMART_LBAM_PASS; 33 tf->lbah = ATA_SMART_LBAH_PASS; 34 tf->command = ATA_CMD_SMART; 35 cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; 36 cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; 37 cmd.protocol = ATA_PROT_PIO; 38 39 return ide_raw_taskfile(drive, &cmd, buf, 1); 40} 41 42static int idedisk_cache_proc_show(struct seq_file *m, void *v) 43{ 44 ide_drive_t *drive = (ide_drive_t *) m->private; 45 46 if (drive->dev_flags & IDE_DFLAG_ID_READ) 47 seq_printf(m, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2); 48 else 49 seq_printf(m, "(none)\n"); 50 return 0; 51} 52 53static int idedisk_cache_proc_open(struct inode *inode, struct file *file) 54{ 55 return single_open(file, idedisk_cache_proc_show, PDE(inode)->data); 56} 57 58static const struct file_operations idedisk_cache_proc_fops = { 59 .owner = THIS_MODULE, 60 .open = idedisk_cache_proc_open, 61 .read = seq_read, 62 .llseek = seq_lseek, 63 .release = single_release, 64}; 65 66static int idedisk_capacity_proc_show(struct seq_file *m, void *v) 67{ 68 ide_drive_t*drive = (ide_drive_t *)m->private; 69 70 seq_printf(m, "%llu\n", (long long)ide_gd_capacity(drive)); 71 return 0; 72} 73 74static int idedisk_capacity_proc_open(struct inode *inode, struct file *file) 75{ 76 return single_open(file, idedisk_capacity_proc_show, PDE(inode)->data); 77} 78 79static const struct file_operations idedisk_capacity_proc_fops = { 80 .owner = THIS_MODULE, 81 .open = idedisk_capacity_proc_open, 82 .read = seq_read, 83 .llseek = seq_lseek, 84 .release = single_release, 85}; 86 87static int __idedisk_proc_show(struct seq_file *m, ide_drive_t *drive, u8 sub_cmd) 88{ 89 u8 *buf; 90 91 buf = kmalloc(SECTOR_SIZE, GFP_KERNEL); 92 if (!buf) 93 return -ENOMEM; 94 95 (void)smart_enable(drive); 96 97 if (get_smart_data(drive, buf, sub_cmd) == 0) { 98 __le16 *val = (__le16 *)buf; 99 int i; 100 101 for (i = 0; i < SECTOR_SIZE / 2; i++) { 102 seq_printf(m, "%04x%c", le16_to_cpu(val[i]), 103 (i % 8) == 7 ? '\n' : ' '); 104 } 105 } 106 kfree(buf); 107 return 0; 108} 109 110static int idedisk_sv_proc_show(struct seq_file *m, void *v) 111{ 112 return __idedisk_proc_show(m, m->private, ATA_SMART_READ_VALUES); 113} 114 115static int idedisk_sv_proc_open(struct inode *inode, struct file *file) 116{ 117 return single_open(file, idedisk_sv_proc_show, PDE(inode)->data); 118} 119 120static const struct file_operations idedisk_sv_proc_fops = { 121 .owner = THIS_MODULE, 122 .open = idedisk_sv_proc_open, 123 .read = seq_read, 124 .llseek = seq_lseek, 125 .release = single_release, 126}; 127 128static int idedisk_st_proc_show(struct seq_file *m, void *v) 129{ 130 return __idedisk_proc_show(m, m->private, ATA_SMART_READ_THRESHOLDS); 131} 132 133static int idedisk_st_proc_open(struct inode *inode, struct file *file) 134{ 135 return single_open(file, idedisk_st_proc_show, PDE(inode)->data); 136} 137 138static const struct file_operations idedisk_st_proc_fops = { 139 .owner = THIS_MODULE, 140 .open = idedisk_st_proc_open, 141 .read = seq_read, 142 .llseek = seq_lseek, 143 .release = single_release, 144}; 145 146ide_proc_entry_t ide_disk_proc[] = { 147 { "cache", S_IFREG|S_IRUGO, &idedisk_cache_proc_fops }, 148 { "capacity", S_IFREG|S_IRUGO, &idedisk_capacity_proc_fops }, 149 { "geometry", S_IFREG|S_IRUGO, &ide_geometry_proc_fops }, 150 { "smart_values", S_IFREG|S_IRUSR, &idedisk_sv_proc_fops }, 151 { "smart_thresholds", S_IFREG|S_IRUSR, &idedisk_st_proc_fops }, 152 {} 153}; 154 155ide_devset_rw_field(bios_cyl, bios_cyl); 156ide_devset_rw_field(bios_head, bios_head); 157ide_devset_rw_field(bios_sect, bios_sect); 158ide_devset_rw_field(failures, failures); 159ide_devset_rw_field(lun, lun); 160ide_devset_rw_field(max_failures, max_failures); 161 162const struct ide_proc_devset ide_disk_settings[] = { 163 IDE_PROC_DEVSET(acoustic, 0, 254), 164 IDE_PROC_DEVSET(address, 0, 2), 165 IDE_PROC_DEVSET(bios_cyl, 0, 65535), 166 IDE_PROC_DEVSET(bios_head, 0, 255), 167 IDE_PROC_DEVSET(bios_sect, 0, 63), 168 IDE_PROC_DEVSET(failures, 0, 65535), 169 IDE_PROC_DEVSET(lun, 0, 7), 170 IDE_PROC_DEVSET(max_failures, 0, 65535), 171 IDE_PROC_DEVSET(multcount, 0, 16), 172 IDE_PROC_DEVSET(nowerr, 0, 1), 173 IDE_PROC_DEVSET(wcache, 0, 1), 174 { NULL }, 175}; 176