/*
* Copyright (C) 1997-1998 Mark Lord
* Copyright (C) 2003 Red Hat
*
* 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
*/
#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/ide.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <asm/io.h>
static struct proc_dir_entry *proc_ide_root;
static int ide_imodel_proc_show(struct seq_file *m, void *v)
{
ide_hwif_t *hwif = (ide_hwif_t *) m->private;
const char *name;
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_4drives: name = "4drives"; break;
case ide_pmac: name = "mac-io"; break;
case ide_au1xxx: name = "au1xxx"; break;
case ide_palm3710: name = "palm3710"; break;
case ide_acorn: name = "acorn"; break;
default: name = "(unknown)"; break;
}
seq_printf(m, "%s\n", name);
return 0;
}
static int ide_imodel_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, ide_imodel_proc_show, PDE(inode)->data);
}
static const struct file_operations ide_imodel_proc_fops = {
.owner = THIS_MODULE,
.open = ide_imodel_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int ide_mate_proc_show(struct seq_file *m, void *v)
{
ide_hwif_t *hwif = (ide_hwif_t *) m->private;
if (hwif && hwif->mate)
seq_printf(m, "%s\n", hwif->mate->name);
else
seq_printf(m, "(none)\n");
return 0;
}
static int ide_mate_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, ide_mate_proc_show, PDE(inode)->data);
}
static const struct file_operations ide_mate_proc_fops = {
.owner = THIS_MODULE,
.open = ide_mate_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int ide_channel_proc_show(struct seq_file *m, void *v)
{
ide_hwif_t *hwif = (ide_hwif_t *) m->private;
seq_printf(m, "%c\n", hwif->channel ? '1' : '0');
return 0;
}
static int ide_channel_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, ide_channel_proc_show, PDE(inode)->data);
}
static const struct file_operations ide_channel_proc_fops = {
.owner = THIS_MODULE,
.open = ide_channel_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int ide_identify_proc_show(struct seq_file *m, void *v)
{
ide_drive_t *drive = (ide_drive_t *)m->private;
u8 *buf;
if (!drive) {
seq_putc(m, '\n');
return 0;
}
buf = kmalloc(SECTOR_SIZE, GFP_KERNEL);
if (!buf)
return -ENOMEM;
if (taskfile_lib_get_identify(drive, buf) == 0) {
__le16 *val = (__le16 *)buf;
int i;
for (i = 0; i < SECTOR_SIZE / 2; i++) {
seq_printf(m, "%04x%c", le16_to_cpu(val[i]),
(i % 8) == 7 ? '\n' : ' ');
}
} else
seq_putc(m, buf[0]);
kfree(buf);
return 0;
}
static int ide_identify_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, ide_identify_proc_show, PDE(inode)->data);
}
static const struct file_operations ide_identify_proc_fops = {
.owner = THIS_MODULE,
.open = ide_identify_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release