Commit 0cb583fd authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-next-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-next-2.6:
  ide: fixup for fujitsu disk
  ide: convert to ->proc_fops
  at91_ide: remove headers specific for at91sam9263
  IDE: palm_bk3710: convert clock usage after clkdev conversion
  ide: fix races in handling of user-space SET XFER commands
  ide: allow ide_dev_read_id() to be called from the IRQ context
  ide: ide-taskfile.c fix style problems
  drivers/ide/ide-cd.c: Use DIV_ROUND_CLOSEST
  ide-tape: fix handling of postponed rqs
  ide-tape: convert to ide_debug_log macro
  ide-tape: fix debug call
  ide: Fix annoying warning in ide_pio_bytes().
  IDE: Save a call to PageHighMem()
parents 723e9db7 a2d10568
......@@ -29,9 +29,7 @@
#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/at91sam9263.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91sam9263_matrix.h>
#define DRV_NAME "at91_ide"
......
......@@ -30,6 +30,7 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
......@@ -1146,8 +1147,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u",
curspeed, maxspeed);
cd->current_speed = (curspeed + (176/2)) / 176;
cd->max_speed = (maxspeed + (176/2)) / 176;
cd->current_speed = DIV_ROUND_CLOSEST(curspeed, 176);
cd->max_speed = DIV_ROUND_CLOSEST(maxspeed, 176);
}
#define IDE_CD_CAPABILITIES \
......@@ -1389,19 +1390,30 @@ static sector_t ide_cdrom_capacity(ide_drive_t *drive)
return capacity * sectors_per_frame;
}
static int proc_idecd_read_capacity(char *page, char **start, off_t off,
int count, int *eof, void *data)
static int idecd_capacity_proc_show(struct seq_file *m, void *v)
{
ide_drive_t *drive = data;
int len;
ide_drive_t *drive = m->private;
len = sprintf(page, "%llu\n", (long long)ide_cdrom_capacity(drive));
PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
seq_printf(m, "%llu\n", (long long)ide_cdrom_capacity(drive));
return 0;
}
static int idecd_capacity_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, idecd_capacity_proc_show, PDE(inode)->data);
}
static const struct file_operations idecd_capacity_proc_fops = {
.owner = THIS_MODULE,
.open = idecd_capacity_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static ide_proc_entry_t idecd_proc[] = {
{ "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
{ NULL, 0, NULL, NULL }
{ "capacity", S_IFREG|S_IRUGO, &idecd_capacity_proc_fops },
{}
};
static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive)
......
#include <linux/kernel.h>
#include <linux/ide.h>
#include <linux/seq_file.h>
#include "ide-disk.h"
......@@ -37,77 +38,117 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
return ide_raw_taskfile(drive, &cmd, buf, 1);
}
static int proc_idedisk_read_cache
(char *page, char **start, off_t off, int count, int *eof, void *data)
static int idedisk_cache_proc_show(struct seq_file *m, void *v)
{
ide_drive_t *drive = (ide_drive_t *) data;
char *out = page;
int len;
ide_drive_t *drive = (ide_drive_t *) m->private;
if (drive->dev_flags & IDE_DFLAG_ID_READ)
len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2);
seq_printf(m, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2);
else
len = sprintf(out, "(none)\n");
seq_printf(m, "(none)\n");
return 0;
}
PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
static int idedisk_cache_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, idedisk_cache_proc_show, PDE(inode)->data);
}
static int proc_idedisk_read_capacity
(char *page, char **start, off_t off, int count, int *eof, void *data)
static const struct file_operations idedisk_cache_proc_fops = {
.owner = THIS_MODULE,
.open = idedisk_cache_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int idedisk_capacity_proc_show(struct seq_file *m, void *v)
{
ide_drive_t*drive = (ide_drive_t *)data;
int len;
ide_drive_t*drive = (ide_drive_t *)m->private;
len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive));
seq_printf(m, "%llu\n", (long long)ide_gd_capacity(drive));
return 0;
}
PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
static int idedisk_capacity_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, idedisk_capacity_proc_show, PDE(inode)->data);
}
static int proc_idedisk_read_smart(char *page, char **start, off_t off,
int count, int *eof, void *data, u8 sub_cmd)
static const struct file_operations idedisk_capacity_proc_fops = {
.owner = THIS_MODULE,
.open = idedisk_capacity_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int __idedisk_proc_show(struct seq_file *m, ide_drive_t *drive, u8 sub_cmd)
{
ide_drive_t *drive = (ide_drive_t *)data;
int len = 0, i = 0;
u8 *buf;
buf = kmalloc(SECTOR_SIZE, GFP_KERNEL);
if (!buf)
return -ENOMEM;
(void)smart_enable(drive);
if (get_smart_data(drive, page, sub_cmd) == 0) {
unsigned short *val = (unsigned short *) page;
char *out = (char *)val + SECTOR_SIZE;
page = out;
do {
out += sprintf(out, "%04x%c", le16_to_cpu(*val),
(++i & 7) ? ' ' : '\n');
val += 1;
} while (i < SECTOR_SIZE / 2);
len = out - page;
if (get_smart_data(drive, buf, sub_cmd) == 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' : ' ');
}
}
kfree(buf);
return 0;
}
PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
static int idedisk_sv_proc_show(struct seq_file *m, void *v)
{
return __idedisk_proc_show(m, m->private, ATA_SMART_READ_VALUES);
}
static int proc_idedisk_read_sv
(char *page, char **start, off_t off, int count, int *eof, void *data)
static int idedisk_sv_proc_open(struct inode *inode, struct file *file)
{
return proc_idedisk_read_smart(page, start, off, count, eof, data,
ATA_SMART_READ_VALUES);
return single_open(file, idedisk_sv_proc_show, PDE(inode)->data);
}
static int proc_idedisk_read_st
(char *page, char **start, off_t off, int count, int *eof, void *data)
static const struct file_operations idedisk_sv_proc_fops = {
.owner = THIS_MODULE,
.open = idedisk_sv_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int idedisk_st_proc_show(struct seq_file *m, void *v)
{
return proc_idedisk_read_smart(page, start, off, count, eof, data,
ATA_SMART_READ_THRESHOLDS);
return __idedisk_proc_show(m, m->private, ATA_SMART_READ_THRESHOLDS);
}
static int idedisk_st_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, idedisk_st_proc_show, PDE(inode)->data);
}
static const struct file_operations idedisk_st_proc_fops = {
.owner = THIS_MODULE,
.open = idedisk_st_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
ide_proc_entry_t ide_disk_proc[] = {
{ "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL },
{ "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL },
{ "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL },
{ "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv, NULL },
{ "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st, NULL },
{ NULL, 0, NULL, NULL }
{ "cache", S_IFREG|S_IRUGO, &idedisk_cache_proc_fops },
{ "capacity", S_IFREG|S_IRUGO, &idedisk_capacity_proc_fops },
{ "geometry", S_IFREG|S_IRUGO, &ide_geometry_proc_fops },
{ "smart_values", S_IFREG|S_IRUSR, &idedisk_sv_proc_fops },
{ "smart_thresholds", S_IFREG|S_IRUSR, &idedisk_st_proc_fops },
{}
};
ide_devset_rw_field(bios_cyl, bios_cyl);
......
#include <linux/kernel.h>
#include <linux/ide.h>
#include <linux/seq_file.h>
#include "ide-floppy.h"
static int proc_idefloppy_read_capacity(char *page, char **start, off_t off,
int count, int *eof, void *data)
static int idefloppy_capacity_proc_show(struct seq_file *m, void *v)
{
ide_drive_t*drive = (ide_drive_t *)data;
int len;
ide_drive_t*drive = (ide_drive_t *)m->private;
len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive));
PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
seq_printf(m, "%llu\n", (long long)ide_gd_capacity(drive));
return 0;
}
static int idefloppy_capacity_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, idefloppy_capacity_proc_show, PDE(inode)->data);
}
static const struct file_operations idefloppy_capacity_proc_fops = {
.owner = THIS_MODULE,
.open = idefloppy_capacity_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
ide_proc_entry_t ide_floppy_proc[] = {
{ "capacity", S_IFREG|S_IRUGO, proc_idefloppy_read_capacity, NULL },
{ "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL },
{ NULL, 0, NULL, NULL }
{ "capacity", S_IFREG|S_IRUGO, &idefloppy_capacity_proc_fops },
{ "geometry", S_IFREG|S_IRUGO, &ide_geometry_proc_fops },
{}
};
ide_devset_rw_field(bios_cyl, bios_cyl);
......
......@@ -167,6 +167,8 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
err = -EINVAL;
goto abort;
}
cmd.tf_flags |= IDE_TFLAG_SET_XFER;
}
err = ide_raw_taskfile(drive, &cmd, buf, args[3]);
......@@ -174,12 +176,6 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
args[0] = tf->status;
args[1] = tf->error;
args[2] = tf->nsect;
if (!err && xfer_rate) {
/* active-retuning-calls future */
ide_set_xfer_rate(drive, xfer_rate);
ide_driveid_update(drive);
}
abort:
if (copy_to_user((void __user *)arg, &args, 4))
err = -EFAULT;
......
......@@ -102,8 +102,8 @@ EXPORT_SYMBOL(ide_fixstring);
* setting a timer to wake up at half second intervals thereafter,
* until timeout is achieved, before timing out.
*/
static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
unsigned long timeout, u8 *rstat)
int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
unsigned long timeout, u8 *rstat)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
......@@ -292,6 +292,7 @@ static const char *nien_quirk_list[] = {
"QUANTUM FIREBALLP KX27.3",
"QUANTUM FIREBALLP LM20.4",
"QUANTUM FIREBALLP LM20.5",
"FUJITSU MHZ2160BH G2",
NULL
};
......@@ -316,7 +317,7 @@ int ide_driveid_update(ide_drive_t *drive)
return 0;
SELECT_MASK(drive, 1);
rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id);
rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id, 1);
SELECT_MASK(drive, 0);
if (rc)
......@@ -363,14 +364,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
* this point (lost interrupt).
*/
/*
* FIXME: we race against the running IRQ here if
* this is called from non IRQ context. If we use
* disable_irq() we hang on the error path. Work
* is needed.
*/
disable_irq_nosync(hwif->irq);
udelay(1);
tp_ops->dev_select(drive);
SELECT_MASK(drive, 1);
......@@ -394,8 +387,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
SELECT_MASK(drive, 0);
enable_irq(hwif->irq);
if (error) {
(void) ide_dump_status(drive, "set_drive_speed_status", stat);
return error;
......
......@@ -238,6 +238,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
* @drive: drive to identify
* @cmd: command to use
* @id: buffer for IDENTIFY data
* @irq_ctx: flag set when called from the IRQ context
*
* Sends an ATA(PI) IDENTIFY request to a drive and waits for a response.
*
......@@ -246,7 +247,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
* 2 device aborted the command (refused to identify itself)
*/
int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id, int irq_ctx)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
......@@ -263,7 +264,10 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
/* take a deep breath */
msleep(50);
if (irq_ctx)
mdelay(50);
else
msleep(50);
if (io_ports->ctl_addr &&
(hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) {
......@@ -295,12 +299,19 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
if (ide_busy_sleep(drive, timeout, use_altstatus))
return 1;
/* wait for IRQ and ATA_DRQ */
msleep(50);
s = tp_ops->read_status(hwif);
if (irq_ctx) {
rc = __ide_wait_stat(drive, ATA_DRQ, BAD_R_STAT, timeout, &s);
if (rc)
return 1;
} else {
rc = ide_busy_sleep(drive, timeout, use_altstatus);
if (rc)
return 1;
msleep(50);
s = tp_ops->read_status(hwif);
}
if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
/* drive returned ID */
......@@ -406,10 +417,10 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
present || cmd == ATA_CMD_ID_ATAPI) {
rc = ide_dev_read_id(drive, cmd, id);
rc = ide_dev_read_id(drive, cmd, id, 0);
if (rc)
/* failed: try again */
rc = ide_dev_read_id(drive, cmd, id);
rc = ide_dev_read_id(drive, cmd, id, 0);
stat = tp_ops->read_status(hwif);
......@@ -424,7 +435,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
msleep(50);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
(void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0);
rc = ide_dev_read_id(drive, cmd, id);
rc = ide_dev_read_id(drive, cmd, id, 0);
}
/* ensure drive IRQ is clear */
......
......@@ -30,11 +30,9 @@
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)
static int ide_imodel_proc_show(struct seq_file *m, void *v)
{
ide_hwif_t *hwif = (ide_hwif_t *) data;
int len;
ide_hwif_t *hwif = (ide_hwif_t *) m->private;
const char *name;
switch (hwif->chipset) {
......@@ -53,63 +51,108 @@ static int proc_ide_read_imodel
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);
seq_printf(m, "%s\n", name);
return 0;
}
static int proc_ide_read_mate
(char *page, char **start, off_t off, int count, int *eof, void *data)
static int ide_imodel_proc_open(struct inode *inode, struct file *file)
{
ide_hwif_t *hwif = (ide_hwif_t *) data;
int len;
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)
len = sprintf(page, "%s\n", hwif->mate->name);
seq_printf(m, "%s\n", hwif->mate->name);
else
len = sprintf(page, "(none)\n");
PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
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 int proc_ide_read_channel
(char *page, char **start, off_t off, int count, int *eof, void *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 *) data;
int len;
ide_hwif_t *hwif = (ide_hwif_t *) m->private;
page[0] = hwif->channel ? '1' : '0';
page[1] = '\n';
len = 2;
PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
seq_printf(m, "%c\n", hwif->channel ? '1' : '0');
return 0;
}
static int proc_ide_read_identify
(char *page, char **start, off_t off, int count, int *eof, void *data)
static int ide_channel_proc_open(struct inode *inode, struct file *file)
{
ide_drive_t *drive = (ide_drive_t *)data;
int len = 0, i = 0;
int err = 0;
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,
};
len = sprintf(page, "\n");
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) {
__le16 *val = (__le16 *)page;
if (!drive) {
seq_putc(m, '\n');
return 0;
}
err = taskfile_lib_get_identify(drive, page);
if (!err) {
char *out = (char *)page + SECTOR_SIZE;
buf = kmalloc(SECTOR_SIZE, GFP_KERNEL);
if (!buf)
return -ENOMEM;
if (taskfile_lib_get_identify(drive, buf) == 0) {
__le16 *val = (__le16 *)buf;
int i;
page = out;
do {
out += sprintf(out, "%04x%c",
le16_to_cpup(val), (++i & 7) ? ' ' : '\n');
val += 1;
} while (i < SECTOR_SIZE / 2);
len = out - page;
for (i = 0; i < SECTOR_SIZE / 2; i++) {
seq_printf(m, "%04x%c", le16_to_cpu(val[i]),
(i % 8) == 7 ? '\n' : ' ');
}
}
PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
} 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 = single_release,
};
/**
* ide_find_setting - find a specific setting
* @st: setting table pointer
......@@ -195,7 +238,6 @@ ide_devset_get(xfer_rate, current_speed);
static int set_xfer_rate (ide_drive_t *drive, int arg)
{
struct ide_cmd cmd;
int err;
if (arg < XFER_PIO_0 || arg > XFER_UDMA_6)
return -EINVAL;
......@@ -206,14 +248,9 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
cmd.tf.nsect = (u8)arg;
cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT;
cmd.valid.in.tf = IDE_VALID_NSECT;
cmd.tf_flags = IDE_TFLAG_SET_XFER;
err = ide_no_data_taskfile(drive, &cmd);
if (!err) {