ide-disk_proc.c revision 06b89518fa69fb7243dc98c31f9a9cfa61bfe788
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_disk_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