linux/drivers/ide/ide-disk_proc.c
<<
>>
Prefs
   1#include <linux/kernel.h>
   2#include <linux/ide.h>
   3#include <linux/hdreg.h>
   4
   5#include "ide-disk.h"
   6
   7static int smart_enable(ide_drive_t *drive)
   8{
   9        ide_task_t args;
  10        struct ide_taskfile *tf = &args.tf;
  11
  12        memset(&args, 0, sizeof(ide_task_t));
  13        tf->feature = ATA_SMART_ENABLE;
  14        tf->lbam    = ATA_SMART_LBAM_PASS;
  15        tf->lbah    = ATA_SMART_LBAH_PASS;
  16        tf->command = ATA_CMD_SMART;
  17        args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
  18        return ide_no_data_taskfile(drive, &args);
  19}
  20
  21static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
  22{
  23        ide_task_t args;
  24        struct ide_taskfile *tf = &args.tf;
  25
  26        memset(&args, 0, sizeof(ide_task_t));
  27        tf->feature = sub_cmd;
  28        tf->nsect   = 0x01;
  29        tf->lbam    = ATA_SMART_LBAM_PASS;
  30        tf->lbah    = ATA_SMART_LBAH_PASS;
  31        tf->command = ATA_CMD_SMART;
  32        args.tf_flags   = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
  33        args.data_phase = TASKFILE_IN;
  34        (void) smart_enable(drive);
  35        return ide_raw_taskfile(drive, &args, buf, 1);
  36}
  37
  38static int proc_idedisk_read_cache
  39        (char *page, char **start, off_t off, int count, int *eof, void *data)
  40{
  41        ide_drive_t     *drive = (ide_drive_t *) data;
  42        char            *out = page;
  43        int             len;
  44
  45        if (drive->dev_flags & IDE_DFLAG_ID_READ)
  46                len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2);
  47        else
  48                len = sprintf(out, "(none)\n");
  49
  50        PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
  51}
  52
  53static int proc_idedisk_read_capacity
  54        (char *page, char **start, off_t off, int count, int *eof, void *data)
  55{
  56        ide_drive_t*drive = (ide_drive_t *)data;
  57        int len;
  58
  59        len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive));
  60
  61        PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
  62}
  63
  64static int proc_idedisk_read_smart(char *page, char **start, off_t off,
  65                                   int count, int *eof, void *data, u8 sub_cmd)
  66{
  67        ide_drive_t     *drive = (ide_drive_t *)data;
  68        int             len = 0, i = 0;
  69
  70        if (get_smart_data(drive, page, sub_cmd) == 0) {
  71                unsigned short *val = (unsigned short *) page;
  72                char *out = (char *)val + SECTOR_SIZE;
  73
  74                page = out;
  75                do {
  76                        out += sprintf(out, "%04x%c", le16_to_cpu(*val),
  77                                       (++i & 7) ? ' ' : '\n');
  78                        val += 1;
  79                } while (i < SECTOR_SIZE / 2);
  80                len = out - page;
  81        }
  82
  83        PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
  84}
  85
  86static int proc_idedisk_read_sv
  87        (char *page, char **start, off_t off, int count, int *eof, void *data)
  88{
  89        return proc_idedisk_read_smart(page, start, off, count, eof, data,
  90                                       ATA_SMART_READ_VALUES);
  91}
  92
  93static int proc_idedisk_read_st
  94        (char *page, char **start, off_t off, int count, int *eof, void *data)
  95{
  96        return proc_idedisk_read_smart(page, start, off, count, eof, data,
  97                                       ATA_SMART_READ_THRESHOLDS);
  98}
  99
 100ide_proc_entry_t ide_disk_proc[] = {
 101        { "cache",        S_IFREG|S_IRUGO, proc_idedisk_read_cache,    NULL },
 102        { "capacity",     S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL },
 103        { "geometry",     S_IFREG|S_IRUGO, proc_ide_read_geometry,     NULL },
 104        { "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv,       NULL },
 105        { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st,   NULL },
 106        { NULL, 0, NULL, NULL }
 107};
 108
 109ide_devset_rw_field(bios_cyl, bios_cyl);
 110ide_devset_rw_field(bios_head, bios_head);
 111ide_devset_rw_field(bios_sect, bios_sect);
 112ide_devset_rw_field(failures, failures);
 113ide_devset_rw_field(lun, lun);
 114ide_devset_rw_field(max_failures, max_failures);
 115
 116const struct ide_proc_devset ide_disk_settings[] = {
 117        IDE_PROC_DEVSET(acoustic,       0,   254),
 118        IDE_PROC_DEVSET(address,        0,     2),
 119        IDE_PROC_DEVSET(bios_cyl,       0, 65535),
 120        IDE_PROC_DEVSET(bios_head,      0,   255),
 121        IDE_PROC_DEVSET(bios_sect,      0,    63),
 122        IDE_PROC_DEVSET(failures,       0, 65535),
 123        IDE_PROC_DEVSET(lun,            0,     7),
 124        IDE_PROC_DEVSET(max_failures,   0, 65535),
 125        IDE_PROC_DEVSET(multcount,      0,    16),
 126        IDE_PROC_DEVSET(nowerr,         0,     1),
 127        IDE_PROC_DEVSET(wcache,         0,     1),
 128        { 0 },
 129};
 130