summaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/Kconfig34
-rw-r--r--drivers/ide/Makefile2
-rw-r--r--drivers/ide/arm/bast-ide.c15
-rw-r--r--drivers/ide/arm/icside.c77
-rw-r--r--drivers/ide/arm/ide_arm.c18
-rw-r--r--drivers/ide/arm/palm_bk3710.c39
-rw-r--r--drivers/ide/arm/rapide.c10
-rw-r--r--drivers/ide/cris/Makefile3
-rw-r--r--drivers/ide/cris/ide-cris.c1081
-rw-r--r--drivers/ide/h8300/ide-h8300.c115
-rw-r--r--drivers/ide/ide-acpi.c30
-rw-r--r--drivers/ide/ide-cd.c631
-rw-r--r--drivers/ide/ide-cd_verbose.c2
-rw-r--r--drivers/ide/ide-dma.c151
-rw-r--r--drivers/ide/ide-floppy.c43
-rw-r--r--drivers/ide/ide-generic.c20
-rw-r--r--drivers/ide/ide-io.c96
-rw-r--r--drivers/ide/ide-iops.c428
-rw-r--r--drivers/ide/ide-lib.c28
-rw-r--r--drivers/ide/ide-pnp.c33
-rw-r--r--drivers/ide/ide-probe.c242
-rw-r--r--drivers/ide/ide-proc.c21
-rw-r--r--drivers/ide/ide-scan-pci.c2
-rw-r--r--drivers/ide/ide-tape.c1223
-rw-r--r--drivers/ide/ide-taskfile.c95
-rw-r--r--drivers/ide/ide.c450
-rw-r--r--drivers/ide/legacy/ali14xx.c44
-rw-r--r--drivers/ide/legacy/buddha.c16
-rw-r--r--drivers/ide/legacy/dtc2278.c41
-rw-r--r--drivers/ide/legacy/falconide.c33
-rw-r--r--drivers/ide/legacy/gayle.c20
-rw-r--r--drivers/ide/legacy/ht6560b.c57
-rw-r--r--drivers/ide/legacy/ide-4drives.c20
-rw-r--r--drivers/ide/legacy/ide-cs.c82
-rw-r--r--drivers/ide/legacy/ide_platform.c15
-rw-r--r--drivers/ide/legacy/macide.c6
-rw-r--r--drivers/ide/legacy/q40ide.c72
-rw-r--r--drivers/ide/legacy/qd65xx.c163
-rw-r--r--drivers/ide/legacy/umc8672.c41
-rw-r--r--drivers/ide/mips/au1xxx-ide.c147
-rw-r--r--drivers/ide/mips/swarm.c11
-rw-r--r--drivers/ide/pci/aec62xx.c36
-rw-r--r--drivers/ide/pci/alim15x3.c333
-rw-r--r--drivers/ide/pci/amd74xx.c15
-rw-r--r--drivers/ide/pci/atiixp.c24
-rw-r--r--drivers/ide/pci/cmd640.c134
-rw-r--r--drivers/ide/pci/cmd64x.c144
-rw-r--r--drivers/ide/pci/cs5520.c26
-rw-r--r--drivers/ide/pci/cs5530.c15
-rw-r--r--drivers/ide/pci/cs5535.c22
-rw-r--r--drivers/ide/pci/cy82c693.c20
-rw-r--r--drivers/ide/pci/delkin_cb.c16
-rw-r--r--drivers/ide/pci/hpt34x.c15
-rw-r--r--drivers/ide/pci/hpt366.c130
-rw-r--r--drivers/ide/pci/it8213.c22
-rw-r--r--drivers/ide/pci/it821x.c27
-rw-r--r--drivers/ide/pci/jmicron.c25
-rw-r--r--drivers/ide/pci/ns87415.c81
-rw-r--r--drivers/ide/pci/opti621.c23
-rw-r--r--drivers/ide/pci/pdc202xx_new.c31
-rw-r--r--drivers/ide/pci/pdc202xx_old.c126
-rw-r--r--drivers/ide/pci/piix.c14
-rw-r--r--drivers/ide/pci/sc1200.c36
-rw-r--r--drivers/ide/pci/scc_pata.c270
-rw-r--r--drivers/ide/pci/serverworks.c33
-rw-r--r--drivers/ide/pci/sgiioc4.c129
-rw-r--r--drivers/ide/pci/siimage.c683
-rw-r--r--drivers/ide/pci/sis5513.c30
-rw-r--r--drivers/ide/pci/sl82c105.c80
-rw-r--r--drivers/ide/pci/slc90e66.c14
-rw-r--r--drivers/ide/pci/tc86c001.c26
-rw-r--r--drivers/ide/pci/triflex.c11
-rw-r--r--drivers/ide/pci/trm290.c46
-rw-r--r--drivers/ide/pci/via82cxxx.c16
-rw-r--r--drivers/ide/ppc/mpc8xx.c36
-rw-r--r--drivers/ide/ppc/pmac.c94
-rw-r--r--drivers/ide/setup-pci.c101
77 files changed, 3306 insertions, 5235 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 3f9e10001e1..f702f9152ce 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -862,40 +862,6 @@ config BLK_DEV_IDE_BAST
Say Y here if you want to support the onboard IDE channels on the
Simtec BAST or the Thorcom VR1000
-config ETRAX_IDE
- tristate "ETRAX IDE support"
- depends on CRIS && BROKEN
- select BLK_DEV_IDEDMA
- help
- Enables the ETRAX IDE driver.
-
- You can't use parallel ports or SCSI ports at the same time.
-
-config ETRAX_IDE_DELAY
- int "Delay for drives to regain consciousness"
- depends on ETRAX_IDE && ETRAX_ARCH_V10
- default 15
- help
- Number of seconds to wait for IDE drives to spin up after an IDE
- reset.
-
-choice
- prompt "IDE reset pin"
- depends on ETRAX_IDE && ETRAX_ARCH_V10
- default ETRAX_IDE_PB7_RESET
-
-config ETRAX_IDE_PB7_RESET
- bool "Port_PB_Bit_7"
- help
- IDE reset on pin 7 on port B
-
-config ETRAX_IDE_G27_RESET
- bool "Port_G_Bit_27"
- help
- IDE reset on pin 27 on port G
-
-endchoice
-
config IDE_H8300
tristate "H8300 IDE support"
depends on H8300
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 571544c37bb..f94b679b611 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -35,7 +35,7 @@ ifeq ($(CONFIG_BLK_DEV_CMD640), y)
obj-y += cmd640-core.o
endif
-obj-$(CONFIG_BLK_DEV_IDE) += cris/ ppc/
+obj-$(CONFIG_BLK_DEV_IDE) += ppc/
obj-$(CONFIG_IDE_H8300) += h8300/
obj-$(CONFIG_IDE_GENERIC) += ide-generic.o
obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o
diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c
index a80b9574865..713cef20622 100644
--- a/drivers/ide/arm/bast-ide.c
+++ b/drivers/ide/arm/bast-ide.c
@@ -35,12 +35,12 @@ static int __init bastide_register(unsigned int base, unsigned int aux, int irq)
base += BAST_IDE_CS;
aux += BAST_IDE_CS;
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hw.io_ports[i] = (unsigned long)base;
+ for (i = 0; i <= 7; i++) {
+ hw.io_ports_array[i] = (unsigned long)base;
base += 0x20;
}
- hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20);
+ hw.io_ports.ctl_addr = aux + (6 * 0x20);
hw.irq = irq;
hwif = ide_find_port();
@@ -49,14 +49,9 @@ static int __init bastide_register(unsigned int base, unsigned int aux, int irq)
i = hwif->index;
- if (hwif->present)
- ide_unregister(i);
- else
- ide_init_port_data(hwif, i);
-
+ ide_init_port_data(hwif, i);
ide_init_port_hw(hwif, &hw);
- hwif->mmio = 1;
- hwif->quirkproc = NULL;
+ hwif->port_ops = NULL;
idx[0] = i;
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index fd12bbe93f1..061456914ca 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -191,6 +191,10 @@ static void icside_maskproc(ide_drive_t *drive, int mask)
local_irq_restore(flags);
}
+static const struct ide_port_ops icside_v6_no_dma_port_ops = {
+ .maskproc = icside_maskproc,
+};
+
#ifdef CONFIG_BLK_DEV_IDEDMA_ICS
/*
* SG-DMA support.
@@ -266,6 +270,11 @@ static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);
}
+static const struct ide_port_ops icside_v6_port_ops = {
+ .set_dma_mode = icside_set_dma_mode,
+ .maskproc = icside_maskproc,
+};
+
static void icside_dma_host_set(ide_drive_t *drive, int on)
{
}
@@ -375,25 +384,33 @@ static void icside_dma_lost_irq(ide_drive_t *drive)
printk(KERN_ERR "%s: IRQ lost\n", drive->name);
}
-static void icside_dma_init(ide_hwif_t *hwif)
+static int icside_dma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
{
hwif->dmatable_cpu = NULL;
hwif->dmatable_dma = 0;
- hwif->set_dma_mode = icside_set_dma_mode;
-
- hwif->dma_host_set = icside_dma_host_set;
- hwif->dma_setup = icside_dma_setup;
- hwif->dma_exec_cmd = icside_dma_exec_cmd;
- hwif->dma_start = icside_dma_start;
- hwif->ide_dma_end = icside_dma_end;
- hwif->ide_dma_test_irq = icside_dma_test_irq;
- hwif->dma_timeout = icside_dma_timeout;
- hwif->dma_lost_irq = icside_dma_lost_irq;
+
+ return 0;
}
+
+static const struct ide_dma_ops icside_v6_dma_ops = {
+ .dma_host_set = icside_dma_host_set,
+ .dma_setup = icside_dma_setup,
+ .dma_exec_cmd = icside_dma_exec_cmd,
+ .dma_start = icside_dma_start,
+ .dma_end = icside_dma_end,
+ .dma_test_irq = icside_dma_test_irq,
+ .dma_timeout = icside_dma_timeout,
+ .dma_lost_irq = icside_dma_lost_irq,
+};
#else
-#define icside_dma_init(hwif) (0)
+#define icside_v6_dma_ops NULL
#endif
+static int icside_dma_off_init(ide_hwif_t *hwif, const struct ide_port_info *d)
+{
+ return -EOPNOTSUPP;
+}
+
static ide_hwif_t *
icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *ec)
{
@@ -402,21 +419,22 @@ icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *e
hwif = ide_find_port();
if (hwif) {
- int i;
-
/*
* Ensure we're using MMIO
*/
default_hwif_mmiops(hwif);
- hwif->mmio = 1;
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hwif->io_ports[i] = port;
- port += 1 << info->stepping;
- }
- hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset;
+ hwif->io_ports.data_addr = port;
+ hwif->io_ports.error_addr = port + (1 << info->stepping);
+ hwif->io_ports.nsect_addr = port + (2 << info->stepping);
+ hwif->io_ports.lbal_addr = port + (3 << info->stepping);
+ hwif->io_ports.lbam_addr = port + (4 << info->stepping);
+ hwif->io_ports.lbah_addr = port + (5 << info->stepping);
+ hwif->io_ports.device_addr = port + (6 << info->stepping);
+ hwif->io_ports.status_addr = port + (7 << info->stepping);
+ hwif->io_ports.ctl_addr =
+ (unsigned long)base + info->ctrloffset;
hwif->irq = ec->irq;
- hwif->noprobe = 0;
hwif->chipset = ide_acorn;
hwif->gendev.parent = &ec->dev;
hwif->dev = &ec->dev;
@@ -462,9 +480,10 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
}
static const struct ide_port_info icside_v6_port_info __initdata = {
- .host_flags = IDE_HFLAG_SERIALIZE |
- IDE_HFLAG_NO_DMA | /* no SFF-style DMA */
- IDE_HFLAG_NO_AUTOTUNE,
+ .init_dma = icside_dma_off_init,
+ .port_ops = &icside_v6_no_dma_port_ops,
+ .dma_ops = &icside_v6_dma_ops,
+ .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO,
.mwdma_mask = ATA_MWDMA2,
.swdma_mask = ATA_SWDMA2,
};
@@ -526,21 +545,19 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
state->hwif[0] = hwif;
state->hwif[1] = mate;
- hwif->maskproc = icside_maskproc;
hwif->hwif_data = state;
hwif->config_data = (unsigned long)ioc_base;
hwif->select_data = sel;
- mate->maskproc = icside_maskproc;
mate->hwif_data = state;
mate->config_data = (unsigned long)ioc_base;
mate->select_data = sel | 1;
if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) {
- icside_dma_init(hwif);
- icside_dma_init(mate);
- } else
- d.mwdma_mask = d.swdma_mask = 0;
+ d.init_dma = icside_dma_init;
+ d.port_ops = &icside_v6_port_ops;
+ d.dma_ops = NULL;
+ }
idx[0] = hwif->index;
idx[1] = mate->index;
diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c
index 82643df7c49..4263ffd4ab2 100644
--- a/drivers/ide/arm/ide_arm.c
+++ b/drivers/ide/arm/ide_arm.c
@@ -14,6 +14,8 @@
#include <asm/mach-types.h>
#include <asm/irq.h>
+#define DRV_NAME "ide_arm"
+
#ifdef CONFIG_ARCH_CLPS7500
# include <asm/arch/hardware.h>
#
@@ -28,10 +30,24 @@ static int __init ide_arm_init(void)
{
ide_hwif_t *hwif;
hw_regs_t hw;
+ unsigned long base = IDE_ARM_IO, ctl = IDE_ARM_IO + 0x206;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+ if (!request_region(base, 8, DRV_NAME)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
+ DRV_NAME, base, base + 7);
+ return -EBUSY;
+ }
+
+ if (!request_region(ctl, 1, DRV_NAME)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
+ DRV_NAME, ctl);
+ release_region(base, 8);
+ return -EBUSY;
+ }
+
memset(&hw, 0, sizeof(hw));
- ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206);
+ ide_std_init_ports(&hw, base, ctl);
hw.irq = IDE_ARM_IRQ;
hwif = ide_find_port();
diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c
index 666df779a5f..96378ebfb31 100644
--- a/drivers/ide/arm/palm_bk3710.c
+++ b/drivers/ide/arm/palm_bk3710.c
@@ -317,17 +317,32 @@ static u8 __devinit palm_bk3710_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA80;
}
-static void __devinit palm_bk3710_init_hwif(ide_hwif_t *hwif)
+static int __devinit palm_bk3710_init_dma(ide_hwif_t *hwif,
+ const struct ide_port_info *d)
{
- hwif->set_pio_mode = palm_bk3710_set_pio_mode;
- hwif->set_dma_mode = palm_bk3710_set_dma_mode;
+ unsigned long base =
+ hwif->io_ports.data_addr - IDE_PALM_ATA_PRI_REG_OFFSET;
- hwif->cable_detect = palm_bk3710_cable_detect;
+ printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name);
+
+ if (ide_allocate_dma_engine(hwif))
+ return -1;
+
+ ide_setup_dma(hwif, base);
+
+ return 0;
}
+static const struct ide_port_ops palm_bk3710_ports_ops = {
+ .set_pio_mode = palm_bk3710_set_pio_mode,
+ .set_dma_mode = palm_bk3710_set_dma_mode,
+ .cable_detect = palm_bk3710_cable_detect,
+};
+
static const struct ide_port_info __devinitdata palm_bk3710_port_info = {
- .init_hwif = palm_bk3710_init_hwif,
- .host_flags = IDE_HFLAG_NO_DMA, /* hack (no PCI) */
+ .init_dma = palm_bk3710_init_dma,
+ .port_ops = &palm_bk3710_ports_ops,
+ .host_flags = IDE_HFLAG_MMIO,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA4, /* (input clk 99MHz) */
.mwdma_mask = ATA_MWDMA2,
@@ -372,8 +387,8 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev)
pribase = mem->start + IDE_PALM_ATA_PRI_REG_OFFSET;
for (i = 0; i < IDE_NR_PORTS - 2; i++)
- hw.io_ports[i] = pribase + i;
- hw.io_ports[IDE_CONTROL_OFFSET] = mem->start +
+ hw.io_ports_array[i] = pribase + i;
+ hw.io_ports.ctl_addr = mem->start +
IDE_PALM_ATA_PRI_CTL_OFFSET;
hw.irq = irq->start;
hw.chipset = ide_palm3710;
@@ -384,18 +399,12 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev)
i = hwif->index;
- if (hwif->present)
- ide_unregister(i);
- else
- ide_init_port_data(hwif, i);
-
+ ide_init_port_data(hwif, i);
ide_init_port_hw(hwif, &hw);
hwif->mmio = 1;
default_hwif_mmiops(hwif);
- ide_setup_dma(hwif, mem->start);
-
idx[0] = i;
ide_device_add(idx, &palm_bk3710_port_info);
diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c
index 2c3d0ec91dc..1747b235877 100644
--- a/drivers/ide/arm/rapide.c
+++ b/drivers/ide/arm/rapide.c
@@ -17,11 +17,11 @@ static void rapide_setup_ports(hw_regs_t *hw, void __iomem *base,
unsigned long port = (unsigned long)base;
int i;
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hw->io_ports[i] = port;
+ for (i = 0; i <= 7; i++) {
+ hw->io_ports_array[i] = port;
port += sz;
}
- hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
+ hw->io_ports.ctl_addr = (unsigned long)ctrl;
hw->irq = irq;
}
@@ -53,7 +53,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
ide_init_port_hw(hwif, &hw);
- hwif->mmio = 1;
+ hwif->host_flags = IDE_HFLAG_MMIO;
default_hwif_mmiops(hwif);
idx[0] = hwif->index;
@@ -76,7 +76,7 @@ static void __devexit rapide_remove(struct expansion_card *ec)
ecard_set_drvdata(ec, NULL);
- ide_unregister(hwif->index);
+ ide_unregister(hwif);
ecard_release_resources(ec);
}
diff --git a/drivers/ide/cris/Makefile b/drivers/ide/cris/Makefile
deleted file mode 100644
index 20b95960531..00000000000
--- a/drivers/ide/cris/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-EXTRA_CFLAGS += -Idrivers/ide
-
-obj-$(CONFIG_IDE_ETRAX) += ide-cris.o
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
deleted file mode 100644
index 790a7759d45..00000000000
--- a/drivers/ide/cris/ide-cris.c
+++ /dev/null
@@ -1,1081 +0,0 @@
-/*
- * Etrax specific IDE functions, like init and PIO-mode setting etc.
- * Almost the entire ide.c is used for the rest of the Etrax ATA driver.
- * Copyright (c) 2000-2005 Axis Communications AB
- *
- * Authors: Bjorn Wesen (initial version)
- * Mikael Starvik (crisv32 port)
- */
-
-/* Regarding DMA:
- *
- * There are two forms of DMA - "DMA handshaking" between the interface and the drive,
- * and DMA between the memory and the interface. We can ALWAYS use the latter, since it's
- * something built-in in the Etrax. However only some drives support the DMA-mode handshaking
- * on the ATA-bus. The normal PC driver and Triton interface disables memory-if DMA when the
- * device can't do DMA handshaking for some stupid reason. We don't need to do that.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-/* number of DMA descriptors */
-#define MAX_DMA_DESCRS 64
-
-/* number of times to retry busy-flags when reading/writing IDE-registers
- * this can't be too high because a hung harddisk might cause the watchdog
- * to trigger (sometimes INB and OUTB are called with irq's disabled)
- */
-
-#define IDE_REGISTER_TIMEOUT 300
-
-#define LOWDB(x)
-#define D(x)
-
-enum /* Transfer types */
-{
- TYPE_PIO,
- TYPE_DMA,
- TYPE_UDMA
-};
-
-/* CRISv32 specifics */
-#ifdef CONFIG_ETRAX_ARCH_V32
-#include <asm/arch/hwregs/ata_defs.h>
-#include <asm/arch/hwregs/dma_defs.h>
-#include <asm/arch/hwregs/dma.h>
-#include <asm/arch/pinmux.h>
-
-#define ATA_UDMA2_CYC 2
-#define ATA_UDMA2_DVS 3
-#define ATA_UDMA1_CYC 2
-#define ATA_UDMA1_DVS 4
-#define ATA_UDMA0_CYC 4
-#define ATA_UDMA0_DVS 6
-#define ATA_DMA2_STROBE 7
-#define ATA_DMA2_HOLD 1
-#define ATA_DMA1_STROBE 8
-#define ATA_DMA1_HOLD 3
-#define ATA_DMA0_STROBE 25
-#define ATA_DMA0_HOLD 19
-#define ATA_PIO4_SETUP 3
-#define ATA_PIO4_STROBE 7
-#define ATA_PIO4_HOLD 1
-#define ATA_PIO3_SETUP 3
-#define ATA_PIO3_STROBE 9
-#define ATA_PIO3_HOLD 3
-#define ATA_PIO2_SETUP 3
-#define ATA_PIO2_STROBE 13
-#define ATA_PIO2_HOLD 5
-#define ATA_PIO1_SETUP 5
-#define ATA_PIO1_STROBE 23
-#define ATA_PIO1_HOLD 9
-#define ATA_PIO0_SETUP 9
-#define ATA_PIO0_STROBE 39
-#define ATA_PIO0_HOLD 9
-
-int
-cris_ide_ack_intr(ide_hwif_t* hwif)
-{
- reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2,
- int, hwif->io_ports[0]);
- REG_WR_INT(ata, regi_ata, rw_ack_intr, 1 << ctrl2.sel);
- return 1;
-}
-
-static inline int
-cris_ide_busy(void)
-{
- reg_ata_rs_stat_data stat_data;
- stat_data = REG_RD(ata, regi_ata, rs_stat_data);
- return stat_data.busy;
-}
-
-static inline int
-cris_ide_ready(void)
-{
- return !cris_ide_busy();
-}
-
-static inline int
-cris_ide_data_available(unsigned short* data)
-{
- reg_ata_rs_stat_data stat_data;
- stat_data = REG_RD(ata, regi_ata, rs_stat_data);
- *data = stat_data.data;
- return stat_data.dav;
-}
-
-static void
-cris_ide_write_command(unsigned long command)
-{
- REG_WR_INT(ata, regi_ata, rw_ctrl2, command); /* write data to the drive's register */
-}
-
-static void
-cris_ide_set_speed(int type, int setup, int strobe, int hold)
-{
- reg_ata_rw_ctrl0 ctrl0 = REG_RD(ata, regi_ata, rw_ctrl0);
- reg_ata_rw_ctrl1 ctrl1 = REG_RD(ata, regi_ata, rw_ctrl1);
-
- if (type == TYPE_PIO) {
- ctrl0.pio_setup = setup;
- ctrl0.pio_strb = strobe;
- ctrl0.pio_hold = hold;
- } else if (type == TYPE_DMA) {
- ctrl0.dma_strb = strobe;
- ctrl0.dma_hold = hold;
- } else if (type == TYPE_UDMA) {
- ctrl1.udma_tcyc = setup;
- ctrl1.udma_tdvs = strobe;
- }
- REG_WR(ata, regi_ata, rw_ctrl0, ctrl0);
- REG_WR(ata, regi_ata, rw_ctrl1, ctrl1);
-}
-
-static unsigned long
-cris_ide_base_address(int bus)
-{
- reg_ata_rw_ctrl2 ctrl2 = {0};
- ctrl2.sel = bus;
- return REG_TYPE_CONV(int, reg_ata_rw_ctrl2, ctrl2);
-}
-
-static unsigned long
-cris_ide_reg_addr(unsigned long addr, int cs0, int cs1)
-{
- reg_ata_rw_ctrl2 ctrl2 = {0};
- ctrl2.addr = addr;
- ctrl2.cs1 = cs1;
- ctrl2.cs0 = cs0;
- return REG_TYPE_CONV(int, reg_ata_rw_ctrl2, ctrl2);
-}
-
-static __init void
-cris_ide_reset(unsigned val)
-{
- reg_ata_rw_ctrl0 ctrl0 = {0};
- ctrl0.rst = val ? regk_ata_active : regk_ata_inactive;
- REG_WR(ata, regi_ata, rw_ctrl0, ctrl0);
-}
-
-static __init void
-cris_ide_init(void)
-{
- reg_ata_rw_ctrl0 ctrl0 = {0};
- reg_ata_rw_intr_mask intr_mask = {0};
-
- ctrl0.en = regk_ata_yes;
- REG_WR(ata, regi_ata, rw_ctrl0, ctrl0);
-
- intr_mask.bus0 = regk_ata_yes;
- intr_mask.bus1 = regk_ata_yes;
- intr_mask.bus2 = regk_ata_yes;
- intr_mask.bus3 = regk_ata_yes;
-
- REG_WR(ata, regi_ata, rw_intr_mask, intr_mask);
-
- crisv32_request_dma(2, "ETRAX FS built-in ATA", DMA_VERBOSE_ON_ERROR, 0, dma_ata);
- crisv32_request_dma(3, "ETRAX FS built-in ATA", DMA_VERBOSE_ON_ERROR, 0, dma_ata);
-
- crisv32_pinmux_alloc_fixed(pinmux_ata);
- crisv32_pinmux_alloc_fixed(pinmux_ata0);
- crisv32_pinmux_alloc_fixed(pinmux_ata1);
- crisv32_pinmux_alloc_fixed(pinmux_ata2);
- crisv32_pinmux_alloc_fixed(pinmux_ata3);
-
- DMA_RESET(regi_dma2);
- DMA_ENABLE(regi_dma2);
- DMA_RESET(regi_dma3);
- DMA_ENABLE(regi_dma3);
-
- DMA_WR_CMD (regi_dma2, regk_dma_set_w_size2);
- DMA_WR_CMD (regi_dma3, regk_dma_set_w_size2);
-}
-
-static dma_descr_context mycontext __attribute__ ((__aligned__(32)));
-
-#define cris_dma_descr_type dma_descr_data
-#define cris_pio_read regk_ata_rd
-#define cris_ultra_mask 0x7
-#define MAX_DESCR_SIZE 0xffffffffUL
-
-static unsigned long
-cris_ide_get_reg(unsigned long reg)
-{
- return (reg & 0x0e000000) >> 25;
-}
-
-static void
-cris_ide_fill_descriptor(cris_dma_descr_type *d, void* buf, unsigned int len, int last)
-{
- d->buf = (char*)virt_to_phys(buf);
- d->after = d->buf + len;
- d->eol = last;
-}
-
-static void
-cris_ide_start_dma(ide_drive_t *drive, cris_dma_descr_type *d, int dir,int type,int len)
-{
- ide_hwif_t *hwif = drive->hwif;
-
- reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2, int,
- hwif->io_ports[IDE_DATA_OFFSET]);
- reg_ata_rw_trf_cnt trf_cnt = {0};
-
- mycontext.saved_data = (dma_descr_data*)virt_to_phys(d);
- mycontext.saved_data_buf = d->buf;
- /* start the dma channel */
- DMA_START_CONTEXT(dir ? regi_dma3 : regi_dma2, virt_to_phys(&mycontext));
-
- /* initiate a multi word dma read using PIO handshaking */
- trf_cnt.cnt = len >> 1;
- /* Due to a "feature" the transfer count has to be one extra word for UDMA. */
- if (type == TYPE_UDMA)
- trf_cnt.cnt++;
- REG_WR(ata, regi_ata, rw_trf_cnt, trf_cnt);
-
- ctrl2.rw = dir ? regk_ata_rd : regk_ata_wr;
- ctrl2.trf_mode = regk_ata_dma;
- ctrl2.hsh = type == TYPE_PIO ? regk_ata_pio :
- type == TYPE_DMA ? regk_ata_dma : regk_ata_udma;
- ctrl2.multi = regk_ata_yes;
- ctrl2.dma_size = regk_ata_word;
- REG_WR(ata, regi_ata, rw_ctrl2, ctrl2);
-}
-
-static void
-cris_ide_wait_dma(int dir)
-{
- reg_dma_rw_stat status;
- do
- {
- status = REG_RD(dma, dir ? regi_dma3 : regi_dma2, rw_stat);
- } while(status.list_state != regk_dma_data_at_eol);
-}
-
-static int cris_dma_test_irq(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- int intr = REG_RD_INT(ata, regi_ata, r_intr);
-
- reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2, int,
- hwif->io_ports[IDE_DATA_OFFSET]);
-
- return intr & (1 << ctrl2.sel) ? 1 : 0;
-}
-
-static void cris_ide_initialize_dma(int dir)
-{
-}
-
-#else
-/* CRISv10 specifics */
-#include <asm/arch/svinto.h>
-#include <asm/arch/io_interface_mux.h>
-
-/* PIO timing (in R_ATA_CONFIG)
- *
- * _____________________________
- * ADDRESS : ________/
- *
- * _______________
- * DIOR : ____________/ \__________
- *
- * _______________
- * DATA : XXXXXXXXXXXXXXXX_______________XXXXXXXX
- *
- *
- * DIOR is unbuffered while address and data is buffered.
- * This creates two problems:
- * 1. The DIOR pulse is to early (because it is unbuffered)
- * 2. The rise time of DIOR is long
- *
- * There are at least three different plausible solutions
- * 1. Use a pad capable of larger currents in Etrax
- * 2. Use an external buffer
- * 3. Make the strobe pulse longer
- *
- * Some of the strobe timings below are modified to compensate
- * for this. This implies a slight performance decrease.
- *
- * THIS SHOULD NEVER BE CHANGED!
- *
- * TODO: Is this true for the latest LX boards still ?
- */
-
-#define ATA_UDMA2_CYC 0 /* No UDMA supported, just to make it compile. */
-#define ATA_UDMA2_DVS 0
-#define ATA_UDMA1_CYC 0
-#define ATA_UDMA1_DVS 0
-#define ATA_UDMA0_CYC 0
-#define ATA_UDMA0_DVS 0
-#define ATA_DMA2_STROBE 4
-#define ATA_DMA2_HOLD 0
-#define ATA_DMA1_STROBE 4
-#define ATA_DMA1_HOLD 1
-#define ATA_DMA0_STROBE 12
-#define ATA_DMA0_HOLD 9
-#define ATA_PIO4_SETUP 1
-#define ATA_PIO4_STROBE 5
-#define ATA_PIO4_HOLD 0
-#define ATA_PIO3_SETUP 1
-#define ATA_PIO3_STROBE 5
-#define ATA_PIO3_HOLD 1
-#define ATA_PIO2_SETUP 1
-#define ATA_PIO2_STROBE 6
-#define ATA_PIO2_HOLD 2
-#define ATA_PIO1_SETUP 2
-#define ATA_PIO1_STROBE 11
-#define ATA_PIO1_HOLD 4
-#define ATA_PIO0_SETUP 4
-#define ATA_PIO0_STROBE 19
-#define ATA_PIO0_HOLD 4
-
-int
-cris_ide_ack_intr(ide_hwif_t* hwif)
-{
- return 1;
-}
-
-static inline int
-cris_ide_busy(void)
-{
- return *R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy) ;
-}
-
-static inline int
-cris_ide_ready(void)
-{
- return *R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, tr_rdy) ;
-}
-
-static inline int
-cris_ide_data_available(unsigned short* data)
-{
- unsigned long status = *R_ATA_STATUS_DATA;
- *data = (unsigned short)status;
- return status & IO_MASK(R_ATA_STATUS_DATA, dav);
-}
-
-static void
-cris_ide_write_command(unsigned long command)
-{
- *R_ATA_CTRL_DATA = command;
-}
-
-static void
-cris_ide_set_speed(int type, int setup, int strobe, int hold)
-{
- static int pio_setup = ATA_PIO4_SETUP;
- static int pio_strobe = ATA_PIO4_STROBE;
- static int pio_hold = ATA_PIO4_HOLD;
- static int dma_strobe = ATA_DMA2_STROBE;
- static int dma_hold = ATA_DMA2_HOLD;
-
- if (type == TYPE_PIO) {
- pio_setup = setup;
- pio_strobe = strobe;
- pio_hold = hold;
- } else if (type == TYPE_DMA) {
- dma_strobe = strobe;
- dma_hold = hold;
- }
- *R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable, 1 ) |
- IO_FIELD( R_ATA_CONFIG, dma_strobe, dma_strobe ) |
- IO_FIELD( R_ATA_CONFIG, dma_hold, dma_hold ) |
- IO_FIELD( R_ATA_CONFIG, pio_setup, pio_setup ) |
- IO_FIELD( R_ATA_CONFIG, pio_strobe, pio_strobe ) |
- IO_FIELD( R_ATA_CONFIG, pio_hold, pio_hold ) );
-}
-
-static unsigned long
-cris_ide_base_address(int bus)
-{
- return IO_FIELD(R_ATA_CTRL_DATA, sel, bus);
-}
-
-static unsigned long
-cris_ide_reg_addr(unsigned long addr, int cs0, int cs1)
-{
- return IO_FIELD(R_ATA_CTRL_DATA, addr, addr) |
- IO_FIELD(R_ATA_CTRL_DATA, cs0, cs0) |
- IO_FIELD(R_ATA_CTRL_DATA, cs1, cs1);
-}
-
-static __init void
-cris_ide_reset(unsigned val)
-{
-#ifdef CONFIG_ETRAX_IDE_G27_RESET
- REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, val);
-#endif
-#ifdef CONFIG_ETRAX_IDE_PB7_RESET
- port_pb_dir_shadow = port_pb_dir_shadow |
- IO_STATE(R_PORT_PB_DIR, dir7, output);
- *R_PORT_PB_DIR = port_pb_dir_shadow;
- REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 7, val);
-#endif
-}
-
-static __init void
-cris_ide_init(void)
-{
- volatile unsigned int dummy;
-
- *R_ATA_CTRL_DATA = 0;
- *R_ATA_TRANSFER_CNT = 0;
- *R_ATA_CONFIG = 0;
-
- if (cris_request_io_interface(if_ata, "ETRAX100LX IDE")) {
- printk(KERN_CRIT "ide: Failed to get IO interface\n");
- return;
- } else if (cris_request_dma(ATA_TX_DMA_NBR,
- "ETRAX100LX IDE TX",
- DMA_VERBOSE_ON_ERROR,
- dma_ata)) {
- cris_free_io_interface(if_ata);
- printk(KERN_CRIT "ide: Failed to get Tx DMA channel\n");
- return;
- } else if (cris_request_dma(ATA_RX_DMA_NBR,
- "ETRAX100LX IDE RX",
- DMA_VERBOSE_ON_ERROR,
- dma_ata)) {
- cris_free_dma(ATA_TX_DMA_NBR, "ETRAX100LX IDE Tx");
- cris_free_io_interface(if_ata);
- printk(KERN_CRIT "ide: Failed to get Rx DMA channel\n");
- return;
- }
-
- /* make a dummy read to set the ata controller in a proper state */
- dummy = *R_ATA_STATUS_DATA;
-
- *R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable, 1 ));
- *R_ATA_CTRL_DATA = ( IO_STATE( R_ATA_CTRL_DATA, rw, read) |
- IO_FIELD( R_ATA_CTRL_DATA, addr, 1 ) );
-
- while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag*/
-
- *R_IRQ_MASK0_SET = ( IO_STATE( R_IRQ_MASK0_SET, ata_irq0, set ) |
- IO_STATE( R_IRQ_MASK0_SET, ata_irq1, set ) |
- IO_STATE( R_IRQ_MASK0_SET, ata_irq2, set ) |
- IO_STATE( R_IRQ_MASK0_SET, ata_irq3, set ) );
-
- /* reset the dma channels we will use */
-
- RESET_DMA(ATA_TX_DMA_NBR);
- RESET_DMA(ATA_RX_DMA_NBR);
- WAIT_DMA(ATA_TX_DMA_NBR);
- WAIT_DMA(ATA_RX_DMA_NBR);
-}
-
-#define cris_dma_descr_type etrax_dma_descr
-#define cris_pio_read IO_STATE(R_ATA_CTRL_DATA, rw, read)
-#define cris_ultra_mask 0x0
-#define MAX_DESCR_SIZE 0x10000UL
-
-static unsigned long
-cris_ide_get_reg(unsigned long reg)
-{
- return (reg & 0x0e000000) >> 25;
-}
-
-static void
-cris_ide_fill_descriptor(cris_dma_descr_type *d, void* buf, unsigned int len, int last)
-{
- d->buf = virt_to_phys(buf);
- d->sw_len = len == MAX_DESCR_SIZE ? 0 : len;
- if (last)
- d->ctrl |= d_eol;
-}
-
-static void cris_ide_start_dma(ide_drive_t *drive, cris_dma_descr_type *d, int dir, int type, int len)
-{
- unsigned long cmd;
-
- if (dir) {
- /* need to do this before RX DMA due to a chip bug
- * it is enough to just flush the part of the cache that
- * corresponds to the buffers we start, but since HD transfers
- * usually are more than 8 kB, it is easier to optimize for the
- * normal case and just flush the entire cache. its the only
- * way to be sure! (OB movie quote)
- */
- flush_etrax_cache();
- *R_DMA_CH3_FIRST = virt_to_phys(d);
- *R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, start);
-
- } else {
- *R_DMA_CH2_FIRST = virt_to_phys(d);
- *R_DMA_CH2_CMD = IO_STATE(R_DMA_CH2_CMD, cmd, start);
- }
-
- /* initiate a multi word dma read using DMA handshaking */
-
- *R_ATA_TRANSFER_CNT =
- IO_FIELD(R_ATA_TRANSFER_CNT, count, len >> 1);
-
- cmd = dir ? IO_STATE(R_ATA_CTRL_DATA, rw, read) : IO_STATE(R_ATA_CTRL_DATA, rw, write);
- cmd |= type == TYPE_PIO ? IO_STATE(R_ATA_CTRL_DATA, handsh, pio) :
- IO_STATE(R_ATA_CTRL_DATA, handsh, dma);
- *R_ATA_CTRL_DATA =
- cmd |
- IO_FIELD(R_ATA_CTRL_DATA, data,
- drive->hwif->io_ports[IDE_DATA_OFFSET]) |
- IO_STATE(R_ATA_CTRL_DATA, src_dst, dma) |
- IO_STATE(R_ATA_CTRL_DATA, multi, on) |
- IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
-}
-
-static void
-cris_ide_wait_dma(int dir)
-{
- if (dir)
- WAIT_DMA(ATA_RX_DMA_NBR);
- else
- WAIT_DMA(ATA_TX_DMA_NBR);
-}
-
-static int cris_dma_test_irq(ide_drive_t *drive)
-{
- int intr = *R_IRQ_MASK0_RD;
- int bus = IO_EXTRACT(R_ATA_CTRL_DATA, sel,
- drive->hwif->io_ports[IDE_DATA_OFFSET]);
-
- return intr & (1 << (bus + IO_BITNR(R_IRQ_MASK0_RD, ata_irq0))) ? 1 : 0;
-}
-
-
-static void cris_ide_initialize_dma(int dir)
-{
- if (dir)
- {
- RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
- WAIT_DMA(ATA_RX_DMA_NBR);
- }
- else
- {
- RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
- WAIT_DMA(ATA_TX_DMA_NBR);
- }
-}
-
-#endif
-
-void
-cris_ide_outw(unsigned short data, unsigned long reg) {
- int timeleft;
-
- LOWDB(printk("ow: data 0x%x, reg 0x%x\n", data, reg));
-
- /* note the lack of handling any timeouts. we stop waiting, but we don't
- * really notify anybody.
- */
-
- timeleft = IDE_REGISTER_TIMEOUT;
- /* wait for busy flag */
- do {
- timeleft--;
- } while(timeleft && cris_ide_busy());
-
- /*
- * Fall through at a timeout, so the ongoing command will be
- * aborted by the write below, which is expected to be a dummy
- * command to the command register. This happens when a faulty
- * drive times out on a command. See comment on timeout in
- * INB.
- */
- if(!timeleft)
- printk("ATA timeout reg 0x%lx := 0x%x\n", reg, data);
-
- cris_ide_write_command(reg|data); /* write data to the drive's register */
-
- timeleft = IDE_REGISTER_TIMEOUT;
- /* wait for transmitter ready */
- do {
- timeleft--;
- } while(timeleft && !cris_ide_ready());
-}
-
-void
-cris_ide_outb(unsigned char data, unsigned long reg)
-{
- cris_ide_outw(data, reg);
-}
-
-void
-cris_ide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port)
-{
- cris_ide_outw(addr, port);
-}
-
-unsigned short
-cris_ide_inw(unsigned long reg) {
- int timeleft;
- unsigned short val;
-
- timeleft = IDE_REGISTER_TIMEOUT;
- /* wait for busy flag */
- do {
- timeleft--;
- } while(timeleft && cris_ide_busy());
-
- if(!timeleft) {
- /*
- * If we're asked to read the status register, like for
- * example when a command does not complete for an
- * extended time, but the ATA interface is stuck in a
- * busy state at the *ETRAX* ATA interface level (as has
- * happened repeatedly with at least one bad disk), then
- * the best thing to do is to pretend that we read
- * "busy" in the status register, so the IDE driver will
- * time-out, abort the ongoing command and perform a
- * reset sequence. Note that the subsequent OUT_BYTE
- * call will also timeout on busy, but as long as the
- * write is still performed, everything will be fine.
- */
- if (cris_ide_get_reg(reg) == IDE_STATUS_OFFSET)
- return BUSY_STAT;
- else
- /* For other rare cases we assume 0 is good enough. */
- return 0;
- }
-
- cris_ide_write_command(reg | cris_pio_read);
-
- timeleft = IDE_REGISTER_TIMEOUT;
- /* wait for available */
- do {
- timeleft--;
- } while(timeleft && !cris_ide_data_available(&val));
-
- if(!timeleft)
- return 0;
-
- LOWDB(printk("inb: 0x%x from reg 0x%x\n", val & 0xff, reg));
-
- return val;
-}
-
-unsigned char
-cris_ide_inb(unsigned long reg)
-{
- return (unsigned char)cris_ide_inw(reg);
-}
-
-static int cris_dma_end (ide_drive_t *drive);
-static int cris_dma_setup (ide_drive_t *drive);
-static void cris_dma_exec_cmd (ide_drive_t *drive, u8 command);
-static int cris_dma_test_irq(ide_drive_t *drive);
-static void cris_dma_start(ide_drive_t *drive);
-static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int);
-static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int);
-static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
-static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
-
-static void cris_dma_host_set(ide_drive_t *drive, int on)
-{
-}
-
-static void cris_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- int setup, strobe, hold;
-
- switch(pio)
- {
- case 0:
- setup = ATA_PIO0_SETUP;
- strobe = ATA_PIO0_STROBE;
- hold = ATA_PIO0_HOLD;
- break;
- case 1:
- setup = ATA_PIO1_SETUP;
- strobe = ATA_PIO1_STROBE;
- hold = ATA_PIO1_HOLD;
- break;
- case 2:
- setup = ATA_PIO2_SETUP;
- strobe = ATA_PIO2_STROBE;
- hold = ATA_PIO2_HOLD;
- break;
- case 3:
- setup = ATA_PIO3_SETUP;
- strobe = ATA_PIO3_STROBE;
- hold = ATA_PIO3_HOLD;
- break;
- case 4:
- setup = ATA_PIO4_SETUP;
- strobe = ATA_PIO4_STROBE;
- hold = ATA_PIO4_HOLD;
- break;
- default:
- return;
- }
-
- cris_ide_set_speed(TYPE_PIO, setup, strobe, hold);
-}
-
-static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed)
-{
- int cyc = 0, dvs = 0, strobe = 0, hold = 0;
-
- switch(speed)
- {
- case XFER_UDMA_0:
- cyc = ATA_UDMA0_CYC;
- dvs = ATA_UDMA0_DVS;
- break;
- case XFER_UDMA_1:
- cyc = ATA_UDMA1_CYC;
- dvs = ATA_UDMA1_DVS;
- break;
- case XFER_UDMA_2:
- cyc = ATA_UDMA2_CYC;
- dvs = ATA_UDMA2_DVS;
- break;
- case XFER_MW_DMA_0:
- strobe = ATA_DMA0_STROBE;
- hold = ATA_DMA0_HOLD;
- break;
- case XFER_MW_DMA_1:
- strobe = ATA_DMA1_STROBE;
- hold = ATA_DMA1_HOLD;
- break;
- case XFER_MW_DMA_2:
- strobe = ATA_DMA2_STROBE;
- hold = ATA_DMA2_HOLD;
- break;
- }
-
- if (speed >= XFER_UDMA_0)
- cris_ide_set_speed(TYPE_UDMA, cyc, dvs, 0);
- else
- cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);
-}
-
-static void __init cris_setup_ports(hw_regs_t *hw, unsigned long base)
-{
- int i;
-
- memset(hw, 0, sizeof(*hw));
-
- for (i = 0; i <= 7; i++)
- hw->io_ports[i] = base + cris_ide_reg_addr(i, 0, 1);
-
- /*
- * the IDE control register is at ATA address 6,
- * with CS1 active instead of CS0
- */
- hw->io_ports[IDE_CONTROL_OFFSET] = base + cris_ide_reg_addr(6, 1, 0);
-
- hw->irq = ide_default_irq(0);
- hw->ack_intr = cris_ide_ack_intr;
-}
-
-static const struct ide_port_info cris_port_info __initdata = {
- .chipset = ide_etrax100,
- .host_flags = IDE_HFLAG_NO_ATAPI_DMA |
- IDE_HFLAG_NO_DMA, /* no SFF-style DMA */
- .pio_mask = ATA_PIO4,
- .udma_mask = cris_ultra_mask,
- .mwdma_mask = ATA_MWDMA2,
-};
-
-static int __init init_e100_ide(void)
-{
- hw_regs_t hw;
- int h;
- u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-
- printk("ide: ETRAX FS built-in ATA DMA controller\n");
-
- for (h = 0; h < 4; h++) {
- ide_hwif_t *hwif = NULL;
-
- cris_setup_ports(&hw, cris_ide_base_address(h));
-
- hwif = ide_find_port();
- if (hwif == NULL)
- continue;
- ide_init_port_data(hwif, hwif->index);
- ide_init_port_hw(hwif, &hw);
- hwif->mmio = 1;
- hwif->set_pio_mode = &cris_set_pio_mode;
- hwif->set_dma_mode = &cris_set_dma_mode;
- hwif->ata_input_data = &cris_ide_input_data;
- hwif->ata_output_data = &cris_ide_output_data;
- hwif->atapi_input_bytes = &cris_atapi_input_bytes;
- hwif->atapi_output_bytes = &cris_atapi_output_bytes;
- hwif->dma_host_set = &cris_dma_host_set;
- hwif->ide_dma_end = &cris_dma_end;
- hwif->dma_setup = &cris_dma_setup;
- hwif->dma_exec_cmd = &cris_dma_exec_cmd;
- hwif->ide_dma_test_irq = &cris_dma_test_irq;
- hwif->dma_start = &cris_dma_start;
- hwif->OUTB = &cris_ide_outb;
- hwif->OUTW = &cris_ide_outw;
- hwif->OUTBSYNC = &cris_ide_outbsync;
- hwif->INB = &cris_ide_inb;
- hwif->INW = &cris_ide_inw;
- hwif->cbl = ATA_CBL_PATA40;
-
- idx[h] = hwif->index;
- }
-
- /* Reset pulse */
- cris_ide_reset(0);
- udelay(25);
- cris_ide_reset(1);
-
- cris_ide_init();
-
- cris_ide_set_speed(TYPE_PIO, ATA_PIO4_SETUP, ATA_PIO4_STROBE, ATA_PIO4_HOLD);
- cris_ide_set_speed(TYPE_DMA, 0, ATA_DMA2_STROBE, ATA_DMA2_HOLD);
- cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0);
-
- ide_device_add(idx, &cris_port_info);
-
- return 0;
-}
-
-static cris_dma_descr_type mydescr __attribute__ ((__aligned__(16)));
-
-/*
- * The following routines are mainly used by the ATAPI drivers.
- *
- * These routines will round up any request for an odd number of bytes,
- * so if an odd bytecount is specified, be sure that there's at least one
- * extra byte allocated for the buffer.
- */
-static void
-cris_atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
-{
- D(printk("atapi_input_bytes, buffer 0x%x, count %d\n",
- buffer, bytecount));
-
- if(bytecount & 1) {
- printk("warning, odd bytecount in cdrom_in_bytes = %d.\n", bytecount);
- bytecount++; /* to round off */
- }
-
- /* setup DMA and start transfer */
-
- cris_ide_fill_descriptor(&mydescr, buffer, bytecount, 1);
- cris_ide_start_dma(drive, &mydescr, 1, TYPE_PIO, bytecount);
-
- /* wait for completion */
- LED_DISK_READ(1);
- cris_ide_wait_dma(1);
- LED_DISK_READ(0);
-}
-
-static void
-cris_atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
-{
- D(printk("atapi_output_bytes, buffer 0x%x, count %d\n",
- buffer, bytecount));
-
- if(bytecount & 1) {
- printk("odd bytecount %d in atapi_out_bytes!\n", bytecount);
- bytecount++;
- }
-
- cris_ide_fill_descriptor(&mydescr, buffer, bytecount, 1);
- cris_ide_start_dma(drive, &mydescr, 0, TYPE_PIO, bytecount);
-
- /* wait for completion */
-
- LED_DISK_WRITE(1);
- LED_DISK_READ(1);
- cris_ide_wait_dma(0);
- LED_DISK_WRITE(0);
-}
-
-/*
- * This is used for most PIO data transfers *from* the IDE interface
- */
-static void
-cris_ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
-{
- cris_atapi_input_bytes(drive, buffer, wcount << 2);
-}
-
-/*
- * This is used for most PIO data transfers *to* the IDE interface
- */
-static void
-cris_ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
-{
- cris_atapi_output_bytes(drive, buffer, wcount << 2);
-}
-
-/* we only have one DMA channel on the chip for ATA, so we can keep these statically */
-static cris_dma_descr_type ata_descrs[MAX_DMA_DESCRS] __attribute__ ((__aligned__(16)));
-static unsigned int ata_tot_size;
-
-/*
- * cris_ide_build_dmatable() prepares a dma request.
- * Returns 0 if all went okay, returns 1 otherwise.
- */
-static int cris_ide_build_dmatable (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct scatterlist* sg;
- struct request *rq = drive->hwif->hwgroup->rq;
- unsigned long size, addr;
- unsigned int count = 0;
- int i = 0;
-
- sg = hwif->sg_table;
-
- ata_tot_size = 0;
-
- ide_map_sg(drive, rq);
- i = hwif->sg_nents;
-
- while(i) {
- /*
- * Determine addr and size of next buffer area. We assume that
- * individual virtual buffers are always composed linearly in
- * physical memory. For example, we assume that any 8kB buffer
- * is always composed of two adjacent physical 4kB pages rather
- * than two possibly non-adjacent physical 4kB pages.
- */
- /* group sequential buffers into one large buffer */
- addr = sg_phys(sg);
- size = sg_dma_len(sg);
- while (--i) {
- sg = sg_next(sg);
- if ((addr + size) != sg_phys(sg))
- break;
- size += sg_dma_len(sg);
- }
-
- /* did we run out of descriptors? */
-
- if(count >= MAX_DMA_DESCRS) {
- printk("%s: too few DMA descriptors\n", drive->name);
- return 1;
- }
-
- /* however, this case is more difficult - rw_trf_cnt cannot be more
- than 65536 words per transfer, so in that case we need to either
- 1) use a DMA interrupt to re-trigger rw_trf_cnt and continue with
- the descriptors, or
- 2) simply do the request here, and get dma_intr to only ide_end_request on
- those blocks that were actually set-up for transfer.
- */
-
- if(ata_tot_size + size > 131072) {
- printk("too large total ATA DMA request, %d + %d!\n", ata_tot_size, (int)size);
- return 1;
- }
-
- /* If size > MAX_DESCR_SIZE it has to be splitted into new descriptors. Since we
- don't handle size > 131072 only one split is necessary */
-
- if(size > MAX_DESCR_SIZE) {
- cris_ide_fill_descriptor(&ata_descrs[count], (void*)addr, MAX_DESCR_SIZE, 0);
- count++;
- ata_tot_size += MAX_DESCR_SIZE;
- size -= MAX_DESCR_SIZE;
- addr += MAX_DESCR_SIZE;
- }
-
- cris_ide_fill_descriptor(&ata_descrs[count], (void*)addr, size,i ? 0 : 1);
- count++;
- ata_tot_size += size;
- }
-
- if (count) {
- /* return and say all is ok */
- return 0;
- }
-
- printk("%s: empty DMA table?\n", drive->name);
- return 1; /* let the PIO routines handle this weirdness */
-}
-
-/*
- * cris_dma_intr() is the handler for disk read/write DMA interrupts
- */
-static ide_startstop_t cris_dma_intr (ide_drive_t *drive)
-{
- LED_DISK_READ(0);
- LED_DISK_WRITE(0);
-
- return ide_dma_intr(drive);
-}
-
-/*
- * Functions below initiates/aborts DMA read/write operations on a drive.
- *
- * The caller is assumed to have selected the drive and programmed the drive's
- * sector address using CHS or LBA. All that remains is to prepare for DMA
- * and then issue the actual read/write DMA/PIO command to the drive.
- *
- * For ATAPI devices, we just prepare for DMA and return. The caller should
- * then issue the packet command to the drive and call us again with
- * cris_dma_start afterwards.
- *
- * Returns 0 if all went well.
- * Returns 1 if DMA read/write could not be started, in which case
- * the caller should revert to PIO for the current request.
- */
-
-static int cris_dma_end(ide_drive_t *drive)
-{
- drive->waiting_for_dma = 0;
- return 0;
-}
-
-static int cris_dma_setup(ide_drive_t *drive)
-{
- struct request *rq = drive->hwif->hwgroup->rq;
-
- cris_ide_initialize_dma(!rq_data_dir(rq));
- if (cris_ide_build_dmatable (drive)) {
- ide_map_sg(drive, rq);
- return 1;
- }
-
- drive->waiting_for_dma = 1;
- return 0;
-}
-
-static void cris_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
- ide_execute_command(drive, command, &cris_dma_intr, WAIT_CMD, NULL);
-}
-
-static void cris_dma_start(ide_drive_t *drive)
-{
- struct request *rq = drive->hwif->hwgroup->rq;
- int writing = rq_data_dir(rq);
- int type = TYPE_DMA;
-
- if (drive->current_speed >= XFER_UDMA_0)
- type = TYPE_UDMA;
-
- cris_ide_start_dma(drive, &ata_descrs[0], writing ? 0 : 1, type, ata_tot_size);
-
- if (writing) {
- LED_DISK_WRITE(1);
- } else {
- LED_DISK_READ(1);
- }
-}
-
-module_init(init_e100_ide);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c
index 92b02b96d7d..ecf53bb0d2a 100644
--- a/drivers/ide/h8300/ide-h8300.c
+++ b/drivers/ide/h8300/ide-h8300.c
@@ -42,6 +42,91 @@ static u16 mm_inw(unsigned long a)
return r;
}
+static void h8300_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;
+ u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+
+ if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ HIHI = 0xFF;
+
+ ide_set_irq(drive, 1);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_DATA)
+ mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ outb(tf->hob_feature, io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ outb(tf->hob_nsect, io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ outb(tf->hob_lbal, io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ outb(tf->hob_lbam, io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ outb(tf->hob_lbah, io_ports->lbah_addr);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ outb(tf->feature, io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ outb(tf->nsect, io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ outb(tf->lbal, io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ outb(tf->lbam, io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ outb(tf->lbah, io_ports->lbah_addr);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ outb((tf->device & HIHI) | drive->select.all,
+ io_ports->device_addr);
+}
+
+static void h8300_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;
+
+ if (task->tf_flags & IDE_TFLAG_IN_DATA) {
+ u16 data = mm_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 */
+ outb(drive->ctl & ~0x80, io_ports->ctl_addr);
+
+ if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ tf->nsect = inb(io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ tf->lbal = inb(io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ tf->lbam = inb(io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ tf->lbah = inb(io_ports->lbah_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ tf->device = inb(io_ports->device_addr);
+
+ if (task->tf_flags & IDE_TFLAG_LBA48) {
+ outb(drive->ctl | 0x80, io_ports->ctl_addr);
+
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+ tf->hob_feature = inb(io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = inb(io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = inb(io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = inb(io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = inb(io_ports->lbah_addr);
+ }
+}
+
static void mm_outsw(unsigned long addr, void *buf, u32 len)
{
unsigned short *bp = (unsigned short *)buf;
@@ -56,6 +141,18 @@ static void mm_insw(unsigned long addr, void *buf, u32 len)
*bp = bswap(*(volatile u16 *)addr);
}
+static void h8300_input_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
+{
+ mm_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
+}
+
+static void h8300_output_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
+{
+ mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
+}
+
#define H8300_IDE_GAP (2)
static inline void hw_setup(hw_regs_t *hw)
@@ -63,9 +160,9 @@ static inline void hw_setup(hw_regs_t *hw)
int i;
memset(hw, 0, sizeof(hw_regs_t));
- for (i = 0; i <= IDE_STATUS_OFFSET; i++)
- hw->io_ports[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i;
- hw->io_ports[IDE_CONTROL_OFFSET] = CONFIG_H8300_IDE_ALT;
+ for (i = 0; i <= 7; i++)
+ hw->io_ports_array[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i;
+ hw->io_ports.ctl_addr = CONFIG_H8300_IDE_ALT;
hw->irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ;
hw->chipset = ide_generic;
}
@@ -74,13 +171,11 @@ static inline void hwif_setup(ide_hwif_t *hwif)
{
default_hwif_iops(hwif);
- hwif->mmio = 1;
- hwif->OUTW = mm_outw;
- hwif->OUTSW = mm_outsw;
- hwif->INW = mm_inw;
- hwif->INSW = mm_insw;
- hwif->OUTSL = NULL;
- hwif->INSL = NULL;
+ hwif->tf_load = h8300_tf_load;
+ hwif->tf_read = h8300_tf_read;
+
+ hwif->input_data = h8300_input_data;
+ hwif->output_data = h8300_output_data;
}
static int __init h8300_ide_init(void)
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index 0f6fb6b72dd..9d3601fa568 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -55,14 +55,22 @@ struct ide_acpi_hwif_link {
/* note: adds function name and KERN_DEBUG */
#ifdef DEBUGGING
#define DEBPRINT(fmt, args...) \
- printk(KERN_DEBUG "%s: " fmt, __FUNCTION__, ## args)
+ printk(KERN_DEBUG "%s: " fmt, __func__, ## args)
#else
#define DEBPRINT(fmt, args...) do {} while (0)
#endif /* DEBUGGING */
-extern int ide_noacpi;
-extern int ide_noacpitfs;
-extern int ide_noacpionboot;
+int ide_noacpi;
+module_param_named(noacpi, ide_noacpi, bool, 0);
+MODULE_PARM_DESC(noacpi, "disable IDE ACPI support");
+
+int ide_acpigtf;
+module_param_named(acpigtf, ide_acpigtf, bool, 0);
+MODULE_PARM_DESC(acpigtf, "enable IDE ACPI _GTF support");
+
+int ide_acpionboot;
+module_param_named(acpionboot, ide_acpionboot, bool, 0);
+MODULE_PARM_DESC(acpionboot, "call IDE ACPI methods on boot");
static bool ide_noacpi_psx;
static int no_acpi_psx(const struct dmi_system_id *id)
@@ -309,7 +317,7 @@ static int do_drive_get_GTF(ide_drive_t *drive,
if (ACPI_FAILURE(status)) {
printk(KERN_DEBUG
"%s: Run _GTF error: status = 0x%x\n",
- __FUNCTION__, status);
+ __func__, status);
goto out;
}
@@ -335,7 +343,7 @@ static int do_drive_get_GTF(ide_drive_t *drive,
out_obj->buffer.length % REGS_PER_GTF) {
printk(KERN_ERR
"%s: unexpected GTF length (%d) or addr (0x%p)\n",
- __FUNCTION__, out_obj->buffer.length,
+ __func__, out_obj->buffer.length,
out_obj->buffer.pointer);
err = -ENOENT;
kfree(output.pointer);
@@ -376,7 +384,7 @@ static int taskfile_load_raw(ide_drive_t *drive,
memcpy(&args.tf_array[7], &gtf->tfa, 7);
args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- if (ide_noacpitfs) {
+ if (!ide_acpigtf) {
DEBPRINT("_GTF execution disabled\n");
return err;
}
@@ -384,7 +392,7 @@ static int taskfile_load_raw(ide_drive_t *drive,
err = ide_no_data_taskfile(drive, &args);
if (err)
printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n",
- __FUNCTION__, err);
+ __func__, err);
return err;
}
@@ -422,7 +430,7 @@ static int do_drive_set_taskfiles(ide_drive_t *drive,
if (gtf_length % REGS_PER_GTF) {
printk(KERN_ERR "%s: unexpected GTF length (%d)\n",
- __FUNCTION__, gtf_length);
+ __func__, gtf_length);
goto out;
}
@@ -547,7 +555,7 @@ void ide_acpi_get_timing(ide_hwif_t *hwif)
printk(KERN_ERR
"%s: unexpected _GTM length (0x%x)[should be 0x%zx] or "
"addr (0x%p)\n",
- __FUNCTION__, out_obj->buffer.length,
+ __func__, out_obj->buffer.length,
sizeof(struct GTM_buffer), out_obj->buffer.pointer);
return;
}
@@ -721,7 +729,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
drive->name, err);
}
- if (ide_noacpionboot) {
+ if (!ide_acpionboot) {
DEBPRINT("ACPI methods disabled on boot\n");
return;
}
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 1afd95ad465..68e7f19dc03 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -39,12 +39,13 @@
#include <linux/mutex.h>
#include <linux/bcd.h>
-#include <scsi/scsi.h> /* For SCSI -> ATAPI command conversion */
+/* For SCSI -> ATAPI command conversion */
+#include <scsi/scsi.h>
-#include <asm/irq.h>
-#include <asm/io.h>
+#include <linux/irq.h>
+#include <linux/io.h>
#include <asm/byteorder.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/unaligned.h>
#include "ide-cd.h"
@@ -77,12 +78,11 @@ static void ide_cd_put(struct cdrom_info *cd)
mutex_unlock(&idecd_ref_mutex);
}
-/****************************************************************************
+/*
* Generic packet command support and error handling routines.
*/
-/* Mark that we've seen a media change, and invalidate our internal
- buffers. */
+/* Mark that we've seen a media change and invalidate our internal buffers. */
static void cdrom_saw_media_change(ide_drive_t *drive)
{
struct cdrom_info *cd = drive->driver_data;
@@ -105,9 +105,8 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
break;
case NOT_READY:
/*
- * don't care about tray state messages for
- * e.g. capacity commands or in-progress or
- * becoming ready
+ * don't care about tray state messages for e.g. capacity
+ * commands or in-progress or becoming ready
*/
if (sense->asc == 0x3a || sense->asc == 0x04)
break;
@@ -115,8 +114,8 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
break;
case ILLEGAL_REQUEST:
/*
- * don't log START_STOP unit with LoEj set, since
- * we cannot reliably check if drive can auto-close
+ * don't log START_STOP unit with LoEj set, since we cannot
+ * reliably check if drive can auto-close
*/
if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
break;
@@ -124,9 +123,9 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
break;
case UNIT_ATTENTION:
/*
- * Make good and sure we've seen this potential media
- * change. Some drives (i.e. Creative) fail to present
- * the correct sense key in the error register.
+ * Make good and sure we've seen this potential media change.
+ * Some drives (i.e. Creative) fail to present the correct sense
+ * key in the error register.
*/
cdrom_saw_media_change(drive);
break;
@@ -137,29 +136,28 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
return log;
}
-static
-void cdrom_analyze_sense_data(ide_drive_t *drive,
+static void cdrom_analyze_sense_data(ide_drive_t *drive,
struct request *failed_command,
struct request_sense *sense)
{
unsigned long sector;
unsigned long bio_sectors;
- unsigned long valid;
struct cdrom_info *info = drive->driver_data;
if (!cdrom_log_sense(drive, failed_command, sense))
return;
/*
- * If a read toc is executed for a CD-R or CD-RW medium where
- * the first toc has not been recorded yet, it will fail with
- * 05/24/00 (which is a confusing error)
+ * If a read toc is executed for a CD-R or CD-RW medium where the first
+ * toc has not been recorded yet, it will fail with 05/24/00 (which is a
+ * confusing error)
*/
if (failed_command && failed_command->cmd[0] == GPCMD_READ_TOC_PMA_ATIP)
if (sense->sense_key == 0x05 && sense->asc == 0x24)
return;
- if (sense->error_code == 0x70) { /* Current Error */
+ /* current error */
+ if (sense->error_code == 0x70) {
switch (sense->sense_key) {
case MEDIUM_ERROR:
case VOLUME_OVERFLOW:
@@ -174,29 +172,23 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
(sense->information[2] << 8) |
(sense->information[3]);
- bio_sectors = bio_sectors(failed_command->bio);
- if (bio_sectors < 4)
- bio_sectors = 4;
if (drive->queue->hardsect_size == 2048)
- sector <<= 2; /* Device sector size is 2K */
+ /* device sector size is 2K */
+ sector <<= 2;
+
+ bio_sectors = max(bio_sectors(failed_command->bio), 4U);
sector &= ~(bio_sectors - 1);
- valid = (sector - failed_command->sector) << 9;
- if (valid < 0)
- valid = 0;
if (sector < get_capacity(info->disk) &&
- drive->probed_capacity - sector < 4 * 75) {
+ drive->probed_capacity - sector < 4 * 75)
set_capacity(info->disk, sector);
- }
}
}
ide_cd_log_error(drive->name, failed_command, sense);
}
-/*
- * Initialize a ide-cd packet command request
- */
+/* Initialize a ide-cd packet command request */
void ide_cd_init_rq(ide_drive_t *drive, struct request *rq)
{
struct cdrom_info *cd = drive->driver_data;
@@ -220,7 +212,8 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
rq->data = sense;
rq->cmd[0] = GPCMD_REQUEST_SENSE;
- rq->cmd[4] = rq->data_len = 18;
+ rq->cmd[4] = 18;
+ rq->data_len = 18;
rq->cmd_type = REQ_TYPE_SENSE;
@@ -252,7 +245,7 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate)
}
cdrom_analyze_sense_data(drive, failed, sense);
/*
- * now end failed request
+ * now end the failed request
*/
if (blk_fs_request(failed)) {
if (ide_end_dequeued_request(drive, failed, 0,
@@ -280,21 +273,24 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate)
ide_end_request(drive, uptodate, nsectors);
}
-static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 stat)
+static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st)
{
- if (stat & 0x80)
+ if (st & 0x80)
return;
- ide_dump_status(drive, msg, stat);
+ ide_dump_status(drive, msg, st);
}
-/* Returns 0 if the request should be continued.
- Returns 1 if the request was ended. */
+/*
+ * Returns:
+ * 0: if the request should be continued.
+ * 1: if the request was ended.
+ */
static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
{
struct request *rq = HWGROUP(drive)->rq;
int stat, err, sense_key;
- /* Check for errors. */
+ /* check for errors */
stat = ide_read_status(drive);
if (stat_ret)
@@ -303,20 +299,22 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
if (OK_STAT(stat, good_stat, BAD_R_STAT))
return 0;
- /* Get the IDE error register. */
+ /* get the IDE error register */
err = ide_read_error(drive);
sense_key = err >> 4;
if (rq == NULL) {
- printk("%s: missing rq in cdrom_decode_status\n", drive->name);
+ printk(KERN_ERR "%s: missing rq in %s\n",
+ drive->name, __func__);
return 1;
}
if (blk_sense_request(rq)) {
- /* We got an error trying to get sense info
- from the drive (probably while trying
- to recover from a former error). Just give up. */
-
+ /*
+ * We got an error trying to get sense info from the drive
+ * (probably while trying to recover from a former error).
+ * Just give up.
+ */
rq->cmd_flags |= REQ_FAILED;
cdrom_end_request(drive, 0);
ide_error(drive, "request sense failure", stat);
@@ -332,13 +330,12 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
if (blk_pc_request(rq) && !rq->errors)
rq->errors = SAM_STAT_CHECK_CONDITION;
- /* Check for tray open. */
+ /* check for tray open */
if (sense_key == NOT_READY) {
cdrom_saw_media_change(drive);
} else if (sense_key == UNIT_ATTENTION) {
- /* Check for media change. */
+ /* check for media change */
cdrom_saw_media_change(drive);
- /*printk("%s: media changed\n",drive->name);*/
return 0;
} else if (sense_key == ILLEGAL_REQUEST &&
rq->cmd[0] == GPCMD_START_STOP_UNIT) {
@@ -350,7 +347,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
* cdrom_log_sense() knows this!
*/
} else if (!(rq->cmd_flags & REQ_QUIET)) {
- /* Otherwise, print an error. */
+ /* otherwise, print an error */
ide_dump_status(drive, "packet command error", stat);
}
@@ -366,27 +363,30 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
} else if (blk_fs_request(rq)) {
int do_end_request = 0;
- /* Handle errors from READ and WRITE requests. */
+ /* handle errors from READ and WRITE requests */
if (blk_noretry_request(rq))
do_end_request = 1;
if (sense_key == NOT_READY) {
- /* Tray open. */
+ /* tray open */
if (rq_data_dir(rq) == READ) {
cdrom_saw_media_change(drive);
- /* Fail the request. */
- printk("%s: tray open\n", drive->name);
+ /* fail the request */
+ printk(KERN_ERR "%s: tray open\n", drive->name);
do_end_request = 1;
} else {
struct cdrom_info *info = drive->driver_data;
- /* allow the drive 5 seconds to recover, some
+ /*
+ * Allow the drive 5 seconds to recover, some
* devices will return this error while flushing
- * data from cache */
+ * data from cache.
+ */
if (!rq->errors)
- info->write_timeout = jiffies + ATAPI_WAIT_WRITE_BUSY;
+ info->write_timeout = jiffies +
+ ATAPI_WAIT_WRITE_BUSY;
rq->errors = 1;
if (time_after(jiffies, info->write_timeout))
do_end_request = 1;
@@ -394,65 +394,68 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
unsigned long flags;
/*
- * take a breather relying on the
- * unplug timer to kick us again
+ * take a breather relying on the unplug
+ * timer to kick us again
*/
spin_lock_irqsave(&ide_lock, flags);
blk_plug_device(drive->queue);
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&ide_lock,
+ flags);
return 1;
}
}
} else if (sense_key == UNIT_ATTENTION) {
- /* Media change. */
- cdrom_saw_media_change (drive);
+ /* media change */
+ cdrom_saw_media_change(drive);
/*
- * Arrange to retry the request.
- * But be sure to give up if we've retried
- * too many times.
+ * Arrange to retry the request but be sure to give up
+ * if we've retried too many times.
*/
if (++rq->errors > ERROR_MAX)
do_end_request = 1;
} else if (sense_key == ILLEGAL_REQUEST ||
sense_key == DATA_PROTECT) {
/*
- * No point in retrying after an illegal
- * request or data protect error.
+ * No point in retrying after an illegal request or data
+ * protect error.
*/
ide_dump_status_no_sense(drive, "command error", stat);
do_end_request = 1;
} else if (sense_key == MEDIUM_ERROR) {
/*
* No point in re-trying a zillion times on a bad
- * sector... If we got here the error is not correctable
+ * sector. If we got here the error is not correctable.
*/
- ide_dump_status_no_sense(drive, "media error (bad sector)", stat);
+ ide_dump_status_no_sense(drive,
+ "media error (bad sector)",
+ stat);
do_end_request = 1;
} else if (sense_key == BLANK_CHECK) {
- /* Disk appears blank ?? */
- ide_dump_status_no_sense(drive, "media error (blank)", stat);
+ /* disk appears blank ?? */
+ ide_dump_status_no_sense(drive, "media error (blank)",
+ stat);
do_end_request = 1;
} else if ((err & ~ABRT_ERR) != 0) {
- /* Go to the default handler
- for other errors. */
+ /* go to the default handler for other errors */
ide_error(drive, "cdrom_decode_status", stat);
return 1;
} else if ((++rq->errors > ERROR_MAX)) {
- /* We've racked up too many retries. Abort. */
+ /* we've racked up too many retries, abort */
do_end_request = 1;
}
- /* End a request through request sense analysis when we have
- sense data. We need this in order to perform end of media
- processing */
-
+ /*
+ * End a request through request sense analysis when we have
+ * sense data. We need this in order to perform end of media
+ * processing.
+ */
if (do_end_request)
goto end_request;
/*
- * If we got a CHECK_CONDITION status,
- * queue a request sense command.
+ * If we got a CHECK_CONDITION status, queue
+ * a request sense command.
*/
if (stat & ERR_STAT)
cdrom_queue_request_sense(drive, NULL, NULL);
@@ -461,7 +464,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
cdrom_end_request(drive, 0);
}
- /* Retry, or handle the next request. */
+ /* retry, or handle the next request */
return 1;
end_request:
@@ -486,10 +489,10 @@ static int cdrom_timer_expiry(ide_drive_t *drive)
unsigned long wait = 0;
/*
- * Some commands are *slow* and normally take a long time to
- * complete. Usually we can use the ATAPI "disconnect" to bypass
- * this, but not all commands/drives support that. Let
- * ide_timer_expiry keep polling us for these.
+ * Some commands are *slow* and normally take a long time to complete.
+ * Usually we can use the ATAPI "disconnect" to bypass this, but not all
+ * commands/drives support that. Let ide_timer_expiry keep polling us
+ * for these.
*/
switch (rq->cmd[0]) {
case GPCMD_BLANK:
@@ -501,20 +504,22 @@ static int cdrom_timer_expiry(ide_drive_t *drive)
break;
default:
if (!(rq->cmd_flags & REQ_QUIET))
- printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]);
+ printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n",
+ rq->cmd[0]);
wait = 0;
break;
}
return wait;
}
-/* Set up the device registers for transferring a packet command on DEV,
- expecting to later transfer XFERLEN bytes. HANDLER is the routine
- which actually transfers the command to the drive. If this is a
- drq_interrupt device, this routine will arrange for HANDLER to be
- called when the interrupt from the drive arrives. Otherwise, HANDLER
- will be called immediately after the drive is prepared for the transfer. */
-
+/*
+ * Set up the device registers for transferring a packet command on DEV,
+ * expecting to later transfer XFERLEN bytes. HANDLER is the routine
+ * which actually transfers the command to the drive. If this is a
+ * drq_interrupt device, this routine will arrange for HANDLER to be
+ * called when the interrupt from the drive arrives. Otherwise, HANDLER
+ * will be called immediately after the drive is prepared for the transfer.
+ */
static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
int xferlen,
ide_handler_t *handler)
@@ -523,15 +528,15 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
struct cdrom_info *info = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
- /* Wait for the controller to be idle. */
+ /* wait for the controller to be idle */
if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY))
return startstop;
/* FIXME: for Virtual DMA we must check harder */
if (info->dma)
- info->dma = !hwif->dma_setup(drive);
+ info->dma = !hwif->dma_ops->dma_setup(drive);
- /* Set up the controller registers. */
+ /* set up the controller registers */
ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL |
IDE_TFLAG_NO_SELECT_MASK, xferlen, info->dma);
@@ -541,27 +546,22 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
drive->waiting_for_dma = 0;
/* packet command */
- ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry);
+ ide_execute_command(drive, WIN_PACKETCMD, handler,
+ ATAPI_WAIT_PC, cdrom_timer_expiry);
return ide_started;
} else {
- unsigned long flags;
-
- /* packet command */
- spin_lock_irqsave(&ide_lock, flags);
- hwif->OUTBSYNC(drive, WIN_PACKETCMD,
- hwif->io_ports[IDE_COMMAND_OFFSET]);
- ndelay(400);
- spin_unlock_irqrestore(&ide_lock, flags);
+ ide_execute_pkt_cmd(drive);
return (*handler) (drive);
}
}
-/* Send a packet command to DRIVE described by CMD_BUF and CMD_LEN.
- The device registers must have already been prepared
- by cdrom_start_packet_command.
- HANDLER is the interrupt handler to call when the command completes
- or there's data ready. */
+/*
+ * Send a packet command to DRIVE described by CMD_BUF and CMD_LEN. The device
+ * registers must have already been prepared by cdrom_start_packet_command.
+ * HANDLER is the interrupt handler to call when the command completes or
+ * there's data ready.
+ */
#define ATAPI_MIN_CDB_BYTES 12
static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
struct request *rq,
@@ -573,24 +573,26 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
ide_startstop_t startstop;
if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) {
- /* Here we should have been called after receiving an interrupt
- from the device. DRQ should how be set. */
+ /*
+ * Here we should have been called after receiving an interrupt
+ * from the device. DRQ should how be set.
+ */
- /* Check for errors. */
+ /* check for errors */
if (cdrom_decode_status(drive, DRQ_STAT, NULL))
return ide_stopped;
- /* Ok, next interrupt will be DMA interrupt. */
+ /* ok, next interrupt will be DMA interrupt */
if (info->dma)
drive->waiting_for_dma = 1;
} else {
- /* Otherwise, we must wait for DRQ to get set. */
+ /* otherwise, we must wait for DRQ to get set */
if (ide_wait_stat(&startstop, drive, DRQ_STAT,
BUSY_STAT, WAIT_READY))
return startstop;
}
- /* Arm the interrupt handler. */
+ /* arm the interrupt handler */
ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);
/* ATAPI commands get padded out to 12 bytes minimum */
@@ -598,25 +600,24 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
if (cmd_len < ATAPI_MIN_CDB_BYTES)
cmd_len = ATAPI_MIN_CDB_BYTES;
- /* Send the command to the device. */
- HWIF(drive)->atapi_output_bytes(drive, rq->cmd, cmd_len);
+ /* send the command to the device */
+ hwif->output_data(drive, NULL, rq->cmd, cmd_len);
- /* Start the DMA if need be */
+ /* start the DMA if need be */
if (info->dma)
- hwif->dma_start(drive);
+ hwif->dma_ops->dma_start(drive);
return ide_started;
}
-/****************************************************************************
+/*
* Block read functions.
*/
-
static void ide_cd_pad_transfer(ide_drive_t *drive, xfer_func_t *xf, int len)
{
while (len > 0) {
int dum = 0;
- xf(drive, &dum, sizeof(dum));
+ xf(drive, NULL, &dum, sizeof(dum));
len -= sizeof(dum);
}
}
@@ -626,7 +627,7 @@ static void ide_cd_drain_data(ide_drive_t *drive, int nsects)
while (nsects > 0) {
static char dum[SECTOR_SIZE];
- drive->hwif->atapi_input_bytes(drive, dum, sizeof(dum));
+ drive->hwif->input_data(drive, NULL, dum, sizeof(dum));
nsects--;
}
}
@@ -649,20 +650,21 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
ide_hwif_t *hwif = drive->hwif;
xfer_func_t *xf;
- /* Whoops... */
+ /* whoops... */
printk(KERN_ERR "%s: %s: wrong transfer direction!\n",
drive->name, __func__);
- xf = rw ? hwif->atapi_output_bytes : hwif->atapi_input_bytes;
+ xf = rw ? hwif->output_data : hwif->input_data;
ide_cd_pad_transfer(drive, xf, len);
} else if (rw == 0 && ireason == 1) {
- /* Some drives (ASUS) seem to tell us that status
- * info is available. just get it and ignore.
+ /*
+ * Some drives (ASUS) seem to tell us that status info is
+ * available. Just get it and ignore.
*/
(void)ide_read_status(drive);
return 0;
} else {
- /* Drive wants a command packet, or invalid ireason... */
+ /* drive wants a command packet, or invalid ireason... */
printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n",
drive->name, __func__, ireason);
}
@@ -702,10 +704,10 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);
/*
- * Routine to send a read/write packet command to the drive.
- * This is usually called directly from cdrom_start_{read,write}().
- * However, for drq_interrupt devices, it is called from an interrupt
- * when the drive is ready to accept the command.
+ * Routine to send a read/write packet command to the drive. This is usually
+ * called directly from cdrom_start_{read,write}(). However, for drq_interrupt
+ * devices, it is called from an interrupt when the drive is ready to accept
+ * the command.
*/
static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
{
@@ -727,7 +729,7 @@ static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
* is larger than the buffer size.
*/
if (nskip > 0) {
- /* Sanity check... */
+ /* sanity check... */
if (rq->current_nr_sectors !=
bio_cur_sectors(rq->bio)) {
printk(KERN_ERR "%s: %s: buffer botch (%u)\n",
@@ -744,10 +746,10 @@ static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
/* the immediate bit */
rq->cmd[1] = 1 << 3;
#endif
- /* Set up the command */
+ /* set up the command */
rq->timeout = ATAPI_WAIT_PC;
- /* Send the command to the drive and return. */
+ /* send the command to the drive and return */
return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
}
@@ -767,14 +769,8 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive)
info->cd_flags |= IDE_CD_FLAG_SEEKING;
if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) {
- if (--retry == 0) {
- /*
- * this condition is far too common, to bother
- * users about it
- */
- /* printk("%s: disabled DSC seek overlap\n", drive->name);*/
+ if (--retry == 0)
drive->dsc_overlap = 0;
- }
}
return ide_stopped;
}
@@ -786,7 +782,7 @@ static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive)
sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS);
- memset(rq->cmd, 0, sizeof(rq->cmd));
+ memset(rq->cmd, 0, BLK_MAX_CDB);
rq->cmd[0] = GPCMD_SEEK;
put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]);
@@ -800,32 +796,34 @@ static ide_startstop_t cdrom_start_seek(ide_drive_t *drive, unsigned int block)
info->dma = 0;
info->start_seek = jiffies;
- return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
+ return cdrom_start_packet_command(drive, 0,
+ cdrom_start_seek_continuation);
}
/*
- * Fix up a possibly partially-processed request so that we can
- * start it over entirely, or even put it back on the request queue.
+ * Fix up a possibly partially-processed request so that we can start it over
+ * entirely, or even put it back on the request queue.
*/
static void restore_request(struct request *rq)
{
if (rq->buffer != bio_data(rq->bio)) {
- sector_t n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE;
+ sector_t n =
+ (rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE;
rq->buffer = bio_data(rq->bio);
rq->nr_sectors += n;
rq->sector -= n;
}
- rq->hard_cur_sectors = rq->current_nr_sectors = bio_cur_sectors(rq->bio);
+ rq->current_nr_sectors = bio_cur_sectors(rq->bio);
+ rq->hard_cur_sectors = rq->current_nr_sectors;
rq->hard_nr_sectors = rq->nr_sectors;
rq->hard_sector = rq->sector;
rq->q->prep_rq_fn(rq->q, rq);
}
-/****************************************************************************
- * Execute all other packet commands.
+/*
+ * All other packet commands.
*/
-
static void ide_cd_request_sense_fixup(struct request *rq)
{
/*
@@ -849,7 +847,7 @@ int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq)
if (rq->sense == NULL)
rq->sense = &sense;
- /* Start of retry loop. */
+ /* start of retry loop */
do {
int error;
unsigned long time = jiffies;
@@ -858,41 +856,45 @@ int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq)
error = ide_do_drive_cmd(drive, rq, ide_wait);
time = jiffies - time;
- /* FIXME: we should probably abort/retry or something
- * in case of failure */
+ /*
+ * FIXME: we should probably abort/retry or something in case of
+ * failure.
+ */
if (rq->cmd_flags & REQ_FAILED) {
- /* The request failed. Retry if it was due to a unit
- attention status
- (usually means media was changed). */
+ /*
+ * The request failed. Retry if it was due to a unit
+ * attention status (usually means media was changed).
+ */
struct request_sense *reqbuf = rq->sense;
if (reqbuf->sense_key == UNIT_ATTENTION)
cdrom_saw_media_change(drive);
else if (reqbuf->sense_key == NOT_READY &&
reqbuf->asc == 4 && reqbuf->ascq != 4) {
- /* The drive is in the process of loading
- a disk. Retry, but wait a little to give
- the drive time to complete the load. */
+ /*
+ * The drive is in the process of loading
+ * a disk. Retry, but wait a little to give
+ * the drive time to complete the load.
+ */
ssleep(2);
} else {
- /* Otherwise, don't retry. */
+ /* otherwise, don't retry */
retries = 0;
}
--retries;
}
- /* End of retry loop. */
+ /* end of retry loop */
} while ((rq->cmd_flags & REQ_FAILED) && retries >= 0);
- /* Return an error if the command failed. */
+ /* return an error if the command failed */
return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0;
}
/*
- * Called from blk_end_request_callback() after the data of the request
- * is completed and before the request is completed.
- * By returning value '1', blk_end_request_callback() returns immediately
- * without completing the request.
+ * Called from blk_end_request_callback() after the data of the request is
+ * completed and before the request itself is completed. By returning value '1',
+ * blk_end_request_callback() returns immediately without completing it.
*/
static int cdrom_newpc_intr_dummy_cb(struct request *rq)
{
@@ -911,11 +913,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
unsigned int timeout;
u8 lowcyl, highcyl;
- /* Check for errors. */
+ /* check for errors */
dma = info->dma;
if (dma) {
info->dma = 0;
- dma_error = HWIF(drive)->ide_dma_end(drive);
+ dma_error = hwif->dma_ops->dma_end(drive);
if (dma_error) {
printk(KERN_ERR "%s: DMA %s error\n", drive->name,
write ? "write" : "read");
@@ -926,9 +928,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
if (cdrom_decode_status(drive, 0, &stat))
return ide_stopped;
- /*
- * using dma, transfer is complete now
- */
+ /* using dma, transfer is complete now */
if (dma) {
if (dma_error)
return ide_error(drive, "dma error", stat);
@@ -939,12 +939,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
goto end_request;
}
- /*
- * ok we fall to pio :/
- */
- ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]) & 0x3;
- lowcyl = hwif->INB(hwif->io_ports[IDE_BCOUNTL_OFFSET]);
- highcyl = hwif->INB(hwif->io_ports[IDE_BCOUNTH_OFFSET]);
+ /* ok we fall to pio :/ */
+ ireason = hwif->INB(hwif->io_ports.nsect_addr) & 0x3;
+ lowcyl = hwif->INB(hwif->io_ports.lbam_addr);
+ highcyl = hwif->INB(hwif->io_ports.lbah_addr);
len = lowcyl + (256 * highcyl);
@@ -952,9 +950,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
if (thislen > len)
thislen = len;
- /*
- * If DRQ is clear, the command has completed.
- */
+ /* If DRQ is clear, the command has completed. */
if ((stat & DRQ_STAT) == 0) {
if (blk_fs_request(rq)) {
/*
@@ -975,15 +971,13 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
return ide_stopped;
} else if (!blk_pc_request(rq)) {
ide_cd_request_sense_fixup(rq);
- /* Complain if we still have data left to transfer. */
+ /* complain if we still have data left to transfer */
uptodate = rq->data_len ? 0 : 1;
}
goto end_request;
}
- /*
- * check which way to transfer data
- */
+ /* check which way to transfer data */
if (ide_cd_check_ireason(drive, rq, len, ireason, write))
return ide_stopped;
@@ -1013,22 +1007,18 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
if (ireason == 0) {
write = 1;
- xferfunc = HWIF(drive)->atapi_output_bytes;
+ xferfunc = hwif->output_data;
} else {
write = 0;
- xferfunc = HWIF(drive)->atapi_input_bytes;
+ xferfunc = hwif->input_data;
}
- /*
- * transfer data
- */
+ /* transfer data */
while (thislen > 0) {
u8 *ptr = blk_fs_request(rq) ? NULL : rq->data;
int blen = rq->data_len;
- /*
- * bio backed?
- */
+ /* bio backed? */
if (rq->bio) {
if (blk_fs_request(rq)) {
ptr = rq->buffer;
@@ -1043,7 +1033,8 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
if (blk_fs_request(rq) && !write)
/*
* If the buffers are full, pipe the rest into
- * oblivion. */
+ * oblivion.
+ */
ide_cd_drain_data(drive, thislen >> 9);
else {
printk(KERN_ERR "%s: confused, missing data\n",
@@ -1058,7 +1049,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
if (blen > thislen)
blen = thislen;
- xferfunc(drive, ptr, blen);
+ xferfunc(drive, NULL, ptr, blen);
thislen -= blen;
len -= blen;
@@ -1090,9 +1081,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
rq->sense_len += blen;
}
- /*
- * pad, if necessary
- */
+ /* pad, if necessary */
if (!blk_fs_request(rq) && len > 0)
ide_cd_pad_transfer(drive, xferfunc, len);
@@ -1136,9 +1125,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
queue_hardsect_size(drive->queue) >> SECTOR_BITS;
if (write) {
- /*
- * disk has become write protected
- */
+ /* disk has become write protected */
if (cd->disk->policy) {
cdrom_end_request(drive, 0);
return ide_stopped;
@@ -1151,9 +1138,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
restore_request(rq);
}
- /*
- * use DMA, if possible / writes *must* be hardware frame aligned
- */
+ /* use DMA, if possible / writes *must* be hardware frame aligned */
if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
(rq->sector & (sectors_per_frame - 1))) {
if (write) {
@@ -1167,7 +1152,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
if (write)
cd->devinfo.media_written = 1;
- /* Start sending the read/write request to the drive. */
+ /* start sending the read/write request to the drive */
return cdrom_start_packet_command(drive, 32768, cdrom_start_rw_cont);
}
@@ -1192,12 +1177,11 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
info->dma = 0;
- /*
- * sg request
- */
+ /* sg request */
if (rq->bio) {
int mask = drive->queue->dma_alignment;
- unsigned long addr = (unsigned long) page_address(bio_page(rq->bio));
+ unsigned long addr =
+ (unsigned long)page_address(bio_page(rq->bio));
info->dma = drive->using_dma;
@@ -1211,15 +1195,16 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
info->dma = 0;
}
- /* Start sending the command to the drive. */
- return cdrom_start_packet_command(drive, rq->data_len, cdrom_do_newpc_cont);
+ /* start sending the command to the drive */
+ return cdrom_start_packet_command(drive, rq->data_len,
+ cdrom_do_newpc_cont);
}
-/****************************************************************************
+/*
* cdrom driver request routine.
*/
-static ide_startstop_t
-ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, sector_t block)
+static ide_startstop_t ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq,
+ sector_t block)
{
ide_startstop_t action;
struct cdrom_info *info = drive->driver_data;
@@ -1231,14 +1216,19 @@ ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, sector_t block)
if ((stat & SEEK_STAT) != SEEK_STAT) {
if (elapsed < IDECD_SEEK_TIMEOUT) {
- ide_stall_queue(drive, IDECD_SEEK_TIMER);
+ ide_stall_queue(drive,
+ IDECD_SEEK_TIMER);
return ide_stopped;
}
- printk(KERN_ERR "%s: DSC timeout\n", drive->name);
+ printk(KERN_ERR "%s: DSC timeout\n",
+ drive->name);
}
info->cd_flags &= ~IDE_CD_FLAG_SEEKING;
}
- if ((rq_data_dir(rq) == READ) && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
+ if (rq_data_dir(rq) == READ &&
+ IDE_LARGE_SEEK(info->last_block, block,
+ IDECD_SEEK_THRESHOLD) &&
+ drive->dsc_overlap)
action = cdrom_start_seek(drive, block);
else
action = cdrom_start_rw(drive, rq);
@@ -1248,9 +1238,7 @@ ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, sector_t block)
rq->cmd_type == REQ_TYPE_ATA_PC) {
return cdrom_do_block_pc(drive, rq);
} else if (blk_special_request(rq)) {
- /*
- * right now this can only be a reset...
- */
+ /* right now this can only be a reset... */
cdrom_end_request(drive, 1);
return ide_stopped;
}
@@ -1262,18 +1250,16 @@ ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, sector_t block)
-/****************************************************************************
+/*
* Ioctl handling.
*
- * Routines which queue packet commands take as a final argument a pointer
- * to a request_sense struct. If execution of the command results
- * in an error with a CHECK CONDITION status, this structure will be filled
- * with the results of the subsequent request sense command. The pointer
- * can also be NULL, in which case no sense information is returned.
+ * Routines which queue packet commands take as a final argument a pointer to a
+ * request_sense struct. If execution of the command results in an error with a
+ * CHECK CONDITION status, this structure will be filled with the results of the
+ * subsequent request sense command. The pointer can also be NULL, in which case
+ * no sense information is returned.
*/
-
-static
-void msf_from_bcd(struct atapi_msf *msf)
+static void msf_from_bcd(struct atapi_msf *msf)
{
msf->minute = BCD2BIN(msf->minute);
msf->second = BCD2BIN(msf->second);
@@ -1293,8 +1279,8 @@ int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
req.cmd_flags |= REQ_QUIET;
/*
- * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to
- * switch CDs instead of supporting the LOAD_UNLOAD opcode.
+ * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs
+ * instead of supporting the LOAD_UNLOAD opcode.
*/
req.cmd[7] = cdi->sanyo_slot % 3;
@@ -1370,36 +1356,39 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
unsigned long sectors_per_frame = SECTORS_PER_FRAME;
if (toc == NULL) {
- /* Try to allocate space. */
+ /* try to allocate space */
toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
if (toc == NULL) {
- printk(KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name);
+ printk(KERN_ERR "%s: No cdrom TOC buffer!\n",
+ drive->name);
return -ENOMEM;
}
info->toc = toc;
}
- /* Check to see if the existing data is still valid.
- If it is, just return. */
+ /*
+ * Check to see if the existing data is still valid. If it is,
+ * just return.
+ */
(void) cdrom_check_status(drive, sense);
if (info->cd_flags & IDE_CD_FLAG_TOC_VALID)
return 0;
- /* Try to get the total cdrom capacity and sector size. */
+ /* try to get the total cdrom capacity and sector size */
stat = cdrom_read_capacity(drive, &toc->capacity, &sectors_per_frame,
sense);
if (stat)
toc->capacity = 0x1fffff;
set_capacity(info->disk, toc->capacity * sectors_per_frame);
- /* Save a private copy of te TOC capacity for error handling */
+ /* save a private copy of the TOC capacity for error handling */
drive->probed_capacity = toc->capacity * sectors_per_frame;
blk_queue_hardsect_size(drive->queue,
sectors_per_frame << SECTOR_BITS);
- /* First read just the header, so we know how long the TOC is. */
+ /* first read just the header, so we know how long the TOC is */
stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
sizeof(struct atapi_toc_header), sense);
if (stat)
@@ -1416,7 +1405,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
if (ntracks > MAX_TRACKS)
ntracks = MAX_TRACKS;
- /* Now read the whole schmeer. */
+ /* now read the whole schmeer */
stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0,
(char *)&toc->hdr,
sizeof(struct atapi_toc_header) +
@@ -1424,15 +1413,18 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
sizeof(struct atapi_toc_entry), sense);
if (stat && toc->hdr.first_track > 1) {
- /* Cds with CDI tracks only don't have any TOC entries,
- despite of this the returned values are
- first_track == last_track = number of CDI tracks + 1,
- so that this case is indistinguishable from the same
- layout plus an additional audio track.
- If we get an error for the regular case, we assume
- a CDI without additional audio tracks. In this case
- the readable TOC is empty (CDI tracks are not included)
- and only holds the Leadout entry. Heiko Eißfeldt */
+ /*
+ * Cds with CDI tracks only don't have any TOC entries, despite
+ * of this the returned values are
+ * first_track == last_track = number of CDI tracks + 1,
+ * so that this case is indistinguishable from the same layout
+ * plus an additional audio track. If we get an error for the
+ * regular case, we assume a CDI without additional audio
+ * tracks. In this case the readable TOC is empty (CDI tracks
+ * are not included) and only holds the Leadout entry.
+ *
+ * Heiko Eißfeldt.
+ */
ntracks = 0;
stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
(char *)&toc->hdr,
@@ -1473,9 +1465,8 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
toc->ent[i].addr.msf.frame);
}
- /* Read the multisession information. */
if (toc->hdr.first_track != CDROM_LEADOUT) {
- /* Read the multisession information. */
+ /* read the multisession information */
stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
sizeof(ms_tmp), sense);
if (stat)
@@ -1483,12 +1474,13 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
} else {
- ms_tmp.hdr.first_track = ms_tmp.hdr.last_track = CDROM_LEADOUT;
+ ms_tmp.hdr.last_track = CDROM_LEADOUT;
+ ms_tmp.hdr.first_track = ms_tmp.hdr.last_track;
toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */
}
if (info->cd_flags & IDE_CD_FLAG_TOCADDR_AS_BCD) {
- /* Re-read multisession information using MSF format */
+ /* re-read multisession information using MSF format */
stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
sizeof(ms_tmp), sense);
if (stat)
@@ -1502,7 +1494,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
- /* Now try to get the total cdrom capacity. */
+ /* now try to get the total cdrom capacity */
stat = cdrom_get_last_written(cdi, &last_written);
if (!stat && (last_written > toc->capacity)) {
toc->capacity = last_written;
@@ -1527,7 +1519,8 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN);
- do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
+ do {
+ /* we seem to get stat=0x01,err=0x00 the first time (??) */
stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
if (!stat)
break;
@@ -1596,8 +1589,7 @@ static int ide_cdrom_register(ide_drive_t *drive, int nslots)
return register_cdrom(devinfo);
}
-static
-int ide_cdrom_probe_capabilities(ide_drive_t *drive)
+static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
{
struct cdrom_info *cd = drive->driver_data;
struct cdrom_device_info *cdi = &cd->devinfo;
@@ -1611,7 +1603,8 @@ int ide_cdrom_probe_capabilities(ide_drive_t *drive)
if (drive->media == ide_optical) {
cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM);
- printk(KERN_ERR "%s: ATAPI magneto-optical drive\n", drive->name);
+ printk(KERN_ERR "%s: ATAPI magneto-optical drive\n",
+ drive->name);
return nslots;
}
@@ -1622,11 +1615,10 @@ int ide_cdrom_probe_capabilities(ide_drive_t *drive)
}
/*
- * we have to cheat a little here. the packet will eventually
- * be queued with ide_cdrom_packet(), which extracts the
- * drive from cdi->handle. Since this device hasn't been
- * registered with the Uniform layer yet, it can't do this.
- * Same goes for cdi->ops.
+ * We have to cheat a little here. the packet will eventually be queued
+ * with ide_cdrom_packet(), which extracts the drive from cdi->handle.
+ * Since this device hasn't been registered with the Uniform layer yet,
+ * it can't do this. Same goes for cdi->ops.
*/
cdi->handle = drive;
cdi->ops = &ide_cdrom_dops;
@@ -1695,25 +1687,14 @@ int ide_cdrom_probe_capabilities(ide_drive_t *drive)
return nslots;
}
-#ifdef CONFIG_IDE_PROC_FS
-static void ide_cdrom_add_settings(ide_drive_t *drive)
-{
- ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL);
-}
-#else
-static inline void ide_cdrom_add_settings(ide_drive_t *drive) { ; }
-#endif
-
-/*
- * standard prep_rq_fn that builds 10 byte cmds
- */
+/* standard prep_rq_fn that builds 10 byte cmds */
static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
{
int hard_sect = queue_hardsect_size(q);
long block = (long)rq->hard_sector / (hard_sect >> 9);
unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);
- memset(rq->cmd, 0, sizeof(rq->cmd));
+ memset(rq->cmd, 0, BLK_MAX_CDB);
if (rq_data_dir(rq) == READ)
rq->cmd[0] = GPCMD_READ_10;
@@ -1745,9 +1726,7 @@ static int ide_cdrom_prep_pc(struct request *rq)
{
u8 *c = rq->cmd;
- /*
- * Transform 6-byte read/write commands to the 10-byte version
- */
+ /* transform 6-byte read/write commands to the 10-byte version */
if (c[0] == READ_6 || c[0] == WRITE_6) {
c[8] = c[4];
c[5] = c[3];
@@ -1789,6 +1768,41 @@ struct cd_list_entry {
unsigned int cd_flags;
};
+#ifdef CONFIG_IDE_PROC_FS
+static sector_t ide_cdrom_capacity(ide_drive_t *drive)
+{
+ unsigned long capacity, sectors_per_frame;
+
+ if (cdrom_read_capacity(drive, &capacity, &sectors_per_frame, NULL))
+ return 0;
+
+ return capacity * sectors_per_frame;
+}
+
+static int proc_idecd_read_capacity(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ ide_drive_t *drive = data;
+ int len;
+
+ len = sprintf(page, "%llu\n", (long long)ide_cdrom_capacity(drive));
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+}
+
+static ide_proc_entry_t idecd_proc[] = {
+ { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
+ { NULL, 0, NULL, NULL }
+};
+
+static void ide_cdrom_add_settings(ide_drive_t *drive)
+{
+ ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1,
+ &drive->dsc_overlap, NULL);
+}
+#else
+static inline void ide_cdrom_add_settings(ide_drive_t *drive) { ; }
+#endif
+
static const struct cd_list_entry ide_cd_quirks_list[] = {
/* Limit transfer size per interrupt. */
{ "SAMSUNG CD-ROM SCR-2430", NULL, IDE_CD_FLAG_LIMIT_NFRAMES },
@@ -1846,8 +1860,7 @@ static unsigned int ide_cd_flags(struct hd_driveid *id)
return 0;
}
-static
-int ide_cdrom_setup(ide_drive_t *drive)
+static int ide_cdrom_setup(ide_drive_t *drive)
{
struct cdrom_info *cd = drive->driver_data;
struct cdrom_device_info *cdi = &cd->devinfo;
@@ -1876,21 +1889,19 @@ int ide_cdrom_setup(ide_drive_t *drive)
id->fw_rev[4] == '1' && id->fw_rev[6] <= '2')
cd->cd_flags |= IDE_CD_FLAG_TOCTRACKS_AS_BCD;
else if (cd->cd_flags & IDE_CD_FLAG_SANYO_3CD)
- cdi->sanyo_slot = 3; /* 3 => use CD in slot 0 */
+ /* 3 => use CD in slot 0 */
+ cdi->sanyo_slot = 3;
nslots = ide_cdrom_probe_capabilities(drive);
- /*
- * set correct block size
- */
+ /* set correct block size */
blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
- if (drive->autotune == IDE_TUNE_DEFAULT ||
- drive->autotune == IDE_TUNE_AUTO)
- drive->dsc_overlap = (drive->next != drive);
+ drive->dsc_overlap = (drive->next != drive);
if (ide_cdrom_register(drive, nslots)) {
- printk(KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
+ printk(KERN_ERR "%s: %s failed to register device with the"
+ " cdrom driver.\n", drive->name, __func__);
cd->devinfo.handle = NULL;
return 1;
}
@@ -1929,33 +1940,6 @@ static void ide_cd_release(struct kref *kref)
static int ide_cd_probe(ide_drive_t *);
-#ifdef CONFIG_IDE_PROC_FS
-static sector_t ide_cdrom_capacity(ide_drive_t *drive)
-{
- unsigned long capacity, sectors_per_frame;
-
- if (cdrom_read_capacity(drive, &capacity, &sectors_per_frame, NULL))
- return 0;
-
- return capacity * sectors_per_frame;
-}
-
-static int proc_idecd_read_capacity
- (char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- ide_drive_t *drive = data;
- int len;
-
- len = sprintf(page, "%llu\n", (long long)ide_cdrom_capacity(drive));
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
-}
-
-static ide_proc_entry_t idecd_proc[] = {
- { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
- { NULL, 0, NULL, NULL }
-};
-#endif
-
static ide_driver_t ide_cdrom_driver = {
.gen_driver = {
.owner = THIS_MODULE,
@@ -2093,7 +2077,7 @@ static struct block_device_operations idecd_ops = {
.revalidate_disk = idecd_revalidate_disk
};
-/* options */
+/* module options */
static char *ignore;
module_param(ignore, charp, 0400);
@@ -2114,17 +2098,20 @@ static int ide_cd_probe(ide_drive_t *drive)
/* skip drives that we were told to ignore */
if (ignore != NULL) {
if (strstr(ignore, drive->name)) {
- printk(KERN_INFO "ide-cd: ignoring drive %s\n", drive->name);
+ printk(KERN_INFO "ide-cd: ignoring drive %s\n",
+ drive->name);
goto failed;
}
}
if (drive->scsi) {
- printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
+ printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi "
+ "emulation.\n", drive->name);
goto failed;
}
info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
if (info == NULL) {
- printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
+ printk(KERN_ERR "%s: Can't allocate a cdrom structure\n",
+ drive->name);
goto failed;
}
diff --git a/drivers/ide/ide-cd_verbose.c b/drivers/ide/ide-cd_verbose.c
index 6ed7ca07133..6490a2dea96 100644
--- a/drivers/ide/ide-cd_verbose.c
+++ b/drivers/ide/ide-cd_verbose.c
@@ -326,7 +326,7 @@ void ide_cd_log_error(const char *name, struct request *failed_command,
printk(KERN_ERR " The failed \"%s\" packet command "
"was: \n \"", s);
- for (i = 0; i < sizeof(failed_command->cmd); i++)
+ for (i = 0; i < BLK_MAX_CDB; i++)
printk(KERN_CONT "%02x ", failed_command->cmd[i]);
printk(KERN_CONT "\"\n");
}
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 8757e5ef6c9..653b1ade13d 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -102,7 +102,7 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
{
u8 stat = 0, dma_stat = 0;
- dma_stat = HWIF(drive)->ide_dma_end(drive);
+ dma_stat = drive->hwif->dma_ops->dma_end(drive);
stat = ide_read_status(drive);
if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
@@ -394,7 +394,7 @@ void ide_dma_off_quietly(ide_drive_t *drive)
drive->using_dma = 0;
ide_toggle_bounce(drive, 0);
- drive->hwif->dma_host_set(drive, 0);
+ drive->hwif->dma_ops->dma_host_set(drive, 0);
}
EXPORT_SYMBOL(ide_dma_off_quietly);
@@ -427,7 +427,7 @@ void ide_dma_on(ide_drive_t *drive)
drive->using_dma = 1;
ide_toggle_bounce(drive, 1);
- drive->hwif->dma_host_set(drive, 1);
+ drive->hwif->dma_ops->dma_host_set(drive, 1);
}
#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
@@ -464,9 +464,10 @@ int ide_dma_setup(ide_drive_t *drive)
/* PRD table */
if (hwif->mmio)
- writel(hwif->dmatable_dma, (void __iomem *)hwif->dma_prdtable);
+ writel(hwif->dmatable_dma,
+ (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS));
else
- outl(hwif->dmatable_dma, hwif->dma_prdtable);
+ outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS);
/* specify r/w */
hwif->OUTB(reading, hwif->dma_command);
@@ -482,11 +483,12 @@ int ide_dma_setup(ide_drive_t *drive)
EXPORT_SYMBOL_GPL(ide_dma_setup);
-static void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
+void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
{
/* issue cmd to drive */
ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry);
}
+EXPORT_SYMBOL_GPL(ide_dma_exec_cmd);
void ide_dma_start(ide_drive_t *drive)
{
@@ -532,7 +534,7 @@ int __ide_dma_end (ide_drive_t *drive)
EXPORT_SYMBOL(__ide_dma_end);
/* returns 1 if dma irq issued, 0 otherwise */
-static int __ide_dma_test_irq(ide_drive_t *drive)
+int ide_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u8 dma_stat = hwif->INB(hwif->dma_status);
@@ -542,9 +544,10 @@ static int __ide_dma_test_irq(ide_drive_t *drive)
return 1;
if (!drive->waiting_for_dma)
printk(KERN_WARNING "%s: (%s) called while not waiting\n",
- drive->name, __FUNCTION__);
+ drive->name, __func__);
return 0;
}
+EXPORT_SYMBOL_GPL(ide_dma_test_irq);
#else
static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; }
#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
@@ -574,6 +577,7 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
{
struct hd_driveid *id = drive->id;
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
unsigned int mask = 0;
switch(base) {
@@ -581,8 +585,8 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
if ((id->field_valid & 4) == 0)
break;
- if (hwif->udma_filter)
- mask = hwif->udma_filter(drive);
+ if (port_ops && port_ops->udma_filter)
+ mask = port_ops->udma_filter(drive);
else
mask = hwif->ultra_mask;
mask &= id->dma_ultra;
@@ -598,8 +602,8 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
case XFER_MW_DMA_0:
if ((id->field_valid & 2) == 0)
break;
- if (hwif->mdma_filter)
- mask = hwif->mdma_filter(drive);
+ if (port_ops && port_ops->mdma_filter)
+ mask = port_ops->mdma_filter(drive);
else
mask = hwif->mwdma_mask;
mask &= id->dma_mword;
@@ -801,15 +805,15 @@ void ide_dma_timeout (ide_drive_t *drive)
printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
- if (hwif->ide_dma_test_irq(drive))
+ if (hwif->dma_ops->dma_test_irq(drive))
return;
- hwif->ide_dma_end(drive);
+ hwif->dma_ops->dma_end(drive);
}
EXPORT_SYMBOL(ide_dma_timeout);
-static void ide_release_dma_engine(ide_hwif_t *hwif)
+void ide_release_dma_engine(ide_hwif_t *hwif)
{
if (hwif->dmatable_cpu) {
struct pci_dev *pdev = to_pci_dev(hwif->dev);
@@ -820,28 +824,7 @@ static void ide_release_dma_engine(ide_hwif_t *hwif)
}
}
-static int ide_release_iomio_dma(ide_hwif_t *hwif)
-{
- release_region(hwif->dma_base, 8);
- if (hwif->extra_ports)
- release_region(hwif->extra_base, hwif->extra_ports);
- return 1;
-}
-
-/*
- * Needed for allowing full modular support of ide-driver
- */
-int ide_release_dma(ide_hwif_t *hwif)
-{
- ide_release_dma_engine(hwif);
-
- if (hwif->mmio)
- return 1;
- else
- return ide_release_iomio_dma(hwif);
-}
-
-static int ide_allocate_dma_engine(ide_hwif_t *hwif)
+int ide_allocate_dma_engine(ide_hwif_t *hwif)
{
struct pci_dev *pdev = to_pci_dev(hwif->dev);
@@ -853,99 +836,33 @@ static int ide_allocate_dma_engine(ide_hwif_t *hwif)
return 0;
printk(KERN_ERR "%s: -- Error, unable to allocate DMA table.\n",
- hwif->cds->name);
+ hwif->name);
return 1;
}
-
-static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base)
-{
- printk(KERN_INFO " %s: MMIO-DMA ", hwif->name);
-
- return 0;
-}
-
-static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base)
-{
- printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx",
- hwif->name, base, base + 7);
-
- if (!request_region(base, 8, hwif->name)) {
- printk(" -- Error, ports in use.\n");
- return 1;
- }
-
- if (hwif->cds->extra) {
- hwif->extra_base = base + (hwif->channel ? 8 : 16);
-
- if (!hwif->mate || !hwif->mate->extra_ports) {
- if (!request_region(hwif->extra_base,
- hwif->cds->extra, hwif->cds->name)) {
- printk(" -- Error, extra ports in use.\n");
- release_region(base, 8);
- return 1;
- }
- hwif->extra_ports = hwif->cds->extra;
- }
- }
-
- return 0;
-}
-
-static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base)
-{
- if (hwif->mmio)
- return ide_mapped_mmio_dma(hwif, base);
-
- return ide_iomio_dma(hwif, base);
-}
+EXPORT_SYMBOL_GPL(ide_allocate_dma_engine);
+
+static const struct ide_dma_ops sff_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = ide_dma_start,
+ .dma_end = __ide_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_timeout = ide_dma_timeout,
+ .dma_lost_irq = ide_dma_lost_irq,
+};
void ide_setup_dma(ide_hwif_t *hwif, unsigned long base)
{
- u8 dma_stat;
-
- if (ide_dma_iobase(hwif, base))
- return;
-
- if (ide_allocate_dma_engine(hwif)) {
- ide_release_dma(hwif);
- return;
- }
-
hwif->dma_base = base;
if (!hwif->dma_command)
hwif->dma_command = hwif->dma_base + 0;
- if (!hwif->dma_vendor1)
- hwif->dma_vendor1 = hwif->dma_base + 1;
if (!hwif->dma_status)
hwif->dma_status = hwif->dma_base + 2;
- if (!hwif->dma_vendor3)
- hwif->dma_vendor3 = hwif->dma_base + 3;
- if (!hwif->dma_prdtable)
- hwif->dma_prdtable = hwif->dma_base + 4;
-
- if (!hwif->dma_host_set)
- hwif->dma_host_set = &ide_dma_host_set;
- if (!hwif->dma_setup)
- hwif->dma_setup = &ide_dma_setup;
- if (!hwif->dma_exec_cmd)
- hwif->dma_exec_cmd = &ide_dma_exec_cmd;
- if (!hwif->dma_start)
- hwif->dma_start = &ide_dma_start;
- if (!hwif->ide_dma_end)
- hwif->ide_dma_end = &__ide_dma_end;
- if (!hwif->ide_dma_test_irq)
- hwif->ide_dma_test_irq = &__ide_dma_test_irq;
- if (!hwif->dma_timeout)
- hwif->dma_timeout = &ide_dma_timeout;
- if (!hwif->dma_lost_irq)
- hwif->dma_lost_irq = &ide_dma_lost_irq;
- dma_stat = hwif->INB(hwif->dma_status);
- printk(KERN_CONT ", BIOS settings: %s:%s, %s:%s\n",
- hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "PIO",
- hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "PIO");
+ hwif->dma_ops = &sff_dma_ops;
}
EXPORT_SYMBOL_GPL(ide_setup_dma);
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index ed19a8bbd2d..f05fbc2bd7a 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -231,6 +231,7 @@ static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount, int direction)
{
+ ide_hwif_t *hwif = drive->hwif;
struct request *rq = pc->rq;
struct req_iterator iter;
struct bio_vec *bvec;
@@ -246,9 +247,9 @@ static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
data = bvec_kmap_irq(bvec, &flags);
if (direction)
- drive->hwif->atapi_output_bytes(drive, data, count);
+ hwif->output_data(drive, NULL, data, count);
else
- drive->hwif->atapi_input_bytes(drive, data, count);
+ hwif->input_data(drive, NULL, data, count);
bvec_kunmap_irq(data, &flags);
bcount -= count;
@@ -261,10 +262,7 @@ static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
if (bcount) {
printk(KERN_ERR "%s: leftover data in %s, bcount == %d\n",
drive->name, __func__, bcount);
- if (direction)
- ide_atapi_write_zeros(drive, bcount);
- else
- ide_atapi_discard_data(drive, bcount);
+ ide_pad_transfer(drive, direction, bcount);
}
}
@@ -411,7 +409,7 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
debug_log("Reached %s interrupt handler\n", __func__);
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- dma_error = hwif->ide_dma_end(drive);
+ dma_error = hwif->dma_ops->dma_end(drive);
if (dma_error) {
printk(KERN_ERR "%s: DMA %s error\n", drive->name,
rq_data_dir(rq) ? "write" : "read");
@@ -465,10 +463,10 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
}
/* Get the number of bytes to transfer */
- bcount = (hwif->INB(hwif->io_ports[IDE_BCOUNTH_OFFSET]) << 8) |
- hwif->INB(hwif->io_ports[IDE_BCOUNTL_OFFSET]);
+ bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
+ hwif->INB(hwif->io_ports.lbam_addr);
/* on this interrupt */
- ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
if (ireason & CD) {
printk(KERN_ERR "ide-floppy: CoD != 0 in %s\n", __func__);
@@ -490,7 +488,7 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
printk(KERN_ERR "ide-floppy: The floppy wants "
"to send us more data than expected "
"- discarding data\n");
- ide_atapi_discard_data(drive, bcount);
+ ide_pad_transfer(drive, 0, bcount);
ide_set_handler(drive,
&idefloppy_pc_intr,
@@ -503,12 +501,12 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
}
}
if (pc->flags & PC_FLAG_WRITING)
- xferfunc = hwif->atapi_output_bytes;
+ xferfunc = hwif->output_data;
else
- xferfunc = hwif->atapi_input_bytes;
+ xferfunc = hwif->input_data;
if (pc->buf)
- xferfunc(drive, pc->cur_pos, bcount);
+ xferfunc(drive, NULL, pc->cur_pos, bcount);
else
ide_floppy_io_buffers(drive, pc, bcount,
!!(pc->flags & PC_FLAG_WRITING));
@@ -539,7 +537,7 @@ static ide_startstop_t idefloppy_transfer_pc(ide_drive_t *drive)
"initiated yet DRQ isn't asserted\n");
return startstop;
}
- ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
if ((ireason & CD) == 0 || (ireason & IO)) {
printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while "
"issuing a packet command\n");
@@ -548,8 +546,10 @@ static ide_startstop_t idefloppy_transfer_pc(ide_drive_t *drive)
/* Set the interrupt routine */
ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);
+
/* Send the actual packet */
- HWIF(drive)->atapi_output_bytes(drive, floppy->pc->c, 12);
+ hwif->output_data(drive, NULL, floppy->pc->c, 12);
+
return ide_started;
}
@@ -569,7 +569,8 @@ static int idefloppy_transfer_pc2(ide_drive_t *drive)
idefloppy_floppy_t *floppy = drive->driver_data;
/* Send the actual packet */
- HWIF(drive)->atapi_output_bytes(drive, floppy->pc->c, 12);
+ drive->hwif->output_data(drive, NULL, floppy->pc->c, 12);
+
/* Timeout for the packet command */
return IDEFLOPPY_WAIT_CMD;
}
@@ -586,7 +587,7 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive)
"initiated yet DRQ isn't asserted\n");
return startstop;
}
- ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
if ((ireason & CD) == 0 || (ireason & IO)) {
printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) "
"while issuing a packet command\n");
@@ -663,7 +664,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
dma = 0;
if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma)
- dma = !hwif->dma_setup(drive);
+ dma = !hwif->dma_ops->dma_setup(drive);
ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK |
IDE_TFLAG_OUT_DEVICE, bcount, dma);
@@ -671,7 +672,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
if (dma) {
/* Begin DMA, if necessary */
pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
- hwif->dma_start(drive);
+ hwif->dma_ops->dma_start(drive);
}
/* Can we transfer the packet when we get the interrupt or wait? */
@@ -692,7 +693,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
return ide_started;
} else {
/* Issue the packet command */
- hwif->OUTB(WIN_PACKETCMD, hwif->io_ports[IDE_COMMAND_OFFSET]);
+ ide_execute_pkt_cmd(drive);
return (*pkt_xfer_routine) (drive);
}
}
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index 19f63e393d1..a6073e248f4 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -94,7 +94,24 @@ static int __init ide_generic_init(void)
unsigned long io_addr = ide_default_io_base(i);
hw_regs_t hw;
+ idx[i] = 0xff;
+
if (io_addr) {
+ if (!request_region(io_addr, 8, DRV_NAME)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX "
+ "not free.\n",
+ DRV_NAME, io_addr, io_addr + 7);
+ continue;
+ }
+
+ if (!request_region(io_addr + 0x206, 1, DRV_NAME)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX "
+ "not free.\n",
+ DRV_NAME, io_addr + 0x206);
+ release_region(io_addr, 8);
+ continue;
+ }
+
/*
* Skip probing if the corresponding
* slot is already occupied.
@@ -111,8 +128,7 @@ static int __init ide_generic_init(void)
ide_init_port_hw(hwif, &hw);
idx[i] = i;
- } else
- idx[i] = 0xff;
+ }
}
ide_device_add_all(idx, NULL);
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 51d181ee9cf..696525342e9 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -218,7 +218,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
* we could be smarter and check for current xfer_speed
* in struct drive etc...
*/
- if (drive->hwif->dma_host_set == NULL)
+ if (drive->hwif->dma_ops == NULL)
break;
/*
* TODO: respect ->using_dma setting
@@ -295,54 +295,6 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
spin_unlock_irqrestore(&ide_lock, flags);
}
-void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data = hwif->INW(hwif->io_ports[IDE_DATA_OFFSET]);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
- /* be sure we're looking at the low order bits */
- hwif->OUTB(drive->ctl & ~0x80, hwif->io_ports[IDE_CONTROL_OFFSET]);
-
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
- tf->nsect = hwif->INB(hwif->io_ports[IDE_NSECTOR_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
- tf->lbal = hwif->INB(hwif->io_ports[IDE_SECTOR_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
- tf->lbam = hwif->INB(hwif->io_ports[IDE_LCYL_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
- tf->lbah = hwif->INB(hwif->io_ports[IDE_HCYL_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
- tf->device = hwif->INB(hwif->io_ports[IDE_SELECT_OFFSET]);
-
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- hwif->OUTB(drive->ctl | 0x80,
- hwif->io_ports[IDE_CONTROL_OFFSET]);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature =
- hwif->INB(hwif->io_ports[IDE_FEATURE_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect =
- hwif->INB(hwif->io_ports[IDE_NSECTOR_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal =
- hwif->INB(hwif->io_ports[IDE_SECTOR_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam =
- hwif->INB(hwif->io_ports[IDE_LCYL_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah =
- hwif->INB(hwif->io_ports[IDE_HCYL_OFFSET]);
- }
-}
-
/**
* ide_end_drive_cmd - end an explicit drive command
* @drive: command
@@ -378,7 +330,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
tf->error = err;
tf->status = stat;
- ide_tf_read(drive, task);
+ drive->hwif->tf_read(drive, task);
if (task->tf_flags & IDE_TFLAG_DYN)
kfree(task);
@@ -427,7 +379,7 @@ static void try_to_flush_leftover_data (ide_drive_t *drive)
u32 wcount = (i > 16) ? 16 : i;
i -= wcount;
- HWIF(drive)->ata_input_data(drive, buffer, wcount);
+ drive->hwif->input_data(drive, NULL, buffer, wcount * 4);
}
}
@@ -454,7 +406,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
if (err == ABRT_ERR) {
if (drive->select.b.lba &&
/* some newer drives don't support WIN_SPECIFY */
- hwif->INB(hwif->io_ports[IDE_COMMAND_OFFSET]) ==
+ hwif->INB(hwif->io_ports.command_addr) ==
WIN_SPECIFY)
return ide_stopped;
} else if ((err & BAD_CRC) == BAD_CRC) {
@@ -507,8 +459,8 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u
if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
/* force an abort */
- hwif->OUTB(WIN_IDLEIMMEDIATE,
- hwif->io_ports[IDE_COMMAND_OFFSET]);
+ hwif->OUTBSYNC(drive, WIN_IDLEIMMEDIATE,
+ hwif->io_ports.command_addr);
if (rq->errors >= ERROR_MAX) {
ide_kill_rq(drive, rq);
@@ -721,6 +673,7 @@ static ide_startstop_t do_special (ide_drive_t *drive)
#endif
if (s->b.set_tune) {
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
u8 req_pio = drive->tune_req;
s->b.set_tune = 0;
@@ -733,10 +686,10 @@ static ide_startstop_t do_special (ide_drive_t *drive)
unsigned long flags;
spin_lock_irqsave(&ide_lock, flags);
- hwif->set_pio_mode(drive, req_pio);
+ port_ops->set_pio_mode(drive, req_pio);
spin_unlock_irqrestore(&ide_lock, flags);
} else
- hwif->set_pio_mode(drive, req_pio);
+ port_ops->set_pio_mode(drive, req_pio);
} else {
int keep_dma = drive->using_dma;
@@ -1237,12 +1190,12 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
if (error < 0) {
printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
- (void)HWIF(drive)->ide_dma_end(drive);
+ (void)hwif->dma_ops->dma_end(drive);
ret = ide_error(drive, "dma timeout error",
ide_read_status(drive));
} else {
printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
- hwif->dma_timeout(drive);
+ hwif->dma_ops->dma_timeout(drive);
}
/*
@@ -1354,7 +1307,7 @@ void ide_timer_expiry (unsigned long data)
startstop = handler(drive);
} else if (drive_is_ready(drive)) {
if (drive->waiting_for_dma)
- hwgroup->hwif->dma_lost_irq(drive);
+ hwif->dma_ops->dma_lost_irq(drive);
(void)ide_ack_intr(hwif);
printk(KERN_WARNING "%s: lost interrupt\n", drive->name);
startstop = handler(drive);
@@ -1420,7 +1373,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
*/
do {
if (hwif->irq == irq) {
- stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+ stat = hwif->INB(hwif->io_ports.status_addr);
if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {
/* Try to not flood the console with msgs */
static unsigned long last_msgtime, count;
@@ -1510,7 +1463,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
* Whack the status register, just in case
* we have a leftover pending IRQ.
*/
- (void) hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+ (void) hwif->INB(hwif->io_ports.status_addr);
#endif /* CONFIG_BLK_DEV_IDEPCI */
}
spin_unlock_irqrestore(&ide_lock, flags);
@@ -1597,8 +1550,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
void ide_init_drive_cmd (struct request *rq)
{
- memset(rq, 0, sizeof(*rq));
- rq->ref_count = 1;
+ blk_rq_init(NULL, rq);
}
EXPORT_SYMBOL(ide_init_drive_cmd);
@@ -1684,7 +1636,23 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
task.tf.lbam = bcount & 0xff;
task.tf.lbah = (bcount >> 8) & 0xff;
- ide_tf_load(drive, &task);
+ ide_tf_dump(drive->name, &task.tf);
+ drive->hwif->tf_load(drive, &task);
}
EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load);
+
+void ide_pad_transfer(ide_drive_t *drive, int write, int len)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 buf[4] = { 0 };
+
+ while (len > 0) {
+ if (write)
+ hwif->output_data(drive, NULL, buf, min(4, len));
+ else
+ hwif->input_data(drive, NULL, buf, min(4, len));
+ len -= 4;
+ }
+}
+EXPORT_SYMBOL_GPL(ide_pad_transfer);
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 45944219eea..57d9a9a79a6 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -37,21 +37,6 @@ static u8 ide_inb (unsigned long port)
return (u8) inb(port);
}
-static u16 ide_inw (unsigned long port)
-{
- return (u16) inw(port);
-}
-
-static void ide_insw (unsigned long port, void *addr, u32 count)
-{
- insw(port, addr, count);
-}
-
-static void ide_insl (unsigned long port, void *addr, u32 count)
-{
- insl(port, addr, count);
-}
-
static void ide_outb (u8 val, unsigned long port)
{
outb(val, port);
@@ -62,32 +47,11 @@ static void ide_outbsync (ide_drive_t *drive, u8 addr, unsigned long port)
outb(addr, port);
}
-static void ide_outw (u16 val, unsigned long port)
-{
- outw(val, port);
-}
-
-static void ide_outsw (unsigned long port, void *addr, u32 count)
-{
- outsw(port, addr, count);
-}
-
-static void ide_outsl (unsigned long port, void *addr, u32 count)
-{
- outsl(port, addr, count);
-}
-
void default_hwif_iops (ide_hwif_t *hwif)
{
hwif->OUTB = ide_outb;
hwif->OUTBSYNC = ide_outbsync;
- hwif->OUTW = ide_outw;
- hwif->OUTSW = ide_outsw;
- hwif->OUTSL = ide_outsl;
hwif->INB = ide_inb;
- hwif->INW = ide_inw;
- hwif->INSW = ide_insw;
- hwif->INSL = ide_insl;
}
/*
@@ -99,21 +63,6 @@ static u8 ide_mm_inb (unsigned long port)
return (u8) readb((void __iomem *) port);
}
-static u16 ide_mm_inw (unsigned long port)
-{
- return (u16) readw((void __iomem *) port);
-}
-
-static void ide_mm_insw (unsigned long port, void *addr, u32 count)
-{
- __ide_mm_insw((void __iomem *) port, addr, count);
-}
-
-static void ide_mm_insl (unsigned long port, void *addr, u32 count)
-{
- __ide_mm_insl((void __iomem *) port, addr, count);
-}
-
static void ide_mm_outb (u8 value, unsigned long port)
{
writeb(value, (void __iomem *) port);
@@ -124,34 +73,13 @@ static void ide_mm_outbsync (ide_drive_t *drive, u8 value, unsigned long port)
writeb(value, (void __iomem *) port);
}
-static void ide_mm_outw (u16 value, unsigned long port)
-{
- writew(value, (void __iomem *) port);
-}
-
-static void ide_mm_outsw (unsigned long port, void *addr, u32 count)
-{
- __ide_mm_outsw((void __iomem *) port, addr, count);
-}
-
-static void ide_mm_outsl (unsigned long port, void *addr, u32 count)
-{
- __ide_mm_outsl((void __iomem *) port, addr, count);
-}
-
void default_hwif_mmiops (ide_hwif_t *hwif)
{
hwif->OUTB = ide_mm_outb;
/* Most systems will need to override OUTBSYNC, alas however
this one is controller specific! */
hwif->OUTBSYNC = ide_mm_outbsync;
- hwif->OUTW = ide_mm_outw;
- hwif->OUTSW = ide_mm_outsw;
- hwif->OUTSL = ide_mm_outsl;
hwif->INB = ide_mm_inb;
- hwif->INW = ide_mm_inw;
- hwif->INSW = ide_mm_insw;
- hwif->INSL = ide_mm_insl;
}
EXPORT_SYMBOL(default_hwif_mmiops);
@@ -159,17 +87,137 @@ EXPORT_SYMBOL(default_hwif_mmiops);
void SELECT_DRIVE (ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
- if (hwif->selectproc)
- hwif->selectproc(drive);
+ if (port_ops && port_ops->selectproc)
+ port_ops->selectproc(drive);
- hwif->OUTB(drive->select.all, hwif->io_ports[IDE_SELECT_OFFSET]);
+ hwif->OUTB(drive->select.all, hwif->io_ports.device_addr);
}
void SELECT_MASK (ide_drive_t *drive, int mask)
{
- if (HWIF(drive)->maskproc)
- HWIF(drive)->maskproc(drive, mask);
+ const struct ide_port_ops *port_ops = drive->hwif->port_ops;
+
+ if (port_ops && port_ops->maskproc)
+ port_ops->maskproc(drive, mask);
+}
+
+static 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;
+
+ ide_set_irq(drive, 1);
+
+ if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0)
+ SELECT_MASK(drive, 0);
+
+ 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.all,
+ io_ports->device_addr);
+}
+
+static 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(drive->ctl & ~0x80, io_ports->ctl_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(drive->ctl | 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);
+ }
}
/*
@@ -179,115 +227,112 @@ void SELECT_MASK (ide_drive_t *drive, int mask)
* of the sector count register location, with interrupts disabled
* to ensure that the reads all happen together.
*/
-static void ata_vlb_sync(ide_drive_t *drive, unsigned long port)
+static void ata_vlb_sync(unsigned long port)
{
- (void) HWIF(drive)->INB(port);
- (void) HWIF(drive)->INB(port);
- (void) HWIF(drive)->INB(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.
*/
-static void ata_input_data(ide_drive_t *drive, void *buffer, u32 wcount)
+static void ata_input_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
{
- ide_hwif_t *hwif = HWIF(drive);
- u8 io_32bit = drive->io_32bit;
+ 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) {
- if (io_32bit & 2) {
- unsigned long flags;
+ unsigned long uninitialized_var(flags);
+ if ((io_32bit & 2) && !mmio) {
local_irq_save(flags);
- ata_vlb_sync(drive, hwif->io_ports[IDE_NSECTOR_OFFSET]);
- hwif->INSL(hwif->io_ports[IDE_DATA_OFFSET], buffer,
- wcount);
+ 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);
- } else
- hwif->INSL(hwif->io_ports[IDE_DATA_OFFSET], buffer,
- wcount);
- } else
- hwif->INSW(hwif->io_ports[IDE_DATA_OFFSET], buffer,
- wcount << 1);
+
+ 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);
+ }
}
/*
* This is used for most PIO data transfers *to* the IDE interface
*/
-static void ata_output_data(ide_drive_t *drive, void *buffer, u32 wcount)
+static void ata_output_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
{
- ide_hwif_t *hwif = HWIF(drive);
- u8 io_32bit = drive->io_32bit;
+ 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) {
- if (io_32bit & 2) {
- unsigned long flags;
+ unsigned long uninitialized_var(flags);
+ if ((io_32bit & 2) && !mmio) {
local_irq_save(flags);
- ata_vlb_sync(drive, hwif->io_ports[IDE_NSECTOR_OFFSET]);
- hwif->OUTSL(hwif->io_ports[IDE_DATA_OFFSET], buffer,
- wcount);
- local_irq_restore(flags);
- } else
- hwif->OUTSL(hwif->io_ports[IDE_DATA_OFFSET], buffer,
- wcount);
- } else
- hwif->OUTSW(hwif->io_ports[IDE_DATA_OFFSET], buffer,
- wcount << 1);
-}
-
-/*
- * The following routines are mainly used by the ATAPI drivers.
- *
- * These routines will round up any request for an odd number of bytes,
- * so if an odd bytecount is specified, be sure that there's at least one
- * extra byte allocated for the buffer.
- */
-
-static void atapi_input_bytes(ide_drive_t *drive, void *buffer, u32 bytecount)
-{
- ide_hwif_t *hwif = HWIF(drive);
+ ata_vlb_sync(io_ports->nsect_addr);
+ }
- ++bytecount;
-#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
- if (MACH_IS_ATARI || MACH_IS_Q40) {
- /* Atari has a byte-swapped IDE interface */
- insw_swapw(hwif->io_ports[IDE_DATA_OFFSET], buffer,
- bytecount / 2);
- return;
- }
-#endif /* CONFIG_ATARI || CONFIG_Q40 */
- hwif->ata_input_data(drive, buffer, bytecount / 4);
- if ((bytecount & 0x03) >= 2)
- hwif->INSW(hwif->io_ports[IDE_DATA_OFFSET],
- (u8 *)buffer + (bytecount & ~0x03), 1);
-}
+ if (mmio)
+ __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
+ else
+ outsl(data_addr, buf, len / 4);
-static void atapi_output_bytes(ide_drive_t *drive, void *buffer, u32 bytecount)
-{
- ide_hwif_t *hwif = HWIF(drive);
+ if ((io_32bit & 2) && !mmio)
+ local_irq_restore(flags);
- ++bytecount;
-#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
- if (MACH_IS_ATARI || MACH_IS_Q40) {
- /* Atari has a byte-swapped IDE interface */
- outsw_swapw(hwif->io_ports[IDE_DATA_OFFSET], buffer,
- bytecount / 2);
- return;
+ 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);
}
-#endif /* CONFIG_ATARI || CONFIG_Q40 */
- hwif->ata_output_data(drive, buffer, bytecount / 4);
- if ((bytecount & 0x03) >= 2)
- hwif->OUTSW(hwif->io_ports[IDE_DATA_OFFSET],
- (u8 *)buffer + (bytecount & ~0x03), 1);
}
void default_hwif_transport(ide_hwif_t *hwif)
{
- hwif->ata_input_data = ata_input_data;
- hwif->ata_output_data = ata_output_data;
- hwif->atapi_input_bytes = atapi_input_bytes;
- hwif->atapi_output_bytes = atapi_output_bytes;
+ hwif->tf_load = ide_tf_load;
+ hwif->tf_read = ide_tf_read;
+
+ hwif->input_data = ata_input_data;
+ hwif->output_data = ata_output_data;
}
void ide_fix_driveid (struct hd_driveid *id)
@@ -429,7 +474,7 @@ int drive_is_ready (ide_drive_t *drive)
u8 stat = 0;
if (drive->waiting_for_dma)
- return hwif->ide_dma_test_irq(drive);
+ return hwif->dma_ops->dma_test_irq(drive);
#if 0
/* need to guarantee 400ns since last command was issued */
@@ -442,7 +487,7 @@ int drive_is_ready (ide_drive_t *drive)
* an interrupt with another pci card/device. We make no assumptions
* about possible isa-pnp and pci-pnp issues yet.
*/
- if (hwif->io_ports[IDE_CONTROL_OFFSET])
+ if (hwif->io_ports.ctl_addr)
stat = ide_read_altstatus(drive);
else
/* Note: this may clear a pending IRQ!! */
@@ -580,6 +625,8 @@ static const struct drive_list_entry ivb_list[] = {
{ "TSSTcorp CDDVDW SH-S202J" , "SB01" },
{ "TSSTcorp CDDVDW SH-S202N" , "SB00" },
{ "TSSTcorp CDDVDW SH-S202N" , "SB01" },
+ { "TSSTcorp CDDVDW SH-S202H" , "SB00" },
+ { "TSSTcorp CDDVDW SH-S202H" , "SB01" },
{ NULL , NULL }
};
@@ -644,7 +691,7 @@ int ide_driveid_update(ide_drive_t *drive)
SELECT_MASK(drive, 1);
ide_set_irq(drive, 1);
msleep(50);
- hwif->OUTB(WIN_IDENTIFY, hwif->io_ports[IDE_COMMAND_OFFSET]);
+ hwif->OUTBSYNC(drive, WIN_IDENTIFY, hwif->io_ports.command_addr);
timeout = jiffies + WAIT_WORSTCASE;
do {
if (time_after(jiffies, timeout)) {
@@ -671,7 +718,7 @@ int ide_driveid_update(ide_drive_t *drive)
local_irq_restore(flags);
return 0;
}
- hwif->ata_input_data(drive, id, SECTOR_WORDS);
+ hwif->input_data(drive, NULL, id, SECTOR_SIZE);
(void)ide_read_status(drive); /* clear drive IRQ */
local_irq_enable();
local_irq_restore(flags);
@@ -693,6 +740,7 @@ int ide_driveid_update(ide_drive_t *drive)
int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
{
ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
int error = 0;
u8 stat;
@@ -700,8 +748,8 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
// msleep(50);
#ifdef CONFIG_BLK_DEV_IDEDMA
- if (hwif->dma_host_set) /* check if host supports DMA */
- hwif->dma_host_set(drive, 0);
+ if (hwif->dma_ops) /* check if host supports DMA */
+ hwif->dma_ops->dma_host_set(drive, 0);
#endif
/* Skip setting PIO flow-control modes on pre-EIDE drives */
@@ -731,10 +779,9 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
SELECT_MASK(drive, 0);
udelay(1);
ide_set_irq(drive, 0);
- hwif->OUTB(speed, hwif->io_ports[IDE_NSECTOR_OFFSET]);
- hwif->OUTB(SETFEATURES_XFER, hwif->io_ports[IDE_FEATURE_OFFSET]);
- hwif->OUTBSYNC(drive, WIN_SETFEATURES,
- hwif->io_ports[IDE_COMMAND_OFFSET]);
+ hwif->OUTB(speed, io_ports->nsect_addr);
+ hwif->OUTB(SETFEATURES_XFER, io_ports->feature_addr);
+ hwif->OUTBSYNC(drive, WIN_SETFEATURES, io_ports->command_addr);
if (drive->quirk_list == 2)
ide_set_irq(drive, 1);
@@ -759,8 +806,8 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
#ifdef CONFIG_BLK_DEV_IDEDMA
if ((speed >= XFER_SW_DMA_0 || (hwif->host_flags & IDE_HFLAG_VDMA)) &&
drive->using_dma)
- hwif->dma_host_set(drive, 1);
- else if (hwif->dma_host_set) /* check if host supports DMA */
+ hwif->dma_ops->dma_host_set(drive, 1);
+ else if (hwif->dma_ops) /* check if host supports DMA */
ide_dma_off_quietly(drive);
#endif
@@ -842,7 +889,7 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
spin_lock_irqsave(&ide_lock, flags);
__ide_set_handler(drive, handler, timeout, expiry);
- hwif->OUTBSYNC(drive, cmd, hwif->io_ports[IDE_COMMAND_OFFSET]);
+ hwif->OUTBSYNC(drive, cmd, hwif->io_ports.command_addr);
/*
* Drive takes 400nS to respond, we must avoid the IRQ being
* serviced before that.
@@ -852,9 +899,19 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
ndelay(400);
spin_unlock_irqrestore(&ide_lock, flags);
}
-
EXPORT_SYMBOL(ide_execute_command);
+void ide_execute_pkt_cmd(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ide_lock, flags);
+ hwif->OUTBSYNC(drive, WIN_PACKETCMD, hwif->io_ports.command_addr);
+ ndelay(400);
+ spin_unlock_irqrestore(&ide_lock, flags);
+}
+EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd);
/* needed below */
static ide_startstop_t do_reset1 (ide_drive_t *, int);
@@ -905,10 +962,11 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
ide_hwif_t *hwif = HWIF(drive);
+ const struct ide_port_ops *port_ops = hwif->port_ops;
u8 tmp;
- if (hwif->reset_poll != NULL) {
- if (hwif->reset_poll(drive)) {
+ if (port_ops && port_ops->reset_poll) {
+ if (port_ops->reset_poll(drive)) {
printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
hwif->name, drive->name);
return ide_stopped;
@@ -974,6 +1032,8 @@ static void ide_disk_pre_reset(ide_drive_t *drive)
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
@@ -994,8 +1054,8 @@ static void pre_reset(ide_drive_t *drive)
return;
}
- if (HWIF(drive)->pre_reset != NULL)
- HWIF(drive)->pre_reset(drive);
+ if (port_ops && port_ops->pre_reset)
+ port_ops->pre_reset(drive);
if (drive->current_speed != 0xff)
drive->desired_speed = drive->current_speed;
@@ -1023,12 +1083,16 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
unsigned long flags;
ide_hwif_t *hwif;
ide_hwgroup_t *hwgroup;
+ struct ide_io_ports *io_ports;
+ const struct ide_port_ops *port_ops;
u8 ctl;
spin_lock_irqsave(&ide_lock, flags);
hwif = HWIF(drive);
hwgroup = HWGROUP(drive);
+ io_ports = &hwif->io_ports;
+
/* We must not reset with running handlers */
BUG_ON(hwgroup->handler != NULL);
@@ -1038,8 +1102,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
pre_reset(drive);
SELECT_DRIVE(drive);
udelay (20);
- hwif->OUTBSYNC(drive, WIN_SRST,
- hwif->io_ports[IDE_COMMAND_OFFSET]);
+ hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr);
ndelay(400);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
hwgroup->polling = 1;
@@ -1055,7 +1118,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
for (unit = 0; unit < MAX_DRIVES; ++unit)
pre_reset(&hwif->drives[unit]);
- if (hwif->io_ports[IDE_CONTROL_OFFSET] == 0) {
+ if (io_ports->ctl_addr == 0) {
spin_unlock_irqrestore(&ide_lock, flags);
return ide_stopped;
}
@@ -1070,14 +1133,14 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
* recover from reset very quickly, saving us the first 50ms wait time.
*/
/* set SRST and nIEN */
- hwif->OUTBSYNC(drive, drive->ctl|6, hwif->io_ports[IDE_CONTROL_OFFSET]);
+ hwif->OUTBSYNC(drive, drive->ctl|6, io_ports->ctl_addr);
/* more than enough time */
udelay(10);
if (drive->quirk_list == 2)
ctl = drive->ctl; /* clear SRST and nIEN */
else
ctl = drive->ctl | 2; /* clear SRST, leave nIEN */
- hwif->OUTBSYNC(drive, ctl, hwif->io_ports[IDE_CONTROL_OFFSET]);
+ hwif->OUTBSYNC(drive, ctl, io_ports->ctl_addr);
/* more than enough time */
udelay(10);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
@@ -1089,8 +1152,9 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
* state when the disks are reset this way. At least, the Winbond
* 553 documentation says that
*/
- if (hwif->resetproc)
- hwif->resetproc(drive);
+ port_ops = hwif->port_ops;
+ if (port_ops && port_ops->resetproc)
+ port_ops->resetproc(drive);
spin_unlock_irqrestore(&ide_lock, flags);
return ide_started;
@@ -1121,7 +1185,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout)
* about locking issues (2.5 work ?).
*/
mdelay(1);
- stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+ stat = hwif->INB(hwif->io_ports.status_addr);
if ((stat & BUSY_STAT) == 0)
return 0;
/*
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index c859de77aa8..47af80df687 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -85,7 +85,7 @@ static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
mode = XFER_PIO_4;
}
-// printk("%s: mode 0x%02x, speed 0x%02x\n", __FUNCTION__, mode, speed);
+/* printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */
return min(speed, mode);
}
@@ -288,9 +288,10 @@ EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
void ide_set_pio(ide_drive_t *drive, u8 req_pio)
{
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
u8 host_pio, pio;
- if (hwif->set_pio_mode == NULL ||
+ if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
(hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
return;
@@ -343,29 +344,30 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
{
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
return 0;
- if (hwif->set_pio_mode == NULL)
+ if (port_ops == NULL || port_ops->set_pio_mode == NULL)
return -1;
/*
* TODO: temporary hack for some legacy host drivers that didn't
* set transfer mode on the device in ->set_pio_mode method...
*/
- if (hwif->set_dma_mode == NULL) {
- hwif->set_pio_mode(drive, mode - XFER_PIO_0);
+ if (port_ops->set_dma_mode == NULL) {
+ port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
return 0;
}
if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
if (ide_config_drive_speed(drive, mode))
return -1;
- hwif->set_pio_mode(drive, mode - XFER_PIO_0);
+ port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
return 0;
} else {
- hwif->set_pio_mode(drive, mode - XFER_PIO_0);
+ port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
return ide_config_drive_speed(drive, mode);
}
}
@@ -373,20 +375,21 @@ int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
{
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
return 0;
- if (hwif->set_dma_mode == NULL)
+ if (port_ops == NULL || port_ops->set_dma_mode == NULL)
return -1;
if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
if (ide_config_drive_speed(drive, mode))
return -1;
- hwif->set_dma_mode(drive, mode);
+ port_ops->set_dma_mode(drive, mode);
return 0;
} else {
- hwif->set_dma_mode(drive, mode);
+ port_ops->set_dma_mode(drive, mode);
return ide_config_drive_speed(drive, mode);
}
}
@@ -406,8 +409,9 @@ EXPORT_SYMBOL_GPL(ide_set_dma_mode);
int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
{
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
- if (hwif->set_dma_mode == NULL ||
+ if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
(hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
return -1;
@@ -483,7 +487,7 @@ static void ide_dump_sector(ide_drive_t *drive)
else
task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
- ide_tf_read(drive, &task);
+ drive->hwif->tf_read(drive, &task);
if (lba48 || (tf->device & ATA_LBA))
printk(", LBAsect=%llu",
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
index 8a178a55a02..6a8953f68e9 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -18,6 +18,8 @@
#include <linux/pnp.h>
#include <linux/ide.h>
+#define DRV_NAME "ide-pnp"
+
/* Add your devices here :)) */
static struct pnp_device_id idepnp_devices[] = {
/* Generic ESDI/IDE/ATA compatible hard disk controller */
@@ -29,13 +31,29 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
hw_regs_t hw;
ide_hwif_t *hwif;
+ unsigned long base, ctl;
if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0)))
return -1;
+ base = pnp_port_start(dev, 0);
+ ctl = pnp_port_start(dev, 1);
+
+ if (!request_region(base, 8, DRV_NAME)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
+ DRV_NAME, base, base + 7);
+ return -EBUSY;
+ }
+
+ if (!request_region(ctl, 1, DRV_NAME)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
+ DRV_NAME, ctl);
+ release_region(base, 8);
+ return -EBUSY;
+ }
+
memset(&hw, 0, sizeof(hw));
- ide_std_init_ports(&hw, pnp_port_start(dev, 0),
- pnp_port_start(dev, 1));
+ ide_std_init_ports(&hw, base, ctl);
hw.irq = pnp_irq(dev, 0);
hwif = ide_find_port();
@@ -54,6 +72,9 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
return 0;
}
+ release_region(ctl, 1);
+ release_region(base, 8);
+
return -1;
}
@@ -61,10 +82,10 @@ static void idepnp_remove(struct pnp_dev *dev)
{
ide_hwif_t *hwif = pnp_get_drvdata(dev);
- if (hwif)
- ide_unregister(hwif->index);
- else
- printk(KERN_ERR "idepnp: Unable to remove device, please report.\n");
+ ide_unregister(hwif);
+
+ release_region(pnp_port_start(dev, 1), 1);
+ release_region(pnp_port_start(dev, 0), 8);
}
static struct pnp_driver idepnp_driver = {
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 87542972802..591deda3f86 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -124,7 +124,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
id = drive->id;
/* read 512 bytes of id info */
- hwif->ata_input_data(drive, id, SECTOR_WORDS);
+ hwif->input_data(drive, NULL, id, SECTOR_SIZE);
drive->id_read = 1;
local_irq_enable();
@@ -264,6 +264,7 @@ err_misc:
static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
{
ide_hwif_t *hwif = HWIF(drive);
+ struct ide_io_ports *io_ports = &hwif->io_ports;
int use_altstatus = 0, rc;
unsigned long timeout;
u8 s = 0, a = 0;
@@ -271,7 +272,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
/* take a deep breath */
msleep(50);
- if (hwif->io_ports[IDE_CONTROL_OFFSET]) {
+ if (io_ports->ctl_addr) {
a = ide_read_altstatus(drive);
s = ide_read_status(drive);
if ((a ^ s) & ~INDEX_STAT)
@@ -289,10 +290,10 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
*/
if ((cmd == WIN_PIDENTIFY))
/* disable dma & overlap */
- hwif->OUTB(0, hwif->io_ports[IDE_FEATURE_OFFSET]);
+ hwif->OUTB(0, io_ports->feature_addr);
/* ask drive for ID */
- hwif->OUTB(cmd, hwif->io_ports[IDE_COMMAND_OFFSET]);
+ hwif->OUTBSYNC(drive, cmd, io_ports->command_addr);
timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
timeout += jiffies;
@@ -353,7 +354,7 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
* interrupts during the identify-phase that
* the irq handler isn't expecting.
*/
- if (hwif->io_ports[IDE_CONTROL_OFFSET]) {
+ if (hwif->io_ports.ctl_addr) {
if (!hwif->irq) {
autoprobe = 1;
cookie = probe_irq_on();
@@ -393,7 +394,7 @@ static int ide_busy_sleep(ide_hwif_t *hwif)
do {
msleep(50);
- stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+ stat = hwif->INB(hwif->io_ports.status_addr);
if ((stat & BUSY_STAT) == 0)
return 0;
} while (time_before(jiffies, timeout));
@@ -425,6 +426,7 @@ static int ide_busy_sleep(ide_hwif_t *hwif)
static int do_probe (ide_drive_t *drive, u8 cmd)
{
ide_hwif_t *hwif = HWIF(drive);
+ struct ide_io_ports *io_ports = &hwif->io_ports;
int rc;
u8 stat;
@@ -445,7 +447,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
msleep(50);
SELECT_DRIVE(drive);
msleep(50);
- if (hwif->INB(hwif->io_ports[IDE_SELECT_OFFSET]) != drive->select.all &&
+ if (hwif->INB(io_ports->device_addr) != drive->select.all &&
!drive->present) {
if (drive->select.b.unit != 0) {
/* exit with drive0 selected */
@@ -472,17 +474,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
if (stat == (BUSY_STAT | READY_STAT))
return 4;
- if ((rc == 1 && cmd == WIN_PIDENTIFY) &&
- ((drive->autotune == IDE_TUNE_DEFAULT) ||
- (drive->autotune == IDE_TUNE_AUTO))) {
+ if (rc == 1 && cmd == WIN_PIDENTIFY) {
printk(KERN_ERR "%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name, stat);
msleep(50);
- hwif->OUTB(drive->select.all,
- hwif->io_ports[IDE_SELECT_OFFSET]);
+ hwif->OUTB(drive->select.all, io_ports->device_addr);
msleep(50);
- hwif->OUTB(WIN_SRST,
- hwif->io_ports[IDE_COMMAND_OFFSET]);
+ hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr);
(void)ide_busy_sleep(hwif);
rc = try_to_identify(drive, cmd);
}
@@ -518,7 +516,7 @@ static void enable_nest (ide_drive_t *drive)
printk("%s: enabling %s -- ", hwif->name, drive->id->model);
SELECT_DRIVE(drive);
msleep(50);
- hwif->OUTB(EXABYTE_ENABLE_NEST, hwif->io_ports[IDE_COMMAND_OFFSET]);
+ hwif->OUTBSYNC(drive, EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr);
if (ide_busy_sleep(hwif)) {
printk(KERN_CONT "failed (timeout)\n");
@@ -644,7 +642,7 @@ static int ide_register_port(ide_hwif_t *hwif)
ret = device_register(&hwif->gendev);
if (ret < 0) {
printk(KERN_WARNING "IDE: %s: device_register error: %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
goto out;
}
@@ -773,8 +771,7 @@ static int ide_probe_port(ide_hwif_t *hwif)
BUG_ON(hwif->present);
- if (hwif->noprobe ||
- (hwif->drives[0].noprobe && hwif->drives[1].noprobe))
+ if (hwif->drives[0].noprobe && hwif->drives[1].noprobe)
return -EACCES;
/*
@@ -801,14 +798,9 @@ static int ide_probe_port(ide_hwif_t *hwif)
if (drive->present)
rc = 0;
}
- if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) {
- printk(KERN_WARNING "%s: reset\n", hwif->name);
- hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
- udelay(10);
- hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
- (void)ide_busy_sleep(hwif);
- }
+
local_irq_restore(flags);
+
/*
* Use cached IRQ number. It might be (and is...) changed by probe
* code above
@@ -821,29 +813,25 @@ static int ide_probe_port(ide_hwif_t *hwif)
static void ide_port_tune_devices(ide_hwif_t *hwif)
{
+ const struct ide_port_ops *port_ops = hwif->port_ops;
int unit;
for (unit = 0; unit < MAX_DRIVES; unit++) {
ide_drive_t *drive = &hwif->drives[unit];
- if (drive->present && hwif->quirkproc)
- hwif->quirkproc(drive);
+ if (drive->present && port_ops && port_ops->quirkproc)
+ port_ops->quirkproc(drive);
}
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
if (drive->present) {
- if (drive->autotune == IDE_TUNE_AUTO)
- ide_set_max_pio(drive);
-
- if (drive->autotune != IDE_TUNE_DEFAULT &&
- drive->autotune != IDE_TUNE_AUTO)
- continue;
+ ide_set_max_pio(drive);
drive->nice1 = 1;
- if (hwif->dma_host_set)
+ if (hwif->dma_ops)
ide_set_dma(drive);
}
}
@@ -994,6 +982,7 @@ static void ide_port_setup_devices(ide_hwif_t *hwif)
*/
static int init_irq (ide_hwif_t *hwif)
{
+ struct ide_io_ports *io_ports = &hwif->io_ports;
unsigned int index;
ide_hwgroup_t *hwgroup;
ide_hwif_t *match = NULL;
@@ -1077,9 +1066,9 @@ static int init_irq (ide_hwif_t *hwif)
if (IDE_CHIPSET_IS_PCI(hwif->chipset))
sa = IRQF_SHARED;
- if (hwif->io_ports[IDE_CONTROL_OFFSET])
+ if (io_ports->ctl_addr)
/* clear nIEN */
- hwif->OUTB(0x08, hwif->io_ports[IDE_CONTROL_OFFSET]);
+ hwif->OUTB(0x08, io_ports->ctl_addr);
if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup))
goto out_unlink;
@@ -1095,12 +1084,11 @@ static int init_irq (ide_hwif_t *hwif)
#if !defined(__mc68000__)
printk("%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
- hwif->io_ports[IDE_DATA_OFFSET],
- hwif->io_ports[IDE_DATA_OFFSET]+7,
- hwif->io_ports[IDE_CONTROL_OFFSET], hwif->irq);
+ io_ports->data_addr, io_ports->status_addr,
+ io_ports->ctl_addr, hwif->irq);
#else
printk("%s at 0x%08lx on irq %d", hwif->name,
- hwif->io_ports[IDE_DATA_OFFSET], hwif->irq);
+ io_ports->data_addr, hwif->irq);
#endif /* __mc68000__ */
if (match)
printk(" (%sed with %s)",
@@ -1242,8 +1230,8 @@ static int hwif_init(ide_hwif_t *hwif)
int old_irq;
if (!hwif->irq) {
- if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET])))
- {
+ hwif->irq = ide_default_irq(hwif->io_ports.data_addr);
+ if (!hwif->irq) {
printk("%s: DISABLED, NO IRQ\n", hwif->name);
return 0;
}
@@ -1272,7 +1260,8 @@ static int hwif_init(ide_hwif_t *hwif)
* It failed to initialise. Find the default IRQ for
* this port and try that.
*/
- if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) {
+ hwif->irq = ide_default_irq(hwif->io_ports.data_addr);
+ if (!hwif->irq) {
printk("%s: Disabled unable to get IRQ %d.\n",
hwif->name, old_irq);
goto out;
@@ -1324,6 +1313,7 @@ static void hwif_register_devices(ide_hwif_t *hwif)
static void ide_port_init_devices(ide_hwif_t *hwif)
{
+ const struct ide_port_ops *port_ops = hwif->port_ops;
int i;
for (i = 0; i < MAX_DRIVES; i++) {
@@ -1335,12 +1325,10 @@ static void ide_port_init_devices(ide_hwif_t *hwif)
drive->unmask = 1;
if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
drive->no_unmask = 1;
- if ((hwif->host_flags & IDE_HFLAG_NO_AUTOTUNE) == 0)
- drive->autotune = 1;
}
- if (hwif->port_init_devs)
- hwif->port_init_devs(hwif);
+ if (port_ops && port_ops->port_init_devs)
+ port_ops->port_init_devs(hwif);
}
static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
@@ -1355,26 +1343,44 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
if (d->init_iops)
d->init_iops(hwif);
- if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0)
- ide_hwif_setup_dma(hwif, d);
-
if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
(d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
hwif->irq = port ? 15 : 14;
- hwif->host_flags = d->host_flags;
+ /* ->host_flags may be set by ->init_iops (or even earlier...) */
+ hwif->host_flags |= d->host_flags;
hwif->pio_mask = d->pio_mask;
- if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate)
- hwif->mate->serialized = hwif->serialized = 1;
+ /* ->set_pio_mode for DTC2278 is currently limited to port 0 */
+ if (hwif->chipset != ide_dtc2278 || hwif->channel == 0)
+ hwif->port_ops = d->port_ops;
+
+ if ((d->host_flags & IDE_HFLAG_SERIALIZE) ||
+ ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base)) {
+ if (hwif->mate)
+ hwif->mate->serialized = hwif->serialized = 1;
+ }
hwif->swdma_mask = d->swdma_mask;
hwif->mwdma_mask = d->mwdma_mask;
hwif->ultra_mask = d->udma_mask;
- /* reset DMA masks only for SFF-style DMA controllers */
- if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0 && hwif->dma_base == 0)
- hwif->swdma_mask = hwif->mwdma_mask = hwif->ultra_mask = 0;
+ if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
+ int rc;
+
+ if (d->init_dma)
+ rc = d->init_dma(hwif, d);
+ else
+ rc = ide_hwif_setup_dma(hwif, d);
+
+ if (rc < 0) {
+ printk(KERN_INFO "%s: DMA disabled\n", hwif->name);
+ hwif->swdma_mask = 0;
+ hwif->mwdma_mask = 0;
+ hwif->ultra_mask = 0;
+ } else if (d->dma_ops)
+ hwif->dma_ops = d->dma_ops;
+ }
if (d->host_flags & IDE_HFLAG_RQSIZE_256)
hwif->rqsize = 256;
@@ -1386,9 +1392,11 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
static void ide_port_cable_detect(ide_hwif_t *hwif)
{
- if (hwif->cable_detect && (hwif->ultra_mask & 0x78)) {
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (port_ops && port_ops->cable_detect && (hwif->ultra_mask & 0x78)) {
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
- hwif->cbl = hwif->cable_detect(hwif);
+ hwif->cbl = port_ops->cable_detect(hwif);
}
}
@@ -1498,13 +1506,20 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
int i, rc = 0;
for (i = 0; i < MAX_HWIFS; i++) {
- if (d == NULL || idx[i] == 0xff) {
+ if (idx[i] == 0xff) {
mate = NULL;
continue;
}
hwif = &ide_hwifs[idx[i]];
+ ide_port_apply_params(hwif);
+
+ if (d == NULL) {
+ mate = NULL;
+ continue;
+ }
+
if (d->chipset != ide_etrax100 && (i & 1) && mate) {
hwif->mate = mate;
mate->mate = hwif;
@@ -1523,25 +1538,15 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
hwif = &ide_hwifs[idx[i]];
- if ((hwif->chipset != ide_4drives || !hwif->mate ||
- !hwif->mate->present) && ide_hwif_request_regions(hwif)) {
- printk(KERN_ERR "%s: ports already in use, "
- "skipping probe\n", hwif->name);
- continue;
- }
-
- if (ide_probe_port(hwif) < 0) {
- ide_hwif_release_regions(hwif);
- continue;
- }
-
- hwif->present = 1;
+ if (ide_probe_port(hwif) == 0)
+ hwif->present = 1;
if (hwif->chipset != ide_4drives || !hwif->mate ||
!hwif->mate->present)
ide_register_port(hwif);
- ide_port_tune_devices(hwif);
+ if (hwif->present)
+ ide_port_tune_devices(hwif);
}
for (i = 0; i < MAX_HWIFS; i++) {
@@ -1550,9 +1555,6 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
hwif = &ide_hwifs[idx[i]];
- if (!hwif->present)
- continue;
-
if (hwif_init(hwif) == 0) {
printk(KERN_INFO "%s: failed to initialize IDE "
"interface\n", hwif->name);
@@ -1561,10 +1563,13 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
continue;
}
- ide_port_setup_devices(hwif);
+ if (hwif->present)
+ ide_port_setup_devices(hwif);
ide_acpi_init(hwif);
- ide_acpi_port_init_devices(hwif);
+
+ if (hwif->present)
+ ide_acpi_port_init_devices(hwif);
}
for (i = 0; i < MAX_HWIFS; i++) {
@@ -1573,11 +1578,11 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
hwif = &ide_hwifs[idx[i]];
- if (hwif->present) {
- if (hwif->chipset == ide_unknown)
- hwif->chipset = ide_generic;
+ if (hwif->chipset == ide_unknown)
+ hwif->chipset = ide_generic;
+
+ if (hwif->present)
hwif_register_devices(hwif);
- }
}
for (i = 0; i < MAX_HWIFS; i++) {
@@ -1586,11 +1591,11 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
hwif = &ide_hwifs[idx[i]];
- if (hwif->present) {
- ide_sysfs_register_port(hwif);
- ide_proc_register_port(hwif);
+ ide_sysfs_register_port(hwif);
+ ide_proc_register_port(hwif);
+
+ if (hwif->present)
ide_proc_port_register_devices(hwif);
- }
}
return rc;
@@ -1611,6 +1616,7 @@ EXPORT_SYMBOL_GPL(ide_device_add);
void ide_port_scan(ide_hwif_t *hwif)
{
+ ide_port_apply_params(hwif);
ide_port_cable_detect(hwif);
ide_port_init_devices(hwif);
@@ -1626,3 +1632,67 @@ void ide_port_scan(ide_hwif_t *hwif)
ide_proc_port_register_devices(hwif);
}
EXPORT_SYMBOL_GPL(ide_port_scan);
+
+static void ide_legacy_init_one(u8 *idx, hw_regs_t *hw, u8 port_no,
+ const struct ide_port_info *d,
+ unsigned long config)
+{
+ ide_hwif_t *hwif;
+ unsigned long base, ctl;
+ int irq;
+
+ if (port_no == 0) {
+ base = 0x1f0;
+ ctl = 0x3f6;
+ irq = 14;
+ } else {
+ base = 0x170;
+ ctl = 0x376;
+ irq = 15;
+ }
+
+ if (!request_region(base, 8, d->name)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
+ d->name, base, base + 7);
+ return;
+ }
+
+ if (!request_region(ctl, 1, d->name)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
+ d->name, ctl);
+ release_region(base, 8);
+ return;
+ }
+
+ ide_std_init_ports(hw, base, ctl);
+ hw->irq = irq;
+
+ hwif = ide_find_port_slot(d);
+ if (hwif) {
+ ide_init_port_hw(hwif, hw);
+ if (config)
+ hwif->config_data = config;
+ idx[port_no] = hwif->index;
+ }
+}
+
+int ide_legacy_device_add(const struct ide_port_info *d, unsigned long config)
+{
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+ hw_regs_t hw[2];
+
+ memset(&hw, 0, sizeof(hw));
+
+ if ((d->host_flags & IDE_HFLAG_QD_2ND_PORT) == 0)
+ ide_legacy_init_one(idx, &hw[0], 0, d, config);
+ ide_legacy_init_one(idx, &hw[1], 1, d, config);
+
+ if (idx[0] == 0xff && idx[1] == 0xff &&
+ (d->host_flags & IDE_HFLAG_SINGLE))
+ return -ENOENT;
+
+ ide_device_add(idx, d);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ide_legacy_device_add);
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 5d3562b4503..8d6ad812a01 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -599,14 +599,14 @@ static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
err = device_attach(dev);
if (err < 0)
printk(KERN_WARNING "IDE: %s: device_attach error: %d\n",
- __FUNCTION__, err);
+ __func__, err);
drive->driver_req[0] = 0;
if (dev->driver == NULL) {
err = device_attach(dev);
if (err < 0)
printk(KERN_WARNING
"IDE: %s: device_attach(2) error: %d\n",
- __FUNCTION__, err);
+ __func__, err);
}
if (dev->driver && !strcmp(dev->driver->name, driver))
ret = 0;
@@ -786,14 +786,6 @@ void ide_proc_register_port(ide_hwif_t *hwif)
}
}
-#ifdef CONFIG_BLK_DEV_IDEPCI
-void ide_pci_create_host_proc(const char *name, get_info_t *get_info)
-{
- create_proc_info_entry(name, 0, proc_ide_root, get_info);
-}
-EXPORT_SYMBOL_GPL(ide_pci_create_host_proc);
-#endif
-
void ide_proc_unregister_port(ide_hwif_t *hwif)
{
if (hwif->proc) {
@@ -820,7 +812,7 @@ static int ide_drivers_show(struct seq_file *s, void *p)
err = bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver);
if (err < 0)
printk(KERN_WARNING "IDE: %s: bus_for_each_drv error: %d\n",
- __FUNCTION__, err);
+ __func__, err);
return 0;
}
@@ -830,6 +822,7 @@ static int ide_drivers_open(struct inode *inode, struct file *file)
}
static const struct file_operations ide_drivers_operations = {
+ .owner = THIS_MODULE,
.open = ide_drivers_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -838,16 +831,12 @@ static const struct file_operations ide_drivers_operations = {
void proc_ide_create(void)
{
- struct proc_dir_entry *entry;
-
proc_ide_root = proc_mkdir("ide", NULL);
if (!proc_ide_root)
return;
- entry = create_proc_entry("drivers", 0, proc_ide_root);
- if (entry)
- entry->proc_fops = &ide_drivers_operations;
+ proc_create("drivers", 0, proc_ide_root, &ide_drivers_operations);
}
void proc_ide_destroy(void)
diff --git a/drivers/ide/ide-scan-pci.c b/drivers/ide/ide-scan-pci.c
index 98888da1b60..0e79efff1de 100644
--- a/drivers/ide/ide-scan-pci.c
+++ b/drivers/ide/ide-scan-pci.c
@@ -102,7 +102,7 @@ static int __init ide_scan_pcibus(void)
if (__pci_register_driver(d, d->driver.owner,
d->driver.mod_name))
printk(KERN_ERR "%s: failed to register %s driver\n",
- __FUNCTION__, d->driver.mod_name);
+ __func__, d->driver.mod_name);
}
return 0;
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index f43fd070f1b..1e1f26331a2 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -72,26 +72,6 @@ enum {
#endif
/**************************** Tunable parameters *****************************/
-
-
-/*
- * Pipelined mode parameters.
- *
- * We try to use the minimum number of stages which is enough to keep the tape
- * constantly streaming. To accomplish that, we implement a feedback loop around
- * the maximum number of stages:
- *
- * We start from MIN maximum stages (we will not even use MIN stages if we don't
- * need them), increment it by RATE*(MAX-MIN) whenever we sense that the
- * pipeline is empty, until we reach the optimum value or until we reach MAX.
- *
- * Setting the following parameter to 0 is illegal: the pipelined mode cannot be
- * disabled (idetape_calculate_speeds() divides by tape->max_stages.)
- */
-#define IDETAPE_MIN_PIPELINE_STAGES 1
-#define IDETAPE_MAX_PIPELINE_STAGES 400
-#define IDETAPE_INCREASE_STAGES_RATE 20
-
/*
* After each failed packet command we issue a request sense command and retry
* the packet command IDETAPE_MAX_PC_RETRIES times.
@@ -224,28 +204,17 @@ enum {
/* 0 When the tape position is unknown */
IDETAPE_FLAG_ADDRESS_VALID = (1 << 1),
/* Device already opened */
- IDETAPE_FLAG_BUSY = (1 << 2),
- /* Error detected in a pipeline stage */
- IDETAPE_FLAG_PIPELINE_ERR = (1 << 3),
+ IDETAPE_FLAG_BUSY = (1 << 2),
/* Attempt to auto-detect the current user block size */
- IDETAPE_FLAG_DETECT_BS = (1 << 4),
+ IDETAPE_FLAG_DETECT_BS = (1 << 3),
/* Currently on a filemark */
- IDETAPE_FLAG_FILEMARK = (1 << 5),
+ IDETAPE_FLAG_FILEMARK = (1 << 4),
/* DRQ interrupt device */
- IDETAPE_FLAG_DRQ_INTERRUPT = (1 << 6),
- /* pipeline active */
- IDETAPE_FLAG_PIPELINE_ACTIVE = (1 << 7),
+ IDETAPE_FLAG_DRQ_INTERRUPT = (1 << 5),
/* 0 = no tape is loaded, so we don't rewind after ejecting */
- IDETAPE_FLAG_MEDIUM_PRESENT = (1 << 8),
+ IDETAPE_FLAG_MEDIUM_PRESENT = (1 << 6),
};
-/* A pipeline stage. */
-typedef struct idetape_stage_s {
- struct request rq; /* The corresponding request */
- struct idetape_bh *bh; /* The data buffers */
- struct idetape_stage_s *next; /* Pointer to the next stage */
-} idetape_stage_t;
-
/*
* Most of our global data which we need to save even as we leave the driver due
* to an interrupt or a timer event is stored in the struct defined below.
@@ -289,9 +258,7 @@ typedef struct ide_tape_obj {
* While polling for DSC we use postponed_rq to postpone the current
* request so that ide.c will be able to service pending requests on the
* other device. Note that at most we will have only one DSC (usually
- * data transfer) request in the device request queue. Additional
- * requests can be queued in our internal pipeline, but they will be
- * visible to ide.c only one at a time.
+ * data transfer) request in the device request queue.
*/
struct request *postponed_rq;
/* The time in which we started polling for DSC */
@@ -331,43 +298,20 @@ typedef struct ide_tape_obj {
* At most, there is only one ide-tape originated data transfer request
* in the device request queue. This allows ide.c to easily service
* requests from the other device when we postpone our active request.
- * In the pipelined operation mode, we use our internal pipeline
- * structure to hold more data requests. The data buffer size is chosen
- * based on the tape's recommendation.
*/
- /* ptr to the request which is waiting in the device request queue */
- struct request *active_data_rq;
+
/* Data buffer size chosen based on the tape's recommendation */
- int stage_size;
- idetape_stage_t *merge_stage;
- int merge_stage_size;
+ int buffer_size;
+ /* merge buffer */
+ struct idetape_bh *merge_bh;
+ /* size of the merge buffer */
+ int merge_bh_size;
+ /* pointer to current buffer head within the merge buffer */
struct idetape_bh *bh;
char *b_data;
int b_count;
- /*
- * Pipeline parameters.
- *
- * To accomplish non-pipelined mode, we simply set the following
- * variables to zero (or NULL, where appropriate).
- */
- /* Number of currently used stages */
- int nr_stages;
- /* Number of pending stages */
- int nr_pending_stages;
- /* We will not allocate more than this number of stages */
- int max_stages, min_pipeline, max_pipeline;
- /* The first stage which will be removed from the pipeline */
- idetape_stage_t *first_stage;
- /* The currently active stage */
- idetape_stage_t *active_stage;
- /* Will be serviced after the currently active request */
- idetape_stage_t *next_stage;
- /* New requests will be added to the pipeline here */
- idetape_stage_t *last_stage;
- /* Optional free stage which we can use */
- idetape_stage_t *cache_stage;
- int pages_per_stage;
+ int pages_per_buffer;
/* Wasted space in each stage */
int excess_bh_size;
@@ -388,45 +332,6 @@ typedef struct ide_tape_obj {
/* the tape is write protected (hardware or opened as read-only) */
char write_prot;
- /*
- * Limit the number of times a request can be postponed, to avoid an
- * infinite postpone deadlock.
- */
- int postpone_cnt;
-
- /*
- * Measures number of frames:
- *
- * 1. written/read to/from the driver pipeline (pipeline_head).
- * 2. written/read to/from the tape buffers (idetape_bh).
- * 3. written/read by the tape to/from the media (tape_head).
- */
- int pipeline_head;
- int buffer_head;
- int tape_head;
- int last_tape_head;
-
- /* Speed control at the tape buffers input/output */
- unsigned long insert_time;
- int insert_size;
- int insert_speed;
- int max_insert_speed;
- int measure_insert_time;
-
- /* Speed regulation negative feedback loop */
- int speed_control;
- int pipeline_head_speed;
- int controlled_pipeline_head_speed;
- int uncontrolled_pipeline_head_speed;
- int controlled_last_pipeline_head;
- unsigned long uncontrolled_pipeline_head_time;
- unsigned long controlled_pipeline_head_time;
- int controlled_previous_pipeline_head;
- int uncontrolled_previous_pipeline_head;
- unsigned long controlled_previous_head_time;
- unsigned long uncontrolled_previous_head_time;
- int restart_speed_control_req;
-
u32 debug_mask;
} idetape_tape_t;
@@ -490,13 +395,13 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
if (bh == NULL) {
printk(KERN_ERR "ide-tape: bh == NULL in "
"idetape_input_buffers\n");
- ide_atapi_discard_data(drive, bcount);
+ ide_pad_transfer(drive, 0, bcount);
return;
}
count = min(
(unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
bcount);
- HWIF(drive)->atapi_input_bytes(drive, bh->b_data +
+ drive->hwif->input_data(drive, NULL, bh->b_data +
atomic_read(&bh->b_count), count);
bcount -= count;
atomic_add(count, &bh->b_count);
@@ -522,7 +427,7 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
return;
}
count = min((unsigned int)pc->b_count, (unsigned int)bcount);
- HWIF(drive)->atapi_output_bytes(drive, pc->b_data, count);
+ drive->hwif->output_data(drive, NULL, pc->b_data, count);
bcount -= count;
pc->b_data += count;
pc->b_count -= count;
@@ -674,128 +579,36 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
}
}
-static void idetape_activate_next_stage(ide_drive_t *drive)
+/* Free data buffers completely. */
+static void ide_tape_kfree_buffer(idetape_tape_t *tape)
{
- idetape_tape_t *tape = drive->driver_data;
- idetape_stage_t *stage = tape->next_stage;
- struct request *rq = &stage->rq;
+ struct idetape_bh *prev_bh, *bh = tape->merge_bh;
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
+ while (bh) {
+ u32 size = bh->b_size;
- if (stage == NULL) {
- printk(KERN_ERR "ide-tape: bug: Trying to activate a non"
- " existing stage\n");
- return;
- }
+ while (size) {
+ unsigned int order = fls(size >> PAGE_SHIFT)-1;
- rq->rq_disk = tape->disk;
- rq->buffer = NULL;
- rq->special = (void *)stage->bh;
- tape->active_data_rq = rq;
- tape->active_stage = stage;
- tape->next_stage = stage->next;
-}
-
-/* Free a stage along with its related buffers completely. */
-static void __idetape_kfree_stage(idetape_stage_t *stage)
-{
- struct idetape_bh *prev_bh, *bh = stage->bh;
- int size;
-
- while (bh != NULL) {
- if (bh->b_data != NULL) {
- size = (int) bh->b_size;
- while (size > 0) {
- free_page((unsigned long) bh->b_data);
- size -= PAGE_SIZE;
- bh->b_data += PAGE_SIZE;
- }
+ if (bh->b_data)
+ free_pages((unsigned long)bh->b_data, order);
+
+ size &= (order-1);
+ bh->b_data += (1 << order) * PAGE_SIZE;
}
prev_bh = bh;
bh = bh->b_reqnext;
kfree(prev_bh);
}
- kfree(stage);
-}
-
-static void idetape_kfree_stage(idetape_tape_t *tape, idetape_stage_t *stage)
-{
- __idetape_kfree_stage(stage);
+ kfree(tape->merge_bh);
}
-/*
- * Remove tape->first_stage from the pipeline. The caller should avoid race
- * conditions.
- */
-static void idetape_remove_stage_head(ide_drive_t *drive)
-{
- idetape_tape_t *tape = drive->driver_data;
- idetape_stage_t *stage;
-
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
-
- if (tape->first_stage == NULL) {
- printk(KERN_ERR "ide-tape: bug: tape->first_stage is NULL\n");
- return;
- }
- if (tape->active_stage == tape->first_stage) {
- printk(KERN_ERR "ide-tape: bug: Trying to free our active "
- "pipeline stage\n");
- return;
- }
- stage = tape->first_stage;
- tape->first_stage = stage->next;
- idetape_kfree_stage(tape, stage);
- tape->nr_stages--;
- if (tape->first_stage == NULL) {
- tape->last_stage = NULL;
- if (tape->next_stage != NULL)
- printk(KERN_ERR "ide-tape: bug: tape->next_stage !="
- " NULL\n");
- if (tape->nr_stages)
- printk(KERN_ERR "ide-tape: bug: nr_stages should be 0 "
- "now\n");
- }
-}
-
-/*
- * This will free all the pipeline stages starting from new_last_stage->next
- * to the end of the list, and point tape->last_stage to new_last_stage.
- */
-static void idetape_abort_pipeline(ide_drive_t *drive,
- idetape_stage_t *new_last_stage)
-{
- idetape_tape_t *tape = drive->driver_data;
- idetape_stage_t *stage = new_last_stage->next;
- idetape_stage_t *nstage;
-
- debug_log(DBG_PROCS, "%s: Enter %s\n", tape->name, __func__);
-
- while (stage) {
- nstage = stage->next;
- idetape_kfree_stage(tape, stage);
- --tape->nr_stages;
- --tape->nr_pending_stages;
- stage = nstage;
- }
- if (new_last_stage)
- new_last_stage->next = NULL;
- tape->last_stage = new_last_stage;
- tape->next_stage = NULL;
-}
-
-/*
- * Finish servicing a request and insert a pending pipeline request into the
- * main device queue.
- */
static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
{
struct request *rq = HWGROUP(drive)->rq;
idetape_tape_t *tape = drive->driver_data;
unsigned long flags;
int error;
- int remove_stage = 0;
- idetape_stage_t *active_stage;
debug_log(DBG_PROCS, "Enter %s\n", __func__);
@@ -815,58 +628,8 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
spin_lock_irqsave(&tape->lock, flags);
- /* The request was a pipelined data transfer request */
- if (tape->active_data_rq == rq) {
- active_stage = tape->active_stage;
- tape->active_stage = NULL;
- tape->active_data_rq = NULL;
- tape->nr_pending_stages--;
- if (rq->cmd[0] & REQ_IDETAPE_WRITE) {
- remove_stage = 1;
- if (error) {
- set_bit(IDETAPE_FLAG_PIPELINE_ERR,
- &tape->flags);
- if (error == IDETAPE_ERROR_EOD)
- idetape_abort_pipeline(drive,
- active_stage);
- }
- } else if (rq->cmd[0] & REQ_IDETAPE_READ) {
- if (error == IDETAPE_ERROR_EOD) {
- set_bit(IDETAPE_FLAG_PIPELINE_ERR,
- &tape->flags);
- idetape_abort_pipeline(drive, active_stage);
- }
- }
- if (tape->next_stage != NULL) {
- idetape_activate_next_stage(drive);
-
- /* Insert the next request into the request queue. */
- (void)ide_do_drive_cmd(drive, tape->active_data_rq,
- ide_end);
- } else if (!error) {
- /*
- * This is a part of the feedback loop which tries to
- * find the optimum number of stages. We are starting
- * from a minimum maximum number of stages, and if we
- * sense that the pipeline is empty, we try to increase
- * it, until we reach the user compile time memory
- * limit.
- */
- int i = (tape->max_pipeline - tape->min_pipeline) / 10;
-
- tape->max_stages += max(i, 1);
- tape->max_stages = max(tape->max_stages,
- tape->min_pipeline);
- tape->max_stages = min(tape->max_stages,
- tape->max_pipeline);
- }
- }
ide_end_drive_cmd(drive, 0, 0);
- if (remove_stage)
- idetape_remove_stage_head(drive);
- if (tape->active_data_rq == NULL)
- clear_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags);
spin_unlock_irqrestore(&tape->lock, flags);
return 0;
}
@@ -899,7 +662,7 @@ static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc)
static void idetape_init_rq(struct request *rq, u8 cmd)
{
- memset(rq, 0, sizeof(*rq));
+ blk_rq_init(NULL, rq);
rq->cmd_type = REQ_TYPE_SPECIAL;
rq->cmd[0] = cmd;
}
@@ -993,7 +756,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
stat = ide_read_status(drive);
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- if (hwif->ide_dma_end(drive) || (stat & ERR_STAT)) {
+ if (hwif->dma_ops->dma_end(drive) || (stat & ERR_STAT)) {
/*
* A DMA error is sometimes expected. For example,
* if the tape is crossing a filemark during a
@@ -1083,10 +846,10 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
return ide_do_reset(drive);
}
/* Get the number of bytes to transfer on this interrupt. */
- bcount = (hwif->INB(hwif->io_ports[IDE_BCOUNTH_OFFSET]) << 8) |
- hwif->INB(hwif->io_ports[IDE_BCOUNTL_OFFSET]);
+ bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
+ hwif->INB(hwif->io_ports.lbam_addr);
- ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
if (ireason & CD) {
printk(KERN_ERR "ide-tape: CoD != 0 in %s\n", __func__);
@@ -1108,7 +871,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
printk(KERN_ERR "ide-tape: The tape wants to "
"send us more data than expected "
"- discarding data\n");
- ide_atapi_discard_data(drive, bcount);
+ ide_pad_transfer(drive, 0, bcount);
ide_set_handler(drive, &idetape_pc_intr,
IDETAPE_WAIT_CMD, NULL);
return ide_started;
@@ -1117,16 +880,16 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
"data than expected - allowing transfer\n");
}
iobuf = &idetape_input_buffers;
- xferfunc = hwif->atapi_input_bytes;
+ xferfunc = hwif->input_data;
} else {
iobuf = &idetape_output_buffers;
- xferfunc = hwif->atapi_output_bytes;
+ xferfunc = hwif->output_data;
}
if (pc->bh)
iobuf(drive, pc, bcount);
else
- xferfunc(drive, pc->cur_pos, bcount);
+ xferfunc(drive, NULL, pc->cur_pos, bcount);
/* Update the current position */
pc->xferred += bcount;
@@ -1190,12 +953,12 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
"yet DRQ isn't asserted\n");
return startstop;
}
- ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) {
printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing "
"a packet command, retrying\n");
udelay(100);
- ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
if (retries == 0) {
printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while "
"issuing a packet command, ignoring\n");
@@ -1213,10 +976,11 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
#ifdef CONFIG_BLK_DEV_IDEDMA
/* Begin DMA, if necessary */
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS)
- hwif->dma_start(drive);
+ hwif->dma_ops->dma_start(drive);
#endif
/* Send the actual packet */
- HWIF(drive)->atapi_output_bytes(drive, pc->c, 12);
+ hwif->output_data(drive, NULL, pc->c, 12);
+
return ide_started;
}
@@ -1279,7 +1043,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
ide_dma_off(drive);
}
if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma)
- dma_ok = !hwif->dma_setup(drive);
+ dma_ok = !hwif->dma_ops->dma_setup(drive);
ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK |
IDE_TFLAG_OUT_DEVICE, bcount, dma_ok);
@@ -1292,7 +1056,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
IDETAPE_WAIT_CMD, NULL);
return ide_started;
} else {
- hwif->OUTB(WIN_PACKETCMD, hwif->io_ports[IDE_COMMAND_OFFSET]);
+ ide_execute_pkt_cmd(drive);
return idetape_transfer_pc(drive);
}
}
@@ -1335,69 +1099,6 @@ static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code)
pc->idetape_callback = &idetape_pc_callback;
}
-static void idetape_calculate_speeds(ide_drive_t *drive)
-{
- idetape_tape_t *tape = drive->driver_data;
-
- if (time_after(jiffies,
- tape->controlled_pipeline_head_time + 120 * HZ)) {
- tape->controlled_previous_pipeline_head =
- tape->controlled_last_pipeline_head;
- tape->controlled_previous_head_time =
- tape->controlled_pipeline_head_time;
- tape->controlled_last_pipeline_head = tape->pipeline_head;
- tape->controlled_pipeline_head_time = jiffies;
- }
- if (time_after(jiffies, tape->controlled_pipeline_head_time + 60 * HZ))
- tape->controlled_pipeline_head_speed = (tape->pipeline_head -
- tape->controlled_last_pipeline_head) * 32 * HZ /
- (jiffies - tape->controlled_pipeline_head_time);
- else if (time_after(jiffies, tape->controlled_previous_head_time))
- tape->controlled_pipeline_head_speed = (tape->pipeline_head -
- tape->controlled_previous_pipeline_head) * 32 *
- HZ / (jiffies - tape->controlled_previous_head_time);
-
- if (tape->nr_pending_stages < tape->max_stages/*- 1 */) {
- /* -1 for read mode error recovery */
- if (time_after(jiffies, tape->uncontrolled_previous_head_time +
- 10 * HZ)) {
- tape->uncontrolled_pipeline_head_time = jiffies;
- tape->uncontrolled_pipeline_head_speed =
- (tape->pipeline_head -
- tape->uncontrolled_previous_pipeline_head) *
- 32 * HZ / (jiffies -
- tape->uncontrolled_previous_head_time);
- }
- } else {
- tape->uncontrolled_previous_head_time = jiffies;
- tape->uncontrolled_previous_pipeline_head = tape->pipeline_head;
- if (time_after(jiffies, tape->uncontrolled_pipeline_head_time +
- 30 * HZ))
- tape->uncontrolled_pipeline_head_time = jiffies;
-
- }
- tape->pipeline_head_speed = max(tape->uncontrolled_pipeline_head_speed,
- tape->controlled_pipeline_head_speed);
-
- if (tape->speed_control == 1) {
- if (tape->nr_pending_stages >= tape->max_stages / 2)
- tape->max_insert_speed = tape->pipeline_head_speed +
- (1100 - tape->pipeline_head_speed) * 2 *
- (tape->nr_pending_stages - tape->max_stages / 2)
- / tape->max_stages;
- else
- tape->max_insert_speed = 500 +
- (tape->pipeline_head_speed - 500) * 2 *
- tape->nr_pending_stages / tape->max_stages;
-
- if (tape->nr_pending_stages >= tape->max_stages * 99 / 100)
- tape->max_insert_speed = 5000;
- } else
- tape->max_insert_speed = tape->speed_control;
-
- tape->max_insert_speed = max(tape->max_insert_speed, 500);
-}
-
static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
@@ -1432,17 +1133,7 @@ static ide_startstop_t idetape_rw_callback(ide_drive_t *drive)
int blocks = tape->pc->xferred / tape->blk_size;
tape->avg_size += blocks * tape->blk_size;
- tape->insert_size += blocks * tape->blk_size;
- if (tape->insert_size > 1024 * 1024)
- tape->measure_insert_time = 1;
- if (tape->measure_insert_time) {
- tape->measure_insert_time = 0;
- tape->insert_time = jiffies;
- tape->insert_size = 0;
- }
- if (time_after(jiffies, tape->insert_time))
- tape->insert_speed = tape->insert_size / 1024 * HZ /
- (jiffies - tape->insert_time);
+
if (time_after_eq(jiffies, tape->avg_time + HZ)) {
tape->avg_speed = tape->avg_size * HZ /
(jiffies - tape->avg_time) / 1024;
@@ -1475,7 +1166,7 @@ static void idetape_create_read_cmd(idetape_tape_t *tape,
pc->buf = NULL;
pc->buf_size = length * tape->blk_size;
pc->req_xfer = pc->buf_size;
- if (pc->req_xfer == tape->stage_size)
+ if (pc->req_xfer == tape->buffer_size)
pc->flags |= PC_FLAG_DMA_RECOMMENDED;
}
@@ -1495,7 +1186,7 @@ static void idetape_create_write_cmd(idetape_tape_t *tape,
pc->buf = NULL;
pc->buf_size = length * tape->blk_size;
pc->req_xfer = pc->buf_size;
- if (pc->req_xfer == tape->stage_size)
+ if (pc->req_xfer == tape->buffer_size)
pc->flags |= PC_FLAG_DMA_RECOMMENDED;
}
@@ -1547,10 +1238,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
drive->post_reset = 0;
}
- if (time_after(jiffies, tape->insert_time))
- tape->insert_speed = tape->insert_size / 1024 * HZ /
- (jiffies - tape->insert_time);
- idetape_calculate_speeds(drive);
if (!test_and_clear_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags) &&
(stat & SEEK_STAT) == 0) {
if (postponed_rq == NULL) {
@@ -1574,16 +1261,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
return ide_stopped;
}
if (rq->cmd[0] & REQ_IDETAPE_READ) {
- tape->buffer_head++;
- tape->postpone_cnt = 0;
pc = idetape_next_pc_storage(drive);
idetape_create_read_cmd(tape, pc, rq->current_nr_sectors,
(struct idetape_bh *)rq->special);
goto out;
}
if (rq->cmd[0] & REQ_IDETAPE_WRITE) {
- tape->buffer_head++;
- tape->postpone_cnt = 0;
pc = idetape_next_pc_storage(drive);
idetape_create_write_cmd(tape, pc, rq->current_nr_sectors,
(struct idetape_bh *)rq->special);
@@ -1604,111 +1287,91 @@ out:
return idetape_issue_pc(drive, pc);
}
-/* Pipeline related functions */
-static inline int idetape_pipeline_active(idetape_tape_t *tape)
-{
- int rc1, rc2;
-
- rc1 = test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags);
- rc2 = (tape->active_data_rq != NULL);
- return rc1;
-}
-
/*
- * The function below uses __get_free_page to allocate a pipeline stage, along
- * with all the necessary small buffers which together make a buffer of size
- * tape->stage_size (or a bit more). We attempt to combine sequential pages as
+ * The function below uses __get_free_pages to allocate a data buffer of size
+ * tape->buffer_size (or a bit more). We attempt to combine sequential pages as
* much as possible.
*
- * It returns a pointer to the new allocated stage, or NULL if we can't (or
- * don't want to) allocate a stage.
- *
- * Pipeline stages are optional and are used to increase performance. If we
- * can't allocate them, we'll manage without them.
+ * It returns a pointer to the newly allocated buffer, or NULL in case of
+ * failure.
*/
-static idetape_stage_t *__idetape_kmalloc_stage(idetape_tape_t *tape, int full,
- int clear)
+static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape,
+ int full, int clear)
{
- idetape_stage_t *stage;
- struct idetape_bh *prev_bh, *bh;
- int pages = tape->pages_per_stage;
+ struct idetape_bh *prev_bh, *bh, *merge_bh;
+ int pages = tape->pages_per_buffer;
+ unsigned int order, b_allocd;
char *b_data = NULL;
- stage = kmalloc(sizeof(idetape_stage_t), GFP_KERNEL);
- if (!stage)
- return NULL;
- stage->next = NULL;
-
- stage->bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
- bh = stage->bh;
+ merge_bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
+ bh = merge_bh;
if (bh == NULL)
goto abort;
- bh->b_reqnext = NULL;
- bh->b_data = (char *) __get_free_page(GFP_KERNEL);
+
+ order = fls(pages) - 1;
+ bh->b_data = (char *) __get_free_pages(GFP_KERNEL, order);
if (!bh->b_data)
goto abort;
+ b_allocd = (1 << order) * PAGE_SIZE;
+ pages &= (order-1);
+
if (clear)
- memset(bh->b_data, 0, PAGE_SIZE);
- bh->b_size = PAGE_SIZE;
+ memset(bh->b_data, 0, b_allocd);
+ bh->b_reqnext = NULL;
+ bh->b_size = b_allocd;
atomic_set(&bh->b_count, full ? bh->b_size : 0);
- while (--pages) {
- b_data = (char *) __get_free_page(GFP_KERNEL);
+ while (pages) {
+ order = fls(pages) - 1;
+ b_data = (char *) __get_free_pages(GFP_KERNEL, order);
if (!b_data)
goto abort;
+ b_allocd = (1 << order) * PAGE_SIZE;
+
if (clear)
- memset(b_data, 0, PAGE_SIZE);
- if (bh->b_data == b_data + PAGE_SIZE) {
- bh->b_size += PAGE_SIZE;
- bh->b_data -= PAGE_SIZE;
+ memset(b_data, 0, b_allocd);
+
+ /* newly allocated page frames below buffer header or ...*/
+ if (bh->b_data == b_data + b_allocd) {
+ bh->b_size += b_allocd;
+ bh->b_data -= b_allocd;
if (full)
- atomic_add(PAGE_SIZE, &bh->b_count);
+ atomic_add(b_allocd, &bh->b_count);
continue;
}
+ /* they are above the header */
if (b_data == bh->b_data + bh->b_size) {
- bh->b_size += PAGE_SIZE;
+ bh->b_size += b_allocd;
if (full)
- atomic_add(PAGE_SIZE, &bh->b_count);
+ atomic_add(b_allocd, &bh->b_count);
continue;
}
prev_bh = bh;
bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
if (!bh) {
- free_page((unsigned long) b_data);
+ free_pages((unsigned long) b_data, order);
goto abort;
}
bh->b_reqnext = NULL;
bh->b_data = b_data;
- bh->b_size = PAGE_SIZE;
+ bh->b_size = b_allocd;
atomic_set(&bh->b_count, full ? bh->b_size : 0);
prev_bh->b_reqnext = bh;
+
+ pages &= (order-1);
}
+
bh->b_size -= tape->excess_bh_size;
if (full)
atomic_sub(tape->excess_bh_size, &bh->b_count);
- return stage;
+ return merge_bh;
abort:
- __idetape_kfree_stage(stage);
+ ide_tape_kfree_buffer(tape);
return NULL;
}
-static idetape_stage_t *idetape_kmalloc_stage(idetape_tape_t *tape)
-{
- idetape_stage_t *cache_stage = tape->cache_stage;
-
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
-
- if (tape->nr_stages >= tape->max_stages)
- return NULL;
- if (cache_stage != NULL) {
- tape->cache_stage = NULL;
- return cache_stage;
- }
- return __idetape_kmalloc_stage(tape, 0, 0);
-}
-
static int idetape_copy_stage_from_user(idetape_tape_t *tape,
- idetape_stage_t *stage, const char __user *buf, int n)
+ const char __user *buf, int n)
{
struct idetape_bh *bh = tape->bh;
int count;
@@ -1740,7 +1403,7 @@ static int idetape_copy_stage_from_user(idetape_tape_t *tape,
}
static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf,
- idetape_stage_t *stage, int n)
+ int n)
{
struct idetape_bh *bh = tape->bh;
int count;
@@ -1771,11 +1434,11 @@ static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf,
return ret;
}
-static void idetape_init_merge_stage(idetape_tape_t *tape)
+static void idetape_init_merge_buffer(idetape_tape_t *tape)
{
- struct idetape_bh *bh = tape->merge_stage->bh;
+ struct idetape_bh *bh = tape->merge_bh;
+ tape->bh = tape->merge_bh;
- tape->bh = bh;
if (tape->chrdev_dir == IDETAPE_DIR_WRITE)
atomic_set(&bh->b_count, 0);
else {
@@ -1784,61 +1447,6 @@ static void idetape_init_merge_stage(idetape_tape_t *tape)
}
}
-static void idetape_switch_buffers(idetape_tape_t *tape, idetape_stage_t *stage)
-{
- struct idetape_bh *tmp;
-
- tmp = stage->bh;
- stage->bh = tape->merge_stage->bh;
- tape->merge_stage->bh = tmp;
- idetape_init_merge_stage(tape);
-}
-
-/* Add a new stage at the end of the pipeline. */
-static void idetape_add_stage_tail(ide_drive_t *drive, idetape_stage_t *stage)
-{
- idetape_tape_t *tape = drive->driver_data;
- unsigned long flags;
-
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
-
- spin_lock_irqsave(&tape->lock, flags);
- stage->next = NULL;
- if (tape->last_stage != NULL)
- tape->last_stage->next = stage;
- else
- tape->first_stage = stage;
- tape->next_stage = stage;
- tape->last_stage = stage;
- if (tape->next_stage == NULL)
- tape->next_stage = tape->last_stage;
- tape->nr_stages++;
- tape->nr_pending_stages++;
- spin_unlock_irqrestore(&tape->lock, flags);
-}
-
-/* Install a completion in a pending request and sleep until it is serviced. The
- * caller should ensure that the request will not be serviced before we install
- * the completion (usually by disabling interrupts).
- */
-static void idetape_wait_for_request(ide_drive_t *drive, struct request *rq)
-{
- DECLARE_COMPLETION_ONSTACK(wait);
- idetape_tape_t *tape = drive->driver_data;
-
- if (rq == NULL || !blk_special_request(rq)) {
- printk(KERN_ERR "ide-tape: bug: Trying to sleep on non-valid"
- " request\n");
- return;
- }
- rq->end_io_data = &wait;
- rq->end_io = blk_end_sync_rq;
- spin_unlock_irq(&tape->lock);
- wait_for_completion(&wait);
- /* The stage and its struct request have been deallocated */
- spin_lock_irq(&tape->lock);
-}
-
static ide_startstop_t idetape_read_position_callback(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
@@ -1907,7 +1515,7 @@ static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc)
* to the request list without waiting for it to be serviced! In that case, we
* usually use idetape_queue_pc_head().
*/
-static int __idetape_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
+static int idetape_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
{
struct ide_tape_obj *tape = drive->driver_data;
struct request rq;
@@ -1939,7 +1547,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
timeout += jiffies;
while (time_before(jiffies, timeout)) {
idetape_create_test_unit_ready_cmd(&pc);
- if (!__idetape_queue_pc_tail(drive, &pc))
+ if (!idetape_queue_pc_tail(drive, &pc))
return 0;
if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2)
|| (tape->asc == 0x3A)) {
@@ -1948,7 +1556,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
return -ENOMEDIUM;
idetape_create_load_unload_cmd(drive, &pc,
IDETAPE_LU_LOAD_MASK);
- __idetape_queue_pc_tail(drive, &pc);
+ idetape_queue_pc_tail(drive, &pc);
load_attempted = 1;
/* not about to be ready */
} else if (!(tape->sense_key == 2 && tape->asc == 4 &&
@@ -1959,11 +1567,6 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
return -EIO;
}
-static int idetape_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
-{
- return __idetape_queue_pc_tail(drive, pc);
-}
-
static int idetape_flush_tape_buffers(ide_drive_t *drive)
{
struct ide_atapi_pc pc;
@@ -2029,50 +1632,21 @@ static int idetape_create_prevent_cmd(ide_drive_t *drive,
return 1;
}
-static int __idetape_discard_read_pipeline(ide_drive_t *drive)
+static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
- unsigned long flags;
- int cnt;
if (tape->chrdev_dir != IDETAPE_DIR_READ)
- return 0;
+ return;
- /* Remove merge stage. */
- cnt = tape->merge_stage_size / tape->blk_size;
- if (test_and_clear_bit(IDETAPE_FLAG_FILEMARK, &tape->flags))
- ++cnt; /* Filemarks count as 1 sector */
- tape->merge_stage_size = 0;
- if (tape->merge_stage != NULL) {
- __idetape_kfree_stage(tape->merge_stage);
- tape->merge_stage = NULL;
+ clear_bit(IDETAPE_FLAG_FILEMARK, &tape->flags);
+ tape->merge_bh_size = 0;
+ if (tape->merge_bh != NULL) {
+ ide_tape_kfree_buffer(tape);
+ tape->merge_bh = NULL;
}
- /* Clear pipeline flags. */
- clear_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags);
tape->chrdev_dir = IDETAPE_DIR_NONE;
-
- /* Remove pipeline stages. */
- if (tape->first_stage == NULL)
- return 0;
-
- spin_lock_irqsave(&tape->lock, flags);
- tape->next_stage = NULL;
- if (idetape_pipeline_active(tape))
- idetape_wait_for_request(drive, tape->active_data_rq);
- spin_unlock_irqrestore(&tape->lock, flags);
-
- while (tape->first_stage != NULL) {
- struct request *rq_ptr = &tape->first_stage->rq;
-
- cnt += rq_ptr->nr_sectors - rq_ptr->current_nr_sectors;
- if (rq_ptr->errors == IDETAPE_ERROR_FILEMARK)
- ++cnt;
- idetape_remove_stage_head(drive);
- }
- tape->nr_pending_stages = 0;
- tape->max_stages = tape->min_pipeline;
- return cnt;
}
/*
@@ -2089,7 +1663,7 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,
struct ide_atapi_pc pc;
if (tape->chrdev_dir == IDETAPE_DIR_READ)
- __idetape_discard_read_pipeline(drive);
+ __ide_tape_discard_merge_buffer(drive);
idetape_wait_ready(drive, 60 * 5 * HZ);
idetape_create_locate_cmd(drive, &pc, block, partition, skip);
retval = idetape_queue_pc_tail(drive, &pc);
@@ -2100,20 +1674,19 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,
return (idetape_queue_pc_tail(drive, &pc));
}
-static void idetape_discard_read_pipeline(ide_drive_t *drive,
+static void ide_tape_discard_merge_buffer(ide_drive_t *drive,
int restore_position)
{
idetape_tape_t *tape = drive->driver_data;
- int cnt;
int seek, position;
- cnt = __idetape_discard_read_pipeline(drive);
+ __ide_tape_discard_merge_buffer(drive);
if (restore_position) {
position = idetape_read_position(drive);
- seek = position > cnt ? position - cnt : 0;
+ seek = position > 0 ? position : 0;
if (idetape_position_tape(drive, seek, 0, 0)) {
printk(KERN_INFO "ide-tape: %s: position_tape failed in"
- " discard_pipeline()\n", tape->name);
+ " %s\n", tape->name, __func__);
return;
}
}
@@ -2131,12 +1704,6 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd);
- if (idetape_pipeline_active(tape)) {
- printk(KERN_ERR "ide-tape: bug: the pipeline is active in %s\n",
- __func__);
- return (0);
- }
-
idetape_init_rq(&rq, cmd);
rq.rq_disk = tape->disk;
rq.special = (void *)bh;
@@ -2148,27 +1715,13 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0)
return 0;
- if (tape->merge_stage)
- idetape_init_merge_stage(tape);
+ if (tape->merge_bh)
+ idetape_init_merge_buffer(tape);
if (rq.errors == IDETAPE_ERROR_GENERAL)
return -EIO;
return (tape->blk_size * (blocks-rq.current_nr_sectors));
}
-/* start servicing the pipeline stages, starting from tape->next_stage. */
-static void idetape_plug_pipeline(ide_drive_t *drive)
-{
- idetape_tape_t *tape = drive->driver_data;
-
- if (tape->next_stage == NULL)
- return;
- if (!idetape_pipeline_active(tape)) {
- set_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags);
- idetape_activate_next_stage(drive);
- (void) ide_do_drive_cmd(drive, tape->active_data_rq, ide_end);
- }
-}
-
static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc)
{
idetape_init_pc(pc);
@@ -2206,135 +1759,39 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd)
pc->idetape_callback = &idetape_pc_callback;
}
-static void idetape_wait_first_stage(ide_drive_t *drive)
-{
- idetape_tape_t *tape = drive->driver_data;
- unsigned long flags;
-
- if (tape->first_stage == NULL)
- return;
- spin_lock_irqsave(&tape->lock, flags);
- if (tape->active_stage == tape->first_stage)
- idetape_wait_for_request(drive, tape->active_data_rq);
- spin_unlock_irqrestore(&tape->lock, flags);
-}
-
-/*
- * Try to add a character device originated write request to our pipeline. In
- * case we don't succeed, we revert to non-pipelined operation mode for this
- * request. In order to accomplish that, we
- *
- * 1. Try to allocate a new pipeline stage.
- * 2. If we can't, wait for more and more requests to be serviced and try again
- * each time.
- * 3. If we still can't allocate a stage, fallback to non-pipelined operation
- * mode for this request.
- */
+/* Queue up a character device originated write request. */
static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_stage_t *new_stage;
- unsigned long flags;
- struct request *rq;
debug_log(DBG_CHRDEV, "Enter %s\n", __func__);
- /* Attempt to allocate a new stage. Beware possible race conditions. */
- while ((new_stage = idetape_kmalloc_stage(tape)) == NULL) {
- spin_lock_irqsave(&tape->lock, flags);
- if (idetape_pipeline_active(tape)) {
- idetape_wait_for_request(drive, tape->active_data_rq);
- spin_unlock_irqrestore(&tape->lock, flags);
- } else {
- spin_unlock_irqrestore(&tape->lock, flags);
- idetape_plug_pipeline(drive);
- if (idetape_pipeline_active(tape))
- continue;
- /*
- * The machine is short on memory. Fallback to non-
- * pipelined operation mode for this request.
- */
- return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE,
- blocks, tape->merge_stage->bh);
- }
- }
- rq = &new_stage->rq;
- idetape_init_rq(rq, REQ_IDETAPE_WRITE);
- /* Doesn't actually matter - We always assume sequential access */
- rq->sector = tape->first_frame;
- rq->current_nr_sectors = blocks;
- rq->nr_sectors = blocks;
-
- idetape_switch_buffers(tape, new_stage);
- idetape_add_stage_tail(drive, new_stage);
- tape->pipeline_head++;
- idetape_calculate_speeds(drive);
-
- /*
- * Estimate whether the tape has stopped writing by checking if our
- * write pipeline is currently empty. If we are not writing anymore,
- * wait for the pipeline to be almost completely full (90%) before
- * starting to service requests, so that we will be able to keep up with
- * the higher speeds of the tape.
- */
- if (!idetape_pipeline_active(tape)) {
- if (tape->nr_stages >= tape->max_stages * 9 / 10 ||
- tape->nr_stages >= tape->max_stages -
- tape->uncontrolled_pipeline_head_speed * 3 * 1024 /
- tape->blk_size) {
- tape->measure_insert_time = 1;
- tape->insert_time = jiffies;
- tape->insert_size = 0;
- tape->insert_speed = 0;
- idetape_plug_pipeline(drive);
- }
- }
- if (test_and_clear_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags))
- /* Return a deferred error */
- return -EIO;
- return blocks;
+ return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE,
+ blocks, tape->merge_bh);
}
-/*
- * Wait until all pending pipeline requests are serviced. Typically called on
- * device close.
- */
-static void idetape_wait_for_pipeline(ide_drive_t *drive)
-{
- idetape_tape_t *tape = drive->driver_data;
- unsigned long flags;
-
- while (tape->next_stage || idetape_pipeline_active(tape)) {
- idetape_plug_pipeline(drive);
- spin_lock_irqsave(&tape->lock, flags);
- if (idetape_pipeline_active(tape))
- idetape_wait_for_request(drive, tape->active_data_rq);
- spin_unlock_irqrestore(&tape->lock, flags);
- }
-}
-
-static void idetape_empty_write_pipeline(ide_drive_t *drive)
+static void ide_tape_flush_merge_buffer(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
int blocks, min;
struct idetape_bh *bh;
if (tape->chrdev_dir != IDETAPE_DIR_WRITE) {
- printk(KERN_ERR "ide-tape: bug: Trying to empty write pipeline,"
+ printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer"
" but we are not writing.\n");
return;
}
- if (tape->merge_stage_size > tape->stage_size) {
+ if (tape->merge_bh_size > tape->buffer_size) {
printk(KERN_ERR "ide-tape: bug: merge_buffer too big\n");
- tape->merge_stage_size = tape->stage_size;
+ tape->merge_bh_size = tape->buffer_size;
}
- if (tape->merge_stage_size) {
- blocks = tape->merge_stage_size / tape->blk_size;
- if (tape->merge_stage_size % tape->blk_size) {
+ if (tape->merge_bh_size) {
+ blocks = tape->merge_bh_size / tape->blk_size;
+ if (tape->merge_bh_size % tape->blk_size) {
unsigned int i;
blocks++;
- i = tape->blk_size - tape->merge_stage_size %
+ i = tape->blk_size - tape->merge_bh_size %
tape->blk_size;
bh = tape->bh->b_reqnext;
while (bh) {
@@ -2358,74 +1815,33 @@ static void idetape_empty_write_pipeline(ide_drive_t *drive)
}
}
(void) idetape_add_chrdev_write_request(drive, blocks);
- tape->merge_stage_size = 0;
+ tape->merge_bh_size = 0;
}
- idetape_wait_for_pipeline(drive);
- if (tape->merge_stage != NULL) {
- __idetape_kfree_stage(tape->merge_stage);
- tape->merge_stage = NULL;
+ if (tape->merge_bh != NULL) {
+ ide_tape_kfree_buffer(tape);
+ tape->merge_bh = NULL;
}
- clear_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags);
tape->chrdev_dir = IDETAPE_DIR_NONE;
-
- /*
- * On the next backup, perform the feedback loop again. (I don't want to
- * keep sense information between backups, as some systems are
- * constantly on, and the system load can be totally different on the
- * next backup).
- */
- tape->max_stages = tape->min_pipeline;
- if (tape->first_stage != NULL ||
- tape->next_stage != NULL ||
- tape->last_stage != NULL ||
- tape->nr_stages != 0) {
- printk(KERN_ERR "ide-tape: ide-tape pipeline bug, "
- "first_stage %p, next_stage %p, "
- "last_stage %p, nr_stages %d\n",
- tape->first_stage, tape->next_stage,
- tape->last_stage, tape->nr_stages);
- }
}
-static void idetape_restart_speed_control(ide_drive_t *drive)
+static int idetape_init_read(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
-
- tape->restart_speed_control_req = 0;
- tape->pipeline_head = 0;
- tape->controlled_last_pipeline_head = 0;
- tape->controlled_previous_pipeline_head = 0;
- tape->uncontrolled_previous_pipeline_head = 0;
- tape->controlled_pipeline_head_speed = 5000;
- tape->pipeline_head_speed = 5000;
- tape->uncontrolled_pipeline_head_speed = 0;
- tape->controlled_pipeline_head_time =
- tape->uncontrolled_pipeline_head_time = jiffies;
- tape->controlled_previous_head_time =
- tape->uncontrolled_previous_head_time = jiffies;
-}
-
-static int idetape_init_read(ide_drive_t *drive, int max_stages)
-{
- idetape_tape_t *tape = drive->driver_data;
- idetape_stage_t *new_stage;
- struct request rq;
int bytes_read;
- u16 blocks = *(u16 *)&tape->caps[12];
/* Initialize read operation */
if (tape->chrdev_dir != IDETAPE_DIR_READ) {
if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
- idetape_empty_write_pipeline(drive);
+ ide_tape_flush_merge_buffer(drive);
idetape_flush_tape_buffers(drive);
}
- if (tape->merge_stage || tape->merge_stage_size) {
- printk(KERN_ERR "ide-tape: merge_stage_size should be"
+ if (tape->merge_bh || tape->merge_bh_size) {
+ printk(KERN_ERR "ide-tape: merge_bh_size should be"
" 0 now\n");
- tape->merge_stage_size = 0;
+ tape->merge_bh_size = 0;
}
- tape->merge_stage = __idetape_kmalloc_stage(tape, 0, 0);
- if (!tape->merge_stage)
+ tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0);
+ if (!tape->merge_bh)
return -ENOMEM;
tape->chrdev_dir = IDETAPE_DIR_READ;
@@ -2438,54 +1854,23 @@ static int idetape_init_read(ide_drive_t *drive, int max_stages)
if (drive->dsc_overlap) {
bytes_read = idetape_queue_rw_tail(drive,
REQ_IDETAPE_READ, 0,
- tape->merge_stage->bh);
+ tape->merge_bh);
if (bytes_read < 0) {
- __idetape_kfree_stage(tape->merge_stage);
- tape->merge_stage = NULL;
+ ide_tape_kfree_buffer(tape);
+ tape->merge_bh = NULL;
tape->chrdev_dir = IDETAPE_DIR_NONE;
return bytes_read;
}
}
}
- if (tape->restart_speed_control_req)
- idetape_restart_speed_control(drive);
- idetape_init_rq(&rq, REQ_IDETAPE_READ);
- rq.sector = tape->first_frame;
- rq.nr_sectors = blocks;
- rq.current_nr_sectors = blocks;
- if (!test_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags) &&
- tape->nr_stages < max_stages) {
- new_stage = idetape_kmalloc_stage(tape);
- while (new_stage != NULL) {
- new_stage->rq = rq;
- idetape_add_stage_tail(drive, new_stage);
- if (tape->nr_stages >= max_stages)
- break;
- new_stage = idetape_kmalloc_stage(tape);
- }
- }
- if (!idetape_pipeline_active(tape)) {
- if (tape->nr_pending_stages >= 3 * max_stages / 4) {
- tape->measure_insert_time = 1;
- tape->insert_time = jiffies;
- tape->insert_size = 0;
- tape->insert_speed = 0;
- idetape_plug_pipeline(drive);
- }
- }
+
return 0;
}
-/*
- * Called from idetape_chrdev_read() to service a character device read request
- * and add read-ahead requests to our pipeline.
- */
+/* called from idetape_chrdev_read() to service a chrdev read request. */
static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)
{
idetape_tape_t *tape = drive->driver_data;
- unsigned long flags;
- struct request *rq_ptr;
- int bytes_read;
debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks);
@@ -2493,39 +1878,10 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)
if (test_bit(IDETAPE_FLAG_FILEMARK, &tape->flags))
return 0;
- /* Wait for the next block to reach the head of the pipeline. */
- idetape_init_read(drive, tape->max_stages);
- if (tape->first_stage == NULL) {
- if (test_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags))
- return 0;
- return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks,
- tape->merge_stage->bh);
- }
- idetape_wait_first_stage(drive);
- rq_ptr = &tape->first_stage->rq;
- bytes_read = tape->blk_size * (rq_ptr->nr_sectors -
- rq_ptr->current_nr_sectors);
- rq_ptr->nr_sectors = 0;
- rq_ptr->current_nr_sectors = 0;
+ idetape_init_read(drive);
- if (rq_ptr->errors == IDETAPE_ERROR_EOD)
- return 0;
- else {
- idetape_switch_buffers(tape, tape->first_stage);
- if (rq_ptr->errors == IDETAPE_ERROR_FILEMARK)
- set_bit(IDETAPE_FLAG_FILEMARK, &tape->flags);
- spin_lock_irqsave(&tape->lock, flags);
- idetape_remove_stage_head(drive);
- spin_unlock_irqrestore(&tape->lock, flags);
- tape->pipeline_head++;
- idetape_calculate_speeds(drive);
- }
- if (bytes_read > blocks * tape->blk_size) {
- printk(KERN_ERR "ide-tape: bug: trying to return more bytes"
- " than requested\n");
- bytes_read = blocks * tape->blk_size;
- }
- return (bytes_read);
+ return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks,
+ tape->merge_bh);
}
static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
@@ -2537,8 +1893,8 @@ static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
while (bcount) {
unsigned int count;
- bh = tape->merge_stage->bh;
- count = min(tape->stage_size, bcount);
+ bh = tape->merge_bh;
+ count = min(tape->buffer_size, bcount);
bcount -= count;
blocks = count / tape->blk_size;
while (count) {
@@ -2549,31 +1905,10 @@ static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
bh = bh->b_reqnext;
}
idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks,
- tape->merge_stage->bh);
+ tape->merge_bh);
}
}
-static int idetape_pipeline_size(ide_drive_t *drive)
-{
- idetape_tape_t *tape = drive->driver_data;
- idetape_stage_t *stage;
- struct request *rq;
- int size = 0;
-
- idetape_wait_for_pipeline(drive);
- stage = tape->first_stage;
- while (stage != NULL) {
- rq = &stage->rq;
- size += tape->blk_size * (rq->nr_sectors -
- rq->current_nr_sectors);
- if (rq->errors == IDETAPE_ERROR_FILEMARK)
- size += tape->blk_size;
- stage = stage->next;
- }
- size += tape->merge_stage_size;
- return size;
-}
-
/*
* Rewinds the tape to the Beginning Of the current Partition (BOP). We
* currently support only one partition.
@@ -2619,11 +1954,10 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,
if (copy_from_user(&config, argp, sizeof(config)))
return -EFAULT;
tape->best_dsc_rw_freq = config.dsc_rw_frequency;
- tape->max_stages = config.nr_stages;
break;
case 0x0350:
config.dsc_rw_frequency = (int) tape->best_dsc_rw_freq;
- config.nr_stages = tape->max_stages;
+ config.nr_stages = 1;
if (copy_to_user(argp, &config, sizeof(config)))
return -EFAULT;
break;
@@ -2633,19 +1967,11 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,
return 0;
}
-/*
- * The function below is now a bit more complicated than just passing the
- * command to the tape since we may have crossed some filemarks during our
- * pipelined read-ahead mode. As a minor side effect, the pipeline enables us to
- * support MTFSFM when the filemark is in our internal pipeline even if the tape
- * doesn't support spacing over filemarks in the reverse direction.
- */
static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
int mt_count)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc pc;
- unsigned long flags;
int retval, count = 0;
int sprev = !!(tape->caps[4] & 0x20);
@@ -2658,48 +1984,12 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
}
if (tape->chrdev_dir == IDETAPE_DIR_READ) {
- /* its a read-ahead buffer, scan it for crossed filemarks. */
- tape->merge_stage_size = 0;
+ tape->merge_bh_size = 0;
if (test_and_clear_bit(IDETAPE_FLAG_FILEMARK, &tape->flags))
++count;
- while (tape->first_stage != NULL) {
- if (count == mt_count) {
- if (mt_op == MTFSFM)
- set_bit(IDETAPE_FLAG_FILEMARK,
- &tape->flags);
- return 0;
- }
- spin_lock_irqsave(&tape->lock, flags);
- if (tape->first_stage == tape->active_stage) {
- /*
- * We have reached the active stage in the read
- * pipeline. There is no point in allowing the
- * drive to continue reading any farther, so we
- * stop the pipeline.
- *
- * This section should be moved to a separate
- * subroutine because similar operations are
- * done in __idetape_discard_read_pipeline(),
- * for example.
- */
- tape->next_stage = NULL;
- spin_unlock_irqrestore(&tape->lock, flags);
- idetape_wait_first_stage(drive);
- tape->next_stage = tape->first_stage->next;
- } else
- spin_unlock_irqrestore(&tape->lock, flags);
- if (tape->first_stage->rq.errors ==
- IDETAPE_ERROR_FILEMARK)
- ++count;
- idetape_remove_stage_head(drive);
- }
- idetape_discard_read_pipeline(drive, 0);
+ ide_tape_discard_merge_buffer(drive, 0);
}
- /*
- * The filemark was not found in our internal pipeline; now we can issue
- * the space command.
- */
switch (mt_op) {
case MTFSF:
case MTBSF:
@@ -2755,27 +2045,25 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
(count % tape->blk_size) == 0)
tape->user_bs_factor = count / tape->blk_size;
}
- rc = idetape_init_read(drive, tape->max_stages);
+ rc = idetape_init_read(drive);
if (rc < 0)
return rc;
if (count == 0)
return (0);
- if (tape->merge_stage_size) {
- actually_read = min((unsigned int)(tape->merge_stage_size),
+ if (tape->merge_bh_size) {
+ actually_read = min((unsigned int)(tape->merge_bh_size),
(unsigned int)count);
- if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage,
- actually_read))
+ if (idetape_copy_stage_to_user(tape, buf, actually_read))
ret = -EFAULT;
buf += actually_read;
- tape->merge_stage_size -= actually_read;
+ tape->merge_bh_size -= actually_read;
count -= actually_read;
}
- while (count >= tape->stage_size) {
+ while (count >= tape->buffer_size) {
bytes_read = idetape_add_chrdev_read_request(drive, ctl);
if (bytes_read <= 0)
goto finish;
- if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage,
- bytes_read))
+ if (idetape_copy_stage_to_user(tape, buf, bytes_read))
ret = -EFAULT;
buf += bytes_read;
count -= bytes_read;
@@ -2786,11 +2074,10 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
if (bytes_read <= 0)
goto finish;
temp = min((unsigned long)count, (unsigned long)bytes_read);
- if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage,
- temp))
+ if (idetape_copy_stage_to_user(tape, buf, temp))
ret = -EFAULT;
actually_read += temp;
- tape->merge_stage_size = bytes_read-temp;
+ tape->merge_bh_size = bytes_read-temp;
}
finish:
if (!actually_read && test_bit(IDETAPE_FLAG_FILEMARK, &tape->flags)) {
@@ -2821,17 +2108,17 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
/* Initialize write operation */
if (tape->chrdev_dir != IDETAPE_DIR_WRITE) {
if (tape->chrdev_dir == IDETAPE_DIR_READ)
- idetape_discard_read_pipeline(drive, 1);
- if (tape->merge_stage || tape->merge_stage_size) {
- printk(KERN_ERR "ide-tape: merge_stage_size "
+ ide_tape_discard_merge_buffer(drive, 1);
+ if (tape->merge_bh || tape->merge_bh_size) {
+ printk(KERN_ERR "ide-tape: merge_bh_size "
"should be 0 now\n");
- tape->merge_stage_size = 0;
+ tape->merge_bh_size = 0;
}
- tape->merge_stage = __idetape_kmalloc_stage(tape, 0, 0);
- if (!tape->merge_stage)
+ tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0);
+ if (!tape->merge_bh)
return -ENOMEM;
tape->chrdev_dir = IDETAPE_DIR_WRITE;
- idetape_init_merge_stage(tape);
+ idetape_init_merge_buffer(tape);
/*
* Issue a write 0 command to ensure that DSC handshake is
@@ -2842,10 +2129,10 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
if (drive->dsc_overlap) {
ssize_t retval = idetape_queue_rw_tail(drive,
REQ_IDETAPE_WRITE, 0,
- tape->merge_stage->bh);
+ tape->merge_bh);
if (retval < 0) {
- __idetape_kfree_stage(tape->merge_stage);
- tape->merge_stage = NULL;
+ ide_tape_kfree_buffer(tape);
+ tape->merge_bh = NULL;
tape->chrdev_dir = IDETAPE_DIR_NONE;
return retval;
}
@@ -2853,49 +2140,44 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
}
if (count == 0)
return (0);
- if (tape->restart_speed_control_req)
- idetape_restart_speed_control(drive);
- if (tape->merge_stage_size) {
- if (tape->merge_stage_size >= tape->stage_size) {
+ if (tape->merge_bh_size) {
+ if (tape->merge_bh_size >= tape->buffer_size) {
printk(KERN_ERR "ide-tape: bug: merge buf too big\n");
- tape->merge_stage_size = 0;
+ tape->merge_bh_size = 0;
}
actually_written = min((unsigned int)
- (tape->stage_size - tape->merge_stage_size),
+ (tape->buffer_size - tape->merge_bh_size),
(unsigned int)count);
- if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf,
- actually_written))
+ if (idetape_copy_stage_from_user(tape, buf, actually_written))
ret = -EFAULT;
buf += actually_written;
- tape->merge_stage_size += actually_written;
+ tape->merge_bh_size += actually_written;
count -= actually_written;
- if (tape->merge_stage_size == tape->stage_size) {
+ if (tape->merge_bh_size == tape->buffer_size) {
ssize_t retval;
- tape->merge_stage_size = 0;
+ tape->merge_bh_size = 0;
retval = idetape_add_chrdev_write_request(drive, ctl);
if (retval <= 0)
return (retval);
}
}
- while (count >= tape->stage_size) {
+ while (count >= tape->buffer_size) {
ssize_t retval;
- if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf,
- tape->stage_size))
+ if (idetape_copy_stage_from_user(tape, buf, tape->buffer_size))
ret = -EFAULT;
- buf += tape->stage_size;
- count -= tape->stage_size;
+ buf += tape->buffer_size;
+ count -= tape->buffer_size;
retval = idetape_add_chrdev_write_request(drive, ctl);
- actually_written += tape->stage_size;
+ actually_written += tape->buffer_size;
if (retval <= 0)
return (retval);
}
if (count) {
actually_written += count;
- if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf,
- count))
+ if (idetape_copy_stage_from_user(tape, buf, count))
ret = -EFAULT;
- tape->merge_stage_size += count;
+ tape->merge_bh_size += count;
}
return ret ? ret : actually_written;
}
@@ -2919,8 +2201,7 @@ static int idetape_write_filemark(ide_drive_t *drive)
*
* Note: MTBSF and MTBSFM are not supported when the tape doesn't support
* spacing over filemarks in the reverse direction. In this case, MTFSFM is also
- * usually not supported (it is supported in the rare case in which we crossed
- * the filemark during our read-ahead pipelined operation mode).
+ * usually not supported.
*
* The following commands are currently not supported:
*
@@ -2936,7 +2217,6 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
debug_log(DBG_ERR, "Handling MTIOCTOP ioctl: mt_op=%d, mt_count=%d\n",
mt_op, mt_count);
- /* Commands which need our pipelined read-ahead stages. */
switch (mt_op) {
case MTFSF:
case MTFSFM:
@@ -2953,7 +2233,7 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
case MTWEOF:
if (tape->write_prot)
return -EACCES;
- idetape_discard_read_pipeline(drive, 1);
+ ide_tape_discard_merge_buffer(drive, 1);
for (i = 0; i < mt_count; i++) {
retval = idetape_write_filemark(drive);
if (retval)
@@ -2961,12 +2241,12 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
}
return 0;
case MTREW:
- idetape_discard_read_pipeline(drive, 0);
+ ide_tape_discard_merge_buffer(drive, 0);
if (idetape_rewind_tape(drive))
return -EIO;
return 0;
case MTLOAD:
- idetape_discard_read_pipeline(drive, 0);
+ ide_tape_discard_merge_buffer(drive, 0);
idetape_create_load_unload_cmd(drive, &pc,
IDETAPE_LU_LOAD_MASK);
return idetape_queue_pc_tail(drive, &pc);
@@ -2981,7 +2261,7 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
if (!idetape_queue_pc_tail(drive, &pc))
tape->door_locked = DOOR_UNLOCKED;
}
- idetape_discard_read_pipeline(drive, 0);
+ ide_tape_discard_merge_buffer(drive, 0);
idetape_create_load_unload_cmd(drive, &pc,
!IDETAPE_LU_LOAD_MASK);
retval = idetape_queue_pc_tail(drive, &pc);
@@ -2989,10 +2269,10 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
clear_bit(IDETAPE_FLAG_MEDIUM_PRESENT, &tape->flags);
return retval;
case MTNOP:
- idetape_discard_read_pipeline(drive, 0);
+ ide_tape_discard_merge_buffer(drive, 0);
return idetape_flush_tape_buffers(drive);
case MTRETEN:
- idetape_discard_read_pipeline(drive, 0);
+ ide_tape_discard_merge_buffer(drive, 0);
idetape_create_load_unload_cmd(drive, &pc,
IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK);
return idetape_queue_pc_tail(drive, &pc);
@@ -3014,11 +2294,11 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
set_bit(IDETAPE_FLAG_DETECT_BS, &tape->flags);
return 0;
case MTSEEK:
- idetape_discard_read_pipeline(drive, 0);
+ ide_tape_discard_merge_buffer(drive, 0);
return idetape_position_tape(drive,
mt_count * tape->user_bs_factor, tape->partition, 0);
case MTSETPART:
- idetape_discard_read_pipeline(drive, 0);
+ ide_tape_discard_merge_buffer(drive, 0);
return idetape_position_tape(drive, 0, mt_count, 0);
case MTFSR:
case MTBSR:
@@ -3063,13 +2343,12 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
debug_log(DBG_CHRDEV, "Enter %s, cmd=%u\n", __func__, cmd);
- tape->restart_speed_control_req = 1;
if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
- idetape_empty_write_pipeline(drive);
+ ide_tape_flush_merge_buffer(drive);
idetape_flush_tape_buffers(drive);
}
if (cmd == MTIOCGET || cmd == MTIOCPOS) {
- block_offset = idetape_pipeline_size(drive) /
+ block_offset = tape->merge_bh_size /
(tape->blk_size * tape->user_bs_factor);
position = idetape_read_position(drive);
if (position < 0)
@@ -3101,7 +2380,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
return 0;
default:
if (tape->chrdev_dir == IDETAPE_DIR_READ)
- idetape_discard_read_pipeline(drive, 1);
+ ide_tape_discard_merge_buffer(drive, 1);
return idetape_blkdev_ioctl(drive, cmd, arg);
}
}
@@ -3175,9 +2454,6 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
if (!test_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags))
(void)idetape_rewind_tape(drive);
- if (tape->chrdev_dir != IDETAPE_DIR_READ)
- clear_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags);
-
/* Read block size and write protect status from drive. */
ide_tape_get_bsize_from_bdesc(drive);
@@ -3206,8 +2482,6 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
}
}
}
- idetape_restart_speed_control(drive);
- tape->restart_speed_control_req = 0;
return 0;
out_put_tape:
@@ -3219,13 +2493,13 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_empty_write_pipeline(drive);
- tape->merge_stage = __idetape_kmalloc_stage(tape, 1, 0);
- if (tape->merge_stage != NULL) {
+ ide_tape_flush_merge_buffer(drive);
+ tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1, 0);
+ if (tape->merge_bh != NULL) {
idetape_pad_zeros(drive, tape->blk_size *
(tape->user_bs_factor - 1));
- __idetape_kfree_stage(tape->merge_stage);
- tape->merge_stage = NULL;
+ ide_tape_kfree_buffer(tape);
+ tape->merge_bh = NULL;
}
idetape_write_filemark(drive);
idetape_flush_tape_buffers(drive);
@@ -3248,14 +2522,9 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
idetape_write_release(drive, minor);
if (tape->chrdev_dir == IDETAPE_DIR_READ) {
if (minor < 128)
- idetape_discard_read_pipeline(drive, 1);
- else
- idetape_wait_for_pipeline(drive);
- }
- if (tape->cache_stage != NULL) {
- __idetape_kfree_stage(tape->cache_stage);
- tape->cache_stage = NULL;
+ ide_tape_discard_merge_buffer(drive, 1);
}
+
if (minor < 128 && test_bit(IDETAPE_FLAG_MEDIUM_PRESENT, &tape->flags))
(void) idetape_rewind_tape(drive);
if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
@@ -3392,33 +2661,15 @@ static void idetape_add_settings(ide_drive_t *drive)
ide_add_setting(drive, "buffer", SETTING_READ, TYPE_SHORT, 0, 0xffff,
1, 2, (u16 *)&tape->caps[16], NULL);
- ide_add_setting(drive, "pipeline_min", SETTING_RW, TYPE_INT, 1, 0xffff,
- tape->stage_size / 1024, 1, &tape->min_pipeline, NULL);
- ide_add_setting(drive, "pipeline", SETTING_RW, TYPE_INT, 1, 0xffff,
- tape->stage_size / 1024, 1, &tape->max_stages, NULL);
- ide_add_setting(drive, "pipeline_max", SETTING_RW, TYPE_INT, 1, 0xffff,
- tape->stage_size / 1024, 1, &tape->max_pipeline, NULL);
- ide_add_setting(drive, "pipeline_used", SETTING_READ, TYPE_INT, 0,
- 0xffff, tape->stage_size / 1024, 1, &tape->nr_stages,
- NULL);
- ide_add_setting(drive, "pipeline_pending", SETTING_READ, TYPE_INT, 0,
- 0xffff, tape->stage_size / 1024, 1,
- &tape->nr_pending_stages, NULL);
ide_add_setting(drive, "speed", SETTING_READ, TYPE_SHORT, 0, 0xffff,
1, 1, (u16 *)&tape->caps[14], NULL);
- ide_add_setting(drive, "stage", SETTING_READ, TYPE_INT, 0, 0xffff, 1,
- 1024, &tape->stage_size, NULL);
+ ide_add_setting(drive, "buffer_size", SETTING_READ, TYPE_INT, 0, 0xffff,
+ 1, 1024, &tape->buffer_size, NULL);
ide_add_setting(drive, "tdsc", SETTING_RW, TYPE_INT, IDETAPE_DSC_RW_MIN,
IDETAPE_DSC_RW_MAX, 1000, HZ, &tape->best_dsc_rw_freq,
NULL);
ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1,
1, &drive->dsc_overlap, NULL);
- ide_add_setting(drive, "pipeline_head_speed_c", SETTING_READ, TYPE_INT,
- 0, 0xffff, 1, 1, &tape->controlled_pipeline_head_speed,
- NULL);
- ide_add_setting(drive, "pipeline_head_speed_u", SETTING_READ, TYPE_INT,
- 0, 0xffff, 1, 1,
- &tape->uncontrolled_pipeline_head_speed, NULL);
ide_add_setting(drive, "avg_speed", SETTING_READ, TYPE_INT, 0, 0xffff,
1, 1, &tape->avg_speed, NULL);
ide_add_setting(drive, "debug_mask", SETTING_RW, TYPE_INT, 0, 0xffff, 1,
@@ -3441,11 +2692,10 @@ static inline void idetape_add_settings(ide_drive_t *drive) { ; }
*/
static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
{
- unsigned long t1, tmid, tn, t;
+ unsigned long t;
int speed;
- int stage_size;
+ int buffer_size;
u8 gcw[2];
- struct sysinfo si;
u16 *ctl = (u16 *)&tape->caps[12];
spin_lock_init(&tape->lock);
@@ -3464,65 +2714,33 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
tape->name[2] = '0' + minor;
tape->chrdev_dir = IDETAPE_DIR_NONE;
tape->pc = tape->pc_stack;
- tape->max_insert_speed = 10000;
- tape->speed_control = 1;
*((unsigned short *) &gcw) = drive->id->config;
/* Command packet DRQ type */
if (((gcw[0] & 0x60) >> 5) == 1)
set_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags);
- tape->min_pipeline = 10;
- tape->max_pipeline = 10;
- tape->max_stages = 10;
-
idetape_get_inquiry_results(drive);
idetape_get_mode_sense_results(drive);
ide_tape_get_bsize_from_bdesc(drive);
tape->user_bs_factor = 1;
- tape->stage_size = *ctl * tape->blk_size;
- while (tape->stage_size > 0xffff) {
+ tape->buffer_size = *ctl * tape->blk_size;
+ while (tape->buffer_size > 0xffff) {
printk(KERN_NOTICE "ide-tape: decreasing stage size\n");
*ctl /= 2;
- tape->stage_size = *ctl * tape->blk_size;
+ tape->buffer_size = *ctl * tape->blk_size;
}
- stage_size = tape->stage_size;
- tape->pages_per_stage = stage_size / PAGE_SIZE;
- if (stage_size % PAGE_SIZE) {
- tape->pages_per_stage++;
- tape->excess_bh_size = PAGE_SIZE - stage_size % PAGE_SIZE;
+ buffer_size = tape->buffer_size;
+ tape->pages_per_buffer = buffer_size / PAGE_SIZE;
+ if (buffer_size % PAGE_SIZE) {
+ tape->pages_per_buffer++;
+ tape->excess_bh_size = PAGE_SIZE - buffer_size % PAGE_SIZE;
}
- /* Select the "best" DSC read/write polling freq and pipeline size. */
+ /* select the "best" DSC read/write polling freq */
speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]);
- tape->max_stages = speed * 1000 * 10 / tape->stage_size;
-
- /* Limit memory use for pipeline to 10% of physical memory */
- si_meminfo(&si);
- if (tape->max_stages * tape->stage_size >
- si.totalram * si.mem_unit / 10)
- tape->max_stages =
- si.totalram * si.mem_unit / (10 * tape->stage_size);
-
- tape->max_stages = min(tape->max_stages, IDETAPE_MAX_PIPELINE_STAGES);
- tape->min_pipeline = min(tape->max_stages, IDETAPE_MIN_PIPELINE_STAGES);
- tape->max_pipeline =
- min(tape->max_stages * 2, IDETAPE_MAX_PIPELINE_STAGES);
- if (tape->max_stages == 0) {
- tape->max_stages = 1;
- tape->min_pipeline = 1;
- tape->max_pipeline = 1;
- }
-
- t1 = (tape->stage_size * HZ) / (speed * 1000);
- tmid = (*(u16 *)&tape->caps[16] * 32 * HZ) / (speed * 125);
- tn = (IDETAPE_FIFO_THRESHOLD * tape->stage_size * HZ) / (speed * 1000);
-
- if (tape->max_stages)
- t = tn;
- else
- t = t1;
+ t = (IDETAPE_FIFO_THRESHOLD * tape->buffer_size * HZ) / (speed * 1000);
/*
* Ensure that the number we got makes sense; limit it within
@@ -3532,11 +2750,10 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
min_t(unsigned long, t, IDETAPE_DSC_RW_MAX),
IDETAPE_DSC_RW_MIN);
printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, "
- "%dkB pipeline, %lums tDSC%s\n",
+ "%lums tDSC%s\n",
drive->name, tape->name, *(u16 *)&tape->caps[14],
- (*(u16 *)&tape->caps[16] * 512) / tape->stage_size,
- tape->stage_size / 1024,
- tape->max_stages * tape->stage_size / 1024,
+ (*(u16 *)&tape->caps[16] * 512) / tape->buffer_size,
+ tape->buffer_size / 1024,
tape->best_dsc_rw_freq * 1000 / HZ,
drive->using_dma ? ", DMA":"");
@@ -3560,7 +2777,7 @@ static void ide_tape_release(struct kref *kref)
ide_drive_t *drive = tape->drive;
struct gendisk *g = tape->disk;
- BUG_ON(tape->first_stage != NULL || tape->merge_stage_size);
+ BUG_ON(tape->merge_bh_size);
drive->dsc_overlap = 0;
drive->driver_data = NULL;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 155cc904f4e..0c908ca3ff7 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -33,60 +33,18 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+void ide_tf_dump(const char *s, struct ide_taskfile *tf)
{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
- HIHI = 0xFF;
-
#ifdef DEBUG
printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x "
"lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n",
- drive->name, tf->feature, tf->nsect, tf->lbal,
+ s, tf->feature, tf->nsect, tf->lbal,
tf->lbam, tf->lbah, tf->device, tf->command);
printk("%s: hob: nsect 0x%02x lbal 0x%02x "
"lbam 0x%02x lbah 0x%02x\n",
- drive->name, tf->hob_nsect, tf->hob_lbal,
+ s, tf->hob_nsect, tf->hob_lbal,
tf->hob_lbam, tf->hob_lbah);
#endif
-
- ide_set_irq(drive, 1);
-
- if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0)
- SELECT_MASK(drive, 0);
-
- if (task->tf_flags & IDE_TFLAG_OUT_DATA)
- hwif->OUTW((tf->hob_data << 8) | tf->data,
- hwif->io_ports[IDE_DATA_OFFSET]);
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
- hwif->OUTB(tf->hob_feature, hwif->io_ports[IDE_FEATURE_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
- hwif->OUTB(tf->hob_nsect, hwif->io_ports[IDE_NSECTOR_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
- hwif->OUTB(tf->hob_lbal, hwif->io_ports[IDE_SECTOR_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
- hwif->OUTB(tf->hob_lbam, hwif->io_ports[IDE_LCYL_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
- hwif->OUTB(tf->hob_lbah, hwif->io_ports[IDE_HCYL_OFFSET]);
-
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
- hwif->OUTB(tf->feature, hwif->io_ports[IDE_FEATURE_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
- hwif->OUTB(tf->nsect, hwif->io_ports[IDE_NSECTOR_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
- hwif->OUTB(tf->lbal, hwif->io_ports[IDE_SECTOR_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
- hwif->OUTB(tf->lbam, hwif->io_ports[IDE_LCYL_OFFSET]);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
- hwif->OUTB(tf->lbah, hwif->io_ports[IDE_HCYL_OFFSET]);
-
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
- hwif->OUTB((tf->device & HIHI) | drive->select.all,
- hwif->io_ports[IDE_SELECT_OFFSET]);
}
int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
@@ -135,6 +93,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
ide_hwif_t *hwif = HWIF(drive);
struct ide_taskfile *tf = &task->tf;
ide_handler_t *handler = NULL;
+ const struct ide_dma_ops *dma_ops = hwif->dma_ops;
if (task->data_phase == TASKFILE_MULTI_IN ||
task->data_phase == TASKFILE_MULTI_OUT) {
@@ -148,14 +107,15 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
if (task->tf_flags & IDE_TFLAG_FLAGGED)
task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS;
- if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0)
- ide_tf_load(drive, task);
+ if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
+ ide_tf_dump(drive->name, tf);
+ hwif->tf_load(drive, task);
+ }
switch (task->data_phase) {
case TASKFILE_MULTI_OUT:
case TASKFILE_OUT:
- hwif->OUTBSYNC(drive, tf->command,
- hwif->io_ports[IDE_COMMAND_OFFSET]);
+ hwif->OUTBSYNC(drive, tf->command, hwif->io_ports.command_addr);
ndelay(400); /* FIXME */
return pre_task_out_intr(drive, task->rq);
case TASKFILE_MULTI_IN:
@@ -178,10 +138,10 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
return ide_started;
default:
if (task_dma_ok(task) == 0 || drive->using_dma == 0 ||
- hwif->dma_setup(drive))
+ dma_ops->dma_setup(drive))
return ide_stopped;
- hwif->dma_exec_cmd(drive, tf->command);
- hwif->dma_start(drive);
+ dma_ops->dma_exec_cmd(drive, tf->command);
+ dma_ops->dma_start(drive);
return ide_started;
}
}
@@ -283,7 +243,8 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
return stat;
}
-static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
+static void ide_pio_sector(ide_drive_t *drive, struct request *rq,
+ unsigned int write)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
@@ -323,9 +284,9 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
/* do the actual data transfer */
if (write)
- hwif->ata_output_data(drive, buf, SECTOR_WORDS);
+ hwif->output_data(drive, rq, buf, SECTOR_SIZE);
else
- hwif->ata_input_data(drive, buf, SECTOR_WORDS);
+ hwif->input_data(drive, rq, buf, SECTOR_SIZE);
kunmap_atomic(buf, KM_BIO_SRC_IRQ);
#ifdef CONFIG_HIGHMEM
@@ -333,13 +294,14 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
#endif
}
-static void ide_pio_multi(ide_drive_t *drive, unsigned int write)
+static void ide_pio_multi(ide_drive_t *drive, struct request *rq,
+ unsigned int write)
{
unsigned int nsect;
nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count);
while (nsect--)
- ide_pio_sector(drive, write);
+ ide_pio_sector(drive, rq, write);
}
static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
@@ -362,10 +324,10 @@ static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
switch (drive->hwif->data_phase) {
case TASKFILE_MULTI_IN:
case TASKFILE_MULTI_OUT:
- ide_pio_multi(drive, write);
+ ide_pio_multi(drive, rq, write);
break;
default:
- ide_pio_sector(drive, write);
+ ide_pio_sector(drive, rq, write);
break;
}
@@ -455,7 +417,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)
/* Error? */
if (stat & ERR_STAT)
- return task_error(drive, rq, __FUNCTION__, stat);
+ return task_error(drive, rq, __func__, stat);
/* Didn't want any data? Odd. */
if (!(stat & DRQ_STAT))
@@ -467,7 +429,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)
if (!hwif->nleft) {
stat = wait_drive_not_busy(drive);
if (!OK_STAT(stat, 0, BAD_STAT))
- return task_error(drive, rq, __FUNCTION__, stat);
+ return task_error(drive, rq, __func__, stat);
task_end_request(drive, rq, stat);
return ide_stopped;
}
@@ -488,11 +450,11 @@ static ide_startstop_t task_out_intr (ide_drive_t *drive)
u8 stat = ide_read_status(drive);
if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
- return task_error(drive, rq, __FUNCTION__, stat);
+ return task_error(drive, rq, __func__, stat);
/* Deal with unexpected ATA data phase. */
if (((stat & DRQ_STAT) == 0) ^ !hwif->nleft)
- return task_error(drive, rq, __FUNCTION__, stat);
+ return task_error(drive, rq, __func__, stat);
if (!hwif->nleft) {
task_end_request(drive, rq, stat);
@@ -532,8 +494,7 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
{
struct request rq;
- memset(&rq, 0, sizeof(rq));
- rq.ref_count = 1;
+ blk_rq_init(NULL, &rq);
rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
rq.buffer = buf;
@@ -675,7 +636,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
/* (hs): give up if multcount is not set */
printk(KERN_ERR "%s: %s Multimode Write " \
"multcount is not set\n",
- drive->name, __FUNCTION__);
+ drive->name, __func__);
err = -EPERM;
goto abort;
}
@@ -692,7 +653,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
/* (hs): give up if multcount is not set */
printk(KERN_ERR "%s: %s Multimode Read failure " \
"multcount is not set\n",
- drive->name, __FUNCTION__);
+ drive->name, __func__);
err = -EPERM;
goto abort;
}
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index d868ca44d03..c758dcb13b1 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -94,12 +94,6 @@ DEFINE_MUTEX(ide_cfg_mtx);
int noautodma = 0;
-#ifdef CONFIG_BLK_DEV_IDEACPI
-int ide_noacpi = 0;
-int ide_noacpitfs = 1;
-int ide_noacpionboot = 1;
-#endif
-
ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */
static void ide_port_init_devices_data(ide_hwif_t *);
@@ -227,79 +221,6 @@ static int ide_system_bus_speed(void)
return pci_dev_present(pci_default) ? 33 : 50;
}
-static struct resource* hwif_request_region(ide_hwif_t *hwif,
- unsigned long addr, int num)
-{
- struct resource *res = request_region(addr, num, hwif->name);
-
- if (!res)
- printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
- hwif->name, addr, addr+num-1);
- return res;
-}
-
-/**
- * ide_hwif_request_regions - request resources for IDE
- * @hwif: interface to use
- *
- * Requests all the needed resources for an interface.
- * Right now core IDE code does this work which is deeply wrong.
- * MMIO leaves it to the controller driver,
- * PIO will migrate this way over time.
- */
-
-int ide_hwif_request_regions(ide_hwif_t *hwif)
-{
- unsigned long addr;
-
- if (hwif->mmio)
- return 0;
-
- addr = hwif->io_ports[IDE_CONTROL_OFFSET];
-
- if (addr && !hwif_request_region(hwif, addr, 1))
- goto control_region_busy;
-
- addr = hwif->io_ports[IDE_DATA_OFFSET];
- BUG_ON((addr | 7) != hwif->io_ports[IDE_STATUS_OFFSET]);
-
- if (!hwif_request_region(hwif, addr, 8))
- goto data_region_busy;
-
- return 0;
-
-data_region_busy:
- addr = hwif->io_ports[IDE_CONTROL_OFFSET];
- if (addr)
- release_region(addr, 1);
-control_region_busy:
- /* If any errors are return, we drop the hwif interface. */
- return -EBUSY;
-}
-
-/**
- * ide_hwif_release_regions - free IDE resources
- *
- * Note that we only release the standard ports,
- * and do not even try to handle any extra ports
- * allocated for weird IDE interface chipsets.
- *
- * Note also that we don't yet handle mmio resources here. More
- * importantly our caller should be doing this so we need to
- * restructure this as a helper function for drivers.
- */
-
-void ide_hwif_release_regions(ide_hwif_t *hwif)
-{
- if (hwif->mmio)
- return;
-
- if (hwif->io_ports[IDE_CONTROL_OFFSET])
- release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
-
- release_region(hwif->io_ports[IDE_DATA_OFFSET], 8);
-}
-
void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
{
ide_hwgroup_t *hwgroup = hwif->hwgroup;
@@ -366,7 +287,7 @@ EXPORT_SYMBOL_GPL(ide_port_unregister_devices);
/**
* ide_unregister - free an IDE interface
- * @index: index of interface (will change soon to a pointer)
+ * @hwif: IDE interface
*
* Perform the final unregister of an IDE interface. At the moment
* we don't refcount interfaces so this will also get split up.
@@ -386,19 +307,16 @@ EXPORT_SYMBOL_GPL(ide_port_unregister_devices);
* This is raving bonkers.
*/
-void ide_unregister(unsigned int index)
+void ide_unregister(ide_hwif_t *hwif)
{
- ide_hwif_t *hwif, *g;
+ ide_hwif_t *g;
ide_hwgroup_t *hwgroup;
int irq_count = 0;
- BUG_ON(index >= MAX_HWIFS);
-
BUG_ON(in_interrupt());
BUG_ON(irqs_disabled());
mutex_lock(&ide_cfg_mtx);
spin_lock_irq(&ide_lock);
- hwif = &ide_hwifs[index];
if (!hwif->present)
goto abort;
__ide_port_unregister_devices(hwif);
@@ -436,12 +354,10 @@ void ide_unregister(unsigned int index)
spin_lock_irq(&ide_lock);
if (hwif->dma_base)
- (void)ide_release_dma(hwif);
-
- ide_hwif_release_regions(hwif);
+ ide_release_dma_engine(hwif);
/* restore hwif data to pristine status */
- ide_init_port_data(hwif, index);
+ ide_init_port_data(hwif, hwif->index);
abort:
spin_unlock_irq(&ide_lock);
@@ -452,9 +368,8 @@ EXPORT_SYMBOL(ide_unregister);
void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
{
- memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
+ memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports));
hwif->irq = hw->irq;
- hwif->noprobe = 0;
hwif->chipset = hw->chipset;
hwif->gendev.parent = hw->dev;
hwif->ack_intr = hw->ack_intr;
@@ -545,7 +460,7 @@ int set_using_dma(ide_drive_t *drive, int arg)
if (!drive->id || !(drive->id->capability & 1))
goto out;
- if (hwif->dma_host_set == NULL)
+ if (hwif->dma_ops == NULL)
goto out;
err = -EBUSY;
@@ -585,11 +500,12 @@ int set_pio_mode(ide_drive_t *drive, int arg)
{
struct request rq;
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
if (arg < 0 || arg > 255)
return -EINVAL;
- if (hwif->set_pio_mode == NULL ||
+ if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
(hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
return -ENOSYS;
@@ -648,7 +564,7 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
if (!(drive->dn % 2))
ide_acpi_get_timing(hwif);
- memset(&rq, 0, sizeof(rq));
+ blk_rq_init(NULL, &rq);
memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args));
rq.cmd_type = REQ_TYPE_PM_SUSPEND;
@@ -686,7 +602,7 @@ static int generic_ide_resume(struct device *dev)
ide_acpi_exec_tfs(drive);
- memset(&rq, 0, sizeof(rq));
+ blk_rq_init(NULL, &rq);
memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args));
rq.cmd_type = REQ_TYPE_PM_RESUME;
@@ -912,16 +828,6 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m
return 0; /* zero = nothing matched */
}
-extern int probe_ali14xx;
-extern int probe_umc8672;
-extern int probe_dtc2278;
-extern int probe_ht6560b;
-extern int probe_qd65xx;
-extern int cmd640_vlb;
-extern int probe_4drives;
-
-static int __initdata is_chipset_set;
-
/*
* ide_setup() gets called VERY EARLY during initialization,
* to handle kernel "command line" strings beginning with "hdx=" or "ide".
@@ -930,14 +836,12 @@ static int __initdata is_chipset_set;
*/
static int __init ide_setup(char *s)
{
- int i, vals[3];
ide_hwif_t *hwif;
ide_drive_t *drive;
unsigned int hw, unit;
+ int vals[3];
const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
- const char max_hwif = '0' + (MAX_HWIFS - 1);
-
if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */
return 0; /* driver and not us */
@@ -953,7 +857,7 @@ static int __init ide_setup(char *s)
printk(" : Enabled support for IDE doublers\n");
ide_doubler = 1;
- return 1;
+ goto obsolete_option;
}
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
@@ -967,17 +871,17 @@ static int __init ide_setup(char *s)
if (!strcmp(s, "ide=noacpi")) {
//printk(" : Disable IDE ACPI support.\n");
ide_noacpi = 1;
- return 1;
+ goto obsolete_option;
}
if (!strcmp(s, "ide=acpigtf")) {
//printk(" : Enable IDE ACPI _GTF support.\n");
- ide_noacpitfs = 0;
- return 1;
+ ide_acpigtf = 1;
+ goto obsolete_option;
}
if (!strcmp(s, "ide=acpionboot")) {
//printk(" : Call IDE ACPI methods on boot.\n");
- ide_noacpionboot = 0;
- return 1;
+ ide_acpionboot = 1;
+ goto obsolete_option;
}
#endif /* CONFIG_BLK_DEV_IDEACPI */
@@ -987,7 +891,7 @@ static int __init ide_setup(char *s)
if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
const char *hd_words[] = {
"none", "noprobe", "nowerr", "cdrom", "nodma",
- "autotune", "noautotune", "-8", "-9", "-10",
+ "-6", "-7", "-8", "-9", "-10",
"noflush", "remap", "remap63", "scsi", NULL };
unit = s[2] - 'a';
hw = unit / MAX_DRIVES;
@@ -1002,30 +906,22 @@ static int __init ide_setup(char *s)
case -1: /* "none" */
case -2: /* "noprobe" */
drive->noprobe = 1;
- goto done;
+ goto obsolete_option;
case -3: /* "nowerr" */
drive->bad_wstat = BAD_R_STAT;
- hwif->noprobe = 0;
- goto done;
+ goto obsolete_option;
case -4: /* "cdrom" */
drive->present = 1;
drive->media = ide_cdrom;
/* an ATAPI device ignores DRDY */
drive->ready_stat = 0;
- hwif->noprobe = 0;
- goto done;
+ goto obsolete_option;
case -5: /* nodma */
drive->nodma = 1;
- goto done;
- case -6: /* "autotune" */
- drive->autotune = IDE_TUNE_AUTO;
- goto obsolete_option;
- case -7: /* "noautotune" */
- drive->autotune = IDE_TUNE_NOAUTO;
goto obsolete_option;
case -11: /* noflush */
drive->noflush = 1;
- goto done;
+ goto obsolete_option;
case -12: /* "remap" */
drive->remap_0_to_1 = 1;
goto obsolete_option;
@@ -1043,8 +939,7 @@ static int __init ide_setup(char *s)
drive->sect = drive->bios_sect = vals[2];
drive->present = 1;
drive->forced_geom = 1;
- hwif->noprobe = 0;
- goto done;
+ goto obsolete_option;
default:
goto bad_option;
}
@@ -1062,126 +957,15 @@ static int __init ide_setup(char *s)
idebus_parameter = vals[0];
} else
printk(" -- BAD BUS SPEED! Expected value from 20 to 66");
- goto done;
+ goto obsolete_option;
}
- /*
- * Look for interface options: "idex="
- */
- if (s[3] >= '0' && s[3] <= max_hwif) {
- /*
- * Be VERY CAREFUL changing this: note hardcoded indexes below
- * (-8, -9, -10) are reserved to ease the hardcoding.
- */
- static const char *ide_words[] = {
- "minus1", "serialize", "minus3", "minus4",
- "reset", "minus6", "ata66", "minus8", "minus9",
- "minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb",
- "dtc2278", "umc8672", "ali14xx", NULL };
-
- hw = s[3] - '0';
- hwif = &ide_hwifs[hw];
- i = match_parm(&s[4], ide_words, vals, 3);
-
- /*
- * Cryptic check to ensure chipset not already set for hwif.
- * Note: we can't depend on hwif->chipset here.
- */
- if (i >= -18 && i <= -11) {
- /* chipset already specified */
- if (is_chipset_set)
- goto bad_option;
- /* these drivers are for "ide0=" only */
- if (hw != 0)
- goto bad_hwif;
- is_chipset_set = 1;
- printk("\n");
- }
-
- switch (i) {
-#ifdef CONFIG_BLK_DEV_ALI14XX
- case -17: /* "ali14xx" */
- probe_ali14xx = 1;
- goto obsolete_option;
-#endif
-#ifdef CONFIG_BLK_DEV_UMC8672
- case -16: /* "umc8672" */
- probe_umc8672 = 1;
- goto obsolete_option;
-#endif
-#ifdef CONFIG_BLK_DEV_DTC2278
- case -15: /* "dtc2278" */
- probe_dtc2278 = 1;
- goto obsolete_option;
-#endif
-#ifdef CONFIG_BLK_DEV_CMD640
- case -14: /* "cmd640_vlb" */
- cmd640_vlb = 1;
- goto obsolete_option;
-#endif
-#ifdef CONFIG_BLK_DEV_HT6560B
- case -13: /* "ht6560b" */
- probe_ht6560b = 1;
- goto obsolete_option;
-#endif
-#ifdef CONFIG_BLK_DEV_QD65XX
- case -12: /* "qd65xx" */
- probe_qd65xx = 1;
- goto obsolete_option;
-#endif
-#ifdef CONFIG_BLK_DEV_4DRIVES
- case -11: /* "four" drives on one set of ports */
- probe_4drives = 1;
- goto obsolete_option;
-#endif
- case -10: /* minus10 */
- case -9: /* minus9 */
- case -8: /* minus8 */
- case -6:
- case -4:
- case -3:
- goto bad_option;
- case -7: /* ata66 */
-#ifdef CONFIG_BLK_DEV_IDEPCI
- /*
- * Use ATA_CBL_PATA40_SHORT so drive side
- * cable detection is also overriden.
- */
- hwif->cbl = ATA_CBL_PATA40_SHORT;
- goto obsolete_option;
-#else
- goto bad_hwif;
-#endif
- case -5: /* "reset" */
- hwif->reset = 1;
- goto obsolete_option;
- case -2: /* "serialize" */
- hwif->mate = &ide_hwifs[hw^1];
- hwif->mate->mate = hwif;
- hwif->serialized = hwif->mate->serialized = 1;
- goto obsolete_option;
- case -1:
- case 0:
- case 1:
- case 2:
- case 3:
- goto bad_option;
- default:
- printk(" -- SUPPORT NOT CONFIGURED IN THIS KERNEL\n");
- return 1;
- }
- }
bad_option:
printk(" -- BAD OPTION\n");
return 1;
obsolete_option:
printk(" -- OBSOLETE OPTION, WILL BE REMOVED SOON!\n");
return 1;
-bad_hwif:
- printk("-- NOT SUPPORTED ON ide%d", hw);
-done:
- printk("\n");
- return 1;
}
EXPORT_SYMBOL(ide_lock);
@@ -1317,6 +1101,185 @@ static void ide_port_class_release(struct device *portdev)
put_device(&hwif->gendev);
}
+int ide_vlb_clk;
+EXPORT_SYMBOL_GPL(ide_vlb_clk);
+
+module_param_named(vlb_clock, ide_vlb_clk, int, 0);
+MODULE_PARM_DESC(vlb_clock, "VLB clock frequency (in MHz)");
+
+int ide_pci_clk;
+EXPORT_SYMBOL_GPL(ide_pci_clk);
+
+module_param_named(pci_clock, ide_pci_clk, int, 0);
+MODULE_PARM_DESC(pci_clock, "PCI bus clock frequency (in MHz)");
+
+static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp)
+{
+ int a, b, i, j = 1;
+ unsigned int *dev_param_mask = (unsigned int *)kp->arg;
+
+ if (sscanf(s, "%d.%d:%d", &a, &b, &j) != 3 &&
+ sscanf(s, "%d.%d", &a, &b) != 2)
+ return -EINVAL;
+
+ i = a * MAX_DRIVES + b;
+
+ if (i >= MAX_HWIFS * MAX_DRIVES || j < 0 || j > 1)
+ return -EINVAL;
+
+ if (j)
+ *dev_param_mask |= (1 << i);
+ else
+ *dev_param_mask &= (1 << i);
+
+ return 0;
+}
+
+static unsigned int ide_nodma;
+
+module_param_call(nodma, ide_set_dev_param_mask, NULL, &ide_nodma, 0);
+MODULE_PARM_DESC(nodma, "disallow DMA for a device");
+
+static unsigned int ide_noflush;
+
+module_param_call(noflush, ide_set_dev_param_mask, NULL, &ide_noflush, 0);
+MODULE_PARM_DESC(noflush, "disable flush requests for a device");
+
+static unsigned int ide_noprobe;
+
+module_param_call(noprobe, ide_set_dev_param_mask, NULL, &ide_noprobe, 0);
+MODULE_PARM_DESC(noprobe, "skip probing for a device");
+
+static unsigned int ide_nowerr;
+
+module_param_call(nowerr, ide_set_dev_param_mask, NULL, &ide_nowerr, 0);
+MODULE_PARM_DESC(nowerr, "ignore the WRERR_STAT bit for a device");
+
+static unsigned int ide_cdroms;
+
+module_param_call(cdrom, ide_set_dev_param_mask, NULL, &ide_cdroms, 0);
+MODULE_PARM_DESC(cdrom, "force device as a CD-ROM");
+
+struct chs_geom {
+ unsigned int cyl;
+ u8 head;
+ u8 sect;
+};
+
+static unsigned int ide_disks;
+static struct chs_geom ide_disks_chs[MAX_HWIFS * MAX_DRIVES];
+
+static int ide_set_disk_chs(const char *str, struct kernel_param *kp)
+{
+ int a, b, c = 0, h = 0, s = 0, i, j = 1;
+
+ if (sscanf(str, "%d.%d:%d,%d,%d", &a, &b, &c, &h, &s) != 5 &&
+ sscanf(str, "%d.%d:%d", &a, &b, &j) != 3)
+ return -EINVAL;
+
+ i = a * MAX_DRIVES + b;
+
+ if (i >= MAX_HWIFS * MAX_DRIVES || j < 0 || j > 1)
+ return -EINVAL;
+
+ if (c > INT_MAX || h > 255 || s > 255)
+ return -EINVAL;
+
+ if (j)
+ ide_disks |= (1 << i);
+ else
+ ide_disks &= (1 << i);
+
+ ide_disks_chs[i].cyl = c;
+ ide_disks_chs[i].head = h;
+ ide_disks_chs[i].sect = s;
+
+ return 0;
+}
+
+module_param_call(chs, ide_set_disk_chs, NULL, NULL, 0);
+MODULE_PARM_DESC(chs, "force device as a disk (using CHS)");
+
+static void ide_dev_apply_params(ide_drive_t *drive)
+{
+ int i = drive->hwif->index * MAX_DRIVES + drive->select.b.unit;
+
+ if (ide_nodma & (1 << i)) {
+ printk(KERN_INFO "ide: disallowing DMA for %s\n", drive->name);
+ drive->nodma = 1;
+ }
+ if (ide_noflush & (1 << i)) {
+ printk(KERN_INFO "ide: disabling flush requests for %s\n",
+ drive->name);
+ drive->noflush = 1;
+ }
+ if (ide_noprobe & (1 << i)) {
+ printk(KERN_INFO "ide: skipping probe for %s\n", drive->name);
+ drive->noprobe = 1;
+ }
+ if (ide_nowerr & (1 << i)) {
+ printk(KERN_INFO "ide: ignoring the WRERR_STAT bit for %s\n",
+ drive->name);
+ drive->bad_wstat = BAD_R_STAT;
+ }
+ if (ide_cdroms & (1 << i)) {
+ printk(KERN_INFO "ide: forcing %s as a CD-ROM\n", drive->name);
+ drive->present = 1;
+ drive->media = ide_cdrom;
+ /* an ATAPI device ignores DRDY */
+ drive->ready_stat = 0;
+ }
+ if (ide_disks & (1 << i)) {
+ drive->cyl = drive->bios_cyl = ide_disks_chs[i].cyl;
+ drive->head = drive->bios_head = ide_disks_chs[i].head;
+ drive->sect = drive->bios_sect = ide_disks_chs[i].sect;
+ drive->forced_geom = 1;
+ printk(KERN_INFO "ide: forcing %s as a disk (%d/%d/%d)\n",
+ drive->name,
+ drive->cyl, drive->head, drive->sect);
+ drive->present = 1;
+ drive->media = ide_disk;
+ drive->ready_stat = READY_STAT;
+ }
+}
+
+static unsigned int ide_ignore_cable;
+
+static int ide_set_ignore_cable(const char *s, struct kernel_param *kp)
+{
+ int i, j = 1;
+
+ if (sscanf(s, "%d:%d", &i, &j) != 2 && sscanf(s, "%d", &i) != 1)
+ return -EINVAL;
+
+ if (i >= MAX_HWIFS || j < 0 || j > 1)
+ return -EINVAL;
+
+ if (j)
+ ide_ignore_cable |= (1 << i);
+ else
+ ide_ignore_cable &= (1 << i);
+
+ return 0;
+}
+
+module_param_call(ignore_cable, ide_set_ignore_cable, NULL, NULL, 0);
+MODULE_PARM_DESC(ignore_cable, "ignore cable detection");
+
+void ide_port_apply_params(ide_hwif_t *hwif)
+{
+ int i;
+
+ if (ide_ignore_cable & (1 << hwif->index)) {
+ printk(KERN_INFO "ide: ignoring cable detection for %s\n",
+ hwif->name);
+ hwif->cbl = ATA_CBL_PATA40_SHORT;
+ }
+
+ for (i = 0; i < MAX_DRIVES; i++)
+ ide_dev_apply_params(&hwif->drives[i]);
+}
+
/*
* This is gets invoked once during initialization, to set *everything* up
*/
@@ -1383,11 +1346,6 @@ int __init init_module (void)
void __exit cleanup_module (void)
{
- int index;
-
- for (index = 0; index < MAX_HWIFS; ++index)
- ide_unregister(index);
-
proc_ide_destroy();
class_destroy(ide_port_class);
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c
index 33bb7b87be5..90c65cf9744 100644
--- a/drivers/ide/legacy/ali14xx.c
+++ b/drivers/ide/legacy/ali14xx.c
@@ -49,6 +49,8 @@
#include <asm/io.h>
+#define DRV_NAME "ali14xx"
+
/* port addresses for auto-detection */
#define ALI_NUM_PORTS 4
static const int ports[ALI_NUM_PORTS] __initdata =
@@ -114,7 +116,7 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
int time1, time2;
u8 param1, param2, param3, param4;
unsigned long flags;
- int bus_speed = system_bus_clock();
+ int bus_speed = ide_vlb_clk ? ide_vlb_clk : system_bus_clock();
/* calculate timing, according to PIO mode */
time1 = ide_pio_cycle_time(drive, pio);
@@ -192,18 +194,20 @@ static int __init initRegisters(void)
return t;
}
+static const struct ide_port_ops ali14xx_port_ops = {
+ .set_pio_mode = ali14xx_set_pio_mode,
+};
+
static const struct ide_port_info ali14xx_port_info = {
+ .name = DRV_NAME,
.chipset = ide_ali14xx,
- .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_NO_AUTOTUNE,
+ .port_ops = &ali14xx_port_ops,
+ .host_flags = IDE_HFLAG_NO_DMA,
.pio_mask = ATA_PIO4,
};
static int __init ali14xx_probe(void)
{
- ide_hwif_t *hwif, *mate;
- static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
- hw_regs_t hw[2];
-
printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n",
basePort, regOn);
@@ -213,34 +217,10 @@ static int __init ali14xx_probe(void)
return 1;
}
- memset(&hw, 0, sizeof(hw));
-
- ide_std_init_ports(&hw[0], 0x1f0, 0x3f6);
- hw[0].irq = 14;
-
- ide_std_init_ports(&hw[1], 0x170, 0x376);
- hw[1].irq = 15;
-
- hwif = ide_find_port();
- if (hwif) {
- ide_init_port_hw(hwif, &hw[0]);
- hwif->set_pio_mode = &ali14xx_set_pio_mode;
- idx[0] = hwif->index;
- }
-
- mate = ide_find_port();
- if (mate) {
- ide_init_port_hw(mate, &hw[1]);
- mate->set_pio_mode = &ali14xx_set_pio_mode;
- idx[1] = mate->index;
- }
-
- ide_device_add(idx, &ali14xx_port_info);
-
- return 0;
+ return ide_legacy_device_add(&ali14xx_port_info, 0);
}
-int probe_ali14xx;
+static int probe_ali14xx;
module_param_named(probe, probe_ali14xx, bool, 0);
MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets");
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c
index 6956eb8f2d5..5c730e4dd73 100644
--- a/drivers/ide/legacy/buddha.c
+++ b/drivers/ide/legacy/buddha.c
@@ -102,7 +102,7 @@ static int buddha_ack_intr(ide_hwif_t *hwif)
{
unsigned char ch;
- ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
+ ch = z_readb(hwif->io_ports.irq_addr);
if (!(ch & 0x80))
return 0;
return 1;
@@ -112,9 +112,9 @@ static int xsurf_ack_intr(ide_hwif_t *hwif)
{
unsigned char ch;
- ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
+ ch = z_readb(hwif->io_ports.irq_addr);
/* X-Surf needs a 0 written to IRQ register to ensure ISA bit A11 stays at 0 */
- z_writeb(0, hwif->io_ports[IDE_IRQ_OFFSET]);
+ z_writeb(0, hwif->io_ports.irq_addr);
if (!(ch & 0x80))
return 0;
return 1;
@@ -128,13 +128,13 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base,
memset(hw, 0, sizeof(*hw));
- hw->io_ports[IDE_DATA_OFFSET] = base;
+ hw->io_ports.data_addr = base;
for (i = 1; i < 8; i++)
- hw->io_ports[i] = base + 2 + i * 4;
+ hw->io_ports_array[i] = base + 2 + i * 4;
- hw->io_ports[IDE_CONTROL_OFFSET] = ctl;
- hw->io_ports[IDE_IRQ_OFFSET] = irq_port;
+ hw->io_ports.ctl_addr = ctl;
+ hw->io_ports.irq_addr = irq_port;
hw->irq = IRQ_AMIGA_PORTS;
hw->ack_intr = ack_intr;
@@ -228,8 +228,6 @@ fail_base2:
ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
- hwif->mmio = 1;
-
idx[i] = index;
}
}
diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c
index 9c6b3249a00..af791a02a12 100644
--- a/drivers/ide/legacy/dtc2278.c
+++ b/drivers/ide/legacy/dtc2278.c
@@ -16,6 +16,8 @@
#include <asm/io.h>
+#define DRV_NAME "dtc2278"
+
/*
* Changing this #undef to #define may solve start up problems in some systems.
*/
@@ -86,24 +88,26 @@ static void dtc2278_set_pio_mode(ide_drive_t *drive, const u8 pio)
}
}
+static const struct ide_port_ops dtc2278_port_ops = {
+ .set_pio_mode = dtc2278_set_pio_mode,
+};
+
static const struct ide_port_info dtc2278_port_info __initdata = {
+ .name = DRV_NAME,
.chipset = ide_dtc2278,
+ .port_ops = &dtc2278_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE |
IDE_HFLAG_NO_UNMASK_IRQS |
IDE_HFLAG_IO_32BIT |
/* disallow ->io_32bit changes */
IDE_HFLAG_NO_IO_32BIT |
- IDE_HFLAG_NO_DMA |
- IDE_HFLAG_NO_AUTOTUNE,
+ IDE_HFLAG_NO_DMA,
.pio_mask = ATA_PIO4,
};
static int __init dtc2278_probe(void)
{
unsigned long flags;
- ide_hwif_t *hwif, *mate;
- static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
- hw_regs_t hw[2];
local_irq_save(flags);
/*
@@ -123,33 +127,10 @@ static int __init dtc2278_probe(void)
#endif
local_irq_restore(flags);
- memset(&hw, 0, sizeof(hw));
-
- ide_std_init_ports(&hw[0], 0x1f0, 0x3f6);
- hw[0].irq = 14;
-
- ide_std_init_ports(&hw[1], 0x170, 0x376);
- hw[1].irq = 15;
-
- hwif = ide_find_port();
- if (hwif) {
- ide_init_port_hw(hwif, &hw[0]);
- hwif->set_pio_mode = dtc2278_set_pio_mode;
- idx[0] = hwif->index;
- }
-
- mate = ide_find_port();
- if (mate) {
- ide_init_port_hw(mate, &hw[1]);
- idx[1] = mate->index;
- }
-
- ide_device_add(idx, &dtc2278_port_info);
-
- return 0;
+ return ide_legacy_device_add(&dtc2278_port_info, 0);
}
-int probe_dtc2278 = 0;
+static int probe_dtc2278;
module_param_named(probe, probe_dtc2278, bool, 0);
MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets");
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c
index 8c9c9f7f54c..83555ca513b 100644
--- a/drivers/ide/legacy/falconide.c
+++ b/drivers/ide/legacy/falconide.c
@@ -44,18 +44,40 @@
int falconide_intr_lock;
EXPORT_SYMBOL(falconide_intr_lock);
+static void falconide_input_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
+{
+ unsigned long data_addr = drive->hwif->io_ports.data_addr;
+
+ if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ return insw(data_addr, buf, (len + 1) / 2);
+
+ insw_swapw(data_addr, buf, (len + 1) / 2);
+}
+
+static void falconide_output_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
+{
+ unsigned long data_addr = drive->hwif->io_ports.data_addr;
+
+ if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ return outsw(data_adr, buf, (len + 1) / 2);
+
+ outsw_swapw(data_addr, buf, (len + 1) / 2);
+}
+
static void __init falconide_setup_ports(hw_regs_t *hw)
{
int i;
memset(hw, 0, sizeof(*hw));
- hw->io_ports[IDE_DATA_OFFSET] = ATA_HD_BASE;
+ hw->io_ports.data_addr = ATA_HD_BASE;
for (i = 1; i < 8; i++)
- hw->io_ports[i] = ATA_HD_BASE + 1 + i * 4;
+ hw->io_ports_array[i] = ATA_HD_BASE + 1 + i * 4;
- hw->io_ports[IDE_CONTROL_OFFSET] = ATA_HD_BASE + ATA_HD_CONTROL;
+ hw->io_ports.ctl_addr = ATA_HD_BASE + ATA_HD_CONTROL;
hw->irq = IRQ_MFP_IDE;
hw->ack_intr = NULL;
@@ -89,7 +111,10 @@ static int __init falconide_init(void)
ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
- hwif->mmio = 1;
+
+ /* Atari has a byte-swapped IDE interface */
+ hwif->input_data = falconide_input_data;
+ hwif->output_data = falconide_output_data;
ide_get_lock(NULL, NULL);
ide_device_add(idx, NULL);
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
index fcc8d52bf2a..a9c2593a898 100644
--- a/drivers/ide/legacy/gayle.c
+++ b/drivers/ide/legacy/gayle.c
@@ -63,6 +63,8 @@
#define GAYLE_HAS_CONTROL_REG (!ide_doubler)
#define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000)
int ide_doubler = 0; /* support IDE doublers? */
+module_param_named(doubler, ide_doubler, bool, 0);
+MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
@@ -74,7 +76,7 @@ static int gayle_ack_intr_a4000(ide_hwif_t *hwif)
{
unsigned char ch;
- ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
+ ch = z_readb(hwif->io_ports.irq_addr);
if (!(ch & GAYLE_IRQ_IDE))
return 0;
return 1;
@@ -84,11 +86,11 @@ static int gayle_ack_intr_a1200(ide_hwif_t *hwif)
{
unsigned char ch;
- ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
+ ch = z_readb(hwif->io_ports.irq_addr);
if (!(ch & GAYLE_IRQ_IDE))
return 0;
- (void)z_readb(hwif->io_ports[IDE_STATUS_OFFSET]);
- z_writeb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]);
+ (void)z_readb(hwif->io_ports.status_addr);
+ z_writeb(0x7c, hwif->io_ports.irq_addr);
return 1;
}
@@ -100,13 +102,13 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base,
memset(hw, 0, sizeof(*hw));
- hw->io_ports[IDE_DATA_OFFSET] = base;
+ hw->io_ports.data_addr = base;
for (i = 1; i < 8; i++)
- hw->io_ports[i] = base + 2 + i * 4;
+ hw->io_ports_array[i] = base + 2 + i * 4;
- hw->io_ports[IDE_CONTROL_OFFSET] = ctl;
- hw->io_ports[IDE_IRQ_OFFSET] = irq_port;
+ hw->io_ports.ctl_addr = ctl;
+ hw->io_ports.irq_addr = irq_port;
hw->irq = IRQ_AMIGA_PORTS;
hw->ack_intr = ack_intr;
@@ -182,8 +184,6 @@ found:
ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
- hwif->mmio = 1;
-
idx[i] = index;
} else
release_mem_region(res_start, res_n);
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
index 60f52f5158c..4fe516df9f7 100644
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -157,8 +157,8 @@ static void ht6560b_selectproc (ide_drive_t *drive)
/*
* Set timing for this drive:
*/
- outb(timing, hwif->io_ports[IDE_SELECT_OFFSET]);
- (void)inb(hwif->io_ports[IDE_STATUS_OFFSET]);
+ outb(timing, hwif->io_ports.device_addr);
+ (void)inb(hwif->io_ports.status_addr);
#ifdef DEBUG
printk("ht6560b: %s: select=%#x timing=%#x\n",
drive->name, select, timing);
@@ -212,8 +212,8 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
{
int active_time, recovery_time;
int active_cycles, recovery_cycles;
- int bus_speed = system_bus_clock();
-
+ int bus_speed = ide_vlb_clk ? ide_vlb_clk : system_bus_clock();
+
if (pio) {
unsigned int cycle_time;
@@ -323,69 +323,44 @@ static void __init ht6560b_port_init_devs(ide_hwif_t *hwif)
hwif->drives[1].drive_data = t;
}
-int probe_ht6560b = 0;
+static int probe_ht6560b;
module_param_named(probe, probe_ht6560b, bool, 0);
MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
+static const struct ide_port_ops ht6560b_port_ops = {
+ .port_init_devs = ht6560b_port_init_devs,
+ .set_pio_mode = ht6560b_set_pio_mode,
+ .selectproc = ht6560b_selectproc,
+};
+
static const struct ide_port_info ht6560b_port_info __initdata = {
+ .name = DRV_NAME,
.chipset = ide_ht6560b,
+ .port_ops = &ht6560b_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE | /* is this needed? */
IDE_HFLAG_NO_DMA |
- IDE_HFLAG_NO_AUTOTUNE |
IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO4,
};
static int __init ht6560b_init(void)
{
- ide_hwif_t *hwif, *mate;
- static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
- hw_regs_t hw[2];
-
if (probe_ht6560b == 0)
return -ENODEV;
if (!request_region(HT_CONFIG_PORT, 1, DRV_NAME)) {
printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n",
- __FUNCTION__);
+ __func__);
return -ENODEV;
}
if (!try_to_init_ht6560b()) {
- printk(KERN_NOTICE "%s: HBA not found\n", __FUNCTION__);
+ printk(KERN_NOTICE "%s: HBA not found\n", __func__);
goto release_region;
}
- memset(&hw, 0, sizeof(hw));
-
- ide_std_init_ports(&hw[0], 0x1f0, 0x3f6);
- hw[0].irq = 14;
-
- ide_std_init_ports(&hw[1], 0x170, 0x376);
- hw[1].irq = 15;
-
- hwif = ide_find_port();
- if (hwif) {
- ide_init_port_hw(hwif, &hw[0]);
- hwif->selectproc = ht6560b_selectproc;
- hwif->set_pio_mode = ht6560b_set_pio_mode;
- hwif->port_init_devs = ht6560b_port_init_devs;
- idx[0] = hwif->index;
- }
-
- mate = ide_find_port();
- if (mate) {
- ide_init_port_hw(mate, &hw[1]);
- mate->selectproc = ht6560b_selectproc;
- mate->set_pio_mode = ht6560b_set_pio_mode;
- mate->port_init_devs = ht6560b_port_init_devs;
- idx[1] = mate->index;
- }
-
- ide_device_add(idx, &ht6560b_port_info);
-
- return 0;
+ return ide_legacy_device_add(&ht6560b_port_info, 0);
release_region:
release_region(HT_CONFIG_PORT, 1);
diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c
index c352f12348a..ecae916a338 100644
--- a/drivers/ide/legacy/ide-4drives.c
+++ b/drivers/ide/legacy/ide-4drives.c
@@ -4,7 +4,9 @@
#include <linux/module.h>
#include <linux/ide.h>
-int probe_4drives;
+#define DRV_NAME "ide-4drives"
+
+static int probe_4drives;
module_param_named(probe, probe_4drives, bool, 0);
MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port");
@@ -12,15 +14,29 @@ MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port");
static int __init ide_4drives_init(void)
{
ide_hwif_t *hwif, *mate;
+ unsigned long base = 0x1f0, ctl = 0x3f6;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
hw_regs_t hw;
if (probe_4drives == 0)
return -ENODEV;
+ if (!request_region(base, 8, DRV_NAME)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
+ DRV_NAME, base, base + 7);
+ return -EBUSY;
+ }
+
+ if (!request_region(ctl, 1, DRV_NAME)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
+ DRV_NAME, ctl);
+ release_region(base, 8);
+ return -EBUSY;
+ }
+
memset(&hw, 0, sizeof(hw));
- ide_std_init_ports(&hw, 0x1f0, 0x3f6);
+ ide_std_init_ports(&hw, base, ctl);
hw.irq = 14;
hw.chipset = ide_4drives;
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index b97b8d51b3e..aa2ea3deac8 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -51,6 +51,8 @@
#include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h>
+#define DRV_NAME "ide-cs"
+
/*====================================================================*/
/* Module parameters */
@@ -72,16 +74,11 @@ static char *version =
/*====================================================================*/
-static const char ide_major[] = {
- IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR,
- IDE4_MAJOR, IDE5_MAJOR
-};
-
typedef struct ide_info_t {
struct pcmcia_device *p_dev;
+ ide_hwif_t *hwif;
int ndev;
dev_node_t node;
- int hd;
} ide_info_t;
static void ide_release(struct pcmcia_device *);
@@ -136,20 +133,44 @@ static int ide_probe(struct pcmcia_device *link)
static void ide_detach(struct pcmcia_device *link)
{
+ ide_info_t *info = link->priv;
+ ide_hwif_t *hwif = info->hwif;
+
DEBUG(0, "ide_detach(0x%p)\n", link);
ide_release(link);
- kfree(link->priv);
+ release_region(hwif->io_ports.ctl_addr, 1);
+ release_region(hwif->io_ports.data_addr, 8);
+
+ kfree(info);
} /* ide_detach */
-static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
+static const struct ide_port_ops idecs_port_ops = {
+ .quirkproc = ide_undecoded_slave,
+};
+
+static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl,
+ unsigned long irq, struct pcmcia_device *handle)
{
ide_hwif_t *hwif;
hw_regs_t hw;
int i;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+ if (!request_region(io, 8, DRV_NAME)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
+ DRV_NAME, io, io + 7);
+ return NULL;
+ }
+
+ if (!request_region(ctl, 1, DRV_NAME)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
+ DRV_NAME, ctl);
+ release_region(io, 8);
+ return NULL;
+ }
+
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, io, ctl);
hw.irq = irq;
@@ -158,23 +179,25 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq
hwif = ide_find_port();
if (hwif == NULL)
- return -1;
+ goto out_release;
i = hwif->index;
- if (hwif->present)
- ide_unregister(i);
- else
- ide_init_port_data(hwif, i);
-
+ ide_init_port_data(hwif, i);
ide_init_port_hw(hwif, &hw);
- hwif->quirkproc = &ide_undecoded_slave;
+ hwif->port_ops = &idecs_port_ops;
idx[0] = i;
ide_device_add(idx, NULL);
- return hwif->present ? i : -1;
+ if (hwif->present)
+ return hwif;
+
+out_release:
+ release_region(ctl, 1);
+ release_region(io, 8);
+ return NULL;
}
/*======================================================================
@@ -199,8 +222,9 @@ static int ide_config(struct pcmcia_device *link)
cistpl_cftable_entry_t dflt;
} *stk = NULL;
cistpl_cftable_entry_t *cfg;
- int i, pass, last_ret = 0, last_fn = 0, hd, is_kme = 0;
+ int i, pass, last_ret = 0, last_fn = 0, is_kme = 0;
unsigned long io_base, ctl_base;
+ ide_hwif_t *hwif;
DEBUG(0, "ide_config(0x%p)\n", link);
@@ -296,14 +320,15 @@ static int ide_config(struct pcmcia_device *link)
outb(0x81, ctl_base+1);
/* retry registration in case device is still spinning up */
- for (hd = -1, i = 0; i < 10; i++) {
- hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link);
- if (hd >= 0) break;
+ for (i = 0; i < 10; i++) {
+ hwif = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link);
+ if (hwif)
+ break;
if (link->io.NumPorts1 == 0x20) {
outb(0x02, ctl_base + 0x10);
- hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
- link->irq.AssignedIRQ, link);
- if (hd >= 0) {
+ hwif = idecs_register(io_base + 0x10, ctl_base + 0x10,
+ link->irq.AssignedIRQ, link);
+ if (hwif) {
io_base += 0x10;
ctl_base += 0x10;
break;
@@ -312,7 +337,7 @@ static int ide_config(struct pcmcia_device *link)
msleep(100);
}
- if (hd < 0) {
+ if (hwif == NULL) {
printk(KERN_NOTICE "ide-cs: ide_register() at 0x%3lx & 0x%3lx"
", irq %u failed\n", io_base, ctl_base,
link->irq.AssignedIRQ);
@@ -320,10 +345,10 @@ static int ide_config(struct pcmcia_device *link)
}
info->ndev = 1;
- sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2));
- info->node.major = ide_major[hd];
+ sprintf(info->node.dev_name, "hd%c", 'a' + hwif->index * 2);
+ info->node.major = hwif->major;
info->node.minor = 0;
- info->hd = hd;
+ info->hwif = hwif;
link->dev_node = &info->node;
printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n",
info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10);
@@ -354,13 +379,14 @@ failed:
void ide_release(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
+ ide_hwif_t *hwif = info->hwif;
DEBUG(0, "ide_release(0x%p)\n", link);
if (info->ndev) {
/* FIXME: if this fails we need to queue the cleanup somehow
-- need to investigate the required PCMCIA magic */
- ide_unregister(info->hd);
+ ide_unregister(hwif);
}
info->ndev = 0;
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c
index bf240775531..d3bc3f24e05 100644
--- a/drivers/ide/legacy/ide_platform.c
+++ b/drivers/ide/legacy/ide_platform.c
@@ -30,14 +30,14 @@ static void __devinit plat_ide_setup_ports(hw_regs_t *hw,
unsigned long port = (unsigned long)base;
int i;
- hw->io_ports[IDE_DATA_OFFSET] = port;
+ hw->io_ports.data_addr = port;
port += (1 << pdata->ioport_shift);
- for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET;
+ for (i = 1; i <= 7;
i++, port += (1 << pdata->ioport_shift))
- hw->io_ports[i] = port;
+ hw->io_ports_array[i] = port;
- hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
+ hw->io_ports.ctl_addr = (unsigned long)ctrl;
hw->irq = irq;
@@ -100,10 +100,11 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
hw.dev = &pdev->dev;
ide_init_port_hw(hwif, &hw);
- hwif->mmio = 1;
- if (mmio)
+ if (mmio) {
+ hwif->host_flags = IDE_HFLAG_MMIO;
default_hwif_mmiops(hwif);
+ }
idx[0] = hwif->index;
@@ -121,7 +122,7 @@ static int __devexit plat_ide_remove(struct platform_device *pdev)
{
ide_hwif_t *hwif = pdev->dev.driver_data;
- ide_unregister(hwif->index);
+ ide_unregister(hwif);
return 0;
}
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index 7429b80cb08..1f527bbf8d9 100644
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -72,9 +72,9 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base,
memset(hw, 0, sizeof(*hw));
for (i = 0; i < 8; i++)
- hw->io_ports[i] = base + i * 4;
+ hw->io_ports_array[i] = base + i * 4;
- hw->io_ports[IDE_CONTROL_OFFSET] = base + IDE_CONTROL;
+ hw->io_ports.ctl_addr = base + IDE_CONTROL;
hw->irq = irq;
hw->ack_intr = ack_intr;
@@ -128,8 +128,6 @@ static int __init macide_init(void)
ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
- hwif->mmio = 1;
-
ide_device_add(idx, NULL);
}
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
index fcbff0eced1..6f535d00e63 100644
--- a/drivers/ide/legacy/q40ide.c
+++ b/drivers/ide/legacy/q40ide.c
@@ -36,23 +36,6 @@ static const unsigned long pcide_bases[Q40IDE_NUM_HWIFS] = {
PCIDE_BASE6 */
};
-
- /*
- * Offsets from one of the above bases
- */
-
-/* used to do addr translation here but it is easier to do in setup ports */
-/*#define IDE_OFF_B(x) ((unsigned long)Q40_ISA_IO_B((IDE_##x##_OFFSET)))*/
-
-#define IDE_OFF_B(x) ((unsigned long)((IDE_##x##_OFFSET)))
-#define IDE_OFF_W(x) ((unsigned long)((IDE_##x##_OFFSET)))
-
-static const int pcide_offsets[IDE_NR_PORTS] = {
- IDE_OFF_W(DATA), IDE_OFF_B(ERROR), IDE_OFF_B(NSECTOR), IDE_OFF_B(SECTOR),
- IDE_OFF_B(LCYL), IDE_OFF_B(HCYL), 6 /*IDE_OFF_B(CURRENT)*/, IDE_OFF_B(STATUS),
- 518/*IDE_OFF(CMD)*/
-};
-
static int q40ide_default_irq(unsigned long base)
{
switch (base) {
@@ -68,29 +51,48 @@ static int q40ide_default_irq(unsigned long base)
/*
* Addresses are pretranslated for Q40 ISA access.
*/
-void q40_ide_setup_ports ( hw_regs_t *hw,
- unsigned long base, int *offsets,
- unsigned long ctrl, unsigned long intr,
+static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base,
ide_ack_intr_t *ack_intr,
int irq)
{
- int i;
-
memset(hw, 0, sizeof(hw_regs_t));
- for (i = 0; i < IDE_NR_PORTS; i++) {
- /* BIG FAT WARNING:
- assumption: only DATA port is ever used in 16 bit mode */
- if ( i==0 )
- hw->io_ports[i] = Q40_ISA_IO_W(base + offsets[i]);
- else
- hw->io_ports[i] = Q40_ISA_IO_B(base + offsets[i]);
- }
+ /* BIG FAT WARNING:
+ assumption: only DATA port is ever used in 16 bit mode */
+ hw->io_ports.data_addr = Q40_ISA_IO_W(base);
+ hw->io_ports.error_addr = Q40_ISA_IO_B(base + 1);
+ hw->io_ports.nsect_addr = Q40_ISA_IO_B(base + 2);
+ hw->io_ports.lbal_addr = Q40_ISA_IO_B(base + 3);
+ hw->io_ports.lbam_addr = Q40_ISA_IO_B(base + 4);
+ hw->io_ports.lbah_addr = Q40_ISA_IO_B(base + 5);
+ hw->io_ports.device_addr = Q40_ISA_IO_B(base + 6);
+ hw->io_ports.status_addr = Q40_ISA_IO_B(base + 7);
+ hw->io_ports.ctl_addr = Q40_ISA_IO_B(base + 0x206);
hw->irq = irq;
hw->ack_intr = ack_intr;
}
+static void q40ide_input_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
+{
+ unsigned long data_addr = drive->hwif->io_ports.data_addr;
+
+ if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ return insw(data_addr, buf, (len + 1) / 2);
+ insw_swapw(data_addr, buf, (len + 1) / 2);
+}
+
+static void q40ide_output_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
+{
+ unsigned long data_addr = drive->hwif->io_ports.data_addr;
+
+ if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ return outsw(data_addr, buf, (len + 1) / 2);
+
+ outsw_swapw(data_addr, buf, (len + 1) / 2);
+}
/*
* the static array is needed to have the name reported in /proc/ioports,
@@ -131,9 +133,8 @@ static int __init q40ide_init(void)
release_region(pcide_bases[i], 8);
continue;
}
- q40_ide_setup_ports(&hw,(unsigned long) pcide_bases[i], (int *)pcide_offsets,
- pcide_bases[i]+0x206,
- 0, NULL,
+ q40_ide_setup_ports(&hw, pcide_bases[i],
+ NULL,
// m68kide_iops,
q40ide_default_irq(pcide_bases[i]));
@@ -141,7 +142,10 @@ static int __init q40ide_init(void)
if (hwif) {
ide_init_port_data(hwif, hwif->index);
ide_init_port_hw(hwif, &hw);
- hwif->mmio = 1;
+
+ /* Q40 has a byte-swapped IDE interface */
+ hwif->input_data = q40ide_input_data;
+ hwif->output_data = q40ide_output_data;
idx[i] = hwif->index;
}
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c
index 6e820c7c5c6..6424af15432 100644
--- a/drivers/ide/legacy/qd65xx.c
+++ b/drivers/ide/legacy/qd65xx.c
@@ -11,11 +11,7 @@
*
* QDI QD6500/QD6580 EIDE controller fast support
*
- * Please set local bus speed using kernel parameter idebus
- * for example, "idebus=33" stands for 33Mhz VLbus
* To activate controller support, use "ide0=qd65xx"
- * To enable tuning, use "hda=autotune hdb=autotune"
- * To enable 2nd channel tuning (qd6580 only), use "hdc=autotune hdd=autotune"
*/
/*
@@ -37,6 +33,8 @@
#include <asm/system.h>
#include <asm/io.h>
+#define DRV_NAME "qd65xx"
+
#include "qd65xx.h"
/*
@@ -112,17 +110,18 @@ static void qd65xx_select(ide_drive_t *drive)
static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time)
{
- u8 active_cycle,recovery_cycle;
+ int clk = ide_vlb_clk ? ide_vlb_clk : system_bus_clock();
+ u8 act_cyc, rec_cyc;
- if (system_bus_clock()<=33) {
- active_cycle = 9 - IDE_IN(active_time * system_bus_clock() / 1000 + 1, 2, 9);
- recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 0, 15);
+ if (clk <= 33) {
+ act_cyc = 9 - IDE_IN(active_time * clk / 1000 + 1, 2, 9);
+ rec_cyc = 15 - IDE_IN(recovery_time * clk / 1000 + 1, 0, 15);
} else {
- active_cycle = 8 - IDE_IN(active_time * system_bus_clock() / 1000 + 1, 1, 8);
- recovery_cycle = 18 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 3, 18);
+ act_cyc = 8 - IDE_IN(active_time * clk / 1000 + 1, 1, 8);
+ rec_cyc = 18 - IDE_IN(recovery_time * clk / 1000 + 1, 3, 18);
}
- return((recovery_cycle<<4) | 0x08 | active_cycle);
+ return (rec_cyc << 4) | 0x08 | act_cyc;
}
/*
@@ -133,10 +132,13 @@ static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery
static u8 qd6580_compute_timing (int active_time, int recovery_time)
{
- u8 active_cycle = 17 - IDE_IN(active_time * system_bus_clock() / 1000 + 1, 2, 17);
- u8 recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 2, 15);
+ int clk = ide_vlb_clk ? ide_vlb_clk : system_bus_clock();
+ u8 act_cyc, rec_cyc;
+
+ act_cyc = 17 - IDE_IN(active_time * clk / 1000 + 1, 2, 17);
+ rec_cyc = 15 - IDE_IN(recovery_time * clk / 1000 + 1, 2, 15);
- return((recovery_cycle<<4) | active_cycle);
+ return (rec_cyc << 4) | act_cyc;
}
/*
@@ -304,11 +306,23 @@ static void __init qd6580_port_init_devs(ide_hwif_t *hwif)
hwif->drives[1].drive_data = t2;
}
+static const struct ide_port_ops qd6500_port_ops = {
+ .port_init_devs = qd6500_port_init_devs,
+ .set_pio_mode = qd6500_set_pio_mode,
+ .selectproc = qd65xx_select,
+};
+
+static const struct ide_port_ops qd6580_port_ops = {
+ .port_init_devs = qd6580_port_init_devs,
+ .set_pio_mode = qd6580_set_pio_mode,
+ .selectproc = qd65xx_select,
+};
+
static const struct ide_port_info qd65xx_port_info __initdata = {
+ .name = DRV_NAME,
.chipset = ide_qd65xx,
.host_flags = IDE_HFLAG_IO_32BIT |
- IDE_HFLAG_NO_DMA |
- IDE_HFLAG_NO_AUTOTUNE,
+ IDE_HFLAG_NO_DMA,
.pio_mask = ATA_PIO4,
};
@@ -321,10 +335,8 @@ static const struct ide_port_info qd65xx_port_info __initdata = {
static int __init qd_probe(int base)
{
- ide_hwif_t *hwif;
- u8 config, unit;
- u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
- hw_regs_t hw[2];
+ int rc;
+ u8 config, unit, control;
struct ide_port_info d = qd65xx_port_info;
config = inb(QD_CONFIG_PORT);
@@ -337,21 +349,11 @@ static int __init qd_probe(int base)
if (unit)
d.host_flags |= IDE_HFLAG_QD_2ND_PORT;
- memset(&hw, 0, sizeof(hw));
-
- ide_std_init_ports(&hw[0], 0x1f0, 0x3f6);
- hw[0].irq = 14;
-
- ide_std_init_ports(&hw[1], 0x170, 0x376);
- hw[1].irq = 15;
-
- if ((config & 0xf0) == QD_CONFIG_QD6500) {
-
+ switch (config & 0xf0) {
+ case QD_CONFIG_QD6500:
if (qd_testreg(base))
return -ENODEV; /* bad register */
- /* qd6500 found */
-
if (config & QD_CONFIG_DISABLED) {
printk(KERN_WARNING "qd6500 is disabled !\n");
return -ENODEV;
@@ -361,37 +363,14 @@ static int __init qd_probe(int base)
printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n",
config, QD_ID3);
+ d.port_ops = &qd6500_port_ops;
d.host_flags |= IDE_HFLAG_SINGLE;
-
- hwif = ide_find_port_slot(&d);
- if (hwif == NULL)
- return -ENOENT;
-
- ide_init_port_hw(hwif, &hw[unit]);
-
- hwif->config_data = (base << 8) | config;
-
- hwif->port_init_devs = qd6500_port_init_devs;
- hwif->set_pio_mode = qd6500_set_pio_mode;
- hwif->selectproc = qd65xx_select;
-
- idx[unit] = hwif->index;
-
- ide_device_add(idx, &d);
-
- return 1;
- }
-
- if (((config & 0xf0) == QD_CONFIG_QD6580_A) ||
- ((config & 0xf0) == QD_CONFIG_QD6580_B)) {
-
- u8 control;
-
+ break;
+ case QD_CONFIG_QD6580_A:
+ case QD_CONFIG_QD6580_B:
if (qd_testreg(base) || qd_testreg(base + 0x02))
return -ENODEV; /* bad registers */
- /* qd6580 found */
-
control = inb(QD_CONTROL_PORT);
printk(KERN_NOTICE "qd6580 at %#x\n", base);
@@ -400,66 +379,26 @@ static int __init qd_probe(int base)
outb(QD_DEF_CONTR, QD_CONTROL_PORT);
- if (control & QD_CONTR_SEC_DISABLED) {
- /* secondary disabled */
-
- printk(KERN_INFO "qd6580: single IDE board\n");
-
+ d.port_ops = &qd6580_port_ops;
+ if (control & QD_CONTR_SEC_DISABLED)
d.host_flags |= IDE_HFLAG_SINGLE;
- hwif = ide_find_port_slot(&d);
- if (hwif == NULL)
- return -ENOENT;
-
- ide_init_port_hw(hwif, &hw[unit]);
-
- hwif->config_data = (base << 8) | config;
-
- hwif->port_init_devs = qd6580_port_init_devs;
- hwif->set_pio_mode = qd6580_set_pio_mode;
- hwif->selectproc = qd65xx_select;
+ printk(KERN_INFO "qd6580: %s IDE board\n",
+ (control & QD_CONTR_SEC_DISABLED) ? "single" : "dual");
+ break;
+ default:
+ return -ENODEV;
+ }
- idx[unit] = hwif->index;
+ rc = ide_legacy_device_add(&d, (base << 8) | config);
- ide_device_add(idx, &d);
+ if (d.host_flags & IDE_HFLAG_SINGLE)
+ return (rc == 0) ? 1 : rc;
- return 1;
- } else {
- ide_hwif_t *mate;
-
- /* secondary enabled */
- printk(KERN_INFO "qd6580: dual IDE board\n");
-
- hwif = ide_find_port();
- if (hwif) {
- ide_init_port_hw(hwif, &hw[0]);
- hwif->config_data = (base << 8) | config;
- hwif->port_init_devs = qd6580_port_init_devs;
- hwif->set_pio_mode = qd6580_set_pio_mode;
- hwif->selectproc = qd65xx_select;
- idx[0] = hwif->index;
- }
-
- mate = ide_find_port();
- if (mate) {
- ide_init_port_hw(mate, &hw[1]);
- mate->config_data = (base << 8) | config;
- mate->port_init_devs = qd6580_port_init_devs;
- mate->set_pio_mode = qd6580_set_pio_mode;
- mate->selectproc = qd65xx_select;
- idx[1] = mate->index;
- }
-
- ide_device_add(idx, &qd65xx_port_info);
-
- return 0; /* no other qd65xx possible */
- }
- }
- /* no qd65xx found */
- return -ENODEV;
+ return rc;
}
-int probe_qd65xx = 0;
+static int probe_qd65xx;
module_param_named(probe, probe_qd65xx, bool, 0);
MODULE_PARM_DESC(probe, "probe for QD65xx chipsets");
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c
index 4d90badd2bd..b54a14a5775 100644
--- a/drivers/ide/legacy/umc8672.c
+++ b/drivers/ide/legacy/umc8672.c
@@ -51,6 +51,8 @@
#include <asm/io.h>
+#define DRV_NAME "umc8672"
+
/*
* Default speeds. These can be changed with "auto-tune" and/or hdparm.
*/
@@ -120,18 +122,21 @@ static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio)
spin_unlock_irqrestore(&ide_lock, flags);
}
+static const struct ide_port_ops umc8672_port_ops = {
+ .set_pio_mode = umc_set_pio_mode,
+};
+
static const struct ide_port_info umc8672_port_info __initdata = {
+ .name = DRV_NAME,
.chipset = ide_umc8672,
- .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_NO_AUTOTUNE,
+ .port_ops = &umc8672_port_ops,
+ .host_flags = IDE_HFLAG_NO_DMA,
.pio_mask = ATA_PIO4,
};
static int __init umc8672_probe(void)
{
- ide_hwif_t *hwif, *mate;
unsigned long flags;
- static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
- hw_regs_t hw[2];
if (!request_region(0x108, 2, "umc8672")) {
printk(KERN_ERR "umc8672: ports 0x108-0x109 already in use.\n");
@@ -150,34 +155,10 @@ static int __init umc8672_probe(void)
umc_set_speeds(current_speeds);
local_irq_restore(flags);
- memset(&hw, 0, sizeof(hw));
-
- ide_std_init_ports(&hw[0], 0x1f0, 0x3f6);
- hw[0].irq = 14;
-
- ide_std_init_ports(&hw[1], 0x170, 0x376);
- hw[1].irq = 15;
-
- hwif = ide_find_port();
- if (hwif) {
- ide_init_port_hw(hwif, &hw[0]);
- hwif->set_pio_mode = umc_set_pio_mode;
- idx[0] = hwif->index;
- }
-
- mate = ide_find_port();
- if (mate) {
- ide_init_port_hw(mate, &hw[1]);
- mate->set_pio_mode = umc_set_pio_mode;
- idx[1] = mate->index;
- }
-
- ide_device_add(idx, &umc8672_port_info);
-
- return 0;
+ return ide_legacy_device_add(&umc8672_port_info, 0);
}
-int probe_umc8672;
+static int probe_umc8672;
module_param_named(probe, probe_umc8672, bool, 0);
MODULE_PARM_DESC(probe, "probe for UMC8672 chipset");
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index a8cd0035936..1a6c27b3249 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -47,9 +47,6 @@
#define IDE_AU1XXX_BURSTMODE 1
static _auide_hwif auide_hwif;
-static int dbdma_init_done;
-
-static int auide_ddma_init(_auide_hwif *auide);
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
@@ -61,7 +58,7 @@ void auide_insw(unsigned long port, void *addr, u32 count)
if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
DDMA_FLAGS_NOIE)) {
- printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+ printk(KERN_ERR "%s failed %d\n", __func__, __LINE__);
return;
}
ctp = *((chan_tab_t **)ahwif->rx_chan);
@@ -79,7 +76,7 @@ void auide_outsw(unsigned long port, void *addr, u32 count)
if(!put_source_flags(ahwif->tx_chan, (void*)addr,
count << 1, DDMA_FLAGS_NOIE)) {
- printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+ printk(KERN_ERR "%s failed %d\n", __func__, __LINE__);
return;
}
ctp = *((chan_tab_t **)ahwif->tx_chan);
@@ -89,6 +86,17 @@ void auide_outsw(unsigned long port, void *addr, u32 count)
ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
+static void au1xxx_input_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
+{
+ auide_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
+}
+
+static void au1xxx_output_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
+{
+ auide_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
+}
#endif
static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
@@ -250,7 +258,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
(void*) sg_virt(sg),
tc, flags)) {
printk(KERN_ERR "%s failed %d\n",
- __FUNCTION__, __LINE__);
+ __func__, __LINE__);
}
} else
{
@@ -258,7 +266,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
(void*) sg_virt(sg),
tc, flags)) {
printk(KERN_ERR "%s failed %d\n",
- __FUNCTION__, __LINE__);
+ __func__, __LINE__);
}
}
@@ -315,35 +323,6 @@ static int auide_dma_setup(ide_drive_t *drive)
return 0;
}
-static u8 auide_mdma_filter(ide_drive_t *drive)
-{
- /*
- * FIXME: ->white_list and ->black_list are based on completely bogus
- * ->ide_dma_check implementation which didn't set neither the host
- * controller timings nor the device for the desired transfer mode.
- *
- * They should be either removed or 0x00 MWDMA mask should be
- * returned for devices on the ->black_list.
- */
-
- if (dbdma_init_done == 0) {
- auide_hwif.white_list = ide_in_drive_list(drive->id,
- dma_white_list);
- auide_hwif.black_list = ide_in_drive_list(drive->id,
- dma_black_list);
- auide_hwif.drive = drive;
- auide_ddma_init(&auide_hwif);
- dbdma_init_done = 1;
- }
-
- /* Is the drive in our DMA black list? */
- if (auide_hwif.black_list)
- printk(KERN_WARNING "%s: Disabling DMA for %s (blacklisted)\n",
- drive->name, drive->id->model);
-
- return drive->hwif->mwdma_mask;
-}
-
static int auide_dma_test_irq(ide_drive_t *drive)
{
if (drive->waiting_for_dma == 0)
@@ -389,48 +368,48 @@ static void auide_ddma_rx_callback(int irq, void *param)
static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags)
{
dev->dev_id = dev_id;
- dev->dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
+ dev->dev_physaddr = (u32)IDE_PHYS_ADDR;
dev->dev_intlevel = 0;
dev->dev_intpolarity = 0;
dev->dev_tsize = tsize;
dev->dev_devwidth = devwidth;
dev->dev_flags = flags;
}
-
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
static void auide_dma_timeout(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
- if (hwif->ide_dma_test_irq(drive))
+ if (auide_dma_test_irq(drive))
return;
- hwif->ide_dma_end(drive);
+ auide_dma_end(drive);
}
-
-static int auide_ddma_init(_auide_hwif *auide) {
-
+static const struct ide_dma_ops au1xxx_dma_ops = {
+ .dma_host_set = auide_dma_host_set,
+ .dma_setup = auide_dma_setup,
+ .dma_exec_cmd = auide_dma_exec_cmd,
+ .dma_start = auide_dma_start,
+ .dma_end = auide_dma_end,
+ .dma_test_irq = auide_dma_test_irq,
+ .dma_lost_irq = auide_dma_lost_irq,
+ .dma_timeout = auide_dma_timeout,
+};
+
+static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
+{
+ _auide_hwif *auide = (_auide_hwif *)hwif->hwif_data;
dbdev_tab_t source_dev_tab, target_dev_tab;
u32 dev_id, tsize, devwidth, flags;
- ide_hwif_t *hwif = auide->hwif;
- dev_id = AU1XXX_ATA_DDMA_REQ;
+ dev_id = IDE_DDMA_REQ;
- if (auide->white_list || auide->black_list) {
- tsize = 8;
- devwidth = 32;
- }
- else {
- tsize = 1;
- devwidth = 16;
-
- printk(KERN_ERR "au1xxx-ide: %s is not on ide driver whitelist.\n",auide_hwif.drive->id->model);
- printk(KERN_ERR " please read 'Documentation/mips/AU1xxx_IDE.README'");
- }
+ tsize = 8; /* 1 */
+ devwidth = 32; /* 16 */
#ifdef IDE_AU1XXX_BURSTMODE
flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;
@@ -482,9 +461,9 @@ static int auide_ddma_init(_auide_hwif *auide) {
return 0;
}
#else
-
-static int auide_ddma_init( _auide_hwif *auide )
+static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
{
+ _auide_hwif *auide = (_auide_hwif *)hwif->hwif_data;
dbdev_tab_t source_dev_tab;
int flags;
@@ -532,20 +511,28 @@ static int auide_ddma_init( _auide_hwif *auide )
static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)
{
int i;
- unsigned long *ata_regs = hw->io_ports;
+ unsigned long *ata_regs = hw->io_ports_array;
/* FIXME? */
- for (i = 0; i < IDE_CONTROL_OFFSET; i++) {
- *ata_regs++ = ahwif->regbase + (i << AU1XXX_ATA_REG_OFFSET);
- }
+ for (i = 0; i < 8; i++)
+ *ata_regs++ = ahwif->regbase + (i << IDE_REG_SHIFT);
/* set the Alternative Status register */
- *ata_regs = ahwif->regbase + (14 << AU1XXX_ATA_REG_OFFSET);
+ *ata_regs = ahwif->regbase + (14 << IDE_REG_SHIFT);
}
+static const struct ide_port_ops au1xxx_port_ops = {
+ .set_pio_mode = au1xxx_set_pio_mode,
+ .set_dma_mode = auide_set_dma_mode,
+};
+
static const struct ide_port_info au1xxx_port_info = {
+ .init_dma = auide_ddma_init,
+ .port_ops = &au1xxx_port_ops,
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ .dma_ops = &au1xxx_dma_ops,
+#endif
.host_flags = IDE_HFLAG_POST_SET_MODE |
- IDE_HFLAG_NO_DMA | /* no SFF-style DMA */
IDE_HFLAG_NO_IO_32BIT |
IDE_HFLAG_UNMASK_IRQS,
.pio_mask = ATA_PIO4,
@@ -615,32 +602,13 @@ static int au_ide_probe(struct device *dev)
hwif->dev = dev;
- hwif->mmio = 1;
-
/* If the user has selected DDMA assisted copies,
then set up a few local I/O function entry points
*/
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
- hwif->INSW = auide_insw;
- hwif->OUTSW = auide_outsw;
-#endif
-
- hwif->set_pio_mode = &au1xxx_set_pio_mode;
- hwif->set_dma_mode = &auide_set_dma_mode;
-
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- hwif->dma_timeout = &auide_dma_timeout;
-
- hwif->mdma_filter = &auide_mdma_filter;
-
- hwif->dma_host_set = &auide_dma_host_set;
- hwif->dma_exec_cmd = &auide_dma_exec_cmd;
- hwif->dma_start = &auide_dma_start;
- hwif->ide_dma_end = &auide_dma_end;
- hwif->dma_setup = &auide_dma_setup;
- hwif->ide_dma_test_irq = &auide_dma_test_irq;
- hwif->dma_lost_irq = &auide_dma_lost_irq;
+ hwif->input_data = au1xxx_input_data;
+ hwif->output_data = au1xxx_output_data;
#endif
hwif->select_data = 0; /* no chipset-specific code */
hwif->config_data = 0; /* no chipset-specific code */
@@ -648,11 +616,6 @@ static int au_ide_probe(struct device *dev)
auide_hwif.hwif = hwif;
hwif->hwif_data = &auide_hwif;
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
- auide_ddma_init(&auide_hwif);
- dbdma_init_done = 1;
-#endif
-
idx[0] = hwif->index;
ide_device_add(idx, &au1xxx_port_info);
@@ -672,7 +635,7 @@ static int au_ide_remove(struct device *dev)
ide_hwif_t *hwif = dev_get_drvdata(dev);
_auide_hwif *ahwif = &auide_hwif;
- ide_unregister(hwif->index);
+ ide_unregister(hwif);
iounmap((void *)ahwif->regbase);
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
index bbe8d585334..712d17bdd47 100644
--- a/drivers/ide/mips/swarm.c
+++ b/drivers/ide/mips/swarm.c
@@ -109,16 +109,15 @@ static int __devinit swarm_ide_probe(struct device *dev)
base = ioremap(offset, size);
/* Setup MMIO ops. */
+ hwif->host_flags = IDE_HFLAG_MMIO;
default_hwif_mmiops(hwif);
- /* Prevent resource map manipulation. */
- hwif->mmio = 1;
+
hwif->chipset = ide_generic;
- hwif->noprobe = 0;
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
- hwif->io_ports[i] =
+ for (i = 0; i <= 7; i++)
+ hwif->io_ports_array[i] =
(unsigned long)(base + ((0x1f0 + i) << 5));
- hwif->io_ports[IDE_CONTROL_OFFSET] =
+ hwif->io_ports.ctl_addr =
(unsigned long)(base + (0x3f6 << 5));
hwif->irq = K_INT_GB_IDE;
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index c9ba15afe97..7f46c224b7c 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -135,12 +135,12 @@ static void aec6260_set_mode(ide_drive_t *drive, const u8 speed)
static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- drive->hwif->set_dma_mode(drive, pio + XFER_PIO_0);
+ drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0);
}
static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name)
{
- int bus_speed = system_bus_clock();
+ int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock();
if (bus_speed <= 33)
pci_set_drvdata(dev, (void *) aec6xxx_33_base);
@@ -175,27 +175,23 @@ static u8 __devinit atp86x_cable_detect(ide_hwif_t *hwif)
return (ata66 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
}
-static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
-{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
-
- hwif->set_pio_mode = &aec_set_pio_mode;
-
- if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
- hwif->set_dma_mode = &aec6210_set_mode;
- else {
- hwif->set_dma_mode = &aec6260_set_mode;
+static const struct ide_port_ops atp850_port_ops = {
+ .set_pio_mode = aec_set_pio_mode,
+ .set_dma_mode = aec6210_set_mode,
+};
- hwif->cable_detect = atp86x_cable_detect;
- }
-}
+static const struct ide_port_ops atp86x_port_ops = {
+ .set_pio_mode = aec_set_pio_mode,
+ .set_dma_mode = aec6260_set_mode,
+ .cable_detect = atp86x_cable_detect,
+};
static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
{ /* 0 */
.name = "AEC6210",
.init_chipset = init_chipset_aec62xx,
- .init_hwif = init_hwif_aec62xx,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+ .port_ops = &atp850_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE |
IDE_HFLAG_NO_ATAPI_DMA |
IDE_HFLAG_NO_DSC |
@@ -207,7 +203,7 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
},{ /* 1 */
.name = "AEC6260",
.init_chipset = init_chipset_aec62xx,
- .init_hwif = init_hwif_aec62xx,
+ .port_ops = &atp86x_port_ops,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA |
IDE_HFLAG_ABUSE_SET_DMA_MODE |
IDE_HFLAG_OFF_BOARD,
@@ -217,8 +213,8 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
},{ /* 2 */
.name = "AEC6260R",
.init_chipset = init_chipset_aec62xx,
- .init_hwif = init_hwif_aec62xx,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+ .port_ops = &atp86x_port_ops,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA |
IDE_HFLAG_ABUSE_SET_DMA_MODE |
IDE_HFLAG_NON_BOOTABLE,
@@ -228,7 +224,7 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
},{ /* 3 */
.name = "AEC6280",
.init_chipset = init_chipset_aec62xx,
- .init_hwif = init_hwif_aec62xx,
+ .port_ops = &atp86x_port_ops,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA |
IDE_HFLAG_ABUSE_SET_DMA_MODE |
IDE_HFLAG_OFF_BOARD,
@@ -238,8 +234,8 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
},{ /* 4 */
.name = "AEC6280R",
.init_chipset = init_chipset_aec62xx,
- .init_hwif = init_hwif_aec62xx,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+ .port_ops = &atp86x_port_ops,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA |
IDE_HFLAG_ABUSE_SET_DMA_MODE |
IDE_HFLAG_OFF_BOARD,
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 3fa2d9f7b1b..c1922f9cfe8 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -38,8 +38,6 @@
#include <asm/io.h>
-#define DISPLAY_ALI_TIMINGS
-
/*
* ALi devices are not plug in. Otherwise these static values would
* need to go. They ought to go away anyway
@@ -49,236 +47,6 @@ static u8 m5229_revision;
static u8 chip_is_1543c_e;
static struct pci_dev *isa_dev;
-#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static u8 ali_proc = 0;
-
-static struct pci_dev *bmide_dev;
-
-static char *fifo[4] = {
- "FIFO Off",
- "FIFO On ",
- "DMA mode",
- "PIO mode" };
-
-static char *udmaT[8] = {
- "1.5T",
- " 2T",
- "2.5T",
- " 3T",
- "3.5T",
- " 4T",
- " 6T",
- " 8T"
-};
-
-static char *channel_status[8] = {
- "OK ",
- "busy ",
- "DRQ ",
- "DRQ busy ",
- "error ",
- "error busy ",
- "error DRQ ",
- "error DRQ busy"
-};
-
-/**
- * ali_get_info - generate proc file for ALi IDE
- * @buffer: buffer to fill
- * @addr: address of user start in buffer
- * @offset: offset into 'file'
- * @count: buffer count
- *
- * Walks the Ali devices and outputs summary data on the tuning and
- * anything else that will help with debugging
- */
-
-static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
-{
- unsigned long bibma;
- u8 reg53h, reg5xh, reg5yh, reg5xh1, reg5yh1, c0, c1, rev, tmp;
- char *q, *p = buffer;
-
- /* fetch rev. */
- pci_read_config_byte(bmide_dev, 0x08, &rev);
- if (rev >= 0xc1) /* M1543C or newer */
- udmaT[7] = " ???";
- else
- fifo[3] = " ??? ";
-
- /* first fetch bibma: */
-
- bibma = pci_resource_start(bmide_dev, 4);
-
- /*
- * at that point bibma+0x2 et bibma+0xa are byte
- * registers to investigate:
- */
- c0 = inb(bibma + 0x02);
- c1 = inb(bibma + 0x0a);
-
- p += sprintf(p,
- "\n Ali M15x3 Chipset.\n");
- p += sprintf(p,
- " ------------------\n");
- pci_read_config_byte(bmide_dev, 0x78, &reg53h);
- p += sprintf(p, "PCI Clock: %d.\n", reg53h);
-
- pci_read_config_byte(bmide_dev, 0x53, &reg53h);
- p += sprintf(p,
- "CD_ROM FIFO:%s, CD_ROM DMA:%s\n",
- (reg53h & 0x02) ? "Yes" : "No ",
- (reg53h & 0x01) ? "Yes" : "No " );
- pci_read_config_byte(bmide_dev, 0x74, &reg53h);
- p += sprintf(p,
- "FIFO Status: contains %d Words, runs%s%s\n\n",
- (reg53h & 0x3f),
- (reg53h & 0x40) ? " OVERWR" : "",
- (reg53h & 0x80) ? " OVERRD." : "." );
-
- p += sprintf(p,
- "-------------------primary channel"
- "-------------------secondary channel"
- "---------\n\n");
-
- pci_read_config_byte(bmide_dev, 0x09, &reg53h);
- p += sprintf(p,
- "channel status: %s"
- " %s\n",
- (reg53h & 0x20) ? "On " : "Off",
- (reg53h & 0x10) ? "On " : "Off" );
-
- p += sprintf(p,
- "both channels togth: %s"
- " %s\n",
- (c0&0x80) ? "No " : "Yes",
- (c1&0x80) ? "No " : "Yes" );
-
- pci_read_config_byte(bmide_dev, 0x76, &reg53h);
- p += sprintf(p,
- "Channel state: %s %s\n",
- channel_status[reg53h & 0x07],
- channel_status[(reg53h & 0x70) >> 4] );
-
- pci_read_config_byte(bmide_dev, 0x58, &reg5xh);
- pci_read_config_byte(bmide_dev, 0x5c, &reg5yh);
- p += sprintf(p,
- "Add. Setup Timing: %dT"
- " %dT\n",
- (reg5xh & 0x07) ? (reg5xh & 0x07) : 8,
- (reg5yh & 0x07) ? (reg5yh & 0x07) : 8 );
-
- pci_read_config_byte(bmide_dev, 0x59, &reg5xh);
- pci_read_config_byte(bmide_dev, 0x5d, &reg5yh);
- p += sprintf(p,
- "Command Act. Count: %dT"
- " %dT\n"
- "Command Rec. Count: %dT"
- " %dT\n\n",
- (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8,
- (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8,
- (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16,
- (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16 );
-
- p += sprintf(p,
- "----------------drive0-----------drive1"
- "------------drive0-----------drive1------\n\n");
- p += sprintf(p,
- "DMA enabled: %s %s"
- " %s %s\n",
- (c0&0x20) ? "Yes" : "No ",
- (c0&0x40) ? "Yes" : "No ",
- (c1&0x20) ? "Yes" : "No ",
- (c1&0x40) ? "Yes" : "No " );
-
- pci_read_config_byte(bmide_dev, 0x54, &reg5xh);
- pci_read_config_byte(bmide_dev, 0x55, &reg5yh);
- q = "FIFO threshold: %2d Words %2d Words"
- " %2d Words %2d Words\n";
- if (rev < 0xc1) {
- if ((rev == 0x20) &&
- (pci_read_config_byte(bmide_dev, 0x4f, &tmp), (tmp &= 0x20))) {
- p += sprintf(p, q, 8, 8, 8, 8);
- } else {
- p += sprintf(p, q,
- (reg5xh & 0x03) + 12,
- ((reg5xh & 0x30)>>4) + 12,
- (reg5yh & 0x03) + 12,
- ((reg5yh & 0x30)>>4) + 12 );
- }
- } else {
- int t1 = (tmp = (reg5xh & 0x03)) ? (tmp << 3) : 4;
- int t2 = (tmp = ((reg5xh & 0x30)>>4)) ? (tmp << 3) : 4;
- int t3 = (tmp = (reg5yh & 0x03)) ? (tmp << 3) : 4;
- int t4 = (tmp = ((reg5yh & 0x30)>>4)) ? (tmp << 3) : 4;
- p += sprintf(p, q, t1, t2, t3, t4);
- }
-
-#if 0
- p += sprintf(p,
- "FIFO threshold: %2d Words %2d Words"
- " %2d Words %2d Words\n",
- (reg5xh & 0x03) + 12,
- ((reg5xh & 0x30)>>4) + 12,
- (reg5yh & 0x03) + 12,
- ((reg5yh & 0x30)>>4) + 12 );
-#endif
-
- p += sprintf(p,
- "FIFO mode: %s %s %s %s\n",
- fifo[((reg5xh & 0x0c) >> 2)],
- fifo[((reg5xh & 0xc0) >> 6)],
- fifo[((reg5yh & 0x0c) >> 2)],
- fifo[((reg5yh & 0xc0) >> 6)] );
-
- pci_read_config_byte(bmide_dev, 0x5a, &reg5xh);
- pci_read_config_byte(bmide_dev, 0x5b, &reg5xh1);
- pci_read_config_byte(bmide_dev, 0x5e, &reg5yh);
- pci_read_config_byte(bmide_dev, 0x5f, &reg5yh1);
-
- p += sprintf(p,/*
- "------------------drive0-----------drive1"
- "------------drive0-----------drive1------\n")*/
- "Dt RW act. Cnt %2dT %2dT"
- " %2dT %2dT\n"
- "Dt RW rec. Cnt %2dT %2dT"
- " %2dT %2dT\n\n",
- (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8,
- (reg5xh1 & 0x70) ? ((reg5xh1 & 0x70) >> 4) : 8,
- (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8,
- (reg5yh1 & 0x70) ? ((reg5yh1 & 0x70) >> 4) : 8,
- (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16,
- (reg5xh1 & 0x0f) ? (reg5xh1 & 0x0f) : 16,
- (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16,
- (reg5yh1 & 0x0f) ? (reg5yh1 & 0x0f) : 16 );
-
- p += sprintf(p,
- "-----------------------------------UDMA Timings"
- "--------------------------------\n\n");
-
- pci_read_config_byte(bmide_dev, 0x56, &reg5xh);
- pci_read_config_byte(bmide_dev, 0x57, &reg5yh);
- p += sprintf(p,
- "UDMA: %s %s"
- " %s %s\n"
- "UDMA timings: %s %s"
- " %s %s\n\n",
- (reg5xh & 0x08) ? "OK" : "No",
- (reg5xh & 0x80) ? "OK" : "No",
- (reg5yh & 0x08) ? "OK" : "No",
- (reg5yh & 0x80) ? "OK" : "No",
- udmaT[(reg5xh & 0x07)],
- udmaT[(reg5xh & 0x70) >> 4],
- udmaT[reg5yh & 0x07],
- udmaT[(reg5yh & 0x70) >> 4] );
-
- return p-buffer; /* => must be less than 4k! */
-}
-#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */
-
/**
* ali_set_pio_mode - set host controller for PIO mode
* @drive: drive
@@ -294,7 +62,7 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
int s_time, a_time, c_time;
u8 s_clc, a_clc, r_clc;
unsigned long flags;
- int bus_speed = system_bus_clock();
+ int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock();
int port = hwif->channel ? 0x5c : 0x58;
int portFIFO = hwif->channel ? 0x55 : 0x54;
u8 cd_dma_fifo = 0;
@@ -465,14 +233,6 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c
isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
-#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
- if (!ali_proc) {
- ali_proc = 1;
- bmide_dev = dev;
- ide_pci_create_host_proc("ali", ali_get_info);
- }
-#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */
-
local_irq_save(flags);
if (m5229_revision < 0xC2) {
@@ -610,7 +370,7 @@ static int ali_cable_override(struct pci_dev *pdev)
}
/**
- * ata66_ali15x3 - check for UDMA 66 support
+ * ali_cable_detect - cable detection
* @hwif: IDE interface
*
* This checks if the controller and the cable are capable
@@ -620,7 +380,7 @@ static int ali_cable_override(struct pci_dev *pdev)
* FIXME: frobs bits that are not defined on newer ALi devicea
*/
-static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif)
+static u8 __devinit ali_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long flags;
@@ -652,34 +412,14 @@ static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif)
return cbl;
}
-/**
- * init_hwif_common_ali15x3 - Set up ALI IDE hardware
- * @hwif: IDE interface
- *
- * Initialize the IDE structure side of the ALi 15x3 driver.
- */
-
-static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &ali_set_pio_mode;
- hwif->set_dma_mode = &ali_set_dma_mode;
- hwif->udma_filter = &ali_udma_filter;
-
- hwif->cable_detect = ata66_ali15x3;
-
- if (hwif->dma_base == 0)
- return;
-
- hwif->dma_setup = &ali15x3_dma_setup;
-}
-
+#if !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC)
/**
* init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff
* @hwif: interface to configure
*
* Obtain the IRQ tables for an ALi based IDE solution on the PC
* class platforms. This part of the code isn't applicable to the
- * Sparc systems
+ * Sparc and PowerPC systems.
*/
static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
@@ -722,34 +462,66 @@ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
if(irq >= 0)
hwif->irq = irq;
}
-
- init_hwif_common_ali15x3(hwif);
}
+#else
+#define init_hwif_ali15x3 NULL
+#endif /* !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC) */
/**
* init_dma_ali15x3 - set up DMA on ALi15x3
* @hwif: IDE interface
- * @dmabase: DMA interface base PCI address
+ * @d: IDE port info
*
- * Set up the DMA functionality on the ALi 15x3. For the ALi
- * controllers this is generic so we can let the generic code do
- * the actual work.
+ * Set up the DMA functionality on the ALi 15x3.
*/
-static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
+static int __devinit init_dma_ali15x3(ide_hwif_t *hwif,
+ const struct ide_port_info *d)
{
- if (m5229_revision < 0x20)
- return;
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
+ unsigned long base = ide_pci_dma_base(hwif, d);
+
+ if (base == 0 || ide_pci_set_master(dev, d->name) < 0)
+ return -1;
+
if (!hwif->channel)
- outb(inb(dmabase + 2) & 0x60, dmabase + 2);
- ide_setup_dma(hwif, dmabase);
+ outb(inb(base + 2) & 0x60, base + 2);
+
+ printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n",
+ hwif->name, base, base + 7);
+
+ if (ide_allocate_dma_engine(hwif))
+ return -1;
+
+ ide_setup_dma(hwif, base);
+
+ return 0;
}
+static const struct ide_port_ops ali_port_ops = {
+ .set_pio_mode = ali_set_pio_mode,
+ .set_dma_mode = ali_set_dma_mode,
+ .udma_filter = ali_udma_filter,
+ .cable_detect = ali_cable_detect,
+};
+
+static const struct ide_dma_ops ali_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ali15x3_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = ide_dma_start,
+ .dma_end = __ide_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
+
static const struct ide_port_info ali15x3_chipset __devinitdata = {
.name = "ALI15X3",
.init_chipset = init_chipset_ali15x3,
.init_hwif = init_hwif_ali15x3,
.init_dma = init_dma_ali15x3,
+ .port_ops = &ali_port_ops,
.pio_mask = ATA_PIO5,
.swdma_mask = ATA_SWDMA2,
.mwdma_mask = ATA_MWDMA2,
@@ -792,14 +564,17 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
d.udma_mask = ATA_UDMA5;
else
d.udma_mask = ATA_UDMA6;
+
+ d.dma_ops = &ali_dma_ops;
+ } else {
+ d.host_flags |= IDE_HFLAG_NO_DMA;
+
+ d.mwdma_mask = d.swdma_mask = 0;
}
if (idx == 0)
d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX;
-#if defined(CONFIG_SPARC64)
- d.init_hwif = init_hwif_common_ali15x3;
-#endif /* CONFIG_SPARC64 */
return ide_setup_pci_device(dev, &d);
}
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index ff684d31237..efcf54338be 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -179,7 +179,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev,
* Determine the system bus clock.
*/
- amd_clock = system_bus_clock() * 1000;
+ amd_clock = (ide_pci_clk ? ide_pci_clk : system_bus_clock()) * 1000;
switch (amd_clock) {
case 33000: amd_clock = 33333; break;
@@ -210,13 +210,14 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
if (hwif->irq == 0) /* 0 is bogus but will do for now */
hwif->irq = pci_get_legacy_ide_irq(dev, hwif->channel);
-
- hwif->set_pio_mode = &amd_set_pio_mode;
- hwif->set_dma_mode = &amd_set_drive;
-
- hwif->cable_detect = amd_cable_detect;
}
+static const struct ide_port_ops amd_port_ops = {
+ .set_pio_mode = amd_set_pio_mode,
+ .set_dma_mode = amd_set_drive,
+ .cable_detect = amd_cable_detect,
+};
+
#define IDE_HFLAGS_AMD \
(IDE_HFLAG_PIO_NO_BLACKLIST | \
IDE_HFLAG_ABUSE_SET_DMA_MODE | \
@@ -230,6 +231,7 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
.init_chipset = init_chipset_amd74xx, \
.init_hwif = init_hwif_amd74xx, \
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \
+ .port_ops = &amd_port_ops, \
.host_flags = IDE_HFLAGS_AMD, \
.pio_mask = ATA_PIO5, \
.swdma_mask = swdma, \
@@ -243,6 +245,7 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
.init_chipset = init_chipset_amd74xx, \
.init_hwif = init_hwif_amd74xx, \
.enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \
+ .port_ops = &amd_port_ops, \
.host_flags = IDE_HFLAGS_AMD, \
.pio_mask = ATA_PIO5, \
.swdma_mask = ATA_SWDMA2, \
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 91722f88b7b..8b637181681 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -130,35 +130,25 @@ static u8 __devinit atiixp_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA40;
}
-/**
- * init_hwif_atiixp - fill in the hwif for the ATIIXP
- * @hwif: IDE interface
- *
- * Set up the ide_hwif_t for the ATIIXP interface according to the
- * capabilities of the hardware.
- */
-
-static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &atiixp_set_pio_mode;
- hwif->set_dma_mode = &atiixp_set_dma_mode;
-
- hwif->cable_detect = atiixp_cable_detect;
-}
+static const struct ide_port_ops atiixp_port_ops = {
+ .set_pio_mode = atiixp_set_pio_mode,
+ .set_dma_mode = atiixp_set_dma_mode,
+ .cable_detect = atiixp_cable_detect,
+};
static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
{ /* 0 */
.name = "ATIIXP",
- .init_hwif = init_hwif_atiixp,
.enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
+ .port_ops = &atiixp_port_ops,
.host_flags = IDE_HFLAG_LEGACY_IRQS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
},{ /* 1 */
.name = "SB600_PATA",
- .init_hwif = init_hwif_atiixp,
.enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}},
+ .port_ops = &atiixp_port_ops,
.host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
index b076dbfc43a..aaf38109eae 100644
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -109,10 +109,9 @@
#include <asm/io.h>
-/*
- * This flag is set in ide.c by the parameter: ide0=cmd640_vlb
- */
-int cmd640_vlb;
+#define DRV_NAME "cmd640"
+
+static int cmd640_vlb;
/*
* CMD640 specific registers definition.
@@ -348,12 +347,12 @@ static int __init secondary_port_responding(void)
spin_lock_irqsave(&cmd640_lock, flags);
- outb_p(0x0a, 0x170 + IDE_SELECT_OFFSET); /* select drive0 */
+ outb_p(0x0a, 0x176); /* select drive0 */
udelay(100);
- if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x0a) {
- outb_p(0x1a, 0x170 + IDE_SELECT_OFFSET); /* select drive1 */
+ if ((inb_p(0x176) & 0x1f) != 0x0a) {
+ outb_p(0x1a, 0x176); /* select drive1 */
udelay(100);
- if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x1a) {
+ if ((inb_p(0x176) & 0x1f) != 0x1a) {
spin_unlock_irqrestore(&cmd640_lock, flags);
return 0; /* nothing responded */
}
@@ -381,6 +380,7 @@ static void cmd640_dump_regs(void)
}
#endif
+#ifndef CONFIG_BLK_DEV_CMD640_ENHANCED
/*
* Check whether prefetch is on for a drive,
* and initialize the unmask flags for safe operation.
@@ -401,9 +401,7 @@ static void __init check_prefetch(ide_drive_t *drive, unsigned int index)
drive->no_io_32bit = 0;
}
}
-
-#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
-
+#else
/*
* Sets prefetch mode for a drive.
*/
@@ -460,34 +458,6 @@ static inline u8 pack_nibbles(u8 upper, u8 lower)
}
/*
- * This routine retrieves the initial drive timings from the chipset.
- */
-static void __init retrieve_drive_counts(unsigned int index)
-{
- u8 b;
-
- /*
- * Get the internal setup timing, and convert to clock count
- */
- b = get_cmd640_reg(arttim_regs[index]) & ~0x3f;
- switch (b) {
- case 0x00: b = 4; break;
- case 0x80: b = 3; break;
- case 0x40: b = 2; break;
- default: b = 5; break;
- }
- setup_counts[index] = b;
-
- /*
- * Get the active/recovery counts
- */
- b = get_cmd640_reg(drwtim_regs[index]);
- active_counts[index] = (b >> 4) ? (b >> 4) : 0x10;
- recovery_counts[index] = (b & 0x0f) ? (b & 0x0f) : 0x10;
-}
-
-
-/*
* This routine writes the prepared setup/active/recovery counts
* for a drive into the cmd640 chipset registers to active them.
*/
@@ -553,7 +523,14 @@ static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
{
int setup_time, active_time, recovery_time, clock_time;
u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count;
- int bus_speed = system_bus_clock();
+ int bus_speed;
+
+ if (cmd640_vlb && ide_vlb_clk)
+ bus_speed = ide_vlb_clk;
+ else if (!cmd640_vlb && ide_pci_clk)
+ bus_speed = ide_pci_clk;
+ else
+ bus_speed = system_bus_clock();
if (pio_mode > 5)
pio_mode = 5;
@@ -633,6 +610,9 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
display_clocks(index);
}
+static const struct ide_port_ops cmd640_port_ops = {
+ .set_pio_mode = cmd640_set_pio_mode,
+};
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
static int pci_conf1(void)
@@ -674,14 +654,32 @@ static const struct ide_port_info cmd640_port_info __initdata = {
.chipset = ide_cmd640,
.host_flags = IDE_HFLAG_SERIALIZE |
IDE_HFLAG_NO_DMA |
- IDE_HFLAG_NO_AUTOTUNE |
IDE_HFLAG_ABUSE_PREFETCH |
IDE_HFLAG_ABUSE_FAST_DEVSEL,
#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
+ .port_ops = &cmd640_port_ops,
.pio_mask = ATA_PIO5,
#endif
};
+static int cmd640x_init_one(unsigned long base, unsigned long ctl)
+{
+ if (!request_region(base, 8, DRV_NAME)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
+ DRV_NAME, base, base + 7);
+ return -EBUSY;
+ }
+
+ if (!request_region(ctl, 1, DRV_NAME)) {
+ printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
+ DRV_NAME, ctl);
+ release_region(base, 8);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
/*
* Probe for a cmd640 chipset, and initialize it if found.
*/
@@ -690,7 +688,7 @@ static int __init cmd640x_init(void)
#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
int second_port_toggled = 0;
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
- int second_port_cmd640 = 0;
+ int second_port_cmd640 = 0, rc;
const char *bus_type, *port2;
unsigned int index;
u8 b, cfr;
@@ -734,6 +732,17 @@ static int __init cmd640x_init(void)
return 0;
}
+ rc = cmd640x_init_one(0x1f0, 0x3f6);
+ if (rc)
+ return rc;
+
+ rc = cmd640x_init_one(0x170, 0x376);
+ if (rc) {
+ release_region(0x3f6, 1);
+ release_region(0x1f0, 8);
+ return rc;
+ }
+
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw[0], 0x1f0, 0x3f6);
@@ -752,10 +761,6 @@ static int __init cmd640x_init(void)
*/
if (cmd_hwif0) {
ide_init_port_hw(cmd_hwif0, &hw[0]);
-#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
- cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode;
-#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
-
idx[0] = cmd_hwif0->index;
}
@@ -808,10 +813,6 @@ static int __init cmd640x_init(void)
*/
if (second_port_cmd640 && cmd_hwif1) {
ide_init_port_hw(cmd_hwif1, &hw[1]);
-#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
- cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode;
-#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
-
idx[1] = cmd_hwif1->index;
}
printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n",
@@ -835,29 +836,16 @@ static int __init cmd640x_init(void)
}
#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
- if (drive->autotune || ((index > 1) && second_port_toggled)) {
- /*
- * Reset timing to the slowest speed and turn off
- * prefetch. This way, the drive identify code has
- * a better chance.
- */
- setup_counts [index] = 4; /* max possible */
- active_counts [index] = 16; /* max possible */
- recovery_counts [index] = 16; /* max possible */
- program_drive_counts(drive, index);
- set_prefetch_mode(drive, index, 0);
- printk("cmd640: drive%d timings/prefetch cleared\n", index);
- } else {
- /*
- * Record timings/prefetch without changing them.
- * This preserves any prior BIOS setup.
- */
- retrieve_drive_counts (index);
- check_prefetch(drive, index);
- printk("cmd640: drive%d timings/prefetch(%s) preserved",
- index, drive->no_io_32bit ? "off" : "on");
- display_clocks(index);
- }
+ /*
+ * Reset timing to the slowest speed and turn off prefetch.
+ * This way, the drive identify code has a better chance.
+ */
+ setup_counts [index] = 4; /* max possible */
+ active_counts [index] = 16; /* max possible */
+ recovery_counts [index] = 16; /* max possible */
+ program_drive_counts(drive, index);
+ set_prefetch_mode(drive, index, 0);
+ printk("cmd640: drive%d timings/prefetch cleared\n", index);
#else
/*
* Set the drive unmask flags to match the prefetch setting
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index 8baccfef237..08674711d08 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -68,8 +68,8 @@ static u8 quantize_timing(int timing, int quant)
*/
static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time)
{
- struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
- int clock_time = 1000 / system_bus_clock();
+ struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
+ int clock_time = 1000 / (ide_pci_clk ? ide_pci_clk : system_bus_clock());
u8 cycle_count, active_count, recovery_count, drwtim;
static const u8 recovery_values[] =
{15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0};
@@ -128,7 +128,7 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
ide_pio_timings[pio].active_time);
setup_count = quantize_timing(ide_pio_timings[pio].setup_time,
- 1000 / system_bus_clock());
+ 1000 / (ide_pci_clk ? ide_pci_clk : system_bus_clock()));
/*
* The primary channel has individual address setup timing registers
@@ -223,7 +223,7 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
(void) pci_write_config_byte(dev, pciU, regU);
}
-static int cmd648_ide_dma_end (ide_drive_t *drive)
+static int cmd648_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long base = hwif->dma_base - (hwif->channel * 8);
@@ -239,7 +239,7 @@ static int cmd648_ide_dma_end (ide_drive_t *drive)
return err;
}
-static int cmd64x_ide_dma_end (ide_drive_t *drive)
+static int cmd64x_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -256,7 +256,7 @@ static int cmd64x_ide_dma_end (ide_drive_t *drive)
return err;
}
-static int cmd648_ide_dma_test_irq (ide_drive_t *drive)
+static int cmd648_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long base = hwif->dma_base - (hwif->channel * 8);
@@ -279,7 +279,7 @@ static int cmd648_ide_dma_test_irq (ide_drive_t *drive)
return 0;
}
-static int cmd64x_ide_dma_test_irq (ide_drive_t *drive)
+static int cmd64x_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -310,7 +310,7 @@ static int cmd64x_ide_dma_test_irq (ide_drive_t *drive)
* event order for DMA transfers.
*/
-static int cmd646_1_ide_dma_end (ide_drive_t *drive)
+static int cmd646_1_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u8 dma_stat = 0, dma_cmd = 0;
@@ -370,7 +370,7 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha
return 0;
}
-static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif)
+static u8 __devinit cmd64x_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 bmidecsr = 0, mask = hwif->channel ? 0x02 : 0x01;
@@ -385,60 +385,52 @@ static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif)
}
}
-static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
-{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
-
- hwif->set_pio_mode = &cmd64x_set_pio_mode;
- hwif->set_dma_mode = &cmd64x_set_dma_mode;
-
- hwif->cable_detect = ata66_cmd64x;
+static const struct ide_port_ops cmd64x_port_ops = {
+ .set_pio_mode = cmd64x_set_pio_mode,
+ .set_dma_mode = cmd64x_set_dma_mode,
+ .cable_detect = cmd64x_cable_detect,
+};
- if (!hwif->dma_base)
- return;
+static const struct ide_dma_ops cmd64x_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = ide_dma_start,
+ .dma_end = cmd64x_dma_end,
+ .dma_test_irq = cmd64x_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
- /*
- * UltraDMA only supported on PCI646U and PCI646U2, which
- * correspond to revisions 0x03, 0x05 and 0x07 respectively.
- * Actually, although the CMD tech support people won't
- * tell me the details, the 0x03 revision cannot support
- * UDMA correctly without hardware modifications, and even
- * then it only works with Quantum disks due to some
- * hold time assumptions in the 646U part which are fixed
- * in the 646U2.
- *
- * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
- */
- if (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 5)
- hwif->ultra_mask = 0x00;
+static const struct ide_dma_ops cmd646_rev1_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = ide_dma_start,
+ .dma_end = cmd646_1_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
- switch (dev->device) {
- case PCI_DEVICE_ID_CMD_648:
- case PCI_DEVICE_ID_CMD_649:
- alt_irq_bits:
- hwif->ide_dma_end = &cmd648_ide_dma_end;
- hwif->ide_dma_test_irq = &cmd648_ide_dma_test_irq;
- break;
- case PCI_DEVICE_ID_CMD_646:
- if (dev->revision == 0x01) {
- hwif->ide_dma_end = &cmd646_1_ide_dma_end;
- break;
- } else if (dev->revision >= 0x03)
- goto alt_irq_bits;
- /* fall thru */
- default:
- hwif->ide_dma_end = &cmd64x_ide_dma_end;
- hwif->ide_dma_test_irq = &cmd64x_ide_dma_test_irq;
- break;
- }
-}
+static const struct ide_dma_ops cmd648_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = ide_dma_start,
+ .dma_end = cmd648_dma_end,
+ .dma_test_irq = cmd648_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
{ /* 0 */
.name = "CMD643",
.init_chipset = init_chipset_cmd64x,
- .init_hwif = init_hwif_cmd64x,
.enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
+ .port_ops = &cmd64x_port_ops,
+ .dma_ops = &cmd64x_dma_ops,
.host_flags = IDE_HFLAG_CLEAR_SIMPLEX |
IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO5,
@@ -447,9 +439,10 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
},{ /* 1 */
.name = "CMD646",
.init_chipset = init_chipset_cmd64x,
- .init_hwif = init_hwif_cmd64x,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
.chipset = ide_cmd646,
+ .port_ops = &cmd64x_port_ops,
+ .dma_ops = &cmd648_dma_ops,
.host_flags = IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
@@ -457,8 +450,9 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
},{ /* 2 */
.name = "CMD648",
.init_chipset = init_chipset_cmd64x,
- .init_hwif = init_hwif_cmd64x,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
+ .port_ops = &cmd64x_port_ops,
+ .dma_ops = &cmd648_dma_ops,
.host_flags = IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
@@ -466,8 +460,9 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
},{ /* 3 */
.name = "CMD649",
.init_chipset = init_chipset_cmd64x,
- .init_hwif = init_hwif_cmd64x,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
+ .port_ops = &cmd64x_port_ops,
+ .dma_ops = &cmd648_dma_ops,
.host_flags = IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
@@ -482,12 +477,35 @@ static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_devic
d = cmd64x_chipsets[idx];
- /*
- * The original PCI0646 didn't have the primary channel enable bit,
- * it appeared starting with PCI0646U (i.e. revision ID 3).
- */
- if (idx == 1 && dev->revision < 3)
- d.enablebits[0].reg = 0;
+ if (idx == 1) {
+ /*
+ * UltraDMA only supported on PCI646U and PCI646U2, which
+ * correspond to revisions 0x03, 0x05 and 0x07 respectively.
+ * Actually, although the CMD tech support people won't
+ * tell me the details, the 0x03 revision cannot support
+ * UDMA correctly without hardware modifications, and even
+ * then it only works with Quantum disks due to some
+ * hold time assumptions in the 646U part which are fixed
+ * in the 646U2.
+ *
+ * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
+ */
+ if (dev->revision < 5) {
+ d.udma_mask = 0x00;
+ /*
+ * The original PCI0646 didn't have the primary
+ * channel enable bit, it appeared starting with
+ * PCI0646U (i.e. revision ID 3).
+ */
+ if (dev->revision < 3) {
+ d.enablebits[0].reg = 0;
+ if (dev->revision == 1)
+ d.dma_ops = &cmd646_rev1_dma_ops;
+ else
+ d.dma_ops = &cmd64x_dma_ops;
+ }
+ }
+ }
return ide_setup_pci_device(dev, &d);
}
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index 01b37ecb5a5..17669a43443 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -103,21 +103,27 @@ static void cs5520_dma_host_set(ide_drive_t *drive, int on)
ide_dma_host_set(drive, on);
}
-static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &cs5520_set_pio_mode;
- hwif->set_dma_mode = &cs5520_set_dma_mode;
-
- if (hwif->dma_base == 0)
- return;
+static const struct ide_port_ops cs5520_port_ops = {
+ .set_pio_mode = cs5520_set_pio_mode,
+ .set_dma_mode = cs5520_set_dma_mode,
+};
- hwif->dma_host_set = &cs5520_dma_host_set;
-}
+static const struct ide_dma_ops cs5520_dma_ops = {
+ .dma_host_set = cs5520_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = ide_dma_start,
+ .dma_end = __ide_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
#define DECLARE_CS_DEV(name_str) \
{ \
.name = name_str, \
- .init_hwif = init_hwif_cs5520, \
+ .port_ops = &cs5520_port_ops, \
+ .dma_ops = &cs5520_dma_ops, \
.host_flags = IDE_HFLAG_ISA_PORTS | \
IDE_HFLAG_CS5520 | \
IDE_HFLAG_VDMA | \
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index 56a369c2a78..f5534c1ff34 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -228,26 +228,25 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
unsigned long basereg;
u32 d0_timings;
- hwif->set_pio_mode = &cs5530_set_pio_mode;
- hwif->set_dma_mode = &cs5530_set_dma_mode;
-
basereg = CS5530_BASEREG(hwif);
d0_timings = inl(basereg + 0);
if (CS5530_BAD_PIO(d0_timings))
outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 0);
if (CS5530_BAD_PIO(inl(basereg + 8)))
outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 8);
-
- if (hwif->dma_base == 0)
- return;
-
- hwif->udma_filter = cs5530_udma_filter;
}
+static const struct ide_port_ops cs5530_port_ops = {
+ .set_pio_mode = cs5530_set_pio_mode,
+ .set_dma_mode = cs5530_set_dma_mode,
+ .udma_filter = cs5530_udma_filter,
+};
+
static const struct ide_port_info cs5530_chipset __devinitdata = {
.name = "CS5530",
.init_chipset = init_chipset_cs5530,
.init_hwif = init_hwif_cs5530,
+ .port_ops = &cs5530_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE |
IDE_HFLAG_POST_SET_MODE,
.pio_mask = ATA_PIO4,
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index c9685f239c6..99fe91a191b 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -166,25 +166,15 @@ static u8 __devinit cs5535_cable_detect(ide_hwif_t *hwif)
return (bit & 1) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
}
-/****
- * init_hwif_cs5535 - Initialize one ide cannel
- * @hwif: Channel descriptor
- *
- * This gets invoked by the IDE driver once for each channel. It
- * performs channel-specific pre-initialization before drive probing.
- *
- */
-static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &cs5535_set_pio_mode;
- hwif->set_dma_mode = &cs5535_set_dma_mode;
-
- hwif->cable_detect = cs5535_cable_detect;
-}
+static const struct ide_port_ops cs5535_port_ops = {
+ .set_pio_mode = cs5535_set_pio_mode,
+ .set_dma_mode = cs5535_set_dma_mode,
+ .cable_detect = cs5535_cable_detect,
+};
static const struct ide_port_info cs5535_chipset __devinitdata = {
.name = "CS5535",
- .init_hwif = init_hwif_cs5535,
+ .port_ops = &cs5535_port_ops,
.host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE |
IDE_HFLAG_ABUSE_SET_DMA_MODE,
.pio_mask = ATA_PIO4,
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 08eab7e7f05..77cc22c2ad4 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -18,8 +18,6 @@
* hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA
* - this is my first linux driver, so there's probably a lot of room
* for optimizations and bug fixing, so feel free to do it.
- * - use idebus=xx parameter to set PCI bus speed - needed to calc
- * timings for PIO modes (default will be 40)
* - if using PIO mode it's a good idea to set the PIO mode and
* 32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda
* - I had some problems with my IBM DHEA with PIO modes < 2
@@ -136,7 +134,7 @@ static int calc_clk(int time, int bus_speed)
static void compute_clocks(u8 pio, pio_clocks_t *p_pclk)
{
int clk1, clk2;
- int bus_speed = system_bus_clock(); /* get speed of PCI bus */
+ int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock();
/* we don't check against CY82C693's min and max speed,
* so you can play with the idebus=xx parameter
@@ -382,15 +380,6 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c
return 0;
}
-/*
- * the init function - called for each ide channel once
- */
-static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &cy82c693_set_pio_mode;
- hwif->set_dma_mode = &cy82c693_set_dma_mode;
-}
-
static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
{
static ide_hwif_t *primary;
@@ -404,11 +393,16 @@ static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
}
}
+static const struct ide_port_ops cy82c693_port_ops = {
+ .set_pio_mode = cy82c693_set_pio_mode,
+ .set_dma_mode = cy82c693_set_dma_mode,
+};
+
static const struct ide_port_info cy82c693_chipset __devinitdata = {
.name = "CY82C693",
.init_chipset = init_chipset_cy82c693,
.init_iops = init_iops_cy82c693,
- .init_hwif = init_hwif_cy82c693,
+ .port_ops = &cy82c693_port_ops,
.chipset = ide_cy82c693,
.host_flags = IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
index 753b86fc663..b9e457996d0 100644
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -43,6 +43,10 @@ static const u8 setup[] = {
0x00, 0x00, 0x00, 0x00, 0xa4, 0x83, 0x02, 0x13,
};
+static const struct ide_port_ops delkin_cb_port_ops = {
+ .quirkproc = ide_undecoded_slave,
+};
+
static int __devinit
delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
@@ -83,14 +87,9 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
i = hwif->index;
- if (hwif->present)
- ide_unregister(i);
- else
- ide_init_port_data(hwif, i);
-
+ ide_init_port_data(hwif, i);
ide_init_port_hw(hwif, &hw);
- hwif->mmio = 1;
- hwif->quirkproc = &ide_undecoded_slave;
+ hwif->port_ops = &delkin_cb_port_ops;
idx[0] = i;
@@ -120,8 +119,7 @@ delkin_cb_remove (struct pci_dev *dev)
{
ide_hwif_t *hwif = pci_get_drvdata(dev);
- if (hwif)
- ide_unregister(hwif->index);
+ ide_unregister(hwif);
pci_release_regions(dev);
pci_disable_device(dev);
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index 9f2fc309400..84c36c11719 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -115,11 +115,10 @@ static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const cha
return dev->irq;
}
-static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &hpt34x_set_pio_mode;
- hwif->set_dma_mode = &hpt34x_set_mode;
-}
+static const struct ide_port_ops hpt34x_port_ops = {
+ .set_pio_mode = hpt34x_set_pio_mode,
+ .set_dma_mode = hpt34x_set_mode,
+};
#define IDE_HFLAGS_HPT34X \
(IDE_HFLAG_NO_ATAPI_DMA | \
@@ -131,16 +130,14 @@ static const struct ide_port_info hpt34x_chipsets[] __devinitdata = {
{ /* 0 */
.name = "HPT343",
.init_chipset = init_chipset_hpt34x,
- .init_hwif = init_hwif_hpt34x,
- .extra = 16,
+ .port_ops = &hpt34x_port_ops,
.host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_NON_BOOTABLE,
.pio_mask = ATA_PIO5,
},
{ /* 1 */
.name = "HPT345",
.init_chipset = init_chipset_hpt34x,
- .init_hwif = init_hwif_hpt34x,
- .extra = 16,
+ .port_ops = &hpt34x_port_ops,
.host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO5,
#ifdef CONFIG_HPT34X_AUTODMA
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index a4909067214..c929dadaaaf 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -760,7 +760,7 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
}
} else
outb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
- hwif->io_ports[IDE_CONTROL_OFFSET]);
+ hwif->io_ports.ctl_addr);
}
/*
@@ -776,7 +776,7 @@ static void hpt366_dma_lost_irq(ide_drive_t *drive)
pci_read_config_byte(dev, 0x52, &mcr3);
pci_read_config_byte(dev, 0x5a, &scr1);
printk("%s: (%s) mcr1=0x%02x, mcr3=0x%02x, scr1=0x%02x\n",
- drive->name, __FUNCTION__, mcr1, mcr3, scr1);
+ drive->name, __func__, mcr1, mcr3, scr1);
if (scr1 & 0x10)
pci_write_config_byte(dev, 0x5a, scr1 & ~0x10);
ide_dma_lost_irq(drive);
@@ -808,7 +808,7 @@ static void hpt370_irq_timeout(ide_drive_t *drive)
hpt370_clear_engine(drive);
}
-static void hpt370_ide_dma_start(ide_drive_t *drive)
+static void hpt370_dma_start(ide_drive_t *drive)
{
#ifdef HPT_RESET_STATE_ENGINE
hpt370_clear_engine(drive);
@@ -816,7 +816,7 @@ static void hpt370_ide_dma_start(ide_drive_t *drive)
ide_dma_start(drive);
}
-static int hpt370_ide_dma_end(ide_drive_t *drive)
+static int hpt370_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u8 dma_stat = inb(hwif->dma_status);
@@ -838,7 +838,7 @@ static void hpt370_dma_timeout(ide_drive_t *drive)
}
/* returns 1 if DMA IRQ issued, 0 otherwise */
-static int hpt374_ide_dma_test_irq(ide_drive_t *drive)
+static int hpt374_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -858,11 +858,11 @@ static int hpt374_ide_dma_test_irq(ide_drive_t *drive)
if (!drive->waiting_for_dma)
printk(KERN_WARNING "%s: (%s) called while not waiting\n",
- drive->name, __FUNCTION__);
+ drive->name, __func__);
return 0;
}
-static int hpt374_ide_dma_end(ide_drive_t *drive)
+static int hpt374_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -1271,17 +1271,6 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
/* Cache the channel's MISC. control registers' offset */
hwif->select_data = hwif->channel ? 0x54 : 0x50;
- hwif->set_pio_mode = &hpt3xx_set_pio_mode;
- hwif->set_dma_mode = &hpt3xx_set_mode;
-
- hwif->quirkproc = &hpt3xx_quirkproc;
- hwif->maskproc = &hpt3xx_maskproc;
-
- hwif->udma_filter = &hpt3xx_udma_filter;
- hwif->mdma_filter = &hpt3xx_mdma_filter;
-
- hwif->cable_detect = hpt3xx_cable_detect;
-
/*
* HPT3xxN chips have some complications:
*
@@ -1323,29 +1312,19 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
if (new_mcr != old_mcr)
pci_write_config_byte(dev, hwif->select_data + 1, new_mcr);
-
- if (hwif->dma_base == 0)
- return;
-
- if (chip_type >= HPT374) {
- hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq;
- hwif->ide_dma_end = &hpt374_ide_dma_end;
- } else if (chip_type >= HPT370) {
- hwif->dma_start = &hpt370_ide_dma_start;
- hwif->ide_dma_end = &hpt370_ide_dma_end;
- hwif->dma_timeout = &hpt370_dma_timeout;
- } else
- hwif->dma_lost_irq = &hpt366_dma_lost_irq;
}
-static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
+static int __devinit init_dma_hpt366(ide_hwif_t *hwif,
+ const struct ide_port_info *d)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
- u8 masterdma = 0, slavedma = 0;
- u8 dma_new = 0, dma_old = 0;
- unsigned long flags;
+ unsigned long flags, base = ide_pci_dma_base(hwif, d);
+ u8 dma_old, dma_new, masterdma = 0, slavedma = 0;
- dma_old = inb(dmabase + 2);
+ if (base == 0 || ide_pci_set_master(dev, d->name) < 0)
+ return -1;
+
+ dma_old = inb(base + 2);
local_irq_save(flags);
@@ -1356,11 +1335,21 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
if (masterdma & 0x30) dma_new |= 0x20;
if ( slavedma & 0x30) dma_new |= 0x40;
if (dma_new != dma_old)
- outb(dma_new, dmabase + 2);
+ outb(dma_new, base + 2);
local_irq_restore(flags);
- ide_setup_dma(hwif, dmabase);
+ printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n",
+ hwif->name, base, base + 7);
+
+ hwif->extra_base = base + (hwif->channel ? 8 : 16);
+
+ if (ide_allocate_dma_engine(hwif))
+ return -1;
+
+ ide_setup_dma(hwif, base);
+
+ return 0;
}
static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2)
@@ -1416,6 +1405,49 @@ static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
IDE_HFLAG_ABUSE_SET_DMA_MODE | \
IDE_HFLAG_OFF_BOARD)
+static const struct ide_port_ops hpt3xx_port_ops = {
+ .set_pio_mode = hpt3xx_set_pio_mode,
+ .set_dma_mode = hpt3xx_set_mode,
+ .quirkproc = hpt3xx_quirkproc,
+ .maskproc = hpt3xx_maskproc,
+ .mdma_filter = hpt3xx_mdma_filter,
+ .udma_filter = hpt3xx_udma_filter,
+ .cable_detect = hpt3xx_cable_detect,
+};
+
+static const struct ide_dma_ops hpt37x_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = ide_dma_start,
+ .dma_end = hpt374_dma_end,
+ .dma_test_irq = hpt374_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
+
+static const struct ide_dma_ops hpt370_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = hpt370_dma_start,
+ .dma_end = hpt370_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = hpt370_dma_timeout,
+};
+
+static const struct ide_dma_ops hpt36x_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = ide_dma_start,
+ .dma_end = __ide_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_lost_irq = hpt366_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
+
static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
{ /* 0 */
.name = "HPT36x",
@@ -1429,7 +1461,8 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
* Bit 4 is for the primary channel, bit 5 for the secondary.
*/
.enablebits = {{0x50,0x10,0x10}, {0x54,0x04,0x04}},
- .extra = 240,
+ .port_ops = &hpt3xx_port_ops,
+ .dma_ops = &hpt36x_dma_ops,
.host_flags = IDE_HFLAGS_HPT3XX | IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -1439,7 +1472,8 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .extra = 240,
+ .port_ops = &hpt3xx_port_ops,
+ .dma_ops = &hpt37x_dma_ops,
.host_flags = IDE_HFLAGS_HPT3XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -1449,7 +1483,8 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .extra = 240,
+ .port_ops = &hpt3xx_port_ops,
+ .dma_ops = &hpt37x_dma_ops,
.host_flags = IDE_HFLAGS_HPT3XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -1459,7 +1494,8 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .extra = 240,
+ .port_ops = &hpt3xx_port_ops,
+ .dma_ops = &hpt37x_dma_ops,
.host_flags = IDE_HFLAGS_HPT3XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -1470,7 +1506,8 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
.init_dma = init_dma_hpt366,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.udma_mask = ATA_UDMA5,
- .extra = 240,
+ .port_ops = &hpt3xx_port_ops,
+ .dma_ops = &hpt37x_dma_ops,
.host_flags = IDE_HFLAGS_HPT3XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -1480,7 +1517,8 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .extra = 240,
+ .port_ops = &hpt3xx_port_ops,
+ .dma_ops = &hpt37x_dma_ops,
.host_flags = IDE_HFLAGS_HPT3XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -1543,6 +1581,10 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
d.name = info->chip_name;
d.udma_mask = info->udma_mask;
+ /* fixup ->dma_ops for HPT370/HPT370A */
+ if (info == &hpt370 || info == &hpt370a)
+ d.dma_ops = &hpt370_dma_ops;
+
pci_set_drvdata(dev, (void *)info);
if (info == &hpt36x || info == &hpt374)
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index 5b5b0cc4b76..9053c8771e6 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -149,27 +149,17 @@ static u8 __devinit it8213_cable_detect(ide_hwif_t *hwif)
return (reg42h & 0x02) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
}
-/**
- * init_hwif_it8213 - set up hwif structs
- * @hwif: interface to set up
- *
- * We do the basic set up of the interface structure.
- */
-
-static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
-{
- hwif->set_dma_mode = &it8213_set_dma_mode;
- hwif->set_pio_mode = &it8213_set_pio_mode;
-
- hwif->cable_detect = it8213_cable_detect;
-}
-
+static const struct ide_port_ops it8213_port_ops = {
+ .set_pio_mode = it8213_set_pio_mode,
+ .set_dma_mode = it8213_set_dma_mode,
+ .cable_detect = it8213_cable_detect,
+};
#define DECLARE_ITE_DEV(name_str) \
{ \
.name = name_str, \
- .init_hwif = init_hwif_it8213, \
.enablebits = { {0x41, 0x80, 0x80} }, \
+ .port_ops = &it8213_port_ops, \
.host_flags = IDE_HFLAG_SINGLE, \
.pio_mask = ATA_PIO4, \
.swdma_mask = ATA_SWDMA2_ONLY, \
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index a38ec47423a..6ab04115286 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -418,7 +418,7 @@ static void it821x_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
/**
- * ata66_it821x - check for 80 pin cable
+ * it821x_cable_detect - cable detection
* @hwif: interface to check
*
* Check for the presence of an ATA66 capable cable on the
@@ -426,7 +426,7 @@ static void it821x_set_dma_mode(ide_drive_t *drive, const u8 speed)
* the needed logic onboard.
*/
-static u8 __devinit ata66_it821x(ide_hwif_t *hwif)
+static u8 __devinit it821x_cable_detect(ide_hwif_t *hwif)
{
/* The reference driver also only does disk side */
return ATA_CBL_PATA80;
@@ -511,6 +511,11 @@ static void __devinit it821x_quirkproc(ide_drive_t *drive)
}
+static struct ide_dma_ops it821x_pass_through_dma_ops = {
+ .dma_start = it821x_dma_start,
+ .dma_end = it821x_dma_end,
+};
+
/**
* init_hwif_it821x - set up hwif structs
* @hwif: interface to set up
@@ -527,8 +532,6 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
struct it821x_dev *idev = itdevs[hwif->channel];
u8 conf;
- hwif->quirkproc = &it821x_quirkproc;
-
ide_set_hwifdata(hwif, idev);
pci_read_config_byte(dev, 0x50, &conf);
@@ -563,17 +566,11 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
}
if (idev->smart == 0) {
- hwif->set_pio_mode = &it821x_set_pio_mode;
- hwif->set_dma_mode = &it821x_set_dma_mode;
-
/* MWDMA/PIO clock switching for pass through mode */
- hwif->dma_start = &it821x_dma_start;
- hwif->ide_dma_end = &it821x_dma_end;
+ hwif->dma_ops = &it821x_pass_through_dma_ops;
} else
hwif->host_flags |= IDE_HFLAG_NO_SET_MODE;
- hwif->cable_detect = ata66_it821x;
-
if (hwif->dma_base == 0)
return;
@@ -613,12 +610,20 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha
return 0;
}
+static const struct ide_port_ops it821x_port_ops = {
+ /* it821x_set_{pio,dma}_mode() are only used in pass-through mode */
+ .set_pio_mode = it821x_set_pio_mode,
+ .set_dma_mode = it821x_set_dma_mode,
+ .quirkproc = it821x_quirkproc,
+ .cable_detect = it821x_cable_detect,
+};
#define DECLARE_ITE_DEV(name_str) \
{ \
.name = name_str, \
.init_chipset = init_chipset_it821x, \
.init_hwif = init_hwif_it821x, \
+ .port_ops = &it821x_port_ops, \
.pio_mask = ATA_PIO4, \
}
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
index 673f7dc8ba6..96ef7394f28 100644
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -19,13 +19,13 @@ typedef enum {
} port_type;
/**
- * ata66_jmicron - Cable check
+ * jmicron_cable_detect - cable detection
* @hwif: IDE port
*
* Returns the cable type.
*/
-static u8 __devinit ata66_jmicron(ide_hwif_t *hwif)
+static u8 __devinit jmicron_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *pdev = to_pci_dev(hwif->dev);
@@ -95,25 +95,16 @@ static void jmicron_set_dma_mode(ide_drive_t *drive, const u8 mode)
{
}
-/**
- * init_hwif_jmicron - set up hwif structs
- * @hwif: interface to set up
- *
- * Minimal set up is required for the Jmicron hardware.
- */
-
-static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &jmicron_set_pio_mode;
- hwif->set_dma_mode = &jmicron_set_dma_mode;
-
- hwif->cable_detect = ata66_jmicron;
-}
+static const struct ide_port_ops jmicron_port_ops = {
+ .set_pio_mode = jmicron_set_pio_mode,
+ .set_dma_mode = jmicron_set_dma_mode,
+ .cable_detect = jmicron_cable_detect,
+};
static const struct ide_port_info jmicron_chipset __devinitdata = {
.name = "JMB",
- .init_hwif = init_hwif_jmicron,
.enablebits = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } },
+ .port_ops = &jmicron_port_ops,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index 3015d6916d4..fec4955f449 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -63,6 +63,48 @@ static u8 superio_ide_inb (unsigned long port)
return inb(port);
}
+static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
+{
+ struct ide_io_ports *io_ports = &drive->hwif->io_ports;
+ struct ide_taskfile *tf = &task->tf;
+
+ if (task->tf_flags & IDE_TFLAG_IN_DATA) {
+ u16 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 */
+ outb(drive->ctl & ~0x80, io_ports->ctl_addr);
+
+ if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ tf->nsect = inb(io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ tf->lbal = inb(io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ tf->lbam = inb(io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ tf->lbah = inb(io_ports->lbah_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ tf->device = superio_ide_inb(io_ports->device_addr);
+
+ if (task->tf_flags & IDE_TFLAG_LBA48) {
+ outb(drive->ctl | 0x80, io_ports->ctl_addr);
+
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+ tf->hob_feature = inb(io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = inb(io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = inb(io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = inb(io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = inb(io_ports->lbah_addr);
+ }
+}
+
static void __devinit superio_ide_init_iops (struct hwif_s *hwif)
{
struct pci_dev *pdev = to_pci_dev(hwif->dev);
@@ -72,14 +114,16 @@ static void __devinit superio_ide_init_iops (struct hwif_s *hwif)
base = pci_resource_start(pdev, port * 2) & ~3;
dmabase = pci_resource_start(pdev, 4) & ~3;
- superio_ide_status[port] = base + IDE_STATUS_OFFSET;
- superio_ide_select[port] = base + IDE_SELECT_OFFSET;
+ superio_ide_status[port] = base + 7;
+ superio_ide_select[port] = base + 6;
superio_ide_dma_status[port] = dmabase + (!port ? 2 : 0xa);
/* Clear error/interrupt, enable dma */
tmp = superio_ide_inb(superio_ide_dma_status[port]);
outb(tmp | 0x66, superio_ide_dma_status[port]);
+ hwif->tf_read = superio_tf_read;
+
/* We need to override inb to workaround a SuperIO errata */
hwif->INB = superio_ide_inb;
}
@@ -150,7 +194,7 @@ static void ns87415_selectproc (ide_drive_t *drive)
ns87415_prepare_drive (drive, drive->using_dma);
}
-static int ns87415_ide_dma_end (ide_drive_t *drive)
+static int ns87415_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u8 dma_stat = 0, dma_cmd = 0;
@@ -170,7 +214,7 @@ static int ns87415_ide_dma_end (ide_drive_t *drive)
return (dma_stat & 7) != 4;
}
-static int ns87415_ide_dma_setup(ide_drive_t *drive)
+static int ns87415_dma_setup(ide_drive_t *drive)
{
/* select DMA xfer */
ns87415_prepare_drive(drive, 1);
@@ -195,8 +239,6 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
u8 stat;
#endif
- hwif->selectproc = &ns87415_selectproc;
-
/*
* We cannot probe for IRQ: both ports share common IRQ on INTA.
* Also, leave IRQ masked during drive probing, to prevent infinite
@@ -233,12 +275,12 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
* SELECT_DRIVE() properly during first ide_probe_port().
*/
timeout = 10000;
- outb(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
+ outb(12, hwif->io_ports.ctl_addr);
udelay(10);
- outb(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
+ outb(8, hwif->io_ports.ctl_addr);
do {
udelay(50);
- stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+ stat = hwif->INB(hwif->io_ports.status_addr);
if (stat == 0xff)
break;
} while ((stat & BUSY_STAT) && --timeout);
@@ -246,7 +288,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
}
if (!using_inta)
- hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]);
+ hwif->irq = ide_default_irq(hwif->io_ports.data_addr);
else if (!hwif->irq && hwif->mate && hwif->mate->irq)
hwif->irq = hwif->mate->irq; /* share IRQ with mate */
@@ -254,16 +296,31 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
return;
outb(0x60, hwif->dma_status);
- hwif->dma_setup = &ns87415_ide_dma_setup;
- hwif->ide_dma_end = &ns87415_ide_dma_end;
}
+static const struct ide_port_ops ns87415_port_ops = {
+ .selectproc = ns87415_selectproc,
+};
+
+static const struct ide_dma_ops ns87415_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ns87415_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = ide_dma_start,
+ .dma_end = ns87415_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
+
static const struct ide_port_info ns87415_chipset __devinitdata = {
.name = "NS87415",
#ifdef CONFIG_SUPERIO
.init_iops = init_iops_ns87415,
#endif
.init_hwif = init_hwif_ns87415,
+ .port_ops = &ns87415_port_ops,
+ .dma_ops = &ns87415_dma_ops,
.host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_NO_ATAPI_DMA,
};
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index 88a4dd94eee..6e99080497b 100644
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -53,8 +53,7 @@
* If you then set the second drive to another PIO, the old value
* (automatically selected) will be overrided by yours.
* There is a 25/33MHz switch in configuration
- * register, but driver is written for use at any frequency which get
- * (use idebus=xx to select PCI bus speed).
+ * register, but driver is written for use at any frequency.
*
* Version 0.1, Nov 8, 1996
* by Jaromir Koutek, for 2.1.8.
@@ -210,7 +209,7 @@ static void compute_clocks(int pio, pio_clocks_t *clks)
{
if (pio != PIO_NOT_EXIST) {
int adr_setup, data_pls;
- int bus_speed = system_bus_clock();
+ int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock();
adr_setup = ide_pio_timings[pio].setup_time;
data_pls = ide_pio_timings[pio].active_time;
@@ -280,7 +279,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
spin_lock_irqsave(&opti621_lock, flags);
- reg_base = hwif->io_ports[IDE_DATA_OFFSET];
+ reg_base = hwif->io_ports.data_addr;
/* allow Register-B */
outb(0xc0, reg_base + CNTRL_REG);
@@ -326,28 +325,24 @@ static void __devinit opti621_port_init_devs(ide_hwif_t *hwif)
hwif->drives[1].drive_data = PIO_DONT_KNOW;
}
-/*
- * init_hwif_opti621() is called once for each hwif found at boot.
- */
-static void __devinit init_hwif_opti621(ide_hwif_t *hwif)
-{
- hwif->port_init_devs = opti621_port_init_devs;
- hwif->set_pio_mode = &opti621_set_pio_mode;
-}
+static const struct ide_port_ops opti621_port_ops = {
+ .port_init_devs = opti621_port_init_devs,
+ .set_pio_mode = opti621_set_pio_mode,
+};
static const struct ide_port_info opti621_chipsets[] __devinitdata = {
{ /* 0 */
.name = "OPTI621",
- .init_hwif = init_hwif_opti621,
.enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} },
+ .port_ops = &opti621_port_ops,
.host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
.pio_mask = ATA_PIO3,
.swdma_mask = ATA_SWDMA2,
.mwdma_mask = ATA_MWDMA2,
}, { /* 1 */
.name = "OPTI621X",
- .init_hwif = init_hwif_opti621,
.enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} },
+ .port_ops = &opti621_port_ops,
.host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
.pio_mask = ATA_PIO3,
.swdma_mask = ATA_SWDMA2,
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 1c8cb7797a4..070df8ab3b2 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -34,7 +34,7 @@
#undef DEBUG
#ifdef DEBUG
-#define DBG(fmt, args...) printk("%s: " fmt, __FUNCTION__, ## args)
+#define DBG(fmt, args...) printk("%s: " fmt, __func__, ## args)
#else
#define DBG(fmt, args...)
#endif
@@ -83,8 +83,8 @@ static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index)
{
u8 value;
- outb(index, hwif->dma_vendor1);
- value = inb(hwif->dma_vendor3);
+ outb(index, hwif->dma_base + 1);
+ value = inb(hwif->dma_base + 3);
DBG("index[%02X] value[%02X]\n", index, value);
return value;
@@ -97,8 +97,8 @@ static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index)
*/
static void set_indexed_reg(ide_hwif_t *hwif, u8 index, u8 value)
{
- outb(index, hwif->dma_vendor1);
- outb(value, hwif->dma_vendor3);
+ outb(index, hwif->dma_base + 1);
+ outb(value, hwif->dma_base + 3);
DBG("index[%02X] value[%02X]\n", index, value);
}
@@ -442,17 +442,6 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha
return dev->irq;
}
-static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &pdcnew_set_pio_mode;
- hwif->set_dma_mode = &pdcnew_set_dma_mode;
-
- hwif->quirkproc = &pdcnew_quirkproc;
- hwif->resetproc = &pdcnew_reset;
-
- hwif->cable_detect = pdcnew_cable_detect;
-}
-
static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
{
struct pci_dev *dev2;
@@ -476,11 +465,19 @@ static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
return NULL;
}
+static const struct ide_port_ops pdcnew_port_ops = {
+ .set_pio_mode = pdcnew_set_pio_mode,
+ .set_dma_mode = pdcnew_set_dma_mode,
+ .quirkproc = pdcnew_quirkproc,
+ .resetproc = pdcnew_reset,
+ .cable_detect = pdcnew_cable_detect,
+};
+
#define DECLARE_PDCNEW_DEV(name_str, udma) \
{ \
.name = name_str, \
.init_chipset = init_chipset_pdcnew, \
- .init_hwif = init_hwif_pdc202new, \
+ .port_ops = &pdcnew_port_ops, \
.host_flags = IDE_HFLAG_POST_SET_MODE | \
IDE_HFLAG_ERROR_STOPS_FIFO | \
IDE_HFLAG_OFF_BOARD, \
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index 150422ec3cf..fca89eda5c0 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -115,7 +115,7 @@ static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
pdc202xx_set_mode(drive, XFER_PIO_0 + pio);
}
-static u8 __devinit pdc2026x_old_cable_detect(ide_hwif_t *hwif)
+static u8 __devinit pdc2026x_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
u16 CIS, mask = hwif->channel ? (1 << 11) : (1 << 10);
@@ -163,7 +163,7 @@ static void pdc202xx_quirkproc(ide_drive_t *drive)
drive->quirk_list = 0;
}
-static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
+static void pdc202xx_dma_start(ide_drive_t *drive)
{
if (drive->current_speed > XFER_UDMA_2)
pdc_old_enable_66MHz_clock(drive->hwif);
@@ -185,7 +185,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
ide_dma_start(drive);
}
-static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
+static int pdc202xx_dma_end(ide_drive_t *drive)
{
if (drive->media != ide_disk || drive->addressing == 1) {
ide_hwif_t *hwif = HWIF(drive);
@@ -202,7 +202,7 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
return __ide_dma_end(drive);
}
-static int pdc202xx_old_ide_dma_test_irq(ide_drive_t *drive)
+static int pdc202xx_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long high_16 = hwif->extra_base - 16;
@@ -226,26 +226,6 @@ somebody_else:
return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
}
-static void pdc202xx_dma_lost_irq(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = HWIF(drive);
-
- if (hwif->resetproc != NULL)
- hwif->resetproc(drive);
-
- ide_dma_lost_irq(drive);
-}
-
-static void pdc202xx_dma_timeout(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = HWIF(drive);
-
- if (hwif->resetproc != NULL)
- hwif->resetproc(drive);
-
- ide_dma_timeout(drive);
-}
-
static void pdc202xx_reset_host (ide_hwif_t *hwif)
{
unsigned long high_16 = hwif->extra_base - 16;
@@ -271,68 +251,46 @@ static void pdc202xx_reset (ide_drive_t *drive)
ide_set_max_pio(drive);
}
-static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev,
- const char *name)
+static void pdc202xx_dma_lost_irq(ide_drive_t *drive)
{
- return dev->irq;
+ pdc202xx_reset(drive);
+ ide_dma_lost_irq(drive);
}
-static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
+static void pdc202xx_dma_timeout(ide_drive_t *drive)
{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
-
- hwif->set_pio_mode = &pdc202xx_set_pio_mode;
- hwif->set_dma_mode = &pdc202xx_set_mode;
-
- hwif->quirkproc = &pdc202xx_quirkproc;
-
- if (dev->device != PCI_DEVICE_ID_PROMISE_20246) {
- hwif->resetproc = &pdc202xx_reset;
-
- hwif->cable_detect = pdc2026x_old_cable_detect;
- }
-
- if (hwif->dma_base == 0)
- return;
-
- hwif->dma_lost_irq = &pdc202xx_dma_lost_irq;
- hwif->dma_timeout = &pdc202xx_dma_timeout;
-
- if (dev->device != PCI_DEVICE_ID_PROMISE_20246) {
- hwif->dma_start = &pdc202xx_old_ide_dma_start;
- hwif->ide_dma_end = &pdc202xx_old_ide_dma_end;
- }
- hwif->ide_dma_test_irq = &pdc202xx_old_ide_dma_test_irq;
+ pdc202xx_reset(drive);
+ ide_dma_timeout(drive);
}
-static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
+static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev,
+ const char *name)
{
+ unsigned long dmabase = pci_resource_start(dev, 4);
u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0;
- if (hwif->channel) {
- ide_setup_dma(hwif, dmabase);
- return;
- }
+ if (dmabase == 0)
+ goto out;
udma_speed_flag = inb(dmabase | 0x1f);
primary_mode = inb(dmabase | 0x1a);
secondary_mode = inb(dmabase | 0x1b);
printk(KERN_INFO "%s: (U)DMA Burst Bit %sABLED " \
"Primary %s Mode " \
- "Secondary %s Mode.\n", hwif->cds->name,
+ "Secondary %s Mode.\n", pci_name(dev),
(udma_speed_flag & 1) ? "EN" : "DIS",
(primary_mode & 1) ? "MASTER" : "PCI",
(secondary_mode & 1) ? "MASTER" : "PCI" );
if (!(udma_speed_flag & 1)) {
printk(KERN_INFO "%s: FORCING BURST BIT 0x%02x->0x%02x ",
- hwif->cds->name, udma_speed_flag,
+ pci_name(dev), udma_speed_flag,
(udma_speed_flag|1));
outb(udma_speed_flag | 1, dmabase | 0x1f);
printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN");
}
-
- ide_setup_dma(hwif, dmabase);
+out:
+ return dev->irq;
}
static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
@@ -357,13 +315,48 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
IDE_HFLAG_ABUSE_SET_DMA_MODE | \
IDE_HFLAG_OFF_BOARD)
+static const struct ide_port_ops pdc20246_port_ops = {
+ .set_pio_mode = pdc202xx_set_pio_mode,
+ .set_dma_mode = pdc202xx_set_mode,
+ .quirkproc = pdc202xx_quirkproc,
+};
+
+static const struct ide_port_ops pdc2026x_port_ops = {
+ .set_pio_mode = pdc202xx_set_pio_mode,
+ .set_dma_mode = pdc202xx_set_mode,
+ .quirkproc = pdc202xx_quirkproc,
+ .resetproc = pdc202xx_reset,
+ .cable_detect = pdc2026x_cable_detect,
+};
+
+static const struct ide_dma_ops pdc20246_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = ide_dma_start,
+ .dma_end = __ide_dma_end,
+ .dma_test_irq = pdc202xx_dma_test_irq,
+ .dma_lost_irq = pdc202xx_dma_lost_irq,
+ .dma_timeout = pdc202xx_dma_timeout,
+};
+
+static const struct ide_dma_ops pdc2026x_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = pdc202xx_dma_start,
+ .dma_end = pdc202xx_dma_end,
+ .dma_test_irq = pdc202xx_dma_test_irq,
+ .dma_lost_irq = pdc202xx_dma_lost_irq,
+ .dma_timeout = pdc202xx_dma_timeout,
+};
+
#define DECLARE_PDC2026X_DEV(name_str, udma, extra_flags) \
{ \
.name = name_str, \
.init_chipset = init_chipset_pdc202xx, \
- .init_hwif = init_hwif_pdc202xx, \
- .init_dma = init_dma_pdc202xx, \
- .extra = 48, \
+ .port_ops = &pdc2026x_port_ops, \
+ .dma_ops = &pdc2026x_dma_ops, \
.host_flags = IDE_HFLAGS_PDC202XX | extra_flags, \
.pio_mask = ATA_PIO4, \
.mwdma_mask = ATA_MWDMA2, \
@@ -374,9 +367,8 @@ static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = {
{ /* 0 */
.name = "PDC20246",
.init_chipset = init_chipset_pdc202xx,
- .init_hwif = init_hwif_pdc202xx,
- .init_dma = init_dma_pdc202xx,
- .extra = 16,
+ .port_ops = &pdc20246_port_ops,
+ .dma_ops = &pdc20246_dma_ops,
.host_flags = IDE_HFLAGS_PDC202XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index 89d74ffdb20..f04738d14a6 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -250,6 +250,7 @@ static const struct ich_laptop ich_laptop[] = {
{ 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
{ 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */
{ 0x24CA, 0x1025, 0x0061 }, /* ICH4 on Acer Aspire 2023WLMi */
+ { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
/* end marker */
{ 0, }
};
@@ -285,11 +286,6 @@ static u8 __devinit piix_cable_detect(ide_hwif_t *hwif)
static void __devinit init_hwif_piix(ide_hwif_t *hwif)
{
- hwif->set_pio_mode = &piix_set_pio_mode;
- hwif->set_dma_mode = &piix_set_dma_mode;
-
- hwif->cable_detect = piix_cable_detect;
-
if (!hwif->dma_base)
return;
@@ -306,6 +302,12 @@ static void __devinit init_hwif_ich(ide_hwif_t *hwif)
hwif->ide_dma_clear_irq = &piix_dma_clear_irq;
}
+static const struct ide_port_ops piix_port_ops = {
+ .set_pio_mode = piix_set_pio_mode,
+ .set_dma_mode = piix_set_dma_mode,
+ .cable_detect = piix_cable_detect,
+};
+
#ifndef CONFIG_IA64
#define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS
#else
@@ -317,6 +319,7 @@ static void __devinit init_hwif_ich(ide_hwif_t *hwif)
.name = name_str, \
.init_hwif = init_hwif_piix, \
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
+ .port_ops = &piix_port_ops, \
.host_flags = IDE_HFLAGS_PIIX, \
.pio_mask = ATA_PIO4, \
.swdma_mask = ATA_SWDMA2_ONLY, \
@@ -330,6 +333,7 @@ static void __devinit init_hwif_ich(ide_hwif_t *hwif)
.init_chipset = init_chipset_ich, \
.init_hwif = init_hwif_ich, \
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
+ .port_ops = &piix_port_ops, \
.host_flags = IDE_HFLAGS_PIIX, \
.pio_mask = ATA_PIO4, \
.swdma_mask = ATA_SWDMA2_ONLY, \
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index 44985c8f36e..14c787b5d95 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -165,7 +165,7 @@ static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode)
*
* returns 1 on error, 0 otherwise
*/
-static int sc1200_ide_dma_end (ide_drive_t *drive)
+static int sc1200_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long dma_base = hwif->dma_base;
@@ -214,7 +214,7 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
printk("SC1200: %s: changing (U)DMA mode\n", drive->name);
ide_dma_off_quietly(drive);
if (ide_set_dma_mode(drive, mode) == 0 && drive->using_dma)
- hwif->dma_host_set(drive, 1);
+ hwif->dma_ops->dma_host_set(drive, 1);
return;
}
@@ -286,25 +286,27 @@ static int sc1200_resume (struct pci_dev *dev)
}
#endif
-/*
- * This gets invoked by the IDE driver once for each channel,
- * and performs channel-specific pre-initialization before drive probing.
- */
-static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &sc1200_set_pio_mode;
- hwif->set_dma_mode = &sc1200_set_dma_mode;
-
- if (hwif->dma_base == 0)
- return;
+static const struct ide_port_ops sc1200_port_ops = {
+ .set_pio_mode = sc1200_set_pio_mode,
+ .set_dma_mode = sc1200_set_dma_mode,
+ .udma_filter = sc1200_udma_filter,
+};
- hwif->udma_filter = sc1200_udma_filter;
- hwif->ide_dma_end = &sc1200_ide_dma_end;
-}
+static const struct ide_dma_ops sc1200_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = ide_dma_start,
+ .dma_end = sc1200_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
static const struct ide_port_info sc1200_chipset __devinitdata = {
.name = "SC1200",
- .init_hwif = init_hwif_sc1200,
+ .port_ops = &sc1200_port_ops,
+ .dma_ops = &sc1200_dma_ops,
.host_flags = IDE_HFLAG_SERIALIZE |
IDE_HFLAG_POST_SET_MODE |
IDE_HFLAG_ABUSE_DMA_MODES,
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index 52145796f12..910fb00deb7 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -126,12 +126,6 @@ static u8 scc_ide_inb(unsigned long port)
return (u8)data;
}
-static u16 scc_ide_inw(unsigned long port)
-{
- u32 data = in_be32((void*)port);
- return (u16)data;
-}
-
static void scc_ide_insw(unsigned long port, void *addr, u32 count)
{
u16 *ptr = (u16 *)addr;
@@ -154,11 +148,6 @@ static void scc_ide_outb(u8 addr, unsigned long port)
out_be32((void*)port, addr);
}
-static void scc_ide_outw(u16 addr, unsigned long port)
-{
- out_be32((void*)port, addr);
-}
-
static void
scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port)
{
@@ -271,6 +260,20 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
out_be32((void __iomem *)udenvt_port, reg);
}
+static void scc_dma_host_set(ide_drive_t *drive, int on)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 unit = (drive->select.b.unit & 0x01);
+ u8 dma_stat = scc_ide_inb(hwif->dma_status);
+
+ if (on)
+ dma_stat |= (1 << (5 + unit));
+ else
+ dma_stat &= ~(1 << (5 + unit));
+
+ scc_ide_outb(dma_stat, hwif->dma_status);
+}
+
/**
* scc_ide_dma_setup - begin a DMA phase
* @drive: target device
@@ -301,7 +304,7 @@ static int scc_dma_setup(ide_drive_t *drive)
}
/* PRD table */
- out_be32((void __iomem *)hwif->dma_prdtable, hwif->dmatable_dma);
+ out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma);
/* specify r/w */
out_be32((void __iomem *)hwif->dma_command, reading);
@@ -315,16 +318,48 @@ static int scc_dma_setup(ide_drive_t *drive)
return 0;
}
+static void scc_dma_start(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 dma_cmd = scc_ide_inb(hwif->dma_command);
+
+ /* start DMA */
+ scc_ide_outb(dma_cmd | 1, hwif->dma_command);
+ hwif->dma = 1;
+ wmb();
+}
+
+static int __scc_dma_end(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 dma_stat, dma_cmd;
+
+ drive->waiting_for_dma = 0;
+ /* get DMA command mode */
+ dma_cmd = scc_ide_inb(hwif->dma_command);
+ /* stop DMA */
+ scc_ide_outb(dma_cmd & ~1, hwif->dma_command);
+ /* get DMA status */
+ dma_stat = scc_ide_inb(hwif->dma_status);
+ /* clear the INTR & ERROR bits */
+ scc_ide_outb(dma_stat | 6, hwif->dma_status);
+ /* purge DMA mappings */
+ ide_destroy_dmatable(drive);
+ /* verify good DMA status */
+ hwif->dma = 0;
+ wmb();
+ return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
+}
/**
- * scc_ide_dma_end - Stop DMA
+ * scc_dma_end - Stop DMA
* @drive: IDE drive
*
* Check and clear INT Status register.
- * Then call __ide_dma_end().
+ * Then call __scc_dma_end().
*/
-static int scc_ide_dma_end(ide_drive_t * drive)
+static int scc_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long intsts_port = hwif->dma_base + 0x014;
@@ -334,7 +369,7 @@ static int scc_ide_dma_end(ide_drive_t * drive)
/* errata A308 workaround: Step5 (check data loss) */
/* We don't check non ide_disk because it is limited to UDMA4 */
- if (!(in_be32((void __iomem *)hwif->io_ports[IDE_ALTSTATUS_OFFSET])
+ if (!(in_be32((void __iomem *)hwif->io_ports.ctl_addr)
& ERR_STAT) &&
drive->media == ide_disk && drive->current_speed > XFER_UDMA_4) {
reg = in_be32((void __iomem *)intsts_port);
@@ -425,7 +460,7 @@ static int scc_ide_dma_end(ide_drive_t * drive)
break;
}
- dma_stat = __ide_dma_end(drive);
+ dma_stat = __scc_dma_end(drive);
if (data_loss)
dma_stat |= 2; /* emulate DMA error (to retry command) */
return dma_stat;
@@ -438,7 +473,7 @@ static int scc_dma_test_irq(ide_drive_t *drive)
u32 int_stat = in_be32((void __iomem *)hwif->dma_base + 0x014);
/* SCC errata A252,A308 workaround: Step4 */
- if ((in_be32((void __iomem *)hwif->io_ports[IDE_ALTSTATUS_OFFSET])
+ if ((in_be32((void __iomem *)hwif->io_ports.ctl_addr)
& ERR_STAT) &&
(int_stat & INTSTS_INTRQ))
return 1;
@@ -449,7 +484,7 @@ static int scc_dma_test_irq(ide_drive_t *drive)
if (!drive->waiting_for_dma)
printk(KERN_WARNING "%s: (%s) called while not waiting\n",
- drive->name, __FUNCTION__);
+ drive->name, __func__);
return 0;
}
@@ -483,7 +518,7 @@ static int setup_mmio_scc (struct pci_dev *dev, const char *name)
unsigned long dma_size = pci_resource_len(dev, 1);
void __iomem *ctl_addr;
void __iomem *dma_addr;
- int i;
+ int i, ret;
for (i = 0; i < MAX_HWIFS; i++) {
if (scc_ports[i].ctl == 0)
@@ -492,21 +527,17 @@ static int setup_mmio_scc (struct pci_dev *dev, const char *name)
if (i >= MAX_HWIFS)
return -ENOMEM;
- if (!request_mem_region(ctl_base, ctl_size, name)) {
- printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME);
- goto fail_0;
- }
-
- if (!request_mem_region(dma_base, dma_size, name)) {
- printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME);
- goto fail_1;
+ ret = pci_request_selected_regions(dev, (1 << 2) - 1, name);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: can't reserve resources\n", name);
+ return ret;
}
if ((ctl_addr = ioremap(ctl_base, ctl_size)) == NULL)
- goto fail_2;
+ goto fail_0;
if ((dma_addr = ioremap(dma_base, dma_size)) == NULL)
- goto fail_3;
+ goto fail_1;
pci_set_master(dev);
scc_ports[i].ctl = (unsigned long)ctl_addr;
@@ -515,12 +546,8 @@ static int setup_mmio_scc (struct pci_dev *dev, const char *name)
return 1;
- fail_3:
- iounmap(ctl_addr);
- fail_2:
- release_mem_region(dma_base, dma_size);
fail_1:
- release_mem_region(ctl_base, ctl_size);
+ iounmap(ctl_addr);
fail_0:
return -ENOMEM;
}
@@ -542,14 +569,13 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev,
}
memset(&hw, 0, sizeof(hw));
- for (i = IDE_DATA_OFFSET; i <= IDE_CONTROL_OFFSET; i++)
- hw.io_ports[i] = ports->dma + 0x20 + i * 4;
+ for (i = 0; i <= 8; i++)
+ hw.io_ports_array[i] = ports->dma + 0x20 + i * 4;
hw.irq = dev->irq;
hw.dev = &dev->dev;
hw.chipset = ide_pci;
ide_init_port_hw(hwif, &hw);
hwif->dev = &dev->dev;
- hwif->cds = d;
idx[0] = hwif->index;
@@ -627,6 +653,122 @@ static int __devinit init_setup_scc(struct pci_dev *dev,
return rc;
}
+static void scc_tf_load(ide_drive_t *drive, ide_task_t *task)
+{
+ struct ide_io_ports *io_ports = &drive->hwif->io_ports;
+ struct ide_taskfile *tf = &task->tf;
+ u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+
+ if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ HIHI = 0xFF;
+
+ ide_set_irq(drive, 1);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_DATA)
+ out_be32((void *)io_ports->data_addr,
+ (tf->hob_data << 8) | tf->data);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ scc_ide_outb(tf->hob_feature, io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ scc_ide_outb(tf->feature, io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ scc_ide_outb(tf->nsect, io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ scc_ide_outb(tf->lbal, io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ scc_ide_outb(tf->lbam, io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ scc_ide_outb(tf->lbah, io_ports->lbah_addr);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ scc_ide_outb((tf->device & HIHI) | drive->select.all,
+ io_ports->device_addr);
+}
+
+static void scc_tf_read(ide_drive_t *drive, ide_task_t *task)
+{
+ struct ide_io_ports *io_ports = &drive->hwif->io_ports;
+ struct ide_taskfile *tf = &task->tf;
+
+ if (task->tf_flags & IDE_TFLAG_IN_DATA) {
+ u16 data = (u16)in_be32((void *)io_ports->data_addr);
+
+ tf->data = data & 0xff;
+ tf->hob_data = (data >> 8) & 0xff;
+ }
+
+ /* be sure we're looking at the low order bits */
+ scc_ide_outb(drive->ctl & ~0x80, io_ports->ctl_addr);
+
+ if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ tf->nsect = scc_ide_inb(io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ tf->lbal = scc_ide_inb(io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ tf->lbam = scc_ide_inb(io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ tf->lbah = scc_ide_inb(io_ports->lbah_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ tf->device = scc_ide_inb(io_ports->device_addr);
+
+ if (task->tf_flags & IDE_TFLAG_LBA48) {
+ scc_ide_outb(drive->ctl | 0x80, io_ports->ctl_addr);
+
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+ tf->hob_feature = scc_ide_inb(io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr);
+ }
+}
+
+static void scc_input_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
+{
+ unsigned long data_addr = drive->hwif->io_ports.data_addr;
+
+ len++;
+
+ if (drive->io_32bit) {
+ scc_ide_insl(data_addr, buf, len / 4);
+
+ if ((len & 3) >= 2)
+ scc_ide_insw(data_addr, (u8 *)buf + (len & ~3), 1);
+ } else
+ scc_ide_insw(data_addr, buf, len / 2);
+}
+
+static void scc_output_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
+{
+ unsigned long data_addr = drive->hwif->io_ports.data_addr;
+
+ len++;
+
+ if (drive->io_32bit) {
+ scc_ide_outsl(data_addr, buf, len / 4);
+
+ if ((len & 3) >= 2)
+ scc_ide_outsw(data_addr, (u8 *)buf + (len & ~3), 1);
+ } else
+ scc_ide_outsw(data_addr, buf, len / 2);
+}
+
/**
* init_mmio_iops_scc - set up the iops for MMIO
* @hwif: interface to set up
@@ -641,15 +783,15 @@ static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif)
ide_set_hwifdata(hwif, ports);
+ hwif->tf_load = scc_tf_load;
+ hwif->tf_read = scc_tf_read;
+
+ hwif->input_data = scc_input_data;
+ hwif->output_data = scc_output_data;
+
hwif->INB = scc_ide_inb;
- hwif->INW = scc_ide_inw;
- hwif->INSW = scc_ide_insw;
- hwif->INSL = scc_ide_insl;
hwif->OUTB = scc_ide_outb;
hwif->OUTBSYNC = scc_ide_outbsync;
- hwif->OUTW = scc_ide_outw;
- hwif->OUTSW = scc_ide_outsw;
- hwif->OUTSL = scc_ide_outsl;
hwif->dma_base = dma_base;
hwif->config_data = ports->ctl;
@@ -696,31 +838,41 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
hwif->dma_command = hwif->dma_base;
hwif->dma_status = hwif->dma_base + 0x04;
- hwif->dma_prdtable = hwif->dma_base + 0x08;
/* PTERADD */
out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma);
- hwif->dma_setup = scc_dma_setup;
- hwif->ide_dma_end = scc_ide_dma_end;
- hwif->set_pio_mode = scc_set_pio_mode;
- hwif->set_dma_mode = scc_set_dma_mode;
- hwif->ide_dma_test_irq = scc_dma_test_irq;
- hwif->udma_filter = scc_udma_filter;
-
if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN)
hwif->ultra_mask = ATA_UDMA6; /* 133MHz */
else
hwif->ultra_mask = ATA_UDMA5; /* 100MHz */
-
- hwif->cable_detect = scc_cable_detect;
}
+static const struct ide_port_ops scc_port_ops = {
+ .set_pio_mode = scc_set_pio_mode,
+ .set_dma_mode = scc_set_dma_mode,
+ .udma_filter = scc_udma_filter,
+ .cable_detect = scc_cable_detect,
+};
+
+static const struct ide_dma_ops scc_dma_ops = {
+ .dma_host_set = scc_dma_host_set,
+ .dma_setup = scc_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = scc_dma_start,
+ .dma_end = scc_dma_end,
+ .dma_test_irq = scc_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
+
#define DECLARE_SCC_DEV(name_str) \
{ \
.name = name_str, \
.init_iops = init_iops_scc, \
.init_hwif = init_hwif_scc, \
+ .port_ops = &scc_port_ops, \
+ .dma_ops = &scc_dma_ops, \
.host_flags = IDE_HFLAG_SINGLE, \
.pio_mask = ATA_PIO4, \
}
@@ -754,10 +906,6 @@ static void __devexit scc_remove(struct pci_dev *dev)
{
struct scc_ports *ports = pci_get_drvdata(dev);
ide_hwif_t *hwif = ports->hwif;
- unsigned long ctl_base = pci_resource_start(dev, 0);
- unsigned long dma_base = pci_resource_start(dev, 1);
- unsigned long ctl_size = pci_resource_len(dev, 0);
- unsigned long dma_size = pci_resource_len(dev, 1);
if (hwif->dmatable_cpu) {
pci_free_consistent(dev, PRD_ENTRIES * PRD_BYTES,
@@ -765,13 +913,11 @@ static void __devexit scc_remove(struct pci_dev *dev)
hwif->dmatable_cpu = NULL;
}
- ide_unregister(hwif->index);
+ ide_unregister(hwif);
- hwif->chipset = ide_unknown;
iounmap((void*)ports->dma);
iounmap((void*)ports->ctl);
- release_mem_region(dma_base, dma_size);
- release_mem_region(ctl_base, ctl_size);
+ pci_release_selected_regions(dev, (1 << 2) - 1);
memset(ports, 0, sizeof(*ports));
}
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index cfe92746979..a1fb20826a5 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -312,7 +312,7 @@ static u8 __devinit ata66_svwks_cobalt(ide_hwif_t *hwif)
return ATA_CBL_PATA40;
}
-static u8 __devinit ata66_svwks(ide_hwif_t *hwif)
+static u8 __devinit svwks_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -336,17 +336,18 @@ static u8 __devinit ata66_svwks(ide_hwif_t *hwif)
return ATA_CBL_PATA40;
}
-static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
-{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
-
- hwif->set_pio_mode = &svwks_set_pio_mode;
- hwif->set_dma_mode = &svwks_set_dma_mode;
- hwif->udma_filter = &svwks_udma_filter;
+static const struct ide_port_ops osb4_port_ops = {
+ .set_pio_mode = svwks_set_pio_mode,
+ .set_dma_mode = svwks_set_dma_mode,
+ .udma_filter = svwks_udma_filter,
+};
- if (dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE)
- hwif->cable_detect = ata66_svwks;
-}
+static const struct ide_port_ops svwks_port_ops = {
+ .set_pio_mode = svwks_set_pio_mode,
+ .set_dma_mode = svwks_set_dma_mode,
+ .udma_filter = svwks_udma_filter,
+ .cable_detect = svwks_cable_detect,
+};
#define IDE_HFLAGS_SVWKS \
(IDE_HFLAG_LEGACY_IRQS | \
@@ -356,7 +357,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
{ /* 0 */
.name = "SvrWks OSB4",
.init_chipset = init_chipset_svwks,
- .init_hwif = init_hwif_svwks,
+ .port_ops = &osb4_port_ops,
.host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -364,7 +365,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
},{ /* 1 */
.name = "SvrWks CSB5",
.init_chipset = init_chipset_svwks,
- .init_hwif = init_hwif_svwks,
+ .port_ops = &svwks_port_ops,
.host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -372,7 +373,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
},{ /* 2 */
.name = "SvrWks CSB6",
.init_chipset = init_chipset_svwks,
- .init_hwif = init_hwif_svwks,
+ .port_ops = &svwks_port_ops,
.host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -380,7 +381,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
},{ /* 3 */
.name = "SvrWks CSB6",
.init_chipset = init_chipset_svwks,
- .init_hwif = init_hwif_svwks,
+ .port_ops = &svwks_port_ops,
.host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -388,7 +389,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
},{ /* 4 */
.name = "SvrWks HT1000",
.init_chipset = init_chipset_svwks,
- .init_hwif = init_hwif_svwks,
+ .port_ops = &svwks_port_ops,
.host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 6bd9523cf64..16a0bce17d6 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -98,28 +98,28 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
int i;
/* Registers are word (32 bit) aligned */
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
- hw->io_ports[i] = reg + i * 4;
+ for (i = 0; i <= 7; i++)
+ hw->io_ports_array[i] = reg + i * 4;
if (ctrl_port)
- hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+ hw->io_ports.ctl_addr = ctrl_port;
if (irq_port)
- hw->io_ports[IDE_IRQ_OFFSET] = irq_port;
+ hw->io_ports.irq_addr = irq_port;
}
static void
sgiioc4_maskproc(ide_drive_t * drive, int mask)
{
writeb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
- (void __iomem *)drive->hwif->io_ports[IDE_CONTROL_OFFSET]);
+ (void __iomem *)drive->hwif->io_ports.ctl_addr);
}
static int
sgiioc4_checkirq(ide_hwif_t * hwif)
{
unsigned long intr_addr =
- hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4;
+ hwif->io_ports.irq_addr + IOC4_INTR_REG * 4;
if ((u8)readl((void __iomem *)intr_addr) & 0x03)
return 1;
@@ -134,8 +134,8 @@ sgiioc4_clearirq(ide_drive_t * drive)
{
u32 intr_reg;
ide_hwif_t *hwif = HWIF(drive);
- unsigned long other_ir =
- hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2);
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ unsigned long other_ir = io_ports->irq_addr + (IOC4_INTR_REG << 2);
/* Code to check for PCI error conditions */
intr_reg = readl((void __iomem *)other_ir);
@@ -147,12 +147,12 @@ sgiioc4_clearirq(ide_drive_t * drive)
* a "clear" status if it got cleared. If not, then spin
* for a bit trying to clear it.
*/
- u8 stat = sgiioc4_INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+ u8 stat = sgiioc4_INB(io_ports->status_addr);
int count = 0;
- stat = sgiioc4_INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+ stat = sgiioc4_INB(io_ports->status_addr);
while ((stat & 0x80) && (count++ < 100)) {
udelay(1);
- stat = sgiioc4_INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+ stat = sgiioc4_INB(io_ports->status_addr);
}
if (intr_reg & 0x02) {
@@ -162,18 +162,18 @@ sgiioc4_clearirq(ide_drive_t * drive)
pci_stat_cmd_reg;
pci_err_addr_low =
- readl((void __iomem *)hwif->io_ports[IDE_IRQ_OFFSET]);
+ readl((void __iomem *)io_ports->irq_addr);
pci_err_addr_high =
- readl((void __iomem *)(hwif->io_ports[IDE_IRQ_OFFSET] + 4));
+ readl((void __iomem *)(io_ports->irq_addr + 4));
pci_read_config_dword(dev, PCI_COMMAND,
&pci_stat_cmd_reg);
printk(KERN_ERR
"%s(%s) : PCI Bus Error when doing DMA:"
" status-cmd reg is 0x%x\n",
- __FUNCTION__, drive->name, pci_stat_cmd_reg);
+ __func__, drive->name, pci_stat_cmd_reg);
printk(KERN_ERR
"%s(%s) : PCI Error Address is 0x%x%x\n",
- __FUNCTION__, drive->name,
+ __func__, drive->name,
pci_err_addr_high, pci_err_addr_low);
/* Clear the PCI Error indicator */
pci_write_config_dword(dev, PCI_COMMAND, 0x00000146);
@@ -188,7 +188,7 @@ sgiioc4_clearirq(ide_drive_t * drive)
return intr_reg & 3;
}
-static void sgiioc4_ide_dma_start(ide_drive_t * drive)
+static void sgiioc4_dma_start(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long ioc4_dma_addr = hwif->dma_base + IOC4_DMA_CTRL * 4;
@@ -215,8 +215,7 @@ sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
}
/* Stops the IOC4 DMA Engine */
-static int
-sgiioc4_ide_dma_end(ide_drive_t * drive)
+static int sgiioc4_dma_end(ide_drive_t *drive)
{
u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0;
ide_hwif_t *hwif = HWIF(drive);
@@ -232,7 +231,7 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
printk(KERN_ERR
"%s(%s): IOC4 DMA STOP bit is still 1 :"
"ioc4_dma_reg 0x%x\n",
- __FUNCTION__, drive->name, ioc4_dma);
+ __func__, drive->name, ioc4_dma);
dma_stat = 1;
}
@@ -251,7 +250,7 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
udelay(1);
}
if (!valid) {
- printk(KERN_ERR "%s(%s) : DMA incomplete\n", __FUNCTION__,
+ printk(KERN_ERR "%s(%s) : DMA incomplete\n", __func__,
drive->name);
dma_stat = 1;
}
@@ -264,7 +263,7 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
printk(KERN_ERR
"%s(%s): WARNING!! byte_count_dev %d "
"!= byte_count_mem %d\n",
- __FUNCTION__, drive->name, bc_dev, bc_mem);
+ __func__, drive->name, bc_dev, bc_mem);
}
}
@@ -279,8 +278,7 @@ static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
/* returns 1 if dma irq issued, 0 otherwise */
-static int
-sgiioc4_ide_dma_test_irq(ide_drive_t * drive)
+static int sgiioc4_dma_test_irq(ide_drive_t *drive)
{
return sgiioc4_checkirq(HWIF(drive));
}
@@ -294,7 +292,7 @@ static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
static void
sgiioc4_resetproc(ide_drive_t * drive)
{
- sgiioc4_ide_dma_end(drive);
+ sgiioc4_dma_end(drive);
sgiioc4_clearirq(drive);
}
@@ -329,13 +327,17 @@ sgiioc4_INB(unsigned long port)
/* Creates a dma map for the scatter-gather list entries */
static int __devinit
-ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
+ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
+ unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET;
void __iomem *virt_dma_base;
int num_ports = sizeof (ioc4_dma_regs_t);
void *pad;
+ if (dma_base == 0)
+ return -1;
+
printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name,
dma_base, dma_base + num_ports - 1);
@@ -343,7 +345,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
printk(KERN_ERR
"%s(%s) -- ERROR, Addresses 0x%p to 0x%p "
"ALREADY in use\n",
- __FUNCTION__, hwif->name, (void *) dma_base,
+ __func__, hwif->name, (void *) dma_base,
(void *) dma_base + num_ports - 1);
return -1;
}
@@ -352,7 +354,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
if (virt_dma_base == NULL) {
printk(KERN_ERR
"%s(%s) -- ERROR, Unable to map addresses 0x%lx to 0x%lx\n",
- __FUNCTION__, hwif->name, dma_base, dma_base + num_ports - 1);
+ __func__, hwif->name, dma_base, dma_base + num_ports - 1);
goto dma_remap_failure;
}
hwif->dma_base = (unsigned long) virt_dma_base;
@@ -378,7 +380,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
hwif->dmatable_cpu, hwif->dmatable_dma);
printk(KERN_INFO
"%s() -- Error! Unable to allocate DMA Maps for drive %s\n",
- __FUNCTION__, hwif->name);
+ __func__, hwif->name);
printk(KERN_INFO
"Changing from DMA to PIO mode for Drive %s\n", hwif->name);
@@ -406,14 +408,14 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
if (ioc4_dma & IOC4_S_DMA_ACTIVE) {
printk(KERN_WARNING
"%s(%s):Warning!! DMA from previous transfer was still active\n",
- __FUNCTION__, drive->name);
+ __func__, drive->name);
writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
if (ioc4_dma & IOC4_S_DMA_STOP)
printk(KERN_ERR
"%s(%s) : IOC4 Dma STOP bit is still 1\n",
- __FUNCTION__, drive->name);
+ __func__, drive->name);
}
ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
@@ -421,14 +423,14 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
printk(KERN_WARNING
"%s(%s) : Warning!! - DMA Error during Previous"
" transfer | status 0x%x\n",
- __FUNCTION__, drive->name, ioc4_dma);
+ __func__, drive->name, ioc4_dma);
writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
if (ioc4_dma & IOC4_S_DMA_STOP)
printk(KERN_ERR
"%s(%s) : IOC4 DMA STOP bit is still 1\n",
- __FUNCTION__, drive->name);
+ __func__, drive->name);
}
/* Address of the Scatter Gather List */
@@ -519,7 +521,7 @@ use_pio_instead:
return 0; /* revert to PIO for this request */
}
-static int sgiioc4_ide_dma_setup(ide_drive_t *drive)
+static int sgiioc4_dma_setup(ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
unsigned int count = 0;
@@ -548,45 +550,37 @@ static int sgiioc4_ide_dma_setup(ide_drive_t *drive)
return 0;
}
-static void __devinit
-ide_init_sgiioc4(ide_hwif_t * hwif)
-{
- hwif->mmio = 1;
- hwif->set_pio_mode = NULL; /* Sets timing for PIO mode */
- hwif->set_dma_mode = &sgiioc4_set_dma_mode;
- hwif->selectproc = NULL;/* Use the default routine to select drive */
- hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */
- hwif->pre_reset = NULL; /* No HBA specific pre_set needed */
- hwif->resetproc = &sgiioc4_resetproc;/* Reset DMA engine,
- clear interrupts */
- hwif->maskproc = &sgiioc4_maskproc; /* Mask on/off NIEN register */
- hwif->quirkproc = NULL;
-
- hwif->INB = &sgiioc4_INB;
-
- if (hwif->dma_base == 0)
- return;
+static const struct ide_port_ops sgiioc4_port_ops = {
+ .set_dma_mode = sgiioc4_set_dma_mode,
+ /* reset DMA engine, clear IRQs */
+ .resetproc = sgiioc4_resetproc,
+ /* mask on/off NIEN register */
+ .maskproc = sgiioc4_maskproc,
+};
- hwif->dma_host_set = &sgiioc4_dma_host_set;
- hwif->dma_setup = &sgiioc4_ide_dma_setup;
- hwif->dma_start = &sgiioc4_ide_dma_start;
- hwif->ide_dma_end = &sgiioc4_ide_dma_end;
- hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
- hwif->dma_lost_irq = &sgiioc4_dma_lost_irq;
- hwif->dma_timeout = &ide_dma_timeout;
-}
+static const struct ide_dma_ops sgiioc4_dma_ops = {
+ .dma_host_set = sgiioc4_dma_host_set,
+ .dma_setup = sgiioc4_dma_setup,
+ .dma_start = sgiioc4_dma_start,
+ .dma_end = sgiioc4_dma_end,
+ .dma_test_irq = sgiioc4_dma_test_irq,
+ .dma_lost_irq = sgiioc4_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
static const struct ide_port_info sgiioc4_port_info __devinitdata = {
.chipset = ide_pci,
- .host_flags = IDE_HFLAG_NO_DMA | /* no SFF-style DMA */
- IDE_HFLAG_NO_AUTOTUNE,
+ .init_dma = ide_dma_sgiioc4,
+ .port_ops = &sgiioc4_port_ops,
+ .dma_ops = &sgiioc4_dma_ops,
+ .host_flags = IDE_HFLAG_MMIO,
.mwdma_mask = ATA_MWDMA2_ONLY,
};
static int __devinit
sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
{
- unsigned long cmd_base, dma_base, irqport;
+ unsigned long cmd_base, irqport;
unsigned long bar0, cmd_phys_base, ctl;
void __iomem *virt_base;
ide_hwif_t *hwif;
@@ -612,7 +606,6 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET;
ctl = (unsigned long) virt_base + IOC4_CTRL_OFFSET;
irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET;
- dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET;
cmd_phys_base = bar0 + IOC4_CMD_OFFSET;
if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
@@ -620,7 +613,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
printk(KERN_ERR
"%s : %s -- ERROR, Addresses "
"0x%p to 0x%p ALREADY in use\n",
- __FUNCTION__, hwif->name, (void *) cmd_phys_base,
+ __func__, hwif->name, (void *) cmd_phys_base,
(void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE);
return -ENOMEM;
}
@@ -641,13 +634,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
/* Initializing chipset IRQ Registers */
writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
- if (dma_base == 0 || ide_dma_sgiioc4(hwif, dma_base)) {
- printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n",
- hwif->name, DRV_NAME);
- d.mwdma_mask = 0;
- }
-
- ide_init_sgiioc4(hwif);
+ hwif->INB = &sgiioc4_INB;
idx[0] = hwif->index;
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index c9ecab8aeb6..0006b9e5856 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -1,8 +1,8 @@
/*
* Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2003 Red Hat <alan@redhat.com>
- * Copyright (C) 2007 MontaVista Software, Inc.
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2008 MontaVista Software, Inc.
+ * Copyright (C) 2007-2008 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public License
*
@@ -17,10 +17,10 @@
*
* FAQ Items:
* If you are using Marvell SATA-IDE adapters with Maxtor drives
- * ensure the system is set up for ATA100/UDMA5 not UDMA6.
+ * ensure the system is set up for ATA100/UDMA5, not UDMA6.
*
* If you are using WD drives with SATA bridges you must set the
- * drive to "Single". "Master" will hang
+ * drive to "Single". "Master" will hang.
*
* If you have strange problems with nVidia chipset systems please
* see the SI support documentation and update your system BIOS
@@ -42,25 +42,24 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/init.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
/**
* pdev_is_sata - check if device is SATA
* @pdev: PCI device to check
- *
+ *
* Returns true if this is a SATA controller
*/
-
+
static int pdev_is_sata(struct pci_dev *pdev)
{
#ifdef CONFIG_BLK_DEV_IDE_SATA
- switch(pdev->device) {
- case PCI_DEVICE_ID_SII_3112:
- case PCI_DEVICE_ID_SII_1210SA:
- return 1;
- case PCI_DEVICE_ID_SII_680:
- return 0;
+ switch (pdev->device) {
+ case PCI_DEVICE_ID_SII_3112:
+ case PCI_DEVICE_ID_SII_1210SA:
+ return 1;
+ case PCI_DEVICE_ID_SII_680:
+ return 0;
}
BUG();
#endif
@@ -70,10 +69,10 @@ static int pdev_is_sata(struct pci_dev *pdev)
/**
* is_sata - check if hwif is SATA
* @hwif: interface to check
- *
+ *
* Returns true if this is a SATA controller
*/
-
+
static inline int is_sata(ide_hwif_t *hwif)
{
return pdev_is_sata(to_pci_dev(hwif->dev));
@@ -86,21 +85,22 @@ static inline int is_sata(ide_hwif_t *hwif)
*
* Turn a config register offset into the right address in either
* PCI space or MMIO space to access the control register in question
- * Thankfully this is a configuration operation so isnt performance
- * criticial.
+ * Thankfully this is a configuration operation, so isn't performance
+ * critical.
*/
-
+
static unsigned long siimage_selreg(ide_hwif_t *hwif, int r)
{
unsigned long base = (unsigned long)hwif->hwif_data;
+
base += 0xA0 + r;
- if(hwif->mmio)
- base += (hwif->channel << 6);
+ if (hwif->mmio)
+ base += hwif->channel << 6;
else
- base += (hwif->channel << 4);
+ base += hwif->channel << 4;
return base;
}
-
+
/**
* siimage_seldev - return register base
* @hwif: interface
@@ -110,20 +110,69 @@ static unsigned long siimage_selreg(ide_hwif_t *hwif, int r)
* PCI space or MMIO space to access the control register in question
* including accounting for the unit shift.
*/
-
+
static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
{
ide_hwif_t *hwif = HWIF(drive);
- unsigned long base = (unsigned long)hwif->hwif_data;
+ unsigned long base = (unsigned long)hwif->hwif_data;
+
base += 0xA0 + r;
- if(hwif->mmio)
- base += (hwif->channel << 6);
+ if (hwif->mmio)
+ base += hwif->channel << 6;
else
- base += (hwif->channel << 4);
+ base += hwif->channel << 4;
base |= drive->select.b.unit << drive->select.b.unit;
return base;
}
+static u8 sil_ioread8(struct pci_dev *dev, unsigned long addr)
+{
+ u8 tmp = 0;
+
+ if (pci_get_drvdata(dev))
+ tmp = readb((void __iomem *)addr);
+ else
+ pci_read_config_byte(dev, addr, &tmp);
+
+ return tmp;
+}
+
+static u16 sil_ioread16(struct pci_dev *dev, unsigned long addr)
+{
+ u16 tmp = 0;
+
+ if (pci_get_drvdata(dev))
+ tmp = readw((void __iomem *)addr);
+ else
+ pci_read_config_word(dev, addr, &tmp);
+
+ return tmp;
+}
+
+static void sil_iowrite8(struct pci_dev *dev, u8 val, unsigned long addr)
+{
+ if (pci_get_drvdata(dev))
+ writeb(val, (void __iomem *)addr);
+ else
+ pci_write_config_byte(dev, addr, val);
+}
+
+static void sil_iowrite16(struct pci_dev *dev, u16 val, unsigned long addr)
+{
+ if (pci_get_drvdata(dev))
+ writew(val, (void __iomem *)addr);
+ else
+ pci_write_config_word(dev, addr, val);
+}
+
+static void sil_iowrite32(struct pci_dev *dev, u32 val, unsigned long addr)
+{
+ if (pci_get_drvdata(dev))
+ writel(val, (void __iomem *)addr);
+ else
+ pci_write_config_dword(dev, addr, val);
+}
+
/**
* sil_udma_filter - compute UDMA mask
* @drive: IDE device
@@ -136,24 +185,26 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
static u8 sil_pata_udma_filter(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
- struct pci_dev *dev = to_pci_dev(hwif->dev);
- unsigned long base = (unsigned long) hwif->hwif_data;
- u8 mask = 0, scsc = 0;
+ ide_hwif_t *hwif = drive->hwif;
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
+ unsigned long base = (unsigned long)hwif->hwif_data;
+ u8 scsc, mask = 0;
- if (hwif->mmio)
- scsc = hwif->INB(base + 0x4A);
- else
- pci_read_config_byte(dev, 0x8A, &scsc);
+ scsc = sil_ioread8(dev, base + (hwif->mmio ? 0x4A : 0x8A));
- if ((scsc & 0x30) == 0x10) /* 133 */
+ switch (scsc & 0x30) {
+ case 0x10: /* 133 */
mask = ATA_UDMA6;
- else if ((scsc & 0x30) == 0x20) /* 2xPCI */
+ break;
+ case 0x20: /* 2xPCI */
mask = ATA_UDMA6;
- else if ((scsc & 0x30) == 0x00) /* 100 */
+ break;
+ case 0x00: /* 100 */
mask = ATA_UDMA5;
- else /* Disabled ? */
+ break;
+ default: /* Disabled ? */
BUG();
+ }
return mask;
}
@@ -175,15 +226,16 @@ static u8 sil_sata_udma_filter(ide_drive_t *drive)
static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
{
- const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
- const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
+ static const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
+ static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
ide_hwif_t *hwif = HWIF(drive);
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
ide_drive_t *pair = ide_get_paired_drive(drive);
u32 speedt = 0;
u16 speedp = 0;
unsigned long addr = siimage_seldev(drive, 0x04);
- unsigned long tfaddr = siimage_selreg(hwif, 0x02);
+ unsigned long tfaddr = siimage_selreg(hwif, 0x02);
unsigned long base = (unsigned long)hwif->hwif_data;
u8 tf_pio = pio;
u8 addr_mask = hwif->channel ? (hwif->mmio ? 0xF4 : 0x84)
@@ -203,36 +255,20 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
speedp = data_speed[pio];
speedt = tf_speed[tf_pio];
- if (hwif->mmio) {
- hwif->OUTW(speedp, addr);
- hwif->OUTW(speedt, tfaddr);
- /* Now set up IORDY */
- if (pio > 2)
- hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2);
- else
- hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2);
-
- mode = hwif->INB(base + addr_mask);
- mode &= ~(unit ? 0x30 : 0x03);
- mode |= (unit ? 0x10 : 0x01);
- hwif->OUTB(mode, base + addr_mask);
- } else {
- struct pci_dev *dev = to_pci_dev(hwif->dev);
-
- pci_write_config_word(dev, addr, speedp);
- pci_write_config_word(dev, tfaddr, speedt);
- pci_read_config_word(dev, tfaddr - 2, &speedp);
- speedp &= ~0x200;
- /* Set IORDY for mode 3 or 4 */
- if (pio > 2)
- speedp |= 0x200;
- pci_write_config_word(dev, tfaddr - 2, speedp);
-
- pci_read_config_byte(dev, addr_mask, &mode);
- mode &= ~(unit ? 0x30 : 0x03);
- mode |= (unit ? 0x10 : 0x01);
- pci_write_config_byte(dev, addr_mask, mode);
- }
+ sil_iowrite16(dev, speedp, addr);
+ sil_iowrite16(dev, speedt, tfaddr);
+
+ /* now set up IORDY */
+ speedp = sil_ioread16(dev, tfaddr - 2);
+ speedp &= ~0x200;
+ if (pio > 2)
+ speedp |= 0x200;
+ sil_iowrite16(dev, speedp, tfaddr - 2);
+
+ mode = sil_ioread8(dev, base + addr_mask);
+ mode &= ~(unit ? 0x30 : 0x03);
+ mode |= unit ? 0x10 : 0x01;
+ sil_iowrite8(dev, mode, base + addr_mask);
}
/**
@@ -245,63 +281,49 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
- u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
- u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
- u16 dma[] = { 0x2208, 0x10C2, 0x10C1 };
+ static const u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
+ static const u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
+ static const u16 dma[] = { 0x2208, 0x10C2, 0x10C1 };
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = to_pci_dev(hwif->dev);
u16 ultra = 0, multi = 0;
u8 mode = 0, unit = drive->select.b.unit;
unsigned long base = (unsigned long)hwif->hwif_data;
- u8 scsc = 0, addr_mask = ((hwif->channel) ?
- ((hwif->mmio) ? 0xF4 : 0x84) :
- ((hwif->mmio) ? 0xB4 : 0x80));
-
+ u8 scsc = 0, addr_mask = hwif->channel ?
+ (hwif->mmio ? 0xF4 : 0x84) :
+ (hwif->mmio ? 0xB4 : 0x80);
unsigned long ma = siimage_seldev(drive, 0x08);
unsigned long ua = siimage_seldev(drive, 0x0C);
- if (hwif->mmio) {
- scsc = hwif->INB(base + 0x4A);
- mode = hwif->INB(base + addr_mask);
- multi = hwif->INW(ma);
- ultra = hwif->INW(ua);
- } else {
- pci_read_config_byte(dev, 0x8A, &scsc);
- pci_read_config_byte(dev, addr_mask, &mode);
- pci_read_config_word(dev, ma, &multi);
- pci_read_config_word(dev, ua, &ultra);
- }
+ scsc = sil_ioread8 (dev, base + (hwif->mmio ? 0x4A : 0x8A));
+ mode = sil_ioread8 (dev, base + addr_mask);
+ multi = sil_ioread16(dev, ma);
+ ultra = sil_ioread16(dev, ua);
- mode &= ~((unit) ? 0x30 : 0x03);
+ mode &= ~(unit ? 0x30 : 0x03);
ultra &= ~0x3F;
scsc = ((scsc & 0x30) == 0x00) ? 0 : 1;
scsc = is_sata(hwif) ? 1 : scsc;
if (speed >= XFER_UDMA_0) {
- multi = dma[2];
- ultra |= (scsc ? ultra6[speed - XFER_UDMA_0] :
- ultra5[speed - XFER_UDMA_0]);
- mode |= (unit ? 0x30 : 0x03);
+ multi = dma[2];
+ ultra |= scsc ? ultra6[speed - XFER_UDMA_0] :
+ ultra5[speed - XFER_UDMA_0];
+ mode |= unit ? 0x30 : 0x03;
} else {
multi = dma[speed - XFER_MW_DMA_0];
- mode |= (unit ? 0x20 : 0x02);
+ mode |= unit ? 0x20 : 0x02;
}
- if (hwif->mmio) {
- hwif->OUTB(mode, base + addr_mask);
- hwif->OUTW(multi, ma);
- hwif->OUTW(ultra, ua);
- } else {
- pci_write_config_byte(dev, addr_mask, mode);
- pci_write_config_word(dev, ma, multi);
- pci_write_config_word(dev, ua, ultra);
- }
+ sil_iowrite8 (dev, mode, base + addr_mask);
+ sil_iowrite16(dev, multi, ma);
+ sil_iowrite16(dev, ultra, ua);
}
/* returns 1 if dma irq issued, 0 otherwise */
-static int siimage_io_ide_dma_test_irq (ide_drive_t *drive)
+static int siimage_io_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -309,25 +331,26 @@ static int siimage_io_ide_dma_test_irq (ide_drive_t *drive)
unsigned long addr = siimage_selreg(hwif, 1);
/* return 1 if INTR asserted */
- if ((hwif->INB(hwif->dma_status) & 4) == 4)
+ if (hwif->INB(hwif->dma_status) & 4)
return 1;
/* return 1 if Device INTR asserted */
pci_read_config_byte(dev, addr, &dma_altstat);
if (dma_altstat & 8)
- return 0; //return 1;
+ return 0; /* return 1; */
+
return 0;
}
/**
- * siimage_mmio_ide_dma_test_irq - check we caused an IRQ
+ * siimage_mmio_dma_test_irq - check we caused an IRQ
* @drive: drive we are testing
*
* Check if we caused an IDE DMA interrupt. We may also have caused
* SATA status interrupts, if so we clean them up and continue.
*/
-
-static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
+
+static int siimage_mmio_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long addr = siimage_selreg(hwif, 0x1);
@@ -335,9 +358,9 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
= (void __iomem *)hwif->sata_scr[SATA_ERROR_OFFSET];
if (sata_error_addr) {
- unsigned long base = (unsigned long)hwif->hwif_data;
- u32 ext_stat = readl((void __iomem *)(base + 0x10));
- u8 watchdog = 0;
+ unsigned long base = (unsigned long)hwif->hwif_data;
+ u32 ext_stat = readl((void __iomem *)(base + 0x10));
+ u8 watchdog = 0;
if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
u32 sata_error = readl(sata_error_addr);
@@ -346,29 +369,34 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
watchdog = (sata_error & 0x00680000) ? 1 : 0;
printk(KERN_WARNING "%s: sata_error = 0x%08x, "
"watchdog = %d, %s\n",
- drive->name, sata_error, watchdog,
- __FUNCTION__);
-
- } else {
+ drive->name, sata_error, watchdog, __func__);
+ } else
watchdog = (ext_stat & 0x8000) ? 1 : 0;
- }
- ext_stat >>= 16;
+ ext_stat >>= 16;
if (!(ext_stat & 0x0404) && !watchdog)
return 0;
}
/* return 1 if INTR asserted */
- if ((readb((void __iomem *)hwif->dma_status) & 0x04) == 0x04)
+ if (readb((void __iomem *)hwif->dma_status) & 0x04)
return 1;
/* return 1 if Device INTR asserted */
- if ((readb((void __iomem *)addr) & 8) == 8)
- return 0; //return 1;
+ if (readb((void __iomem *)addr) & 8)
+ return 0; /* return 1; */
return 0;
}
+static int siimage_dma_test_irq(ide_drive_t *drive)
+{
+ if (drive->hwif->mmio)
+ return siimage_mmio_dma_test_irq(drive);
+ else
+ return siimage_io_dma_test_irq(drive);
+}
+
/**
* sil_sata_reset_poll - wait for SATA reset
* @drive: drive we are resetting
@@ -415,63 +443,33 @@ static void sil_sata_pre_reset(ide_drive_t *drive)
}
/**
- * proc_reports_siimage - add siimage controller to proc
- * @dev: PCI device
- * @clocking: SCSC value
- * @name: controller name
- *
- * Report the clocking mode of the controller and add it to
- * the /proc interface layer
- */
-
-static void proc_reports_siimage (struct pci_dev *dev, u8 clocking, const char *name)
-{
- if (!pdev_is_sata(dev)) {
- printk(KERN_INFO "%s: BASE CLOCK ", name);
- clocking &= 0x03;
- switch (clocking) {
- case 0x03: printk("DISABLED!\n"); break;
- case 0x02: printk("== 2X PCI\n"); break;
- case 0x01: printk("== 133\n"); break;
- case 0x00: printk("== 100\n"); break;
- }
- }
-}
-
-/**
- * setup_mmio_siimage - switch an SI controller into MMIO
+ * setup_mmio_siimage - switch controller into MMIO mode
* @dev: PCI device we are configuring
* @name: device name
*
- * Attempt to put the device into mmio mode. There are some slight
- * complications here with certain systems where the mmio bar isnt
- * mapped so we have to be sure we can fall back to I/O.
+ * Attempt to put the device into MMIO mode. There are some slight
+ * complications here with certain systems where the MMIO BAR isn't
+ * mapped, so we have to be sure that we can fall back to I/O.
*/
-
-static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
+
+static unsigned int setup_mmio_siimage(struct pci_dev *dev, const char *name)
{
resource_size_t bar5 = pci_resource_start(dev, 5);
unsigned long barsize = pci_resource_len(dev, 5);
- u8 tmpbyte = 0;
void __iomem *ioaddr;
- u32 tmp, irq_mask;
/*
- * Drop back to PIO if we can't map the mmio. Some
- * systems seem to get terminally confused in the PCI
- * spaces.
+ * Drop back to PIO if we can't map the MMIO. Some systems
+ * seem to get terminally confused in the PCI spaces.
*/
-
- if(!request_mem_region(bar5, barsize, name))
- {
- printk(KERN_WARNING "siimage: IDE controller MMIO ports not available.\n");
+ if (!request_mem_region(bar5, barsize, name)) {
+ printk(KERN_WARNING "siimage: IDE controller MMIO ports not "
+ "available.\n");
return 0;
}
-
- ioaddr = ioremap(bar5, barsize);
- if (ioaddr == NULL)
- {
+ ioaddr = ioremap(bar5, barsize);
+ if (ioaddr == NULL) {
release_mem_region(bar5, barsize);
return 0;
}
@@ -479,62 +477,6 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
pci_set_master(dev);
pci_set_drvdata(dev, (void *) ioaddr);
- if (pdev_is_sata(dev)) {
- /* make sure IDE0/1 interrupts are not masked */
- irq_mask = (1 << 22) | (1 << 23);
- tmp = readl(ioaddr + 0x48);
- if (tmp & irq_mask) {
- tmp &= ~irq_mask;
- writel(tmp, ioaddr + 0x48);
- readl(ioaddr + 0x48); /* flush */
- }
- writel(0, ioaddr + 0x148);
- writel(0, ioaddr + 0x1C8);
- }
-
- writeb(0, ioaddr + 0xB4);
- writeb(0, ioaddr + 0xF4);
- tmpbyte = readb(ioaddr + 0x4A);
-
- switch(tmpbyte & 0x30) {
- case 0x00:
- /* In 100 MHz clocking, try and switch to 133 */
- writeb(tmpbyte|0x10, ioaddr + 0x4A);
- break;
- case 0x10:
- /* On 133Mhz clocking */
- break;
- case 0x20:
- /* On PCIx2 clocking */
- break;
- case 0x30:
- /* Clocking is disabled */
- /* 133 clock attempt to force it on */
- writeb(tmpbyte & ~0x20, ioaddr + 0x4A);
- break;
- }
-
- writeb( 0x72, ioaddr + 0xA1);
- writew( 0x328A, ioaddr + 0xA2);
- writel(0x62DD62DD, ioaddr + 0xA4);
- writel(0x43924392, ioaddr + 0xA8);
- writel(0x40094009, ioaddr + 0xAC);
- writeb( 0x72, ioaddr + 0xE1);
- writew( 0x328A, ioaddr + 0xE2);
- writel(0x62DD62DD, ioaddr + 0xE4);
- writel(0x43924392, ioaddr + 0xE8);
- writel(0x40094009, ioaddr + 0xEC);
-
- if (pdev_is_sata(dev)) {
- writel(0xFFFF0000, ioaddr + 0x108);
- writel(0xFFFF0000, ioaddr + 0x188);
- writel(0x00680000, ioaddr + 0x148);
- writel(0x00680000, ioaddr + 0x1C8);
- }
-
- tmpbyte = readb(ioaddr + 0x4A);
-
- proc_reports_siimage(dev, (tmpbyte>>4), name);
return 1;
}
@@ -544,55 +486,92 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
* @name: device name
*
* Perform the initial PCI set up for this device. Attempt to switch
- * to 133MHz clocking if the system isn't already set up to do it.
+ * to 133 MHz clocking if the system isn't already set up to do it.
*/
-static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev,
+ const char *name)
{
- u8 rev = dev->revision, tmpbyte = 0, BA5_EN = 0;
+ unsigned long base, scsc_addr;
+ void __iomem *ioaddr = NULL;
+ u8 rev = dev->revision, tmp, BA5_EN;
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, rev ? 1 : 255);
pci_read_config_byte(dev, 0x8A, &BA5_EN);
- if ((BA5_EN & 0x01) || (pci_resource_start(dev, 5))) {
- if (setup_mmio_siimage(dev, name)) {
- return 0;
+
+ if ((BA5_EN & 0x01) || pci_resource_start(dev, 5))
+ if (setup_mmio_siimage(dev, name))
+ ioaddr = pci_get_drvdata(dev);
+
+ base = (unsigned long)ioaddr;
+
+ if (ioaddr && pdev_is_sata(dev)) {
+ u32 tmp32, irq_mask;
+
+ /* make sure IDE0/1 interrupts are not masked */
+ irq_mask = (1 << 22) | (1 << 23);
+ tmp32 = readl(ioaddr + 0x48);
+ if (tmp32 & irq_mask) {
+ tmp32 &= ~irq_mask;
+ writel(tmp32, ioaddr + 0x48);
+ readl(ioaddr + 0x48); /* flush */
}
+ writel(0, ioaddr + 0x148);
+ writel(0, ioaddr + 0x1C8);
}
- pci_write_config_byte(dev, 0x80, 0x00);
- pci_write_config_byte(dev, 0x84, 0x00);
- pci_read_config_byte(dev, 0x8A, &tmpbyte);
- switch(tmpbyte & 0x30) {
- case 0x00:
- /* 133 clock attempt to force it on */
- pci_write_config_byte(dev, 0x8A, tmpbyte|0x10);
- case 0x30:
- /* if clocking is disabled */
- /* 133 clock attempt to force it on */
- pci_write_config_byte(dev, 0x8A, tmpbyte & ~0x20);
- case 0x10:
- /* 133 already */
- break;
- case 0x20:
- /* BIOS set PCI x2 clocking */
- break;
+ sil_iowrite8(dev, 0, base ? (base + 0xB4) : 0x80);
+ sil_iowrite8(dev, 0, base ? (base + 0xF4) : 0x84);
+
+ scsc_addr = base ? (base + 0x4A) : 0x8A;
+ tmp = sil_ioread8(dev, scsc_addr);
+
+ switch (tmp & 0x30) {
+ case 0x00:
+ /* On 100 MHz clocking, try and switch to 133 MHz */
+ sil_iowrite8(dev, tmp | 0x10, scsc_addr);
+ break;
+ case 0x30:
+ /* Clocking is disabled, attempt to force 133MHz clocking. */
+ sil_iowrite8(dev, tmp & ~0x20, scsc_addr);
+ case 0x10:
+ /* On 133Mhz clocking. */
+ break;
+ case 0x20:
+ /* On PCIx2 clocking. */
+ break;
}
- pci_read_config_byte(dev, 0x8A, &tmpbyte);
+ tmp = sil_ioread8(dev, scsc_addr);
- pci_write_config_byte(dev, 0xA1, 0x72);
- pci_write_config_word(dev, 0xA2, 0x328A);
- pci_write_config_dword(dev, 0xA4, 0x62DD62DD);
- pci_write_config_dword(dev, 0xA8, 0x43924392);
- pci_write_config_dword(dev, 0xAC, 0x40094009);
- pci_write_config_byte(dev, 0xB1, 0x72);
- pci_write_config_word(dev, 0xB2, 0x328A);
- pci_write_config_dword(dev, 0xB4, 0x62DD62DD);
- pci_write_config_dword(dev, 0xB8, 0x43924392);
- pci_write_config_dword(dev, 0xBC, 0x40094009);
+ sil_iowrite8 (dev, 0x72, base + 0xA1);
+ sil_iowrite16(dev, 0x328A, base + 0xA2);
+ sil_iowrite32(dev, 0x62DD62DD, base + 0xA4);
+ sil_iowrite32(dev, 0x43924392, base + 0xA8);
+ sil_iowrite32(dev, 0x40094009, base + 0xAC);
+ sil_iowrite8 (dev, 0x72, base ? (base + 0xE1) : 0xB1);
+ sil_iowrite16(dev, 0x328A, base ? (base + 0xE2) : 0xB2);
+ sil_iowrite32(dev, 0x62DD62DD, base ? (base + 0xE4) : 0xB4);
+ sil_iowrite32(dev, 0x43924392, base ? (base + 0xE8) : 0xB8);
+ sil_iowrite32(dev, 0x40094009, base ? (base + 0xEC) : 0xBC);
+
+ if (base && pdev_is_sata(dev)) {
+ writel(0xFFFF0000, ioaddr + 0x108);
+ writel(0xFFFF0000, ioaddr + 0x188);
+ writel(0x00680000, ioaddr + 0x148);
+ writel(0x00680000, ioaddr + 0x1C8);
+ }
+
+ /* report the clocking mode of the controller */
+ if (!pdev_is_sata(dev)) {
+ static const char *clk_str[] =
+ { "== 100", "== 133", "== 2X PCI", "DISABLED!" };
+
+ tmp >>= 4;
+ printk(KERN_INFO "%s: BASE CLOCK %s\n", name, clk_str[tmp & 3]);
+ }
- proc_reports_siimage(dev, (tmpbyte>>4), name);
return 0;
}
@@ -602,8 +581,7 @@ static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const ch
*
* The basic setup here is fairly simple, we can use standard MMIO
* operations. However we do have to set the taskfile register offsets
- * by hand as there isnt a standard defined layout for them this
- * time.
+ * by hand as there isn't a standard defined layout for them this time.
*
* The hardware supports buffered taskfiles and also some rather nice
* extended PRD tables. For better SI3112 support use the libata driver
@@ -614,23 +592,21 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
struct pci_dev *dev = to_pci_dev(hwif->dev);
void *addr = pci_get_drvdata(dev);
u8 ch = hwif->channel;
- hw_regs_t hw;
- unsigned long base;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ unsigned long base;
/*
- * Fill in the basic HWIF bits
+ * Fill in the basic hwif bits
*/
-
+ hwif->host_flags |= IDE_HFLAG_MMIO;
default_hwif_mmiops(hwif);
- hwif->hwif_data = addr;
+ hwif->hwif_data = addr;
/*
- * Now set up the hw. We have to do this ourselves as
- * the MMIO layout isnt the same as the standard port
- * based I/O
+ * Now set up the hw. We have to do this ourselves as the
+ * MMIO layout isn't the same as the standard port based I/O.
*/
-
- memset(&hw, 0, sizeof(hw_regs_t));
+ memset(io_ports, 0, sizeof(*io_ports));
base = (unsigned long)addr;
if (ch)
@@ -639,21 +615,18 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
base += 0x80;
/*
- * The buffered task file doesn't have status/control
- * so we can't currently use it sanely since we want to
- * use LBA48 mode.
- */
- hw.io_ports[IDE_DATA_OFFSET] = base;
- hw.io_ports[IDE_ERROR_OFFSET] = base + 1;
- hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2;
- hw.io_ports[IDE_SECTOR_OFFSET] = base + 3;
- hw.io_ports[IDE_LCYL_OFFSET] = base + 4;
- hw.io_ports[IDE_HCYL_OFFSET] = base + 5;
- hw.io_ports[IDE_SELECT_OFFSET] = base + 6;
- hw.io_ports[IDE_STATUS_OFFSET] = base + 7;
- hw.io_ports[IDE_CONTROL_OFFSET] = base + 10;
-
- hw.io_ports[IDE_IRQ_OFFSET] = 0;
+ * The buffered task file doesn't have status/control, so we
+ * can't currently use it sanely since we want to use LBA48 mode.
+ */
+ io_ports->data_addr = base;
+ io_ports->error_addr = base + 1;
+ io_ports->nsect_addr = base + 2;
+ io_ports->lbal_addr = base + 3;
+ io_ports->lbam_addr = base + 4;
+ io_ports->lbah_addr = base + 5;
+ io_ports->device_addr = base + 6;
+ io_ports->status_addr = base + 7;
+ io_ports->ctl_addr = base + 10;
if (pdev_is_sata(dev)) {
base = (unsigned long)addr;
@@ -664,8 +637,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
hwif->sata_scr[SATA_CONTROL_OFFSET] = base + 0x100;
}
- memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
-
hwif->irq = dev->irq;
hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00);
@@ -675,19 +646,17 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
static int is_dev_seagate_sata(ide_drive_t *drive)
{
- const char *s = &drive->id->model[0];
- unsigned len;
-
- len = strnlen(s, sizeof(drive->id->model));
+ const char *s = &drive->id->model[0];
+ unsigned len = strnlen(s, sizeof(drive->id->model));
- if ((len > 4) && (!memcmp(s, "ST", 2))) {
+ if ((len > 4) && (!memcmp(s, "ST", 2)))
if ((!memcmp(s + len - 2, "AS", 2)) ||
(!memcmp(s + len - 3, "ASL", 3))) {
printk(KERN_INFO "%s: applying pessimistic Seagate "
"errata fix\n", drive->name);
return 1;
}
- }
+
return 0;
}
@@ -704,7 +673,7 @@ static void __devinit sil_quirkproc(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- /* Try and raise the rqsize */
+ /* Try and rise the rqsize */
if (!is_sata(hwif) || !is_dev_seagate_sata(drive))
hwif->rqsize = 128;
}
@@ -735,102 +704,98 @@ static void __devinit init_iops_siimage(ide_hwif_t *hwif)
}
/**
- * ata66_siimage - check for 80 pin cable
+ * sil_cable_detect - cable detection
* @hwif: interface to check
*
- * Check for the presence of an ATA66 capable cable on the
- * interface.
+ * Check for the presence of an ATA66 capable cable on the interface.
*/
-static u8 __devinit ata66_siimage(ide_hwif_t *hwif)
+static u8 __devinit sil_cable_detect(ide_hwif_t *hwif)
{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
- unsigned long addr = siimage_selreg(hwif, 0);
- u8 ata66 = 0;
-
- if (pci_get_drvdata(dev) == NULL)
- pci_read_config_byte(dev, addr, &ata66);
- else
- ata66 = hwif->INB(addr);
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
+ unsigned long addr = siimage_selreg(hwif, 0);
+ u8 ata66 = sil_ioread8(dev, addr);
return (ata66 & 0x01) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
}
-/**
- * init_hwif_siimage - set up hwif structs
- * @hwif: interface to set up
- *
- * We do the basic set up of the interface structure. The SIIMAGE
- * requires several custom handlers so we override the default
- * ide DMA handlers appropriately
- */
-
-static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
-{
- u8 sata = is_sata(hwif);
-
- hwif->set_pio_mode = &sil_set_pio_mode;
- hwif->set_dma_mode = &sil_set_dma_mode;
- hwif->quirkproc = &sil_quirkproc;
-
- if (sata) {
- static int first = 1;
-
- hwif->reset_poll = &sil_sata_reset_poll;
- hwif->pre_reset = &sil_sata_pre_reset;
- hwif->udma_filter = &sil_sata_udma_filter;
-
- if (first) {
- printk(KERN_INFO "siimage: For full SATA support you should use the libata sata_sil module.\n");
- first = 0;
- }
- } else
- hwif->udma_filter = &sil_pata_udma_filter;
-
- hwif->cable_detect = ata66_siimage;
-
- if (hwif->dma_base == 0)
- return;
+static const struct ide_port_ops sil_pata_port_ops = {
+ .set_pio_mode = sil_set_pio_mode,
+ .set_dma_mode = sil_set_dma_mode,
+ .quirkproc = sil_quirkproc,
+ .udma_filter = sil_pata_udma_filter,
+ .cable_detect = sil_cable_detect,
+};
- if (sata)
- hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
+static const struct ide_port_ops sil_sata_port_ops = {
+ .set_pio_mode = sil_set_pio_mode,
+ .set_dma_mode = sil_set_dma_mode,
+ .reset_poll = sil_sata_reset_poll,
+ .pre_reset = sil_sata_pre_reset,
+ .quirkproc = sil_quirkproc,
+ .udma_filter = sil_sata_udma_filter,
+ .cable_detect = sil_cable_detect,
+};
- if (hwif->mmio) {
- hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq;
- } else {
- hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq;
- }
-}
+static const struct ide_dma_ops sil_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = ide_dma_start,
+ .dma_end = __ide_dma_end,
+ .dma_test_irq = siimage_dma_test_irq,
+ .dma_timeout = ide_dma_timeout,
+ .dma_lost_irq = ide_dma_lost_irq,
+};
-#define DECLARE_SII_DEV(name_str) \
+#define DECLARE_SII_DEV(name_str, p_ops) \
{ \
.name = name_str, \
.init_chipset = init_chipset_siimage, \
.init_iops = init_iops_siimage, \
- .init_hwif = init_hwif_siimage, \
+ .port_ops = p_ops, \
+ .dma_ops = &sil_dma_ops, \
.pio_mask = ATA_PIO4, \
.mwdma_mask = ATA_MWDMA2, \
.udma_mask = ATA_UDMA6, \
}
static const struct ide_port_info siimage_chipsets[] __devinitdata = {
- /* 0 */ DECLARE_SII_DEV("SiI680"),
- /* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA"),
- /* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA")
+ /* 0 */ DECLARE_SII_DEV("SiI680", &sil_pata_port_ops),
+ /* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA", &sil_sata_port_ops),
+ /* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA", &sil_sata_port_ops)
};
/**
- * siimage_init_one - pci layer discovery entry
+ * siimage_init_one - PCI layer discovery entry
* @dev: PCI device
* @id: ident table entry
*
- * Called by the PCI code when it finds an SI680 or SI3112 controller.
+ * Called by the PCI code when it finds an SiI680 or SiI3112 controller.
* We then use the IDE PCI generic helper to do most of the work.
*/
-
-static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+
+static int __devinit siimage_init_one(struct pci_dev *dev,
+ const struct pci_device_id *id)
{
- return ide_setup_pci_device(dev, &siimage_chipsets[id->driver_data]);
+ struct ide_port_info d;
+ u8 idx = id->driver_data;
+
+ d = siimage_chipsets[idx];
+
+ if (idx) {
+ static int first = 1;
+
+ if (first) {
+ printk(KERN_INFO "siimage: For full SATA support you "
+ "should use the libata sata_sil module.\n");
+ first = 0;
+ }
+
+ d.host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
+ }
+
+ return ide_setup_pci_device(dev, &d);
}
static const struct pci_device_id siimage_pci_tbl[] = {
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 181b647e5ca..4b0b85d8faf 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -347,7 +347,7 @@ static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
sis_program_timings(drive, speed);
}
-static u8 sis5513_ata133_udma_filter(ide_drive_t *drive)
+static u8 sis_ata133_udma_filter(ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
u32 regdw = 0;
@@ -514,7 +514,7 @@ static const struct sis_laptop sis_laptop[] = {
{ 0, }
};
-static u8 __devinit ata66_sis5513(ide_hwif_t *hwif)
+static u8 __devinit sis_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *pdev = to_pci_dev(hwif->dev);
const struct sis_laptop *lap = &sis_laptop[0];
@@ -543,21 +543,22 @@ static u8 __devinit ata66_sis5513(ide_hwif_t *hwif)
return ata66 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
}
-static void __devinit init_hwif_sis5513(ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &sis_set_pio_mode;
- hwif->set_dma_mode = &sis_set_dma_mode;
-
- if (chipset_family >= ATA_133)
- hwif->udma_filter = sis5513_ata133_udma_filter;
+static const struct ide_port_ops sis_port_ops = {
+ .set_pio_mode = sis_set_pio_mode,
+ .set_dma_mode = sis_set_dma_mode,
+ .cable_detect = sis_cable_detect,
+};
- hwif->cable_detect = ata66_sis5513;
-}
+static const struct ide_port_ops sis_ata133_port_ops = {
+ .set_pio_mode = sis_set_pio_mode,
+ .set_dma_mode = sis_set_dma_mode,
+ .udma_filter = sis_ata133_udma_filter,
+ .cable_detect = sis_cable_detect,
+};
static const struct ide_port_info sis5513_chipset __devinitdata = {
.name = "SIS5513",
.init_chipset = init_chipset_sis5513,
- .init_hwif = init_hwif_sis5513,
.enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} },
.host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA,
.pio_mask = ATA_PIO4,
@@ -572,6 +573,11 @@ static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_devi
if (sis_find_family(dev) == 0)
return -ENOTSUPP;
+ if (chipset_family >= ATA_133)
+ d.port_ops = &sis_ata133_port_ops;
+ else
+ d.port_ops = &sis_port_ops;
+
d.udma_mask = udma_rates[chipset_family];
return ide_setup_pci_device(dev, &d);
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 40b3eeb2d84..ce84fa045d3 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -179,7 +179,7 @@ static void sl82c105_dma_start(ide_drive_t *drive)
struct pci_dev *dev = to_pci_dev(hwif->dev);
int reg = 0x44 + drive->dn * 4;
- DBG(("%s(drive:%s)\n", __FUNCTION__, drive->name));
+ DBG(("%s(drive:%s)\n", __func__, drive->name));
pci_write_config_word(dev, reg, drive->drive_data >> 16);
@@ -203,7 +203,7 @@ static int sl82c105_dma_end(ide_drive_t *drive)
int reg = 0x44 + drive->dn * 4;
int ret;
- DBG(("%s(drive:%s)\n", __FUNCTION__, drive->name));
+ DBG(("%s(drive:%s)\n", __func__, drive->name));
ret = __ide_dma_end(drive);
@@ -232,7 +232,7 @@ static void sl82c105_resetproc(ide_drive_t *drive)
* Return the revision of the Winbond bridge
* which this function is part of.
*/
-static unsigned int sl82c105_bridge_revision(struct pci_dev *dev)
+static u8 sl82c105_bridge_revision(struct pci_dev *dev)
{
struct pci_dev *bridge;
@@ -282,63 +282,59 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
return dev->irq;
}
-/*
- * Initialise IDE channel
- */
-static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
-{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
- unsigned int rev;
-
- DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));
-
- hwif->set_pio_mode = &sl82c105_set_pio_mode;
- hwif->set_dma_mode = &sl82c105_set_dma_mode;
- hwif->resetproc = &sl82c105_resetproc;
-
- if (!hwif->dma_base)
- return;
-
- rev = sl82c105_bridge_revision(dev);
- if (rev <= 5) {
- /*
- * Never ever EVER under any circumstances enable
- * DMA when the bridge is this old.
- */
- printk(" %s: Winbond W83C553 bridge revision %d, "
- "BM-DMA disabled\n", hwif->name, rev);
- return;
- }
-
- hwif->mwdma_mask = ATA_MWDMA2;
-
- hwif->dma_lost_irq = &sl82c105_dma_lost_irq;
- hwif->dma_start = &sl82c105_dma_start;
- hwif->ide_dma_end = &sl82c105_dma_end;
- hwif->dma_timeout = &sl82c105_dma_timeout;
+static const struct ide_port_ops sl82c105_port_ops = {
+ .set_pio_mode = sl82c105_set_pio_mode,
+ .set_dma_mode = sl82c105_set_dma_mode,
+ .resetproc = sl82c105_resetproc,
+};
- if (hwif->mate)
- hwif->serialized = hwif->mate->serialized = 1;
-}
+static const struct ide_dma_ops sl82c105_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = sl82c105_dma_start,
+ .dma_end = sl82c105_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_lost_irq = sl82c105_dma_lost_irq,
+ .dma_timeout = sl82c105_dma_timeout,
+};
static const struct ide_port_info sl82c105_chipset __devinitdata = {
.name = "W82C105",
.init_chipset = init_chipset_sl82c105,
- .init_hwif = init_hwif_sl82c105,
.enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
+ .port_ops = &sl82c105_port_ops,
+ .dma_ops = &sl82c105_dma_ops,
.host_flags = IDE_HFLAG_IO_32BIT |
IDE_HFLAG_UNMASK_IRQS |
/* FIXME: check for Compatibility mode in generic IDE PCI code */
#if defined(CONFIG_LOPEC) || defined(CONFIG_SANDPOINT)
IDE_HFLAG_FORCE_LEGACY_IRQS |
#endif
+ IDE_HFLAG_SERIALIZE_DMA |
IDE_HFLAG_NO_AUTODMA,
.pio_mask = ATA_PIO5,
+ .mwdma_mask = ATA_MWDMA2,
};
static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- return ide_setup_pci_device(dev, &sl82c105_chipset);
+ struct ide_port_info d = sl82c105_chipset;
+ u8 rev = sl82c105_bridge_revision(dev);
+
+ if (rev <= 5) {
+ /*
+ * Never ever EVER under any circumstances enable
+ * DMA when the bridge is this old.
+ */
+ printk(KERN_INFO "W82C105_IDE: Winbond W83C553 bridge "
+ "revision %d, BM-DMA disabled\n", rev);
+ d.dma_ops = NULL;
+ d.mwdma_mask = 0;
+ d.host_flags &= ~IDE_HFLAG_SERIALIZE_DMA;
+ }
+
+ return ide_setup_pci_device(dev, &d);
}
static const struct pci_device_id sl82c105_pci_tbl[] = {
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index eab557c45d1..dae6e2c94d8 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -125,18 +125,16 @@ static u8 __devinit slc90e66_cable_detect(ide_hwif_t *hwif)
return (reg47 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
}
-static void __devinit init_hwif_slc90e66(ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &slc90e66_set_pio_mode;
- hwif->set_dma_mode = &slc90e66_set_dma_mode;
-
- hwif->cable_detect = slc90e66_cable_detect;
-}
+static const struct ide_port_ops slc90e66_port_ops = {
+ .set_pio_mode = slc90e66_set_pio_mode,
+ .set_dma_mode = slc90e66_set_dma_mode,
+ .cable_detect = slc90e66_cable_detect,
+};
static const struct ide_port_info slc90e66_chipset __devinitdata = {
.name = "SLC90E66",
- .init_hwif = init_hwif_slc90e66,
.enablebits = { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} },
+ .port_ops = &slc90e66_port_ops,
.host_flags = IDE_HFLAG_LEGACY_IRQS,
.pio_mask = ATA_PIO4,
.swdma_mask = ATA_SWDMA2_ONLY,
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index c15435182e3..9b4b27a4c71 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -157,11 +157,6 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
/* Store the system control register base for convenience... */
hwif->config_data = sc_base;
- hwif->set_pio_mode = &tc86c001_set_pio_mode;
- hwif->set_dma_mode = &tc86c001_set_mode;
-
- hwif->cable_detect = tc86c001_cable_detect;
-
if (!hwif->dma_base)
return;
@@ -173,8 +168,6 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
/* Sector Count Register limit */
hwif->rqsize = 0xffff;
-
- hwif->dma_start = &tc86c001_dma_start;
}
static unsigned int __devinit init_chipset_tc86c001(struct pci_dev *dev,
@@ -187,10 +180,29 @@ static unsigned int __devinit init_chipset_tc86c001(struct pci_dev *dev,
return err;
}
+static const struct ide_port_ops tc86c001_port_ops = {
+ .set_pio_mode = tc86c001_set_pio_mode,
+ .set_dma_mode = tc86c001_set_mode,
+ .cable_detect = tc86c001_cable_detect,
+};
+
+static const struct ide_dma_ops tc86c001_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = tc86c001_dma_start,
+ .dma_end = __ide_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
+
static const struct ide_port_info tc86c001_chipset __devinitdata = {
.name = "TC86C001",
.init_chipset = init_chipset_tc86c001,
.init_hwif = init_hwif_tc86c001,
+ .port_ops = &tc86c001_port_ops,
+ .dma_ops = &tc86c001_dma_ops,
.host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_OFF_BOARD |
IDE_HFLAG_ABUSE_SET_DMA_MODE,
.pio_mask = ATA_PIO4,
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index 3316b197c77..db65a558d4e 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -87,16 +87,15 @@ static void triflex_set_pio_mode(ide_drive_t *drive, const u8 pio)
triflex_set_mode(drive, XFER_PIO_0 + pio);
}
-static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &triflex_set_pio_mode;
- hwif->set_dma_mode = &triflex_set_mode;
-}
+static const struct ide_port_ops triflex_port_ops = {
+ .set_pio_mode = triflex_set_pio_mode,
+ .set_dma_mode = triflex_set_mode,
+};
static const struct ide_port_info triflex_device __devinitdata = {
.name = "TRIFLEX",
- .init_hwif = init_hwif_triflex,
.enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
+ .port_ops = &triflex_port_ops,
.pio_mask = ATA_PIO4,
.swdma_mask = ATA_SWDMA2,
.mwdma_mask = ATA_MWDMA2,
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
index 2b8f3a2837d..a8a3138682e 100644
--- a/drivers/ide/pci/trm290.c
+++ b/drivers/ide/pci/trm290.c
@@ -214,7 +214,7 @@ static void trm290_dma_start(ide_drive_t *drive)
{
}
-static int trm290_ide_dma_end (ide_drive_t *drive)
+static int trm290_dma_end(ide_drive_t *drive)
{
u16 status;
@@ -225,7 +225,7 @@ static int trm290_ide_dma_end (ide_drive_t *drive)
return status != 0x00ff;
}
-static int trm290_ide_dma_test_irq (ide_drive_t *drive)
+static int trm290_dma_test_irq(ide_drive_t *drive)
{
u16 status;
@@ -254,22 +254,11 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
hwif->config_data = cfg_base;
hwif->dma_base = (cfg_base + 4) ^ (hwif->channel ? 0x80 : 0);
- printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx",
+ printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n",
hwif->name, hwif->dma_base, hwif->dma_base + 3);
- if (!request_region(hwif->dma_base, 4, hwif->name)) {
- printk(KERN_CONT " -- Error, ports in use.\n");
+ if (ide_allocate_dma_engine(hwif))
return;
- }
-
- hwif->dmatable_cpu = pci_alloc_consistent(dev, PRD_ENTRIES * PRD_BYTES,
- &hwif->dmatable_dma);
- if (!hwif->dmatable_cpu) {
- printk(KERN_CONT " -- Error, unable to allocate DMA table.\n");
- release_region(hwif->dma_base, 4);
- return;
- }
- printk(KERN_CONT "\n");
local_irq_save(flags);
/* put config reg into first byte of hwif->select_data */
@@ -291,14 +280,6 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
/* sharing IRQ with mate */
hwif->irq = hwif->mate->irq;
- hwif->dma_host_set = &trm290_dma_host_set;
- hwif->dma_setup = &trm290_dma_setup;
- hwif->dma_exec_cmd = &trm290_dma_exec_cmd;
- hwif->dma_start = &trm290_dma_start;
- hwif->ide_dma_end = &trm290_ide_dma_end;
- hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq;
-
- hwif->selectproc = &trm290_selectproc;
#if 1
{
/*
@@ -317,7 +298,7 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
if (old != compat && old_mask == 0xff) {
/* leave lower 10 bits untouched */
compat += (next_offset += 0x400);
- hwif->io_ports[IDE_CONTROL_OFFSET] = compat + 2;
+ hwif->io_ports.ctl_addr = compat + 2;
outw(compat | 1, hwif->config_data);
new = inw(hwif->config_data);
printk(KERN_INFO "%s: control basereg workaround: "
@@ -328,10 +309,27 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
#endif
}
+static const struct ide_port_ops trm290_port_ops = {
+ .selectproc = trm290_selectproc,
+};
+
+static struct ide_dma_ops trm290_dma_ops = {
+ .dma_host_set = trm290_dma_host_set,
+ .dma_setup = trm290_dma_setup,
+ .dma_exec_cmd = trm290_dma_exec_cmd,
+ .dma_start = trm290_dma_start,
+ .dma_end = trm290_dma_end,
+ .dma_test_irq = trm290_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
+
static const struct ide_port_info trm290_chipset __devinitdata = {
.name = "TRM290",
.init_hwif = init_hwif_trm290,
.chipset = ide_trm290,
+ .port_ops = &trm290_port_ops,
+ .dma_ops = &trm290_dma_ops,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA |
#if 0 /* play it safe for now */
IDE_HFLAG_TRUST_BIOS_FOR_DMA |
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index cff3cafedc4..566e0ecb8db 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -340,7 +340,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
* Determine system bus clock.
*/
- via_clock = system_bus_clock() * 1000;
+ via_clock = (ide_pci_clk ? ide_pci_clk : system_bus_clock()) * 1000;
switch (via_clock) {
case 33000: via_clock = 33333; break;
@@ -415,19 +415,17 @@ static u8 __devinit via82cxxx_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA40;
}
-static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
-{
- hwif->set_pio_mode = &via_set_pio_mode;
- hwif->set_dma_mode = &via_set_drive;
-
- hwif->cable_detect = via82cxxx_cable_detect;
-}
+static const struct ide_port_ops via_port_ops = {
+ .set_pio_mode = via_set_pio_mode,
+ .set_dma_mode = via_set_drive,
+ .cable_detect = via82cxxx_cable_detect,
+};
static const struct ide_port_info via82cxxx_chipset __devinitdata = {
.name = "VP_IDE",
.init_chipset = init_chipset_via82cxxx,
- .init_hwif = init_hwif_via82cxxx,
.enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
+ .port_ops = &via_port_ops,
.host_flags = IDE_HFLAG_PIO_NO_BLACKLIST |
IDE_HFLAG_ABUSE_SET_DMA_MODE |
IDE_HFLAG_POST_SET_MODE |
diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c
index 467656f06cc..f0e638dcc3a 100644
--- a/drivers/ide/ppc/mpc8xx.c
+++ b/drivers/ide/ppc/mpc8xx.c
@@ -131,7 +131,7 @@ static int pcmcia_schlvl = PCMCIA_SCHLVL;
#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT)
static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
{
- unsigned long *p = hw->io_ports;
+ unsigned long *p = hw->io_ports_array;
int i;
typedef struct {
@@ -314,7 +314,7 @@ static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
#if defined(CONFIG_IDE_EXT_DIRECT)
static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
{
- unsigned long *p = hw->io_ports;
+ unsigned long *p = hw->io_ports_array;
int i;
u32 ide_phy_base;
@@ -438,10 +438,14 @@ static void m8xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
#elif defined(CONFIG_IDE_EXT_DIRECT)
printk("%s[%d] %s: not implemented yet!\n",
- __FILE__,__LINE__,__FUNCTION__);
+ __FILE__, __LINE__, __func__);
#endif /* defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_PCMCIA */
}
+static const struct ide_port_ops m8xx_port_ops = {
+ .set_pio_mode = m8xx_ide_set_pio_mode,
+};
+
static void
ide_interrupt_ack (void *dev)
{
@@ -807,26 +811,28 @@ static int __init mpc8xx_ide_probe(void)
#ifdef IDE0_BASE_OFFSET
memset(&hw, 0, sizeof(hw));
if (!m8xx_ide_init_ports(&hw, 0)) {
- ide_hwif_t *hwif = &ide_hwifs[0];
+ ide_hwif_t *hwif = ide_find_port();
- ide_init_port_hw(hwif, &hw);
- hwif->mmio = 1;
- hwif->pio_mask = ATA_PIO4;
- hwif->set_pio_mode = m8xx_ide_set_pio_mode;
+ if (hwif) {
+ ide_init_port_hw(hwif, &hw);
+ hwif->pio_mask = ATA_PIO4;
+ hwif->port_ops = &m8xx_port_ops;
- idx[0] = 0;
+ idx[0] = hwif->index;
+ }
}
#ifdef IDE1_BASE_OFFSET
memset(&hw, 0, sizeof(hw));
if (!m8xx_ide_init_ports(&hw, 1)) {
- ide_hwif_t *mate = &ide_hwifs[1];
+ ide_hwif_t *mate = ide_find_port();
- ide_init_port_hw(mate, &hw);
- mate->mmio = 1;
- mate->pio_mask = ATA_PIO4;
- mate->set_pio_mode = m8xx_ide_set_pio_mode;
+ if (mate) {
+ ide_init_port_hw(mate, &hw);
+ mate->pio_mask = ATA_PIO4;
+ mate->port_ops = &m8xx_port_ops;
- idx[1] = 1;
+ idx[1] = mate->index;
+ }
}
#endif
#endif
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 177961edc43..48aa019127b 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -409,7 +409,7 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
*/
#define IDE_WAKEUP_DELAY (1*HZ)
-static int pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif);
+static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *);
static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq);
static void pmac_ide_selectproc(ide_drive_t *drive);
static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
@@ -417,7 +417,7 @@ static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
#define PMAC_IDE_REG(x) \
- ((void __iomem *)((drive)->hwif->io_ports[IDE_DATA_OFFSET] + (x)))
+ ((void __iomem *)((drive)->hwif->io_ports.data_addr + (x)))
/*
* Apply the timings of the proper unit (master/slave) to the shared
@@ -918,11 +918,30 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
return 0;
}
+static const struct ide_port_ops pmac_ide_ata6_port_ops = {
+ .set_pio_mode = pmac_ide_set_pio_mode,
+ .set_dma_mode = pmac_ide_set_dma_mode,
+ .selectproc = pmac_ide_kauai_selectproc,
+};
+
+static const struct ide_port_ops pmac_ide_port_ops = {
+ .set_pio_mode = pmac_ide_set_pio_mode,
+ .set_dma_mode = pmac_ide_set_dma_mode,
+ .selectproc = pmac_ide_selectproc,
+};
+
+static const struct ide_dma_ops pmac_dma_ops;
+
static const struct ide_port_info pmac_port_info = {
+ .init_dma = pmac_ide_init_dma,
.chipset = ide_pmac,
+#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+ .dma_ops = &pmac_dma_ops,
+#endif
+ .port_ops = &pmac_ide_port_ops,
.host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA |
IDE_HFLAG_POST_SET_MODE |
- IDE_HFLAG_NO_DMA | /* no SFF-style DMA */
+ IDE_HFLAG_MMIO |
IDE_HFLAG_UNMASK_IRQS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -947,12 +966,15 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
pmif->broken_dma = pmif->broken_dma_warn = 0;
if (of_device_is_compatible(np, "shasta-ata")) {
pmif->kind = controller_sh_ata6;
+ d.port_ops = &pmac_ide_ata6_port_ops;
d.udma_mask = ATA_UDMA6;
} else if (of_device_is_compatible(np, "kauai-ata")) {
pmif->kind = controller_un_ata6;
+ d.port_ops = &pmac_ide_ata6_port_ops;
d.udma_mask = ATA_UDMA5;
} else if (of_device_is_compatible(np, "K2-UATA")) {
pmif->kind = controller_k2_ata6;
+ d.port_ops = &pmac_ide_ata6_port_ops;
d.udma_mask = ATA_UDMA5;
} else if (of_device_is_compatible(np, "keylargo-ata")) {
if (strcmp(np->name, "ata-4") == 0) {
@@ -1029,37 +1051,29 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
default_hwif_mmiops(hwif);
hwif->OUTBSYNC = pmac_outbsync;
- /* Tell common code _not_ to mess with resources */
- hwif->mmio = 1;
hwif->hwif_data = pmif;
ide_init_port_hw(hwif, hw);
- hwif->noprobe = pmif->mediabay;
hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
- hwif->set_pio_mode = pmac_ide_set_pio_mode;
- if (pmif->kind == controller_un_ata6
- || pmif->kind == controller_k2_ata6
- || pmif->kind == controller_sh_ata6)
- hwif->selectproc = pmac_ide_kauai_selectproc;
- else
- hwif->selectproc = pmac_ide_selectproc;
- hwif->set_dma_mode = pmac_ide_set_dma_mode;
printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n",
hwif->index, model_name[pmif->kind], pmif->aapl_bus_id,
pmif->mediabay ? " (mediabay)" : "", hwif->irq);
-
+
+ if (pmif->mediabay) {
#ifdef CONFIG_PMAC_MEDIABAY
- if (pmif->mediabay && check_media_bay_by_base(pmif->regbase, MB_CD) == 0)
- hwif->noprobe = 0;
-#endif /* CONFIG_PMAC_MEDIABAY */
+ if (check_media_bay_by_base(pmif->regbase, MB_CD)) {
+#else
+ if (1) {
+#endif
+ hwif->drives[0].noprobe = 1;
+ hwif->drives[1].noprobe = 1;
+ }
+ }
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
if (pmif->cable_80 == 0)
d.udma_mask &= ATA_UDMA2;
- /* has a DBDMA controller channel */
- if (pmif->dma_regs == 0 || pmac_ide_setup_dma(pmif, hwif) < 0)
#endif
- d.udma_mask = d.mwdma_mask = 0;
idx[0] = hwif->index;
@@ -1073,8 +1087,9 @@ static void __devinit pmac_ide_init_ports(hw_regs_t *hw, unsigned long base)
int i;
for (i = 0; i < 8; ++i)
- hw->io_ports[i] = base + i * 0x10;
- hw->io_ports[8] = base + 0x160;
+ hw->io_ports_array[i] = base + i * 0x10;
+
+ hw->io_ports.ctl_addr = base + 0x160;
}
/*
@@ -1662,18 +1677,31 @@ pmac_ide_dma_lost_irq (ide_drive_t *drive)
printk(KERN_ERR "ide-pmac lost interrupt, dma status: %lx\n", status);
}
+static const struct ide_dma_ops pmac_dma_ops = {
+ .dma_host_set = pmac_ide_dma_host_set,
+ .dma_setup = pmac_ide_dma_setup,
+ .dma_exec_cmd = pmac_ide_dma_exec_cmd,
+ .dma_start = pmac_ide_dma_start,
+ .dma_end = pmac_ide_dma_end,
+ .dma_test_irq = pmac_ide_dma_test_irq,
+ .dma_timeout = ide_dma_timeout,
+ .dma_lost_irq = pmac_ide_dma_lost_irq,
+};
+
/*
* Allocate the data structures needed for using DMA with an interface
* and fill the proper list of functions pointers
*/
-static int __devinit pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
+static int __devinit pmac_ide_init_dma(ide_hwif_t *hwif,
+ const struct ide_port_info *d)
{
+ pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
struct pci_dev *dev = to_pci_dev(hwif->dev);
/* We won't need pci_dev if we switch to generic consistent
* DMA routines ...
*/
- if (dev == NULL)
+ if (dev == NULL || pmif->dma_regs == 0)
return -ENODEV;
/*
* Allocate space for the DBDMA commands.
@@ -1692,18 +1720,14 @@ static int __devinit pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
hwif->sg_max_nents = MAX_DCMDS;
- hwif->dma_host_set = &pmac_ide_dma_host_set;
- hwif->dma_setup = &pmac_ide_dma_setup;
- hwif->dma_exec_cmd = &pmac_ide_dma_exec_cmd;
- hwif->dma_start = &pmac_ide_dma_start;
- hwif->ide_dma_end = &pmac_ide_dma_end;
- hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
- hwif->dma_timeout = &ide_dma_timeout;
- hwif->dma_lost_irq = &pmac_ide_dma_lost_irq;
-
return 0;
}
-
+#else
+static int __devinit pmac_ide_init_dma(ide_hwif_t *hwif,
+ const struct ide_port_info *d)
+{
+ return -EOPNOTSUPP;
+}
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
module_init(pmac_ide_probe);
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 6302010fd8e..5171601fb25 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -72,16 +72,16 @@ static void ide_pci_clear_simplex(unsigned long dma_base, const char *name)
}
/**
- * ide_get_or_set_dma_base - setup BMIBA
- * @d: IDE port info
+ * ide_pci_dma_base - setup BMIBA
* @hwif: IDE interface
+ * @d: IDE port info
*
* Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space.
* Where a device has a partner that is already in DMA mode we check
* and enforce IDE simplex rules.
*/
-static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_hwif_t *hwif)
+unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long dma_base = 0;
@@ -132,6 +132,31 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_
out:
return dma_base;
}
+EXPORT_SYMBOL_GPL(ide_pci_dma_base);
+
+/*
+ * Set up BM-DMA capability (PnP BIOS should have done this)
+ */
+int ide_pci_set_master(struct pci_dev *dev, const char *name)
+{
+ u16 pcicmd;
+
+ pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
+
+ if ((pcicmd & PCI_COMMAND_MASTER) == 0) {
+ pci_set_master(dev);
+
+ if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) ||
+ (pcicmd & PCI_COMMAND_MASTER) == 0) {
+ printk(KERN_ERR "%s: error updating PCICMD on %s\n",
+ name, pci_name(dev));
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ide_pci_set_master);
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d)
@@ -158,7 +183,7 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
{
- int ret;
+ int ret, bars;
if (pci_enable_device(dev)) {
ret = pci_enable_device_io(dev);
@@ -181,13 +206,21 @@ static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
goto out;
}
- /* FIXME: Temporary - until we put in the hotplug interface logic
- Check that the bits we want are not in use by someone else. */
- ret = pci_request_region(dev, 4, "ide_tmp");
- if (ret < 0)
- goto out;
+ if (d->host_flags & IDE_HFLAG_SINGLE)
+ bars = (1 << 2) - 1;
+ else
+ bars = (1 << 4) - 1;
- pci_release_region(dev, 4);
+ if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
+ if (d->host_flags & IDE_HFLAG_CS5520)
+ bars |= (1 << 2);
+ else
+ bars |= (1 << 4);
+ }
+
+ ret = pci_request_selected_regions(dev, bars, d->name);
+ if (ret < 0)
+ printk(KERN_ERR "%s: can't reserve resources\n", d->name);
out:
return ret;
}
@@ -314,7 +347,6 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
ide_init_port_hw(hwif, &hw);
hwif->dev = &dev->dev;
- hwif->cds = d;
return hwif;
}
@@ -330,40 +362,33 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
* state
*/
-void ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
+int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
- u16 pcicmd;
-
- pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 ||
((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
(dev->class & 0x80))) {
- unsigned long dma_base = ide_get_or_set_dma_base(d, hwif);
- if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) {
- /*
- * Set up BM-DMA capability
- * (PnP BIOS should have done this)
- */
- pci_set_master(dev);
- if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) || !(pcicmd & PCI_COMMAND_MASTER)) {
- printk(KERN_ERR "%s: %s error updating PCICMD\n",
- hwif->name, d->name);
- dma_base = 0;
- }
- }
- if (dma_base) {
- if (d->init_dma) {
- d->init_dma(hwif, dma_base);
- } else {
- ide_setup_dma(hwif, dma_base);
- }
- } else {
- printk(KERN_INFO "%s: %s Bus-Master DMA disabled "
- "(BIOS)\n", hwif->name, d->name);
- }
+ unsigned long base = ide_pci_dma_base(hwif, d);
+
+ if (base == 0 || ide_pci_set_master(dev, d->name) < 0)
+ return -1;
+
+ if (hwif->mmio)
+ printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name);
+ else
+ printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n",
+ hwif->name, base, base + 7);
+
+ hwif->extra_base = base + (hwif->channel ? 8 : 16);
+
+ if (ide_allocate_dma_engine(hwif))
+ return -1;
+
+ ide_setup_dma(hwif, base);
}
+
+ return 0;
}
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */