提交 0cb583fd 编写于 作者: L Linus Torvalds

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()
...@@ -29,9 +29,7 @@ ...@@ -29,9 +29,7 @@
#include <mach/board.h> #include <mach/board.h>
#include <mach/gpio.h> #include <mach/gpio.h>
#include <mach/at91sam9263.h>
#include <mach/at91sam9_smc.h> #include <mach/at91sam9_smc.h>
#include <mach/at91sam9263_matrix.h>
#define DRV_NAME "at91_ide" #define DRV_NAME "at91_ide"
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/seq_file.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/errno.h> #include <linux/errno.h>
...@@ -1146,8 +1147,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) ...@@ -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", ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u",
curspeed, maxspeed); curspeed, maxspeed);
cd->current_speed = (curspeed + (176/2)) / 176; cd->current_speed = DIV_ROUND_CLOSEST(curspeed, 176);
cd->max_speed = (maxspeed + (176/2)) / 176; cd->max_speed = DIV_ROUND_CLOSEST(maxspeed, 176);
} }
#define IDE_CD_CAPABILITIES \ #define IDE_CD_CAPABILITIES \
...@@ -1389,19 +1390,30 @@ static sector_t ide_cdrom_capacity(ide_drive_t *drive) ...@@ -1389,19 +1390,30 @@ static sector_t ide_cdrom_capacity(ide_drive_t *drive)
return capacity * sectors_per_frame; return capacity * sectors_per_frame;
} }
static int proc_idecd_read_capacity(char *page, char **start, off_t off, static int idecd_capacity_proc_show(struct seq_file *m, void *v)
int count, int *eof, void *data)
{ {
ide_drive_t *drive = data; ide_drive_t *drive = m->private;
int len;
len = sprintf(page, "%llu\n", (long long)ide_cdrom_capacity(drive)); seq_printf(m, "%llu\n", (long long)ide_cdrom_capacity(drive));
PROC_IDE_READ_RETURN(page, start, off, count, eof, len); 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[] = { static ide_proc_entry_t idecd_proc[] = {
{ "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL }, { "capacity", S_IFREG|S_IRUGO, &idecd_capacity_proc_fops },
{ NULL, 0, NULL, NULL } {}
}; };
static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive) static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive)
......
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/seq_file.h>
#include "ide-disk.h" #include "ide-disk.h"
...@@ -37,77 +38,117 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) ...@@ -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); return ide_raw_taskfile(drive, &cmd, buf, 1);
} }
static int proc_idedisk_read_cache static int idedisk_cache_proc_show(struct seq_file *m, void *v)
(char *page, char **start, off_t off, int count, int *eof, void *data)
{ {
ide_drive_t *drive = (ide_drive_t *) data; ide_drive_t *drive = (ide_drive_t *) m->private;
char *out = page;
int len;
if (drive->dev_flags & IDE_DFLAG_ID_READ) 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 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 static const struct file_operations idedisk_cache_proc_fops = {
(char *page, char **start, off_t off, int count, int *eof, void *data) .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; ide_drive_t*drive = (ide_drive_t *)m->private;
int len;
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, static const struct file_operations idedisk_capacity_proc_fops = {
int count, int *eof, void *data, u8 sub_cmd) .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; u8 *buf;
int len = 0, i = 0;
buf = kmalloc(SECTOR_SIZE, GFP_KERNEL);
if (!buf)
return -ENOMEM;
(void)smart_enable(drive); (void)smart_enable(drive);
if (get_smart_data(drive, page, sub_cmd) == 0) { if (get_smart_data(drive, buf, sub_cmd) == 0) {
unsigned short *val = (unsigned short *) page; __le16 *val = (__le16 *)buf;
char *out = (char *)val + SECTOR_SIZE; int i;
page = out; for (i = 0; i < SECTOR_SIZE / 2; i++) {
do { seq_printf(m, "%04x%c", le16_to_cpu(val[i]),
out += sprintf(out, "%04x%c", le16_to_cpu(*val), (i % 8) == 7 ? '\n' : ' ');
(++i & 7) ? ' ' : '\n'); }
val += 1;
} while (i < SECTOR_SIZE / 2);
len = out - page;
} }
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 static int idedisk_sv_proc_open(struct inode *inode, struct file *file)
(char *page, char **start, off_t off, int count, int *eof, void *data)
{ {
return proc_idedisk_read_smart(page, start, off, count, eof, data, return single_open(file, idedisk_sv_proc_show, PDE(inode)->data);
ATA_SMART_READ_VALUES);
} }
static int proc_idedisk_read_st static const struct file_operations idedisk_sv_proc_fops = {
(char *page, char **start, off_t off, int count, int *eof, void *data) .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, return __idedisk_proc_show(m, m->private, ATA_SMART_READ_THRESHOLDS);
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[] = { ide_proc_entry_t ide_disk_proc[] = {
{ "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL }, { "cache", S_IFREG|S_IRUGO, &idedisk_cache_proc_fops },
{ "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL }, { "capacity", S_IFREG|S_IRUGO, &idedisk_capacity_proc_fops },
{ "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, { "geometry", S_IFREG|S_IRUGO, &ide_geometry_proc_fops },
{ "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv, NULL }, { "smart_values", S_IFREG|S_IRUSR, &idedisk_sv_proc_fops },
{ "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st, NULL }, { "smart_thresholds", S_IFREG|S_IRUSR, &idedisk_st_proc_fops },
{ NULL, 0, NULL, NULL } {}
}; };
ide_devset_rw_field(bios_cyl, bios_cyl); ide_devset_rw_field(bios_cyl, bios_cyl);
......
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/seq_file.h>
#include "ide-floppy.h" #include "ide-floppy.h"
static int proc_idefloppy_read_capacity(char *page, char **start, off_t off, static int idefloppy_capacity_proc_show(struct seq_file *m, void *v)
int count, int *eof, void *data)
{ {
ide_drive_t*drive = (ide_drive_t *)data; ide_drive_t*drive = (ide_drive_t *)m->private;
int len;
len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive)); seq_printf(m, "%llu\n", (long long)ide_gd_capacity(drive));
PROC_IDE_READ_RETURN(page, start, off, count, eof, len); 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[] = { ide_proc_entry_t ide_floppy_proc[] = {
{ "capacity", S_IFREG|S_IRUGO, proc_idefloppy_read_capacity, NULL }, { "capacity", S_IFREG|S_IRUGO, &idefloppy_capacity_proc_fops },
{ "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, { "geometry", S_IFREG|S_IRUGO, &ide_geometry_proc_fops },
{ NULL, 0, NULL, NULL } {}
}; };
ide_devset_rw_field(bios_cyl, bios_cyl); ide_devset_rw_field(bios_cyl, bios_cyl);
......
...@@ -167,6 +167,8 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -167,6 +167,8 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
err = -EINVAL; err = -EINVAL;
goto abort; goto abort;
} }
cmd.tf_flags |= IDE_TFLAG_SET_XFER;
} }
err = ide_raw_taskfile(drive, &cmd, buf, args[3]); 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) ...@@ -174,12 +176,6 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
args[0] = tf->status; args[0] = tf->status;
args[1] = tf->error; args[1] = tf->error;
args[2] = tf->nsect; args[2] = tf->nsect;
if (!err && xfer_rate) {
/* active-retuning-calls future */
ide_set_xfer_rate(drive, xfer_rate);
ide_driveid_update(drive);
}
abort: abort:
if (copy_to_user((void __user *)arg, &args, 4)) if (copy_to_user((void __user *)arg, &args, 4))
err = -EFAULT; err = -EFAULT;
......
...@@ -102,8 +102,8 @@ EXPORT_SYMBOL(ide_fixstring); ...@@ -102,8 +102,8 @@ EXPORT_SYMBOL(ide_fixstring);
* setting a timer to wake up at half second intervals thereafter, * setting a timer to wake up at half second intervals thereafter,
* until timeout is achieved, before timing out. * until timeout is achieved, before timing out.
*/ */
static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
unsigned long timeout, u8 *rstat) unsigned long timeout, u8 *rstat)
{ {
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops; const struct ide_tp_ops *tp_ops = hwif->tp_ops;
...@@ -292,6 +292,7 @@ static const char *nien_quirk_list[] = { ...@@ -292,6 +292,7 @@ static const char *nien_quirk_list[] = {
"QUANTUM FIREBALLP KX27.3", "QUANTUM FIREBALLP KX27.3",
"QUANTUM FIREBALLP LM20.4", "QUANTUM FIREBALLP LM20.4",
"QUANTUM FIREBALLP LM20.5", "QUANTUM FIREBALLP LM20.5",
"FUJITSU MHZ2160BH G2",
NULL NULL
}; };
...@@ -316,7 +317,7 @@ int ide_driveid_update(ide_drive_t *drive) ...@@ -316,7 +317,7 @@ int ide_driveid_update(ide_drive_t *drive)
return 0; return 0;
SELECT_MASK(drive, 1); 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); SELECT_MASK(drive, 0);
if (rc) if (rc)
...@@ -363,14 +364,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) ...@@ -363,14 +364,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
* this point (lost interrupt). * 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); udelay(1);
tp_ops->dev_select(drive); tp_ops->dev_select(drive);
SELECT_MASK(drive, 1); SELECT_MASK(drive, 1);
...@@ -394,8 +387,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) ...@@ -394,8 +387,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
SELECT_MASK(drive, 0); SELECT_MASK(drive, 0);
enable_irq(hwif->irq);
if (error) { if (error) {
(void) ide_dump_status(drive, "set_drive_speed_status", stat); (void) ide_dump_status(drive, "set_drive_speed_status", stat);
return error; return error;
......
...@@ -238,6 +238,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id) ...@@ -238,6 +238,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
* @drive: drive to identify * @drive: drive to identify
* @cmd: command to use * @cmd: command to use
* @id: buffer for IDENTIFY data * @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. * 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) ...@@ -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) * 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; ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports; 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) ...@@ -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); tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
/* take a deep breath */ /* take a deep breath */
msleep(50); if (irq_ctx)
mdelay(50);
else
msleep(50);
if (io_ports->ctl_addr && if (io_ports->ctl_addr &&
(hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) { (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) ...@@ -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; 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 */ /* wait for IRQ and ATA_DRQ */
msleep(50); if (irq_ctx) {
s = tp_ops->read_status(hwif); 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)) { if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
/* drive returned ID */ /* drive returned ID */
...@@ -406,10 +417,10 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -406,10 +417,10 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) || if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
present || cmd == ATA_CMD_ID_ATAPI) { 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) if (rc)
/* failed: try again */ /* 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); stat = tp_ops->read_status(hwif);
...@@ -424,7 +435,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -424,7 +435,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
msleep(50); msleep(50);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
(void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0); (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 */ /* ensure drive IRQ is clear */
......
...@@ -30,11 +30,9 @@ ...@@ -30,11 +30,9 @@
static struct proc_dir_entry *proc_ide_root; static struct proc_dir_entry *proc_ide_root;
static int proc_ide_read_imodel static int ide_imodel_proc_show(struct seq_file *m, void *v)
(char *page, char **start, off_t off, int count, int *eof, void *data)
{ {
ide_hwif_t *hwif = (ide_hwif_t *) data; ide_hwif_t *hwif = (ide_hwif_t *) m->private;
int len;
const char *name; const char *name;
switch (hwif->chipset) { switch (hwif->chipset) {
...@@ -53,63 +51,108 @@ static int proc_ide_read_imodel ...@@ -53,63 +51,108 @@ static int proc_ide_read_imodel
case ide_acorn: name = "acorn"; break; case ide_acorn: name = "acorn"; break;
default: name = "(unknown)"; break; default: name = "(unknown)"; break;
} }
len = sprintf(page, "%s\n", name); seq_printf(m, "%s\n", name);
PROC_IDE_READ_RETURN(page, start, off, count, eof, len); return 0;
} }
static int proc_ide_read_mate static int ide_imodel_proc_open(struct inode *inode, struct file *file)
(char *page, char **start, off_t off, int count, int *eof, void *data)
{ {
ide_hwif_t *hwif = (ide_hwif_t *) data; return single_open(file, ide_imodel_proc_show, PDE(inode)->data);
int len; }
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) if (hwif && hwif->mate)
len = sprintf(page, "%s\n", hwif->mate->name); seq_printf(m, "%s\n", hwif->mate->name);
else else
len = sprintf(page, "(none)\n"); seq_printf(m, "(none)\n");
PROC_IDE_READ_RETURN(page, start, off, count, eof, len); 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 static const struct file_operations ide_mate_proc_fops = {
(char *page, char **start, off_t off, int count, int *eof, void *data) .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; ide_hwif_t *hwif = (ide_hwif_t *) m->private;
int len;
page[0] = hwif->channel ? '1' : '0'; seq_printf(m, "%c\n", hwif->channel ? '1' : '0');
page[1] = '\n'; return 0;
len = 2;
PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
} }
static int proc_ide_read_identify static int ide_channel_proc_open(struct inode *inode, struct file *file)
(char *page, char **start, off_t off, int count, int *eof, void *data)
{ {
ide_drive_t *drive = (ide_drive_t *)data; return single_open(file, ide_channel_proc_show, PDE(inode)->data);
int len = 0, i = 0; }
int err = 0;
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) { if (!drive) {
__le16 *val = (__le16 *)page; seq_putc(m, '\n');
return 0;
}
err = taskfile_lib_get_identify(drive, page); buf = kmalloc(SECTOR_SIZE, GFP_KERNEL);
if (!err) { if (!buf)
char *out = (char *)page + SECTOR_SIZE; return -ENOMEM;
if (taskfile_lib_get_identify(drive, buf) == 0) {
__le16 *val = (__le16 *)buf;
int i;
page = out; for (i = 0; i < SECTOR_SIZE / 2; i++) {
do { seq_printf(m, "%04x%c", le16_to_cpu(val[i]),
out += sprintf(out, "%04x%c", (i % 8) == 7 ? '\n' : ' ');
le16_to_cpup(val), (++i & 7) ? ' ' : '\n');
val += 1;
} while (i < SECTOR_SIZE / 2);
len = out - page;
} }
} } else
PROC_IDE_READ_RETURN(page, start, off, count, eof, len); 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 * ide_find_setting - find a specific setting
* @st: setting table pointer * @st: setting table pointer
...@@ -195,7 +238,6 @@ ide_devset_get(xfer_rate, current_speed); ...@@ -195,7 +238,6 @@ ide_devset_get(xfer_rate, current_speed);
static int set_xfer_rate (ide_drive_t *drive, int arg) static int set_xfer_rate (ide_drive_t *drive, int arg)
{ {
struct ide_cmd cmd; struct ide_cmd cmd;
int err;
if (arg < XFER_PIO_0 || arg > XFER_UDMA_6) if (arg < XFER_PIO_0 || arg > XFER_UDMA_6)
return -EINVAL; return -EINVAL;
...@@ -206,14 +248,9 @@ static int set_xfer_rate (ide_drive_t *drive, int arg) ...@@ -206,14 +248,9 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
cmd.tf.nsect = (u8)arg; cmd.tf.nsect = (u8)arg;
cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT; cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT;
cmd.valid.in.tf = IDE_VALID_NSECT; cmd.valid.in.tf = IDE_VALID_NSECT;
cmd.tf_flags = IDE_TFLAG_SET_XFER;
err = ide_no_data_taskfile(drive, &cmd); return ide_no_data_taskfile(drive, &cmd);
if (!err) {
ide_set_xfer_rate(drive, (u8) arg);
ide_driveid_update(drive);
}
return err;
} }
ide_devset_rw(current_speed, xfer_rate); ide_devset_rw(current_speed, xfer_rate);
...@@ -246,22 +283,20 @@ static void proc_ide_settings_warn(void) ...@@ -246,22 +283,20 @@ static void proc_ide_settings_warn(void)
warned = 1; warned = 1;
} }
static int proc_ide_read_settings static int ide_settings_proc_show(struct seq_file *m, void *v)
(char *page, char **start, off_t off, int count, int *eof, void *data)
{ {
const struct ide_proc_devset *setting, *g, *d; const struct ide_proc_devset *setting, *g, *d;
const struct ide_devset *ds; const struct ide_devset *ds;
ide_drive_t *drive = (ide_drive_t *) data; ide_drive_t *drive = (ide_drive_t *) m->private;
char *out = page; int rc, mul_factor, div_factor;
int len, rc, mul_factor, div_factor;
proc_ide_settings_warn(); proc_ide_settings_warn();
mutex_lock(&ide_setting_mtx); mutex_lock(&ide_setting_mtx);
g = ide_generic_settings; g = ide_generic_settings;
d = drive->settings; d = drive->settings;
out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n"); seq_printf(m, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n"); seq_printf(m, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
while (g->name || (d && d->name)) { while (g->name || (d && d->name)) {
/* read settings in the alphabetical order */ /* read settings in the alphabetical order */
if (g->name && d && d->name) { if (g->name && d && d->name) {
...@@ -275,31 +310,35 @@ static int proc_ide_read_settings ...@@ -275,31 +310,35 @@ static int proc_ide_read_settings
setting = g++; setting = g++;
mul_factor = setting->mulf ? setting->mulf(drive) : 1; mul_factor = setting->mulf ? setting->mulf(drive) : 1;
div_factor = setting->divf ? setting->divf(drive) : 1; div_factor = setting->divf ? setting->divf(drive) : 1;
out += sprintf(out, "%-24s", setting->name); seq_printf(m, "%-24s", setting->name);
rc = ide_read_setting(drive, setting); rc = ide_read_setting(drive, setting);
if (rc >= 0) if (rc >= 0)
out += sprintf(out, "%-16d", rc * mul_factor / div_factor); seq_printf(m, "%-16d", rc * mul_factor / div_factor);
else else
out += sprintf(out, "%-16s", "write-only"); seq_printf(m, "%-16s", "write-only");
out += sprintf(out, "%-16d%-16d", (setting->min * mul_factor + div_factor - 1) / div_factor, setting->max * mul_factor / div_factor); seq_printf(m, "%-16d%-16d", (setting->min * mul_factor + div_factor - 1) / div_factor, setting->max * mul_factor / div_factor);
ds = setting->setting; ds = setting->setting;
if (ds->get) if (ds->get)
out += sprintf(out, "r"); seq_printf(m, "r");
if (ds->set) if (ds->set)
out += sprintf(out, "w"); seq_printf(m, "w");
out += sprintf(out, "\n"); seq_printf(m, "\n");
} }
len = out - page;
mutex_unlock(&ide_setting_mtx); mutex_unlock(&ide_setting_mtx);
PROC_IDE_READ_RETURN(page, start, off, count, eof, len); return 0;
}
static int ide_settings_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, ide_settings_proc_show, PDE(inode)->data);
} }
#define MAX_LEN 30 #define MAX_LEN 30
static int proc_ide_write_settings(struct file *file, const char __user *buffer, static ssize_t ide_settings_proc_write(struct file *file, const char __user *buffer,
unsigned long count, void *data) size_t count, loff_t *pos)
{ {
ide_drive_t *drive = (ide_drive_t *) data; ide_drive_t *drive = (ide_drive_t *) PDE(file->f_path.dentry->d_inode)->data;
char name[MAX_LEN + 1]; char name[MAX_LEN + 1];
int for_real = 0, mul_factor, div_factor; int for_real = 0, mul_factor, div_factor;
unsigned long n; unsigned long n;
...@@ -394,63 +433,104 @@ static int proc_ide_write_settings(struct file *file, const char __user *buffer, ...@@ -394,63 +433,104 @@ static int proc_ide_write_settings(struct file *file, const char __user *buffer,
return count; return count;
parse_error: parse_error:
free_page((unsigned long)buf); free_page((unsigned long)buf);
printk("proc_ide_write_settings(): parse error\n"); printk("%s(): parse error\n", __func__);
return -EINVAL; return -EINVAL;
} }
int proc_ide_read_capacity static const struct file_operations ide_settings_proc_fops = {
(char *page, char **start, off_t off, int count, int *eof, void *data) .owner = THIS_MODULE,
.open = ide_settings_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.write = ide_settings_proc_write,
};
static int ide_capacity_proc_show(struct seq_file *m, void *v)
{
seq_printf(m, "%llu\n", (long long)0x7fffffff);
return 0;
}
static int ide_capacity_proc_open(struct inode *inode, struct file *file)
{ {
int len = sprintf(page, "%llu\n", (long long)0x7fffffff); return single_open(file, ide_capacity_proc_show, NULL);
PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
} }
EXPORT_SYMBOL_GPL(proc_ide_read_capacity); const struct file_operations ide_capacity_proc_fops = {
.owner = THIS_MODULE,
.open = ide_capacity_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
EXPORT_SYMBOL_GPL(ide_capacity_proc_fops);
int proc_ide_read_geometry static int ide_geometry_proc_show(struct seq_file *m, void *v)
(char *page, char **start, off_t off, int count, int *eof, void *data)
{ {
ide_drive_t *drive = (ide_drive_t *) data; ide_drive_t *drive = (ide_drive_t *) m->private;
char *out = page;
int len;
out += sprintf(out, "physical %d/%d/%d\n", seq_printf(m, "physical %d/%d/%d\n",
drive->cyl, drive->head, drive->sect); drive->cyl, drive->head, drive->sect);
out += sprintf(out, "logical %d/%d/%d\n", seq_printf(m, "logical %d/%d/%d\n",
drive->bios_cyl, drive->bios_head, drive->bios_sect); drive->bios_cyl, drive->bios_head, drive->bios_sect);
return 0;
}
len = out - page; static int ide_geometry_proc_open(struct inode *inode, struct file *file)
PROC_IDE_READ_RETURN(page, start, off, count, eof, len); {
return single_open(file, ide_geometry_proc_show, PDE(inode)->data);
} }
EXPORT_SYMBOL(proc_ide_read_geometry); const struct file_operations ide_geometry_proc_fops = {
.owner = THIS_MODULE,
.open = ide_geometry_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
EXPORT_SYMBOL(ide_geometry_proc_fops);
static int proc_ide_read_dmodel static int ide_dmodel_proc_show(struct seq_file *seq, void *v)
(char *page, char **start, off_t off, int count, int *eof, void *data)
{ {
ide_drive_t *drive = (ide_drive_t *) data; ide_drive_t *drive = (ide_drive_t *) seq->private;
char *m = (char *)&drive->id[ATA_ID_PROD]; char *m = (char *)&drive->id[ATA_ID_PROD];
int len;
len = sprintf(page, "%.40s\n", m[0] ? m : "(none)"); seq_printf(seq, "%.40s\n", m[0] ? m : "(none)");
PROC_IDE_READ_RETURN(page, start, off, count, eof, len); return 0;
}
static int ide_dmodel_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, ide_dmodel_proc_show, PDE(inode)->data);
} }
static int proc_ide_read_driver static const struct file_operations ide_dmodel_proc_fops = {
(char *page, char **start, off_t off, int count, int *eof, void *data) .owner = THIS_MODULE,
.open = ide_dmodel_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int ide_driver_proc_show(struct seq_file *m, void *v)
{ {
ide_drive_t *drive = (ide_drive_t *)data; ide_drive_t *drive = (ide_drive_t *)m->private;
struct device *dev = &drive->gendev; struct device *dev = &drive->gendev;
struct ide_driver *ide_drv; struct ide_driver *ide_drv;
int len;
if (dev->driver) { if (dev->driver) {
ide_drv = to_ide_driver(dev->driver); ide_drv = to_ide_driver(dev->driver);
len = sprintf(page, "%s version %s\n", seq_printf(m, "%s version %s\n",
dev->driver->name, ide_drv->version); dev->driver->name, ide_drv->version);
} else } else
len = sprintf(page, "ide-default version 0.9.newide\n"); seq_printf(m, "ide-default version 0.9.newide\n");
PROC_IDE_READ_RETURN(page, start, off, count, eof, len); return 0;
}
static int ide_driver_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, ide_driver_proc_show, PDE(inode)->data);
} }
static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
...@@ -480,10 +560,10 @@ static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) ...@@ -480,10 +560,10 @@ static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
return ret; return ret;
} }
static int proc_ide_write_driver static ssize_t ide_driver_proc_write(struct file *file, const char __user *buffer,
(struct file *file, const char __user *buffer, unsigned long count, void *data) size_t count, loff_t *pos)
{ {
ide_drive_t *drive = (ide_drive_t *) data; ide_drive_t *drive = (ide_drive_t *) PDE(file->f_path.dentry->d_inode)->data;
char name[32]; char name[32];
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
...@@ -498,12 +578,19 @@ static int proc_ide_write_driver ...@@ -498,12 +578,19 @@ static int proc_ide_write_driver
return count; return count;
} }
static int proc_ide_read_media static const struct file_operations ide_driver_proc_fops = {
(char *page, char **start, off_t off, int count, int *eof, void *data) .owner = THIS_MODULE,
.open = ide_driver_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.write = ide_driver_proc_write,
};
static int ide_media_proc_show(struct seq_file *m, void *v)
{ {
ide_drive_t *drive = (ide_drive_t *) data; ide_drive_t *drive = (ide_drive_t *) m->private;
const char *media; const char *media;
int len;
switch (drive->media) { switch (drive->media) {
case ide_disk: media = "disk\n"; break; case ide_disk: media = "disk\n"; break;
...@@ -513,20 +600,30 @@ static int proc_ide_read_media ...@@ -513,20 +600,30 @@ static int proc_ide_read_media
case ide_optical: media = "optical\n"; break; case ide_optical: media = "optical\n"; break;
default: media = "UNKNOWN\n"; break; default: media = "UNKNOWN\n"; break;
} }
strcpy(page, media); seq_puts(m, media);
len = strlen(media); return 0;
PROC_IDE_READ_RETURN(page, start, off, count, eof, len); }
static int ide_media_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, ide_media_proc_show, PDE(inode)->data);
} }
static const struct file_operations ide_media_proc_fops = {
.owner = THIS_MODULE,
.open = ide_media_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static ide_proc_entry_t generic_drive_entries[] = { static ide_proc_entry_t generic_drive_entries[] = {
{ "driver", S_IFREG|S_IRUGO, proc_ide_read_driver, { "driver", S_IFREG|S_IRUGO, &ide_driver_proc_fops },
proc_ide_write_driver }, { "identify", S_IFREG|S_IRUSR, &ide_identify_proc_fops},
{ "identify", S_IFREG|S_IRUSR, proc_ide_read_identify, NULL }, { "media", S_IFREG|S_IRUGO, &ide_media_proc_fops },
{ "media", S_IFREG|S_IRUGO, proc_ide_read_media, NULL }, { "model", S_IFREG|S_IRUGO, &ide_dmodel_proc_fops },
{ "model", S_IFREG|S_IRUGO, proc_ide_read_dmodel, NULL }, { "settings", S_IFREG|S_IRUSR|S_IWUSR, &ide_settings_proc_fops},
{ "settings", S_IFREG|S_IRUSR|S_IWUSR, proc_ide_read_settings, {}
proc_ide_write_settings },
{ NULL, 0, NULL, NULL }
}; };
static void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data) static void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data)
...@@ -536,11 +633,8 @@ static void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p ...@@ -536,11 +633,8 @@ static void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p
if (!dir || !p) if (!dir || !p)
return; return;
while (p->name != NULL) { while (p->name != NULL) {
ent = create_proc_entry(p->name, p->mode, dir); ent = proc_create_data(p->name, p->mode, dir, p->proc_fops, data);
if (!ent) return; if (!ent) return;
ent->data = data;
ent->read_proc = p->read_proc;
ent->write_proc = p->write_proc;
p++; p++;
} }
} }
...@@ -623,10 +717,10 @@ void ide_proc_unregister_device(ide_drive_t *drive) ...@@ -623,10 +717,10 @@ void ide_proc_unregister_device(ide_drive_t *drive)
} }
static ide_proc_entry_t hwif_entries[] = { static ide_proc_entry_t hwif_entries[] = {
{ "channel", S_IFREG|S_IRUGO, proc_ide_read_channel, NULL }, { "channel", S_IFREG|S_IRUGO, &ide_channel_proc_fops },
{ "mate", S_IFREG|S_IRUGO, proc_ide_read_mate, NULL }, { "mate", S_IFREG|S_IRUGO, &ide_mate_proc_fops },
{ "model", S_IFREG|S_IRUGO, proc_ide_read_imodel, NULL }, { "model", S_IFREG|S_IRUGO, &ide_imodel_proc_fops },
{ NULL, 0, NULL, NULL } {}
}; };
void ide_proc_register_port(ide_hwif_t *hwif) void ide_proc_register_port(ide_hwif_t *hwif)
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/major.h> #include <linux/major.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/genhd.h> #include <linux/genhd.h>
#include <linux/seq_file.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/ide.h> #include <linux/ide.h>
...@@ -47,28 +48,13 @@ ...@@ -47,28 +48,13 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <linux/mtio.h> #include <linux/mtio.h>
enum {
/* output errors only */
DBG_ERR = (1 << 0),
/* output all sense key/asc */
DBG_SENSE = (1 << 1),
/* info regarding all chrdev-related procedures */
DBG_CHRDEV = (1 << 2),
/* all remaining procedures */
DBG_PROCS = (1 << 3),
};
/* define to see debug info */ /* define to see debug info */
#define IDETAPE_DEBUG_LOG 0 #undef IDETAPE_DEBUG_LOG
#if IDETAPE_DEBUG_LOG #ifdef IDETAPE_DEBUG_LOG
#define debug_log(lvl, fmt, args...) \ #define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args)
{ \
if (tape->debug_mask & lvl) \
printk(KERN_INFO "ide-tape: " fmt, ## args); \
}
#else #else
#define debug_log(lvl, fmt, args...) do {} while (0) #define ide_debug_log(lvl, fmt, args...) do {} while (0)
#endif #endif
/**************************** Tunable parameters *****************************/ /**************************** Tunable parameters *****************************/
...@@ -170,7 +156,8 @@ typedef struct ide_tape_obj { ...@@ -170,7 +156,8 @@ typedef struct ide_tape_obj {
* other device. Note that at most we will have only one DSC (usually * other device. Note that at most we will have only one DSC (usually
* data transfer) request in the device request queue. * data transfer) request in the device request queue.
*/ */
struct request *postponed_rq; bool postponed_rq;
/* The time in which we started polling for DSC */ /* The time in which we started polling for DSC */
unsigned long dsc_polling_start; unsigned long dsc_polling_start;
/* Timer used to poll for dsc */ /* Timer used to poll for dsc */
...@@ -230,8 +217,6 @@ typedef struct ide_tape_obj { ...@@ -230,8 +217,6 @@ typedef struct ide_tape_obj {
char drv_write_prot; char drv_write_prot;
/* the tape is write protected (hardware or opened as read-only) */ /* the tape is write protected (hardware or opened as read-only) */
char write_prot; char write_prot;
u32 debug_mask;
} idetape_tape_t; } idetape_tape_t;
static DEFINE_MUTEX(idetape_ref_mutex); static DEFINE_MUTEX(idetape_ref_mutex);
...@@ -290,8 +275,9 @@ static void idetape_analyze_error(ide_drive_t *drive) ...@@ -290,8 +275,9 @@ static void idetape_analyze_error(ide_drive_t *drive)
tape->asc = sense[12]; tape->asc = sense[12];
tape->ascq = sense[13]; tape->ascq = sense[13];
debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n", ide_debug_log(IDE_DBG_FUNC,
pc->c[0], tape->sense_key, tape->asc, tape->ascq); "cmd: 0x%x, sense key = %x, asc = %x, ascq = %x",
rq->cmd[0], tape->sense_key, tape->asc, tape->ascq);
/* correct remaining bytes to transfer */ /* correct remaining bytes to transfer */
if (pc->flags & PC_FLAG_DMA_ERROR) if (pc->flags & PC_FLAG_DMA_ERROR)
...@@ -344,7 +330,8 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) ...@@ -344,7 +330,8 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
int uptodate = pc->error ? 0 : 1; int uptodate = pc->error ? 0 : 1;
int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL; int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
debug_log(DBG_PROCS, "Enter %s\n", __func__); ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, dsc: %d, err: %d", rq->cmd[0],
dsc, err);
if (dsc) if (dsc)
ide_tape_handle_dsc(drive); ide_tape_handle_dsc(drive);
...@@ -387,13 +374,14 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) ...@@ -387,13 +374,14 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
* Postpone the current request so that ide.c will be able to service requests * Postpone the current request so that ide.c will be able to service requests
* from another device on the same port while we are polling for DSC. * from another device on the same port while we are polling for DSC.
*/ */
static void idetape_postpone_request(ide_drive_t *drive) static void ide_tape_stall_queue(ide_drive_t *drive)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
debug_log(DBG_PROCS, "Enter %s\n", __func__); ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, dsc_poll_freq: %lu",
drive->hwif->rq->cmd[0], tape->dsc_poll_freq);
tape->postponed_rq = drive->hwif->rq; tape->postponed_rq = true;
ide_stall_queue(drive, tape->dsc_poll_freq); ide_stall_queue(drive, tape->dsc_poll_freq);
} }
...@@ -407,7 +395,7 @@ static void ide_tape_handle_dsc(ide_drive_t *drive) ...@@ -407,7 +395,7 @@ static void ide_tape_handle_dsc(ide_drive_t *drive)
tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST; tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST;
tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT; tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT;
/* Allow ide.c to handle other requests */ /* Allow ide.c to handle other requests */
idetape_postpone_request(drive); ide_tape_stall_queue(drive);
} }
/* /*
...@@ -488,7 +476,8 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, ...@@ -488,7 +476,8 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
ide_complete_rq(drive, -EIO, blk_rq_bytes(rq)); ide_complete_rq(drive, -EIO, blk_rq_bytes(rq));
return ide_stopped; return ide_stopped;
} }
debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); ide_debug_log(IDE_DBG_SENSE, "retry #%d, cmd: 0x%02x", pc->retries,
pc->c[0]);
pc->retries++; pc->retries++;
...@@ -579,12 +568,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, ...@@ -579,12 +568,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc *pc = NULL; struct ide_atapi_pc *pc = NULL;
struct request *postponed_rq = tape->postponed_rq;
struct ide_cmd cmd; struct ide_cmd cmd;
u8 stat; u8 stat;
debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %u\n" ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, sector: %llu, nr_sectors: %u",
(unsigned long long)blk_rq_pos(rq), blk_rq_sectors(rq)); rq->cmd[0], (unsigned long long)blk_rq_pos(rq),
blk_rq_sectors(rq));
BUG_ON(!(blk_special_request(rq) || blk_sense_request(rq))); BUG_ON(!(blk_special_request(rq) || blk_sense_request(rq)));
...@@ -594,18 +583,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, ...@@ -594,18 +583,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
goto out; goto out;
} }
if (postponed_rq != NULL)
if (rq != postponed_rq) {
printk(KERN_ERR "ide-tape: ide-tape.c bug - "
"Two DSC requests were queued\n");
drive->failed_pc = NULL;
rq->errors = 0;
ide_complete_rq(drive, 0, blk_rq_bytes(rq));
return ide_stopped;
}
tape->postponed_rq = NULL;
/* /*
* If the tape is still busy, postpone our request and service * If the tape is still busy, postpone our request and service
* the other device meanwhile. * the other device meanwhile.
...@@ -623,7 +600,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, ...@@ -623,7 +600,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
if (!(drive->atapi_flags & IDE_AFLAG_IGNORE_DSC) && if (!(drive->atapi_flags & IDE_AFLAG_IGNORE_DSC) &&
!(stat & ATA_DSC)) { !(stat & ATA_DSC)) {
if (postponed_rq == NULL) { if (!tape->postponed_rq) {
tape->dsc_polling_start = jiffies; tape->dsc_polling_start = jiffies;
tape->dsc_poll_freq = tape->best_dsc_rw_freq; tape->dsc_poll_freq = tape->best_dsc_rw_freq;
tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT; tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT;
...@@ -640,10 +617,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, ...@@ -640,10 +617,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
tape->dsc_polling_start + tape->dsc_polling_start +
IDETAPE_DSC_MA_THRESHOLD)) IDETAPE_DSC_MA_THRESHOLD))
tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW; tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW;
idetape_postpone_request(drive); ide_tape_stall_queue(drive);
return ide_stopped; return ide_stopped;
} else } else {
drive->atapi_flags &= ~IDE_AFLAG_IGNORE_DSC; drive->atapi_flags &= ~IDE_AFLAG_IGNORE_DSC;
tape->postponed_rq = false;
}
if (rq->cmd[13] & REQ_IDETAPE_READ) { if (rq->cmd[13] & REQ_IDETAPE_READ) {
pc = &tape->queued_pc; pc = &tape->queued_pc;
...@@ -745,7 +724,7 @@ static int ide_tape_read_position(ide_drive_t *drive) ...@@ -745,7 +724,7 @@ static int ide_tape_read_position(ide_drive_t *drive)
struct ide_atapi_pc pc; struct ide_atapi_pc pc;
u8 buf[20]; u8 buf[20];
debug_log(DBG_PROCS, "Enter %s\n", __func__); ide_debug_log(IDE_DBG_FUNC, "enter");
/* prep cmd */ /* prep cmd */
ide_init_pc(&pc); ide_init_pc(&pc);
...@@ -756,9 +735,9 @@ static int ide_tape_read_position(ide_drive_t *drive) ...@@ -756,9 +735,9 @@ static int ide_tape_read_position(ide_drive_t *drive)
return -1; return -1;
if (!pc.error) { if (!pc.error) {
debug_log(DBG_SENSE, "BOP - %s\n", ide_debug_log(IDE_DBG_FUNC, "BOP - %s",
(buf[0] & 0x80) ? "Yes" : "No"); (buf[0] & 0x80) ? "Yes" : "No");
debug_log(DBG_SENSE, "EOP - %s\n", ide_debug_log(IDE_DBG_FUNC, "EOP - %s",
(buf[0] & 0x40) ? "Yes" : "No"); (buf[0] & 0x40) ? "Yes" : "No");
if (buf[0] & 0x4) { if (buf[0] & 0x4) {
...@@ -768,8 +747,8 @@ static int ide_tape_read_position(ide_drive_t *drive) ...@@ -768,8 +747,8 @@ static int ide_tape_read_position(ide_drive_t *drive)
&drive->atapi_flags); &drive->atapi_flags);
return -1; return -1;
} else { } else {
debug_log(DBG_SENSE, "Block Location - %u\n", ide_debug_log(IDE_DBG_FUNC, "Block Location: %u",
be32_to_cpup((__be32 *)&buf[4])); be32_to_cpup((__be32 *)&buf[4]));
tape->partition = buf[1]; tape->partition = buf[1];
tape->first_frame = be32_to_cpup((__be32 *)&buf[4]); tape->first_frame = be32_to_cpup((__be32 *)&buf[4]);
...@@ -866,7 +845,8 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size) ...@@ -866,7 +845,8 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size)
struct request *rq; struct request *rq;
int ret; int ret;
debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, size: %d", cmd, size);
BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE); BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE);
BUG_ON(size < 0 || size % tape->blk_size); BUG_ON(size < 0 || size % tape->blk_size);
...@@ -1029,7 +1009,7 @@ static int idetape_rewind_tape(ide_drive_t *drive) ...@@ -1029,7 +1009,7 @@ static int idetape_rewind_tape(ide_drive_t *drive)
struct ide_atapi_pc pc; struct ide_atapi_pc pc;
int ret; int ret;
debug_log(DBG_SENSE, "Enter %s\n", __func__); ide_debug_log(IDE_DBG_FUNC, "enter");
idetape_create_rewind_cmd(drive, &pc); idetape_create_rewind_cmd(drive, &pc);
ret = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); ret = ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
...@@ -1055,7 +1035,7 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, ...@@ -1055,7 +1035,7 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,
int nr_stages; int nr_stages;
} config; } config;
debug_log(DBG_PROCS, "Enter %s\n", __func__); ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%04x", cmd);
switch (cmd) { switch (cmd) {
case 0x0340: case 0x0340:
...@@ -1085,6 +1065,9 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, ...@@ -1085,6 +1065,9 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
int retval, count = 0; int retval, count = 0;
int sprev = !!(tape->caps[4] & 0x20); int sprev = !!(tape->caps[4] & 0x20);
ide_debug_log(IDE_DBG_FUNC, "mt_op: %d, mt_count: %d", mt_op, mt_count);
if (mt_count == 0) if (mt_count == 0)
return 0; return 0;
if (MTBSF == mt_op || MTBSFM == mt_op) { if (MTBSF == mt_op || MTBSFM == mt_op) {
...@@ -1148,7 +1131,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, ...@@ -1148,7 +1131,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
ssize_t ret = 0; ssize_t ret = 0;
int rc; int rc;
debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); ide_debug_log(IDE_DBG_FUNC, "count %Zd", count);
if (tape->chrdev_dir != IDETAPE_DIR_READ) { if (tape->chrdev_dir != IDETAPE_DIR_READ) {
if (test_bit(ilog2(IDE_AFLAG_DETECT_BS), &drive->atapi_flags)) if (test_bit(ilog2(IDE_AFLAG_DETECT_BS), &drive->atapi_flags))
...@@ -1187,8 +1170,6 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, ...@@ -1187,8 +1170,6 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
} }
if (!done && test_bit(ilog2(IDE_AFLAG_FILEMARK), &drive->atapi_flags)) { if (!done && test_bit(ilog2(IDE_AFLAG_FILEMARK), &drive->atapi_flags)) {
debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name);
idetape_space_over_filemarks(drive, MTFSF, 1); idetape_space_over_filemarks(drive, MTFSF, 1);
return 0; return 0;
} }
...@@ -1209,7 +1190,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, ...@@ -1209,7 +1190,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
if (tape->write_prot) if (tape->write_prot)
return -EACCES; return -EACCES;
debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); ide_debug_log(IDE_DBG_FUNC, "count %Zd", count);
/* Initialize write operation */ /* Initialize write operation */
rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE); rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE);
...@@ -1273,8 +1254,8 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) ...@@ -1273,8 +1254,8 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
struct ide_atapi_pc pc; struct ide_atapi_pc pc;
int i, retval; int i, retval;
debug_log(DBG_ERR, "Handling MTIOCTOP ioctl: mt_op=%d, mt_count=%d\n", ide_debug_log(IDE_DBG_FUNC, "MTIOCTOP ioctl: mt_op: %d, mt_count: %d",
mt_op, mt_count); mt_op, mt_count);
switch (mt_op) { switch (mt_op) {
case MTFSF: case MTFSF:
...@@ -1393,7 +1374,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, ...@@ -1393,7 +1374,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
int block_offset = 0, position = tape->first_frame; int block_offset = 0, position = tape->first_frame;
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
debug_log(DBG_CHRDEV, "Enter %s, cmd=%u\n", __func__, cmd); ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x", cmd);
if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
ide_tape_flush_merge_buffer(drive); ide_tape_flush_merge_buffer(drive);
...@@ -1461,6 +1442,9 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive) ...@@ -1461,6 +1442,9 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
(buf[4 + 6] << 8) + (buf[4 + 6] << 8) +
buf[4 + 7]; buf[4 + 7];
tape->drv_write_prot = (buf[2] & 0x80) >> 7; tape->drv_write_prot = (buf[2] & 0x80) >> 7;
ide_debug_log(IDE_DBG_FUNC, "blk_size: %d, write_prot: %d",
tape->blk_size, tape->drv_write_prot);
} }
static int idetape_chrdev_open(struct inode *inode, struct file *filp) static int idetape_chrdev_open(struct inode *inode, struct file *filp)
...@@ -1480,7 +1464,10 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) ...@@ -1480,7 +1464,10 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
return -ENXIO; return -ENXIO;
} }
debug_log(DBG_CHRDEV, "Enter %s\n", __func__); drive = tape->drive;
filp->private_data = tape;
ide_debug_log(IDE_DBG_FUNC, "enter");
/* /*
* We really want to do nonseekable_open(inode, filp); here, but some * We really want to do nonseekable_open(inode, filp); here, but some
...@@ -1489,9 +1476,6 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) ...@@ -1489,9 +1476,6 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
*/ */
filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
drive = tape->drive;
filp->private_data = tape;
if (test_and_set_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags)) { if (test_and_set_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags)) {
retval = -EBUSY; retval = -EBUSY;
...@@ -1570,7 +1554,7 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp) ...@@ -1570,7 +1554,7 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
lock_kernel(); lock_kernel();
tape = drive->driver_data; tape = drive->driver_data;
debug_log(DBG_CHRDEV, "Enter %s\n", __func__); ide_debug_log(IDE_DBG_FUNC, "enter");
if (tape->chrdev_dir == IDETAPE_DIR_WRITE) if (tape->chrdev_dir == IDETAPE_DIR_WRITE)
idetape_write_release(drive, minor); idetape_write_release(drive, minor);
...@@ -1707,7 +1691,6 @@ static int divf_buffer_size(ide_drive_t *drive) { return 1024; } ...@@ -1707,7 +1691,6 @@ static int divf_buffer_size(ide_drive_t *drive) { return 1024; }
ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP); ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP);
ide_tape_devset_rw_field(debug_mask, debug_mask);
ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq); ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq);
ide_tape_devset_r_field(avg_speed, avg_speed); ide_tape_devset_r_field(avg_speed, avg_speed);
...@@ -1719,7 +1702,6 @@ static const struct ide_proc_devset idetape_settings[] = { ...@@ -1719,7 +1702,6 @@ static const struct ide_proc_devset idetape_settings[] = {
__IDE_PROC_DEVSET(avg_speed, 0, 0xffff, NULL, NULL), __IDE_PROC_DEVSET(avg_speed, 0, 0xffff, NULL, NULL),
__IDE_PROC_DEVSET(buffer, 0, 0xffff, NULL, divf_buffer), __IDE_PROC_DEVSET(buffer, 0, 0xffff, NULL, divf_buffer),
__IDE_PROC_DEVSET(buffer_size, 0, 0xffff, NULL, divf_buffer_size), __IDE_PROC_DEVSET(buffer_size, 0, 0xffff, NULL, divf_buffer_size),
__IDE_PROC_DEVSET(debug_mask, 0, 0xffff, NULL, NULL),
__IDE_PROC_DEVSET(dsc_overlap, 0, 1, NULL, NULL), __IDE_PROC_DEVSET(dsc_overlap, 0, 1, NULL, NULL),
__IDE_PROC_DEVSET(speed, 0, 0xffff, NULL, NULL), __IDE_PROC_DEVSET(speed, 0, 0xffff, NULL, NULL),
__IDE_PROC_DEVSET(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX, __IDE_PROC_DEVSET(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX,
...@@ -1746,7 +1728,9 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) ...@@ -1746,7 +1728,9 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
int buffer_size; int buffer_size;
u16 *ctl = (u16 *)&tape->caps[12]; u16 *ctl = (u16 *)&tape->caps[12];
drive->pc_callback = ide_tape_callback; ide_debug_log(IDE_DBG_FUNC, "minor: %d", minor);
drive->pc_callback = ide_tape_callback;
drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
...@@ -1833,22 +1817,32 @@ static void ide_tape_release(struct device *dev) ...@@ -1833,22 +1817,32 @@ static void ide_tape_release(struct device *dev)
} }
#ifdef CONFIG_IDE_PROC_FS #ifdef CONFIG_IDE_PROC_FS
static int proc_idetape_read_name static int idetape_name_proc_show(struct seq_file *m, void *v)
(char *page, char **start, off_t off, int count, int *eof, void *data)
{ {
ide_drive_t *drive = (ide_drive_t *) data; ide_drive_t *drive = (ide_drive_t *) m->private;
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
char *out = page;
int len;
len = sprintf(out, "%s\n", tape->name); seq_printf(m, "%s\n", tape->name);
PROC_IDE_READ_RETURN(page, start, off, count, eof, len); return 0;
}
static int idetape_name_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, idetape_name_proc_show, PDE(inode)->data);
} }
static const struct file_operations idetape_name_proc_fops = {
.owner = THIS_MODULE,
.open = idetape_name_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static ide_proc_entry_t idetape_proc[] = { static ide_proc_entry_t idetape_proc[] = {
{ "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL }, { "capacity", S_IFREG|S_IRUGO, &ide_capacity_proc_fops },
{ "name", S_IFREG|S_IRUGO, proc_idetape_read_name, NULL }, { "name", S_IFREG|S_IRUGO, &idetape_name_proc_fops },
{ NULL, 0, NULL, NULL } {}
}; };
static ide_proc_entry_t *ide_tape_proc_entries(ide_drive_t *drive) static ide_proc_entry_t *ide_tape_proc_entries(ide_drive_t *drive)
...@@ -1932,7 +1926,9 @@ static int ide_tape_probe(ide_drive_t *drive) ...@@ -1932,7 +1926,9 @@ static int ide_tape_probe(ide_drive_t *drive)
struct gendisk *g; struct gendisk *g;
int minor; int minor;
if (!strstr("ide-tape", drive->driver_req)) ide_debug_log(IDE_DBG_FUNC, "enter");
if (!strstr(DRV_NAME, drive->driver_req))
goto failed; goto failed;
if (drive->media != ide_tape) if (drive->media != ide_tape)
......
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/uaccess.h>
#include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd) void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd)
...@@ -53,7 +53,7 @@ void ide_tf_dump(const char *s, struct ide_cmd *cmd) ...@@ -53,7 +53,7 @@ void ide_tf_dump(const char *s, struct ide_cmd *cmd)
#endif #endif
} }
int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) int taskfile_lib_get_identify(ide_drive_t *drive, u8 *buf)
{ {
struct ide_cmd cmd; struct ide_cmd cmd;
...@@ -86,7 +86,7 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) ...@@ -86,7 +86,7 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
if (orig_cmd->protocol == ATA_PROT_PIO && if (orig_cmd->protocol == ATA_PROT_PIO &&
(orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) && (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
drive->mult_count == 0) { drive->mult_count == 0) {
printk(KERN_ERR "%s: multimode not set!\n", drive->name); pr_err("%s: multimode not set!\n", drive->name);
return ide_stopped; return ide_stopped;
} }
...@@ -214,7 +214,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) ...@@ -214,7 +214,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
} }
if (stat & ATA_BUSY) if (stat & ATA_BUSY)
printk(KERN_ERR "%s: drive still BUSY!\n", drive->name); pr_err("%s: drive still BUSY!\n", drive->name);
return stat; return stat;
} }
...@@ -225,8 +225,8 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, ...@@ -225,8 +225,8 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table; struct scatterlist *sg = hwif->sg_table;
struct scatterlist *cursg = cmd->cursg; struct scatterlist *cursg = cmd->cursg;
unsigned long uninitialized_var(flags);
struct page *page; struct page *page;
unsigned long flags;
unsigned int offset; unsigned int offset;
u8 *buf; u8 *buf;
...@@ -236,6 +236,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, ...@@ -236,6 +236,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
while (len) { while (len) {
unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs); unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
int page_is_high;
if (nr_bytes > PAGE_SIZE) if (nr_bytes > PAGE_SIZE)
nr_bytes = PAGE_SIZE; nr_bytes = PAGE_SIZE;
...@@ -247,7 +248,8 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, ...@@ -247,7 +248,8 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
page = nth_page(page, (offset >> PAGE_SHIFT)); page = nth_page(page, (offset >> PAGE_SHIFT));
offset %= PAGE_SIZE; offset %= PAGE_SIZE;
if (PageHighMem(page)) page_is_high = PageHighMem(page);
if (page_is_high)
local_irq_save(flags); local_irq_save(flags);
buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset; buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
...@@ -268,7 +270,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, ...@@ -268,7 +270,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
kunmap_atomic(buf, KM_BIO_SRC_IRQ); kunmap_atomic(buf, KM_BIO_SRC_IRQ);
if (PageHighMem(page)) if (page_is_high)
local_irq_restore(flags); local_irq_restore(flags);
len -= nr_bytes; len -= nr_bytes;
...@@ -322,10 +324,17 @@ static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd) ...@@ -322,10 +324,17 @@ static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat) void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat)
{ {
struct request *rq = drive->hwif->rq; struct request *rq = drive->hwif->rq;
u8 err = ide_read_error(drive); u8 err = ide_read_error(drive), nsect = cmd->tf.nsect;
u8 set_xfer = !!(cmd->tf_flags & IDE_TFLAG_SET_XFER);
ide_complete_cmd(drive, cmd, stat, err); ide_complete_cmd(drive, cmd, stat, err);
rq->errors = err; rq->errors = err;
if (err == 0 && set_xfer) {
ide_set_xfer_rate(drive, nsect);
ide_driveid_update(drive);
}
ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq)); ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
} }
...@@ -398,8 +407,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, ...@@ -398,8 +407,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
if (ide_wait_stat(&startstop, drive, ATA_DRQ, if (ide_wait_stat(&startstop, drive, ATA_DRQ,
drive->bad_wstat, WAIT_DRQ)) { drive->bad_wstat, WAIT_DRQ)) {
printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", pr_err("%s: no DRQ after issuing %sWRITE%s\n", drive->name,
drive->name,
(cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "", (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "",
(drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : ""); (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
return startstop; return startstop;
...@@ -449,7 +457,6 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, ...@@ -449,7 +457,6 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
blk_put_request(rq); blk_put_request(rq);
return error; return error;
} }
EXPORT_SYMBOL(ide_raw_taskfile); EXPORT_SYMBOL(ide_raw_taskfile);
int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd) int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd)
...@@ -475,10 +482,9 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -475,10 +482,9 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
u16 nsect = 0; u16 nsect = 0;
char __user *buf = (char __user *)arg; char __user *buf = (char __user *)arg;
// printk("IDE Taskfile ...\n");
req_task = kzalloc(tasksize, GFP_KERNEL); req_task = kzalloc(tasksize, GFP_KERNEL);
if (req_task == NULL) return -ENOMEM; if (req_task == NULL)
return -ENOMEM;
if (copy_from_user(req_task, buf, tasksize)) { if (copy_from_user(req_task, buf, tasksize)) {
kfree(req_task); kfree(req_task);
return -EFAULT; return -EFAULT;
...@@ -486,7 +492,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -486,7 +492,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
taskout = req_task->out_size; taskout = req_task->out_size;
taskin = req_task->in_size; taskin = req_task->in_size;
if (taskin > 65536 || taskout > 65536) { if (taskin > 65536 || taskout > 65536) {
err = -EINVAL; err = -EINVAL;
goto abort; goto abort;
...@@ -576,51 +582,49 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -576,51 +582,49 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
cmd.protocol = ATA_PROT_DMA; cmd.protocol = ATA_PROT_DMA;
switch (req_task->data_phase) { switch (req_task->data_phase) {
case TASKFILE_MULTI_OUT: case TASKFILE_MULTI_OUT:
if (!drive->mult_count) { if (!drive->mult_count) {
/* (hs): give up if multcount is not set */ /* (hs): give up if multcount is not set */
printk(KERN_ERR "%s: %s Multimode Write " \ pr_err("%s: %s Multimode Write multcount is not set\n",
"multcount is not set\n", drive->name, __func__);
drive->name, __func__); err = -EPERM;
err = -EPERM; goto abort;
goto abort; }
} cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; /* fall through */
/* fall through */ case TASKFILE_OUT:
case TASKFILE_OUT: cmd.protocol = ATA_PROT_PIO;
cmd.protocol = ATA_PROT_PIO; /* fall through */
/* fall through */ case TASKFILE_OUT_DMAQ:
case TASKFILE_OUT_DMAQ: case TASKFILE_OUT_DMA:
case TASKFILE_OUT_DMA: cmd.tf_flags |= IDE_TFLAG_WRITE;
cmd.tf_flags |= IDE_TFLAG_WRITE; nsect = taskout / SECTOR_SIZE;
nsect = taskout / SECTOR_SIZE; data_buf = outbuf;
data_buf = outbuf; break;
break; case TASKFILE_MULTI_IN:
case TASKFILE_MULTI_IN: if (!drive->mult_count) {
if (!drive->mult_count) { /* (hs): give up if multcount is not set */
/* (hs): give up if multcount is not set */ pr_err("%s: %s Multimode Read multcount is not set\n",
printk(KERN_ERR "%s: %s Multimode Read failure " \ drive->name, __func__);
"multcount is not set\n", err = -EPERM;
drive->name, __func__);
err = -EPERM;
goto abort;
}
cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
/* fall through */
case TASKFILE_IN:
cmd.protocol = ATA_PROT_PIO;
/* fall through */
case TASKFILE_IN_DMAQ:
case TASKFILE_IN_DMA:
nsect = taskin / SECTOR_SIZE;
data_buf = inbuf;
break;
case TASKFILE_NO_DATA:
cmd.protocol = ATA_PROT_NODATA;
break;
default:
err = -EFAULT;
goto abort; goto abort;
}
cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
/* fall through */
case TASKFILE_IN:
cmd.protocol = ATA_PROT_PIO;
/* fall through */
case TASKFILE_IN_DMAQ:
case TASKFILE_IN_DMA:
nsect = taskin / SECTOR_SIZE;
data_buf = inbuf;
break;
case TASKFILE_NO_DATA:
cmd.protocol = ATA_PROT_NODATA;
break;
default:
err = -EFAULT;
goto abort;
} }
if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA) if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
...@@ -629,7 +633,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -629,7 +633,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect; nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect;
if (!nsect) { if (!nsect) {
printk(KERN_ERR "%s: in/out command without data\n", pr_err("%s: in/out command without data\n",
drive->name); drive->name);
err = -EFAULT; err = -EFAULT;
goto abort; goto abort;
...@@ -671,8 +675,6 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -671,8 +675,6 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
kfree(outbuf); kfree(outbuf);
kfree(inbuf); kfree(inbuf);
// printk("IDE Taskfile ioctl ended. rc = %i\n", err);
return err; return err;
} }
#endif #endif
...@@ -318,7 +318,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev) ...@@ -318,7 +318,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
int i, rc; int i, rc;
struct ide_hw hw, *hws[] = { &hw }; struct ide_hw hw, *hws[] = { &hw };
clk = clk_get(&pdev->dev, "IDECLK"); clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) if (IS_ERR(clk))
return -ENODEV; return -ENODEV;
......
...@@ -258,6 +258,7 @@ enum { ...@@ -258,6 +258,7 @@ enum {
IDE_TFLAG_DYN = (1 << 5), IDE_TFLAG_DYN = (1 << 5),
IDE_TFLAG_FS = (1 << 6), IDE_TFLAG_FS = (1 << 6),
IDE_TFLAG_MULTI_PIO = (1 << 7), IDE_TFLAG_MULTI_PIO = (1 << 7),
IDE_TFLAG_SET_XFER = (1 << 8),
}; };
enum { enum {
...@@ -294,7 +295,7 @@ struct ide_cmd { ...@@ -294,7 +295,7 @@ struct ide_cmd {
} out, in; } out, in;
} valid; } valid;
u8 tf_flags; u16 tf_flags;
u8 ftf_flags; /* for TASKFILE ioctl */ u8 ftf_flags; /* for TASKFILE ioctl */
int protocol; int protocol;
...@@ -918,8 +919,7 @@ __IDE_PROC_DEVSET(_name, _min, _max, NULL, NULL) ...@@ -918,8 +919,7 @@ __IDE_PROC_DEVSET(_name, _min, _max, NULL, NULL)
typedef struct { typedef struct {
const char *name; const char *name;
mode_t mode; mode_t mode;
read_proc_t *read_proc; const struct file_operations *proc_fops;
write_proc_t *write_proc;
} ide_proc_entry_t; } ide_proc_entry_t;
void proc_ide_create(void); void proc_ide_create(void);
...@@ -931,24 +931,8 @@ void ide_proc_unregister_port(ide_hwif_t *); ...@@ -931,24 +931,8 @@ void ide_proc_unregister_port(ide_hwif_t *);
void ide_proc_register_driver(ide_drive_t *, struct ide_driver *); void ide_proc_register_driver(ide_drive_t *, struct ide_driver *);
void ide_proc_unregister_driver(ide_drive_t *, struct ide_driver *); void ide_proc_unregister_driver(ide_drive_t *, struct ide_driver *);
read_proc_t proc_ide_read_capacity; extern const struct file_operations ide_capacity_proc_fops;
read_proc_t proc_ide_read_geometry; extern const struct file_operations ide_geometry_proc_fops;
/*
* Standard exit stuff:
*/
#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) \
{ \
len -= off; \
if (len < count) { \
*eof = 1; \
if (len <= 0) \
return 0; \
} else \
len = count; \
*start = page + off; \
return len; \
}
#else #else
static inline void proc_ide_create(void) { ; } static inline void proc_ide_create(void) { ; }
static inline void proc_ide_destroy(void) { ; } static inline void proc_ide_destroy(void) { ; }
...@@ -960,7 +944,6 @@ static inline void ide_proc_register_driver(ide_drive_t *drive, ...@@ -960,7 +944,6 @@ static inline void ide_proc_register_driver(ide_drive_t *drive,
struct ide_driver *driver) { ; } struct ide_driver *driver) { ; }
static inline void ide_proc_unregister_driver(ide_drive_t *drive, static inline void ide_proc_unregister_driver(ide_drive_t *drive,
struct ide_driver *driver) { ; } struct ide_driver *driver) { ; }
#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0;
#endif #endif
enum { enum {
...@@ -1081,6 +1064,7 @@ extern void ide_fixstring(u8 *, const int, const int); ...@@ -1081,6 +1064,7 @@ extern void ide_fixstring(u8 *, const int, const int);
int ide_busy_sleep(ide_drive_t *, unsigned long, int); int ide_busy_sleep(ide_drive_t *, unsigned long, int);
int __ide_wait_stat(ide_drive_t *, u8, u8, unsigned long, u8 *);
int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
ide_startstop_t ide_do_park_unpark(ide_drive_t *, struct request *); ide_startstop_t ide_do_park_unpark(ide_drive_t *, struct request *);
...@@ -1169,7 +1153,7 @@ int ide_no_data_taskfile(ide_drive_t *, struct ide_cmd *); ...@@ -1169,7 +1153,7 @@ int ide_no_data_taskfile(ide_drive_t *, struct ide_cmd *);
int ide_taskfile_ioctl(ide_drive_t *, unsigned long); int ide_taskfile_ioctl(ide_drive_t *, unsigned long);
int ide_dev_read_id(ide_drive_t *, u8, u16 *); int ide_dev_read_id(ide_drive_t *, u8, u16 *, int);
extern int ide_driveid_update(ide_drive_t *); extern int ide_driveid_update(ide_drive_t *);
extern int ide_config_drive_speed(ide_drive_t *, u8); extern int ide_config_drive_speed(ide_drive_t *, u8);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册