/*
* Copyright (C) 1997-1998 Mark Lord
* Copyright (C) 2003 Red Hat <alan@redhat.com>
*
* Some code was moved here from ide.c, see it for original copyrights.
*/
/*
* This is the /proc/ide/ filesystem implementation.
*
* Drive/Driver settings can be retrieved by reading the drive's
* "settings" files. e.g. "cat /proc/ide0/hda/settings"
* To write a new value "val" into a specific setting "name", use:
* echo "name:val" >/proc/ide/ide0/hda/settings
*
* Also useful, "cat /proc/ide0/hda/[identify, smart_values,
* smart_thresholds, capabilities]" will issue an IDENTIFY /
* PACKET_IDENTIFY / SMART_READ_VALUES / SMART_READ_THRESHOLDS /
* SENSE CAPABILITIES command to /dev/hda, and then dump out the
* returned data as 256 16-bit words. The "hdparm" utility will
* be updated someday soon to use this mechanism.
*
*/
#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/errno.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/ctype.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/seq_file.h>
#include <asm/io.h>
static struct proc_dir_entry *proc_ide_root;
static int proc_ide_read_imodel
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_hwif_t *hwif = (ide_hwif_t *) data;
int len;
const char *name;
/*
* Neither ide_unknown nor ide_forced should be set at this point.
*/
switch (hwif->chipset) {
case ide_generic: name = "generic"; break;
case ide_pci: name = "pci"; break;
case ide_cmd640: name = "cmd640"; break;
case ide_dtc2278: name = "dtc2278"; break;
case ide_ali14xx: name = "ali14xx"; break;
case ide_qd65xx: name = "qd65xx"; break;
case ide_umc8672: name = "umc8672"; break;
case ide_ht6560b: name = "ht6560b"; break;
case ide_rz1000: name = "rz1000"; break;
case ide_trm290: name = "trm290"; break;
case ide_cmd646: name = "cmd646"; break;
case ide_cy82c693: name = "cy82c693"; break;
case ide_4drives: name = "4drives"; break;
case ide_pmac: name = "mac-io"; break;
case ide_au1xxx: name = "au1xxx"; break;
case ide_etrax100: name = "etrax100"; break;
case ide_acorn: name = "acorn"; break;
default: name = "(unknown)"; break;
}
len = sprintf(page, "%s\n", name);
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
static int proc_ide_read_mate
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_hwif_t *hwif = (ide_hwif_t *) data;
int len;
if (hwif && hwif->mate && hwif->mate->present)
len = sprintf(page, "%s\n", hwif->mate->name);
else
len = sprintf(page, "(none)\n");
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
static int proc_ide_read_channel
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_hwif_t *hwif = (ide_hwif_t *) data;
int len;
page[0] = hwif->channel ? '1' : '0';
page[1] = '\n';
len = 2;
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
static int proc_ide_read_identify
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = (ide_drive_t *)data;
int len = 0, i = 0;
int err = 0;
len = sprintf(page, "\n");
if (drive) {
unsigned short *val = (unsigned short *) page;
err = taskfile_lib_get_identify(drive, page);
if (!err) {
char *out = ((char *)page) + (SECTOR_WORDS * 4);
page = out;
do {
out += sprintf(out, "%04x%c",
le16_to_cpu(*val), (++i & 7) ? ' ' : '\n');
val += 1;
} while (i < (SECTOR_WORDS * 2));
len = out - page;
}
}
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
/**
* __ide_add_setting - add an ide setting option
* @drive: drive to use
* @name: setting name
* @rw: true if the function is read write
* @data_type: type of data
* @min: range minimum
* @max: range maximum
* @mul_factor: multiplication scale
* @div_factor: divison scale
* @data: private data field
* @set: setting
* @auto_remove: setting auto removal flag
*
* Removes the setting named from the device if it is present.