* [PATCH 1/6] ide: move ide_read_bcount_and_ireason() to ide-atapi.c
2009-01-19 13:03 [PATCH 0/6] ide: more core code housekeeping Bartlomiej Zolnierkiewicz
@ 2009-01-19 13:03 ` Bartlomiej Zolnierkiewicz
2009-01-19 13:03 ` [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c Bartlomiej Zolnierkiewicz
` (5 subsequent siblings)
6 siblings, 0 replies; 27+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-01-19 13:03 UTC (permalink / raw)
To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Subject: [PATCH] ide: move ide_read_bcount_and_ireason() to ide-atapi.c
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
drivers/ide/ide-atapi.c | 15 +++++++++++++++
drivers/ide/ide-iops.c | 15 ---------------
2 files changed, 15 insertions(+), 15 deletions(-)
Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -288,6 +288,21 @@ int ide_cd_get_xferlen(struct request *r
}
EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);
+void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
+{
+ ide_task_t task;
+
+ memset(&task, 0, sizeof(task));
+ task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
+ IDE_TFLAG_IN_NSECT;
+
+ drive->hwif->tp_ops->tf_read(drive, &task);
+
+ *bcount = (task.tf.lbah << 8) | task.tf.lbam;
+ *ireason = task.tf.nsect & 3;
+}
+EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
+
/*
* This is the usual interrupt handler which will be called during a packet
* command. We will transfer some of the data (as requested by the drive)
Index: b/drivers/ide/ide-iops.c
===================================================================
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -360,21 +360,6 @@ u8 ide_read_error(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_read_error);
-void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
-{
- ide_task_t task;
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
- IDE_TFLAG_IN_NSECT;
-
- drive->hwif->tp_ops->tf_read(drive, &task);
-
- *bcount = (task.tf.lbah << 8) | task.tf.lbam;
- *ireason = task.tf.nsect & 3;
-}
-EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
-
const struct ide_tp_ops default_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 13:03 [PATCH 0/6] ide: more core code housekeeping Bartlomiej Zolnierkiewicz
2009-01-19 13:03 ` [PATCH 1/6] ide: move ide_read_bcount_and_ireason() to ide-atapi.c Bartlomiej Zolnierkiewicz
@ 2009-01-19 13:03 ` Bartlomiej Zolnierkiewicz
2009-01-19 14:17 ` Sergei Shtylyov
2009-01-19 16:39 ` Sergei Shtylyov
2009-01-19 13:03 ` [PATCH 3/6] ide: fix printk() levels in [atapi_]reset_pollfunc() Bartlomiej Zolnierkiewicz
` (4 subsequent siblings)
6 siblings, 2 replies; 27+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-01-19 13:03 UTC (permalink / raw)
To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Subject: [PATCH] ide: move SFF I/O code to ide-io-sff.c
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
drivers/ide/Makefile | 3
drivers/ide/ide-io-sff.c | 314 +++++++++++++++++++++++++++++++++++++++++++++++
drivers/ide/ide-iops.c | 311 ----------------------------------------------
3 files changed, 316 insertions(+), 312 deletions(-)
Index: b/drivers/ide/Makefile
===================================================================
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -5,7 +5,8 @@
EXTRA_CFLAGS += -Idrivers/ide
ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
- ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o
+ ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \
+ ide-io-sff.o
# core IDE code
ide-core-$(CONFIG_IDE_XFER_MODE) += ide-pio-blacklist.o ide-xfer-mode.o
Index: b/drivers/ide/ide-io-sff.c
===================================================================
--- /dev/null
+++ b/drivers/ide/ide-io-sff.c
@@ -0,0 +1,314 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+
+/*
+ * Conventional PIO operations for ATA devices
+ */
+
+static u8 ide_inb(unsigned long port)
+{
+ return (u8) inb(port);
+}
+
+static void ide_outb(u8 val, unsigned long port)
+{
+ outb(val, port);
+}
+
+/*
+ * MMIO operations, typically used for SATA controllers
+ */
+
+static u8 ide_mm_inb(unsigned long port)
+{
+ return (u8) readb((void __iomem *) port);
+}
+
+static void ide_mm_outb(u8 value, unsigned long port)
+{
+ writeb(value, (void __iomem *) port);
+}
+
+void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
+ else
+ outb(cmd, hwif->io_ports.command_addr);
+}
+EXPORT_SYMBOL_GPL(ide_exec_command);
+
+u8 ide_read_status(ide_hwif_t *hwif)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ return readb((void __iomem *)hwif->io_ports.status_addr);
+ else
+ return inb(hwif->io_ports.status_addr);
+}
+EXPORT_SYMBOL_GPL(ide_read_status);
+
+u8 ide_read_altstatus(ide_hwif_t *hwif)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ return readb((void __iomem *)hwif->io_ports.ctl_addr);
+ else
+ return inb(hwif->io_ports.ctl_addr);
+}
+EXPORT_SYMBOL_GPL(ide_read_altstatus);
+
+void ide_set_irq(ide_hwif_t *hwif, int on)
+{
+ u8 ctl = ATA_DEVCTL_OBS;
+
+ if (on == 4) { /* hack for SRST */
+ ctl |= 4;
+ on &= ~4;
+ }
+
+ ctl |= on ? 0 : 2;
+
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
+ else
+ outb(ctl, hwif->io_ports.ctl_addr);
+}
+EXPORT_SYMBOL_GPL(ide_set_irq);
+
+void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ struct ide_taskfile *tf = &task->tf;
+ void (*tf_outb)(u8 addr, unsigned long port);
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+ u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+
+ if (mmio)
+ tf_outb = ide_mm_outb;
+ else
+ tf_outb = ide_outb;
+
+ if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ HIHI = 0xFF;
+
+ if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
+ u16 data = (tf->hob_data << 8) | tf->data;
+
+ if (mmio)
+ writew(data, (void __iomem *)io_ports->data_addr);
+ else
+ outw(data, io_ports->data_addr);
+ }
+
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ tf_outb(tf->hob_feature, io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ tf_outb(tf->hob_nsect, io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ tf_outb(tf->hob_lbal, io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ tf_outb(tf->hob_lbam, io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ tf_outb(tf->hob_lbah, io_ports->lbah_addr);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ tf_outb(tf->feature, io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ tf_outb(tf->nsect, io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ tf_outb(tf->lbal, io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ tf_outb(tf->lbam, io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ tf_outb(tf->lbah, io_ports->lbah_addr);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ tf_outb((tf->device & HIHI) | drive->select,
+ io_ports->device_addr);
+}
+EXPORT_SYMBOL_GPL(ide_tf_load);
+
+void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ struct ide_taskfile *tf = &task->tf;
+ void (*tf_outb)(u8 addr, unsigned long port);
+ u8 (*tf_inb)(unsigned long port);
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+ if (mmio) {
+ tf_outb = ide_mm_outb;
+ tf_inb = ide_mm_inb;
+ } else {
+ tf_outb = ide_outb;
+ tf_inb = ide_inb;
+ }
+
+ if (task->tf_flags & IDE_TFLAG_IN_DATA) {
+ u16 data;
+
+ if (mmio)
+ data = readw((void __iomem *)io_ports->data_addr);
+ else
+ data = inw(io_ports->data_addr);
+
+ tf->data = data & 0xff;
+ tf->hob_data = (data >> 8) & 0xff;
+ }
+
+ /* be sure we're looking at the low order bits */
+ tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+
+ if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
+ tf->feature = tf_inb(io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ tf->nsect = tf_inb(io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ tf->lbal = tf_inb(io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ tf->lbam = tf_inb(io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ tf->lbah = tf_inb(io_ports->lbah_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ tf->device = tf_inb(io_ports->device_addr);
+
+ if (task->tf_flags & IDE_TFLAG_LBA48) {
+ tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
+
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+ tf->hob_feature = tf_inb(io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = tf_inb(io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = tf_inb(io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = tf_inb(io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = tf_inb(io_ports->lbah_addr);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_tf_read);
+
+/*
+ * Some localbus EIDE interfaces require a special access sequence
+ * when using 32-bit I/O instructions to transfer data. We call this
+ * the "vlb_sync" sequence, which consists of three successive reads
+ * of the sector count register location, with interrupts disabled
+ * to ensure that the reads all happen together.
+ */
+static void ata_vlb_sync(unsigned long port)
+{
+ (void)inb(port);
+ (void)inb(port);
+ (void)inb(port);
+}
+
+/*
+ * This is used for most PIO data transfers *from* the IDE interface
+ *
+ * These routines will round up any request for an odd number of bytes,
+ * so if an odd len is specified, be sure that there's at least one
+ * extra byte allocated for the buffer.
+ */
+void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
+ unsigned int len)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ unsigned long data_addr = io_ports->data_addr;
+ u8 io_32bit = drive->io_32bit;
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+ len++;
+
+ if (io_32bit) {
+ unsigned long uninitialized_var(flags);
+
+ if ((io_32bit & 2) && !mmio) {
+ local_irq_save(flags);
+ ata_vlb_sync(io_ports->nsect_addr);
+ }
+
+ if (mmio)
+ __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
+ else
+ insl(data_addr, buf, len / 4);
+
+ if ((io_32bit & 2) && !mmio)
+ local_irq_restore(flags);
+
+ if ((len & 3) >= 2) {
+ if (mmio)
+ __ide_mm_insw((void __iomem *)data_addr,
+ (u8 *)buf + (len & ~3), 1);
+ else
+ insw(data_addr, (u8 *)buf + (len & ~3), 1);
+ }
+ } else {
+ if (mmio)
+ __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
+ else
+ insw(data_addr, buf, len / 2);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_input_data);
+
+/*
+ * This is used for most PIO data transfers *to* the IDE interface
+ */
+void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf,
+ unsigned int len)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ unsigned long data_addr = io_ports->data_addr;
+ u8 io_32bit = drive->io_32bit;
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+ if (io_32bit) {
+ unsigned long uninitialized_var(flags);
+
+ if ((io_32bit & 2) && !mmio) {
+ local_irq_save(flags);
+ ata_vlb_sync(io_ports->nsect_addr);
+ }
+
+ if (mmio)
+ __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
+ else
+ outsl(data_addr, buf, len / 4);
+
+ if ((io_32bit & 2) && !mmio)
+ local_irq_restore(flags);
+
+ if ((len & 3) >= 2) {
+ if (mmio)
+ __ide_mm_outsw((void __iomem *)data_addr,
+ (u8 *)buf + (len & ~3), 1);
+ else
+ outsw(data_addr, (u8 *)buf + (len & ~3), 1);
+ }
+ } else {
+ if (mmio)
+ __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
+ else
+ outsw(data_addr, buf, len / 2);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_output_data);
+
+const struct ide_tp_ops default_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+
+ .set_irq = ide_set_irq,
+
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
+};
Index: b/drivers/ide/ide-iops.c
===================================================================
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -27,34 +27,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-/*
- * Conventional PIO operations for ATA devices
- */
-
-static u8 ide_inb (unsigned long port)
-{
- return (u8) inb(port);
-}
-
-static void ide_outb (u8 val, unsigned long port)
-{
- outb(val, port);
-}
-
-/*
- * MMIO operations, typically used for SATA controllers
- */
-
-static u8 ide_mm_inb (unsigned long port)
-{
- return (u8) readb((void __iomem *) port);
-}
-
-static void ide_mm_outb (u8 value, unsigned long port)
-{
- writeb(value, (void __iomem *) port);
-}
-
void SELECT_DRIVE (ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
@@ -78,275 +50,6 @@ void SELECT_MASK(ide_drive_t *drive, int
port_ops->maskproc(drive, mask);
}
-void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
- else
- outb(cmd, hwif->io_ports.command_addr);
-}
-EXPORT_SYMBOL_GPL(ide_exec_command);
-
-u8 ide_read_status(ide_hwif_t *hwif)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- return readb((void __iomem *)hwif->io_ports.status_addr);
- else
- return inb(hwif->io_ports.status_addr);
-}
-EXPORT_SYMBOL_GPL(ide_read_status);
-
-u8 ide_read_altstatus(ide_hwif_t *hwif)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- return readb((void __iomem *)hwif->io_ports.ctl_addr);
- else
- return inb(hwif->io_ports.ctl_addr);
-}
-EXPORT_SYMBOL_GPL(ide_read_altstatus);
-
-void ide_set_irq(ide_hwif_t *hwif, int on)
-{
- u8 ctl = ATA_DEVCTL_OBS;
-
- if (on == 4) { /* hack for SRST */
- ctl |= 4;
- on &= ~4;
- }
-
- ctl |= on ? 0 : 2;
-
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
- else
- outb(ctl, hwif->io_ports.ctl_addr);
-}
-EXPORT_SYMBOL_GPL(ide_set_irq);
-
-void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- void (*tf_outb)(u8 addr, unsigned long port);
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
- if (mmio)
- tf_outb = ide_mm_outb;
- else
- tf_outb = ide_outb;
-
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
- HIHI = 0xFF;
-
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- if (mmio)
- writew(data, (void __iomem *)io_ports->data_addr);
- else
- outw(data, io_ports->data_addr);
- }
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
- tf_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
- tf_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
- tf_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
- tf_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
- tf_outb(tf->hob_lbah, io_ports->lbah_addr);
-
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
- tf_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
- tf_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
- tf_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
- tf_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
- tf_outb(tf->lbah, io_ports->lbah_addr);
-
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
- tf_outb((tf->device & HIHI) | drive->select,
- io_ports->device_addr);
-}
-EXPORT_SYMBOL_GPL(ide_tf_load);
-
-void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- void (*tf_outb)(u8 addr, unsigned long port);
- u8 (*tf_inb)(unsigned long port);
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
- if (mmio) {
- tf_outb = ide_mm_outb;
- tf_inb = ide_mm_inb;
- } else {
- tf_outb = ide_outb;
- tf_inb = ide_inb;
- }
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data;
-
- if (mmio)
- data = readw((void __iomem *)io_ports->data_addr);
- else
- data = inw(io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
- /* be sure we're looking at the low order bits */
- tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = tf_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
- tf->nsect = tf_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
- tf->lbal = tf_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
- tf->lbam = tf_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
- tf->lbah = tf_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
- tf->device = tf_inb(io_ports->device_addr);
-
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = tf_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tf_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tf_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tf_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tf_inb(io_ports->lbah_addr);
- }
-}
-EXPORT_SYMBOL_GPL(ide_tf_read);
-
-/*
- * Some localbus EIDE interfaces require a special access sequence
- * when using 32-bit I/O instructions to transfer data. We call this
- * the "vlb_sync" sequence, which consists of three successive reads
- * of the sector count register location, with interrupts disabled
- * to ensure that the reads all happen together.
- */
-static void ata_vlb_sync(unsigned long port)
-{
- (void)inb(port);
- (void)inb(port);
- (void)inb(port);
-}
-
-/*
- * This is used for most PIO data transfers *from* the IDE interface
- *
- * These routines will round up any request for an odd number of bytes,
- * so if an odd len is specified, be sure that there's at least one
- * extra byte allocated for the buffer.
- */
-void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
- unsigned int len)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- unsigned long data_addr = io_ports->data_addr;
- u8 io_32bit = drive->io_32bit;
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
- len++;
-
- if (io_32bit) {
- unsigned long uninitialized_var(flags);
-
- if ((io_32bit & 2) && !mmio) {
- local_irq_save(flags);
- ata_vlb_sync(io_ports->nsect_addr);
- }
-
- if (mmio)
- __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
- else
- insl(data_addr, buf, len / 4);
-
- if ((io_32bit & 2) && !mmio)
- local_irq_restore(flags);
-
- if ((len & 3) >= 2) {
- if (mmio)
- __ide_mm_insw((void __iomem *)data_addr,
- (u8 *)buf + (len & ~3), 1);
- else
- insw(data_addr, (u8 *)buf + (len & ~3), 1);
- }
- } else {
- if (mmio)
- __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
- else
- insw(data_addr, buf, len / 2);
- }
-}
-EXPORT_SYMBOL_GPL(ide_input_data);
-
-/*
- * This is used for most PIO data transfers *to* the IDE interface
- */
-void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf,
- unsigned int len)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- unsigned long data_addr = io_ports->data_addr;
- u8 io_32bit = drive->io_32bit;
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
- if (io_32bit) {
- unsigned long uninitialized_var(flags);
-
- if ((io_32bit & 2) && !mmio) {
- local_irq_save(flags);
- ata_vlb_sync(io_ports->nsect_addr);
- }
-
- if (mmio)
- __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
- else
- outsl(data_addr, buf, len / 4);
-
- if ((io_32bit & 2) && !mmio)
- local_irq_restore(flags);
-
- if ((len & 3) >= 2) {
- if (mmio)
- __ide_mm_outsw((void __iomem *)data_addr,
- (u8 *)buf + (len & ~3), 1);
- else
- outsw(data_addr, (u8 *)buf + (len & ~3), 1);
- }
- } else {
- if (mmio)
- __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
- else
- outsw(data_addr, buf, len / 2);
- }
-}
-EXPORT_SYMBOL_GPL(ide_output_data);
-
u8 ide_read_error(ide_drive_t *drive)
{
ide_task_t task;
@@ -360,20 +63,6 @@ u8 ide_read_error(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_read_error);
-const struct ide_tp_ops default_tp_ops = {
- .exec_command = ide_exec_command,
- .read_status = ide_read_status,
- .read_altstatus = ide_read_altstatus,
-
- .set_irq = ide_set_irq,
-
- .tf_load = ide_tf_load,
- .tf_read = ide_tf_read,
-
- .input_data = ide_input_data,
- .output_data = ide_output_data,
-};
-
void ide_fix_driveid(u16 *id)
{
#ifndef __LITTLE_ENDIAN
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 13:03 ` [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c Bartlomiej Zolnierkiewicz
@ 2009-01-19 14:17 ` Sergei Shtylyov
2009-01-19 14:23 ` Bartlomiej Zolnierkiewicz
2009-01-19 16:39 ` Sergei Shtylyov
1 sibling, 1 reply; 27+ messages in thread
From: Sergei Shtylyov @ 2009-01-19 14:17 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel
Bartlomiej Zolnierkiewicz wrote:
> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Gah, what in the world is that SFF I/O code?
> Index: b/drivers/ide/ide-io-sff.c
> ===================================================================
> --- /dev/null
> +++ b/drivers/ide/ide-io-sff.c
> @@ -0,0 +1,314 @@
> +
> +#include <linux/kernel.h>
> +#include <linux/ide.h>
> +
> +/*
> + * Conventional PIO operations for ATA devices
> + */
> +
> +static u8 ide_inb(unsigned long port)
> +{
> + return (u8) inb(port);
> +}
> +
> +static void ide_outb(u8 val, unsigned long port)
> +{
> + outb(val, port);
> +}
> +
> +/*
> + * MMIO operations, typically used for SATA controllers
> + */
> +
> +static u8 ide_mm_inb(unsigned long port)
> +{
> + return (u8) readb((void __iomem *) port);
> +}
> +
> +static void ide_mm_outb(u8 value, unsigned long port)
> +{
> + writeb(value, (void __iomem *) port);
> +}
Ah, I see. Can we finally stop abusing the SFF name? Or are we bound to
copy every mistake that libata has made? :-/
MBR, Sergei
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 14:17 ` Sergei Shtylyov
@ 2009-01-19 14:23 ` Bartlomiej Zolnierkiewicz
2009-01-19 14:29 ` Sergei Shtylyov
0 siblings, 1 reply; 27+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-01-19 14:23 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: linux-ide, linux-kernel
On Monday 19 January 2009, Sergei Shtylyov wrote:
> Bartlomiej Zolnierkiewicz wrote:
>
> > Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
>
> Gah, what in the world is that SFF I/O code?
>
> > Index: b/drivers/ide/ide-io-sff.c
> > ===================================================================
> > --- /dev/null
> > +++ b/drivers/ide/ide-io-sff.c
> > @@ -0,0 +1,314 @@
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/ide.h>
> > +
> > +/*
> > + * Conventional PIO operations for ATA devices
> > + */
> > +
> > +static u8 ide_inb(unsigned long port)
> > +{
> > + return (u8) inb(port);
> > +}
> > +
> > +static void ide_outb(u8 val, unsigned long port)
> > +{
> > + outb(val, port);
> > +}
> > +
> > +/*
> > + * MMIO operations, typically used for SATA controllers
> > + */
> > +
> > +static u8 ide_mm_inb(unsigned long port)
> > +{
> > + return (u8) readb((void __iomem *) port);
> > +}
> > +
> > +static void ide_mm_outb(u8 value, unsigned long port)
> > +{
> > + writeb(value, (void __iomem *) port);
> > +}
>
> Ah, I see. Can we finally stop abusing the SFF name? Or are we bound to
> copy every mistake that libata has made? :-/
Please suggest a better name. :)
[ I'm also not happy with the naming but couldn't think of a better one. ]
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 14:23 ` Bartlomiej Zolnierkiewicz
@ 2009-01-19 14:29 ` Sergei Shtylyov
2009-01-19 14:31 ` Sergei Shtylyov
2009-01-19 17:37 ` Alan Cox
0 siblings, 2 replies; 27+ messages in thread
From: Sergei Shtylyov @ 2009-01-19 14:29 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel
Bartlomiej Zolnierkiewicz wrote:
>>>Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
>> Gah, what in the world is that SFF I/O code?
>>>Index: b/drivers/ide/ide-io-sff.c
>>>===================================================================
>>>--- /dev/null
>>>+++ b/drivers/ide/ide-io-sff.c
>>>@@ -0,0 +1,314 @@
>>>+
>>>+#include <linux/kernel.h>
>>>+#include <linux/ide.h>
>>>+
>>>+/*
>>>+ * Conventional PIO operations for ATA devices
>>>+ */
>>>+
>>>+static u8 ide_inb(unsigned long port)
>>>+{
>>>+ return (u8) inb(port);
>>>+}
>>>+
>>>+static void ide_outb(u8 val, unsigned long port)
>>>+{
>>>+ outb(val, port);
>>>+}
>>>+
>>>+/*
>>>+ * MMIO operations, typically used for SATA controllers
>>>+ */
>>>+
>>>+static u8 ide_mm_inb(unsigned long port)
>>>+{
>>>+ return (u8) readb((void __iomem *) port);
>>>+}
>>>+
>>>+static void ide_mm_outb(u8 value, unsigned long port)
>>>+{
>>>+ writeb(value, (void __iomem *) port);
>>>+}
>> Ah, I see. Can we finally stop abusing the SFF name? Or are we bound to
>>copy every mistake that libata has made? :-/
> Please suggest a better name. :)
> [ I'm also not happy with the naming but couldn't think of a better one. ]
Legacy perhaps?
WBR, Sergei
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 14:29 ` Sergei Shtylyov
@ 2009-01-19 14:31 ` Sergei Shtylyov
2009-01-19 14:35 ` Bartlomiej Zolnierkiewicz
2009-01-19 17:37 ` Alan Cox
1 sibling, 1 reply; 27+ messages in thread
From: Sergei Shtylyov @ 2009-01-19 14:31 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel
Hello, I wrote:
>>>> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
>>> Gah, what in the world is that SFF I/O code?
>>>> Index: b/drivers/ide/ide-io-sff.c
>>>> ===================================================================
>>>> --- /dev/null
>>>> +++ b/drivers/ide/ide-io-sff.c
>>>> @@ -0,0 +1,314 @@
>>>> +
>>>> +#include <linux/kernel.h>
>>>> +#include <linux/ide.h>
>>>> +
>>>> +/*
>>>> + * Conventional PIO operations for ATA devices
>>>> + */
>>>> +
>>>> +static u8 ide_inb(unsigned long port)
>>>> +{
>>>> + return (u8) inb(port);
>>>> +}
>>>> +
>>>> +static void ide_outb(u8 val, unsigned long port)
>>>> +{
>>>> + outb(val, port);
>>>> +}
>>>> +
>>>> +/*
>>>> + * MMIO operations, typically used for SATA controllers
>>>> + */
>>>> +
>>>> +static u8 ide_mm_inb(unsigned long port)
>>>> +{
>>>> + return (u8) readb((void __iomem *) port);
>>>> +}
>>>> +
>>>> +static void ide_mm_outb(u8 value, unsigned long port)
>>>> +{
>>>> + writeb(value, (void __iomem *) port);
>>>> +}
>>> Ah, I see. Can we finally stop abusing the SFF name? Or are we
>>> bound to copy every mistake that libata has made? :-/
>> Please suggest a better name. :)
>> [ I'm also not happy with the naming but couldn't think of a better
>> one. ]
> Legacy perhaps?
As in ide-io-legacy.c. I can also suggest ide-io-std.c,
ide-io-trad[itional].c...
MBR, Sergei
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 14:31 ` Sergei Shtylyov
@ 2009-01-19 14:35 ` Bartlomiej Zolnierkiewicz
0 siblings, 0 replies; 27+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-01-19 14:35 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: linux-ide, linux-kernel
On Monday 19 January 2009, Sergei Shtylyov wrote:
> Hello, I wrote:
>
> >>>> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
>
> >>> Gah, what in the world is that SFF I/O code?
>
> >>>> Index: b/drivers/ide/ide-io-sff.c
> >>>> ===================================================================
> >>>> --- /dev/null
> >>>> +++ b/drivers/ide/ide-io-sff.c
> >>>> @@ -0,0 +1,314 @@
> >>>> +
> >>>> +#include <linux/kernel.h>
> >>>> +#include <linux/ide.h>
> >>>> +
> >>>> +/*
> >>>> + * Conventional PIO operations for ATA devices
> >>>> + */
> >>>> +
> >>>> +static u8 ide_inb(unsigned long port)
> >>>> +{
> >>>> + return (u8) inb(port);
> >>>> +}
> >>>> +
> >>>> +static void ide_outb(u8 val, unsigned long port)
> >>>> +{
> >>>> + outb(val, port);
> >>>> +}
> >>>> +
> >>>> +/*
> >>>> + * MMIO operations, typically used for SATA controllers
> >>>> + */
> >>>> +
> >>>> +static u8 ide_mm_inb(unsigned long port)
> >>>> +{
> >>>> + return (u8) readb((void __iomem *) port);
> >>>> +}
> >>>> +
> >>>> +static void ide_mm_outb(u8 value, unsigned long port)
> >>>> +{
> >>>> + writeb(value, (void __iomem *) port);
> >>>> +}
>
> >>> Ah, I see. Can we finally stop abusing the SFF name? Or are we
> >>> bound to copy every mistake that libata has made? :-/
>
> >> Please suggest a better name. :)
>
> >> [ I'm also not happy with the naming but couldn't think of a better
> >> one. ]
>
> > Legacy perhaps?
>
> As in ide-io-legacy.c. I can also suggest ide-io-std.c,
> ide-io-trad[itional].c...
ide-io-std.c sounds good to me. I'll recast the patch before merging it.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 14:29 ` Sergei Shtylyov
2009-01-19 14:31 ` Sergei Shtylyov
@ 2009-01-19 17:37 ` Alan Cox
2009-01-19 18:02 ` Sergei Shtylyov
1 sibling, 1 reply; 27+ messages in thread
From: Alan Cox @ 2009-01-19 17:37 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel
> > [ I'm also not happy with the naming but couldn't think of a better one. ]
>
> Legacy perhaps?
Legacy to most people means either ISA/VLB or the PCI legacy
compatibility mode so that would be confusing.
BTW if you moved to ioreadX you could get rid of almost all the readb/inb
special casing.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 17:37 ` Alan Cox
@ 2009-01-19 18:02 ` Sergei Shtylyov
2009-01-19 18:36 ` Alan Cox
0 siblings, 1 reply; 27+ messages in thread
From: Sergei Shtylyov @ 2009-01-19 18:02 UTC (permalink / raw)
To: Alan Cox; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel
Hello.
Alan Cox wrote:
>>>[ I'm also not happy with the naming but couldn't think of a better one. ]
>> Legacy perhaps?
> Legacy to most people means either ISA/VLB or the PCI legacy
> compatibility mode so that would be confusing.
That's what this code is for (minus the MMIO accessors perhaps).
> BTW if you moved to ioreadX you could get rid of almost all the readb/inb
> special casing.
And burden the driver code with function calls ISO in/out instructions, at
least on x86. It's somewhat arguable move.
MBR, Sergei
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 18:02 ` Sergei Shtylyov
@ 2009-01-19 18:36 ` Alan Cox
2009-01-19 18:46 ` Sergei Shtylyov
0 siblings, 1 reply; 27+ messages in thread
From: Alan Cox @ 2009-01-19 18:36 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel
> > BTW if you moved to ioreadX you could get rid of almost all the readb/inb
> > special casing.
>
> And burden the driver code with function calls ISO in/out instructions, at
> least on x86. It's somewhat arguable move.
And exactly how do you think the IDE accessors in the file get called ?
It's already making function calls, without the benefit of inlining and
sharing common paths across architectures that can handle more than just
PIO v MMIO but also other addressing modes.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 18:36 ` Alan Cox
@ 2009-01-19 18:46 ` Sergei Shtylyov
2009-01-19 18:49 ` Alan Cox
0 siblings, 1 reply; 27+ messages in thread
From: Sergei Shtylyov @ 2009-01-19 18:46 UTC (permalink / raw)
To: Alan Cox; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel
Alan Cox wrote:
>>>BTW if you moved to ioreadX you could get rid of almost all the readb/inb
>>>special casing.
>> And burden the driver code with function calls ISO in/out instructions, at
>>least on x86. It's somewhat arguable move.
> And exactly how do you think the IDE accessors in the file get called ?
Tried looking at how in*()/out*() are defined on x86?
> It's already making function calls, without the benefit of inlining and
I'm afraid you're wrong here.
MBR, Sergei
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 18:46 ` Sergei Shtylyov
@ 2009-01-19 18:49 ` Alan Cox
2009-01-19 19:04 ` Sergei Shtylyov
2009-01-19 19:12 ` Bartlomiej Zolnierkiewicz
0 siblings, 2 replies; 27+ messages in thread
From: Alan Cox @ 2009-01-19 18:49 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel
> Tried looking at how in*()/out*() are defined on x86?
Tried looking at how ide_mm_inb is defined on x86
> > It's already making function calls, without the benefit of inlining and
>
> I'm afraid you're wrong here.
I'm afraid you are the one who is wrong. The IDE layer is duplicating a
generic level of indirection with its own code - purely because IDE
pre-dates that core functionality. The whole IDE layer indirection can go
away because Linux has caught up with the needs of the IDE layer.
Alan
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 18:49 ` Alan Cox
@ 2009-01-19 19:04 ` Sergei Shtylyov
2009-01-19 21:31 ` Alan Cox
2009-01-19 19:12 ` Bartlomiej Zolnierkiewicz
1 sibling, 1 reply; 27+ messages in thread
From: Sergei Shtylyov @ 2009-01-19 19:04 UTC (permalink / raw)
To: Alan Cox; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel
Alan Cox wrote:
>> Tried looking at how in*()/out*() are defined on x86?
> Tried looking at how ide_mm_inb is defined on x86
That's a bogus argument because:
- MMIO isn't much used by the IDE drivers much (normally the inline
ins*()/outs*() accessors are used;
- that's used only by generic IDE code, not by the drivers about which
I'veargued;
I've already agreed that the generic code would probably win from using
ioread*()/iowrite*().
>>>It's already making function calls, without the benefit of inlining and
>> I'm afraid you're wrong here.
> I'm afraid you are the one who is wrong. The IDE layer is duplicating a
> generic level of indirection with its own code - purely because IDE
> pre-dates that core functionality. The whole IDE layer indirection can go
> away because Linux has caught up with the needs of the IDE layer.
What IDE indirection you're talking about anyway?
> Alan
MBR, Sergei
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 19:04 ` Sergei Shtylyov
@ 2009-01-19 21:31 ` Alan Cox
2009-01-19 21:48 ` Sergei Shtylyov
0 siblings, 1 reply; 27+ messages in thread
From: Alan Cox @ 2009-01-19 21:31 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel
> > I'm afraid you are the one who is wrong. The IDE layer is duplicating a
> > generic level of indirection with its own code - purely because IDE
> > pre-dates that core functionality. The whole IDE layer indirection can go
> > away because Linux has caught up with the needs of the IDE layer.
>
> What IDE indirection you're talking about anyway?
As I said earlier ide_mm_inb etc via the function pointers tf_inb/tf_outb
etc.
Given how small those functions are it might even be worth rolling them
into two different versions of the functions like ide_tf_read as surely
it costs more to call them (in size) than to inline the two for those
functions?
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 21:31 ` Alan Cox
@ 2009-01-19 21:48 ` Sergei Shtylyov
2009-01-19 22:37 ` Sergei Shtylyov
0 siblings, 1 reply; 27+ messages in thread
From: Sergei Shtylyov @ 2009-01-19 21:48 UTC (permalink / raw)
To: Alan Cox; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel
Hello.
Alan Cox wrote:
>>> I'm afraid you are the one who is wrong. The IDE layer is duplicating a
>>> generic level of indirection with its own code - purely because IDE
>>> pre-dates that core functionality. The whole IDE layer indirection can go
>>> away because Linux has caught up with the needs of the IDE layer.
>>>
>> What IDE indirection you're talking about anyway?
>>
>
> As I said earlier ide_mm_inb etc via the function pointers tf_inb/tf_outb
> etc.
>
Ah... at least they don't have additional address checks that
ioread*()/iowrite*() have...
> Given how small those functions are it might even be worth rolling them
> into two different versions of the functions like ide_tf_read as surely
> it costs more to call them (in size) than to inline the two for those
> functions?
>
Indeed.
WBR, Sergei
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 21:48 ` Sergei Shtylyov
@ 2009-01-19 22:37 ` Sergei Shtylyov
0 siblings, 0 replies; 27+ messages in thread
From: Sergei Shtylyov @ 2009-01-19 22:37 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: Alan Cox, Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel
Hello, I wrote:
>>>> I'm afraid you are the one who is wrong. The IDE layer is
>>>> duplicating a
>>>> generic level of indirection with its own code - purely because IDE
>>>> pre-dates that core functionality. The whole IDE layer indirection
>>>> can go
>>>> away because Linux has caught up with the needs of the IDE layer.
>>>>
>>> What IDE indirection you're talking about anyway?
>>>
>>
>> As I said earlier ide_mm_inb etc via the function pointers
>> tf_inb/tf_outb
>> etc.
>>
>
> Ah... at least they don't have additional address checks that
> ioread*()/iowrite*() have...
Somehow I was looling at __ide_mm_{ins|outs}*() calls in ide-iops.c
instead... it doesn't help to fix the USB code and argue about IDE at
the same time. :-]
>> into two different versions of the functions like ide_tf_read as surely
>> it costs more to call them (in size) than to inline the two for those
>> functions?
>>
> Given how small those functions are it might even be worth rolling them
>
> Indeed.
The calling fucntions aren't that small, so it's again arguable...
MBR, Sergei
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 18:49 ` Alan Cox
2009-01-19 19:04 ` Sergei Shtylyov
@ 2009-01-19 19:12 ` Bartlomiej Zolnierkiewicz
2009-01-19 19:53 ` Sergei Shtylyov
1 sibling, 1 reply; 27+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-01-19 19:12 UTC (permalink / raw)
To: Alan Cox; +Cc: Sergei Shtylyov, linux-ide, linux-kernel
On Monday 19 January 2009, Alan Cox wrote:
> > Tried looking at how in*()/out*() are defined on x86?
>
> Tried looking at how ide_mm_inb is defined on x86
>
> > > It's already making function calls, without the benefit of inlining and
> >
> > I'm afraid you're wrong here.
>
> I'm afraid you are the one who is wrong. The IDE layer is duplicating a
> generic level of indirection with its own code - purely because IDE
> pre-dates that core functionality. The whole IDE layer indirection can go
> away because Linux has caught up with the needs of the IDE layer.
I wish it would be so simple as I would have removed the said indirection
long time ago. Unfortunately:
- not all archs support ioread() & co.
- there is still issue with cache aliasing on some CPUs
Once above deficiences get fixed we can look into ioread() conversion again.
[ IOW right now it is the correct thing to stick to ide_mm_*() indirection
since extra hardware coverage is more valuable than minor code cleanup. ]
Thanks,
Bart
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 19:12 ` Bartlomiej Zolnierkiewicz
@ 2009-01-19 19:53 ` Sergei Shtylyov
0 siblings, 0 replies; 27+ messages in thread
From: Sergei Shtylyov @ 2009-01-19 19:53 UTC (permalink / raw)
To: Alan Cox; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel
Bartlomiej Zolnierkiewicz wrote:
>>> Tried looking at how in*()/out*() are defined on x86?
>>Tried looking at how ide_mm_inb is defined on x86
>>>>It's already making function calls, without the benefit of inlining and
>>> I'm afraid you're wrong here.
>>I'm afraid you are the one who is wrong. The IDE layer is duplicating a
>>generic level of indirection with its own code - purely because IDE
>>pre-dates that core functionality. The whole IDE layer indirection can go
>>away because Linux has caught up with the needs of the IDE layer.
> I wish it would be so simple as I would have removed the said indirection
> long time ago. Unfortunately:
> - not all archs support ioread() & co.
> - there is still issue with cache aliasing on some CPUs
Yep, look at MIPS for an example.
> Thanks,
> Bart
MBR, Sergei
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c
2009-01-19 13:03 ` [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c Bartlomiej Zolnierkiewicz
2009-01-19 14:17 ` Sergei Shtylyov
@ 2009-01-19 16:39 ` Sergei Shtylyov
1 sibling, 0 replies; 27+ messages in thread
From: Sergei Shtylyov @ 2009-01-19 16:39 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel
Bartlomiej Zolnierkiewicz wrote:
> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
based on the promised file rename. :-)
> Index: b/drivers/ide/ide-io-sff.c
> ===================================================================
> --- /dev/null
> +++ b/drivers/ide/ide-io-sff.c
> @@ -0,0 +1,314 @@
> +
> +#include <linux/kernel.h>
> +#include <linux/ide.h>
> +
> +/*
> + * Conventional PIO operations for ATA devices
> + */
> +
> +static u8 ide_inb(unsigned long port)
> +{
> + return (u8) inb(port);
> +}
> +
> +static void ide_outb(u8 val, unsigned long port)
> +{
> + outb(val, port);
> +}
> +
> +/*
> + * MMIO operations, typically used for SATA controllers
> + */
> +
> +static u8 ide_mm_inb(unsigned long port)
> +{
> + return (u8) readb((void __iomem *) port);
> +}
> +
> +static void ide_mm_outb(u8 value, unsigned long port)
> +{
> + writeb(value, (void __iomem *) port);
> +}
Inconsistent spacing in the type casts: space present everywhere above,
absent everywhere below...
> +void ide_set_irq(ide_hwif_t *hwif, int on)
> +{
> + u8 ctl = ATA_DEVCTL_OBS;
> +
> + if (on == 4) { /* hack for SRST */
> + ctl |= 4;
> + on &= ~4;
> + }
> +
> + ctl |= on ? 0 : 2;
> +
> + if (hwif->host_flags & IDE_HFLAG_MMIO)
> + writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
> + else
> + outb(ctl, hwif->io_ports.ctl_addr);
> +}
> +EXPORT_SYMBOL_GPL(ide_set_irq);
Ugh, I really need to convert set_irq() to write_devctl(), it's a pity I
hasn't done it still...
> +/*
> + * Some localbus EIDE interfaces require a special access sequence
> + * when using 32-bit I/O instructions to transfer data. We call this
> + * the "vlb_sync" sequence, which consists of three successive reads
> + * of the sector count register location, with interrupts disabled
> + * to ensure that the reads all happen together.
> + */
> +static void ata_vlb_sync(unsigned long port)
Not clear why this has ata_ prefix...
> +{
> + (void)inb(port);
> + (void)inb(port);
> + (void)inb(port);
> +}
> +
> +/*
> + * This is used for most PIO data transfers *from* the IDE interface
> + *
> + * These routines will round up any request for an odd number of bytes,
> + * so if an odd len is specified, be sure that there's at least one
> + * extra byte allocated for the buffer.
> + */
> +void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
> + unsigned int len)
> +{
> + ide_hwif_t *hwif = drive->hwif;
> + struct ide_io_ports *io_ports = &hwif->io_ports;
> + unsigned long data_addr = io_ports->data_addr;
> + u8 io_32bit = drive->io_32bit;
> + u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
> +
> + len++;
> +
> + if (io_32bit) {
> + unsigned long uninitialized_var(flags);
> +
> + if ((io_32bit & 2) && !mmio) {
> + local_irq_save(flags);
> + ata_vlb_sync(io_ports->nsect_addr);
> + }
> +
> + if (mmio)
> + __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
It's not clear why we're not using readsl()...
> + else
> + insl(data_addr, buf, len / 4);
> +
> + if ((io_32bit & 2) && !mmio)
> + local_irq_restore(flags);
> +
> + if ((len & 3) >= 2) {
> + if (mmio)
> + __ide_mm_insw((void __iomem *)data_addr,
> + (u8 *)buf + (len & ~3), 1);
... ans readsw(). Ah, some archs do cache flushes around reads[wl]().
Besides, I doubt that the definitions in include/asm-generic/ide_iops.h are
correct as they use read[wl]() in a loop which may not fly on BE...
MBR, Sergei
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 3/6] ide: fix printk() levels in [atapi_]reset_pollfunc()
2009-01-19 13:03 [PATCH 0/6] ide: more core code housekeeping Bartlomiej Zolnierkiewicz
2009-01-19 13:03 ` [PATCH 1/6] ide: move ide_read_bcount_and_ireason() to ide-atapi.c Bartlomiej Zolnierkiewicz
2009-01-19 13:03 ` [PATCH 2/6] ide: move SFF I/O code to ide-io-sff.c Bartlomiej Zolnierkiewicz
@ 2009-01-19 13:03 ` Bartlomiej Zolnierkiewicz
2009-01-19 14:28 ` Sergei Shtylyov
2009-01-19 13:03 ` [PATCH 4/6] ide: fix comments in ide_config_drive_speed() Bartlomiej Zolnierkiewicz
` (3 subsequent siblings)
6 siblings, 1 reply; 27+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-01-19 13:03 UTC (permalink / raw)
To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Subject: [PATCH] ide: fix printk() levels in [atapi_]reset_pollfunc()
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
drivers/ide/ide-iops.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
Index: b/drivers/ide/ide-iops.c
===================================================================
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -549,7 +549,7 @@ static ide_startstop_t atapi_reset_pollf
stat = hwif->tp_ops->read_status(hwif);
if (OK_STAT(stat, 0, ATA_BUSY))
- printk("%s: ATAPI reset complete\n", drive->name);
+ printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name);
else {
if (time_before(jiffies, hwif->poll_timeout)) {
ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
@@ -558,8 +558,8 @@ static ide_startstop_t atapi_reset_pollf
}
/* end of polling */
hwif->polling = 0;
- printk("%s: ATAPI reset timed-out, status=0x%02x\n",
- drive->name, stat);
+ printk(KERN_ERR "%s: ATAPI reset timed-out, status=0x%02x\n",
+ drive->name, stat);
/* do it the old fashioned way */
return do_reset1(drive, 1);
}
@@ -618,7 +618,8 @@ static ide_startstop_t reset_pollfunc (i
/* continue polling */
return ide_started;
}
- printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
+ printk(KERN_ERR "%s: reset timed-out, status=0x%02x\n",
+ hwif->name, tmp);
drive->failures++;
err = -EIO;
} else {
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 4/6] ide: fix comments in ide_config_drive_speed()
2009-01-19 13:03 [PATCH 0/6] ide: more core code housekeeping Bartlomiej Zolnierkiewicz
` (2 preceding siblings ...)
2009-01-19 13:03 ` [PATCH 3/6] ide: fix printk() levels in [atapi_]reset_pollfunc() Bartlomiej Zolnierkiewicz
@ 2009-01-19 13:03 ` Bartlomiej Zolnierkiewicz
2009-01-19 14:25 ` Sergei Shtylyov
2009-01-19 13:03 ` [PATCH 5/6] ide: checkpatch.pl fixes for ide-iops.c Bartlomiej Zolnierkiewicz
` (2 subsequent siblings)
6 siblings, 1 reply; 27+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-01-19 13:03 UTC (permalink / raw)
To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Subject: [PATCH] ide: fix comments in ide_config_drive_speed()
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
drivers/ide/ide-iops.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
Index: b/drivers/ide/ide-iops.c
===================================================================
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -369,18 +369,15 @@ int ide_config_drive_speed(ide_drive_t *
* but for some reason these don't work at
* this point (lost interrupt).
*/
- /*
- * Select the drive, and issue the SETFEATURES command
- */
- disable_irq_nosync(hwif->irq);
-
+
/*
* 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);
SELECT_DRIVE(drive);
SELECT_MASK(drive, 1);
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 5/6] ide: checkpatch.pl fixes for ide-iops.c
2009-01-19 13:03 [PATCH 0/6] ide: more core code housekeeping Bartlomiej Zolnierkiewicz
` (3 preceding siblings ...)
2009-01-19 13:03 ` [PATCH 4/6] ide: fix comments in ide_config_drive_speed() Bartlomiej Zolnierkiewicz
@ 2009-01-19 13:03 ` Bartlomiej Zolnierkiewicz
2009-01-19 13:03 ` [PATCH 6/6] ide: move error handling code to ide-eh.c Bartlomiej Zolnierkiewicz
2009-01-19 14:19 ` [PATCH 0/6] ide: more core code housekeeping Sergei Shtylyov
6 siblings, 0 replies; 27+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-01-19 13:03 UTC (permalink / raw)
To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Subject: [PATCH] ide: checkpatch.pl fixes for ide-iops.c
Fix following checkpatch.pl warnings/errors:
- WARNING: space prohibited between function name and open parenthesis '('
- WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable
- WARNING: line over 80 characters
- ERROR: trailing whitespace
- ERROR: space required before the open parenthesis '('
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
drivers/ide/ide-iops.c | 48 +++++++++++++++++++++++-------------------------
1 file changed, 23 insertions(+), 25 deletions(-)
Index: b/drivers/ide/ide-iops.c
===================================================================
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -27,7 +27,7 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-void SELECT_DRIVE (ide_drive_t *drive)
+void SELECT_DRIVE(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;
@@ -84,7 +84,7 @@ void ide_fix_driveid(u16 *id)
* returned by the ATA_CMD_ID_ATA[PI] commands.
*/
-void ide_fixstring (u8 *s, const int bytecount, const int byteswap)
+void ide_fixstring(u8 *s, const int bytecount, const int byteswap)
{
u8 *p, *end = &s[bytecount & ~1]; /* bytecount must be even */
@@ -107,7 +107,6 @@ void ide_fixstring (u8 *s, const int byt
while (p != end)
*p++ = '\0';
}
-
EXPORT_SYMBOL(ide_fixstring);
/*
@@ -121,7 +120,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)
+static 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;
@@ -179,7 +179,8 @@ static int __ide_wait_stat(ide_drive_t *
* The caller should return the updated value of "startstop" in this case,
* "startstop" is unchanged when the function returns 0.
*/
-int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout)
+int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good,
+ u8 bad, unsigned long timeout)
{
int err;
u8 stat;
@@ -199,7 +200,6 @@ int ide_wait_stat(ide_startstop_t *start
return err;
}
-
EXPORT_SYMBOL(ide_wait_stat);
/**
@@ -220,7 +220,6 @@ int ide_in_drive_list(u16 *id, const str
return 1;
return 0;
}
-
EXPORT_SYMBOL_GPL(ide_in_drive_list);
/*
@@ -245,7 +244,7 @@ static const struct drive_list_entry ivb
* All hosts that use the 80c ribbon must use!
* The name is derived from upper byte of word 93 and the 80c ribbon.
*/
-u8 eighty_ninty_three (ide_drive_t *drive)
+u8 eighty_ninty_three(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
u16 *id = drive->id;
@@ -470,9 +469,8 @@ void ide_set_handler (ide_drive_t *drive
__ide_set_handler(drive, handler, timeout, expiry);
spin_unlock_irqrestore(&hwif->lock, flags);
}
-
EXPORT_SYMBOL(ide_set_handler);
-
+
/**
* ide_execute_command - execute an IDE command
* @drive: IDE drive to issue the command against
@@ -482,7 +480,7 @@ EXPORT_SYMBOL(ide_set_handler);
* @expiry: handler to run on timeout
*
* Helper function to issue an IDE command. This handles the
- * atomicity requirements, command timing and ensures that the
+ * atomicity requirements, command timing and ensures that the
* handler and IRQ setup do not race. All IDE command kick off
* should go via this function or do equivalent locking.
*/
@@ -528,28 +526,29 @@ static inline void ide_complete_drive_re
}
/* needed below */
-static ide_startstop_t do_reset1 (ide_drive_t *, int);
+static ide_startstop_t do_reset1(ide_drive_t *, int);
/*
- * atapi_reset_pollfunc() gets invoked to poll the interface for completion every 50ms
- * during an atapi drive reset operation. If the drive has not yet responded,
- * and we have not yet hit our maximum waiting time, then the timer is restarted
- * for another 50ms.
+ * atapi_reset_pollfunc() gets invoked to poll the interface for completion
+ * every 50ms during an atapi drive reset operation. If the drive has not yet
+ * responded, and we have not yet hit our maximum waiting time, then the timer
+ * is restarted for another 50ms.
*/
-static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
+static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
u8 stat;
SELECT_DRIVE(drive);
- udelay (10);
+ udelay(10);
stat = hwif->tp_ops->read_status(hwif);
if (OK_STAT(stat, 0, ATA_BUSY))
printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name);
else {
if (time_before(jiffies, hwif->poll_timeout)) {
- ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
+ ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20,
+ NULL);
/* continue polling */
return ide_started;
}
@@ -591,7 +590,7 @@ static void ide_reset_report_error(ide_h
* and we have not yet hit our maximum waiting time, then the timer is restarted
* for another 50ms.
*/
-static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
+static ide_startstop_t reset_pollfunc(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;
@@ -703,7 +702,7 @@ static void pre_reset(ide_drive_t *drive
* (up to 30 seconds worstcase). So, instead of busy-waiting here for it,
* we set a timer to poll at 50ms intervals.
*/
-static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
+static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
@@ -723,7 +722,7 @@ static ide_startstop_t do_reset1 (ide_dr
if (drive->media != ide_disk && !do_not_try_atapi) {
pre_reset(drive);
SELECT_DRIVE(drive);
- udelay (20);
+ udelay(20);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
ndelay(400);
hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
@@ -807,11 +806,10 @@ static ide_startstop_t do_reset1 (ide_dr
* ide_do_reset() is the entry point to the drive/interface reset code.
*/
-ide_startstop_t ide_do_reset (ide_drive_t *drive)
+ide_startstop_t ide_do_reset(ide_drive_t *drive)
{
return do_reset1(drive, 0);
}
-
EXPORT_SYMBOL(ide_do_reset);
/*
@@ -822,7 +820,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif,
{
u8 stat = 0;
- while(timeout--) {
+ while (timeout--) {
/*
* Turn this into a schedule() sleep once I'm sure
* about locking issues (2.5 work ?).
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 6/6] ide: move error handling code to ide-eh.c
2009-01-19 13:03 [PATCH 0/6] ide: more core code housekeeping Bartlomiej Zolnierkiewicz
` (4 preceding siblings ...)
2009-01-19 13:03 ` [PATCH 5/6] ide: checkpatch.pl fixes for ide-iops.c Bartlomiej Zolnierkiewicz
@ 2009-01-19 13:03 ` Bartlomiej Zolnierkiewicz
2009-01-19 14:19 ` [PATCH 0/6] ide: more core code housekeeping Sergei Shtylyov
6 siblings, 0 replies; 27+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-01-19 13:03 UTC (permalink / raw)
To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Subject: [PATCH] ide: move error handling code to ide-eh.c
Do some CodingStyle fixups in <linux/ide.h> while at it.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
drivers/ide/Makefile | 2
drivers/ide/ide-eh.c | 427 +++++++++++++++++++++++++++++++++++++++++++++++++
drivers/ide/ide-io.c | 129 --------------
drivers/ide/ide-iops.c | 299 ----------------------------------
include/linux/ide.h | 13 -
5 files changed, 439 insertions(+), 431 deletions(-)
Index: b/drivers/ide/Makefile
===================================================================
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -6,7 +6,7 @@ EXTRA_CFLAGS += -Idrivers/ide
ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \
- ide-io-sff.o
+ ide-io-sff.o ide-eh.o
# core IDE code
ide-core-$(CONFIG_IDE_XFER_MODE) += ide-pio-blacklist.o ide-xfer-mode.o
Index: b/drivers/ide/ide-eh.c
===================================================================
--- /dev/null
+++ b/drivers/ide/ide-eh.c
@@ -0,0 +1,427 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+
+static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq,
+ u8 stat, u8 err)
+{
+ ide_hwif_t *hwif = drive->hwif;
+
+ if ((stat & ATA_BUSY) ||
+ ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
+ /* other bits are useless when BUSY */
+ rq->errors |= ERROR_RESET;
+ } else if (stat & ATA_ERR) {
+ /* err has different meaning on cdrom and tape */
+ if (err == ATA_ABORTED) {
+ if ((drive->dev_flags & IDE_DFLAG_LBA) &&
+ /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
+ hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS)
+ return ide_stopped;
+ } else if ((err & BAD_CRC) == BAD_CRC) {
+ /* UDMA crc error, just retry the operation */
+ drive->crc_count++;
+ } else if (err & (ATA_BBK | ATA_UNC)) {
+ /* retries won't help these */
+ rq->errors = ERROR_MAX;
+ } else if (err & ATA_TRK0NF) {
+ /* help it find track zero */
+ rq->errors |= ERROR_RECAL;
+ }
+ }
+
+ if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ &&
+ (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
+ int nsect = drive->mult_count ? drive->mult_count : 1;
+
+ ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
+ }
+
+ if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
+ ide_kill_rq(drive, rq);
+ return ide_stopped;
+ }
+
+ if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
+ rq->errors |= ERROR_RESET;
+
+ if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+ ++rq->errors;
+ return ide_do_reset(drive);
+ }
+
+ if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
+ drive->special.b.recalibrate = 1;
+
+ ++rq->errors;
+
+ return ide_stopped;
+}
+
+static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq,
+ u8 stat, u8 err)
+{
+ ide_hwif_t *hwif = drive->hwif;
+
+ if ((stat & ATA_BUSY) ||
+ ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
+ /* other bits are useless when BUSY */
+ rq->errors |= ERROR_RESET;
+ } else {
+ /* add decoding error stuff */
+ }
+
+ if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
+ /* force an abort */
+ hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);
+
+ if (rq->errors >= ERROR_MAX) {
+ ide_kill_rq(drive, rq);
+ } else {
+ if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+ ++rq->errors;
+ return ide_do_reset(drive);
+ }
+ ++rq->errors;
+ }
+
+ return ide_stopped;
+}
+
+static ide_startstop_t __ide_error(ide_drive_t *drive, struct request *rq,
+ u8 stat, u8 err)
+{
+ if (drive->media == ide_disk)
+ return ide_ata_error(drive, rq, stat, err);
+ return ide_atapi_error(drive, rq, stat, err);
+}
+
+/**
+ * ide_error - handle an error on the IDE
+ * @drive: drive the error occurred on
+ * @msg: message to report
+ * @stat: status bits
+ *
+ * ide_error() takes action based on the error returned by the drive.
+ * For normal I/O that may well include retries. We deal with
+ * both new-style (taskfile) and old style command handling here.
+ * In the case of taskfile command handling there is work left to
+ * do
+ */
+
+ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat)
+{
+ struct request *rq;
+ u8 err;
+
+ err = ide_dump_status(drive, msg, stat);
+
+ rq = drive->hwif->rq;
+ if (rq == NULL)
+ return ide_stopped;
+
+ /* retry only "normal" I/O: */
+ if (!blk_fs_request(rq)) {
+ rq->errors = 1;
+ ide_end_drive_cmd(drive, stat, err);
+ return ide_stopped;
+ }
+
+ return __ide_error(drive, rq, stat, err);
+}
+EXPORT_SYMBOL_GPL(ide_error);
+
+static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
+{
+ struct request *rq = drive->hwif->rq;
+
+ if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET)
+ ide_end_request(drive, err ? err : 1, 0);
+}
+
+/* needed below */
+static ide_startstop_t do_reset1(ide_drive_t *, int);
+
+/*
+ * atapi_reset_pollfunc() gets invoked to poll the interface for completion
+ * every 50ms during an atapi drive reset operation. If the drive has not yet
+ * responded, and we have not yet hit our maximum waiting time, then the timer
+ * is restarted for another 50ms.
+ */
+static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 stat;
+
+ SELECT_DRIVE(drive);
+ udelay(10);
+ stat = hwif->tp_ops->read_status(hwif);
+
+ if (OK_STAT(stat, 0, ATA_BUSY))
+ printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name);
+ else {
+ if (time_before(jiffies, hwif->poll_timeout)) {
+ ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20,
+ NULL);
+ /* continue polling */
+ return ide_started;
+ }
+ /* end of polling */
+ hwif->polling = 0;
+ printk(KERN_ERR "%s: ATAPI reset timed-out, status=0x%02x\n",
+ drive->name, stat);
+ /* do it the old fashioned way */
+ return do_reset1(drive, 1);
+ }
+ /* done polling */
+ hwif->polling = 0;
+ ide_complete_drive_reset(drive, 0);
+ return ide_stopped;
+}
+
+static void ide_reset_report_error(ide_hwif_t *hwif, u8 err)
+{
+ static const char *err_master_vals[] =
+ { NULL, "passed", "formatter device error",
+ "sector buffer error", "ECC circuitry error",
+ "controlling MPU error" };
+
+ u8 err_master = err & 0x7f;
+
+ printk(KERN_ERR "%s: reset: master: ", hwif->name);
+ if (err_master && err_master < 6)
+ printk(KERN_CONT "%s", err_master_vals[err_master]);
+ else
+ printk(KERN_CONT "error (0x%02x?)", err);
+ if (err & 0x80)
+ printk(KERN_CONT "; slave: failed");
+ printk(KERN_CONT "\n");
+}
+
+/*
+ * reset_pollfunc() gets invoked to poll the interface for completion every 50ms
+ * during an ide reset operation. If the drives have not yet responded,
+ * and we have not yet hit our maximum waiting time, then the timer is restarted
+ * for another 50ms.
+ */
+static ide_startstop_t reset_pollfunc(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+ u8 tmp;
+ int err = 0;
+
+ if (port_ops && port_ops->reset_poll) {
+ err = port_ops->reset_poll(drive);
+ if (err) {
+ printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
+ hwif->name, drive->name);
+ goto out;
+ }
+ }
+
+ tmp = hwif->tp_ops->read_status(hwif);
+
+ if (!OK_STAT(tmp, 0, ATA_BUSY)) {
+ if (time_before(jiffies, hwif->poll_timeout)) {
+ ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
+ /* continue polling */
+ return ide_started;
+ }
+ printk(KERN_ERR "%s: reset timed-out, status=0x%02x\n",
+ hwif->name, tmp);
+ drive->failures++;
+ err = -EIO;
+ } else {
+ tmp = ide_read_error(drive);
+
+ if (tmp == 1) {
+ printk(KERN_INFO "%s: reset: success\n", hwif->name);
+ drive->failures = 0;
+ } else {
+ ide_reset_report_error(hwif, tmp);
+ drive->failures++;
+ err = -EIO;
+ }
+ }
+out:
+ hwif->polling = 0; /* done polling */
+ ide_complete_drive_reset(drive, err);
+ return ide_stopped;
+}
+
+static void ide_disk_pre_reset(ide_drive_t *drive)
+{
+ int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1;
+
+ drive->special.all = 0;
+ drive->special.b.set_geometry = legacy;
+ drive->special.b.recalibrate = legacy;
+
+ drive->mult_count = 0;
+ drive->dev_flags &= ~IDE_DFLAG_PARKED;
+
+ if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 &&
+ (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0)
+ drive->mult_req = 0;
+
+ if (drive->mult_req != drive->mult_count)
+ drive->special.b.set_multmode = 1;
+}
+
+static void pre_reset(ide_drive_t *drive)
+{
+ const struct ide_port_ops *port_ops = drive->hwif->port_ops;
+
+ if (drive->media == ide_disk)
+ ide_disk_pre_reset(drive);
+ else
+ drive->dev_flags |= IDE_DFLAG_POST_RESET;
+
+ if (drive->dev_flags & IDE_DFLAG_USING_DMA) {
+ if (drive->crc_count)
+ ide_check_dma_crc(drive);
+ else
+ ide_dma_off(drive);
+ }
+
+ if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) {
+ if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) {
+ drive->dev_flags &= ~IDE_DFLAG_UNMASK;
+ drive->io_32bit = 0;
+ }
+ return;
+ }
+
+ if (port_ops && port_ops->pre_reset)
+ port_ops->pre_reset(drive);
+
+ if (drive->current_speed != 0xff)
+ drive->desired_speed = drive->current_speed;
+ drive->current_speed = 0xff;
+}
+
+/*
+ * do_reset1() attempts to recover a confused drive by resetting it.
+ * Unfortunately, resetting a disk drive actually resets all devices on
+ * the same interface, so it can really be thought of as resetting the
+ * interface rather than resetting the drive.
+ *
+ * ATAPI devices have their own reset mechanism which allows them to be
+ * individually reset without clobbering other devices on the same interface.
+ *
+ * Unfortunately, the IDE interface does not generate an interrupt to let
+ * us know when the reset operation has finished, so we must poll for this.
+ * Equally poor, though, is the fact that this may a very long time to complete,
+ * (up to 30 seconds worstcase). So, instead of busy-waiting here for it,
+ * we set a timer to poll at 50ms intervals.
+ */
+static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+ const struct ide_port_ops *port_ops;
+ ide_drive_t *tdrive;
+ unsigned long flags, timeout;
+ int i;
+ DEFINE_WAIT(wait);
+
+ spin_lock_irqsave(&hwif->lock, flags);
+
+ /* We must not reset with running handlers */
+ BUG_ON(hwif->handler != NULL);
+
+ /* For an ATAPI device, first try an ATAPI SRST. */
+ if (drive->media != ide_disk && !do_not_try_atapi) {
+ pre_reset(drive);
+ SELECT_DRIVE(drive);
+ udelay(20);
+ tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
+ ndelay(400);
+ hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
+ hwif->polling = 1;
+ __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ return ide_started;
+ }
+
+ /* We must not disturb devices in the IDE_DFLAG_PARKED state. */
+ do {
+ unsigned long now;
+
+ prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE);
+ timeout = jiffies;
+ ide_port_for_each_present_dev(i, tdrive, hwif) {
+ if ((tdrive->dev_flags & IDE_DFLAG_PARKED) &&
+ time_after(tdrive->sleep, timeout))
+ timeout = tdrive->sleep;
+ }
+
+ now = jiffies;
+ if (time_before_eq(timeout, now))
+ break;
+
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ timeout = schedule_timeout_uninterruptible(timeout - now);
+ spin_lock_irqsave(&hwif->lock, flags);
+ } while (timeout);
+ finish_wait(&ide_park_wq, &wait);
+
+ /*
+ * First, reset any device state data we were maintaining
+ * for any of the drives on this interface.
+ */
+ ide_port_for_each_dev(i, tdrive, hwif)
+ pre_reset(tdrive);
+
+ if (io_ports->ctl_addr == 0) {
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ ide_complete_drive_reset(drive, -ENXIO);
+ return ide_stopped;
+ }
+
+ /*
+ * Note that we also set nIEN while resetting the device,
+ * to mask unwanted interrupts from the interface during the reset.
+ * However, due to the design of PC hardware, this will cause an
+ * immediate interrupt due to the edge transition it produces.
+ * This single interrupt gives us a "fast poll" for drives that
+ * recover from reset very quickly, saving us the first 50ms wait time.
+ *
+ * TODO: add ->softreset method and stop abusing ->set_irq
+ */
+ /* set SRST and nIEN */
+ tp_ops->set_irq(hwif, 4);
+ /* more than enough time */
+ udelay(10);
+ /* clear SRST, leave nIEN (unless device is on the quirk list) */
+ tp_ops->set_irq(hwif, drive->quirk_list == 2);
+ /* more than enough time */
+ udelay(10);
+ hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
+ hwif->polling = 1;
+ __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
+
+ /*
+ * Some weird controller like resetting themselves to a strange
+ * state when the disks are reset this way. At least, the Winbond
+ * 553 documentation says that
+ */
+ port_ops = hwif->port_ops;
+ if (port_ops && port_ops->resetproc)
+ port_ops->resetproc(drive);
+
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ return ide_started;
+}
+
+/*
+ * ide_do_reset() is the entry point to the drive/interface reset code.
+ */
+
+ide_startstop_t ide_do_reset(ide_drive_t *drive)
+{
+ return do_reset1(drive, 0);
+}
+EXPORT_SYMBOL(ide_do_reset);
Index: b/drivers/ide/ide-io.c
===================================================================
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -196,7 +196,7 @@ void ide_end_drive_cmd (ide_drive_t *dri
}
EXPORT_SYMBOL(ide_end_drive_cmd);
-static void ide_kill_rq(ide_drive_t *drive, struct request *rq)
+void ide_kill_rq(ide_drive_t *drive, struct request *rq)
{
if (rq->rq_disk) {
struct ide_driver *drv;
@@ -207,133 +207,6 @@ static void ide_kill_rq(ide_drive_t *dri
ide_end_request(drive, 0, 0);
}
-static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
-{
- ide_hwif_t *hwif = drive->hwif;
-
- if ((stat & ATA_BUSY) ||
- ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
- /* other bits are useless when BUSY */
- rq->errors |= ERROR_RESET;
- } else if (stat & ATA_ERR) {
- /* err has different meaning on cdrom and tape */
- if (err == ATA_ABORTED) {
- if ((drive->dev_flags & IDE_DFLAG_LBA) &&
- /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
- hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS)
- return ide_stopped;
- } else if ((err & BAD_CRC) == BAD_CRC) {
- /* UDMA crc error, just retry the operation */
- drive->crc_count++;
- } else if (err & (ATA_BBK | ATA_UNC)) {
- /* retries won't help these */
- rq->errors = ERROR_MAX;
- } else if (err & ATA_TRK0NF) {
- /* help it find track zero */
- rq->errors |= ERROR_RECAL;
- }
- }
-
- if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ &&
- (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
- int nsect = drive->mult_count ? drive->mult_count : 1;
-
- ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
- }
-
- if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
- ide_kill_rq(drive, rq);
- return ide_stopped;
- }
-
- if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
- rq->errors |= ERROR_RESET;
-
- if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
- ++rq->errors;
- return ide_do_reset(drive);
- }
-
- if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
- drive->special.b.recalibrate = 1;
-
- ++rq->errors;
-
- return ide_stopped;
-}
-
-static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
-{
- ide_hwif_t *hwif = drive->hwif;
-
- if ((stat & ATA_BUSY) ||
- ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
- /* other bits are useless when BUSY */
- rq->errors |= ERROR_RESET;
- } else {
- /* add decoding error stuff */
- }
-
- if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
- /* force an abort */
- hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);
-
- if (rq->errors >= ERROR_MAX) {
- ide_kill_rq(drive, rq);
- } else {
- if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
- ++rq->errors;
- return ide_do_reset(drive);
- }
- ++rq->errors;
- }
-
- return ide_stopped;
-}
-
-static ide_startstop_t
-__ide_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
-{
- if (drive->media == ide_disk)
- return ide_ata_error(drive, rq, stat, err);
- return ide_atapi_error(drive, rq, stat, err);
-}
-
-/**
- * ide_error - handle an error on the IDE
- * @drive: drive the error occurred on
- * @msg: message to report
- * @stat: status bits
- *
- * ide_error() takes action based on the error returned by the drive.
- * For normal I/O that may well include retries. We deal with
- * both new-style (taskfile) and old style command handling here.
- * In the case of taskfile command handling there is work left to
- * do
- */
-
-ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
-{
- struct request *rq;
- u8 err;
-
- err = ide_dump_status(drive, msg, stat);
-
- rq = drive->hwif->rq;
- if (rq == NULL)
- return ide_stopped;
-
- /* retry only "normal" I/O: */
- if (!blk_fs_request(rq)) {
- rq->errors = 1;
- ide_end_drive_cmd(drive, stat, err);
- return ide_stopped;
- }
-
- return __ide_error(drive, rq, stat, err);
-}
-EXPORT_SYMBOL_GPL(ide_error);
-
static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
{
tf->nsect = drive->sect;
Index: b/drivers/ide/ide-iops.c
===================================================================
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -446,8 +446,8 @@ int ide_config_drive_speed(ide_drive_t *
*
* See also ide_execute_command
*/
-static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
- unsigned int timeout, ide_expiry_t *expiry)
+void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
+ unsigned int timeout, ide_expiry_t *expiry)
{
ide_hwif_t *hwif = drive->hwif;
@@ -517,301 +517,6 @@ void ide_execute_pkt_cmd(ide_drive_t *dr
}
EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd);
-static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
-{
- struct request *rq = drive->hwif->rq;
-
- if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET)
- ide_end_request(drive, err ? err : 1, 0);
-}
-
-/* needed below */
-static ide_startstop_t do_reset1(ide_drive_t *, int);
-
-/*
- * atapi_reset_pollfunc() gets invoked to poll the interface for completion
- * every 50ms during an atapi drive reset operation. If the drive has not yet
- * responded, and we have not yet hit our maximum waiting time, then the timer
- * is restarted for another 50ms.
- */
-static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- u8 stat;
-
- SELECT_DRIVE(drive);
- udelay(10);
- stat = hwif->tp_ops->read_status(hwif);
-
- if (OK_STAT(stat, 0, ATA_BUSY))
- printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name);
- else {
- if (time_before(jiffies, hwif->poll_timeout)) {
- ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20,
- NULL);
- /* continue polling */
- return ide_started;
- }
- /* end of polling */
- hwif->polling = 0;
- printk(KERN_ERR "%s: ATAPI reset timed-out, status=0x%02x\n",
- drive->name, stat);
- /* do it the old fashioned way */
- return do_reset1(drive, 1);
- }
- /* done polling */
- hwif->polling = 0;
- ide_complete_drive_reset(drive, 0);
- return ide_stopped;
-}
-
-static void ide_reset_report_error(ide_hwif_t *hwif, u8 err)
-{
- static const char *err_master_vals[] =
- { NULL, "passed", "formatter device error",
- "sector buffer error", "ECC circuitry error",
- "controlling MPU error" };
-
- u8 err_master = err & 0x7f;
-
- printk(KERN_ERR "%s: reset: master: ", hwif->name);
- if (err_master && err_master < 6)
- printk(KERN_CONT "%s", err_master_vals[err_master]);
- else
- printk(KERN_CONT "error (0x%02x?)", err);
- if (err & 0x80)
- printk(KERN_CONT "; slave: failed");
- printk(KERN_CONT "\n");
-}
-
-/*
- * reset_pollfunc() gets invoked to poll the interface for completion every 50ms
- * during an ide reset operation. If the drives have not yet responded,
- * and we have not yet hit our maximum waiting time, then the timer is restarted
- * for another 50ms.
- */
-static ide_startstop_t reset_pollfunc(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
- u8 tmp;
- int err = 0;
-
- if (port_ops && port_ops->reset_poll) {
- err = port_ops->reset_poll(drive);
- if (err) {
- printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
- hwif->name, drive->name);
- goto out;
- }
- }
-
- tmp = hwif->tp_ops->read_status(hwif);
-
- if (!OK_STAT(tmp, 0, ATA_BUSY)) {
- if (time_before(jiffies, hwif->poll_timeout)) {
- ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
- /* continue polling */
- return ide_started;
- }
- printk(KERN_ERR "%s: reset timed-out, status=0x%02x\n",
- hwif->name, tmp);
- drive->failures++;
- err = -EIO;
- } else {
- tmp = ide_read_error(drive);
-
- if (tmp == 1) {
- printk(KERN_INFO "%s: reset: success\n", hwif->name);
- drive->failures = 0;
- } else {
- ide_reset_report_error(hwif, tmp);
- drive->failures++;
- err = -EIO;
- }
- }
-out:
- hwif->polling = 0; /* done polling */
- ide_complete_drive_reset(drive, err);
- return ide_stopped;
-}
-
-static void ide_disk_pre_reset(ide_drive_t *drive)
-{
- int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1;
-
- drive->special.all = 0;
- drive->special.b.set_geometry = legacy;
- drive->special.b.recalibrate = legacy;
-
- drive->mult_count = 0;
- drive->dev_flags &= ~IDE_DFLAG_PARKED;
-
- if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 &&
- (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0)
- drive->mult_req = 0;
-
- if (drive->mult_req != drive->mult_count)
- drive->special.b.set_multmode = 1;
-}
-
-static void pre_reset(ide_drive_t *drive)
-{
- const struct ide_port_ops *port_ops = drive->hwif->port_ops;
-
- if (drive->media == ide_disk)
- ide_disk_pre_reset(drive);
- else
- drive->dev_flags |= IDE_DFLAG_POST_RESET;
-
- if (drive->dev_flags & IDE_DFLAG_USING_DMA) {
- if (drive->crc_count)
- ide_check_dma_crc(drive);
- else
- ide_dma_off(drive);
- }
-
- if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) {
- if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) {
- drive->dev_flags &= ~IDE_DFLAG_UNMASK;
- drive->io_32bit = 0;
- }
- return;
- }
-
- if (port_ops && port_ops->pre_reset)
- port_ops->pre_reset(drive);
-
- if (drive->current_speed != 0xff)
- drive->desired_speed = drive->current_speed;
- drive->current_speed = 0xff;
-}
-
-/*
- * do_reset1() attempts to recover a confused drive by resetting it.
- * Unfortunately, resetting a disk drive actually resets all devices on
- * the same interface, so it can really be thought of as resetting the
- * interface rather than resetting the drive.
- *
- * ATAPI devices have their own reset mechanism which allows them to be
- * individually reset without clobbering other devices on the same interface.
- *
- * Unfortunately, the IDE interface does not generate an interrupt to let
- * us know when the reset operation has finished, so we must poll for this.
- * Equally poor, though, is the fact that this may a very long time to complete,
- * (up to 30 seconds worstcase). So, instead of busy-waiting here for it,
- * we set a timer to poll at 50ms intervals.
- */
-static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- const struct ide_port_ops *port_ops;
- ide_drive_t *tdrive;
- unsigned long flags, timeout;
- int i;
- DEFINE_WAIT(wait);
-
- spin_lock_irqsave(&hwif->lock, flags);
-
- /* We must not reset with running handlers */
- BUG_ON(hwif->handler != NULL);
-
- /* For an ATAPI device, first try an ATAPI SRST. */
- if (drive->media != ide_disk && !do_not_try_atapi) {
- pre_reset(drive);
- SELECT_DRIVE(drive);
- udelay(20);
- tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
- ndelay(400);
- hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
- hwif->polling = 1;
- __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
- spin_unlock_irqrestore(&hwif->lock, flags);
- return ide_started;
- }
-
- /* We must not disturb devices in the IDE_DFLAG_PARKED state. */
- do {
- unsigned long now;
-
- prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE);
- timeout = jiffies;
- ide_port_for_each_present_dev(i, tdrive, hwif) {
- if ((tdrive->dev_flags & IDE_DFLAG_PARKED) &&
- time_after(tdrive->sleep, timeout))
- timeout = tdrive->sleep;
- }
-
- now = jiffies;
- if (time_before_eq(timeout, now))
- break;
-
- spin_unlock_irqrestore(&hwif->lock, flags);
- timeout = schedule_timeout_uninterruptible(timeout - now);
- spin_lock_irqsave(&hwif->lock, flags);
- } while (timeout);
- finish_wait(&ide_park_wq, &wait);
-
- /*
- * First, reset any device state data we were maintaining
- * for any of the drives on this interface.
- */
- ide_port_for_each_dev(i, tdrive, hwif)
- pre_reset(tdrive);
-
- if (io_ports->ctl_addr == 0) {
- spin_unlock_irqrestore(&hwif->lock, flags);
- ide_complete_drive_reset(drive, -ENXIO);
- return ide_stopped;
- }
-
- /*
- * Note that we also set nIEN while resetting the device,
- * to mask unwanted interrupts from the interface during the reset.
- * However, due to the design of PC hardware, this will cause an
- * immediate interrupt due to the edge transition it produces.
- * This single interrupt gives us a "fast poll" for drives that
- * recover from reset very quickly, saving us the first 50ms wait time.
- *
- * TODO: add ->softreset method and stop abusing ->set_irq
- */
- /* set SRST and nIEN */
- tp_ops->set_irq(hwif, 4);
- /* more than enough time */
- udelay(10);
- /* clear SRST, leave nIEN (unless device is on the quirk list) */
- tp_ops->set_irq(hwif, drive->quirk_list == 2);
- /* more than enough time */
- udelay(10);
- hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
- hwif->polling = 1;
- __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
-
- /*
- * Some weird controller like resetting themselves to a strange
- * state when the disks are reset this way. At least, the Winbond
- * 553 documentation says that
- */
- port_ops = hwif->port_ops;
- if (port_ops && port_ops->resetproc)
- port_ops->resetproc(drive);
-
- spin_unlock_irqrestore(&hwif->lock, flags);
- return ide_started;
-}
-
-/*
- * ide_do_reset() is the entry point to the drive/interface reset code.
- */
-
-ide_startstop_t ide_do_reset(ide_drive_t *drive)
-{
- return do_reset1(drive, 0);
-}
-EXPORT_SYMBOL(ide_do_reset);
-
/*
* ide_wait_not_busy() waits for the currently selected device on the hwif
* to report a non-busy status, see comments in ide_probe_port().
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1144,11 +1144,14 @@ int generic_ide_ioctl(ide_drive_t *, str
extern int ide_vlb_clk;
extern int ide_pci_clk;
-extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs);
-int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
- int uptodate, int nr_sectors);
-
-extern void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry);
+int ide_end_request(ide_drive_t *, int, int);
+int ide_end_dequeued_request(ide_drive_t *, struct request *, int, int);
+void ide_kill_rq(ide_drive_t *, struct request *);
+
+void __ide_set_handler(ide_drive_t *, ide_handler_t *, unsigned int,
+ ide_expiry_t *);
+void ide_set_handler(ide_drive_t *, ide_handler_t *, unsigned int,
+ ide_expiry_t *);
void ide_execute_command(ide_drive_t *, u8, ide_handler_t *, unsigned int,
ide_expiry_t *);
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 0/6] ide: more core code housekeeping
2009-01-19 13:03 [PATCH 0/6] ide: more core code housekeeping Bartlomiej Zolnierkiewicz
` (5 preceding siblings ...)
2009-01-19 13:03 ` [PATCH 6/6] ide: move error handling code to ide-eh.c Bartlomiej Zolnierkiewicz
@ 2009-01-19 14:19 ` Sergei Shtylyov
6 siblings, 0 replies; 27+ messages in thread
From: Sergei Shtylyov @ 2009-01-19 14:19 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel
Bartlomiej Zolnierkiewicz wrote:
> SFF I/O code goes to ide-io-sff.c and error handling to ide-eh.c...
There's no such thing as SFF I/O code I'm afraid -- whatever libata
authors might think...
MBR, Sergei
^ permalink raw reply [flat|nested] 27+ messages in thread