summaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/Kconfig80
-rw-r--r--drivers/ide/Makefile4
-rw-r--r--drivers/ide/arm/bast-ide.c25
-rw-r--r--drivers/ide/arm/icside.c79
-rw-r--r--drivers/ide/arm/ide_arm.c20
-rw-r--r--drivers/ide/arm/palm_bk3710.c69
-rw-r--r--drivers/ide/arm/rapide.c12
-rw-r--r--drivers/ide/cris/Makefile3
-rw-r--r--drivers/ide/cris/ide-cris.c1071
-rw-r--r--drivers/ide/h8300/ide-h8300.c118
-rw-r--r--drivers/ide/ide-acpi.c32
-rw-r--r--drivers/ide/ide-cd.c952
-rw-r--r--drivers/ide/ide-cd.h4
-rw-r--r--drivers/ide/ide-disk.c159
-rw-r--r--drivers/ide/ide-dma.c164
-rw-r--r--drivers/ide/ide-floppy.c385
-rw-r--r--drivers/ide/ide-generic.c119
-rw-r--r--drivers/ide/ide-io.c91
-rw-r--r--drivers/ide/ide-iops.c432
-rw-r--r--drivers/ide/ide-lib.c46
-rw-r--r--drivers/ide/ide-pnp.c45
-rw-r--r--drivers/ide/ide-probe.c395
-rw-r--r--drivers/ide/ide-proc.c188
-rw-r--r--drivers/ide/ide-scan-pci.c11
-rw-r--r--drivers/ide/ide-tape.c1679
-rw-r--r--drivers/ide/ide-taskfile.c89
-rw-r--r--drivers/ide/ide.c866
-rw-r--r--drivers/ide/legacy/Makefile1
-rw-r--r--drivers/ide/legacy/ali14xx.c32
-rw-r--r--drivers/ide/legacy/buddha.c18
-rw-r--r--drivers/ide/legacy/dtc2278.c27
-rw-r--r--drivers/ide/legacy/falconide.c40
-rw-r--r--drivers/ide/legacy/gayle.c22
-rw-r--r--drivers/ide/legacy/hd.c78
-rw-r--r--drivers/ide/legacy/ht6560b.c54
-rw-r--r--drivers/ide/legacy/ide-4drives.c72
-rw-r--r--drivers/ide/legacy/ide-cs.c84
-rw-r--r--drivers/ide/legacy/ide_platform.c16
-rw-r--r--drivers/ide/legacy/macide.c8
-rw-r--r--drivers/ide/legacy/q40ide.c74
-rw-r--r--drivers/ide/legacy/qd65xx.c223
-rw-r--r--drivers/ide/legacy/qd65xx.h1
-rw-r--r--drivers/ide/legacy/umc8672.c80
-rw-r--r--drivers/ide/mips/au1xxx-ide.c172
-rw-r--r--drivers/ide/mips/swarm.c20
-rw-r--r--drivers/ide/pci/aec62xx.c39
-rw-r--r--drivers/ide/pci/alim15x3.c332
-rw-r--r--drivers/ide/pci/amd74xx.c19
-rw-r--r--drivers/ide/pci/atiixp.c29
-rw-r--r--drivers/ide/pci/cmd640.c318
-rw-r--r--drivers/ide/pci/cmd64x.c153
-rw-r--r--drivers/ide/pci/cs5520.c29
-rw-r--r--drivers/ide/pci/cs5530.c18
-rw-r--r--drivers/ide/pci/cs5535.c24
-rw-r--r--drivers/ide/pci/cy82c693.c97
-rw-r--r--drivers/ide/pci/delkin_cb.c20
-rw-r--r--drivers/ide/pci/generic.c10
-rw-r--r--drivers/ide/pci/hpt34x.c17
-rw-r--r--drivers/ide/pci/hpt366.c191
-rw-r--r--drivers/ide/pci/it8213.c34
-rw-r--r--drivers/ide/pci/it821x.c54
-rw-r--r--drivers/ide/pci/jmicron.c29
-rw-r--r--drivers/ide/pci/ns87415.c88
-rw-r--r--drivers/ide/pci/opti621.c82
-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.c18
-rw-r--r--drivers/ide/pci/rz1000.c2
-rw-r--r--drivers/ide/pci/sc1200.c39
-rw-r--r--drivers/ide/pci/scc_pata.c335
-rw-r--r--drivers/ide/pci/serverworks.c38
-rw-r--r--drivers/ide/pci/sgiioc4.c153
-rw-r--r--drivers/ide/pci/siimage.c712
-rw-r--r--drivers/ide/pci/sis5513.c253
-rw-r--r--drivers/ide/pci/sl82c105.c87
-rw-r--r--drivers/ide/pci/slc90e66.c22
-rw-r--r--drivers/ide/pci/tc86c001.c90
-rw-r--r--drivers/ide/pci/triflex.c12
-rw-r--r--drivers/ide/pci/trm290.c47
-rw-r--r--drivers/ide/pci/via82cxxx.c20
-rw-r--r--drivers/ide/ppc/mpc8xx.c142
-rw-r--r--drivers/ide/ppc/pmac.c282
-rw-r--r--drivers/ide/setup-pci.c246
83 files changed, 5033 insertions, 7365 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index eed6d8e1b5c7..f702f9152ce6 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -122,24 +122,6 @@ config BLK_DEV_IDE_SATA
If unsure, say N.
-config BLK_DEV_HD_IDE
- bool "Use old disk-only driver on primary interface"
- depends on (X86 || SH_MPC1211)
- ---help---
- There are two drivers for MFM/RLL/IDE disks. Most people use just
- the new enhanced driver by itself. This option however installs the
- old hard disk driver to control the primary IDE/disk interface in
- the system, leaving the new enhanced IDE driver to take care of only
- the 2nd/3rd/4th IDE interfaces. Doing this will prevent you from
- having an IDE/ATAPI CD-ROM or tape drive connected to the primary
- IDE interface. Choosing this option may be useful for older systems
- which have MFM/RLL/ESDI controller+drives at the primary port
- address (0x1f0), along with IDE drives at the secondary/3rd/4th port
- addresses.
-
- Normally, just say N here; you will then use the new driver for all
- 4 interfaces.
-
config BLK_DEV_IDEDISK
tristate "Include IDE/ATA-2 DISK support"
---help---
@@ -325,6 +307,7 @@ comment "IDE chipset support/bugfixes"
config IDE_GENERIC
tristate "generic/default IDE chipset support"
+ depends on ALPHA || X86 || IA64 || M32R || MIPS || PPC32
help
If unsure, say N.
@@ -416,12 +399,6 @@ config BLK_DEV_OFFBOARD
This can improve the usability of some boot managers such as lilo
when booting from a drive on an off-board controller.
- If you say Y here, and you actually want to reverse the device scan
- order as explained above, you also need to issue the kernel command
- line option "ide=reverse". (Try "man bootparam" or see the
- documentation of your boot loader (lilo or loadlin) about how to
- pass options to the kernel at boot time.)
-
Note that, if you do this, the order of the hd* devices will be
rearranged which may require modification of fstab and other files.
@@ -615,8 +592,7 @@ config BLK_DEV_HPT366
reference to device 0x80. The other solution is to say Y to "Boot
off-board chipsets first support" (CONFIG_BLK_DEV_OFFBOARD) unless
your mother board has the chipset natively mounted. Regardless one
- should use the fore mentioned option and call at LILO or include
- "ide=reverse" in LILO's append-line.
+ should use the fore mentioned option and call at LILO.
This driver requires dynamic tuning of the chipset during the
ide-probe at boot. It is reported to support DVD II drives, by the
@@ -886,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
@@ -1049,19 +991,19 @@ config IDE_EXT_DIRECT
endchoice
# no isa -> no vlb
-if ISA
+if ISA && (ALPHA || X86 || MIPS)
comment "Other IDE chipsets support"
comment "Note: most of these also require special kernel boot parameters"
config BLK_DEV_4DRIVES
- bool "Generic 4 drives/port support"
+ tristate "Generic 4 drives/port support"
help
Certain older chipsets, including the Tekram 690CD, use a single set
of I/O ports at 0x1f0 to control up to four drives, instead of the
customary two drives per port. Support for this can be enabled at
- runtime using the "ide0=four" kernel boot parameter if you say Y
- here.
+ runtime using the "ide-4drives.probe" kernel boot parameter if you
+ say Y here.
config BLK_DEV_ALI14XX
tristate "ALI M14xx support"
@@ -1114,14 +1056,10 @@ config BLK_DEV_IDEDMA
def_bool BLK_DEV_IDEDMA_SFF || BLK_DEV_IDEDMA_PMAC || \
BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-config IDE_ARCH_OBSOLETE_INIT
- def_bool ALPHA || (ARM && !ARCH_L7200) || BLACKFIN || X86 || IA64 || M32R || MIPS || PARISC || PPC || (SUPERH64 && BLK_DEV_IDEPCI) || SPARC
-
endif
config BLK_DEV_HD_ONLY
bool "Old hard disk (MFM/RLL/IDE) driver"
- depends on BLK_DEV_IDE=n
help
There are two drivers for MFM/RLL/IDE hard disks. Most people use
the newer enhanced driver, but this old one is still around for two
@@ -1133,12 +1071,16 @@ config BLK_DEV_HD_ONLY
for systems with only older MFM/RLL/ESDI drives. Choosing the old
driver can save 13 KB or so of kernel memory.
+ If you want to use this driver together with the new one you have
+ to use "hda=noprobe hdb=noprobe" kernel parameters to prevent the new
+ driver from probing the primary interface.
+
If you are unsure, then just choose the Enhanced IDE/MFM/RLL driver
instead of this one. For more detailed information, read the
Disk-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
config BLK_DEV_HD
- def_bool BLK_DEV_HD_IDE || BLK_DEV_HD_ONLY
+ def_bool BLK_DEV_HD_ONLY
endif # IDE
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index a4a4323be911..f94b679b611e 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -35,10 +35,10 @@ ifeq ($(CONFIG_BLK_DEV_CMD640), y)
obj-y += cmd640-core.o
endif
-obj-$(CONFIG_BLK_DEV_IDE) += cris/ ppc/
-obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o
+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
ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o
diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c
index 161d30c8481e..713cef20622e 100644
--- a/drivers/ide/arm/bast-ide.c
+++ b/drivers/ide/arm/bast-ide.c
@@ -21,6 +21,8 @@
#include <asm/arch/bast-map.h>
#include <asm/arch/bast-irq.h>
+#define DRV_NAME "bast-ide"
+
static int __init bastide_register(unsigned int base, unsigned int aux, int irq)
{
ide_hwif_t *hwif;
@@ -33,27 +35,23 @@ 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_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port();
if (hwif == NULL)
goto out;
i = hwif->index;
- if (hwif->present)
- ide_unregister(i, 0, 0);
- else if (!hwif->hold)
- ide_init_port_data(hwif, i);
-
+ ide_init_port_data(hwif, i);
ide_init_port_hw(hwif, &hw);
- hwif->quirkproc = NULL;
+ hwif->port_ops = NULL;
idx[0] = i;
@@ -64,6 +62,8 @@ out:
static int __init bastide_init(void)
{
+ unsigned long base = BAST_VA_IDEPRI + BAST_IDE_CS;
+
/* we can treat the VR1000 and the BAST the same */
if (!(machine_is_bast() || machine_is_vr1000()))
@@ -71,6 +71,11 @@ static int __init bastide_init(void)
printk("BAST: IDE driver, (c) 2003-2004 Simtec Electronics\n");
+ if (!request_mem_region(base, 0x400000, DRV_NAME)) {
+ printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
+ return -EBUSY;
+ }
+
bastide_register(BAST_VA_IDEPRI, BAST_VA_IDEPRIAUX, IRQ_IDE0);
bastide_register(BAST_VA_IDESEC, BAST_VA_IDESECAUX, IRQ_IDE1);
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index e816b0ffcfe6..061456914ca3 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,48 +384,57 @@ 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)
{
unsigned long port = (unsigned long)base + info->dataoffset;
ide_hwif_t *hwif;
- hwif = ide_find_port(port);
+ 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 be9ff7334c52..4263ffd4ab20 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,13 +30,27 @@ 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(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port();
if (hwif) {
ide_init_port_hw(hwif, &hw);
idx[0] = hwif->index;
diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c
index 8e1f6bd33887..96378ebfb31f 100644
--- a/drivers/ide/arm/palm_bk3710.c
+++ b/drivers/ide/arm/palm_bk3710.c
@@ -96,11 +96,11 @@ static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
u16 val16;
/* DMA Data Setup */
- t0 = (palm_bk3710_udmatimings[mode].cycletime + ide_palm_clk - 1)
- / ide_palm_clk - 1;
- tenv = (20 + ide_palm_clk - 1) / ide_palm_clk - 1;
- trp = (palm_bk3710_udmatimings[mode].rptime + ide_palm_clk - 1)
- / ide_palm_clk - 1;
+ t0 = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].cycletime,
+ ide_palm_clk) - 1;
+ tenv = DIV_ROUND_UP(20, ide_palm_clk) - 1;
+ trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime,
+ ide_palm_clk) - 1;
/* udmatim Register */
val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0);
@@ -141,8 +141,8 @@ static void palm_bk3710_setdmamode(void __iomem *base, unsigned int dev,
cycletime = max_t(int, t->cycle, min_cycle);
/* DMA Data Setup */
- t0 = (cycletime + ide_palm_clk - 1) / ide_palm_clk;
- td = (t->active + ide_palm_clk - 1) / ide_palm_clk;
+ t0 = DIV_ROUND_UP(cycletime, ide_palm_clk);
+ td = DIV_ROUND_UP(t->active, ide_palm_clk);
tkw = t0 - td - 1;
td -= 1;
@@ -168,9 +168,9 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
struct ide_timing *t;
/* PIO Data Setup */
- t0 = (cycletime + ide_palm_clk - 1) / ide_palm_clk;
- t2 = (ide_timing_find_mode(XFER_PIO_0 + mode)->active +
- ide_palm_clk - 1) / ide_palm_clk;
+ t0 = DIV_ROUND_UP(cycletime, ide_palm_clk);
+ t2 = DIV_ROUND_UP(ide_timing_find_mode(XFER_PIO_0 + mode)->active,
+ ide_palm_clk);
t2i = t0 - t2 - 1;
t2 -= 1;
@@ -192,8 +192,8 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
/* TASKFILE Setup */
t = ide_timing_find_mode(XFER_PIO_0 + mode);
- t0 = (t->cyc8b + ide_palm_clk - 1) / ide_palm_clk;
- t2 = (t->act8b + ide_palm_clk - 1) / ide_palm_clk;
+ t0 = DIV_ROUND_UP(t->cyc8b, ide_palm_clk);
+ t2 = DIV_ROUND_UP(t->act8b, ide_palm_clk);
t2i = t0 - t2 - 1;
t2 -= 1;
@@ -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,30 +387,24 @@ 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;
- hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port();
if (hwif == NULL)
goto out;
i = hwif->index;
- if (hwif->present)
- ide_unregister(i, 0, 0);
- else if (!hwif->hold)
- 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);
@@ -409,9 +418,13 @@ out:
return -ENODEV;
}
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:palm_bk3710");
+
static struct platform_driver platform_bk_driver = {
.driver = {
.name = "palm_bk3710",
+ .owner = THIS_MODULE,
},
.probe = palm_bk3710_probe,
.remove = NULL,
diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c
index efba00d2fc37..1747b2358775 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;
}
@@ -44,7 +44,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
goto release;
}
- hwif = ide_find_port((unsigned long)base);
+ hwif = ide_find_port();
if (hwif) {
memset(&hw, 0, sizeof(hw));
rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->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, 0, 0);
+ ide_unregister(hwif);
ecard_release_resources(ec);
}
diff --git a/drivers/ide/cris/Makefile b/drivers/ide/cris/Makefile
deleted file mode 100644
index 20b95960531f..000000000000
--- 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 c8ffbaf29a88..000000000000
--- a/drivers/ide/cris/ide-cris.c
+++ /dev/null
@@ -1,1071 +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)
-{
- reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2, int, IDE_DATA_REG);
- 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)
-{
- int intr = REG_RD_INT(ata, regi_ata, r_intr);
- reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2, int, IDE_DATA_REG);
- 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, IDE_DATA_REG) |
- 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, IDE_DATA_REG);
- 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(hw.io_ports[IDE_DATA_OFFSET]);
- 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 4108ec4ffa7f..ecf53bb0d2aa 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)
@@ -99,8 +194,7 @@ static int __init h8300_ide_init(void)
hw_setup(&hw);
- /* register if */
- hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port();
if (hwif == NULL) {
printk(KERN_ERR "ide-h8300: IDE I/F register failed\n");
return -ENOENT;
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index e07b189f3ec8..9d3601fa5680 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;
}
@@ -710,6 +718,8 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
for (i = 0; i < MAX_DRIVES; i++) {
drive = &hwif->drives[i];
+ memset(drive->acpidata, 0, sizeof(*drive->acpidata));
+
if (!drive->present)
continue;
@@ -719,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 c8d0e8715997..fe9df38f62cc 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -13,8 +13,8 @@
*
* Suggestions are welcome. Patches that work are more welcome though. ;-)
* For those wishing to work on this driver, please be sure you download
- * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
- * (SFF-8020i rev 2.6) standards. These documents can be obtained by
+ * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
+ * (SFF-8020i rev 2.6) standards. These documents can be obtained by
* anonymous ftp from:
* ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
* ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
@@ -39,19 +39,20 @@
#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"
static DEFINE_MUTEX(idecd_ref_mutex);
-#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref)
+#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref)
#define ide_cd_g(disk) \
container_of((disk)->private_data, struct cdrom_info, driver)
@@ -77,19 +78,17 @@ 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. */
-static void cdrom_saw_media_change (ide_drive_t *drive)
+/* 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;
cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED;
cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID;
- cd->nsectors_buffered = 0;
}
static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
@@ -101,66 +100,65 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
return 0;
switch (sense->sense_key) {
- case NO_SENSE: case RECOVERED_ERROR:
- break;
- case NOT_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;
- log = 1;
- break;
- case ILLEGAL_REQUEST:
- /*
- * 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;
- log = 1;
- 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.
- */
- cdrom_saw_media_change(drive);
+ case NO_SENSE:
+ case RECOVERED_ERROR:
+ break;
+ case NOT_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;
- default:
- log = 1;
+ log = 1;
+ break;
+ case ILLEGAL_REQUEST:
+ /*
+ * 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;
+ log = 1;
+ 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.
+ */
+ cdrom_saw_media_change(drive);
+ break;
+ default:
+ log = 1;
+ break;
}
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 */
- switch(sense->sense_key) {
+ /* current error */
+ if (sense->error_code == 0x70) {
+ switch (sense->sense_key) {
case MEDIUM_ERROR:
case VOLUME_OVERFLOW:
case ILLEGAL_REQUEST:
@@ -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 */
- sector &= ~(bio_sectors -1);
- valid = (sector - failed_command->sector) << 9;
+ /* device sector size is 2K */
+ sector <<= 2;
+
+ bio_sectors = max(bio_sectors(failed_command->bio), 4U);
+ sector &= ~(bio_sectors - 1);
- 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;
@@ -230,7 +223,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
(void) ide_do_drive_cmd(drive, rq, ide_preempt);
}
-static void cdrom_end_request (ide_drive_t *drive, int uptodate)
+static void cdrom_end_request(ide_drive_t *drive, int uptodate)
{
struct request *rq = HWGROUP(drive)->rq;
int nsectors = rq->hard_cur_sectors;
@@ -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,28 +330,27 @@ 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);
+ cdrom_saw_media_change(drive);
} else if (sense_key == UNIT_ATTENTION) {
- /* Check for media change. */
- cdrom_saw_media_change (drive);
- /*printk("%s: media changed\n",drive->name);*/
+ /* check for media change */
+ cdrom_saw_media_change(drive);
return 0;
- } else if ((sense_key == ILLEGAL_REQUEST) &&
- (rq->cmd[0] == GPCMD_START_STOP_UNIT)) {
- /*
- * Don't print error message for this condition--
- * SFF8090i indicates that 5/24/00 is the correct
- * response to a request to close the tray if the
- * drive doesn't have that capability.
- * cdrom_log_sense() knows this!
- */
+ } else if (sense_key == ILLEGAL_REQUEST &&
+ rq->cmd[0] == GPCMD_START_STOP_UNIT) {
+ /*
+ * Don't print error message for this condition--
+ * SFF8090i indicates that 5/24/00 is the correct
+ * response to a request to close the tray if the
+ * drive doesn't have that capability.
+ * 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);
}
-
+
rq->cmd_flags |= REQ_FAILED;
/*
@@ -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);
+ 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,59 +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.*/
- ide_dump_status_no_sense (drive, "command error", stat);
+ /*
+ * 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 */
- ide_dump_status_no_sense (drive, "media error (bad sector)", stat);
+ /*
+ * No point in re-trying a zillion times on a bad
+ * sector. If we got here the error is not correctable.
+ */
+ 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);
@@ -455,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:
@@ -480,35 +489,37 @@ 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:
- case GPCMD_FORMAT_UNIT:
- case GPCMD_RESERVE_RZONE_TRACK:
- case GPCMD_CLOSE_TRACK:
- case GPCMD_FLUSH_CACHE:
- wait = ATAPI_WAIT_PC;
- break;
- default:
- if (!(rq->cmd_flags & REQ_QUIET))
- printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]);
- wait = 0;
- break;
+ case GPCMD_BLANK:
+ case GPCMD_FORMAT_UNIT:
+ case GPCMD_RESERVE_RZONE_TRACK:
+ case GPCMD_CLOSE_TRACK:
+ case GPCMD_FLUSH_CACHE:
+ wait = ATAPI_WAIT_PC;
+ break;
+ default:
+ if (!(rq->cmd_flags & REQ_QUIET))
+ 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)
@@ -517,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);
@@ -535,28 +546,24 @@ 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, IDE_COMMAND_REG);
- 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,
+static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
struct request *rq,
ide_handler_t *handler)
{
@@ -566,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 */
@@ -591,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);
}
}
@@ -619,53 +627,12 @@ 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--;
}
}
/*
- * Buffer up to SECTORS_TO_TRANSFER sectors from the drive in our sector
- * buffer. Once the first sector is added, any subsequent sectors are
- * assumed to be continuous (until the buffer is cleared). For the first
- * sector added, SECTOR is its sector number. (SECTOR is then ignored until
- * the buffer is cleared.)
- */
-static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
- int sectors_to_transfer)
-{
- struct cdrom_info *info = drive->driver_data;
-
- /* Number of sectors to read into the buffer. */
- int sectors_to_buffer = min_t(int, sectors_to_transfer,
- (SECTOR_BUFFER_SIZE >> SECTOR_BITS) -
- info->nsectors_buffered);
-
- char *dest;
-
- /* If we couldn't get a buffer, don't try to buffer anything... */
- if (info->buffer == NULL)
- sectors_to_buffer = 0;
-
- /* If this is the first sector in the buffer, remember its number. */
- if (info->nsectors_buffered == 0)
- info->sector_buffered = sector;
-
- /* Read the data into the buffer. */
- dest = info->buffer + info->nsectors_buffered * SECTOR_SIZE;
- while (sectors_to_buffer > 0) {
- HWIF(drive)->atapi_input_bytes(drive, dest, SECTOR_SIZE);
- --sectors_to_buffer;
- --sectors_to_transfer;
- ++info->nsectors_buffered;
- dest += SECTOR_SIZE;
- }
-
- /* Throw away any remaining data. */
- ide_cd_drain_data(drive, sectors_to_transfer);
-}
-
-/*
* Check the contents of the interrupt reason register from the cdrom
* and attempt to recover if there are problems. Returns 0 if everything's
* ok; nonzero if the request has been terminated.
@@ -683,22 +650,23 @@ 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, __FUNCTION__);
+ 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, __FUNCTION__, ireason);
+ drive->name, __func__, ireason);
}
if (rq->cmd_type == REQ_TYPE_ATA_PC)
@@ -720,7 +688,7 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
return 0;
printk(KERN_ERR "%s: %s: Bad transfer size %d\n",
- drive->name, __FUNCTION__, len);
+ drive->name, __func__, len);
if (cd->cd_flags & IDE_CD_FLAG_LIMIT_NFRAMES)
printk(KERN_ERR " This drive is not supported by "
@@ -733,72 +701,13 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
return 1;
}
-/*
- * Try to satisfy some of the current read request from our cached data.
- * Returns nonzero if the request has been completed, zero otherwise.
- */
-static int cdrom_read_from_buffer (ide_drive_t *drive)
-{
- struct cdrom_info *info = drive->driver_data;
- struct request *rq = HWGROUP(drive)->rq;
- unsigned short sectors_per_frame;
-
- sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
-
- /* Can't do anything if there's no buffer. */
- if (info->buffer == NULL) return 0;
-
- /* Loop while this request needs data and the next block is present
- in our cache. */
- while (rq->nr_sectors > 0 &&
- rq->sector >= info->sector_buffered &&
- rq->sector < info->sector_buffered + info->nsectors_buffered) {
- if (rq->current_nr_sectors == 0)
- cdrom_end_request(drive, 1);
-
- memcpy (rq->buffer,
- info->buffer +
- (rq->sector - info->sector_buffered) * SECTOR_SIZE,
- SECTOR_SIZE);
- rq->buffer += SECTOR_SIZE;
- --rq->current_nr_sectors;
- --rq->nr_sectors;
- ++rq->sector;
- }
-
- /* If we've satisfied the current request,
- terminate it successfully. */
- if (rq->nr_sectors == 0) {
- cdrom_end_request(drive, 1);
- return -1;
- }
-
- /* Move on to the next buffer if needed. */
- if (rq->current_nr_sectors == 0)
- cdrom_end_request(drive, 1);
-
- /* If this condition does not hold, then the kluge i use to
- represent the number of sectors to skip at the start of a transfer
- will fail. I think that this will never happen, but let's be
- paranoid and check. */
- if (rq->current_nr_sectors < bio_cur_sectors(rq->bio) &&
- (rq->sector & (sectors_per_frame - 1))) {
- printk(KERN_ERR "%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
- drive->name, (long)rq->sector);
- cdrom_end_request(drive, 0);
- return -1;
- }
-
- return 0;
-}
-
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)
{
@@ -820,11 +729,11 @@ 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",
- drive->name, __FUNCTION__,
+ drive->name, __func__,
rq->current_nr_sectors);
cdrom_end_request(drive, 0);
return ide_stopped;
@@ -837,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);
}
@@ -848,7 +757,7 @@ static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
#define IDECD_SEEK_TIMER (5 * WAIT_MIN_SLEEP) /* 100 ms */
#define IDECD_SEEK_TIMEOUT (2 * WAIT_CMD) /* 20 sec */
-static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive)
+static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
int stat;
@@ -860,19 +769,13 @@ 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;
}
-static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
+static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
sector_t frame = rq->sector;
@@ -887,36 +790,40 @@ static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr);
}
-static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
+static ide_startstop_t cdrom_start_seek(ide_drive_t *drive, unsigned int block)
{
struct cdrom_info *info = drive->driver_data;
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. */
-static void restore_request (struct request *rq)
+/*
+ * 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)
{
/*
@@ -940,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;
@@ -949,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)
{
@@ -992,6 +903,7 @@ static int cdrom_newpc_intr_dummy_cb(struct request *rq)
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
{
+ ide_hwif_t *hwif = drive->hwif;
struct cdrom_info *info = drive->driver_data;
struct request *rq = HWGROUP(drive)->rq;
xfer_func_t *xferfunc;
@@ -1001,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");
@@ -1016,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);
@@ -1029,12 +939,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
goto end_request;
}
- /*
- * ok we fall to pio :/
- */
- ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
- lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
- highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
+ /* 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);
@@ -1042,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)) {
/*
@@ -1055,7 +961,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
if (rq->current_nr_sectors > 0) {
printk(KERN_ERR "%s: %s: data underrun "
"(%d blocks)\n",
- drive->name, __FUNCTION__,
+ drive->name, __func__,
rq->current_nr_sectors);
if (!write)
rq->cmd_flags |= REQ_FAILED;
@@ -1065,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;
@@ -1103,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;
@@ -1132,11 +1032,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
if (!ptr) {
if (blk_fs_request(rq) && !write)
/*
- * If the buffers are full, cache the rest
- * of the data in our internal buffer.
+ * If the buffers are full, pipe the rest into
+ * oblivion.
*/
- cdrom_buffer_sectors(drive, rq->sector,
- thislen >> 9);
+ ide_cd_drain_data(drive, thislen >> 9);
else {
printk(KERN_ERR "%s: confused, missing data\n",
drive->name);
@@ -1150,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;
@@ -1182,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);
@@ -1228,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;
@@ -1241,15 +1136,9 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
* weirdness which might be present in the request packet.
*/
restore_request(rq);
-
- /* Satisfy whatever we can of this request from our cache. */
- if (cdrom_read_from_buffer(drive))
- return ide_stopped;
}
- /*
- * 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) {
@@ -1260,13 +1149,10 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
} else
cd->dma = drive->using_dma;
- /* Clear the local sector buffer. */
- cd->nsectors_buffered = 0;
-
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);
}
@@ -1291,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;
@@ -1310,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;
@@ -1330,16 +1216,21 @@ 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
+ else
action = cdrom_start_rw(drive, rq);
info->last_block = block;
return action;
@@ -1347,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;
}
@@ -1361,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);
@@ -1392,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;
@@ -1469,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)
@@ -1515,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) +
@@ -1523,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,
@@ -1567,14 +1460,13 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
toc->ent[i].track = BCD2BIN(toc->ent[i].track);
msf_from_bcd(&toc->ent[i].addr.msf);
}
- toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.minute,
- toc->ent[i].addr.msf.second,
- toc->ent[i].addr.msf.frame);
+ toc->ent[i].addr.lba = msf_to_lba(toc->ent[i].addr.msf.minute,
+ toc->ent[i].addr.msf.second,
+ 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)
@@ -1582,26 +1474,27 @@ 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)
return stat;
- msf_from_bcd (&ms_tmp.ent.addr.msf);
+ msf_from_bcd(&ms_tmp.ent.addr.msf);
toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute,
- ms_tmp.ent.addr.msf.second,
+ ms_tmp.ent.addr.msf.second,
ms_tmp.ent.addr.msf.frame);
}
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;
@@ -1626,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;
@@ -1677,7 +1571,7 @@ static struct cdrom_device_ops ide_cdrom_dops = {
.generic_packet = ide_cdrom_packet,
};
-static int ide_cdrom_register (ide_drive_t *drive, int nslots)
+static int ide_cdrom_register(ide_drive_t *drive, int nslots)
{
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *devinfo = &info->devinfo;
@@ -1695,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;
@@ -1710,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;
}
@@ -1721,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;
@@ -1794,18 +1687,7 @@ 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);
@@ -1844,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];
@@ -1868,7 +1748,7 @@ static int ide_cdrom_prep_pc(struct request *rq)
rq->errors = ILLEGAL_REQUEST;
return BLKPREP_KILL;
}
-
+
return BLKPREP_OK;
}
@@ -1888,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 },
@@ -1945,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;
@@ -1975,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);
+ 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;
}
@@ -1997,19 +1909,6 @@ int ide_cdrom_setup (ide_drive_t *drive)
return 0;
}
-#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;
-}
-#endif
-
static void ide_cd_remove(ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
@@ -2028,11 +1927,9 @@ static void ide_cd_release(struct kref *kref)
ide_drive_t *drive = info->drive;
struct gendisk *g = info->disk;
- kfree(info->buffer);
kfree(info->toc);
- if (devinfo->handle == drive && unregister_cdrom(devinfo))
- printk(KERN_ERR "%s: %s failed to unregister device from the cdrom "
- "driver.\n", __FUNCTION__, drive->name);
+ if (devinfo->handle == drive)
+ unregister_cdrom(devinfo);
drive->dsc_overlap = 0;
drive->driver_data = NULL;
blk_queue_prep_rq(drive->queue, NULL);
@@ -2043,23 +1940,6 @@ static void ide_cd_release(struct kref *kref)
static int ide_cd_probe(ide_drive_t *);
-#ifdef CONFIG_IDE_PROC_FS
-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,
@@ -2080,20 +1960,17 @@ static ide_driver_t ide_cdrom_driver = {
#endif
};
-static int idecd_open(struct inode * inode, struct file * file)
+static int idecd_open(struct inode *inode, struct file *file)
{
struct gendisk *disk = inode->i_bdev->bd_disk;
struct cdrom_info *info;
int rc = -ENOMEM;
- if (!(info = ide_cd_get(disk)))
+ info = ide_cd_get(disk);
+ if (!info)
return -ENXIO;
- if (!info->buffer)
- info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT);
-
- if (info->buffer)
- rc = cdrom_open(&info->devinfo, inode, file);
+ rc = cdrom_open(&info->devinfo, inode, file);
if (rc < 0)
ide_cd_put(info);
@@ -2101,12 +1978,12 @@ static int idecd_open(struct inode * inode, struct file * file)
return rc;
}
-static int idecd_release(struct inode * inode, struct file * file)
+static int idecd_release(struct inode *inode, struct file *file)
{
struct gendisk *disk = inode->i_bdev->bd_disk;
struct cdrom_info *info = ide_cd_g(disk);
- cdrom_release (&info->devinfo, file);
+ cdrom_release(&info->devinfo, file);
ide_cd_put(info);
@@ -2138,7 +2015,7 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
struct packet_command cgc;
char buffer[16];
int stat;
- char spindown;
+ char spindown;
init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
@@ -2147,12 +2024,12 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
return stat;
spindown = buffer[11] & 0x0f;
- if (copy_to_user((void __user *)arg, &spindown, sizeof (char)))
+ if (copy_to_user((void __user *)arg, &spindown, sizeof(char)))
return -EFAULT;
return 0;
}
-static int idecd_ioctl (struct inode *inode, struct file *file,
+static int idecd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct block_device *bdev = inode->i_bdev;
@@ -2160,13 +2037,13 @@ static int idecd_ioctl (struct inode *inode, struct file *file,
int err;
switch (cmd) {
- case CDROMSETSPINDOWN:
+ case CDROMSETSPINDOWN:
return idecd_set_spindown(&info->devinfo, arg);
- case CDROMGETSPINDOWN:
+ case CDROMGETSPINDOWN:
return idecd_get_spindown(&info->devinfo, arg);
default:
break;
- }
+ }
err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
if (err == -EINVAL)
@@ -2192,16 +2069,16 @@ static int idecd_revalidate_disk(struct gendisk *disk)
}
static struct block_device_operations idecd_ops = {
- .owner = THIS_MODULE,
- .open = idecd_open,
- .release = idecd_release,
- .ioctl = idecd_ioctl,
- .media_changed = idecd_media_changed,
- .revalidate_disk= idecd_revalidate_disk
+ .owner = THIS_MODULE,
+ .open = idecd_open,
+ .release = idecd_release,
+ .ioctl = idecd_ioctl,
+ .media_changed = idecd_media_changed,
+ .revalidate_disk = idecd_revalidate_disk
};
-/* options */
-static char *ignore = NULL;
+/* module options */
+static char *ignore;
module_param(ignore, charp, 0400);
MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
@@ -2221,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.h b/drivers/ide/ide-cd.h
index 22e3751a681e..a58801c4484d 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -119,10 +119,6 @@ struct cdrom_info {
struct atapi_toc *toc;
- unsigned long sector_buffered;
- unsigned long nsectors_buffered;
- unsigned char *buffer;
-
/* The result of the last successful request sense command
on this device. */
struct request_sense sense_data;
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 39501d130256..8e08d083fce9 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -16,8 +16,6 @@
#define IDEDISK_VERSION "1.18"
-//#define DEBUG
-
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
@@ -88,7 +86,7 @@ static void ide_disk_put(struct ide_disk_obj *idkp)
*
* It is called only once for each drive.
*/
-static int lba_capacity_is_ok (struct hd_driveid *id)
+static int lba_capacity_is_ok(struct hd_driveid *id)
{
unsigned long lba_sects, chs_sects, head, tail;
@@ -176,7 +174,8 @@ static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma)
* __ide_do_rw_disk() issues READ and WRITE commands to a disk,
* using LBA if supported, or CHS otherwise, to address sectors.
*/
-static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block)
+static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
+ sector_t block)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned int dma = drive->using_dma;
@@ -228,7 +227,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
tf->device = (block >> 8) & 0xf;
}
} else {
- unsigned int sect,head,cyl,track;
+ unsigned int sect, head, cyl, track;
+
track = (int)block / drive->sect;
sect = (int)block % drive->sect + 1;
head = track % drive->head;
@@ -271,7 +271,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
* 1073741822 == 549756 MB or 48bit addressing fake drive
*/
-static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
+static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
+ sector_t block)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -452,7 +453,7 @@ static void idedisk_check_hpa(ide_drive_t *drive)
* in above order (i.e., if value of higher priority is available,
* reset will be ignored).
*/
-static void init_idedisk_capacity (ide_drive_t *drive)
+static void init_idedisk_capacity(ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
/*
@@ -479,7 +480,7 @@ static void init_idedisk_capacity (ide_drive_t *drive)
}
}
-static sector_t idedisk_capacity (ide_drive_t *drive)
+static sector_t idedisk_capacity(ide_drive_t *drive)
{
return drive->capacity64 - drive->sect0;
}
@@ -524,10 +525,11 @@ static int proc_idedisk_read_cache
int len;
if (drive->id_read)
- len = sprintf(out,"%i\n", drive->id->buf_size / 2);
+ len = sprintf(out, "%i\n", drive->id->buf_size / 2);
else
- len = sprintf(out,"(none)\n");
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+ len = sprintf(out, "(none)\n");
+
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
static int proc_idedisk_read_capacity
@@ -536,54 +538,52 @@ static int proc_idedisk_read_capacity
ide_drive_t*drive = (ide_drive_t *)data;
int len;
- len = sprintf(page,"%llu\n", (long long)idedisk_capacity(drive));
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+ len = sprintf(page, "%llu\n", (long long)idedisk_capacity(drive));
+
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
-static int proc_idedisk_read_smart_thresholds
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int proc_idedisk_read_smart(char *page, char **start, off_t off,
+ int count, int *eof, void *data, u8 sub_cmd)
{
ide_drive_t *drive = (ide_drive_t *)data;
int len = 0, i = 0;
- if (get_smart_data(drive, page, SMART_READ_THRESHOLDS) == 0) {
+ if (get_smart_data(drive, page, sub_cmd) == 0) {
unsigned short *val = (unsigned short *) page;
char *out = ((char *)val) + (SECTOR_WORDS * 4);
page = out;
do {
- out += sprintf(out, "%04x%c", le16_to_cpu(*val), (++i & 7) ? ' ' : '\n');
+ out += sprintf(out, "%04x%c", le16_to_cpu(*val),
+ (++i & 7) ? ' ' : '\n');
val += 1;
} while (i < (SECTOR_WORDS * 2));
len = out - page;
}
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
-static int proc_idedisk_read_smart_values
+static int proc_idedisk_read_sv
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
- ide_drive_t *drive = (ide_drive_t *)data;
- int len = 0, i = 0;
+ return proc_idedisk_read_smart(page, start, off, count, eof, data,
+ SMART_READ_VALUES);
+}
- if (get_smart_data(drive, page, SMART_READ_VALUES) == 0) {
- unsigned short *val = (unsigned short *) page;
- char *out = ((char *)val) + (SECTOR_WORDS * 4);
- page = out;
- do {
- out += sprintf(out, "%04x%c", le16_to_cpu(*val), (++i & 7) ? ' ' : '\n');
- val += 1;
- } while (i < (SECTOR_WORDS * 2));
- len = out - page;
- }
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+static int proc_idedisk_read_st
+ (char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ return proc_idedisk_read_smart(page, start, off, count, eof, data,
+ SMART_READ_THRESHOLDS);
}
static ide_proc_entry_t idedisk_proc[] = {
- { "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL },
- { "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL },
- { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL },
- { "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_smart_values, NULL },
- { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_smart_thresholds, NULL },
+ { "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL },
+ { "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL },
+ { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL },
+ { "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv, NULL },
+ { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st, NULL },
{ NULL, 0, NULL, NULL }
};
#endif /* CONFIG_IDE_PROC_FS */
@@ -625,12 +625,13 @@ static int set_multcount(ide_drive_t *drive, int arg)
if (drive->special.b.set_multmode)
return -EBUSY;
- ide_init_drive_cmd (&rq);
+ ide_init_drive_cmd(&rq);
rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
drive->mult_req = arg;
drive->special.b.set_multmode = 1;
- (void) ide_do_drive_cmd (drive, &rq, ide_wait);
+ (void)ide_do_drive_cmd(drive, &rq, ide_wait);
+
return (drive->mult_count == arg) ? 0 : -EIO;
}
@@ -706,7 +707,7 @@ static int write_cache(ide_drive_t *drive, int arg)
return err;
}
-static int do_idedisk_flushcache (ide_drive_t *drive)
+static int do_idedisk_flushcache(ide_drive_t *drive)
{
ide_task_t args;
@@ -719,7 +720,7 @@ static int do_idedisk_flushcache (ide_drive_t *drive)
return ide_no_data_taskfile(drive, &args);
}
-static int set_acoustic (ide_drive_t *drive, int arg)
+static int set_acoustic(ide_drive_t *drive, int arg)
{
ide_task_t args;
@@ -753,7 +754,7 @@ static int set_lba_addressing(ide_drive_t *drive, int arg)
return 0;
if (!idedisk_supports_lba48(drive->id))
- return -EIO;
+ return -EIO;
drive->addressing = arg;
return 0;
}
@@ -763,23 +764,35 @@ static void idedisk_add_settings(ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
- ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->bios_cyl, NULL);
- ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL);
- ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL);
- ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1, &drive->addressing, set_lba_addressing);
- ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0, id->max_multsect, 1, 1, &drive->mult_count, set_multcount);
- ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr);
- ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL);
- ide_add_setting(drive, "wcache", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->wcache, write_cache);
- ide_add_setting(drive, "acoustic", SETTING_RW, TYPE_BYTE, 0, 254, 1, 1, &drive->acoustic, set_acoustic);
- ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL);
- ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL);
+ ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 65535, 1, 1,
+ &drive->bios_cyl, NULL);
+ ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1,
+ &drive->bios_head, NULL);
+ ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1,
+ &drive->bios_sect, NULL);
+ ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1,
+ &drive->addressing, set_lba_addressing);
+ ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0,
+ id->max_multsect, 1, 1, &drive->mult_count,
+ set_multcount);
+ ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1,
+ &drive->nowerr, set_nowerr);
+ ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1,
+ &drive->lun, NULL);
+ ide_add_setting(drive, "wcache", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1,
+ &drive->wcache, write_cache);
+ ide_add_setting(drive, "acoustic", SETTING_RW, TYPE_BYTE, 0, 254, 1, 1,
+ &drive->acoustic, set_acoustic);
+ ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1,
+ &drive->failures, NULL);
+ ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535,
+ 1, 1, &drive->max_failures, NULL);
}
#else
static inline void idedisk_add_settings(ide_drive_t *drive) { ; }
#endif
-static void idedisk_setup (ide_drive_t *drive)
+static void idedisk_setup(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct hd_driveid *id = drive->id;
@@ -792,11 +805,10 @@ static void idedisk_setup (ide_drive_t *drive)
if (drive->removable) {
/*
- * Removable disks (eg. SYQUEST); ignore 'WD' drives
+ * Removable disks (eg. SYQUEST); ignore 'WD' drives
*/
- if (id->model[0] != 'W' || id->model[1] != 'D') {
+ if (id->model[0] != 'W' || id->model[1] != 'D')
drive->doorlocking = 1;
- }
}
(void)set_lba_addressing(drive, 1);
@@ -810,10 +822,11 @@ static void idedisk_setup (ide_drive_t *drive)
blk_queue_max_sectors(drive->queue, max_s);
}
- printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name, drive->queue->max_sectors / 2);
+ printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name,
+ drive->queue->max_sectors / 2);
/* calculate drive capacity, and select LBA if possible */
- init_idedisk_capacity (drive);
+ init_idedisk_capacity(drive);
/* limit drive capacity to 137GB if LBA48 cannot be used */
if (drive->addressing == 0 && drive->capacity64 > 1ULL << 28) {
@@ -826,9 +839,9 @@ static void idedisk_setup (ide_drive_t *drive)
if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && drive->addressing) {
if (drive->capacity64 > 1ULL << 28) {
- printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode will"
- " be used for accessing sectors > %u\n",
- drive->name, 1 << 28);
+ printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode"
+ " will be used for accessing sectors "
+ "> %u\n", drive->name, 1 << 28);
} else
drive->addressing = 0;
}
@@ -837,7 +850,8 @@ static void idedisk_setup (ide_drive_t *drive)
* if possible, give fdisk access to more of the drive,
* by correcting bios_cyls:
*/
- capacity = idedisk_capacity (drive);
+ capacity = idedisk_capacity(drive);
+
if (!drive->forced_geom) {
if (idedisk_supports_lba48(drive->id)) {
@@ -993,7 +1007,8 @@ static int idedisk_open(struct inode *inode, struct file *filp)
struct ide_disk_obj *idkp;
ide_drive_t *drive;
- if (!(idkp = ide_disk_get(disk)))
+ idkp = ide_disk_get(disk);
+ if (idkp == NULL)
return -ENXIO;
drive = idkp->drive;
@@ -1115,13 +1130,13 @@ static int idedisk_revalidate_disk(struct gendisk *disk)
}
static struct block_device_operations idedisk_ops = {
- .owner = THIS_MODULE,
- .open = idedisk_open,
- .release = idedisk_release,
- .ioctl = idedisk_ioctl,
- .getgeo = idedisk_getgeo,
- .media_changed = idedisk_media_changed,
- .revalidate_disk= idedisk_revalidate_disk
+ .owner = THIS_MODULE,
+ .open = idedisk_open,
+ .release = idedisk_release,
+ .ioctl = idedisk_ioctl,
+ .getgeo = idedisk_getgeo,
+ .media_changed = idedisk_media_changed,
+ .revalidate_disk = idedisk_revalidate_disk
};
MODULE_DESCRIPTION("ATA DISK Driver");
@@ -1184,7 +1199,7 @@ failed:
return -ENODEV;
}
-static void __exit idedisk_exit (void)
+static void __exit idedisk_exit(void)
{
driver_unregister(&idedisk_driver.gen_driver);
}
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index d61e5788d310..653b1ade13d3 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;
@@ -703,17 +707,8 @@ static int ide_tune_dma(ide_drive_t *drive)
speed = ide_max_dma_mode(drive);
- if (!speed) {
- /* is this really correct/needed? */
- if ((hwif->host_flags & IDE_HFLAG_CY82C693) &&
- ide_dma_good_drive(drive))
- return 1;
- else
- return 0;
- }
-
- if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
- return 1;
+ if (!speed)
+ return 0;
if (ide_set_dma_mode(drive, speed))
return 0;
@@ -810,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);
@@ -829,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);
@@ -862,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 faf22d716f80..f05fbc2bd7a8 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -78,40 +78,6 @@
*/
#define IDEFLOPPY_PC_STACK (10 + IDEFLOPPY_MAX_PC_RETRIES)
-typedef struct idefloppy_packet_command_s {
- u8 c[12]; /* Actual packet bytes */
- int retries; /* On each retry, we increment
- retries */
- int error; /* Error code */
- int request_transfer; /* Bytes to transfer */
- int actually_transferred; /* Bytes actually transferred */
- int buffer_size; /* Size of our data buffer */
- int b_count; /* Missing/Available data on
- the current buffer */
- struct request *rq; /* The corresponding request */
- u8 *buffer; /* Data buffer */
- u8 *current_position; /* Pointer into above buffer */
- void (*callback) (ide_drive_t *); /* Called when this packet
- command is completed */
- u8 pc_buffer[IDEFLOPPY_PC_BUFFER_SIZE]; /* Temporary buffer */
- unsigned long flags; /* Status/Action bit flags: long
- for set_bit */
-} idefloppy_pc_t;
-
-/* Packet command flag bits. */
-enum {
- /* 1 when we prefer to use DMA if possible */
- PC_FLAG_DMA_RECOMMENDED = (1 << 0),
- /* 1 while DMA in progress */
- PC_FLAG_DMA_IN_PROGRESS = (1 << 1),
- /* 1 when encountered problem during DMA */
- PC_FLAG_DMA_ERROR = (1 << 2),
- /* Data direction */
- PC_FLAG_WRITING = (1 << 3),
- /* Suppress error reporting */
- PC_FLAG_SUPPRESS_ERROR = (1 << 4),
-};
-
/* format capacities descriptor codes */
#define CAPACITY_INVALID 0x00
#define CAPACITY_UNFORMATTED 0x01
@@ -131,11 +97,11 @@ typedef struct ide_floppy_obj {
unsigned int openers; /* protected by BKL for now */
/* Current packet command */
- idefloppy_pc_t *pc;
+ struct ide_atapi_pc *pc;
/* Last failed packet command */
- idefloppy_pc_t *failed_pc;
+ struct ide_atapi_pc *failed_pc;
/* Packet command stack */
- idefloppy_pc_t pc_stack[IDEFLOPPY_PC_STACK];
+ struct ide_atapi_pc pc_stack[IDEFLOPPY_PC_STACK];
/* Next free packet command storage space */
int pc_stack_index;
struct request rq_stack[IDEFLOPPY_PC_STACK];
@@ -195,32 +161,6 @@ enum {
#define IDEFLOPPY_ERROR_GENERAL 101
/*
- * The following is used to format the general configuration word of the
- * ATAPI IDENTIFY DEVICE command.
- */
-struct idefloppy_id_gcw {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned packet_size :2; /* Packet Size */
- unsigned reserved234 :3; /* Reserved */
- unsigned drq_type :2; /* Command packet DRQ type */
- unsigned removable :1; /* Removable media */
- unsigned device_type :5; /* Device type */
- unsigned reserved13 :1; /* Reserved */
- unsigned protocol :2; /* Protocol type */
-#elif defined(__BIG_ENDIAN_BITFIELD)
- unsigned protocol :2; /* Protocol type */
- unsigned reserved13 :1; /* Reserved */
- unsigned device_type :5; /* Device type */
- unsigned removable :1; /* Removable media */
- unsigned drq_type :2; /* Command packet DRQ type */
- unsigned reserved234 :3; /* Reserved */
- unsigned packet_size :2; /* Packet Size */
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
-};
-
-/*
* Pages of the SELECT SENSE / MODE SENSE packet commands.
* See SFF-8070i spec.
*/
@@ -256,27 +196,10 @@ static void ide_floppy_put(struct ide_floppy_obj *floppy)
}
/*
- * Too bad. The drive wants to send us data which we are not ready to accept.
- * Just throw it away.
- */
-static void idefloppy_discard_data(ide_drive_t *drive, unsigned int bcount)
-{
- while (bcount--)
- (void) HWIF(drive)->INB(IDE_DATA_REG);
-}
-
-static void idefloppy_write_zeros(ide_drive_t *drive, unsigned int bcount)
-{
- while (bcount--)
- HWIF(drive)->OUTB(0, IDE_DATA_REG);
-}
-
-
-/*
* Used to finish servicing a request. For read/write requests, we will call
* ide_end_request to pass to the next buffer.
*/
-static int idefloppy_do_end_request(ide_drive_t *drive, int uptodate, int nsecs)
+static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
{
idefloppy_floppy_t *floppy = drive->driver_data;
struct request *rq = HWGROUP(drive)->rq;
@@ -305,9 +228,10 @@ static int idefloppy_do_end_request(ide_drive_t *drive, int uptodate, int nsecs)
return 0;
}
-static void ide_floppy_io_buffers(ide_drive_t *drive, idefloppy_pc_t *pc,
+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;
@@ -323,9 +247,9 @@ static void ide_floppy_io_buffers(ide_drive_t *drive, idefloppy_pc_t *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;
@@ -333,26 +257,23 @@ static void ide_floppy_io_buffers(ide_drive_t *drive, idefloppy_pc_t *pc,
done += count;
}
- idefloppy_do_end_request(drive, 1, done >> 9);
+ idefloppy_end_request(drive, 1, done >> 9);
if (bcount) {
printk(KERN_ERR "%s: leftover data in %s, bcount == %d\n",
drive->name, __func__, bcount);
- if (direction)
- idefloppy_write_zeros(drive, bcount);
- else
- idefloppy_discard_data(drive, bcount);
-
+ ide_pad_transfer(drive, direction, bcount);
}
}
-static void idefloppy_update_buffers(ide_drive_t *drive, idefloppy_pc_t *pc)
+static void idefloppy_update_buffers(ide_drive_t *drive,
+ struct ide_atapi_pc *pc)
{
struct request *rq = pc->rq;
struct bio *bio = rq->bio;
while ((bio = rq->bio) != NULL)
- idefloppy_do_end_request(drive, 1, 0);
+ idefloppy_end_request(drive, 1, 0);
}
/*
@@ -360,7 +281,7 @@ static void idefloppy_update_buffers(ide_drive_t *drive, idefloppy_pc_t *pc)
* the current request so that it will be processed immediately, on the next
* pass through the driver.
*/
-static void idefloppy_queue_pc_head(ide_drive_t *drive, idefloppy_pc_t *pc,
+static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
struct request *rq)
{
struct ide_floppy_obj *floppy = drive->driver_data;
@@ -372,7 +293,7 @@ static void idefloppy_queue_pc_head(ide_drive_t *drive, idefloppy_pc_t *pc,
(void) ide_do_drive_cmd(drive, rq, ide_preempt);
}
-static idefloppy_pc_t *idefloppy_next_pc_storage(ide_drive_t *drive)
+static struct ide_atapi_pc *idefloppy_next_pc_storage(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
@@ -393,7 +314,7 @@ static struct request *idefloppy_next_rq_storage(ide_drive_t *drive)
static void idefloppy_request_sense_callback(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
- u8 *buf = floppy->pc->buffer;
+ u8 *buf = floppy->pc->buf;
debug_log("Reached %s\n", __func__);
@@ -418,11 +339,11 @@ static void idefloppy_request_sense_callback(ide_drive_t *drive)
floppy->ascq);
- idefloppy_do_end_request(drive, 1, 0);
+ idefloppy_end_request(drive, 1, 0);
} else {
printk(KERN_ERR "Error in REQUEST SENSE itself - Aborting"
" request!\n");
- idefloppy_do_end_request(drive, 0, 0);
+ idefloppy_end_request(drive, 0, 0);
}
}
@@ -433,27 +354,27 @@ static void idefloppy_pc_callback(ide_drive_t *drive)
debug_log("Reached %s\n", __func__);
- idefloppy_do_end_request(drive, floppy->pc->error ? 0 : 1, 0);
+ idefloppy_end_request(drive, floppy->pc->error ? 0 : 1, 0);
}
-static void idefloppy_init_pc(idefloppy_pc_t *pc)
+static void idefloppy_init_pc(struct ide_atapi_pc *pc)
{
memset(pc->c, 0, 12);
pc->retries = 0;
pc->flags = 0;
- pc->request_transfer = 0;
- pc->buffer = pc->pc_buffer;
- pc->buffer_size = IDEFLOPPY_PC_BUFFER_SIZE;
- pc->callback = &idefloppy_pc_callback;
+ pc->req_xfer = 0;
+ pc->buf = pc->pc_buf;
+ pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE;
+ pc->idefloppy_callback = &idefloppy_pc_callback;
}
-static void idefloppy_create_request_sense_cmd(idefloppy_pc_t *pc)
+static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc)
{
idefloppy_init_pc(pc);
pc->c[0] = GPCMD_REQUEST_SENSE;
pc->c[4] = 255;
- pc->request_transfer = 18;
- pc->callback = &idefloppy_request_sense_callback;
+ pc->req_xfer = 18;
+ pc->idefloppy_callback = &idefloppy_request_sense_callback;
}
/*
@@ -462,7 +383,7 @@ static void idefloppy_create_request_sense_cmd(idefloppy_pc_t *pc)
*/
static void idefloppy_retry_pc(ide_drive_t *drive)
{
- idefloppy_pc_t *pc;
+ struct ide_atapi_pc *pc;
struct request *rq;
(void)ide_read_error(drive);
@@ -473,11 +394,11 @@ static void idefloppy_retry_pc(ide_drive_t *drive)
}
/* The usual interrupt handler called during a packet command. */
-static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
+static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
- idefloppy_pc_t *pc = floppy->pc;
+ struct ide_atapi_pc *pc = floppy->pc;
struct request *rq = pc->rq;
xfer_func_t *xferfunc;
unsigned int temp;
@@ -488,13 +409,13 @@ 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");
pc->flags |= PC_FLAG_DMA_ERROR;
} else {
- pc->actually_transferred = pc->request_transfer;
+ pc->xferred = pc->req_xfer;
idefloppy_update_buffers(drive, pc);
}
debug_log("DMA finished\n");
@@ -506,7 +427,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
/* No more interrupts */
if ((stat & DRQ_STAT) == 0) {
debug_log("Packet command completed, %d bytes transferred\n",
- pc->actually_transferred);
+ pc->xferred);
pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
local_irq_enable_in_hardirq();
@@ -529,7 +450,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
if (floppy->failed_pc == pc)
floppy->failed_pc = NULL;
/* Command finished - Call the callback function */
- pc->callback(drive);
+ pc->idefloppy_callback(drive);
return ide_stopped;
}
@@ -542,10 +463,10 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
}
/* Get the number of bytes to transfer */
- bcount = (hwif->INB(IDE_BCOUNTH_REG) << 8) |
- hwif->INB(IDE_BCOUNTL_REG);
+ bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
+ hwif->INB(hwif->io_ports.lbam_addr);
/* on this interrupt */
- ireason = hwif->INB(IDE_IREASON_REG);
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
if (ireason & CD) {
printk(KERN_ERR "ide-floppy: CoD != 0 in %s\n", __func__);
@@ -561,13 +482,13 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
}
if (!(pc->flags & PC_FLAG_WRITING)) {
/* Reading - Check that we have enough space */
- temp = pc->actually_transferred + bcount;
- if (temp > pc->request_transfer) {
- if (temp > pc->buffer_size) {
+ temp = pc->xferred + bcount;
+ if (temp > pc->req_xfer) {
+ if (temp > pc->buf_size) {
printk(KERN_ERR "ide-floppy: The floppy wants "
"to send us more data than expected "
"- discarding data\n");
- idefloppy_discard_data(drive, bcount);
+ ide_pad_transfer(drive, 0, bcount);
ide_set_handler(drive,
&idefloppy_pc_intr,
@@ -580,19 +501,19 @@ 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->buffer)
- xferfunc(drive, pc->current_position, bcount);
+ if (pc->buf)
+ xferfunc(drive, NULL, pc->cur_pos, bcount);
else
ide_floppy_io_buffers(drive, pc, bcount,
!!(pc->flags & PC_FLAG_WRITING));
/* Update the current position */
- pc->actually_transferred += bcount;
- pc->current_position += bcount;
+ pc->xferred += bcount;
+ pc->cur_pos += bcount;
/* And set the interrupt handler again */
ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);
@@ -606,6 +527,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
*/
static ide_startstop_t idefloppy_transfer_pc(ide_drive_t *drive)
{
+ ide_hwif_t *hwif = drive->hwif;
ide_startstop_t startstop;
idefloppy_floppy_t *floppy = drive->driver_data;
u8 ireason;
@@ -615,7 +537,7 @@ static ide_startstop_t idefloppy_transfer_pc(ide_drive_t *drive)
"initiated yet DRQ isn't asserted\n");
return startstop;
}
- ireason = drive->hwif->INB(IDE_IREASON_REG);
+ 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");
@@ -624,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;
}
@@ -645,13 +569,15 @@ 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;
}
static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive)
{
+ ide_hwif_t *hwif = drive->hwif;
idefloppy_floppy_t *floppy = drive->driver_data;
ide_startstop_t startstop;
u8 ireason;
@@ -661,7 +587,7 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive)
"initiated yet DRQ isn't asserted\n");
return startstop;
}
- ireason = drive->hwif->INB(IDE_IREASON_REG);
+ 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");
@@ -682,7 +608,7 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive)
}
static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
- idefloppy_pc_t *pc)
+ struct ide_atapi_pc *pc)
{
/* supress error messages resulting from Medium not present */
if (floppy->sense_key == 0x02 &&
@@ -698,7 +624,7 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
}
static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
- idefloppy_pc_t *pc)
+ struct ide_atapi_pc *pc)
{
idefloppy_floppy_t *floppy = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
@@ -719,7 +645,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
pc->error = IDEFLOPPY_ERROR_GENERAL;
floppy->failed_pc = NULL;
- pc->callback(drive);
+ pc->idefloppy_callback(drive);
return ide_stopped;
}
@@ -727,9 +653,9 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
pc->retries++;
/* We haven't transferred any data yet */
- pc->actually_transferred = 0;
- pc->current_position = pc->buffer;
- bcount = min(pc->request_transfer, 63 * 1024);
+ pc->xferred = 0;
+ pc->cur_pos = pc->buf;
+ bcount = min(pc->req_xfer, 63 * 1024);
if (pc->flags & PC_FLAG_DMA_ERROR) {
pc->flags &= ~PC_FLAG_DMA_ERROR;
@@ -738,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);
@@ -746,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? */
@@ -757,7 +683,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
/* immediate */
pkt_xfer_routine = &idefloppy_transfer_pc;
}
-
+
if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT) {
/* Issue the packet command */
ide_execute_command(drive, WIN_PACKETCMD,
@@ -767,7 +693,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
return ide_started;
} else {
/* Issue the packet command */
- HWIF(drive)->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG);
+ ide_execute_pkt_cmd(drive);
return (*pkt_xfer_routine) (drive);
}
}
@@ -776,11 +702,11 @@ static void idefloppy_rw_callback(ide_drive_t *drive)
{
debug_log("Reached %s\n", __func__);
- idefloppy_do_end_request(drive, 1, 0);
+ idefloppy_end_request(drive, 1, 0);
return;
}
-static void idefloppy_create_prevent_cmd(idefloppy_pc_t *pc, int prevent)
+static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent)
{
debug_log("creating prevent removal command, prevent = %d\n", prevent);
@@ -789,39 +715,39 @@ static void idefloppy_create_prevent_cmd(idefloppy_pc_t *pc, int prevent)
pc->c[4] = prevent;
}
-static void idefloppy_create_read_capacity_cmd(idefloppy_pc_t *pc)
+static void idefloppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
{
idefloppy_init_pc(pc);
pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES;
pc->c[7] = 255;
pc->c[8] = 255;
- pc->request_transfer = 255;
+ pc->req_xfer = 255;
}
-static void idefloppy_create_format_unit_cmd(idefloppy_pc_t *pc, int b, int l,
- int flags)
+static void idefloppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b,
+ int l, int flags)
{
idefloppy_init_pc(pc);
pc->c[0] = GPCMD_FORMAT_UNIT;
pc->c[1] = 0x17;
- memset(pc->buffer, 0, 12);
- pc->buffer[1] = 0xA2;
+ memset(pc->buf, 0, 12);
+ pc->buf[1] = 0xA2;
/* Default format list header, u8 1: FOV/DCRT/IMM bits set */
if (flags & 1) /* Verify bit on... */
- pc->buffer[1] ^= 0x20; /* ... turn off DCRT bit */
- pc->buffer[3] = 8;
+ pc->buf[1] ^= 0x20; /* ... turn off DCRT bit */
+ pc->buf[3] = 8;
- put_unaligned(cpu_to_be32(b), (unsigned int *)(&pc->buffer[4]));
- put_unaligned(cpu_to_be32(l), (unsigned int *)(&pc->buffer[8]));
- pc->buffer_size = 12;
+ put_unaligned(cpu_to_be32(b), (unsigned int *)(&pc->buf[4]));
+ put_unaligned(cpu_to_be32(l), (unsigned int *)(&pc->buf[8]));
+ pc->buf_size = 12;
pc->flags |= PC_FLAG_WRITING;
}
/* A mode sense command is used to "sense" floppy parameters. */
-static void idefloppy_create_mode_sense_cmd(idefloppy_pc_t *pc, u8 page_code,
- u8 type)
+static void idefloppy_create_mode_sense_cmd(struct ide_atapi_pc *pc,
+ u8 page_code, u8 type)
{
u16 length = 8; /* sizeof(Mode Parameter Header) = 8 Bytes */
@@ -842,24 +768,24 @@ static void idefloppy_create_mode_sense_cmd(idefloppy_pc_t *pc, u8 page_code,
"in create_mode_sense_cmd\n");
}
put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]);
- pc->request_transfer = length;
+ pc->req_xfer = length;
}
-static void idefloppy_create_start_stop_cmd(idefloppy_pc_t *pc, int start)
+static void idefloppy_create_start_stop_cmd(struct ide_atapi_pc *pc, int start)
{
idefloppy_init_pc(pc);
pc->c[0] = GPCMD_START_STOP_UNIT;
pc->c[4] = start;
}
-static void idefloppy_create_test_unit_ready_cmd(idefloppy_pc_t *pc)
+static void idefloppy_create_test_unit_ready_cmd(struct ide_atapi_pc *pc)
{
idefloppy_init_pc(pc);
pc->c[0] = GPCMD_TEST_UNIT_READY;
}
static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy,
- idefloppy_pc_t *pc, struct request *rq,
+ struct ide_atapi_pc *pc, struct request *rq,
unsigned long sector)
{
int block = sector / floppy->bs_factor;
@@ -874,41 +800,41 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy,
put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]);
put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]);
- pc->callback = &idefloppy_rw_callback;
+ pc->idefloppy_callback = &idefloppy_rw_callback;
pc->rq = rq;
pc->b_count = cmd == READ ? 0 : rq->bio->bi_size;
if (rq->cmd_flags & REQ_RW)
pc->flags |= PC_FLAG_WRITING;
- pc->buffer = NULL;
- pc->request_transfer = pc->buffer_size = blocks * floppy->block_size;
+ pc->buf = NULL;
+ pc->req_xfer = pc->buf_size = blocks * floppy->block_size;
pc->flags |= PC_FLAG_DMA_RECOMMENDED;
}
static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
- idefloppy_pc_t *pc, struct request *rq)
+ struct ide_atapi_pc *pc, struct request *rq)
{
idefloppy_init_pc(pc);
- pc->callback = &idefloppy_rw_callback;
+ pc->idefloppy_callback = &idefloppy_rw_callback;
memcpy(pc->c, rq->cmd, sizeof(pc->c));
pc->rq = rq;
pc->b_count = rq->data_len;
if (rq->data_len && rq_data_dir(rq) == WRITE)
pc->flags |= PC_FLAG_WRITING;
- pc->buffer = rq->data;
+ pc->buf = rq->data;
if (rq->bio)
pc->flags |= PC_FLAG_DMA_RECOMMENDED;
/*
* possibly problematic, doesn't look like ide-floppy correctly
* handled scattered requests if dma fails...
*/
- pc->request_transfer = pc->buffer_size = rq->data_len;
+ pc->req_xfer = pc->buf_size = rq->data_len;
}
static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
struct request *rq, sector_t block_s)
{
idefloppy_floppy_t *floppy = drive->driver_data;
- idefloppy_pc_t *pc;
+ struct ide_atapi_pc *pc;
unsigned long block = (unsigned long)block_s;
debug_log("dev: %s, cmd_type: %x, errors: %d\n",
@@ -924,7 +850,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
else
printk(KERN_ERR "ide-floppy: %s: I/O error\n",
drive->name);
- idefloppy_do_end_request(drive, 0, 0);
+ idefloppy_end_request(drive, 0, 0);
return ide_stopped;
}
if (blk_fs_request(rq)) {
@@ -932,20 +858,20 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
(rq->nr_sectors % floppy->bs_factor)) {
printk(KERN_ERR "%s: unsupported r/w request size\n",
drive->name);
- idefloppy_do_end_request(drive, 0, 0);
+ idefloppy_end_request(drive, 0, 0);
return ide_stopped;
}
pc = idefloppy_next_pc_storage(drive);
idefloppy_create_rw_cmd(floppy, pc, rq, block);
} else if (blk_special_request(rq)) {
- pc = (idefloppy_pc_t *) rq->buffer;
+ pc = (struct ide_atapi_pc *) rq->buffer;
} else if (blk_pc_request(rq)) {
pc = idefloppy_next_pc_storage(drive);
idefloppy_blockpc_cmd(floppy, pc, rq);
} else {
blk_dump_rq_flags(rq,
"ide-floppy: unsupported command in queue");
- idefloppy_do_end_request(drive, 0, 0);
+ idefloppy_end_request(drive, 0, 0);
return ide_stopped;
}
@@ -957,7 +883,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
* Add a special packet command request to the tail of the request queue,
* and wait for it to be serviced.
*/
-static int idefloppy_queue_pc_tail(ide_drive_t *drive, idefloppy_pc_t *pc)
+static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
{
struct ide_floppy_obj *floppy = drive->driver_data;
struct request rq;
@@ -977,7 +903,7 @@ static int idefloppy_queue_pc_tail(ide_drive_t *drive, idefloppy_pc_t *pc)
static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
- idefloppy_pc_t pc;
+ struct ide_atapi_pc pc;
u8 *page;
int capacity, lba_capacity;
u16 transfer_rate, sector_size, cyls, rpm;
@@ -991,16 +917,16 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
" parameters\n");
return 1;
}
- floppy->wp = !!(pc.buffer[3] & 0x80);
+ floppy->wp = !!(pc.buf[3] & 0x80);
set_disk_ro(floppy->disk, floppy->wp);
- page = &pc.buffer[8];
+ page = &pc.buf[8];
- transfer_rate = be16_to_cpu(*(u16 *)&pc.buffer[8 + 2]);
- sector_size = be16_to_cpu(*(u16 *)&pc.buffer[8 + 6]);
- cyls = be16_to_cpu(*(u16 *)&pc.buffer[8 + 8]);
- rpm = be16_to_cpu(*(u16 *)&pc.buffer[8 + 28]);
- heads = pc.buffer[8 + 4];
- sectors = pc.buffer[8 + 5];
+ transfer_rate = be16_to_cpu(*(u16 *)&pc.buf[8 + 2]);
+ sector_size = be16_to_cpu(*(u16 *)&pc.buf[8 + 6]);
+ cyls = be16_to_cpu(*(u16 *)&pc.buf[8 + 8]);
+ rpm = be16_to_cpu(*(u16 *)&pc.buf[8 + 28]);
+ heads = pc.buf[8 + 4];
+ sectors = pc.buf[8 + 5];
capacity = cyls * heads * sectors * sector_size;
@@ -1029,7 +955,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
static int idefloppy_get_sfrp_bit(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
- idefloppy_pc_t pc;
+ struct ide_atapi_pc pc;
floppy->srfp = 0;
idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE,
@@ -1039,7 +965,7 @@ static int idefloppy_get_sfrp_bit(ide_drive_t *drive)
if (idefloppy_queue_pc_tail(drive, &pc))
return 1;
- floppy->srfp = pc.buffer[8 + 2] & 0x40;
+ floppy->srfp = pc.buf[8 + 2] & 0x40;
return (0);
}
@@ -1050,7 +976,7 @@ static int idefloppy_get_sfrp_bit(ide_drive_t *drive)
static int ide_floppy_get_capacity(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
- idefloppy_pc_t pc;
+ struct ide_atapi_pc pc;
u8 *cap_desc;
u8 header_len, desc_cnt;
int i, rc = 1, blocks, length;
@@ -1066,15 +992,15 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
return 1;
}
- header_len = pc.buffer[3];
- cap_desc = &pc.buffer[4];
+ header_len = pc.buf[3];
+ cap_desc = &pc.buf[4];
desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */
for (i = 0; i < desc_cnt; i++) {
unsigned int desc_start = 4 + i*8;
- blocks = be32_to_cpu(*(u32 *)&pc.buffer[desc_start]);
- length = be16_to_cpu(*(u16 *)&pc.buffer[desc_start + 6]);
+ blocks = be32_to_cpu(*(u32 *)&pc.buf[desc_start]);
+ length = be16_to_cpu(*(u16 *)&pc.buf[desc_start + 6]);
debug_log("Descriptor %d: %dkB, %d blocks, %d sector size\n",
i, blocks * length / 1024, blocks, length);
@@ -1085,7 +1011,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
* the code below is valid only for the 1st descriptor, ie i=0
*/
- switch (pc.buffer[desc_start + 4] & 0x03) {
+ switch (pc.buf[desc_start + 4] & 0x03) {
/* Clik! drive returns this instead of CAPACITY_CURRENT */
case CAPACITY_UNFORMATTED:
if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE))
@@ -1130,7 +1056,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
break;
}
debug_log("Descriptor 0 Code: %d\n",
- pc.buffer[desc_start + 4] & 0x03);
+ pc.buf[desc_start + 4] & 0x03);
}
/* Clik! disk does not support get_flexible_disk_page */
@@ -1162,7 +1088,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
{
- idefloppy_pc_t pc;
+ struct ide_atapi_pc pc;
u8 header_len, desc_cnt;
int i, blocks, length, u_array_size, u_index;
int __user *argp;
@@ -1178,7 +1104,7 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
return (-EIO);
}
- header_len = pc.buffer[3];
+ header_len = pc.buf[3];
desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */
u_index = 0;
@@ -1195,8 +1121,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
if (u_index >= u_array_size)
break; /* User-supplied buffer too small */
- blocks = be32_to_cpu(*(u32 *)&pc.buffer[desc_start]);
- length = be16_to_cpu(*(u16 *)&pc.buffer[desc_start + 6]);
+ blocks = be32_to_cpu(*(u32 *)&pc.buf[desc_start]);
+ length = be16_to_cpu(*(u16 *)&pc.buf[desc_start + 6]);
if (put_user(blocks, argp))
return(-EFAULT);
@@ -1227,7 +1153,7 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)
{
idefloppy_floppy_t *floppy = drive->driver_data;
- idefloppy_pc_t pc;
+ struct ide_atapi_pc pc;
int progress_indication = 0x10000;
if (floppy->srfp) {
@@ -1271,33 +1197,39 @@ static sector_t idefloppy_capacity(ide_drive_t *drive)
*/
static int idefloppy_identify_device(ide_drive_t *drive, struct hd_driveid *id)
{
- struct idefloppy_id_gcw gcw;
+ u8 gcw[2];
+ u8 device_type, protocol, removable, drq_type, packet_size;
*((u16 *) &gcw) = id->config;
+ device_type = gcw[1] & 0x1F;
+ removable = (gcw[0] & 0x80) >> 7;
+ protocol = (gcw[1] & 0xC0) >> 6;
+ drq_type = (gcw[0] & 0x60) >> 5;
+ packet_size = gcw[0] & 0x03;
+
#ifdef CONFIG_PPC
/* kludge for Apple PowerBook internal zip */
- if ((gcw.device_type == 5) &&
- !strstr(id->model, "CD-ROM") &&
- strstr(id->model, "ZIP"))
- gcw.device_type = 0;
+ if (device_type == 5 &&
+ !strstr(id->model, "CD-ROM") && strstr(id->model, "ZIP"))
+ device_type = 0;
#endif
- if (gcw.protocol != 2)
+ if (protocol != 2)
printk(KERN_ERR "ide-floppy: Protocol (0x%02x) is not ATAPI\n",
- gcw.protocol);
- else if (gcw.device_type != 0)
+ protocol);
+ else if (device_type != 0)
printk(KERN_ERR "ide-floppy: Device type (0x%02x) is not set "
- "to floppy\n", gcw.device_type);
- else if (!gcw.removable)
+ "to floppy\n", device_type);
+ else if (!removable)
printk(KERN_ERR "ide-floppy: The removable flag is not set\n");
- else if (gcw.drq_type == 3) {
+ else if (drq_type == 3)
printk(KERN_ERR "ide-floppy: Sorry, DRQ type (0x%02x) not "
- "supported\n", gcw.drq_type);
- } else if (gcw.packet_size != 0) {
+ "supported\n", drq_type);
+ else if (packet_size != 0)
printk(KERN_ERR "ide-floppy: Packet size (0x%02x) is not 12 "
- "bytes long\n", gcw.packet_size);
- } else
+ "bytes\n", packet_size);
+ else
return 1;
return 0;
}
@@ -1322,11 +1254,12 @@ static inline void idefloppy_add_settings(ide_drive_t *drive) { ; }
static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
{
- struct idefloppy_id_gcw gcw;
+ u8 gcw[2];
*((u16 *) &gcw) = drive->id->config;
floppy->pc = floppy->pc_stack;
- if (gcw.drq_type == 1)
+
+ if (((gcw[0] & 0x60) >> 5) == 1)
floppy->flags |= IDEFLOPPY_FLAG_DRQ_INTERRUPT;
/*
* We used to check revisions here. At this point however I'm giving up.
@@ -1413,7 +1346,7 @@ static ide_driver_t idefloppy_driver = {
.media = ide_floppy,
.supports_dsc_overlap = 0,
.do_request = idefloppy_do_request,
- .end_request = idefloppy_do_end_request,
+ .end_request = idefloppy_end_request,
.error = __ide_error,
.abort = __ide_abort,
#ifdef CONFIG_IDE_PROC_FS
@@ -1426,7 +1359,7 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
struct gendisk *disk = inode->i_bdev->bd_disk;
struct ide_floppy_obj *floppy;
ide_drive_t *drive;
- idefloppy_pc_t pc;
+ struct ide_atapi_pc pc;
int ret = 0;
debug_log("Reached %s\n", __func__);
@@ -1489,7 +1422,7 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
struct gendisk *disk = inode->i_bdev->bd_disk;
struct ide_floppy_obj *floppy = ide_floppy_g(disk);
ide_drive_t *drive = floppy->drive;
- idefloppy_pc_t pc;
+ struct ide_atapi_pc pc;
debug_log("Reached %s\n", __func__);
@@ -1521,8 +1454,8 @@ static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
return 0;
}
-static int ide_floppy_lockdoor(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc,
- unsigned long arg, unsigned int cmd)
+static int ide_floppy_lockdoor(idefloppy_floppy_t *floppy,
+ struct ide_atapi_pc *pc, unsigned long arg, unsigned int cmd)
{
if (floppy->openers > 1)
return -EBUSY;
@@ -1551,7 +1484,7 @@ static int ide_floppy_format_unit(idefloppy_floppy_t *floppy,
int __user *arg)
{
int blocks, length, flags, err = 0;
- idefloppy_pc_t pc;
+ struct ide_atapi_pc pc;
if (floppy->openers > 1) {
/* Don't format if someone is using the disk */
@@ -1602,7 +1535,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
struct block_device *bdev = inode->i_bdev;
struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);
ide_drive_t *drive = floppy->drive;
- idefloppy_pc_t pc;
+ struct ide_atapi_pc pc;
void __user *argp = (void __user *)arg;
int err;
@@ -1664,13 +1597,13 @@ static int idefloppy_revalidate_disk(struct gendisk *disk)
}
static struct block_device_operations idefloppy_ops = {
- .owner = THIS_MODULE,
- .open = idefloppy_open,
- .release = idefloppy_release,
- .ioctl = idefloppy_ioctl,
- .getgeo = idefloppy_getgeo,
- .media_changed = idefloppy_media_changed,
- .revalidate_disk= idefloppy_revalidate_disk
+ .owner = THIS_MODULE,
+ .open = idefloppy_open,
+ .release = idefloppy_release,
+ .ioctl = idefloppy_ioctl,
+ .getgeo = idefloppy_getgeo,
+ .media_changed = idefloppy_media_changed,
+ .revalidate_disk = idefloppy_revalidate_disk
};
static int ide_floppy_probe(ide_drive_t *drive)
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index 9ebec08eefd9..a6073e248f45 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -1,33 +1,142 @@
/*
* generic/default IDE host driver
*
- * Copyright (C) 2004 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2004, 2008 Bartlomiej Zolnierkiewicz
* This code was split off from ide.c. See it for original copyrights.
*
* May be copied or modified under the terms of the GNU General Public License.
*/
+/*
+ * For special cases new interfaces may be added using sysfs, i.e.
+ *
+ * echo -n "0x168:0x36e:10" > /sys/class/ide_generic/add
+ *
+ * will add an interface using I/O ports 0x168-0x16f/0x36e and IRQ 10.
+ */
+
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>
+#define DRV_NAME "ide_generic"
+
+static ssize_t store_add(struct class *cls, const char *buf, size_t n)
+{
+ ide_hwif_t *hwif;
+ unsigned int base, ctl;
+ int irq;
+ hw_regs_t hw;
+ u8 idx[] = { 0xff, 0xff, 0xff, 0xff };
+
+ if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3)
+ return -EINVAL;
+
+ hwif = ide_find_port();
+ if (hwif == NULL)
+ return -ENOENT;
+
+ memset(&hw, 0, sizeof(hw));
+ ide_std_init_ports(&hw, base, ctl);
+ hw.irq = irq;
+ hw.chipset = ide_generic;
+
+ ide_init_port_hw(hwif, &hw);
+
+ idx[0] = hwif->index;
+
+ ide_device_add(idx, NULL);
+
+ return n;
+};
+
+static struct class_attribute ide_generic_class_attrs[] = {
+ __ATTR(add, S_IWUSR, NULL, store_add),
+ __ATTR_NULL
+};
+
+static void ide_generic_class_release(struct class *cls)
+{
+ kfree(cls);
+}
+
+static int __init ide_generic_sysfs_init(void)
+{
+ struct class *cls;
+ int rc;
+
+ cls = kzalloc(sizeof(*cls), GFP_KERNEL);
+ if (!cls)
+ return -ENOMEM;
+
+ cls->name = DRV_NAME;
+ cls->owner = THIS_MODULE;
+ cls->class_release = ide_generic_class_release;
+ cls->class_attrs = ide_generic_class_attrs;
+
+ rc = class_register(cls);
+ if (rc) {
+ kfree(cls);
+ return rc;
+ }
+
+ return 0;
+}
+
static int __init ide_generic_init(void)
{
u8 idx[MAX_HWIFS];
int i;
for (i = 0; i < MAX_HWIFS; i++) {
- ide_hwif_t *hwif = &ide_hwifs[i];
+ ide_hwif_t *hwif;
+ 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.
+ */
+ hwif = ide_find_port();
+ if (hwif == NULL || hwif->index != i) {
+ idx[i] = 0xff;
+ continue;
+ }
+
+ memset(&hw, 0, sizeof(hw));
+ ide_std_init_ports(&hw, io_addr, io_addr + 0x206);
+ hw.irq = ide_default_irq(io_addr);
+ ide_init_port_hw(hwif, &hw);
- if (hwif->io_ports[IDE_DATA_OFFSET] && !hwif->present)
idx[i] = i;
- else
- idx[i] = 0xff;
+ }
}
ide_device_add_all(idx, NULL);
+ if (ide_generic_sysfs_init())
+ printk(KERN_ERR DRV_NAME ": failed to create ide_generic "
+ "class\n");
+
return 0;
}
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 715379605a7b..788783da9025 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,48 +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(IDE_DATA_REG);
-
- 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, IDE_CONTROL_REG);
-
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
- tf->nsect = hwif->INB(IDE_NSECTOR_REG);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
- tf->lbal = hwif->INB(IDE_SECTOR_REG);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
- tf->lbam = hwif->INB(IDE_LCYL_REG);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
- tf->lbah = hwif->INB(IDE_HCYL_REG);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
- tf->device = hwif->INB(IDE_SELECT_REG);
-
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- hwif->OUTB(drive->ctl | 0x80, IDE_CONTROL_REG);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = hwif->INB(IDE_FEATURE_REG);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = hwif->INB(IDE_NSECTOR_REG);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = hwif->INB(IDE_SECTOR_REG);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = hwif->INB(IDE_LCYL_REG);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = hwif->INB(IDE_HCYL_REG);
- }
-}
-
/**
* ide_end_drive_cmd - end an explicit drive command
* @drive: command
@@ -372,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);
@@ -421,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);
}
}
@@ -448,7 +406,8 @@ 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(IDE_COMMAND_REG) == WIN_SPECIFY)
+ hwif->INB(hwif->io_ports.command_addr) ==
+ WIN_SPECIFY)
return ide_stopped;
} else if ((err & BAD_CRC) == BAD_CRC) {
/* UDMA crc error, just retry the operation */
@@ -500,7 +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, IDE_COMMAND_REG);
+ hwif->OUTBSYNC(drive, WIN_IDLEIMMEDIATE,
+ hwif->io_ports.command_addr);
if (rq->errors >= ERROR_MAX) {
ide_kill_rq(drive, rq);
@@ -713,15 +673,12 @@ 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;
if (set_pio_mode_abuse(drive->hwif, req_pio)) {
-
- if (hwif->set_pio_mode == NULL)
- return ide_stopped;
-
/*
* take ide_lock for drive->[no_]unmask/[no_]io_32bit
*/
@@ -729,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;
@@ -1233,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);
}
/*
@@ -1350,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);
@@ -1416,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;
@@ -1506,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);
@@ -1680,7 +1637,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 e77cee0e5d65..57d9a9a79a6f 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,49 +73,151 @@ 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);
void SELECT_DRIVE (ide_drive_t *drive)
{
- if (HWIF(drive)->selectproc)
- HWIF(drive)->selectproc(drive);
- HWIF(drive)->OUTB(drive->select.all, IDE_SELECT_REG);
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (port_ops && port_ops->selectproc)
+ port_ops->selectproc(drive);
+
+ 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);
+ }
}
/*
@@ -176,105 +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, IDE_NSECTOR_REG);
- hwif->INSL(IDE_DATA_REG, 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(IDE_DATA_REG, buffer, wcount);
+
+ 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 {
- hwif->INSW(IDE_DATA_REG, buffer, wcount<<1);
+ 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;
- local_irq_save(flags);
- ata_vlb_sync(drive, IDE_NSECTOR_REG);
- hwif->OUTSL(IDE_DATA_REG, buffer, wcount);
- local_irq_restore(flags);
- } else
- hwif->OUTSL(IDE_DATA_REG, buffer, wcount);
- } else {
- hwif->OUTSW(IDE_DATA_REG, 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.
- */
+ unsigned long uninitialized_var(flags);
-static void atapi_input_bytes(ide_drive_t *drive, void *buffer, u32 bytecount)
-{
- ide_hwif_t *hwif = HWIF(drive);
+ if ((io_32bit & 2) && !mmio) {
+ local_irq_save(flags);
+ 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(IDE_DATA_REG, buffer, bytecount / 2);
- return;
- }
-#endif /* CONFIG_ATARI || CONFIG_Q40 */
- hwif->ata_input_data(drive, buffer, bytecount / 4);
- if ((bytecount & 0x03) >= 2)
- hwif->INSW(IDE_DATA_REG, ((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(IDE_DATA_REG, 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(IDE_DATA_REG, ((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)
@@ -416,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 */
@@ -429,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 (IDE_CONTROL_REG)
+ if (hwif->io_ports.ctl_addr)
stat = ide_read_altstatus(drive);
else
/* Note: this may clear a pending IRQ!! */
@@ -567,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 }
};
@@ -631,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, IDE_COMMAND_REG);
+ hwif->OUTBSYNC(drive, WIN_IDENTIFY, hwif->io_ports.command_addr);
timeout = jiffies + WAIT_WORSTCASE;
do {
if (time_after(jiffies, timeout)) {
@@ -658,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);
@@ -680,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;
@@ -687,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 */
@@ -718,9 +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, IDE_NSECTOR_REG);
- hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG);
- hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG);
+ 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);
@@ -745,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
@@ -828,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, IDE_COMMAND_REG);
+ hwif->OUTBSYNC(drive, cmd, hwif->io_ports.command_addr);
/*
* Drive takes 400nS to respond, we must avoid the IRQ being
* serviced before that.
@@ -838,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);
@@ -891,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;
@@ -960,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
@@ -980,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;
@@ -1009,11 +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);
@@ -1023,7 +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, IDE_COMMAND_REG);
+ hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr);
ndelay(400);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
hwgroup->polling = 1;
@@ -1039,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 (!IDE_CONTROL_REG) {
+ if (io_ports->ctl_addr == 0) {
spin_unlock_irqrestore(&ide_lock, flags);
return ide_stopped;
}
@@ -1054,16 +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,IDE_CONTROL_REG);
+ hwif->OUTBSYNC(drive, drive->ctl|6, io_ports->ctl_addr);
/* more than enough time */
udelay(10);
- if (drive->quirk_list == 2) {
- /* clear SRST and nIEN */
- hwif->OUTBSYNC(drive, drive->ctl, IDE_CONTROL_REG);
- } else {
- /* clear SRST, leave nIEN */
- hwif->OUTBSYNC(drive, drive->ctl|2, IDE_CONTROL_REG);
- }
+ 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, io_ports->ctl_addr);
/* more than enough time */
udelay(10);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
@@ -1075,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;
@@ -1107,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 7031a8dcf692..47af80df6872 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);
}
@@ -274,16 +274,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
if (overridden)
printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
drive->name);
-
- /*
- * Conservative "downgrade" for all pre-ATA2 drives
- */
- if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_DOWNGRADE) == 0 &&
- pio_mode && pio_mode < 4) {
- pio_mode--;
- printk(KERN_INFO "%s: applying conservative "
- "PIO \"downgrade\"\n", drive->name);
- }
}
if (pio_mode > max_mode)
@@ -298,9 +288,11 @@ 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;
BUG_ON(hwif->pio_mask == 0x00);
@@ -352,26 +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);
}
}
@@ -379,17 +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);
}
}
@@ -409,8 +409,10 @@ 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;
rate = ide_rate_filter(drive, rate);
@@ -485,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 c14bb5380c25..6a8953f68e9f 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -11,34 +11,52 @@
*
* You should have received a copy of the GNU General Public License
* (for example /usr/src/linux/COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#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 */
+ /* Generic ESDI/IDE/ATA compatible hard disk controller */
{.id = "PNP0600", .driver_data = 0},
{.id = ""}
};
-static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
+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(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port();
if (hwif) {
u8 index = hwif->index;
u8 idx[4] = { index, 0xff, 0xff, 0xff };
@@ -47,24 +65,27 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
ide_init_port_hw(hwif, &hw);
printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
- pnp_set_drvdata(dev,hwif);
+ pnp_set_drvdata(dev, hwif);
ide_device_add(idx, NULL);
return 0;
}
+ release_region(ctl, 1);
+ release_region(base, 8);
+
return -1;
}
-static void idepnp_remove(struct pnp_dev * dev)
+static void idepnp_remove(struct pnp_dev *dev)
{
ide_hwif_t *hwif = pnp_get_drvdata(dev);
- if (hwif)
- ide_unregister(hwif->index, 0, 0);
- 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 47a114927c31..099a0fe1745b 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 (IDE_CONTROL_REG) {
+ 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, IDE_FEATURE_REG);
+ hwif->OUTB(0, io_ports->feature_addr);
/* ask drive for ID */
- hwif->OUTB(cmd, IDE_COMMAND_REG);
+ 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 (IDE_CONTROL_REG) {
+ 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,8 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
msleep(50);
SELECT_DRIVE(drive);
msleep(50);
- if (hwif->INB(IDE_SELECT_REG) != drive->select.all && !drive->present) {
+ if (hwif->INB(io_ports->device_addr) != drive->select.all &&
+ !drive->present) {
if (drive->select.b.unit != 0) {
/* exit with drive0 selected */
SELECT_DRIVE(&hwif->drives[0]);
@@ -471,15 +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, IDE_SELECT_REG);
+ hwif->OUTB(drive->select.all, io_ports->device_addr);
msleep(50);
- hwif->OUTB(WIN_SRST, IDE_COMMAND_REG);
+ hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr);
(void)ide_busy_sleep(hwif);
rc = try_to_identify(drive, cmd);
}
@@ -515,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, IDE_COMMAND_REG);
+ hwif->OUTBSYNC(drive, EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr);
if (ide_busy_sleep(hwif)) {
printk(KERN_CONT "failed (timeout)\n");
@@ -623,7 +624,7 @@ static void hwif_release_dev (struct device *dev)
complete(&hwif->gendev_rel_comp);
}
-static void ide_register_port(ide_hwif_t *hwif)
+static int ide_register_port(ide_hwif_t *hwif)
{
int ret;
@@ -639,9 +640,23 @@ static void ide_register_port(ide_hwif_t *hwif)
}
hwif->gendev.release = hwif_release_dev;
ret = device_register(&hwif->gendev);
- if (ret < 0)
+ if (ret < 0) {
printk(KERN_WARNING "IDE: %s: device_register error: %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
+ goto out;
+ }
+
+ get_device(&hwif->gendev);
+
+ hwif->portdev = device_create(ide_port_class, &hwif->gendev,
+ MKDEV(0, 0), hwif->name);
+ if (IS_ERR(hwif->portdev)) {
+ ret = PTR_ERR(hwif->portdev);
+ device_unregister(&hwif->gendev);
+ }
+ dev_set_drvdata(hwif->portdev, hwif);
+out:
+ return ret;
}
/**
@@ -756,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;
/*
@@ -784,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
@@ -804,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);
}
}
@@ -949,6 +954,7 @@ static void ide_port_setup_devices(ide_hwif_t *hwif)
{
int i;
+ mutex_lock(&ide_cfg_mtx);
for (i = 0; i < MAX_DRIVES; i++) {
ide_drive_t *drive = &hwif->drives[i];
@@ -963,6 +969,7 @@ static void ide_port_setup_devices(ide_hwif_t *hwif)
ide_add_drive_to_hwgroup(drive);
}
+ mutex_unlock(&ide_cfg_mtx);
}
/*
@@ -975,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;
@@ -1058,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;
@@ -1076,20 +1084,17 @@ 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)",
hwif->sharing_irq ? "shar" : "serializ", match->name);
printk("\n");
- ide_port_setup_devices(hwif);
-
mutex_unlock(&ide_cfg_mtx);
return 0;
out_unlink:
@@ -1199,6 +1204,8 @@ static void drive_release_dev (struct device *dev)
{
ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
+ ide_proc_unregister_device(drive);
+
spin_lock_irq(&ide_lock);
ide_remove_drive_from_hwgroup(drive);
kfree(drive->id);
@@ -1214,24 +1221,21 @@ static void drive_release_dev (struct device *dev)
complete(&drive->gendev_rel_comp);
}
+#ifndef ide_default_irq
+#define ide_default_irq(irq) 0
+#endif
+
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;
}
}
-#ifdef CONFIG_BLK_DEV_HD
- if (hwif->irq == HD_IRQ && hwif->io_ports[IDE_DATA_OFFSET] != HD_DATA) {
- printk("%s: CANNOT SHARE IRQ WITH OLD "
- "HARDDISK DRIVER (hd.c)\n", hwif->name);
- return 0;
- }
-#endif /* CONFIG_BLK_DEV_HD */
if (register_blkdev(hwif->major, hwif->name))
return 0;
@@ -1256,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;
@@ -1308,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++) {
@@ -1319,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,
@@ -1339,9 +1343,6 @@ 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;
@@ -1349,16 +1350,36 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
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;
@@ -1366,26 +1387,138 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
/* call chipset specific routine for each enabled port */
if (d->init_hwif)
d->init_hwif(hwif);
+}
- if (hwif->cable_detect && (hwif->ultra_mask & 0x78)) {
+static void ide_port_cable_detect(ide_hwif_t *hwif)
+{
+ 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);
}
}
+static ssize_t store_delete_devices(struct device *portdev,
+ struct device_attribute *attr,
+ const char *buf, size_t n)
+{
+ ide_hwif_t *hwif = dev_get_drvdata(portdev);
+
+ if (strncmp(buf, "1", n))
+ return -EINVAL;
+
+ ide_port_unregister_devices(hwif);
+
+ return n;
+};
+
+static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices);
+
+static ssize_t store_scan(struct device *portdev,
+ struct device_attribute *attr,
+ const char *buf, size_t n)
+{
+ ide_hwif_t *hwif = dev_get_drvdata(portdev);
+
+ if (strncmp(buf, "1", n))
+ return -EINVAL;
+
+ ide_port_unregister_devices(hwif);
+ ide_port_scan(hwif);
+
+ return n;
+};
+
+static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);
+
+static struct device_attribute *ide_port_attrs[] = {
+ &dev_attr_delete_devices,
+ &dev_attr_scan,
+ NULL
+};
+
+static int ide_sysfs_register_port(ide_hwif_t *hwif)
+{
+ int i, rc;
+
+ for (i = 0; ide_port_attrs[i]; i++) {
+ rc = device_create_file(hwif->portdev, ide_port_attrs[i]);
+ if (rc)
+ break;
+ }
+
+ return rc;
+}
+
+/**
+ * ide_find_port_slot - find free ide_hwifs[] slot
+ * @d: IDE port info
+ *
+ * Return the new hwif. If we are out of free slots return NULL.
+ */
+
+ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d)
+{
+ ide_hwif_t *hwif;
+ int i;
+ u8 bootable = (d && (d->host_flags & IDE_HFLAG_NON_BOOTABLE)) ? 0 : 1;
+
+ /*
+ * Claim an unassigned slot.
+ *
+ * Give preference to claiming other slots before claiming ide0/ide1,
+ * just in case there's another interface yet-to-be-scanned
+ * which uses ports 0x1f0/0x170 (the ide0/ide1 defaults).
+ *
+ * Unless there is a bootable card that does not use the standard
+ * ports 0x1f0/0x170 (the ide0/ide1 defaults).
+ */
+ if (bootable) {
+ i = (d && (d->host_flags & IDE_HFLAG_QD_2ND_PORT)) ? 1 : 0;
+
+ for (; i < MAX_HWIFS; i++) {
+ hwif = &ide_hwifs[i];
+ if (hwif->chipset == ide_unknown)
+ return hwif;
+ }
+ } else {
+ for (i = 2; i < MAX_HWIFS; i++) {
+ hwif = &ide_hwifs[i];
+ if (hwif->chipset == ide_unknown)
+ return hwif;
+ }
+ for (i = 0; i < 2 && i < MAX_HWIFS; i++) {
+ hwif = &ide_hwifs[i];
+ if (hwif->chipset == ide_unknown)
+ return hwif;
+ }
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(ide_find_port_slot);
+
int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
{
ide_hwif_t *hwif, *mate = NULL;
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;
@@ -1394,6 +1527,7 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
mate = (i & 1) ? NULL : hwif;
ide_init_port(hwif, i & 1, d);
+ ide_port_cable_detect(hwif);
ide_port_init_devices(hwif);
}
@@ -1403,25 +1537,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++) {
@@ -1430,9 +1554,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);
@@ -1441,8 +1562,13 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
continue;
}
+ 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++) {
@@ -1451,12 +1577,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_forced)
- 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++) {
@@ -1465,10 +1590,11 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
hwif = &ide_hwifs[idx[i]];
- if (hwif->present) {
- 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;
@@ -1486,3 +1612,86 @@ int ide_device_add(u8 idx[4], const struct ide_port_info *d)
return ide_device_add_all(idx_all, d);
}
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);
+
+ if (ide_probe_port(hwif) < 0)
+ return;
+
+ hwif->present = 1;
+
+ ide_port_tune_devices(hwif);
+ ide_acpi_port_init_devices(hwif);
+ ide_port_setup_devices(hwif);
+ hwif_register_devices(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 bab88ca7f7ec..7b2f3815a838 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -46,32 +46,29 @@ static int proc_ide_read_imodel
int len;
const char *name;
- /*
- * Neither ide_unknown nor ide_forced should be set at this point.
- */
switch (hwif->chipset) {
- case ide_generic: name = "generic"; break;
- case ide_pci: name = "pci"; break;
- case ide_cmd640: name = "cmd640"; break;
- case ide_dtc2278: name = "dtc2278"; break;
- case ide_ali14xx: name = "ali14xx"; break;
- case ide_qd65xx: name = "qd65xx"; break;
- case ide_umc8672: name = "umc8672"; break;
- case ide_ht6560b: name = "ht6560b"; break;
- case ide_rz1000: name = "rz1000"; break;
- case ide_trm290: name = "trm290"; break;
- case ide_cmd646: name = "cmd646"; break;
- case ide_cy82c693: name = "cy82c693"; break;
- case ide_4drives: name = "4drives"; break;
- case ide_pmac: name = "mac-io"; break;
- case ide_au1xxx: name = "au1xxx"; break;
- case ide_palm3710: name = "palm3710"; break;
- case ide_etrax100: name = "etrax100"; break;
- case ide_acorn: name = "acorn"; break;
- default: name = "(unknown)"; break;
+ case ide_generic: name = "generic"; break;
+ case ide_pci: name = "pci"; break;
+ case ide_cmd640: name = "cmd640"; break;
+ case ide_dtc2278: name = "dtc2278"; break;
+ case ide_ali14xx: name = "ali14xx"; break;
+ case ide_qd65xx: name = "qd65xx"; break;
+ case ide_umc8672: name = "umc8672"; break;
+ case ide_ht6560b: name = "ht6560b"; break;
+ case ide_rz1000: name = "rz1000"; break;
+ case ide_trm290: name = "trm290"; break;
+ case ide_cmd646: name = "cmd646"; break;
+ case ide_cy82c693: name = "cy82c693"; break;
+ case ide_4drives: name = "4drives"; break;
+ case ide_pmac: name = "mac-io"; break;
+ case ide_au1xxx: name = "au1xxx"; break;
+ case ide_palm3710: name = "palm3710"; break;
+ case ide_etrax100: name = "etrax100"; break;
+ case ide_acorn: name = "acorn"; break;
+ default: name = "(unknown)"; break;
}
len = sprintf(page, "%s\n", name);
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
static int proc_ide_read_mate
@@ -84,7 +81,7 @@ static int proc_ide_read_mate
len = sprintf(page, "%s\n", hwif->mate->name);
else
len = sprintf(page, "(none)\n");
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
static int proc_ide_read_channel
@@ -96,7 +93,7 @@ static int proc_ide_read_channel
page[0] = hwif->channel ? '1' : '0';
page[1] = '\n';
len = 2;
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
static int proc_ide_read_identify
@@ -123,7 +120,7 @@ static int proc_ide_read_identify
len = out - page;
}
}
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
/**
@@ -200,7 +197,7 @@ EXPORT_SYMBOL(ide_add_setting);
* The caller must hold the setting semaphore.
*/
-static void __ide_remove_setting (ide_drive_t *drive, char *name)
+static void __ide_remove_setting(ide_drive_t *drive, char *name)
{
ide_settings_t **p, *setting;
@@ -208,7 +205,8 @@ static void __ide_remove_setting (ide_drive_t *drive, char *name)
while ((*p) && strcmp((*p)->name, name))
p = &((*p)->next);
- if ((setting = (*p)) == NULL)
+ setting = (*p);
+ if (setting == NULL)
return;
(*p) = setting->next;
@@ -226,7 +224,7 @@ static void __ide_remove_setting (ide_drive_t *drive, char *name)
* caller must hold ide_setting_mtx.
*/
-static void auto_remove_settings (ide_drive_t *drive)
+static void auto_remove_settings(ide_drive_t *drive)
{
ide_settings_t *setting;
repeat:
@@ -282,16 +280,16 @@ static int ide_read_setting(ide_drive_t *drive, ide_settings_t *setting)
if ((setting->rw & SETTING_READ)) {
spin_lock_irqsave(&ide_lock, flags);
- switch(setting->data_type) {
- case TYPE_BYTE:
- val = *((u8 *) setting->data);
- break;
- case TYPE_SHORT:
- val = *((u16 *) setting->data);
- break;
- case TYPE_INT:
- val = *((u32 *) setting->data);
- break;
+ switch (setting->data_type) {
+ case TYPE_BYTE:
+ val = *((u8 *) setting->data);
+ break;
+ case TYPE_SHORT:
+ val = *((u16 *) setting->data);
+ break;
+ case TYPE_INT:
+ val = *((u32 *) setting->data);
+ break;
}
spin_unlock_irqrestore(&ide_lock, flags);
}
@@ -329,15 +327,15 @@ static int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int va
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
switch (setting->data_type) {
- case TYPE_BYTE:
- *((u8 *) setting->data) = val;
- break;
- case TYPE_SHORT:
- *((u16 *) setting->data) = val;
- break;
- case TYPE_INT:
- *((u32 *) setting->data) = val;
- break;
+ case TYPE_BYTE:
+ *((u8 *) setting->data) = val;
+ break;
+ case TYPE_SHORT:
+ *((u16 *) setting->data) = val;
+ break;
+ case TYPE_INT:
+ *((u32 *) setting->data) = val;
+ break;
}
spin_unlock_irq(&ide_lock);
return 0;
@@ -393,7 +391,7 @@ void ide_add_generic_settings (ide_drive_t *drive)
static void proc_ide_settings_warn(void)
{
- static int warned = 0;
+ static int warned;
if (warned)
return;
@@ -416,11 +414,12 @@ static int proc_ide_read_settings
mutex_lock(&ide_setting_mtx);
out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
- while(setting) {
+ while (setting) {
mul_factor = setting->mul_factor;
div_factor = setting->div_factor;
out += sprintf(out, "%-24s", setting->name);
- if ((rc = ide_read_setting(drive, setting)) >= 0)
+ rc = ide_read_setting(drive, setting);
+ if (rc >= 0)
out += sprintf(out, "%-16d", rc * mul_factor / div_factor);
else
out += sprintf(out, "%-16s", "write-only");
@@ -434,7 +433,7 @@ static int proc_ide_read_settings
}
len = out - page;
mutex_unlock(&ide_setting_mtx);
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
#define MAX_LEN 30
@@ -515,8 +514,7 @@ static int proc_ide_write_settings(struct file *file, const char __user *buffer,
mutex_lock(&ide_setting_mtx);
setting = ide_find_setting_by_name(drive, name);
- if (!setting)
- {
+ if (!setting) {
mutex_unlock(&ide_setting_mtx);
goto parse_error;
}
@@ -536,8 +534,8 @@ parse_error:
int proc_ide_read_capacity
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
- int len = sprintf(page,"%llu\n", (long long)0x7fffffff);
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+ int len = sprintf(page, "%llu\n", (long long)0x7fffffff);
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
EXPORT_SYMBOL_GPL(proc_ide_read_capacity);
@@ -549,13 +547,13 @@ int proc_ide_read_geometry
char *out = page;
int len;
- out += sprintf(out,"physical %d/%d/%d\n",
+ out += sprintf(out, "physical %d/%d/%d\n",
drive->cyl, drive->head, drive->sect);
- out += sprintf(out,"logical %d/%d/%d\n",
+ out += sprintf(out, "logical %d/%d/%d\n",
drive->bios_cyl, drive->bios_head, drive->bios_sect);
len = out - page;
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
EXPORT_SYMBOL(proc_ide_read_geometry);
@@ -569,7 +567,7 @@ static int proc_ide_read_dmodel
len = sprintf(page, "%.40s\n",
(id && id->model[0]) ? (char *)id->model : "(none)");
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
static int proc_ide_read_driver
@@ -586,7 +584,7 @@ static int proc_ide_read_driver
dev->driver->name, ide_drv->version);
} else
len = sprintf(page, "ide-default version 0.9.newide\n");
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
@@ -601,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;
@@ -642,30 +640,26 @@ static int proc_ide_read_media
int len;
switch (drive->media) {
- case ide_disk: media = "disk\n";
- break;
- case ide_cdrom: media = "cdrom\n";
- break;
- case ide_tape: media = "tape\n";
- break;
- case ide_floppy:media = "floppy\n";
- break;
- case ide_optical:media = "optical\n";
- break;
- default: media = "UNKNOWN\n";
- break;
+ case ide_disk: media = "disk\n"; break;
+ case ide_cdrom: media = "cdrom\n"; break;
+ case ide_tape: media = "tape\n"; break;
+ case ide_floppy: media = "floppy\n"; break;
+ case ide_optical: media = "optical\n"; break;
+ default: media = "UNKNOWN\n"; break;
}
- strcpy(page,media);
+ strcpy(page, media);
len = strlen(media);
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+ PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
static ide_proc_entry_t generic_drive_entries[] = {
- { "driver", S_IFREG|S_IRUGO, proc_ide_read_driver, proc_ide_write_driver },
- { "identify", S_IFREG|S_IRUSR, proc_ide_read_identify, NULL },
- { "media", S_IFREG|S_IRUGO, proc_ide_read_media, NULL },
- { "model", S_IFREG|S_IRUGO, proc_ide_read_dmodel, NULL },
- { "settings", S_IFREG|S_IRUSR|S_IWUSR,proc_ide_read_settings, proc_ide_write_settings },
+ { "driver", S_IFREG|S_IRUGO, proc_ide_read_driver,
+ proc_ide_write_driver },
+ { "identify", S_IFREG|S_IRUSR, proc_ide_read_identify, NULL },
+ { "media", S_IFREG|S_IRUGO, proc_ide_read_media, NULL },
+ { "model", S_IFREG|S_IRUGO, proc_ide_read_dmodel, NULL },
+ { "settings", S_IFREG|S_IRUSR|S_IWUSR, proc_ide_read_settings,
+ proc_ide_write_settings },
{ NULL, 0, NULL, NULL }
};
@@ -737,7 +731,6 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
spin_unlock_irqrestore(&ide_lock, flags);
mutex_unlock(&ide_setting_mtx);
}
-
EXPORT_SYMBOL(ide_proc_unregister_driver);
void ide_proc_port_register_devices(ide_hwif_t *hwif)
@@ -758,33 +751,22 @@ void ide_proc_port_register_devices(ide_hwif_t *hwif)
drive->proc = proc_mkdir(drive->name, parent);
if (drive->proc)
ide_add_proc_entries(drive->proc, generic_drive_entries, drive);
- sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name);
+ sprintf(name, "ide%d/%s", (drive->name[2]-'a')/2, drive->name);
ent = proc_symlink(drive->name, proc_ide_root, name);
if (!ent) return;
}
}
-static void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
+void ide_proc_unregister_device(ide_drive_t *drive)
{
if (drive->proc) {
ide_remove_proc_entries(drive->proc, generic_drive_entries);
remove_proc_entry(drive->name, proc_ide_root);
- remove_proc_entry(drive->name, hwif->proc);
+ remove_proc_entry(drive->name, drive->hwif->proc);
drive->proc = NULL;
}
}
-static void destroy_proc_ide_drives(ide_hwif_t *hwif)
-{
- int d;
-
- for (d = 0; d < MAX_DRIVES; d++) {
- ide_drive_t *drive = &hwif->drives[d];
- if (drive->proc)
- destroy_proc_ide_device(hwif, drive);
- }
-}
-
static ide_proc_entry_t hwif_entries[] = {
{ "channel", S_IFREG|S_IRUGO, proc_ide_read_channel, NULL },
{ "mate", S_IFREG|S_IRUGO, proc_ide_read_mate, NULL },
@@ -804,19 +786,9 @@ 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) {
- destroy_proc_ide_drives(hwif);
ide_remove_proc_entries(hwif->proc, hwif_entries);
remove_proc_entry(hwif->name, proc_ide_root);
hwif->proc = NULL;
@@ -840,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;
}
diff --git a/drivers/ide/ide-scan-pci.c b/drivers/ide/ide-scan-pci.c
index 93d2e41be853..0e79efff1deb 100644
--- a/drivers/ide/ide-scan-pci.c
+++ b/drivers/ide/ide-scan-pci.c
@@ -88,13 +88,8 @@ static int __init ide_scan_pcibus(void)
struct list_head *l, *n;
pre_init = 0;
- if (!ide_scan_direction)
- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)))
- ide_scan_pcidev(dev);
- else
- while ((dev = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID,
- dev)))
- ide_scan_pcidev(dev);
+ while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)))
+ ide_scan_pcidev(dev);
/*
* Hand the drivers over to the PCI layer now we
@@ -107,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 0598ecfd5f37..54a43b044608 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.
@@ -181,56 +161,59 @@ struct idetape_bh {
char *b_data;
};
-typedef struct idetape_packet_command_s {
- /* Actual packet bytes */
- u8 c[12];
- /* On each retry, we increment retries */
- int retries;
- /* Error code */
- int error;
- /* Bytes to transfer */
- int request_transfer;
- /* Bytes actually transferred */
- int actually_transferred;
- /* Size of our data buffer */
- int buffer_size;
- struct idetape_bh *bh;
- char *b_data;
- int b_count;
- /* Data buffer */
- u8 *buffer;
- /* Pointer into the above buffer */
- u8 *current_position;
- /* Called when this packet command is completed */
- ide_startstop_t (*callback) (ide_drive_t *);
- /* Temporary buffer */
- u8 pc_buffer[IDETAPE_PC_BUFFER_SIZE];
- /* Status/Action bit flags: long for set_bit */
- unsigned long flags;
-} idetape_pc_t;
+/* Tape door status */
+#define DOOR_UNLOCKED 0
+#define DOOR_LOCKED 1
+#define DOOR_EXPLICITLY_LOCKED 2
+
+/* Some defines for the SPACE command */
+#define IDETAPE_SPACE_OVER_FILEMARK 1
+#define IDETAPE_SPACE_TO_EOD 3
+
+/* Some defines for the LOAD UNLOAD command */
+#define IDETAPE_LU_LOAD_MASK 1
+#define IDETAPE_LU_RETENSION_MASK 2
+#define IDETAPE_LU_EOT_MASK 4
/*
- * Packet command flag bits.
+ * Special requests for our block device strategy routine.
+ *
+ * In order to service a character device command, we add special requests to
+ * the tail of our block device request queue and wait for their completion.
*/
-/* Set when an error is considered normal - We won't retry */
-#define PC_ABORT 0
-/* 1 When polling for DSC on a media access command */
-#define PC_WAIT_FOR_DSC 1
-/* 1 when we prefer to use DMA if possible */
-#define PC_DMA_RECOMMENDED 2
-/* 1 while DMA in progress */
-#define PC_DMA_IN_PROGRESS 3
-/* 1 when encountered problem during DMA */
-#define PC_DMA_ERROR 4
-/* Data direction */
-#define PC_WRITING 5
-
-/* 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;
+
+enum {
+ REQ_IDETAPE_PC1 = (1 << 0), /* packet command (first stage) */
+ REQ_IDETAPE_PC2 = (1 << 1), /* packet command (second stage) */
+ REQ_IDETAPE_READ = (1 << 2),
+ REQ_IDETAPE_WRITE = (1 << 3),
+};
+
+/* Error codes returned in rq->errors to the higher part of the driver. */
+#define IDETAPE_ERROR_GENERAL 101
+#define IDETAPE_ERROR_FILEMARK 102
+#define IDETAPE_ERROR_EOD 103
+
+/* Structures related to the SELECT SENSE / MODE SENSE packet commands. */
+#define IDETAPE_BLOCK_DESCRIPTOR 0
+#define IDETAPE_CAPABILITIES_PAGE 0x2a
+
+/* Tape flag bits values. */
+enum {
+ IDETAPE_FLAG_IGNORE_DSC = (1 << 0),
+ /* 0 When the tape position is unknown */
+ IDETAPE_FLAG_ADDRESS_VALID = (1 << 1),
+ /* Device already opened */
+ IDETAPE_FLAG_BUSY = (1 << 2),
+ /* Attempt to auto-detect the current user block size */
+ IDETAPE_FLAG_DETECT_BS = (1 << 3),
+ /* Currently on a filemark */
+ IDETAPE_FLAG_FILEMARK = (1 << 4),
+ /* DRQ interrupt device */
+ IDETAPE_FLAG_DRQ_INTERRUPT = (1 << 5),
+ /* 0 = no tape is loaded, so we don't rewind after ejecting */
+ IDETAPE_FLAG_MEDIUM_PRESENT = (1 << 6),
+};
/*
* Most of our global data which we need to save even as we leave the driver due
@@ -258,11 +241,11 @@ typedef struct ide_tape_obj {
* retry, to get detailed information on what went wrong.
*/
/* Current packet command */
- idetape_pc_t *pc;
+ struct ide_atapi_pc *pc;
/* Last failed packet command */
- idetape_pc_t *failed_pc;
+ struct ide_atapi_pc *failed_pc;
/* Packet command stack */
- idetape_pc_t pc_stack[IDETAPE_PC_STACK];
+ struct ide_atapi_pc pc_stack[IDETAPE_PC_STACK];
/* Next free packet command storage space */
int pc_stack_index;
struct request rq_stack[IDETAPE_PC_STACK];
@@ -275,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 */
@@ -317,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;
@@ -374,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;
@@ -446,58 +365,6 @@ static void ide_tape_put(struct ide_tape_obj *tape)
mutex_unlock(&idetape_ref_mutex);
}
-/* Tape door status */
-#define DOOR_UNLOCKED 0
-#define DOOR_LOCKED 1
-#define DOOR_EXPLICITLY_LOCKED 2
-
-/*
- * Tape flag bits values.
- */
-#define IDETAPE_IGNORE_DSC 0
-#define IDETAPE_ADDRESS_VALID 1 /* 0 When the tape position is unknown */
-#define IDETAPE_BUSY 2 /* Device already opened */
-#define IDETAPE_PIPELINE_ERROR 3 /* Error detected in a pipeline stage */
-#define IDETAPE_DETECT_BS 4 /* Attempt to auto-detect the current user block size */
-#define IDETAPE_FILEMARK 5 /* Currently on a filemark */
-#define IDETAPE_DRQ_INTERRUPT 6 /* DRQ interrupt device */
-#define IDETAPE_READ_ERROR 7
-#define IDETAPE_PIPELINE_ACTIVE 8 /* pipeline active */
-/* 0 = no tape is loaded, so we don't rewind after ejecting */
-#define IDETAPE_MEDIUM_PRESENT 9
-
-/* Some defines for the SPACE command */
-#define IDETAPE_SPACE_OVER_FILEMARK 1
-#define IDETAPE_SPACE_TO_EOD 3
-
-/* Some defines for the LOAD UNLOAD command */
-#define IDETAPE_LU_LOAD_MASK 1
-#define IDETAPE_LU_RETENSION_MASK 2
-#define IDETAPE_LU_EOT_MASK 4
-
-/*
- * Special requests for our block device strategy routine.
- *
- * In order to service a character device command, we add special requests to
- * the tail of our block device request queue and wait for their completion.
- */
-
-enum {
- REQ_IDETAPE_PC1 = (1 << 0), /* packet command (first stage) */
- REQ_IDETAPE_PC2 = (1 << 1), /* packet command (second stage) */
- REQ_IDETAPE_READ = (1 << 2),
- REQ_IDETAPE_WRITE = (1 << 3),
-};
-
-/* Error codes returned in rq->errors to the higher part of the driver. */
-#define IDETAPE_ERROR_GENERAL 101
-#define IDETAPE_ERROR_FILEMARK 102
-#define IDETAPE_ERROR_EOD 103
-
-/* Structures related to the SELECT SENSE / MODE SENSE packet commands. */
-#define IDETAPE_BLOCK_DESCRIPTOR 0
-#define IDETAPE_CAPABILITIES_PAGE 0x2a
-
/*
* The variables below are used for the character device interface. Additional
* state variables are defined in our ide_drive_t structure.
@@ -518,17 +385,7 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
return tape;
}
-/*
- * Too bad. The drive wants to send us data which we are not ready to accept.
- * Just throw it away.
- */
-static void idetape_discard_data(ide_drive_t *drive, unsigned int bcount)
-{
- while (bcount--)
- (void) HWIF(drive)->INB(IDE_DATA_REG);
-}
-
-static void idetape_input_buffers(ide_drive_t *drive, idetape_pc_t *pc,
+static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount)
{
struct idetape_bh *bh = pc->bh;
@@ -538,13 +395,13 @@ static void idetape_input_buffers(ide_drive_t *drive, idetape_pc_t *pc,
if (bh == NULL) {
printk(KERN_ERR "ide-tape: bh == NULL in "
"idetape_input_buffers\n");
- idetape_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);
@@ -557,7 +414,7 @@ static void idetape_input_buffers(ide_drive_t *drive, idetape_pc_t *pc,
pc->bh = bh;
}
-static void idetape_output_buffers(ide_drive_t *drive, idetape_pc_t *pc,
+static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount)
{
struct idetape_bh *bh = pc->bh;
@@ -570,7 +427,7 @@ static void idetape_output_buffers(ide_drive_t *drive, idetape_pc_t *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;
@@ -585,13 +442,13 @@ static void idetape_output_buffers(ide_drive_t *drive, idetape_pc_t *pc,
}
}
-static void idetape_update_buffers(idetape_pc_t *pc)
+static void idetape_update_buffers(struct ide_atapi_pc *pc)
{
struct idetape_bh *bh = pc->bh;
int count;
- unsigned int bcount = pc->actually_transferred;
+ unsigned int bcount = pc->xferred;
- if (test_bit(PC_WRITING, &pc->flags))
+ if (pc->flags & PC_FLAG_WRITING)
return;
while (bcount) {
if (bh == NULL) {
@@ -614,7 +471,7 @@ static void idetape_update_buffers(idetape_pc_t *pc)
* driver. A storage space for a maximum of IDETAPE_PC_STACK packet
* commands is allocated at initialization time.
*/
-static idetape_pc_t *idetape_next_pc_storage(ide_drive_t *drive)
+static struct ide_atapi_pc *idetape_next_pc_storage(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
@@ -649,14 +506,14 @@ static struct request *idetape_next_rq_storage(ide_drive_t *drive)
return (&tape->rq_stack[tape->rq_stack_index++]);
}
-static void idetape_init_pc(idetape_pc_t *pc)
+static void idetape_init_pc(struct ide_atapi_pc *pc)
{
memset(pc->c, 0, 12);
pc->retries = 0;
pc->flags = 0;
- pc->request_transfer = 0;
- pc->buffer = pc->pc_buffer;
- pc->buffer_size = IDETAPE_PC_BUFFER_SIZE;
+ pc->req_xfer = 0;
+ pc->buf = pc->pc_buf;
+ pc->buf_size = IDETAPE_PC_BUFFER_SIZE;
pc->bh = NULL;
pc->b_data = NULL;
}
@@ -668,7 +525,7 @@ static void idetape_init_pc(idetape_pc_t *pc)
static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_pc_t *pc = tape->failed_pc;
+ struct ide_atapi_pc *pc = tape->failed_pc;
tape->sense_key = sense[2] & 0xF;
tape->asc = sense[12];
@@ -677,9 +534,9 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n",
pc->c[0], tape->sense_key, tape->asc, tape->ascq);
- /* Correct pc->actually_transferred by asking the tape. */
- if (test_bit(PC_DMA_ERROR, &pc->flags)) {
- pc->actually_transferred = pc->request_transfer -
+ /* Correct pc->xferred by asking the tape. */
+ if (pc->flags & PC_FLAG_DMA_ERROR) {
+ pc->xferred = pc->req_xfer -
tape->blk_size *
be32_to_cpu(get_unaligned((u32 *)&sense[3]));
idetape_update_buffers(pc);
@@ -697,153 +554,61 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
/* don't report an error, everything's ok */
pc->error = 0;
/* don't retry read/write */
- set_bit(PC_ABORT, &pc->flags);
+ pc->flags |= PC_FLAG_ABORT;
}
}
if (pc->c[0] == READ_6 && (sense[2] & 0x80)) {
pc->error = IDETAPE_ERROR_FILEMARK;
- set_bit(PC_ABORT, &pc->flags);
+ pc->flags |= PC_FLAG_ABORT;
}
if (pc->c[0] == WRITE_6) {
if ((sense[2] & 0x40) || (tape->sense_key == 0xd
&& tape->asc == 0x0 && tape->ascq == 0x2)) {
pc->error = IDETAPE_ERROR_EOD;
- set_bit(PC_ABORT, &pc->flags);
+ pc->flags |= PC_FLAG_ABORT;
}
}
if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
if (tape->sense_key == 8) {
pc->error = IDETAPE_ERROR_EOD;
- set_bit(PC_ABORT, &pc->flags);
+ pc->flags |= PC_FLAG_ABORT;
}
- if (!test_bit(PC_ABORT, &pc->flags) &&
- pc->actually_transferred)
+ if (!(pc->flags & PC_FLAG_ABORT) &&
+ pc->xferred)
pc->retries = IDETAPE_MAX_PC_RETRIES + 1;
}
}
-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);
-}
-
-/*
- * 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;
+ kfree(tape->merge_bh);
}
-/*
- * 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__);
@@ -863,56 +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_PIPELINE_ERROR, &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_PIPELINE_ERROR, &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_PIPELINE_ACTIVE, &tape->flags);
spin_unlock_irqrestore(&tape->lock, flags);
return 0;
}
@@ -924,7 +641,7 @@ static ide_startstop_t idetape_request_sense_callback(ide_drive_t *drive)
debug_log(DBG_PROCS, "Enter %s\n", __func__);
if (!tape->pc->error) {
- idetape_analyze_error(drive, tape->pc->buffer);
+ idetape_analyze_error(drive, tape->pc->buf);
idetape_end_request(drive, 1, 0);
} else {
printk(KERN_ERR "ide-tape: Error in REQUEST SENSE itself - "
@@ -934,13 +651,13 @@ static ide_startstop_t idetape_request_sense_callback(ide_drive_t *drive)
return ide_stopped;
}
-static void idetape_create_request_sense_cmd(idetape_pc_t *pc)
+static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc)
{
idetape_init_pc(pc);
pc->c[0] = REQUEST_SENSE;
pc->c[4] = 20;
- pc->request_transfer = 20;
- pc->callback = &idetape_request_sense_callback;
+ pc->req_xfer = 20;
+ pc->idetape_callback = &idetape_request_sense_callback;
}
static void idetape_init_rq(struct request *rq, u8 cmd)
@@ -965,7 +682,7 @@ static void idetape_init_rq(struct request *rq, u8 cmd)
* handling functions should queue request to the lower level part and wait for
* their completion using idetape_queue_pc_tail or idetape_queue_rw_tail.
*/
-static void idetape_queue_pc_head(ide_drive_t *drive, idetape_pc_t *pc,
+static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
struct request *rq)
{
struct ide_tape_obj *tape = drive->driver_data;
@@ -984,14 +701,14 @@ static void idetape_queue_pc_head(ide_drive_t *drive, idetape_pc_t *pc,
static ide_startstop_t idetape_retry_pc (ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_pc_t *pc;
+ struct ide_atapi_pc *pc;
struct request *rq;
(void)ide_read_error(drive);
pc = idetape_next_pc_storage(drive);
rq = idetape_next_rq_storage(drive);
idetape_create_request_sense_cmd(pc);
- set_bit(IDETAPE_IGNORE_DSC, &tape->flags);
+ set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags);
idetape_queue_pc_head(drive, pc, rq);
return ide_stopped;
}
@@ -1010,7 +727,7 @@ static void idetape_postpone_request(ide_drive_t *drive)
ide_stall_queue(drive, tape->dsc_poll_freq);
}
-typedef void idetape_io_buf(ide_drive_t *, idetape_pc_t *, unsigned int);
+typedef void idetape_io_buf(ide_drive_t *, struct ide_atapi_pc *, unsigned int);
/*
* This is the usual interrupt handler which will be called during a packet
@@ -1023,7 +740,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
idetape_tape_t *tape = drive->driver_data;
- idetape_pc_t *pc = tape->pc;
+ struct ide_atapi_pc *pc = tape->pc;
xfer_func_t *xferfunc;
idetape_io_buf *iobuf;
unsigned int temp;
@@ -1038,8 +755,8 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
/* Clear the interrupt */
stat = ide_read_status(drive);
- if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
- if (hwif->ide_dma_end(drive) || (stat & ERR_STAT)) {
+ if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
+ 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
@@ -1061,9 +778,9 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
* data transfer will occur, but no DMA error.
* (AS, 19 Apr 2001)
*/
- set_bit(PC_DMA_ERROR, &pc->flags);
+ pc->flags |= PC_FLAG_DMA_ERROR;
} else {
- pc->actually_transferred = pc->request_transfer;
+ pc->xferred = pc->req_xfer;
idetape_update_buffers(pc);
}
debug_log(DBG_PROCS, "DMA finished\n");
@@ -1073,9 +790,9 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
/* No more interrupts */
if ((stat & DRQ_STAT) == 0) {
debug_log(DBG_SENSE, "Packet command completed, %d bytes"
- " transferred\n", pc->actually_transferred);
+ " transferred\n", pc->xferred);
- clear_bit(PC_DMA_IN_PROGRESS, &pc->flags);
+ pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
local_irq_enable();
#if SIMULATE_ERRORS
@@ -1088,7 +805,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
#endif
if ((stat & ERR_STAT) && pc->c[0] == REQUEST_SENSE)
stat &= ~ERR_STAT;
- if ((stat & ERR_STAT) || test_bit(PC_DMA_ERROR, &pc->flags)) {
+ if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
/* Error detected */
debug_log(DBG_ERR, "%s: I/O error\n", tape->name);
@@ -1104,7 +821,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
return idetape_retry_pc(drive);
}
pc->error = 0;
- if (test_bit(PC_WAIT_FOR_DSC, &pc->flags) &&
+ if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) &&
(stat & SEEK_STAT) == 0) {
/* Media access command */
tape->dsc_polling_start = jiffies;
@@ -1117,9 +834,11 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
if (tape->failed_pc == pc)
tape->failed_pc = NULL;
/* Command finished - Call the callback function */
- return pc->callback(drive);
+ return pc->idetape_callback(drive);
}
- if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
+
+ if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
+ pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
printk(KERN_ERR "ide-tape: The tape wants to issue more "
"interrupts in DMA mode\n");
printk(KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n");
@@ -1127,16 +846,16 @@ 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(IDE_BCOUNTH_REG) << 8) |
- hwif->INB(IDE_BCOUNTL_REG);
+ bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
+ hwif->INB(hwif->io_ports.lbam_addr);
- ireason = hwif->INB(IDE_IREASON_REG);
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
if (ireason & CD) {
printk(KERN_ERR "ide-tape: CoD != 0 in %s\n", __func__);
return ide_do_reset(drive);
}
- if (((ireason & IO) == IO) == test_bit(PC_WRITING, &pc->flags)) {
+ if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
/* Hopefully, we will never get here */
printk(KERN_ERR "ide-tape: We wanted to %s, ",
(ireason & IO) ? "Write" : "Read");
@@ -1144,15 +863,15 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
(ireason & IO) ? "Read" : "Write");
return ide_do_reset(drive);
}
- if (!test_bit(PC_WRITING, &pc->flags)) {
+ if (!(pc->flags & PC_FLAG_WRITING)) {
/* Reading - Check that we have enough space */
- temp = pc->actually_transferred + bcount;
- if (temp > pc->request_transfer) {
- if (temp > pc->buffer_size) {
+ temp = pc->xferred + bcount;
+ if (temp > pc->req_xfer) {
+ if (temp > pc->buf_size) {
printk(KERN_ERR "ide-tape: The tape wants to "
"send us more data than expected "
"- discarding data\n");
- idetape_discard_data(drive, bcount);
+ ide_pad_transfer(drive, 0, bcount);
ide_set_handler(drive, &idetape_pc_intr,
IDETAPE_WAIT_CMD, NULL);
return ide_started;
@@ -1161,20 +880,20 @@ 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->current_position, bcount);
+ xferfunc(drive, NULL, pc->cur_pos, bcount);
/* Update the current position */
- pc->actually_transferred += bcount;
- pc->current_position += bcount;
+ pc->xferred += bcount;
+ pc->cur_pos += bcount;
debug_log(DBG_SENSE, "[cmd %x] transferred %d bytes on that intr.\n",
pc->c[0], bcount);
@@ -1224,7 +943,7 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
idetape_tape_t *tape = drive->driver_data;
- idetape_pc_t *pc = tape->pc;
+ struct ide_atapi_pc *pc = tape->pc;
int retries = 100;
ide_startstop_t startstop;
u8 ireason;
@@ -1234,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(IDE_IREASON_REG);
+ 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(IDE_IREASON_REG);
+ 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");
@@ -1256,15 +975,17 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
#ifdef CONFIG_BLK_DEV_IDEDMA
/* Begin DMA, if necessary */
- if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags))
- hwif->dma_start(drive);
+ if (pc->flags & PC_FLAG_DMA_IN_PROGRESS)
+ 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;
}
-static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, idetape_pc_t *pc)
+static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
+ struct ide_atapi_pc *pc)
{
ide_hwif_t *hwif = drive->hwif;
idetape_tape_t *tape = drive->driver_data;
@@ -1283,13 +1004,13 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, idetape_pc_t *pc)
tape->pc = pc;
if (pc->retries > IDETAPE_MAX_PC_RETRIES ||
- test_bit(PC_ABORT, &pc->flags)) {
+ (pc->flags & PC_FLAG_ABORT)) {
/*
* We will "abort" retrying a packet command in case legitimate
* error code was received (crossing a filemark, or end of the
* media, for example).
*/
- if (!test_bit(PC_ABORT, &pc->flags)) {
+ if (!(pc->flags & PC_FLAG_ABORT)) {
if (!(pc->c[0] == TEST_UNIT_READY &&
tape->sense_key == 2 && tape->asc == 4 &&
(tape->ascq == 1 || tape->ascq == 8))) {
@@ -1304,36 +1025,38 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, idetape_pc_t *pc)
pc->error = IDETAPE_ERROR_GENERAL;
}
tape->failed_pc = NULL;
- return pc->callback(drive);
+ return pc->idetape_callback(drive);
}
debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]);
pc->retries++;
/* We haven't transferred any data yet */
- pc->actually_transferred = 0;
- pc->current_position = pc->buffer;
+ pc->xferred = 0;
+ pc->cur_pos = pc->buf;
/* Request to transfer the entire buffer at once */
- bcount = pc->request_transfer;
+ bcount = pc->req_xfer;
- if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) {
+ if (pc->flags & PC_FLAG_DMA_ERROR) {
+ pc->flags &= ~PC_FLAG_DMA_ERROR;
printk(KERN_WARNING "ide-tape: DMA disabled, "
"reverting to PIO\n");
ide_dma_off(drive);
}
- if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
- dma_ok = !hwif->dma_setup(drive);
+ if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma)
+ 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);
- if (dma_ok) /* Will begin DMA later */
- set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
- if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
+ if (dma_ok)
+ /* Will begin DMA later */
+ pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
+ if (test_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags)) {
ide_execute_command(drive, WIN_PACKETCMD, &idetape_transfer_pc,
IDETAPE_WAIT_CMD, NULL);
return ide_started;
} else {
- hwif->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG);
+ ide_execute_pkt_cmd(drive);
return idetape_transfer_pc(drive);
}
}
@@ -1349,7 +1072,7 @@ static ide_startstop_t idetape_pc_callback(ide_drive_t *drive)
}
/* A mode sense command is used to "sense" tape parameters. */
-static void idetape_create_mode_sense_cmd(idetape_pc_t *pc, u8 page_code)
+static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code)
{
idetape_init_pc(pc);
pc->c[0] = MODE_SENSE;
@@ -1368,81 +1091,18 @@ static void idetape_create_mode_sense_cmd(idetape_pc_t *pc, u8 page_code)
/* We will just discard data in that case */
pc->c[4] = 255;
if (page_code == IDETAPE_BLOCK_DESCRIPTOR)
- pc->request_transfer = 12;
+ pc->req_xfer = 12;
else if (page_code == IDETAPE_CAPABILITIES_PAGE)
- pc->request_transfer = 24;
+ pc->req_xfer = 24;
else
- pc->request_transfer = 50;
- pc->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);
+ pc->req_xfer = 50;
+ pc->idetape_callback = &idetape_pc_callback;
}
static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_pc_t *pc = tape->pc;
+ struct ide_atapi_pc *pc = tape->pc;
u8 stat;
stat = ide_read_status(drive);
@@ -1463,27 +1123,17 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
pc->error = IDETAPE_ERROR_GENERAL;
tape->failed_pc = NULL;
}
- return pc->callback(drive);
+ return pc->idetape_callback(drive);
}
static ide_startstop_t idetape_rw_callback(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
struct request *rq = HWGROUP(drive)->rq;
- int blocks = tape->pc->actually_transferred / tape->blk_size;
+ 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;
@@ -1502,47 +1152,49 @@ static ide_startstop_t idetape_rw_callback(ide_drive_t *drive)
return ide_stopped;
}
-static void idetape_create_read_cmd(idetape_tape_t *tape, idetape_pc_t *pc,
+static void idetape_create_read_cmd(idetape_tape_t *tape,
+ struct ide_atapi_pc *pc,
unsigned int length, struct idetape_bh *bh)
{
idetape_init_pc(pc);
pc->c[0] = READ_6;
put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]);
pc->c[1] = 1;
- pc->callback = &idetape_rw_callback;
+ pc->idetape_callback = &idetape_rw_callback;
pc->bh = bh;
atomic_set(&bh->b_count, 0);
- pc->buffer = NULL;
- pc->buffer_size = length * tape->blk_size;
- pc->request_transfer = pc->buffer_size;
- if (pc->request_transfer == tape->stage_size)
- set_bit(PC_DMA_RECOMMENDED, &pc->flags);
+ pc->buf = NULL;
+ pc->buf_size = length * tape->blk_size;
+ pc->req_xfer = pc->buf_size;
+ if (pc->req_xfer == tape->buffer_size)
+ pc->flags |= PC_FLAG_DMA_RECOMMENDED;
}
-static void idetape_create_write_cmd(idetape_tape_t *tape, idetape_pc_t *pc,
+static void idetape_create_write_cmd(idetape_tape_t *tape,
+ struct ide_atapi_pc *pc,
unsigned int length, struct idetape_bh *bh)
{
idetape_init_pc(pc);
pc->c[0] = WRITE_6;
put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]);
pc->c[1] = 1;
- pc->callback = &idetape_rw_callback;
- set_bit(PC_WRITING, &pc->flags);
+ pc->idetape_callback = &idetape_rw_callback;
+ pc->flags |= PC_FLAG_WRITING;
pc->bh = bh;
pc->b_data = bh->b_data;
pc->b_count = atomic_read(&bh->b_count);
- pc->buffer = NULL;
- pc->buffer_size = length * tape->blk_size;
- pc->request_transfer = pc->buffer_size;
- if (pc->request_transfer == tape->stage_size)
- set_bit(PC_DMA_RECOMMENDED, &pc->flags);
+ pc->buf = NULL;
+ pc->buf_size = length * tape->blk_size;
+ pc->req_xfer = pc->buf_size;
+ if (pc->req_xfer == tape->buffer_size)
+ pc->flags |= PC_FLAG_DMA_RECOMMENDED;
}
static ide_startstop_t idetape_do_request(ide_drive_t *drive,
struct request *rq, sector_t block)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_pc_t *pc = NULL;
+ struct ide_atapi_pc *pc = NULL;
struct request *postponed_rq = tape->postponed_rq;
u8 stat;
@@ -1579,18 +1231,14 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
stat = ide_read_status(drive);
if (!drive->dsc_overlap && !(rq->cmd[0] & REQ_IDETAPE_PC2))
- set_bit(IDETAPE_IGNORE_DSC, &tape->flags);
+ set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags);
if (drive->post_reset == 1) {
- set_bit(IDETAPE_IGNORE_DSC, &tape->flags);
+ set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags);
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_IGNORE_DSC, &tape->flags) &&
+ if (!test_and_clear_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags) &&
(stat & SEEK_STAT) == 0) {
if (postponed_rq == NULL) {
tape->dsc_polling_start = jiffies;
@@ -1613,23 +1261,19 @@ 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);
goto out;
}
if (rq->cmd[0] & REQ_IDETAPE_PC1) {
- pc = (idetape_pc_t *) rq->buffer;
+ pc = (struct ide_atapi_pc *) rq->buffer;
rq->cmd[0] &= ~(REQ_IDETAPE_PC1);
rq->cmd[0] |= REQ_IDETAPE_PC2;
goto out;
@@ -1643,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_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;
@@ -1779,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;
@@ -1810,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 {
@@ -1823,65 +1447,10 @@ 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;
- u8 *readpos = tape->pc->buffer;
+ u8 *readpos = tape->pc->buf;
debug_log(DBG_PROCS, "Enter %s\n", __func__);
@@ -1894,7 +1463,7 @@ static ide_startstop_t idetape_read_position_callback(ide_drive_t *drive)
if (readpos[0] & 0x4) {
printk(KERN_INFO "ide-tape: Block location is unknown"
"to the tape\n");
- clear_bit(IDETAPE_ADDRESS_VALID, &tape->flags);
+ clear_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags);
idetape_end_request(drive, 0, 0);
} else {
debug_log(DBG_SENSE, "Block Location - %u\n",
@@ -1903,7 +1472,7 @@ static ide_startstop_t idetape_read_position_callback(ide_drive_t *drive)
tape->partition = readpos[1];
tape->first_frame =
be32_to_cpu(*(u32 *)&readpos[4]);
- set_bit(IDETAPE_ADDRESS_VALID, &tape->flags);
+ set_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags);
idetape_end_request(drive, 1, 0);
}
} else {
@@ -1917,20 +1486,20 @@ static ide_startstop_t idetape_read_position_callback(ide_drive_t *drive)
* writing a filemark otherwise.
*/
static void idetape_create_write_filemark_cmd(ide_drive_t *drive,
- idetape_pc_t *pc, int write_filemark)
+ struct ide_atapi_pc *pc, int write_filemark)
{
idetape_init_pc(pc);
pc->c[0] = WRITE_FILEMARKS;
pc->c[4] = write_filemark;
- set_bit(PC_WAIT_FOR_DSC, &pc->flags);
- pc->callback = &idetape_pc_callback;
+ pc->flags |= PC_FLAG_WAIT_FOR_DSC;
+ pc->idetape_callback = &idetape_pc_callback;
}
-static void idetape_create_test_unit_ready_cmd(idetape_pc_t *pc)
+static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc)
{
idetape_init_pc(pc);
pc->c[0] = TEST_UNIT_READY;
- pc->callback = &idetape_pc_callback;
+ pc->idetape_callback = &idetape_pc_callback;
}
/*
@@ -1946,7 +1515,7 @@ static void idetape_create_test_unit_ready_cmd(idetape_pc_t *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, idetape_pc_t *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;
@@ -1957,28 +1526,28 @@ static int __idetape_queue_pc_tail(ide_drive_t *drive, idetape_pc_t *pc)
return ide_do_drive_cmd(drive, &rq, ide_wait);
}
-static void idetape_create_load_unload_cmd(ide_drive_t *drive, idetape_pc_t *pc,
- int cmd)
+static void idetape_create_load_unload_cmd(ide_drive_t *drive,
+ struct ide_atapi_pc *pc, int cmd)
{
idetape_init_pc(pc);
pc->c[0] = START_STOP;
pc->c[4] = cmd;
- set_bit(PC_WAIT_FOR_DSC, &pc->flags);
- pc->callback = &idetape_pc_callback;
+ pc->flags |= PC_FLAG_WAIT_FOR_DSC;
+ pc->idetape_callback = &idetape_pc_callback;
}
static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_pc_t pc;
+ struct ide_atapi_pc pc;
int load_attempted = 0;
/* Wait for the tape to become ready */
- set_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags);
+ set_bit(IDETAPE_FLAG_MEDIUM_PRESENT, &tape->flags);
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)) {
@@ -1987,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 &&
@@ -1998,14 +1567,9 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
return -EIO;
}
-static int idetape_queue_pc_tail(ide_drive_t *drive, idetape_pc_t *pc)
-{
- return __idetape_queue_pc_tail(drive, pc);
-}
-
static int idetape_flush_tape_buffers(ide_drive_t *drive)
{
- idetape_pc_t pc;
+ struct ide_atapi_pc pc;
int rc;
idetape_create_write_filemark_cmd(drive, &pc, 0);
@@ -2016,18 +1580,18 @@ static int idetape_flush_tape_buffers(ide_drive_t *drive)
return 0;
}
-static void idetape_create_read_position_cmd(idetape_pc_t *pc)
+static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc)
{
idetape_init_pc(pc);
pc->c[0] = READ_POSITION;
- pc->request_transfer = 20;
- pc->callback = &idetape_read_position_callback;
+ pc->req_xfer = 20;
+ pc->idetape_callback = &idetape_read_position_callback;
}
static int idetape_read_position(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_pc_t pc;
+ struct ide_atapi_pc pc;
int position;
debug_log(DBG_PROCS, "Enter %s\n", __func__);
@@ -2039,7 +1603,8 @@ static int idetape_read_position(ide_drive_t *drive)
return position;
}
-static void idetape_create_locate_cmd(ide_drive_t *drive, idetape_pc_t *pc,
+static void idetape_create_locate_cmd(ide_drive_t *drive,
+ struct ide_atapi_pc *pc,
unsigned int block, u8 partition, int skip)
{
idetape_init_pc(pc);
@@ -2047,12 +1612,12 @@ static void idetape_create_locate_cmd(ide_drive_t *drive, idetape_pc_t *pc,
pc->c[1] = 2;
put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[3]);
pc->c[8] = partition;
- set_bit(PC_WAIT_FOR_DSC, &pc->flags);
- pc->callback = &idetape_pc_callback;
+ pc->flags |= PC_FLAG_WAIT_FOR_DSC;
+ pc->idetape_callback = &idetape_pc_callback;
}
-static int idetape_create_prevent_cmd(ide_drive_t *drive, idetape_pc_t *pc,
- int prevent)
+static int idetape_create_prevent_cmd(ide_drive_t *drive,
+ struct ide_atapi_pc *pc, int prevent)
{
idetape_tape_t *tape = drive->driver_data;
@@ -2063,54 +1628,25 @@ static int idetape_create_prevent_cmd(ide_drive_t *drive, idetape_pc_t *pc,
idetape_init_pc(pc);
pc->c[0] = ALLOW_MEDIUM_REMOVAL;
pc->c[4] = prevent;
- pc->callback = &idetape_pc_callback;
+ pc->idetape_callback = &idetape_pc_callback;
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_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_PIPELINE_ERROR, &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;
}
/*
@@ -2124,10 +1660,10 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,
{
idetape_tape_t *tape = drive->driver_data;
int retval;
- idetape_pc_t pc;
+ 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);
@@ -2138,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;
}
}
@@ -2169,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;
@@ -2186,192 +1715,83 @@ 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_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(idetape_pc_t *pc)
+static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc)
{
idetape_init_pc(pc);
pc->c[0] = INQUIRY;
pc->c[4] = 254;
- pc->request_transfer = 254;
- pc->callback = &idetape_pc_callback;
+ pc->req_xfer = 254;
+ pc->idetape_callback = &idetape_pc_callback;
}
-static void idetape_create_rewind_cmd(ide_drive_t *drive, idetape_pc_t *pc)
+static void idetape_create_rewind_cmd(ide_drive_t *drive,
+ struct ide_atapi_pc *pc)
{
idetape_init_pc(pc);
pc->c[0] = REZERO_UNIT;
- set_bit(PC_WAIT_FOR_DSC, &pc->flags);
- pc->callback = &idetape_pc_callback;
+ pc->flags |= PC_FLAG_WAIT_FOR_DSC;
+ pc->idetape_callback = &idetape_pc_callback;
}
-static void idetape_create_erase_cmd(idetape_pc_t *pc)
+static void idetape_create_erase_cmd(struct ide_atapi_pc *pc)
{
idetape_init_pc(pc);
pc->c[0] = ERASE;
pc->c[1] = 1;
- set_bit(PC_WAIT_FOR_DSC, &pc->flags);
- pc->callback = &idetape_pc_callback;
+ pc->flags |= PC_FLAG_WAIT_FOR_DSC;
+ pc->idetape_callback = &idetape_pc_callback;
}
-static void idetape_create_space_cmd(idetape_pc_t *pc, int count, u8 cmd)
+static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd)
{
idetape_init_pc(pc);
pc->c[0] = SPACE;
put_unaligned(cpu_to_be32(count), (unsigned int *) &pc->c[1]);
pc->c[1] = cmd;
- set_bit(PC_WAIT_FOR_DSC, &pc->flags);
- pc->callback = &idetape_pc_callback;
+ pc->flags |= PC_FLAG_WAIT_FOR_DSC;
+ 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_PIPELINE_ERROR, &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) {
@@ -2395,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_PIPELINE_ERROR, &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;
@@ -2475,94 +1854,34 @@ 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_PIPELINE_ERROR, &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);
/* If we are at a filemark, return a read length of 0 */
- if (test_bit(IDETAPE_FILEMARK, &tape->flags))
+ 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_PIPELINE_ERROR, &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_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)
@@ -2574,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) {
@@ -2586,29 +1905,8 @@ 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);
- }
-}
-
-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;
+ tape->merge_bh);
}
- size += tape->merge_stage_size;
- return size;
}
/*
@@ -2618,7 +1916,7 @@ static int idetape_pipeline_size(ide_drive_t *drive)
static int idetape_rewind_tape(ide_drive_t *drive)
{
int retval;
- idetape_pc_t pc;
+ struct ide_atapi_pc pc;
idetape_tape_t *tape;
tape = drive->driver_data;
@@ -2656,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;
@@ -2670,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;
- idetape_pc_t pc;
- unsigned long flags;
+ struct ide_atapi_pc pc;
int retval, count = 0;
int sprev = !!(tape->caps[4] & 0x20);
@@ -2695,47 +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;
- if (test_and_clear_bit(IDETAPE_FILEMARK, &tape->flags))
+ 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_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:
@@ -2786,32 +2040,30 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count);
if (tape->chrdev_dir != IDETAPE_DIR_READ) {
- if (test_bit(IDETAPE_DETECT_BS, &tape->flags))
+ if (test_bit(IDETAPE_FLAG_DETECT_BS, &tape->flags))
if (count > tape->blk_size &&
(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;
@@ -2822,14 +2074,13 @@ 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_FILEMARK, &tape->flags)) {
+ if (!actually_read && test_bit(IDETAPE_FLAG_FILEMARK, &tape->flags)) {
debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name);
idetape_space_over_filemarks(drive, MTFSF, 1);
@@ -2857,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
@@ -2878,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;
}
@@ -2889,56 +2140,51 @@ 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;
}
static int idetape_write_filemark(ide_drive_t *drive)
{
- idetape_pc_t pc;
+ struct ide_atapi_pc pc;
/* Write a filemark */
idetape_create_write_filemark_cmd(drive, &pc, 1);
@@ -2955,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:
*
@@ -2966,13 +2211,12 @@ static int idetape_write_filemark(ide_drive_t *drive)
static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_pc_t pc;
+ struct ide_atapi_pc pc;
int i, retval;
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:
@@ -2989,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)
@@ -2997,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);
@@ -3017,18 +2261,18 @@ 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);
if (!retval)
- clear_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags);
+ 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);
@@ -3045,16 +2289,16 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
mt_count % tape->blk_size)
return -EIO;
tape->user_bs_factor = mt_count / tape->blk_size;
- clear_bit(IDETAPE_DETECT_BS, &tape->flags);
+ clear_bit(IDETAPE_FLAG_DETECT_BS, &tape->flags);
} else
- set_bit(IDETAPE_DETECT_BS, &tape->flags);
+ 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:
@@ -3099,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)
@@ -3137,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);
}
}
@@ -3149,7 +2392,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_pc_t pc;
+ struct ide_atapi_pc pc;
idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR);
if (idetape_queue_pc_tail(drive, &pc)) {
@@ -3161,10 +2404,10 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
}
return;
}
- tape->blk_size = (pc.buffer[4 + 5] << 16) +
- (pc.buffer[4 + 6] << 8) +
- pc.buffer[4 + 7];
- tape->drv_write_prot = (pc.buffer[2] & 0x80) >> 7;
+ tape->blk_size = (pc.buf[4 + 5] << 16) +
+ (pc.buf[4 + 6] << 8) +
+ pc.buf[4 + 7];
+ tape->drv_write_prot = (pc.buf[2] & 0x80) >> 7;
}
static int idetape_chrdev_open(struct inode *inode, struct file *filp)
@@ -3172,7 +2415,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
unsigned int minor = iminor(inode), i = minor & ~0xc0;
ide_drive_t *drive;
idetape_tape_t *tape;
- idetape_pc_t pc;
+ struct ide_atapi_pc pc;
int retval;
if (i >= MAX_HWIFS * MAX_DRIVES)
@@ -3195,25 +2438,22 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
filp->private_data = tape;
- if (test_and_set_bit(IDETAPE_BUSY, &tape->flags)) {
+ if (test_and_set_bit(IDETAPE_FLAG_BUSY, &tape->flags)) {
retval = -EBUSY;
goto out_put_tape;
}
retval = idetape_wait_ready(drive, 60 * HZ);
if (retval) {
- clear_bit(IDETAPE_BUSY, &tape->flags);
+ clear_bit(IDETAPE_FLAG_BUSY, &tape->flags);
printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name);
goto out_put_tape;
}
idetape_read_position(drive);
- if (!test_bit(IDETAPE_ADDRESS_VALID, &tape->flags))
+ if (!test_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags))
(void)idetape_rewind_tape(drive);
- if (tape->chrdev_dir != IDETAPE_DIR_READ)
- clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
-
/* Read block size and write protect status from drive. */
ide_tape_get_bsize_from_bdesc(drive);
@@ -3227,7 +2467,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
if (tape->write_prot) {
if ((filp->f_flags & O_ACCMODE) == O_WRONLY ||
(filp->f_flags & O_ACCMODE) == O_RDWR) {
- clear_bit(IDETAPE_BUSY, &tape->flags);
+ clear_bit(IDETAPE_FLAG_BUSY, &tape->flags);
retval = -EROFS;
goto out_put_tape;
}
@@ -3242,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:
@@ -3255,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);
@@ -3272,7 +2510,7 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
{
struct ide_tape_obj *tape = ide_tape_f(filp);
ide_drive_t *drive = tape->drive;
- idetape_pc_t pc;
+ struct ide_atapi_pc pc;
unsigned int minor = iminor(inode);
lock_kernel();
@@ -3284,15 +2522,10 @@ 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_MEDIUM_PRESENT, &tape->flags))
+
+ if (minor < 128 && test_bit(IDETAPE_FLAG_MEDIUM_PRESENT, &tape->flags))
(void) idetape_rewind_tape(drive);
if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
if (tape->door_locked == DOOR_LOCKED) {
@@ -3302,7 +2535,7 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
}
}
}
- clear_bit(IDETAPE_BUSY, &tape->flags);
+ clear_bit(IDETAPE_FLAG_BUSY, &tape->flags);
ide_tape_put(tape);
unlock_kernel();
return 0;
@@ -3350,7 +2583,7 @@ static int idetape_identify_device(ide_drive_t *drive)
static void idetape_get_inquiry_results(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_pc_t pc;
+ struct ide_atapi_pc pc;
char fw_rev[6], vendor_id[10], product_id[18];
idetape_create_inquiry_cmd(&pc);
@@ -3359,9 +2592,9 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
tape->name);
return;
}
- memcpy(vendor_id, &pc.buffer[8], 8);
- memcpy(product_id, &pc.buffer[16], 16);
- memcpy(fw_rev, &pc.buffer[32], 4);
+ memcpy(vendor_id, &pc.buf[8], 8);
+ memcpy(product_id, &pc.buf[16], 16);
+ memcpy(fw_rev, &pc.buf[32], 4);
ide_fixstring(vendor_id, 10, 0);
ide_fixstring(product_id, 18, 0);
@@ -3378,7 +2611,7 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
static void idetape_get_mode_sense_results(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_pc_t pc;
+ struct ide_atapi_pc pc;
u8 *caps;
u8 speed, max_speed;
@@ -3392,7 +2625,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
put_unaligned(6*52, (u16 *)&tape->caps[16]);
return;
}
- caps = pc.buffer + 4 + pc.buffer[3];
+ caps = pc.buf + 4 + pc.buf[3];
/* convert to host order and save for later use */
speed = be16_to_cpu(*(u16 *)&caps[14]);
@@ -3428,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,
@@ -3477,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);
@@ -3500,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_DRQ_INTERRUPT, &tape->flags);
-
- tape->min_pipeline = 10;
- tape->max_pipeline = 10;
- tape->max_stages = 10;
+ set_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags);
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
@@ -3568,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":"");
@@ -3596,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 4c86a8d84b4c..9a846a0cd5a4 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -33,58 +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, IDE_DATA_REG);
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
- hwif->OUTB(tf->hob_feature, IDE_FEATURE_REG);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
- hwif->OUTB(tf->hob_nsect, IDE_NSECTOR_REG);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
- hwif->OUTB(tf->hob_lbal, IDE_SECTOR_REG);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
- hwif->OUTB(tf->hob_lbam, IDE_LCYL_REG);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
- hwif->OUTB(tf->hob_lbah, IDE_HCYL_REG);
-
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
- hwif->OUTB(tf->feature, IDE_FEATURE_REG);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
- hwif->OUTB(tf->nsect, IDE_NSECTOR_REG);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
- hwif->OUTB(tf->lbal, IDE_SECTOR_REG);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
- hwif->OUTB(tf->lbam, IDE_LCYL_REG);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
- hwif->OUTB(tf->lbah, IDE_HCYL_REG);
-
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
- hwif->OUTB((tf->device & HIHI) | drive->select.all, IDE_SELECT_REG);
}
int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
@@ -133,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) {
@@ -146,13 +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, IDE_COMMAND_REG);
+ 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:
@@ -175,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;
}
}
@@ -280,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;
@@ -320,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
@@ -330,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,
@@ -359,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;
}
@@ -452,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))
@@ -464,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;
}
@@ -485,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);
@@ -672,7 +637,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;
}
@@ -689,7 +654,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 fc69fe2e3ec0..999584c03d97 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -78,6 +78,8 @@
/* default maximum number of failures */
#define IDE_DEFAULT_MAX_FAILURES 1
+struct class *ide_port_class;
+
static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR,
IDE2_MAJOR, IDE3_MAJOR,
IDE4_MAJOR, IDE5_MAJOR,
@@ -90,32 +92,17 @@ static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */
DEFINE_MUTEX(ide_cfg_mtx);
__cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock);
-#ifdef CONFIG_IDEPCI_PCIBUS_ORDER
-int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
-#endif
-
int noautodma = 0;
-#ifdef CONFIG_BLK_DEV_IDEACPI
-int ide_noacpi = 0;
-int ide_noacpitfs = 1;
-int ide_noacpionboot = 1;
-#endif
-
-/*
- * This is declared extern in ide.h, for access by other IDE modules:
- */
ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */
-EXPORT_SYMBOL(ide_hwifs);
+static void ide_port_init_devices_data(ide_hwif_t *);
/*
* Do not even *think* about calling this!
*/
void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
{
- unsigned int unit;
-
/* bulk initialize hwif & drive info with zeros */
memset(hwif, 0, sizeof(ide_hwif_t));
@@ -134,8 +121,20 @@ void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
default_hwif_iops(hwif);
default_hwif_transport(hwif);
+
+ ide_port_init_devices_data(hwif);
+}
+EXPORT_SYMBOL_GPL(ide_init_port_data);
+
+static void ide_port_init_devices_data(ide_hwif_t *hwif)
+{
+ int unit;
+
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
+ u8 j = (hwif->index * MAX_DRIVES) + unit;
+
+ memset(drive, 0, sizeof(*drive));
drive->media = ide_disk;
drive->select.all = (unit<<4)|0xa0;
@@ -147,32 +146,13 @@ void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
drive->special.b.set_geometry = 1;
drive->name[0] = 'h';
drive->name[1] = 'd';
- drive->name[2] = 'a' + (index * MAX_DRIVES) + unit;
+ drive->name[2] = 'a' + j;
drive->max_failures = IDE_DEFAULT_MAX_FAILURES;
- drive->using_dma = 0;
- drive->vdma = 0;
+
INIT_LIST_HEAD(&drive->list);
init_completion(&drive->gendev_rel_comp);
}
}
-EXPORT_SYMBOL_GPL(ide_init_port_data);
-
-static void init_hwif_default(ide_hwif_t *hwif, unsigned int index)
-{
- hw_regs_t hw;
-
- memset(&hw, 0, sizeof(hw_regs_t));
-
- ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq);
-
- memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));
-
- hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
-#ifdef CONFIG_BLK_DEV_HD
- if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA)
- hwif->noprobe = 1; /* may be overridden by ide_setup() */
-#endif
-}
/*
* init_ide_data() sets reasonable default values into all fields
@@ -194,7 +174,6 @@ static void init_hwif_default(ide_hwif_t *hwif, unsigned int index)
#define MAGIC_COOKIE 0x12345678
static void __init init_ide_data (void)
{
- ide_hwif_t *hwif;
unsigned int index;
static unsigned long magic_cookie = MAGIC_COOKIE;
@@ -204,13 +183,9 @@ static void __init init_ide_data (void)
/* Initialise all interface structures */
for (index = 0; index < MAX_HWIFS; ++index) {
- hwif = &ide_hwifs[index];
+ ide_hwif_t *hwif = &ide_hwifs[index];
+
ide_init_port_data(hwif, index);
- init_hwif_default(hwif, index);
-#if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI)
- hwif->irq =
- ide_init_default_irq(hwif->io_ports[IDE_DATA_OFFSET]);
-#endif
}
}
@@ -246,219 +221,6 @@ static int ide_system_bus_speed(void)
return pci_dev_present(pci_default) ? 33 : 50;
}
-ide_hwif_t * ide_find_port(unsigned long base)
-{
- ide_hwif_t *hwif;
- int i;
-
- for (i = 0; i < MAX_HWIFS; i++) {
- hwif = &ide_hwifs[i];
- if (hwif->io_ports[IDE_DATA_OFFSET] == base)
- goto found;
- }
-
- for (i = 0; i < MAX_HWIFS; i++) {
- hwif = &ide_hwifs[i];
- if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
- goto found;
- }
-
- hwif = NULL;
-found:
- return hwif;
-}
-
-EXPORT_SYMBOL_GPL(ide_find_port);
-
-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;
- unsigned int i;
-
- if (hwif->mmio)
- return 0;
- addr = hwif->io_ports[IDE_CONTROL_OFFSET];
- if (addr && !hwif_request_region(hwif, addr, 1))
- goto control_region_busy;
- hwif->straight8 = 0;
- addr = hwif->io_ports[IDE_DATA_OFFSET];
- if ((addr | 7) == hwif->io_ports[IDE_STATUS_OFFSET]) {
- if (!hwif_request_region(hwif, addr, 8))
- goto data_region_busy;
- hwif->straight8 = 1;
- return 0;
- }
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- addr = hwif->io_ports[i];
- if (!hwif_request_region(hwif, addr, 1)) {
- while (--i)
- release_region(addr, 1);
- 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)
-{
- u32 i = 0;
-
- if (hwif->mmio)
- return;
- if (hwif->io_ports[IDE_CONTROL_OFFSET])
- release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
- if (hwif->straight8) {
- release_region(hwif->io_ports[IDE_DATA_OFFSET], 8);
- return;
- }
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
- if (hwif->io_ports[i])
- release_region(hwif->io_ports[i], 1);
-}
-
-/**
- * ide_hwif_restore - restore hwif to template
- * @hwif: hwif to update
- * @tmp_hwif: template
- *
- * Restore hwif to a previous state by copying most settings
- * from the template.
- */
-
-static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
-{
- hwif->hwgroup = tmp_hwif->hwgroup;
-
- hwif->gendev.parent = tmp_hwif->gendev.parent;
-
- hwif->proc = tmp_hwif->proc;
-
- hwif->major = tmp_hwif->major;
- hwif->straight8 = tmp_hwif->straight8;
- hwif->bus_state = tmp_hwif->bus_state;
-
- hwif->host_flags = tmp_hwif->host_flags;
-
- hwif->pio_mask = tmp_hwif->pio_mask;
-
- hwif->ultra_mask = tmp_hwif->ultra_mask;
- hwif->mwdma_mask = tmp_hwif->mwdma_mask;
- hwif->swdma_mask = tmp_hwif->swdma_mask;
-
- hwif->cbl = tmp_hwif->cbl;
-
- hwif->chipset = tmp_hwif->chipset;
- hwif->hold = tmp_hwif->hold;
-
- hwif->dev = tmp_hwif->dev;
-
-#ifdef CONFIG_BLK_DEV_IDEPCI
- hwif->cds = tmp_hwif->cds;
-#endif
-
- hwif->set_pio_mode = tmp_hwif->set_pio_mode;
- hwif->set_dma_mode = tmp_hwif->set_dma_mode;
- hwif->mdma_filter = tmp_hwif->mdma_filter;
- hwif->udma_filter = tmp_hwif->udma_filter;
- hwif->selectproc = tmp_hwif->selectproc;
- hwif->reset_poll = tmp_hwif->reset_poll;
- hwif->pre_reset = tmp_hwif->pre_reset;
- hwif->resetproc = tmp_hwif->resetproc;
- hwif->maskproc = tmp_hwif->maskproc;
- hwif->quirkproc = tmp_hwif->quirkproc;
- hwif->busproc = tmp_hwif->busproc;
-
- hwif->ata_input_data = tmp_hwif->ata_input_data;
- hwif->ata_output_data = tmp_hwif->ata_output_data;
- hwif->atapi_input_bytes = tmp_hwif->atapi_input_bytes;
- hwif->atapi_output_bytes = tmp_hwif->atapi_output_bytes;
-
- hwif->dma_host_set = tmp_hwif->dma_host_set;
- hwif->dma_setup = tmp_hwif->dma_setup;
- hwif->dma_exec_cmd = tmp_hwif->dma_exec_cmd;
- hwif->dma_start = tmp_hwif->dma_start;
- hwif->ide_dma_end = tmp_hwif->ide_dma_end;
- hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq;
- hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq;
- hwif->dma_lost_irq = tmp_hwif->dma_lost_irq;
- hwif->dma_timeout = tmp_hwif->dma_timeout;
-
- hwif->OUTB = tmp_hwif->OUTB;
- hwif->OUTBSYNC = tmp_hwif->OUTBSYNC;
- hwif->OUTW = tmp_hwif->OUTW;
- hwif->OUTSW = tmp_hwif->OUTSW;
- hwif->OUTSL = tmp_hwif->OUTSL;
-
- hwif->INB = tmp_hwif->INB;
- hwif->INW = tmp_hwif->INW;
- hwif->INSW = tmp_hwif->INSW;
- hwif->INSL = tmp_hwif->INSL;
-
- hwif->sg_max_nents = tmp_hwif->sg_max_nents;
-
- hwif->mmio = tmp_hwif->mmio;
- hwif->rqsize = tmp_hwif->rqsize;
-
-#ifndef CONFIG_BLK_DEV_IDECS
- hwif->irq = tmp_hwif->irq;
-#endif
-
- hwif->dma_base = tmp_hwif->dma_base;
- hwif->dma_command = tmp_hwif->dma_command;
- hwif->dma_vendor1 = tmp_hwif->dma_vendor1;
- hwif->dma_status = tmp_hwif->dma_status;
- hwif->dma_vendor3 = tmp_hwif->dma_vendor3;
- hwif->dma_prdtable = tmp_hwif->dma_prdtable;
-
- hwif->config_data = tmp_hwif->config_data;
- hwif->select_data = tmp_hwif->select_data;
- hwif->extra_base = tmp_hwif->extra_base;
- hwif->extra_ports = tmp_hwif->extra_ports;
-
- hwif->hwif_data = tmp_hwif->hwif_data;
-}
-
void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
{
ide_hwgroup_t *hwgroup = hwif->hwgroup;
@@ -494,11 +256,38 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
spin_unlock_irq(&ide_lock);
}
+/* Called with ide_lock held. */
+static void __ide_port_unregister_devices(ide_hwif_t *hwif)
+{
+ int i;
+
+ for (i = 0; i < MAX_DRIVES; i++) {
+ ide_drive_t *drive = &hwif->drives[i];
+
+ if (drive->present) {
+ spin_unlock_irq(&ide_lock);
+ device_unregister(&drive->gendev);
+ wait_for_completion(&drive->gendev_rel_comp);
+ spin_lock_irq(&ide_lock);
+ }
+ }
+}
+
+void ide_port_unregister_devices(ide_hwif_t *hwif)
+{
+ mutex_lock(&ide_cfg_mtx);
+ spin_lock_irq(&ide_lock);
+ __ide_port_unregister_devices(hwif);
+ hwif->present = 0;
+ ide_port_init_devices_data(hwif);
+ spin_unlock_irq(&ide_lock);
+ mutex_unlock(&ide_cfg_mtx);
+}
+EXPORT_SYMBOL_GPL(ide_port_unregister_devices);
+
/**
* ide_unregister - free an IDE interface
- * @index: index of interface (will change soon to a pointer)
- * @init_default: init default hwif flag
- * @restore: restore hwif flag
+ * @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.
@@ -518,32 +307,19 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
* This is raving bonkers.
*/
-void ide_unregister(unsigned int index, int init_default, int restore)
+void ide_unregister(ide_hwif_t *hwif)
{
- ide_drive_t *drive;
- ide_hwif_t *hwif, *g;
- static ide_hwif_t tmp_hwif; /* protected by ide_cfg_mtx */
+ ide_hwif_t *g;
ide_hwgroup_t *hwgroup;
- int irq_count = 0, unit;
-
- BUG_ON(index >= MAX_HWIFS);
+ int irq_count = 0;
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;
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- drive = &hwif->drives[unit];
- if (!drive->present)
- continue;
- spin_unlock_irq(&ide_lock);
- device_unregister(&drive->gendev);
- wait_for_completion(&drive->gendev_rel_comp);
- spin_lock_irq(&ide_lock);
- }
+ __ide_port_unregister_devices(hwif);
hwif->present = 0;
spin_unlock_irq(&ide_lock);
@@ -565,6 +341,7 @@ void ide_unregister(unsigned int index, int init_default, int restore)
ide_remove_port_from_hwgroup(hwif);
+ device_unregister(hwif->portdev);
device_unregister(&hwif->gendev);
wait_for_completion(&hwif->gendev_rel_comp);
@@ -576,33 +353,11 @@ void ide_unregister(unsigned int index, int init_default, int restore)
unregister_blkdev(hwif->major, hwif->name);
spin_lock_irq(&ide_lock);
- if (hwif->dma_base) {
- (void) ide_release_dma(hwif);
-
- hwif->dma_base = 0;
- hwif->dma_command = 0;
- hwif->dma_vendor1 = 0;
- hwif->dma_status = 0;
- hwif->dma_vendor3 = 0;
- hwif->dma_prdtable = 0;
-
- hwif->extra_base = 0;
- hwif->extra_ports = 0;
- }
-
- ide_hwif_release_regions(hwif);
-
- /* copy original settings */
- tmp_hwif = *hwif;
+ if (hwif->dma_base)
+ ide_release_dma_engine(hwif);
/* restore hwif data to pristine status */
- ide_init_port_data(hwif, index);
-
- if (init_default)
- init_hwif_default(hwif, index);
-
- if (restore)
- ide_hwif_restore(hwif, &tmp_hwif);
+ ide_init_port_data(hwif, hwif->index);
abort:
spin_unlock_irq(&ide_lock);
@@ -613,88 +368,14 @@ 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;
}
EXPORT_SYMBOL_GPL(ide_init_port_hw);
-ide_hwif_t *ide_deprecated_find_port(unsigned long base)
-{
- ide_hwif_t *hwif;
- int i;
-
- for (i = 0; i < MAX_HWIFS; i++) {
- hwif = &ide_hwifs[i];
- if (hwif->io_ports[IDE_DATA_OFFSET] == base)
- goto found;
- }
-
- for (i = 0; i < MAX_HWIFS; i++) {
- hwif = &ide_hwifs[i];
- if (hwif->hold)
- continue;
- if (!hwif->present && hwif->mate == NULL)
- goto found;
- }
-
- hwif = NULL;
-found:
- return hwif;
-}
-EXPORT_SYMBOL_GPL(ide_deprecated_find_port);
-
-/**
- * ide_register_hw - register IDE interface
- * @hw: hardware registers
- * @quirkproc: quirkproc function
- * @hwifp: pointer to returned hwif
- *
- * Register an IDE interface, specifying exactly the registers etc.
- *
- * Returns -1 on error.
- */
-
-int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *),
- ide_hwif_t **hwifp)
-{
- int index, retry = 1;
- ide_hwif_t *hwif;
- u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-
- do {
- hwif = ide_deprecated_find_port(hw->io_ports[IDE_DATA_OFFSET]);
- if (hwif)
- goto found;
- for (index = 0; index < MAX_HWIFS; index++)
- ide_unregister(index, 1, 1);
- } while (retry--);
- return -1;
-found:
- index = hwif->index;
- if (hwif->present)
- ide_unregister(index, 0, 1);
- else if (!hwif->hold)
- ide_init_port_data(hwif, index);
-
- ide_init_port_hw(hwif, hw);
- hwif->quirkproc = quirkproc;
-
- idx[0] = index;
-
- ide_device_add(idx, NULL);
-
- if (hwifp)
- *hwifp = hwif;
-
- return hwif->present ? index : -1;
-}
-
-EXPORT_SYMBOL(ide_register_hw);
-
/*
* Locks for IDE setting functionality
*/
@@ -779,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;
@@ -818,11 +499,14 @@ out:
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 (drive->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;
if (drive->special.b.set_tune)
@@ -997,27 +681,6 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
if (!capable(CAP_SYS_RAWIO))
return -EACCES;
return ide_task_ioctl(drive, cmd, arg);
-
- case HDIO_SCAN_HWIF:
- {
- hw_regs_t hw;
- int args[3];
- if (!capable(CAP_SYS_RAWIO)) return -EACCES;
- if (copy_from_user(args, p, 3 * sizeof(int)))
- return -EFAULT;
- memset(&hw, 0, sizeof(hw));
- ide_init_hwif_ports(&hw, (unsigned long) args[0],
- (unsigned long) args[1], NULL);
- hw.irq = args[2];
- if (ide_register_hw(&hw, NULL, NULL) == -1)
- return -EIO;
- return 0;
- }
- case HDIO_UNREGISTER_HWIF:
- if (!capable(CAP_SYS_RAWIO)) return -EACCES;
- /* (arg > MAX_HWIFS) checked in function */
- ide_unregister(arg, 1, 1);
- return 0;
case HDIO_SET_NICE:
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1))))
@@ -1071,8 +734,6 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
case HDIO_SET_BUSSTATE:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- if (HWIF(drive)->busproc)
- return HWIF(drive)->busproc(drive, (int)arg);
return -EOPNOTSUPP;
default:
return -EINVAL;
@@ -1167,15 +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;
-
-static int __initdata is_chipset_set[MAX_HWIFS];
-
/*
* ide_setup() gets called VERY EARLY during initialization,
* to handle kernel "command line" strings beginning with "hdx=" or "ide".
@@ -1184,14 +836,12 @@ static int __initdata is_chipset_set[MAX_HWIFS];
*/
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 */
@@ -1207,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 */
@@ -1217,29 +867,21 @@ static int __init ide_setup(char *s)
goto obsolete_option;
}
-#ifdef CONFIG_IDEPCI_PCIBUS_ORDER
- if (!strcmp(s, "ide=reverse")) {
- ide_scan_direction = 1;
- printk(" : Enabled support for IDE inverse scan order.\n");
- goto obsolete_option;
- }
-#endif
-
#ifdef CONFIG_BLK_DEV_IDEACPI
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 */
@@ -1249,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;
@@ -1264,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;
@@ -1305,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;
}
@@ -1324,155 +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[] = {
- "noprobe", "serialize", "minus3", "minus4",
- "reset", "minus6", "ata66", "minus8", "minus9",
- "minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb",
- "dtc2278", "umc8672", "ali14xx", NULL };
-
- hw_regs_t hwregs;
-
- 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) || (i > 0 && i <= 3)) {
- /* chipset already specified */
- if (is_chipset_set[hw])
- goto bad_option;
- if (i > -18 && i <= -11) {
- /* these drivers are for "ide0=" only */
- if (hw != 0)
- goto bad_hwif;
- /* chipset already specified for 2nd port */
- if (is_chipset_set[hw+1])
- goto bad_option;
- }
- is_chipset_set[hw] = 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 */
- {
- ide_hwif_t *mate = &ide_hwifs[hw^1];
- mate->drives[0].select.all ^= 0x20;
- mate->drives[1].select.all ^= 0x20;
- hwif->chipset = mate->chipset = ide_4drives;
- mate->irq = hwif->irq;
- memcpy(mate->io_ports, hwif->io_ports, sizeof(hwif->io_ports));
- hwif->mate = mate;
- mate->mate = hwif;
- hwif->serialized = mate->serialized = 1;
- goto obsolete_option;
- }
-#endif /* CONFIG_BLK_DEV_4DRIVES */
- 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: /* "noprobe" */
- hwif->noprobe = 1;
- goto obsolete_option;
-
- case 1: /* base */
- vals[1] = vals[0] + 0x206; /* default ctl */
- case 2: /* base,ctl */
- vals[2] = 0; /* default irq = probe for it */
- case 3: /* base,ctl,irq */
- memset(&hwregs, 0, sizeof(hwregs));
- ide_init_hwif_ports(&hwregs, vals[0], vals[1], &hwif->irq);
- memcpy(hwif->io_ports, hwregs.io_ports, sizeof(hwif->io_ports));
- hwif->irq = vals[2];
- hwif->noprobe = 0;
- hwif->chipset = ide_forced;
- goto obsolete_option;
- case 0: 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);
@@ -1601,6 +1094,192 @@ struct bus_type ide_bus_type = {
EXPORT_SYMBOL_GPL(ide_bus_type);
+static void ide_port_class_release(struct device *portdev)
+{
+ ide_hwif_t *hwif = dev_get_drvdata(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
*/
@@ -1621,11 +1300,23 @@ static int __init ide_init(void)
return ret;
}
+ ide_port_class = class_create(THIS_MODULE, "ide_port");
+ if (IS_ERR(ide_port_class)) {
+ ret = PTR_ERR(ide_port_class);
+ goto out_port_class;
+ }
+ ide_port_class->dev_release = ide_port_class_release;
+
init_ide_data();
proc_ide_create();
return 0;
+
+out_port_class:
+ bus_unregister(&ide_bus_type);
+
+ return ret;
}
#ifdef MODULE
@@ -1655,13 +1346,10 @@ int __init init_module (void)
void __exit cleanup_module (void)
{
- int index;
-
- for (index = 0; index < MAX_HWIFS; ++index)
- ide_unregister(index, 0, 0);
-
proc_ide_destroy();
+ class_destroy(ide_port_class);
+
bus_unregister(&ide_bus_type);
}
diff --git a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile
index 7043ec7d1e05..6939329f89e8 100644
--- a/drivers/ide/legacy/Makefile
+++ b/drivers/ide/legacy/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o
obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o
obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o
+obj-$(CONFIG_BLK_DEV_4DRIVES) += ide-4drives.o
obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o
obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c
index d4d1a6bea599..90c65cf97448 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 =
@@ -86,7 +88,7 @@ static u8 regOff; /* output to base port to close registers */
/*
* Read a controller register.
*/
-static inline u8 inReg (u8 reg)
+static inline u8 inReg(u8 reg)
{
outb_p(reg, regPort);
return inb(dataPort);
@@ -95,7 +97,7 @@ static inline u8 inReg (u8 reg)
/*
* Write a controller register.
*/
-static void outReg (u8 data, u8 reg)
+static void outReg(u8 data, u8 reg)
{
outb_p(reg, regPort);
outb_p(data, dataPort);
@@ -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);
@@ -143,7 +145,7 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
/*
* Auto-detect the IDE controller port.
*/
-static int __init findPort (void)
+static int __init findPort(void)
{
int i;
u8 t;
@@ -175,7 +177,8 @@ static int __init findPort (void)
/*
* Initialize controller registers with default values.
*/
-static int __init initRegisters (void) {
+static int __init initRegisters(void)
+{
const RegInitializer *p;
u8 t;
unsigned long flags;
@@ -191,16 +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)
{
- static u8 idx[4] = { 0, 1, 0xff, 0xff };
-
printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n",
basePort, regOn);
@@ -210,15 +217,10 @@ static int __init ali14xx_probe(void)
return 1;
}
- ide_hwifs[0].set_pio_mode = &ali14xx_set_pio_mode;
- ide_hwifs[1].set_pio_mode = &ali14xx_set_pio_mode;
-
- ide_device_add(idx, &ali14xx_port_info);
-
- return 0;
+ return ide_legacy_device_add(&ali14xx_port_info, 0);
}
-int probe_ali14xx = 0;
+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 fdd3791e465f..5c730e4dd735 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;
@@ -221,15 +221,13 @@ fail_base2:
buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr);
- hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port();
if (hwif) {
u8 index = hwif->index;
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 73396f70f2b7..af791a02a120 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,29 +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] = { 0, 1, 0xff, 0xff };
-
- hwif = &ide_hwifs[0];
- mate = &ide_hwifs[1];
-
- if (hwif->chipset != ide_unknown || mate->chipset != ide_unknown)
- return 1;
local_irq_save(flags);
/*
@@ -128,14 +127,10 @@ static int __init dtc2278_probe(void)
#endif
local_irq_restore(flags);
- hwif->set_pio_mode = &dtc2278_set_pio_mode;
-
- 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 e950afa5939c..83555ca513b5 100644
--- a/drivers/ide/legacy/falconide.c
+++ b/drivers/ide/legacy/falconide.c
@@ -22,6 +22,7 @@
#include <asm/atariints.h>
#include <asm/atari_stdma.h>
+#define DRV_NAME "falconide"
/*
* Base of the IDE interface
@@ -43,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;
@@ -74,9 +97,14 @@ static int __init falconide_init(void)
printk(KERN_INFO "ide: Falcon IDE controller\n");
+ if (!request_mem_region(ATA_HD_BASE, 0x40, DRV_NAME)) {
+ printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
+ return -EBUSY;
+ }
+
falconide_setup_ports(&hw);
- hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port();
if (hwif) {
u8 index = hwif->index;
u8 idx[4] = { index, 0xff, 0xff, 0xff };
@@ -84,6 +112,10 @@ static int __init falconide_init(void)
ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
+ /* 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);
ide_release_lock();
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
index e3b4638cc883..a9c2593a898c 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;
@@ -175,15 +177,13 @@ found:
gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr);
- hwif = ide_find_port(base);
+ hwif = ide_find_port();
if (hwif) {
u8 index = hwif->index;
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/hd.c b/drivers/ide/legacy/hd.c
index 0b0d86731927..abdedf56643e 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -122,12 +122,12 @@ static int hd_error;
* This struct defines the HD's and their types.
*/
struct hd_i_struct {
- unsigned int head,sect,cyl,wpcom,lzone,ctl;
+ unsigned int head, sect, cyl, wpcom, lzone, ctl;
int unit;
int recalibrate;
int special_op;
};
-
+
#ifdef HD_TYPE
static struct hd_i_struct hd_info[] = { HD_TYPE };
static int NR_HD = ARRAY_SIZE(hd_info);
@@ -168,7 +168,7 @@ unsigned long read_timer(void)
spin_lock_irqsave(&i8253_lock, flags);
t = jiffies * 11932;
- outb_p(0, 0x43);
+ outb_p(0, 0x43);
i = inb_p(0x40);
i |= inb(0x40) << 8;
spin_unlock_irqrestore(&i8253_lock, flags);
@@ -183,7 +183,7 @@ static void __init hd_setup(char *str, int *ints)
if (ints[0] != 3)
return;
if (hd_info[0].head != 0)
- hdind=1;
+ hdind = 1;
hd_info[hdind].head = ints[2];
hd_info[hdind].sect = ints[3];
hd_info[hdind].cyl = ints[1];
@@ -193,7 +193,7 @@ static void __init hd_setup(char *str, int *ints)
NR_HD = hdind+1;
}
-static void dump_status (const char *msg, unsigned int stat)
+static void dump_status(const char *msg, unsigned int stat)
{
char *name = "hd?";
if (CURRENT)
@@ -291,7 +291,6 @@ static int controller_ready(unsigned int drive, unsigned int head)
return 0;
}
-
static void hd_out(struct hd_i_struct *disk,
unsigned int nsect,
unsigned int sect,
@@ -313,15 +312,15 @@ static void hd_out(struct hd_i_struct *disk,
return;
}
SET_HANDLER(intr_addr);
- outb_p(disk->ctl,HD_CMD);
- port=HD_DATA;
- outb_p(disk->wpcom>>2,++port);
- outb_p(nsect,++port);
- outb_p(sect,++port);
- outb_p(cyl,++port);
- outb_p(cyl>>8,++port);
- outb_p(0xA0|(disk->unit<<4)|head,++port);
- outb_p(cmd,++port);
+ outb_p(disk->ctl, HD_CMD);
+ port = HD_DATA;
+ outb_p(disk->wpcom >> 2, ++port);
+ outb_p(nsect, ++port);
+ outb_p(sect, ++port);
+ outb_p(cyl, ++port);
+ outb_p(cyl >> 8, ++port);
+ outb_p(0xA0 | (disk->unit << 4) | head, ++port);
+ outb_p(cmd, ++port);
}
static void hd_request (void);
@@ -344,14 +343,14 @@ static void reset_controller(void)
{
int i;
- outb_p(4,HD_CMD);
- for(i = 0; i < 1000; i++) barrier();
- outb_p(hd_info[0].ctl & 0x0f,HD_CMD);
- for(i = 0; i < 1000; i++) barrier();
+ outb_p(4, HD_CMD);
+ for (i = 0; i < 1000; i++) barrier();
+ outb_p(hd_info[0].ctl & 0x0f, HD_CMD);
+ for (i = 0; i < 1000; i++) barrier();
if (drive_busy())
printk("hd: controller still busy\n");
else if ((hd_error = inb(HD_ERROR)) != 1)
- printk("hd: controller reset failed: %02x\n",hd_error);
+ printk("hd: controller reset failed: %02x\n", hd_error);
}
static void reset_hd(void)
@@ -371,8 +370,8 @@ repeat:
if (++i < NR_HD) {
struct hd_i_struct *disk = &hd_info[i];
disk->special_op = disk->recalibrate = 1;
- hd_out(disk,disk->sect,disk->sect,disk->head-1,
- disk->cyl,WIN_SPECIFY,&reset_hd);
+ hd_out(disk, disk->sect, disk->sect, disk->head-1,
+ disk->cyl, WIN_SPECIFY, &reset_hd);
if (reset)
goto repeat;
} else
@@ -393,7 +392,7 @@ static void unexpected_hd_interrupt(void)
unsigned int stat = inb_p(HD_STATUS);
if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) {
- dump_status ("unexpected interrupt", stat);
+ dump_status("unexpected interrupt", stat);
SET_TIMER;
}
}
@@ -453,7 +452,7 @@ static void read_intr(void)
return;
ok_to_read:
req = CURRENT;
- insw(HD_DATA,req->buffer,256);
+ insw(HD_DATA, req->buffer, 256);
req->sector++;
req->buffer += 512;
req->errors = 0;
@@ -507,7 +506,7 @@ ok_to_write:
end_request(req, 1);
if (i > 0) {
SET_HANDLER(&write_intr);
- outsw(HD_DATA,req->buffer,256);
+ outsw(HD_DATA, req->buffer, 256);
local_irq_enable();
} else {
#if (HD_DELAY > 0)
@@ -560,11 +559,11 @@ static int do_special_op(struct hd_i_struct *disk, struct request *req)
{
if (disk->recalibrate) {
disk->recalibrate = 0;
- hd_out(disk,disk->sect,0,0,0,WIN_RESTORE,&recal_intr);
+ hd_out(disk, disk->sect, 0, 0, 0, WIN_RESTORE, &recal_intr);
return reset;
}
if (disk->head > 16) {
- printk ("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name);
+ printk("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name);
end_request(req, 0);
}
disk->special_op = 0;
@@ -633,19 +632,21 @@ repeat:
if (blk_fs_request(req)) {
switch (rq_data_dir(req)) {
case READ:
- hd_out(disk,nsect,sec,head,cyl,WIN_READ,&read_intr);
+ hd_out(disk, nsect, sec, head, cyl, WIN_READ,
+ &read_intr);
if (reset)
goto repeat;
break;
case WRITE:
- hd_out(disk,nsect,sec,head,cyl,WIN_WRITE,&write_intr);
+ hd_out(disk, nsect, sec, head, cyl, WIN_WRITE,
+ &write_intr);
if (reset)
goto repeat;
if (wait_DRQ()) {
bad_rw_intr();
goto repeat;
}
- outsw(HD_DATA,req->buffer,256);
+ outsw(HD_DATA, req->buffer, 256);
break;
default:
printk("unknown hd-command\n");
@@ -655,7 +656,7 @@ repeat:
}
}
-static void do_hd_request (struct request_queue * q)
+static void do_hd_request(struct request_queue *q)
{
disable_irq(HD_IRQ);
hd_request();
@@ -708,12 +709,12 @@ static int __init hd_init(void)
{
int drive;
- if (register_blkdev(MAJOR_NR,"hd"))
+ if (register_blkdev(MAJOR_NR, "hd"))
return -1;
hd_queue = blk_init_queue(do_hd_request, &hd_lock);
if (!hd_queue) {
- unregister_blkdev(MAJOR_NR,"hd");
+ unregister_blkdev(MAJOR_NR, "hd");
return -ENOMEM;
}
@@ -742,7 +743,7 @@ static int __init hd_init(void)
goto out;
}
- for (drive=0 ; drive < NR_HD ; drive++) {
+ for (drive = 0 ; drive < NR_HD ; drive++) {
struct gendisk *disk = alloc_disk(64);
struct hd_i_struct *p = &hd_info[drive];
if (!disk)
@@ -756,7 +757,7 @@ static int __init hd_init(void)
disk->queue = hd_queue;
p->unit = drive;
hd_gendisk[drive] = disk;
- printk ("%s: %luMB, CHS=%d/%d/%d\n",
+ printk("%s: %luMB, CHS=%d/%d/%d\n",
disk->disk_name, (unsigned long)get_capacity(disk)/2048,
p->cyl, p->head, p->sect);
}
@@ -776,7 +777,7 @@ static int __init hd_init(void)
}
/* Let them fly */
- for(drive=0; drive < NR_HD; drive++)
+ for (drive = 0; drive < NR_HD; drive++)
add_disk(hd_gendisk[drive]);
return 0;
@@ -791,7 +792,7 @@ out1:
NR_HD = 0;
out:
del_timer(&device_timer);
- unregister_blkdev(MAJOR_NR,"hd");
+ unregister_blkdev(MAJOR_NR, "hd");
blk_cleanup_queue(hd_queue);
return -1;
Enomem:
@@ -800,7 +801,8 @@ Enomem:
goto out;
}
-static int __init parse_hd_setup (char *line) {
+static int __init parse_hd_setup(char *line)
+{
int ints[6];
(void) get_options(line, ARRAY_SIZE(ints), ints);
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
index 78ca68e60f97..4fe516df9f74 100644
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -35,6 +35,7 @@
* Try: http://www.maf.iki.fi/~maf/ht6560b/
*/
+#define DRV_NAME "ht6560b"
#define HT6560B_VERSION "v0.08"
#include <linux/module.h>
@@ -82,7 +83,7 @@
* out how they setup those cycle time interfacing values, as they at Holtek
* call them. IDESETUP.COM that is supplied with the drivers figures out
* optimal values and fetches those values to drivers. I found out that
- * they use IDE_SELECT_REG to fetch timings to the ide board right after
+ * they use Select register to fetch timings to the ide board right after
* interface switching. After that it was quite easy to add code to
* ht6560b.c.
*
@@ -127,6 +128,7 @@
*/
static void ht6560b_selectproc (ide_drive_t *drive)
{
+ ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
static u8 current_select = 0;
static u8 current_timing = 0;
@@ -155,8 +157,8 @@ static void ht6560b_selectproc (ide_drive_t *drive)
/*
* Set timing for this drive:
*/
- outb(timing, IDE_SELECT_REG);
- (void)inb(IDE_STATUS_REG);
+ 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);
@@ -193,9 +195,9 @@ static int __init try_to_init_ht6560b(void)
* Ht6560b autodetected
*/
outb(HT_CONFIG_DEFAULT, HT_CONFIG_PORT);
- outb(HT_TIMING_DEFAULT, 0x1f6); /* IDE_SELECT_REG */
- (void) inb(0x1f7); /* IDE_STATUS_REG */
-
+ outb(HT_TIMING_DEFAULT, 0x1f6); /* Select register */
+ (void)inb(0x1f7); /* Status register */
+
printk("ht6560b " HT6560B_VERSION
": chipset detected and initialized"
#ifdef DEBUG
@@ -210,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;
@@ -321,54 +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] = { 0, 1, 0xff, 0xff };
-
if (probe_ht6560b == 0)
return -ENODEV;
- hwif = &ide_hwifs[0];
- mate = &ide_hwifs[1];
-
- if (!request_region(HT_CONFIG_PORT, 1, hwif->name)) {
+ 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;
}
- hwif->selectproc = &ht6560b_selectproc;
- hwif->set_pio_mode = &ht6560b_set_pio_mode;
-
- mate->selectproc = &ht6560b_selectproc;
- mate->set_pio_mode = &ht6560b_set_pio_mode;
-
- hwif->port_init_devs = ht6560b_port_init_devs;
- mate->port_init_devs = ht6560b_port_init_devs;
-
- 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
new file mode 100644
index 000000000000..ecae916a3385
--- /dev/null
+++ b/drivers/ide/legacy/ide-4drives.c
@@ -0,0 +1,72 @@
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ide.h>
+
+#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");
+
+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, base, ctl);
+ hw.irq = 14;
+ hw.chipset = ide_4drives;
+
+ hwif = ide_find_port();
+ if (hwif) {
+ ide_init_port_hw(hwif, &hw);
+ idx[0] = hwif->index;
+ }
+
+ mate = ide_find_port();
+ if (mate) {
+ ide_init_port_hw(mate, &hw);
+ mate->drives[0].select.all ^= 0x20;
+ mate->drives[1].select.all ^= 0x20;
+ idx[1] = mate->index;
+
+ if (hwif) {
+ hwif->mate = mate;
+ mate->mate = hwif;
+ hwif->serialized = mate->serialized = 1;
+ }
+ }
+
+ ide_device_add(idx, NULL);
+
+ return 0;
+}
+
+module_init(ide_4drives_init);
+
+MODULE_AUTHOR("Bartlomiej Zolnierkiewicz");
+MODULE_DESCRIPTION("generic IDE chipset with 4 drives/port support");
+MODULE_LICENSE("GPL");
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 15ccf6944ae2..aa2ea3deac85 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,45 +133,71 @@ 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;
hw.chipset = ide_pci;
hw.dev = &handle->dev;
- hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port();
if (hwif == NULL)
- return -1;
+ goto out_release;
i = hwif->index;
- if (hwif->present)
- ide_unregister(i, 0, 0);
- else if (!hwif->hold)
- 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, 0, 0);
+ ide_unregister(hwif);
}
info->ndev = 0;
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c
index 688fcae17488..d3bc3f24e05d 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;
@@ -89,7 +89,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
res_alt->start, res_alt->end - res_alt->start + 1);
}
- hwif = ide_find_port((unsigned long)base);
+ hwif = ide_find_port();
if (!hwif) {
ret = -ENODEV;
goto out;
@@ -102,7 +102,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
ide_init_port_hw(hwif, &hw);
if (mmio) {
- hwif->mmio = 1;
+ hwif->host_flags = IDE_HFLAG_MMIO;
default_hwif_mmiops(hwif);
}
@@ -122,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, 0, 0);
+ ide_unregister(hwif);
return 0;
}
@@ -130,6 +130,7 @@ static int __devexit plat_ide_remove(struct platform_device *pdev)
static struct platform_driver platform_ide_driver = {
.driver = {
.name = "pata_platform",
+ .owner = THIS_MODULE,
},
.probe = plat_ide_probe,
.remove = __devexit_p(plat_ide_remove),
@@ -147,6 +148,7 @@ static void __exit platform_ide_exit(void)
MODULE_DESCRIPTION("Platform IDE driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pata_platform");
module_init(platform_ide_init);
module_exit(platform_ide_exit);
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index eaf5dbe58bc2..1f527bbf8d96 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;
@@ -120,7 +120,7 @@ static int __init macide_init(void)
macide_setup_ports(&hw, base, irq, ack_intr);
- hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port();
if (hwif) {
u8 index = hwif->index;
u8 idx[4] = { index, 0xff, 0xff, 0xff };
@@ -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 2da28759686e..6f535d00e638 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,17 +133,19 @@ 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]));
- hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port();
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 2f4f47ad602f..6424af154325 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"
/*
@@ -88,12 +86,12 @@
static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
/*
- * qd_select:
+ * qd65xx_select:
*
- * This routine is invoked from ide.c to prepare for access to a given drive.
+ * This routine is invoked to prepare for access to a given drive.
*/
-static void qd_select (ide_drive_t *drive)
+static void qd65xx_select(ide_drive_t *drive)
{
u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) |
(QD_TIMREG(drive) & 0x02);
@@ -112,17 +110,18 @@ static void qd_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;
}
/*
@@ -168,36 +170,15 @@ static int qd_find_disk_type (ide_drive_t *drive,
}
/*
- * qd_timing_ok:
- *
- * check whether timings don't conflict
- */
-
-static int qd_timing_ok (ide_drive_t drives[])
-{
- return (IDE_IMPLY(drives[0].present && drives[1].present,
- IDE_IMPLY(QD_TIMREG(drives) == QD_TIMREG(drives+1),
- QD_TIMING(drives) == QD_TIMING(drives+1))));
- /* if same timing register, must be same timing */
-}
-
-/*
* qd_set_timing:
*
- * records the timing, and enables selectproc as needed
+ * records the timing
*/
static void qd_set_timing (ide_drive_t *drive, u8 timing)
{
- ide_hwif_t *hwif = HWIF(drive);
-
drive->drive_data &= 0xff00;
drive->drive_data |= timing;
- if (qd_timing_ok(hwif->drives)) {
- qd_select(drive); /* selects once */
- hwif->selectproc = NULL;
- } else
- hwif->selectproc = &qd_select;
printk(KERN_DEBUG "%s: %#x\n", drive->name, timing);
}
@@ -225,10 +206,11 @@ static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- int base = HWIF(drive)->select_data;
+ ide_hwif_t *hwif = drive->hwif;
unsigned int cycle_time;
int active_time = 175;
int recovery_time = 415; /* worst case values from the dos driver */
+ u8 base = (hwif->config_data & 0xff00) >> 8;
if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)) {
cycle_time = ide_pio_cycle_time(drive, pio);
@@ -299,21 +281,10 @@ static int __init qd_testreg(int port)
return (readreg != QD_TESTVAL);
}
-/*
- * qd_setup:
- *
- * called to setup an ata channel : adjusts attributes & links for tuning
- */
-
-static void __init qd_setup(ide_hwif_t *hwif, int base, int config)
-{
- hwif->select_data = base;
- hwif->config_data = config;
-}
-
static void __init qd6500_port_init_devs(ide_hwif_t *hwif)
{
- u8 base = hwif->select_data, config = QD_CONFIG(hwif);
+ u8 base = (hwif->config_data & 0xff00) >> 8;
+ u8 config = QD_CONFIG(hwif);
hwif->drives[0].drive_data = QD6500_DEF_DATA;
hwif->drives[1].drive_data = QD6500_DEF_DATA;
@@ -322,9 +293,10 @@ static void __init qd6500_port_init_devs(ide_hwif_t *hwif)
static void __init qd6580_port_init_devs(ide_hwif_t *hwif)
{
u16 t1, t2;
- u8 base = hwif->select_data, config = QD_CONFIG(hwif);
+ u8 base = (hwif->config_data & 0xff00) >> 8;
+ u8 config = QD_CONFIG(hwif);
- if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) {
+ if (hwif->host_flags & IDE_HFLAG_SINGLE) {
t1 = QD6580_DEF_DATA;
t2 = QD6580_DEF_DATA2;
} else
@@ -334,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,
};
@@ -351,55 +335,41 @@ static const struct ide_port_info qd65xx_port_info __initdata = {
static int __init qd_probe(int base)
{
- ide_hwif_t *hwif;
- u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
- u8 config;
- u8 unit;
+ int rc;
+ u8 config, unit, control;
+ struct ide_port_info d = qd65xx_port_info;
config = inb(QD_CONFIG_PORT);
if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) )
- return 1;
+ return -ENODEV;
unit = ! (config & QD_CONFIG_IDE_BASEPORT);
- if ((config & 0xf0) == QD_CONFIG_QD6500) {
+ if (unit)
+ d.host_flags |= IDE_HFLAG_QD_2ND_PORT;
- if (qd_testreg(base)) return 1; /* bad register */
+ switch (config & 0xf0) {
+ case QD_CONFIG_QD6500:
+ if (qd_testreg(base))
+ return -ENODEV; /* bad register */
- /* qd6500 found */
-
- hwif = &ide_hwifs[unit];
- printk(KERN_NOTICE "%s: qd6500 at %#x\n", hwif->name, base);
- printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n",
- config, QD_ID3);
-
if (config & QD_CONFIG_DISABLED) {
printk(KERN_WARNING "qd6500 is disabled !\n");
- return 1;
+ return -ENODEV;
}
- qd_setup(hwif, base, config);
-
- hwif->port_init_devs = qd6500_port_init_devs;
- hwif->set_pio_mode = &qd6500_set_pio_mode;
-
- idx[unit] = unit;
-
- ide_device_add(idx, &qd65xx_port_info);
-
- return 1;
- }
-
- if (((config & 0xf0) == QD_CONFIG_QD6580_A) ||
- ((config & 0xf0) == QD_CONFIG_QD6580_B)) {
-
- u8 control;
-
- if (qd_testreg(base) || qd_testreg(base+0x02)) return 1;
- /* bad registers */
+ printk(KERN_NOTICE "qd6500 at %#x\n", base);
+ printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n",
+ config, QD_ID3);
- /* qd6580 found */
+ d.port_ops = &qd6500_port_ops;
+ d.host_flags |= IDE_HFLAG_SINGLE;
+ break;
+ case QD_CONFIG_QD6580_A:
+ case QD_CONFIG_QD6580_B:
+ if (qd_testreg(base) || qd_testreg(base + 0x02))
+ return -ENODEV; /* bad registers */
control = inb(QD_CONTROL_PORT);
@@ -409,69 +379,44 @@ static int __init qd_probe(int base)
outb(QD_DEF_CONTR, QD_CONTROL_PORT);
- if (control & QD_CONTR_SEC_DISABLED) {
- /* secondary disabled */
-
- hwif = &ide_hwifs[unit];
- printk(KERN_INFO "%s: qd6580: single IDE board\n",
- hwif->name);
-
- qd_setup(hwif, base, config | (control << 8));
-
- hwif->port_init_devs = qd6580_port_init_devs;
- hwif->set_pio_mode = &qd6580_set_pio_mode;
-
- idx[unit] = unit;
+ d.port_ops = &qd6580_port_ops;
+ if (control & QD_CONTR_SEC_DISABLED)
+ d.host_flags |= IDE_HFLAG_SINGLE;
- ide_device_add(idx, &qd65xx_port_info);
-
- return 1;
- } else {
- ide_hwif_t *mate;
-
- hwif = &ide_hwifs[0];
- mate = &ide_hwifs[1];
- /* secondary enabled */
- printk(KERN_INFO "%s&%s: qd6580: dual IDE board\n",
- hwif->name, mate->name);
-
- qd_setup(hwif, base, config | (control << 8));
-
- hwif->port_init_devs = qd6580_port_init_devs;
- hwif->set_pio_mode = &qd6580_set_pio_mode;
-
- qd_setup(mate, base, config | (control << 8));
-
- mate->port_init_devs = qd6580_port_init_devs;
- mate->set_pio_mode = &qd6580_set_pio_mode;
+ printk(KERN_INFO "qd6580: %s IDE board\n",
+ (control & QD_CONTR_SEC_DISABLED) ? "single" : "dual");
+ break;
+ default:
+ return -ENODEV;
+ }
- idx[0] = 0;
- idx[1] = 1;
+ rc = ide_legacy_device_add(&d, (base << 8) | config);
- ide_device_add(idx, &qd65xx_port_info);
+ if (d.host_flags & IDE_HFLAG_SINGLE)
+ return (rc == 0) ? 1 : rc;
- return 0; /* no other qd65xx possible */
- }
- }
- /* no qd65xx found */
- return 1;
+ 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");
static int __init qd65xx_init(void)
{
+ int rc1, rc2 = -ENODEV;
+
if (probe_qd65xx == 0)
return -ENODEV;
- if (qd_probe(0x30))
- qd_probe(0xb0);
- if (ide_hwifs[0].chipset != ide_qd65xx &&
- ide_hwifs[1].chipset != ide_qd65xx)
+ rc1 = qd_probe(0x30);
+ if (rc1)
+ rc2 = qd_probe(0xb0);
+
+ if (rc1 < 0 && rc2 < 0)
return -ENODEV;
+
return 0;
}
diff --git a/drivers/ide/legacy/qd65xx.h b/drivers/ide/legacy/qd65xx.h
index 28dd50a15d55..c83dea85e621 100644
--- a/drivers/ide/legacy/qd65xx.h
+++ b/drivers/ide/legacy/qd65xx.h
@@ -30,7 +30,6 @@
#define QD_ID3 ((config & QD_CONFIG_ID3)!=0)
#define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff)
-#define QD_CONTROL(hwif) (((hwif)->config_data & 0xff00) >> 8)
#define QD_TIMING(drive) (byte)(((drive)->drive_data) & 0x00ff)
#define QD_TIMREG(drive) (byte)((((drive)->drive_data) & 0xff00) >> 8)
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c
index 5696ba026005..b54a14a57755 100644
--- a/drivers/ide/legacy/umc8672.c
+++ b/drivers/ide/legacy/umc8672.c
@@ -19,7 +19,7 @@
*/
/*
- * VLB Controller Support from
+ * VLB Controller Support from
* Wolfram Podien
* Rohoefe 3
* D28832 Achim
@@ -32,7 +32,7 @@
* #define UMC_DRIVE0 11
* in the beginning of the driver, which sets the speed of drive 0 to 11 (there
* are some lines present). 0 - 11 are allowed speed values. These values are
- * the results from the DOS speed test program supplied from UMC. 11 is the
+ * the results from the DOS speed test program supplied from UMC. 11 is the
* highest speed (about PIO mode 3)
*/
#define REALLY_SLOW_IO /* some systems can safely undef this */
@@ -51,6 +51,8 @@
#include <asm/io.h>
+#define DRV_NAME "umc8672"
+
/*
* Default speeds. These can be changed with "auto-tune" and/or hdparm.
*/
@@ -60,103 +62,103 @@
#define UMC_DRIVE3 1 /* In case of crash reduce speed */
static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3};
-static const u8 pio_to_umc [5] = {0,3,7,10,11}; /* rough guesses */
+static const u8 pio_to_umc [5] = {0, 3, 7, 10, 11}; /* rough guesses */
/* 0 1 2 3 4 5 6 7 8 9 10 11 */
static const u8 speedtab [3][12] = {
- {0xf, 0xb, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 },
- {0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 },
- {0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}};
+ {0x0f, 0x0b, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1},
+ {0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1},
+ {0xff, 0xcb, 0xc0, 0x58, 0x36, 0x33, 0x23, 0x22, 0x21, 0x11, 0x10, 0x0}
+};
-static void out_umc (char port,char wert)
+static void out_umc(char port, char wert)
{
- outb_p(port,0x108);
- outb_p(wert,0x109);
+ outb_p(port, 0x108);
+ outb_p(wert, 0x109);
}
-static inline u8 in_umc (char port)
+static inline u8 in_umc(char port)
{
- outb_p(port,0x108);
+ outb_p(port, 0x108);
return inb_p(0x109);
}
-static void umc_set_speeds (u8 speeds[])
+static void umc_set_speeds(u8 speeds[])
{
int i, tmp;
- outb_p(0x5A,0x108); /* enable umc */
+ outb_p(0x5A, 0x108); /* enable umc */
- out_umc (0xd7,(speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4)));
- out_umc (0xd6,(speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4)));
+ out_umc(0xd7, (speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4)));
+ out_umc(0xd6, (speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4)));
tmp = 0;
- for (i = 3; i >= 0; i--) {
+ for (i = 3; i >= 0; i--)
tmp = (tmp << 2) | speedtab[1][speeds[i]];
+ out_umc(0xdc, tmp);
+ for (i = 0; i < 4; i++) {
+ out_umc(0xd0 + i, speedtab[2][speeds[i]]);
+ out_umc(0xd8 + i, speedtab[2][speeds[i]]);
}
- out_umc (0xdc,tmp);
- for (i = 0;i < 4; i++) {
- out_umc (0xd0+i,speedtab[2][speeds[i]]);
- out_umc (0xd8+i,speedtab[2][speeds[i]]);
- }
- outb_p(0xa5,0x108); /* disable umc */
+ outb_p(0xa5, 0x108); /* disable umc */
- printk ("umc8672: drive speeds [0 to 11]: %d %d %d %d\n",
+ printk("umc8672: drive speeds [0 to 11]: %d %d %d %d\n",
speeds[0], speeds[1], speeds[2], speeds[3]);
}
static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
+ ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
- ide_hwgroup_t *hwgroup = ide_hwifs[HWIF(drive)->index^1].hwgroup;
printk("%s: setting umc8672 to PIO mode%d (speed %d)\n",
drive->name, pio, pio_to_umc[pio]);
spin_lock_irqsave(&ide_lock, flags);
- if (hwgroup && hwgroup->handler != NULL) {
+ if (hwif->mate && hwif->mate->hwgroup->handler) {
printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n");
} else {
current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio];
- umc_set_speeds (current_speeds);
+ umc_set_speeds(current_speeds);
}
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)
{
unsigned long flags;
- static u8 idx[4] = { 0, 1, 0xff, 0xff };
if (!request_region(0x108, 2, "umc8672")) {
printk(KERN_ERR "umc8672: ports 0x108-0x109 already in use.\n");
return 1;
}
local_irq_save(flags);
- outb_p(0x5A,0x108); /* enable umc */
+ outb_p(0x5A, 0x108); /* enable umc */
if (in_umc (0xd5) != 0xa0) {
local_irq_restore(flags);
printk(KERN_ERR "umc8672: not found\n");
release_region(0x108, 2);
- return 1;
+ return 1;
}
- outb_p(0xa5,0x108); /* disable umc */
+ outb_p(0xa5, 0x108); /* disable umc */
- umc_set_speeds (current_speeds);
+ umc_set_speeds(current_speeds);
local_irq_restore(flags);
- ide_hwifs[0].set_pio_mode = &umc_set_pio_mode;
- ide_hwifs[1].set_pio_mode = &umc_set_pio_mode;
-
- ide_device_add(idx, &umc8672_port_info);
-
- return 0;
+ return ide_legacy_device_add(&umc8672_port_info, 0);
}
-int probe_umc8672 = 0;
+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 0f4bf5d72835..1a6c27b32498 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -32,19 +32,12 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
-
#include <linux/init.h>
#include <linux/ide.h>
-#include <linux/sysdev.h>
-
-#include <linux/dma-mapping.h>
-
-#include "ide-timing.h"
+#include <linux/scatterlist.h>
-#include <asm/io.h>
#include <asm/mach-au1x00/au1xxx.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
-
#include <asm/mach-au1x00/au1xxx_ide.h>
#define DRV_NAME "au1200-ide"
@@ -54,7 +47,6 @@
#define IDE_AU1XXX_BURSTMODE 1
static _auide_hwif auide_hwif;
-static int dbdma_init_done;
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
@@ -66,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);
@@ -84,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);
@@ -94,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)
@@ -255,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
{
@@ -263,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__);
}
}
@@ -320,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)
@@ -394,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;
@@ -487,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;
@@ -537,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,
@@ -591,21 +573,24 @@ static int au_ide_probe(struct device *dev)
goto out;
}
- if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
+ if (!request_mem_region(res->start, res->end - res->start + 1,
+ pdev->name)) {
pr_debug("%s: request_mem_region failed\n", DRV_NAME);
ret = -EBUSY;
goto out;
}
- ahwif->regbase = (u32)ioremap(res->start, res->end-res->start);
+ ahwif->regbase = (u32)ioremap(res->start, res->end - res->start + 1);
if (ahwif->regbase == 0) {
ret = -ENOMEM;
goto out;
}
- /* FIXME: This might possibly break PCMCIA IDE devices */
-
- hwif = &ide_hwifs[pdev->id];
+ hwif = ide_find_port();
+ if (hwif == NULL) {
+ ret = -ENOENT;
+ goto out;
+ }
memset(&hw, 0, sizeof(hw));
auide_setup_ports(&hw, ahwif);
@@ -617,35 +602,13 @@ static int au_ide_probe(struct device *dev)
hwif->dev = dev;
- /* hold should be on in all cases */
- hwif->hold = 1;
-
- 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 */
@@ -653,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);
@@ -677,12 +635,12 @@ 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, 0, 0);
+ ide_unregister(hwif);
iounmap((void *)ahwif->regbase);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, res->end - res->start);
+ release_mem_region(res->start, res->end - res->start + 1);
return 0;
}
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
index 956259fc09ba..712d17bdd470 100644
--- a/drivers/ide/mips/swarm.c
+++ b/drivers/ide/mips/swarm.c
@@ -76,17 +76,12 @@ static int __devinit swarm_ide_probe(struct device *dev)
if (!SIBYTE_HAVE_IDE)
return -ENODEV;
- /* Find an empty slot. */
- for (i = 0; i < MAX_HWIFS; i++)
- if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET])
- break;
- if (i >= MAX_HWIFS) {
+ hwif = ide_find_port();
+ if (hwif == NULL) {
printk(KERN_ERR DRV_NAME ": no free slot for interface\n");
return -ENOMEM;
}
- hwif = ide_hwifs + i;
-
base = ioremap(A_IO_EXT_BASE, 0x800);
offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS));
size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS));
@@ -114,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 cfb3265bc1a8..7f46c224b7c4 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,17 +213,18 @@ 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_ABUSE_SET_DMA_MODE |
+ IDE_HFLAG_NON_BOOTABLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
},{ /* 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,
@@ -237,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 b3b6f514ce2d..b36a22b8c213 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,27 +412,7 @@ 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;
-}
-
+#ifndef CONFIG_SPARC64
/**
* init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff
* @hwif: interface to configure
@@ -722,35 +462,66 @@ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
if(irq >= 0)
hwif->irq = irq;
}
-
- init_hwif_common_ali15x3(hwif);
}
+#endif
/**
* 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,
+#ifndef CONFIG_SPARC64
.init_hwif = init_hwif_ali15x3,
+#endif
.init_dma = init_dma_ali15x3,
- .host_flags = IDE_HFLAG_BOOTABLE,
+ .port_ops = &ali_port_ops,
.pio_mask = ATA_PIO5,
.swdma_mask = ATA_SWDMA2,
.mwdma_mask = ATA_MWDMA2,
@@ -793,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 2ef890ce8097..efcf54338be7 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,21 +210,20 @@ 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_PIO_NO_DOWNGRADE | \
IDE_HFLAG_ABUSE_SET_DMA_MODE | \
IDE_HFLAG_POST_SET_MODE | \
IDE_HFLAG_IO_32BIT | \
- IDE_HFLAG_UNMASK_IRQS | \
- IDE_HFLAG_BOOTABLE)
+ IDE_HFLAG_UNMASK_IRQS)
#define DECLARE_AMD_DEV(name_str, swdma, udma) \
{ \
@@ -232,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, \
@@ -245,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 7e037c880cb0..8b637181681a 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -130,37 +130,26 @@ 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}},
- .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
+ .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}},
- .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS |
- IDE_HFLAG_BOOTABLE,
+ .port_ops = &atiixp_port_ops,
+ .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
index 29fbc5ead03b..aaf38109eaec 100644
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -4,7 +4,7 @@
/*
* Original authors: abramov@cecmow.enet.dec.com (Igor Abramov)
- * mlord@pobox.com (Mark Lord)
+ * mlord@pobox.com (Mark Lord)
*
* See linux/MAINTAINERS for address of current maintainer.
*
@@ -98,7 +98,7 @@
#define CMD640_PREFETCH_MASKS 1
-//#define CMD640_DUMP_REGS
+/*#define CMD640_DUMP_REGS */
#include <linux/types.h>
#include <linux/kernel.h>
@@ -109,10 +109,9 @@
#include <asm/io.h>
-/*
- * This flag is set in ide.c by the parameter: ide0=cmd640_vlb
- */
-int cmd640_vlb = 0;
+#define DRV_NAME "cmd640"
+
+static int cmd640_vlb;
/*
* CMD640 specific registers definition.
@@ -185,7 +184,6 @@ static DEFINE_SPINLOCK(cmd640_lock);
* These are initialized to point at the devices we control
*/
static ide_hwif_t *cmd_hwif0, *cmd_hwif1;
-static ide_drive_t *cmd_drives[4];
/*
* Interface to access cmd640x registers
@@ -207,13 +205,13 @@ static unsigned int cmd640_chip_version;
/* PCI method 1 access */
-static void put_cmd640_reg_pci1 (u16 reg, u8 val)
+static void put_cmd640_reg_pci1(u16 reg, u8 val)
{
outl_p((reg & 0xfc) | cmd640_key, 0xcf8);
outb_p(val, (reg & 3) | 0xcfc);
}
-static u8 get_cmd640_reg_pci1 (u16 reg)
+static u8 get_cmd640_reg_pci1(u16 reg)
{
outl_p((reg & 0xfc) | cmd640_key, 0xcf8);
return inb_p((reg & 3) | 0xcfc);
@@ -221,14 +219,14 @@ static u8 get_cmd640_reg_pci1 (u16 reg)
/* PCI method 2 access (from CMD datasheet) */
-static void put_cmd640_reg_pci2 (u16 reg, u8 val)
+static void put_cmd640_reg_pci2(u16 reg, u8 val)
{
outb_p(0x10, 0xcf8);
outb_p(val, cmd640_key + reg);
outb_p(0, 0xcf8);
}
-static u8 get_cmd640_reg_pci2 (u16 reg)
+static u8 get_cmd640_reg_pci2(u16 reg)
{
u8 b;
@@ -240,13 +238,13 @@ static u8 get_cmd640_reg_pci2 (u16 reg)
/* VLB access */
-static void put_cmd640_reg_vlb (u16 reg, u8 val)
+static void put_cmd640_reg_vlb(u16 reg, u8 val)
{
outb_p(reg, cmd640_key);
outb_p(val, cmd640_key + 4);
}
-static u8 get_cmd640_reg_vlb (u16 reg)
+static u8 get_cmd640_reg_vlb(u16 reg)
{
outb_p(reg, cmd640_key);
return inb_p(cmd640_key + 4);
@@ -268,11 +266,11 @@ static void put_cmd640_reg(u16 reg, u8 val)
unsigned long flags;
spin_lock_irqsave(&cmd640_lock, flags);
- __put_cmd640_reg(reg,val);
+ __put_cmd640_reg(reg, val);
spin_unlock_irqrestore(&cmd640_lock, flags);
}
-static int __init match_pci_cmd640_device (void)
+static int __init match_pci_cmd640_device(void)
{
const u8 ven_dev[4] = {0x95, 0x10, 0x40, 0x06};
unsigned int i;
@@ -292,7 +290,7 @@ static int __init match_pci_cmd640_device (void)
/*
* Probe for CMD640x -- pci method 1
*/
-static int __init probe_for_cmd640_pci1 (void)
+static int __init probe_for_cmd640_pci1(void)
{
__get_cmd640_reg = get_cmd640_reg_pci1;
__put_cmd640_reg = put_cmd640_reg_pci1;
@@ -308,7 +306,7 @@ static int __init probe_for_cmd640_pci1 (void)
/*
* Probe for CMD640x -- pci method 2
*/
-static int __init probe_for_cmd640_pci2 (void)
+static int __init probe_for_cmd640_pci2(void)
{
__get_cmd640_reg = get_cmd640_reg_pci2;
__put_cmd640_reg = put_cmd640_reg_pci2;
@@ -322,7 +320,7 @@ static int __init probe_for_cmd640_pci2 (void)
/*
* Probe for CMD640x -- vlb
*/
-static int __init probe_for_cmd640_vlb (void)
+static int __init probe_for_cmd640_vlb(void)
{
u8 b;
@@ -343,18 +341,18 @@ static int __init probe_for_cmd640_vlb (void)
* Returns 1 if an IDE interface/drive exists at 0x170,
* Returns 0 otherwise.
*/
-static int __init secondary_port_responding (void)
+static int __init secondary_port_responding(void)
{
unsigned long flags;
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 */
}
@@ -367,7 +365,7 @@ static int __init secondary_port_responding (void)
/*
* Dump out all cmd640 registers. May be called from ide.c
*/
-static void cmd640_dump_regs (void)
+static void cmd640_dump_regs(void)
{
unsigned int reg = cmd640_vlb ? 0x50 : 0x00;
@@ -382,13 +380,13 @@ 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.
*/
-static void __init check_prefetch (unsigned int index)
+static void __init check_prefetch(ide_drive_t *drive, unsigned int index)
{
- ide_drive_t *drive = cmd_drives[index];
u8 b = get_cmd640_reg(prefetch_regs[index]);
if (b & prefetch_masks[index]) { /* is prefetch off? */
@@ -403,39 +401,12 @@ static void __init check_prefetch (unsigned int index)
drive->no_io_32bit = 0;
}
}
-
-/*
- * Figure out which devices we control
- */
-static void __init setup_device_ptrs (void)
-{
- unsigned int i;
-
- cmd_hwif0 = &ide_hwifs[0]; /* default, if not found below */
- cmd_hwif1 = &ide_hwifs[1]; /* default, if not found below */
- for (i = 0; i < MAX_HWIFS; i++) {
- ide_hwif_t *hwif = &ide_hwifs[i];
- if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced) {
- if (hwif->io_ports[IDE_DATA_OFFSET] == 0x1f0)
- cmd_hwif0 = hwif;
- else if (hwif->io_ports[IDE_DATA_OFFSET] == 0x170)
- cmd_hwif1 = hwif;
- }
- }
- cmd_drives[0] = &cmd_hwif0->drives[0];
- cmd_drives[1] = &cmd_hwif0->drives[1];
- cmd_drives[2] = &cmd_hwif1->drives[0];
- cmd_drives[3] = &cmd_hwif1->drives[1];
-}
-
-#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
-
+#else
/*
* Sets prefetch mode for a drive.
*/
-static void set_prefetch_mode (unsigned int index, int mode)
+static void set_prefetch_mode(ide_drive_t *drive, unsigned int index, int mode)
{
- ide_drive_t *drive = cmd_drives[index];
unsigned long flags;
int reg = prefetch_regs[index];
u8 b;
@@ -462,7 +433,7 @@ static void set_prefetch_mode (unsigned int index, int mode)
/*
* Dump out current drive clocks settings
*/
-static void display_clocks (unsigned int index)
+static void display_clocks(unsigned int index)
{
u8 active_count, recovery_count;
@@ -481,44 +452,16 @@ static void display_clocks (unsigned int index)
* Pack active and recovery counts into single byte representation
* used by controller
*/
-static inline u8 pack_nibbles (u8 upper, u8 lower)
+static inline u8 pack_nibbles(u8 upper, u8 lower)
{
return ((upper & 0x0f) << 4) | (lower & 0x0f);
}
/*
- * 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.
*/
-static void program_drive_counts (unsigned int index)
+static void program_drive_counts(ide_drive_t *drive, unsigned int index)
{
unsigned long flags;
u8 setup_count = setup_counts[index];
@@ -532,8 +475,11 @@ static void program_drive_counts (unsigned int index)
* so we merge the timings, using the slowest value for each timing.
*/
if (index > 1) {
- unsigned int mate;
- if (cmd_drives[mate = index ^ 1]->present) {
+ ide_hwif_t *hwif = drive->hwif;
+ ide_drive_t *peer = &hwif->drives[!drive->select.b.unit];
+ unsigned int mate = index ^ 1;
+
+ if (peer->present) {
if (setup_count < setup_counts[mate])
setup_count = setup_counts[mate];
if (active_count < active_counts[mate])
@@ -547,11 +493,11 @@ static void program_drive_counts (unsigned int index)
* Convert setup_count to internal chipset representation
*/
switch (setup_count) {
- case 4: setup_count = 0x00; break;
- case 3: setup_count = 0x80; break;
- case 1:
- case 2: setup_count = 0x40; break;
- default: setup_count = 0xc0; /* case 5 */
+ case 4: setup_count = 0x00; break;
+ case 3: setup_count = 0x80; break;
+ case 1:
+ case 2: setup_count = 0x40; break;
+ default: setup_count = 0xc0; /* case 5 */
}
/*
@@ -572,11 +518,19 @@ static void program_drive_counts (unsigned int index)
/*
* Set a specific pio_mode for a drive
*/
-static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle_time)
+static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
+ u8 pio_mode, unsigned int cycle_time)
{
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;
@@ -584,15 +538,15 @@ static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle
active_time = ide_pio_timings[pio_mode].active_time;
recovery_time = cycle_time - (setup_time + active_time);
clock_time = 1000 / bus_speed;
- cycle_count = (cycle_time + clock_time - 1) / clock_time;
+ cycle_count = DIV_ROUND_UP(cycle_time, clock_time);
- setup_count = (setup_time + clock_time - 1) / clock_time;
+ setup_count = DIV_ROUND_UP(setup_time, clock_time);
- active_count = (active_time + clock_time - 1) / clock_time;
+ active_count = DIV_ROUND_UP(active_time, clock_time);
if (active_count < 2)
active_count = 2; /* minimum allowed by cmd640 */
- recovery_count = (recovery_time + clock_time - 1) / clock_time;
+ recovery_count = DIV_ROUND_UP(recovery_time, clock_time);
recovery_count2 = cycle_count - (setup_count + active_count);
if (recovery_count2 > recovery_count)
recovery_count = recovery_count2;
@@ -621,7 +575,7 @@ static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle
* 1) this is the wrong place to do it (proper is do_special() in ide.c)
* 2) in practice this is rarely, if ever, necessary
*/
- program_drive_counts (index);
+ program_drive_counts(drive, index);
}
static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
@@ -629,32 +583,26 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
unsigned int index = 0, cycle_time;
u8 b;
- while (drive != cmd_drives[index]) {
- if (++index > 3) {
- printk(KERN_ERR "%s: bad news in %s\n",
- drive->name, __FUNCTION__);
- return;
- }
- }
switch (pio) {
- case 6: /* set fast-devsel off */
- case 7: /* set fast-devsel on */
- b = get_cmd640_reg(CNTRL) & ~0x27;
- if (pio & 1)
- b |= 0x27;
- put_cmd640_reg(CNTRL, b);
- printk("%s: %sabled cmd640 fast host timing (devsel)\n", drive->name, (pio & 1) ? "en" : "dis");
- return;
-
- case 8: /* set prefetch off */
- case 9: /* set prefetch on */
- set_prefetch_mode(index, pio & 1);
- printk("%s: %sabled cmd640 prefetch\n", drive->name, (pio & 1) ? "en" : "dis");
- return;
+ case 6: /* set fast-devsel off */
+ case 7: /* set fast-devsel on */
+ b = get_cmd640_reg(CNTRL) & ~0x27;
+ if (pio & 1)
+ b |= 0x27;
+ put_cmd640_reg(CNTRL, b);
+ printk("%s: %sabled cmd640 fast host timing (devsel)\n",
+ drive->name, (pio & 1) ? "en" : "dis");
+ return;
+ case 8: /* set prefetch off */
+ case 9: /* set prefetch on */
+ set_prefetch_mode(drive, index, pio & 1);
+ printk("%s: %sabled cmd640 prefetch\n",
+ drive->name, (pio & 1) ? "en" : "dis");
+ return;
}
cycle_time = ide_pio_cycle_time(drive, pio);
- cmd640_set_mode(index, pio, cycle_time);
+ cmd640_set_mode(drive, index, pio, cycle_time);
printk("%s: selected cmd640 PIO mode%d (%dns)",
drive->name, pio, cycle_time);
@@ -662,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)
@@ -703,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.
*/
@@ -719,11 +688,12 @@ 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;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+ hw_regs_t hw[2];
if (cmd640_vlb && probe_for_cmd640_vlb()) {
bus_type = "VLB";
@@ -758,21 +728,41 @@ static int __init cmd640x_init(void)
cfr = get_cmd640_reg(CFR);
cmd640_chip_version = cfr & CFR_DEVREV;
if (cmd640_chip_version == 0) {
- printk ("ide: bad cmd640 revision: %d\n", cmd640_chip_version);
+ printk("ide: bad cmd640 revision: %d\n", cmd640_chip_version);
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);
+ hw[0].irq = 14;
+
+ ide_std_init_ports(&hw[1], 0x170, 0x376);
+ hw[1].irq = 15;
+
+ printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x"
+ "\n", 'a' + cmd640_chip_version - 1, bus_type, cfr);
+
+ cmd_hwif0 = ide_find_port();
+
/*
* Initialize data for primary port
*/
- setup_device_ptrs ();
- printk("%s: buggy cmd640%c interface on %s, config=0x%02x\n",
- cmd_hwif0->name, 'a' + cmd640_chip_version - 1, bus_type, cfr);
-#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;
+ if (cmd_hwif0) {
+ ide_init_port_hw(cmd_hwif0, &hw[0]);
+ idx[0] = cmd_hwif0->index;
+ }
/*
* Ensure compatibility by always using the slowest timings
@@ -784,11 +774,13 @@ static int __init cmd640x_init(void)
put_cmd640_reg(CMDTIM, 0);
put_cmd640_reg(BRST, 0x40);
+ cmd_hwif1 = ide_find_port();
+
/*
* Try to enable the secondary interface, if not already enabled
*/
- if (cmd_hwif1->noprobe ||
- (cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe)) {
+ if (cmd_hwif1 &&
+ cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe) {
port2 = "not probed";
} else {
b = get_cmd640_reg(CNTRL);
@@ -819,14 +811,11 @@ static int __init cmd640x_init(void)
/*
* Initialize data for secondary cmd640 port, if enabled
*/
- if (second_port_cmd640) {
-#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
- cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode;
-#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
-
+ if (second_port_cmd640 && cmd_hwif1) {
+ ide_init_port_hw(cmd_hwif1, &hw[1]);
idx[1] = cmd_hwif1->index;
}
- printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name,
+ printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n",
second_port_cmd640 ? "" : "not ", port2);
/*
@@ -834,35 +823,34 @@ static int __init cmd640x_init(void)
* Do not unnecessarily disturb any prior BIOS setup of these.
*/
for (index = 0; index < (2 + (second_port_cmd640 << 1)); index++) {
- ide_drive_t *drive = cmd_drives[index];
-#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 (index);
- set_prefetch_mode (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 (index);
- printk("cmd640: drive%d timings/prefetch(%s) preserved",
- index, drive->no_io_32bit ? "off" : "on");
- display_clocks(index);
+ ide_drive_t *drive;
+
+ if (index > 1) {
+ if (cmd_hwif1 == NULL)
+ continue;
+ drive = &cmd_hwif1->drives[index & 1];
+ } else {
+ if (cmd_hwif0 == NULL)
+ continue;
+ drive = &cmd_hwif0->drives[index & 1];
}
+
+#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
+ /*
+ * 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
*/
- check_prefetch (index);
+ check_prefetch(drive, index);
printk("cmd640: drive%d timings/prefetch(%s) preserved\n",
index, drive->no_io_32bit ? "off" : "on");
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index edabe6299efd..08674711d089 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,91 +385,85 @@ 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 |
- IDE_HFLAG_BOOTABLE,
+ IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = 0x00, /* no udma */
},{ /* 1 */
.name = "CMD646",
.init_chipset = init_chipset_cmd64x,
- .init_hwif = init_hwif_cmd64x,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
.chipset = ide_cmd646,
- .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
+ .port_ops = &cmd64x_port_ops,
+ .dma_ops = &cmd648_dma_ops,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
},{ /* 2 */
.name = "CMD648",
.init_chipset = init_chipset_cmd64x,
- .init_hwif = init_hwif_cmd64x,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
- .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
+ .port_ops = &cmd64x_port_ops,
+ .dma_ops = &cmd648_dma_ops,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
},{ /* 3 */
.name = "CMD649",
.init_chipset = init_chipset_cmd64x,
- .init_hwif = init_hwif_cmd64x,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
- .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
+ .port_ops = &cmd64x_port_ops,
+ .dma_ops = &cmd648_dma_ops,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -483,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 1c163e4ef03f..17669a434438 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -103,27 +103,32 @@ 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 | \
IDE_HFLAG_NO_ATAPI_DMA | \
- IDE_HFLAG_ABUSE_SET_DMA_MODE |\
- IDE_HFLAG_BOOTABLE, \
+ IDE_HFLAG_ABUSE_SET_DMA_MODE, \
.pio_mask = ATA_PIO4, \
}
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index 941a1344820b..f5534c1ff349 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -228,29 +228,27 @@ 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 |
- IDE_HFLAG_BOOTABLE,
+ IDE_HFLAG_POST_SET_MODE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index d7b5ea992e94..99fe91a191b8 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -166,27 +166,17 @@ 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 | IDE_HFLAG_BOOTABLE,
+ IDE_HFLAG_ABUSE_SET_DMA_MODE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 724cbacf4e5b..77cc22c2ad45 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -6,7 +6,7 @@
*
* The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards.
* Writing the driver was quite simple, since most of the job is
- * done by the generic pci-ide support.
+ * done by the generic pci-ide support.
* The hard part was finding the CY82C693's datasheet on Cypress's
* web page :-(. But Altavista solved this problem :-).
*
@@ -15,12 +15,10 @@
* - I recently got a 16.8G IBM DTTA, so I was able to test it with
* a large and fast disk - the results look great, so I'd say the
* driver is working fine :-)
- * 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
+ * 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
+ * - 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
* (lost interrupts) ?????
@@ -110,11 +108,11 @@ typedef struct pio_clocks_s {
* calc clocks using bus_speed
* returns (rounded up) time in bus clocks for time in ns
*/
-static int calc_clk (int time, int bus_speed)
+static int calc_clk(int time, int bus_speed)
{
int clocks;
- clocks = (time*bus_speed+999)/1000 -1;
+ clocks = (time*bus_speed+999)/1000 - 1;
if (clocks < 0)
clocks = 0;
@@ -132,11 +130,11 @@ static int calc_clk (int time, int bus_speed)
* NOTE: for mode 0,1 and 2 drives 8-bit IDE command control registers are used
* for mode 3 and 4 drives 8 and 16-bit timings are the same
*
- */
-static void compute_clocks (u8 pio, pio_clocks_t *p_pclk)
+ */
+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
@@ -158,7 +156,7 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk)
clk1 = (clk1<<4)|clk2; /* combine active and recovery clocks */
/* note: we use the same values for 16bit IOR and IOW
- * those are all the same, since I don't have other
+ * those are all the same, since I don't have other
* timings than those from ide-lib.c
*/
@@ -186,7 +184,7 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
outb(index, CY82_INDEX_PORT);
data = inb(CY82_DATA_PORT);
- printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n",
+ printk(KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n",
drive->name, HWIF(drive)->channel, drive->select.b.unit,
(data&0x3), ((data>>2)&1));
#endif /* CY82C693_DEBUG_LOGS */
@@ -202,7 +200,7 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
mode & 3, single);
#endif /* CY82C693_DEBUG_INFO */
- /*
+ /*
* note: below we set the value for Bus Master IDE TimeOut Register
* I'm not absolutly sure what this does, but it solved my problem
* with IDE DMA and sound, so I now can play sound and work with
@@ -216,8 +214,8 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
outb(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT);
outb(data, CY82_DATA_PORT);
-#if CY82C693_DEBUG_INFO
- printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n",
+#if CY82C693_DEBUG_INFO
+ printk(KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n",
drive->name, data);
#endif /* CY82C693_DEBUG_INFO */
}
@@ -242,14 +240,14 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
#if CY82C693_DEBUG_LOGS
/* for debug let's show the register values */
-
- if (drive->select.b.unit == 0) {
+
+ if (drive->select.b.unit == 0) {
/*
- * get master drive registers
+ * get master drive registers
* address setup control register
* is 32 bit !!!
- */
- pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
+ */
+ pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
addrCtrl &= 0x0F;
/* now let's get the remaining registers */
@@ -261,7 +259,7 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
* set slave drive registers
* address setup control register
* is 32 bit !!!
- */
+ */
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
addrCtrl &= 0xF0;
@@ -288,9 +286,9 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
* set master drive
* address setup control register
* is 32 bit !!!
- */
+ */
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
-
+
addrCtrl &= (~0xF);
addrCtrl |= (unsigned int)pclk.address_time;
pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
@@ -299,14 +297,14 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r);
pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w);
pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8);
-
+
addrCtrl &= 0xF;
} else {
/*
* set slave drive
* address setup control register
* is 32 bit !!!
- */
+ */
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
addrCtrl &= (~0xF0);
@@ -320,7 +318,7 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
addrCtrl >>= 4;
addrCtrl &= 0xF;
- }
+ }
#if CY82C693_DEBUG_INFO
printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to "
@@ -340,41 +338,41 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c
#ifdef CY82C693_SETDMA_CLOCK
u8 data = 0;
-#endif /* CY82C693_SETDMA_CLOCK */
+#endif /* CY82C693_SETDMA_CLOCK */
/* write info about this verion of the driver */
printk(KERN_INFO CY82_VERSION "\n");
#ifdef CY82C693_SETDMA_CLOCK
/* okay let's set the DMA clock speed */
-
- outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT);
- data = inb(CY82_DATA_PORT);
+
+ outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT);
+ data = inb(CY82_DATA_PORT);
#if CY82C693_DEBUG_INFO
printk(KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n",
name, data);
#endif /* CY82C693_DEBUG_INFO */
- /*
+ /*
* for some reason sometimes the DMA controller
* speed is set to ATCLK/2 ???? - we fix this here
- *
+ *
* note: i don't know what causes this strange behaviour,
* but even changing the dma speed doesn't solve it :-(
- * the ide performance is still only half the normal speed
- *
+ * the ide performance is still only half the normal speed
+ *
* if anybody knows what goes wrong with my machine, please
* let me know - ASK
- */
+ */
data |= 0x03;
- outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT);
- outb(data, CY82_DATA_PORT);
+ outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT);
+ outb(data, CY82_DATA_PORT);
#if CY82C693_DEBUG_INFO
- printk (KERN_INFO "%s: New Peripheral Configuration Register: 0x%X\n",
+ printk(KERN_INFO "%s: New Peripheral Configuration Register: 0x%X\n",
name, data);
#endif /* CY82C693_DEBUG_INFO */
@@ -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,14 +393,18 @@ 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 | IDE_HFLAG_CY82C693 |
- IDE_HFLAG_BOOTABLE,
+ .host_flags = IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.swdma_mask = ATA_SWDMA2,
.mwdma_mask = ATA_MWDMA2,
@@ -424,7 +417,7 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev
/* CY82C693 is more than only a IDE controller.
Function 1 is primary IDE channel, function 2 - secondary. */
- if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
+ if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
PCI_FUNC(dev->devfn) == 1) {
dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
ret = ide_setup_pci_devices(dev, dev2, &cy82c693_chipset);
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
index 3f9cd64c26a6..b9e457996d0e 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)
{
@@ -71,26 +75,21 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
if (setup[i])
outb(setup[i], base + i);
}
- pci_release_regions(dev); /* IDE layer handles regions itself */
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, base + 0x10, base + 0x1e);
hw.irq = dev->irq;
hw.chipset = ide_pci; /* this enables IRQ sharing */
- hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+ hwif = ide_find_port();
if (hwif == NULL)
goto out_disable;
i = hwif->index;
- if (hwif->present)
- ide_unregister(i, 0, 0);
- else if (!hwif->hold)
- 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 = &delkin_cb_port_ops;
idx[0] = i;
@@ -110,6 +109,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
out_disable:
printk(KERN_ERR "delkin_cb: no IDE devices found\n");
+ pci_release_regions(dev);
pci_disable_device(dev);
return -ENODEV;
}
@@ -119,9 +119,9 @@ delkin_cb_remove (struct pci_dev *dev)
{
ide_hwif_t *hwif = pci_get_drvdata(dev);
- if (hwif)
- ide_unregister(hwif->index, 0, 0);
+ ide_unregister(hwif);
+ pci_release_regions(dev);
pci_disable_device(dev);
}
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index 7fd83a9d4dee..041720e22762 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -38,8 +38,7 @@ MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE st
{ \
.name = name_str, \
.host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | \
- extra_flags | \
- IDE_HFLAG_BOOTABLE, \
+ extra_flags, \
.swdma_mask = ATA_SWDMA2, \
.mwdma_mask = ATA_MWDMA2, \
.udma_mask = ATA_UDMA6, \
@@ -50,9 +49,8 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
{ /* 1 */
.name = "NS87410",
- .enablebits = {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
- .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
- IDE_HFLAG_BOOTABLE,
+ .enablebits = { {0x43, 0x08, 0x08}, {0x47, 0x08, 0x08} },
+ .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
.swdma_mask = ATA_SWDMA2,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
@@ -99,7 +97,7 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
* Called when the PCI registration layer (or the IDE initialization)
* finds a device matching our IDE device tables.
*/
-
+
static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
const struct ide_port_info *d = &generic_chipsets[id->driver_data];
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index 9f01da46b016..84c36c117194 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,
- .host_flags = IDE_HFLAGS_HPT34X,
+ .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 6357bb6269ab..c929dadaaaff 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),
- IDE_CONTROL_REG);
+ 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);
@@ -929,64 +929,6 @@ static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq)
hpt3xxn_set_clock(HWIF(drive), rq_data_dir(rq) ? 0x23 : 0x21);
}
-/*
- * Set/get power state for a drive.
- * NOTE: affects both drives on each channel.
- *
- * When we turn the power back on, we need to re-initialize things.
- */
-#define TRISTATE_BIT 0x8000
-
-static int hpt3xx_busproc(ide_drive_t *drive, int state)
-{
- ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = to_pci_dev(hwif->dev);
- u8 mcr_addr = hwif->select_data + 2;
- u8 resetmask = hwif->channel ? 0x80 : 0x40;
- u8 bsr2 = 0;
- u16 mcr = 0;
-
- hwif->bus_state = state;
-
- /* Grab the status. */
- pci_read_config_word(dev, mcr_addr, &mcr);
- pci_read_config_byte(dev, 0x59, &bsr2);
-
- /*
- * Set the state. We don't set it if we don't need to do so.
- * Make sure that the drive knows that it has failed if it's off.
- */
- switch (state) {
- case BUSSTATE_ON:
- if (!(bsr2 & resetmask))
- return 0;
- hwif->drives[0].failures = hwif->drives[1].failures = 0;
-
- pci_write_config_byte(dev, 0x59, bsr2 & ~resetmask);
- pci_write_config_word(dev, mcr_addr, mcr & ~TRISTATE_BIT);
- return 0;
- case BUSSTATE_OFF:
- if ((bsr2 & resetmask) && !(mcr & TRISTATE_BIT))
- return 0;
- mcr &= ~TRISTATE_BIT;
- break;
- case BUSSTATE_TRISTATE:
- if ((bsr2 & resetmask) && (mcr & TRISTATE_BIT))
- return 0;
- mcr |= TRISTATE_BIT;
- break;
- default:
- return -EINVAL;
- }
-
- hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
- hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
-
- pci_write_config_word(dev, mcr_addr, mcr);
- pci_write_config_byte(dev, 0x59, bsr2 | resetmask);
- return 0;
-}
-
/**
* hpt37x_calibrate_dpll - calibrate the DPLL
* @dev: PCI device
@@ -1329,18 +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->busproc = &hpt3xx_busproc;
-
- hwif->udma_filter = &hpt3xx_udma_filter;
- hwif->mdma_filter = &hpt3xx_mdma_filter;
-
- hwif->cable_detect = hpt3xx_cable_detect;
-
/*
* HPT3xxN chips have some complications:
*
@@ -1382,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);
@@ -1415,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)
@@ -1475,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",
@@ -1488,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,
@@ -1498,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,
@@ -1508,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,
@@ -1518,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,
@@ -1529,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,
@@ -1539,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,
@@ -1602,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)
@@ -1616,7 +1599,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
hpt374_init(dev, dev2);
else {
if (hpt36x_init(dev, dev2))
- d.host_flags |= IDE_HFLAG_BOOTABLE;
+ d.host_flags &= ~IDE_HFLAG_NON_BOOTABLE;
}
ret = ide_setup_pci_devices(dev, dev2, &d);
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index e3427eaab430..9053c8771e6e 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -35,7 +35,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
static DEFINE_SPINLOCK(tune_lock);
int control = 0;
- static const u8 timings[][2]= {
+ static const u8 timings[][2] = {
{ 0, 0 },
{ 0, 0 },
{ 1, 0 },
@@ -105,11 +105,10 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
if (!(reg48 & u_flag))
pci_write_config_byte(dev, 0x48, reg48 | u_flag);
- if (speed >= XFER_UDMA_5) {
+ if (speed >= XFER_UDMA_5)
pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
- } else {
+ else
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
- }
if ((reg4a & a_speed) != u_speed)
pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
@@ -150,29 +149,18 @@ 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}}, \
- .host_flags = IDE_HFLAG_SINGLE | \
- IDE_HFLAG_BOOTABLE, \
+ .enablebits = { {0x41, 0x80, 0x80} }, \
+ .port_ops = &it8213_port_ops, \
+ .host_flags = IDE_HFLAG_SINGLE, \
.pio_mask = ATA_PIO4, \
.swdma_mask = ATA_SWDMA2_ONLY, \
.mwdma_mask = ATA_MWDMA12_ONLY, \
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index 1597f0cc1bf1..6ab04115286b 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
@@ -523,16 +528,10 @@ static void __devinit it821x_quirkproc(ide_drive_t *drive)
static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
- struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL);
+ struct it821x_dev **itdevs = (struct it821x_dev **)pci_get_drvdata(dev);
+ struct it821x_dev *idev = itdevs[hwif->channel];
u8 conf;
- hwif->quirkproc = &it821x_quirkproc;
-
- if (idev == NULL) {
- printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");
- return;
- }
-
ide_set_hwifdata(hwif, idev);
pci_read_config_byte(dev, 0x50, &conf);
@@ -567,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;
@@ -617,13 +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, \
- .host_flags = IDE_HFLAG_BOOTABLE, \
+ .port_ops = &it821x_port_ops, \
.pio_mask = ATA_PIO4, \
}
@@ -642,6 +642,22 @@ static const struct ide_port_info it821x_chipsets[] __devinitdata = {
static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
+ struct it821x_dev *itdevs[2] = { NULL, NULL} , *itdev;
+ unsigned int i;
+
+ for (i = 0; i < 2; i++) {
+ itdev = kzalloc(sizeof(*itdev), GFP_KERNEL);
+ if (itdev == NULL) {
+ kfree(itdevs[0]);
+ printk(KERN_ERR "it821x: out of memory\n");
+ return -ENOMEM;
+ }
+
+ itdevs[i] = itdev;
+ }
+
+ pci_set_drvdata(dev, itdevs);
+
return ide_setup_pci_device(dev, &it821x_chipsets[id->driver_data]);
}
@@ -667,7 +683,7 @@ static int __init it821x_ide_init(void)
module_init(it821x_ide_init);
module_param_named(noraid, it8212_noraid, int, S_IRUGO);
-MODULE_PARM_DESC(it8212_noraid, "Force card into bypass mode");
+MODULE_PARM_DESC(noraid, "Force card into bypass mode");
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("PCI driver module for the ITE 821x");
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
index a56bcb4f22f4..96ef7394f283 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);
@@ -63,8 +63,7 @@ static u8 __devinit ata66_jmicron(ide_hwif_t *hwif)
* actually do our cable checking etc. Thankfully we don't need
* to do the plumbing for other cases.
*/
- switch (port_map[port])
- {
+ switch (port_map[port]) {
case PORT_PATA0:
if (control & (1 << 3)) /* 40/80 pin primary */
return ATA_CBL_PATA40;
@@ -96,26 +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,
- .host_flags = IDE_HFLAG_BOOTABLE,
.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 bf0d3b2931f1..fec4955f449b 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);
@@ -181,6 +225,10 @@ static int ns87415_ide_dma_setup(ide_drive_t *drive)
return 1;
}
+#ifndef ide_default_irq
+#define ide_default_irq(irq) 0
+#endif
+
static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -191,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
@@ -229,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);
@@ -242,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 */
@@ -250,19 +296,33 @@ 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 |
- IDE_HFLAG_BOOTABLE,
+ IDE_HFLAG_NO_ATAPI_DMA,
};
static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index 46e8748f507e..6e99080497bf 100644
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -53,13 +53,12 @@
* 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.
+ * by Jaromir Koutek, for 2.1.8.
* Initial version of driver.
- *
+ *
* Version 0.2
* Number 0.2 skipped.
*
@@ -75,7 +74,7 @@
* by Jaromir Koutek
* Updates for use with (again) new IDE block driver.
* Update of documentation.
- *
+ *
* Version 0.6, Jan 2, 1999
* by Jaromir Koutek
* Reversed to version 0.3 of the driver, because
@@ -208,29 +207,34 @@ typedef struct pio_clocks_s {
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();
-
- adr_setup = ide_pio_timings[pio].setup_time;
- data_pls = ide_pio_timings[pio].active_time;
- clks->address_time = cmpt_clk(adr_setup, bus_speed);
- clks->data_time = cmpt_clk(data_pls, bus_speed);
- clks->recovery_time = cmpt_clk(ide_pio_timings[pio].cycle_time
- - adr_setup-data_pls, bus_speed);
- if (clks->address_time<1) clks->address_time = 1;
- if (clks->address_time>4) clks->address_time = 4;
- if (clks->data_time<1) clks->data_time = 1;
- if (clks->data_time>16) clks->data_time = 16;
- if (clks->recovery_time<2) clks->recovery_time = 2;
- if (clks->recovery_time>17) clks->recovery_time = 17;
+ if (pio != PIO_NOT_EXIST) {
+ int adr_setup, data_pls;
+ 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;
+ clks->address_time = cmpt_clk(adr_setup, bus_speed);
+ clks->data_time = cmpt_clk(data_pls, bus_speed);
+ clks->recovery_time = cmpt_clk(ide_pio_timings[pio].cycle_time
+ - adr_setup-data_pls, bus_speed);
+ if (clks->address_time < 1)
+ clks->address_time = 1;
+ if (clks->address_time > 4)
+ clks->address_time = 4;
+ if (clks->data_time < 1)
+ clks->data_time = 1;
+ if (clks->data_time > 16)
+ clks->data_time = 16;
+ if (clks->recovery_time < 2)
+ clks->recovery_time = 2;
+ if (clks->recovery_time > 17)
+ clks->recovery_time = 17;
} else {
clks->address_time = 1;
clks->data_time = 1;
clks->recovery_time = 2;
/* minimal values */
}
-
}
static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
@@ -247,8 +251,8 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
/* sets drive->drive_data for both drives */
compute_pios(drive, pio);
- pio1 = hwif->drives[0].drive_data;
- pio2 = hwif->drives[1].drive_data;
+ pio1 = hwif->drives[0].drive_data;
+ pio2 = hwif->drives[1].drive_data;
compute_clocks(pio1, &first);
compute_clocks(pio2, &second);
@@ -275,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);
@@ -321,31 +325,25 @@ 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}},
- .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
- IDE_HFLAG_BOOTABLE,
+ .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 */
+ }, { /* 1 */
.name = "OPTI621X",
- .init_hwif = init_hwif_opti621,
- .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
- .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
- IDE_HFLAG_BOOTABLE,
+ .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,
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 1c8cb7797a4a..070df8ab3b21 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 150422ec3cfa..fca89eda5c02 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 decef0f47674..f04738d14a6f 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,10 +302,16 @@ 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 | IDE_HFLAG_BOOTABLE)
+ #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS
#else
- #define IDE_HFLAGS_PIIX IDE_HFLAG_BOOTABLE
+ #define IDE_HFLAGS_PIIX 0
#endif
#define DECLARE_PIIX_DEV(name_str, udma) \
@@ -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/rz1000.c b/drivers/ide/pci/rz1000.c
index 51676612f78f..532154adba29 100644
--- a/drivers/ide/pci/rz1000.c
+++ b/drivers/ide/pci/rz1000.c
@@ -43,7 +43,7 @@ static const struct ide_port_info rz1000_chipset __devinitdata = {
.name = "RZ100x",
.init_hwif = init_hwif_rz1000,
.chipset = ide_rz1000,
- .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_BOOTABLE,
+ .host_flags = IDE_HFLAG_NO_DMA,
};
static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index 561aa47c7720..14c787b5d95f 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,29 +286,30 @@ 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 |
- IDE_HFLAG_BOOTABLE,
+ IDE_HFLAG_ABUSE_DMA_MODES,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index 238e3e181e87..910fb00deb71 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -65,7 +65,7 @@
static struct scc_ports {
unsigned long ctl, dma;
- unsigned char hwif_id; /* for removing hwif from system */
+ ide_hwif_t *hwif; /* for removing port from system */
} scc_ports[MAX_HWIFS];
/* PIO transfer mode table */
@@ -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,8 @@ 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 *)IDE_ALTSTATUS_REG) & ERR_STAT) &&
+ 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);
if (!(reg & INTSTS_ACTEINT)) {
@@ -424,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;
@@ -437,7 +473,8 @@ 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 *)IDE_ALTSTATUS_REG) & ERR_STAT) &&
+ if ((in_be32((void __iomem *)hwif->io_ports.ctl_addr)
+ & ERR_STAT) &&
(int_stat & INTSTS_INTRQ))
return 1;
@@ -447,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;
}
@@ -481,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)
@@ -490,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;
@@ -513,16 +546,44 @@ 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;
}
+static int scc_ide_setup_pci_device(struct pci_dev *dev,
+ const struct ide_port_info *d)
+{
+ struct scc_ports *ports = pci_get_drvdata(dev);
+ ide_hwif_t *hwif = NULL;
+ hw_regs_t hw;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+ int i;
+
+ hwif = ide_find_port();
+ if (hwif == NULL) {
+ printk(KERN_ERR "%s: too many IDE interfaces, "
+ "no room in table\n", SCC_PATA_NAME);
+ return -ENOMEM;
+ }
+
+ memset(&hw, 0, sizeof(hw));
+ 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;
+
+ idx[0] = hwif->index;
+
+ ide_device_add(idx, d);
+
+ return 0;
+}
+
/**
* init_setup_scc - set up an SCC PATA Controller
* @dev: PCI device
@@ -545,10 +606,13 @@ static int __devinit init_setup_scc(struct pci_dev *dev,
struct scc_ports *ports;
int rc;
+ rc = pci_enable_device(dev);
+ if (rc)
+ goto end;
+
rc = setup_mmio_scc(dev, d->name);
- if (rc < 0) {
- return rc;
- }
+ if (rc < 0)
+ goto end;
ports = pci_get_drvdata(dev);
ctl_base = ports->ctl;
@@ -583,7 +647,126 @@ static int __devinit init_setup_scc(struct pci_dev *dev,
out_be32((void*)mode_port, MODE_JCUSFEN);
out_be32((void*)intmask_port, INTMASK_MSK);
- return ide_setup_pci_device(dev, d);
+ rc = scc_ide_setup_pci_device(dev, d);
+
+ end:
+ 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);
}
/**
@@ -600,27 +783,16 @@ 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->io_ports[IDE_DATA_OFFSET] = dma_base + 0x20;
- hwif->io_ports[IDE_ERROR_OFFSET] = dma_base + 0x24;
- hwif->io_ports[IDE_NSECTOR_OFFSET] = dma_base + 0x28;
- hwif->io_ports[IDE_SECTOR_OFFSET] = dma_base + 0x2c;
- hwif->io_ports[IDE_LCYL_OFFSET] = dma_base + 0x30;
- hwif->io_ports[IDE_HCYL_OFFSET] = dma_base + 0x34;
- hwif->io_ports[IDE_SELECT_OFFSET] = dma_base + 0x38;
- hwif->io_ports[IDE_STATUS_OFFSET] = dma_base + 0x3c;
- hwif->io_ports[IDE_CONTROL_OFFSET] = dma_base + 0x40;
-
- hwif->irq = dev->irq;
+
hwif->dma_base = dma_base;
hwif->config_data = ports->ctl;
hwif->mmio = 1;
@@ -662,37 +834,46 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
{
struct scc_ports *ports = ide_get_hwifdata(hwif);
- ports->hwif_id = hwif->index;
+ ports->hwif = 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, \
- .host_flags = IDE_HFLAG_SINGLE | \
- IDE_HFLAG_BOOTABLE, \
+ .port_ops = &scc_port_ops, \
+ .dma_ops = &scc_dma_ops, \
+ .host_flags = IDE_HFLAG_SINGLE, \
.pio_mask = ATA_PIO4, \
}
@@ -724,11 +905,7 @@ static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_i
static void __devexit scc_remove(struct pci_dev *dev)
{
struct scc_ports *ports = pci_get_drvdata(dev);
- ide_hwif_t *hwif = &ide_hwifs[ports->hwif_id];
- 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);
+ ide_hwif_t *hwif = ports->hwif;
if (hwif->dmatable_cpu) {
pci_free_consistent(dev, PRD_ENTRIES * PRD_BYTES,
@@ -736,13 +913,11 @@ static void __devexit scc_remove(struct pci_dev *dev)
hwif->dmatable_cpu = NULL;
}
- ide_unregister(hwif->index, 0, 0);
+ 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 c11880b0709f..a1fb20826a5b 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,28 +336,28 @@ 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 | \
- IDE_HFLAG_ABUSE_SET_DMA_MODE | \
- IDE_HFLAG_BOOTABLE)
+ IDE_HFLAG_ABUSE_SET_DMA_MODE)
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,
@@ -365,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,
@@ -373,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,
@@ -381,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,
@@ -389,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,
@@ -418,7 +418,7 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device
else if (idx == 2 || idx == 3) {
if ((PCI_FUNC(dev->devfn) & 1) == 0) {
if (pci_resource_start(dev, 0) != 0x01f1)
- d.host_flags &= ~IDE_HFLAG_BOOTABLE;
+ d.host_flags |= IDE_HFLAG_NON_BOOTABLE;
d.host_flags |= IDE_HFLAG_SINGLE;
} else
d.host_flags &= ~IDE_HFLAG_SINGLE;
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 054626497be4..16a0bce17d69 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -98,29 +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 *)IDE_CONTROL_REG);
+ (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;
@@ -135,25 +134,25 @@ 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);
if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */
/*
- * Using sgiioc4_INB to read the IDE_STATUS_REG has a side effect
- * of clearing the interrupt. The first read should clear it
- * if it is set. The second read should return a "clear" status
- * if it got cleared. If not, then spin for a bit trying to
- * clear it.
+ * Using sgiioc4_INB to read the Status register has a side
+ * effect of clearing the interrupt. The first read should
+ * clear it if it is set. The second read should return
+ * a "clear" status if it got cleared. If not, then spin
+ * for a bit trying to clear it.
*/
- u8 stat = sgiioc4_INB(IDE_STATUS_REG);
+ u8 stat = sgiioc4_INB(io_ports->status_addr);
int count = 0;
- stat = sgiioc4_INB(IDE_STATUS_REG);
+ stat = sgiioc4_INB(io_ports->status_addr);
while ((stat & 0x80) && (count++ < 100)) {
udelay(1);
- stat = sgiioc4_INB(IDE_STATUS_REG);
+ stat = sgiioc4_INB(io_ports->status_addr);
}
if (intr_reg & 0x02) {
@@ -163,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);
@@ -189,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;
@@ -216,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);
@@ -233,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;
}
@@ -252,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;
}
@@ -265,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);
}
}
@@ -280,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));
}
@@ -295,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);
}
@@ -330,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);
@@ -344,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;
}
@@ -353,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;
@@ -379,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);
@@ -407,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);
@@ -422,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 */
@@ -520,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;
@@ -549,63 +550,46 @@ 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->busproc = 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;
- int h;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
hw_regs_t hw;
struct ide_port_info d = sgiioc4_port_info;
- /*
- * Find an empty HWIF; if none available, return -ENOMEM.
- */
- for (h = 0; h < MAX_HWIFS; ++h) {
- hwif = &ide_hwifs[h];
- if (hwif->chipset == ide_unknown)
- break;
- }
- if (h == MAX_HWIFS) {
+ hwif = ide_find_port();
+ if (hwif == NULL) {
printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n",
DRV_NAME);
return -ENOMEM;
@@ -622,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,
@@ -630,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;
}
@@ -651,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 8d624afe8529..4cf8fc54aa2a 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,69 +369,32 @@ 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;
}
-/**
- * sil_sata_busproc - bus isolation IOCTL
- * @drive: drive to isolate/restore
- * @state: bus state to set
- *
- * Used by the SII3112 to handle bus isolation. As this is a
- * SATA controller the work required is quite limited, we
- * just have to clean up the statistics
- */
-
-static int sil_sata_busproc(ide_drive_t * drive, int state)
+static int siimage_dma_test_irq(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = to_pci_dev(hwif->dev);
- u32 stat_config = 0;
- unsigned long addr = siimage_selreg(hwif, 0);
-
- if (hwif->mmio)
- stat_config = readl((void __iomem *)addr);
+ if (drive->hwif->mmio)
+ return siimage_mmio_dma_test_irq(drive);
else
- pci_read_config_dword(dev, addr, &stat_config);
-
- switch (state) {
- case BUSSTATE_ON:
- hwif->drives[0].failures = 0;
- hwif->drives[1].failures = 0;
- break;
- case BUSSTATE_OFF:
- hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
- hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
- break;
- case BUSSTATE_TRISTATE:
- hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
- hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
- break;
- default:
- return -EINVAL;
- }
- hwif->bus_state = state;
- return 0;
+ return siimage_io_dma_test_irq(drive);
}
/**
@@ -457,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;
}
@@ -521,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;
}
@@ -586,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;
+ }
+
+ tmp = sil_ioread8(dev, scsc_addr);
+
+ 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);
}
- pci_read_config_byte(dev, 0x8A, &tmpbyte);
+ /* report the clocking mode of the controller */
+ if (!pdev_is_sata(dev)) {
+ static const char *clk_str[] =
+ { "== 100", "== 133", "== 2X PCI", "DISABLED!" };
- 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);
+ tmp >>= 4;
+ printk(KERN_INFO "%s: BASE CLOCK %s\n", name, clk_str[tmp & 3]);
+ }
- proc_reports_siimage(dev, (tmpbyte>>4), name);
return 0;
}
@@ -644,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
@@ -656,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)
@@ -681,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;
@@ -706,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);
@@ -717,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;
+ const char *s = &drive->id->model[0];
+ unsigned len = strnlen(s, sizeof(drive->id->model));
- 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;
}
@@ -746,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;
}
@@ -777,104 +704,91 @@ 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->busproc = &sil_sata_busproc;
- 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 struct ide_dma_ops sil_dma_ops = {
+ .dma_test_irq = siimage_dma_test_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, \
- .host_flags = IDE_HFLAG_BOOTABLE, \
+ .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 512bb4c1fd5c..4b0b85d8faf5 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -59,10 +59,10 @@
#define ATA_16 0x01
#define ATA_33 0x02
#define ATA_66 0x03
-#define ATA_100a 0x04 // SiS730/SiS550 is ATA100 with ATA66 layout
+#define ATA_100a 0x04 /* SiS730/SiS550 is ATA100 with ATA66 layout */
#define ATA_100 0x05
-#define ATA_133a 0x06 // SiS961b with 133 support
-#define ATA_133 0x07 // SiS962/963
+#define ATA_133a 0x06 /* SiS961b with 133 support */
+#define ATA_133 0x07 /* SiS962/963 */
static u8 chipset_family;
@@ -111,69 +111,70 @@ static const struct {
Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */
/* {0, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */
-static u8 cycle_time_offset[] = {0,0,5,4,4,0,0};
-static u8 cycle_time_range[] = {0,0,2,3,3,4,4};
+static u8 cycle_time_offset[] = { 0, 0, 5, 4, 4, 0, 0 };
+static u8 cycle_time_range[] = { 0, 0, 2, 3, 3, 4, 4 };
static u8 cycle_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = {
- {0,0,0,0,0,0,0}, /* no udma */
- {0,0,0,0,0,0,0}, /* no udma */
- {3,2,1,0,0,0,0}, /* ATA_33 */
- {7,5,3,2,1,0,0}, /* ATA_66 */
- {7,5,3,2,1,0,0}, /* ATA_100a (730 specific), differences are on cycle_time range and offset */
- {11,7,5,4,2,1,0}, /* ATA_100 */
- {15,10,7,5,3,2,1}, /* ATA_133a (earliest 691 southbridges) */
- {15,10,7,5,3,2,1}, /* ATA_133 */
+ { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */
+ { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */
+ { 3, 2, 1, 0, 0, 0, 0 }, /* ATA_33 */
+ { 7, 5, 3, 2, 1, 0, 0 }, /* ATA_66 */
+ { 7, 5, 3, 2, 1, 0, 0 }, /* ATA_100a (730 specific),
+ different cycle_time range and offset */
+ { 11, 7, 5, 4, 2, 1, 0 }, /* ATA_100 */
+ { 15, 10, 7, 5, 3, 2, 1 }, /* ATA_133a (earliest 691 southbridges) */
+ { 15, 10, 7, 5, 3, 2, 1 }, /* ATA_133 */
};
/* CRC Valid Setup Time vary across IDE clock setting 33/66/100/133
See SiS962 data sheet for more detail */
static u8 cvs_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = {
- {0,0,0,0,0,0,0}, /* no udma */
- {0,0,0,0,0,0,0}, /* no udma */
- {2,1,1,0,0,0,0},
- {4,3,2,1,0,0,0},
- {4,3,2,1,0,0,0},
- {6,4,3,1,1,1,0},
- {9,6,4,2,2,2,2},
- {9,6,4,2,2,2,2},
+ { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */
+ { 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */
+ { 2, 1, 1, 0, 0, 0, 0 },
+ { 4, 3, 2, 1, 0, 0, 0 },
+ { 4, 3, 2, 1, 0, 0, 0 },
+ { 6, 4, 3, 1, 1, 1, 0 },
+ { 9, 6, 4, 2, 2, 2, 2 },
+ { 9, 6, 4, 2, 2, 2, 2 },
};
/* Initialize time, Active time, Recovery time vary across
IDE clock settings. These 3 arrays hold the register value
for PIO0/1/2/3/4 and DMA0/1/2 mode in order */
static u8 ini_time_value[][8] = {
- {0,0,0,0,0,0,0,0},
- {0,0,0,0,0,0,0,0},
- {2,1,0,0,0,1,0,0},
- {4,3,1,1,1,3,1,1},
- {4,3,1,1,1,3,1,1},
- {6,4,2,2,2,4,2,2},
- {9,6,3,3,3,6,3,3},
- {9,6,3,3,3,6,3,3},
+ { 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 2, 1, 0, 0, 0, 1, 0, 0 },
+ { 4, 3, 1, 1, 1, 3, 1, 1 },
+ { 4, 3, 1, 1, 1, 3, 1, 1 },
+ { 6, 4, 2, 2, 2, 4, 2, 2 },
+ { 9, 6, 3, 3, 3, 6, 3, 3 },
+ { 9, 6, 3, 3, 3, 6, 3, 3 },
};
static u8 act_time_value[][8] = {
- {0,0,0,0,0,0,0,0},
- {0,0,0,0,0,0,0,0},
- {9,9,9,2,2,7,2,2},
- {19,19,19,5,4,14,5,4},
- {19,19,19,5,4,14,5,4},
- {28,28,28,7,6,21,7,6},
- {38,38,38,10,9,28,10,9},
- {38,38,38,10,9,28,10,9},
+ { 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 9, 9, 9, 2, 2, 7, 2, 2 },
+ { 19, 19, 19, 5, 4, 14, 5, 4 },
+ { 19, 19, 19, 5, 4, 14, 5, 4 },
+ { 28, 28, 28, 7, 6, 21, 7, 6 },
+ { 38, 38, 38, 10, 9, 28, 10, 9 },
+ { 38, 38, 38, 10, 9, 28, 10, 9 },
};
static u8 rco_time_value[][8] = {
- {0,0,0,0,0,0,0,0},
- {0,0,0,0,0,0,0,0},
- {9,2,0,2,0,7,1,1},
- {19,5,1,5,2,16,3,2},
- {19,5,1,5,2,16,3,2},
- {30,9,3,9,4,25,6,4},
- {40,12,4,12,5,34,12,5},
- {40,12,4,12,5,34,12,5},
+ { 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 9, 2, 0, 2, 0, 7, 1, 1 },
+ { 19, 5, 1, 5, 2, 16, 3, 2 },
+ { 19, 5, 1, 5, 2, 16, 3, 2 },
+ { 30, 9, 3, 9, 4, 25, 6, 4 },
+ { 40, 12, 4, 12, 5, 34, 12, 5 },
+ { 40, 12, 4, 12, 5, 34, 12, 5 },
};
/*
* Printing configuration
*/
/* Used for chipset type printing at boot time */
-static char* chipset_capability[] = {
+static char *chipset_capability[] = {
"ATA", "ATA 16",
"ATA 33", "ATA 66",
"ATA 100 (1st gen)", "ATA 100 (2nd gen)",
@@ -272,7 +273,7 @@ static void sis_program_timings(ide_drive_t *drive, const u8 mode)
sis_ata133_program_timings(drive, mode);
}
-static void config_drive_art_rwp (ide_drive_t *drive)
+static void config_drive_art_rwp(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -346,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;
@@ -358,8 +359,7 @@ static u8 sis5513_ata133_udma_filter(ide_drive_t *drive)
return (regdw & 0x08) ? ATA_UDMA6 : ATA_UDMA5;
}
-/* Chip detection and general config */
-static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name)
+static int __devinit sis_find_family(struct pci_dev *dev)
{
struct pci_dev *host;
int i = 0;
@@ -381,7 +381,7 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
chipset_family = ATA_100a;
}
pci_dev_put(host);
-
+
printk(KERN_INFO "SIS5513: %s %s controller\n",
SiSHostChipInfo[i].name, chipset_capability[chipset_family]);
}
@@ -440,63 +440,60 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
}
}
- if (!chipset_family)
- return -1;
+ return chipset_family;
+}
+static unsigned int __devinit init_chipset_sis5513(struct pci_dev *dev,
+ const char *name)
+{
/* Make general config ops here
1/ tell IDE channels to operate in Compatibility mode only
2/ tell old chips to allow per drive IDE timings */
- {
- u8 reg;
- u16 regw;
-
- switch(chipset_family) {
- case ATA_133:
- /* SiS962 operation mode */
- pci_read_config_word(dev, 0x50, &regw);
- if (regw & 0x08)
- pci_write_config_word(dev, 0x50, regw&0xfff7);
- pci_read_config_word(dev, 0x52, &regw);
- if (regw & 0x08)
- pci_write_config_word(dev, 0x52, regw&0xfff7);
- break;
- case ATA_133a:
- case ATA_100:
- /* Fixup latency */
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80);
- /* Set compatibility bit */
- pci_read_config_byte(dev, 0x49, &reg);
- if (!(reg & 0x01)) {
- pci_write_config_byte(dev, 0x49, reg|0x01);
- }
- break;
- case ATA_100a:
- case ATA_66:
- /* Fixup latency */
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10);
-
- /* On ATA_66 chips the bit was elsewhere */
- pci_read_config_byte(dev, 0x52, &reg);
- if (!(reg & 0x04)) {
- pci_write_config_byte(dev, 0x52, reg|0x04);
- }
- break;
- case ATA_33:
- /* On ATA_33 we didn't have a single bit to set */
- pci_read_config_byte(dev, 0x09, &reg);
- if ((reg & 0x0f) != 0x00) {
- pci_write_config_byte(dev, 0x09, reg&0xf0);
- }
- case ATA_16:
- /* force per drive recovery and active timings
- needed on ATA_33 and below chips */
- pci_read_config_byte(dev, 0x52, &reg);
- if (!(reg & 0x08)) {
- pci_write_config_byte(dev, 0x52, reg|0x08);
- }
- break;
- }
+ u8 reg;
+ u16 regw;
+
+ switch (chipset_family) {
+ case ATA_133:
+ /* SiS962 operation mode */
+ pci_read_config_word(dev, 0x50, &regw);
+ if (regw & 0x08)
+ pci_write_config_word(dev, 0x50, regw&0xfff7);
+ pci_read_config_word(dev, 0x52, &regw);
+ if (regw & 0x08)
+ pci_write_config_word(dev, 0x52, regw&0xfff7);
+ break;
+ case ATA_133a:
+ case ATA_100:
+ /* Fixup latency */
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80);
+ /* Set compatibility bit */
+ pci_read_config_byte(dev, 0x49, &reg);
+ if (!(reg & 0x01))
+ pci_write_config_byte(dev, 0x49, reg|0x01);
+ break;
+ case ATA_100a:
+ case ATA_66:
+ /* Fixup latency */
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10);
+
+ /* On ATA_66 chips the bit was elsewhere */
+ pci_read_config_byte(dev, 0x52, &reg);
+ if (!(reg & 0x04))
+ pci_write_config_byte(dev, 0x52, reg|0x04);
+ break;
+ case ATA_33:
+ /* On ATA_33 we didn't have a single bit to set */
+ pci_read_config_byte(dev, 0x09, &reg);
+ if ((reg & 0x0f) != 0x00)
+ pci_write_config_byte(dev, 0x09, reg&0xf0);
+ case ATA_16:
+ /* force per drive recovery and active timings
+ needed on ATA_33 and below chips */
+ pci_read_config_byte(dev, 0x52, &reg);
+ if (!(reg & 0x08))
+ pci_write_config_byte(dev, 0x52, reg|0x08);
+ break;
}
return 0;
@@ -517,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];
@@ -546,38 +543,44 @@ 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)
-{
- u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f };
-
- 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;
-
- hwif->cable_detect = ata66_sis5513;
-
- if (hwif->dma_base == 0)
- return;
+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->ultra_mask = udma_rates[chipset_family];
-}
+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 |
- IDE_HFLAG_BOOTABLE,
+ .enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} },
+ .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
};
static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- return ide_setup_pci_device(dev, &sis5513_chipset);
+ struct ide_port_info d = sis5513_chipset;
+ u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f };
+
+ 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);
}
static const struct pci_device_id sis5513_pci_tbl[] = {
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index ee261ae15b6f..ce84fa045d39 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,60 +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 |
- IDE_HFLAG_NO_AUTODMA |
- IDE_HFLAG_BOOTABLE,
+/* 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 65f4c2ffaa59..dae6e2c94d86 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -27,9 +27,9 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
unsigned long flags;
u16 master_data;
u8 slave_data;
- int control = 0;
+ int control = 0;
/* ISP RTC */
- static const u8 timings[][2]= {
+ static const u8 timings[][2] = {
{ 0, 0 },
{ 0, 0 },
{ 1, 0 },
@@ -125,19 +125,17 @@ 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}},
- .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
+ .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,
.mwdma_mask = ATA_MWDMA12_ONLY,
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index 2ef2ed2f2b32..9b4b27a4c711 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -18,20 +18,20 @@ static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed)
u16 mode, scr = inw(scr_port);
switch (speed) {
- case XFER_UDMA_4: mode = 0x00c0; break;
- case XFER_UDMA_3: mode = 0x00b0; break;
- case XFER_UDMA_2: mode = 0x00a0; break;
- case XFER_UDMA_1: mode = 0x0090; break;
- case XFER_UDMA_0: mode = 0x0080; break;
- case XFER_MW_DMA_2: mode = 0x0070; break;
- case XFER_MW_DMA_1: mode = 0x0060; break;
- case XFER_MW_DMA_0: mode = 0x0050; break;
- case XFER_PIO_4: mode = 0x0400; break;
- case XFER_PIO_3: mode = 0x0300; break;
- case XFER_PIO_2: mode = 0x0200; break;
- case XFER_PIO_1: mode = 0x0100; break;
- case XFER_PIO_0:
- default: mode = 0x0000; break;
+ case XFER_UDMA_4: mode = 0x00c0; break;
+ case XFER_UDMA_3: mode = 0x00b0; break;
+ case XFER_UDMA_2: mode = 0x00a0; break;
+ case XFER_UDMA_1: mode = 0x0090; break;
+ case XFER_UDMA_0: mode = 0x0080; break;
+ case XFER_MW_DMA_2: mode = 0x0070; break;
+ case XFER_MW_DMA_1: mode = 0x0060; break;
+ case XFER_MW_DMA_0: mode = 0x0050; break;
+ case XFER_PIO_4: mode = 0x0400; break;
+ case XFER_PIO_3: mode = 0x0300; break;
+ case XFER_PIO_2: mode = 0x0200; break;
+ case XFER_PIO_1: mode = 0x0100; break;
+ case XFER_PIO_0:
+ default: mode = 0x0000; break;
}
scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f;
@@ -126,40 +126,6 @@ static void tc86c001_dma_start(ide_drive_t *drive)
ide_dma_start(drive);
}
-static int tc86c001_busproc(ide_drive_t *drive, int state)
-{
- ide_hwif_t *hwif = HWIF(drive);
- unsigned long sc_base = hwif->config_data;
- u16 scr1;
-
- /* System Control 1 Register bit 11 (ATA Hard Reset) read */
- scr1 = inw(sc_base + 0x00);
-
- switch (state) {
- case BUSSTATE_ON:
- if (!(scr1 & 0x0800))
- return 0;
- scr1 &= ~0x0800;
-
- hwif->drives[0].failures = hwif->drives[1].failures = 0;
- break;
- case BUSSTATE_OFF:
- if (scr1 & 0x0800)
- return 0;
- scr1 |= 0x0800;
-
- hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
- hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
- break;
- default:
- return -EINVAL;
- }
-
- /* System Control 1 Register bit 11 (ATA Hard Reset) write */
- outw(scr1, sc_base + 0x00);
- return 0;
-}
-
static u8 __devinit tc86c001_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -191,13 +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->busproc = &tc86c001_busproc;
-
- hwif->cable_detect = tc86c001_cable_detect;
-
if (!hwif->dma_base)
return;
@@ -209,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,
@@ -223,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 a67d02a3f96e..db65a558d4ec 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -87,17 +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}},
- .host_flags = IDE_HFLAG_BOOTABLE,
+ .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 de750f7a43e9..a8a3138682ef 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,16 +309,32 @@ 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 |
#endif
IDE_HFLAG_NO_AUTODMA |
- IDE_HFLAG_BOOTABLE |
IDE_HFLAG_NO_LBA48,
};
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 9004e7521889..566e0ecb8db1 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,25 +415,21 @@ 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_PIO_NO_DOWNGRADE |
IDE_HFLAG_ABUSE_SET_DMA_MODE |
IDE_HFLAG_POST_SET_MODE |
- IDE_HFLAG_IO_32BIT |
- IDE_HFLAG_BOOTABLE,
+ IDE_HFLAG_IO_32BIT,
.pio_mask = ATA_PIO5,
.swdma_mask = ATA_SWDMA2,
.mwdma_mask = ATA_MWDMA2,
diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c
index ebaba01c7551..f0e638dcc3ab 100644
--- a/drivers/ide/ppc/mpc8xx.c
+++ b/drivers/ide/ppc/mpc8xx.c
@@ -36,6 +36,8 @@
#include <asm/machdep.h>
#include <asm/irq.h>
+#define DRV_NAME "ide-mpc8xx"
+
static int identify (volatile u8 *p);
static void print_fixed (volatile u8 *p);
static void print_funcid (int func);
@@ -99,32 +101,6 @@ static int _slot_ = -1; /* will be read from PCMCIA registers */
/* Make clock cycles and always round up */
#define PCMCIA_MK_CLKS( t, T ) (( (t) * ((T)/1000000) + 999U ) / 1000U )
-
-
-/*
- * IDE stuff.
- */
-static int
-m8xx_ide_default_irq(unsigned long base)
-{
-#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
- if (base >= MAX_HWIFS)
- return 0;
-
- printk("[%d] m8xx_ide_default_irq %d\n",__LINE__,ioport_dsc[base].irq);
-
- return (ioport_dsc[base].irq);
-#else
- return 9;
-#endif
-}
-
-static unsigned long
-m8xx_ide_default_io_base(int index)
-{
- return index;
-}
-
#define M8XX_PCMCIA_CD2(slot) (0x10000000 >> (slot << 4))
#define M8XX_PCMCIA_CD1(slot) (0x08000000 >> (slot << 4))
@@ -149,14 +125,13 @@ static int pcmcia_schlvl = PCMCIA_SCHLVL;
*/
/*
- * m8xx_ide_init_hwif_ports for a direct IDE interface _using_
+ * m8xx_ide_init_ports() for a direct IDE interface _using_
+ * MPC8xx's internal PCMCIA interface
*/
#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT)
-static void
-m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
- unsigned long ctrl_port, int *irq)
+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 {
@@ -173,8 +148,6 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
unsigned long base;
*p = 0;
- if (irq)
- *irq = 0;
pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
@@ -211,6 +184,13 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
pcmcia_phy_base, pcmcia_phy_end,
pcmcia_phy_end - pcmcia_phy_base);
+ if (!request_mem_region(pcmcia_phy_base,
+ pcmcia_phy_end - pcmcia_phy_base,
+ DRV_NAME)) {
+ printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
+ return -EBUSY;
+ }
+
pcmcia_base=(unsigned long)ioremap(pcmcia_phy_base,
pcmcia_phy_end-pcmcia_phy_base);
@@ -248,9 +228,6 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
}
}
- if (data_port >= MAX_HWIFS)
- return;
-
if (_slot_ == -1) {
printk ("PCMCIA slot has not been defined! Using A as default\n");
_slot_ = 0;
@@ -268,7 +245,7 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
if (pcmp->pcmc_pipr & (M8XX_PCMCIA_CD1(_slot_)|M8XX_PCMCIA_CD2(_slot_))) {
printk ("No card in slot %c: PIPR=%08x\n",
'A' + _slot_, (u32) pcmp->pcmc_pipr);
- return; /* No card in slot */
+ return -ENODEV; /* No card in slot */
}
check_ide_device (pcmcia_base);
@@ -292,11 +269,13 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
*p++ = base + ioport_dsc[data_port].reg_off[i];
}
- if (irq) {
+ hw->irq = ioport_dsc[data_port].irq;
+ hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
+
#ifdef CONFIG_IDE_8xx_PCCARD
+ {
unsigned int reg;
- *irq = ioport_dsc[data_port].irq;
if (_slot_)
pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcrb;
else
@@ -306,14 +285,8 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
reg |= mk_int_int_mask (pcmcia_schlvl) << 24;
reg |= mk_int_int_mask (pcmcia_schlvl) << 16;
*pgcrx = reg;
-#else /* direct connected IDE drive, i.e. external IRQ, not the PCMCIA irq */
- *irq = ioport_dsc[data_port].irq;
-#endif /* CONFIG_IDE_8xx_PCCARD */
}
-
- ide_hwifs[data_port].pio_mask = ATA_PIO4;
- ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode;
- ide_hwifs[data_port].ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
+#endif /* CONFIG_IDE_8xx_PCCARD */
/* Enable Harddisk Interrupt,
* and make it edge sensitive
@@ -329,18 +302,19 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
/* Enable falling edge irq */
pcmp->pcmc_per = 0x100000 >> (16 * _slot_);
#endif /* CONFIG_IDE_8xx_PCCARD */
-} /* m8xx_ide_init_hwif_ports() using 8xx internal PCMCIA interface */
+
+ return 0;
+}
#endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */
/*
- * m8xx_ide_init_hwif_ports for a direct IDE interface _not_ using
+ * m8xx_ide_init_ports() for a direct IDE interface _not_ using
* MPC8xx's internal PCMCIA interface
*/
#if defined(CONFIG_IDE_EXT_DIRECT)
-void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
- unsigned long data_port, unsigned long ctrl_port, int *irq)
+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;
@@ -349,8 +323,6 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
unsigned long base;
*p = 0;
- if (irq)
- *irq = 0;
if (!ide_base) {
@@ -363,7 +335,12 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
printk ("IDE phys mem : %08x...%08x (size %08x)\n",
ide_phy_base, ide_phy_end,
ide_phy_end - ide_phy_base);
-
+
+ if (!request_mem_region(ide_phy_base, 0x200, DRV_NAME)) {
+ printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
+ return -EBUSY;
+ }
+
ide_base=(unsigned long)ioremap(ide_phy_base,
ide_phy_end-ide_phy_base);
@@ -372,9 +349,6 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
#endif
}
- if (data_port >= MAX_HWIFS)
- return;
-
base = ide_base + ioport_dsc[data_port].base_off;
#ifdef DEBUG
printk ("base: %08x + %08x = %08x\n",
@@ -392,14 +366,9 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
*p++ = base + ioport_dsc[data_port].reg_off[i];
}
- if (irq) {
- /* direct connected IDE drive, i.e. external IRQ */
- *irq = ioport_dsc[data_port].irq;
- }
-
- ide_hwifs[data_port].pio_mask = ATA_PIO4;
- ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode;
- ide_hwifs[data_port].ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
+ /* direct connected IDE drive, i.e. external IRQ */
+ hw->irq = ioport_dsc[data_port].irq;
+ hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
/* Enable Harddisk Interrupt,
* and make it edge sensitive
@@ -407,8 +376,9 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
/* (11-18) Set edge detect for irq, no wakeup from low power mode */
((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |=
(0x80000000 >> ioport_dsc[data_port].irq);
-} /* m8xx_ide_init_hwif_ports() for CONFIG_IDE_8xx_DIRECT */
+ return 0;
+}
#endif /* CONFIG_IDE_8xx_DIRECT */
@@ -468,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)
{
@@ -829,21 +803,37 @@ static int identify (volatile u8 *p)
return (0); /* don't know */
}
-void m8xx_ide_init(void)
-{
- ppc_ide_md.default_irq = m8xx_ide_default_irq;
- ppc_ide_md.default_io_base = m8xx_ide_default_io_base;
- ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports;
-}
-
static int __init mpc8xx_ide_probe(void)
{
+ hw_regs_t hw;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
#ifdef IDE0_BASE_OFFSET
- idx[0] = 0;
+ memset(&hw, 0, sizeof(hw));
+ if (!m8xx_ide_init_ports(&hw, 0)) {
+ ide_hwif_t *hwif = ide_find_port();
+
+ if (hwif) {
+ ide_init_port_hw(hwif, &hw);
+ hwif->pio_mask = ATA_PIO4;
+ hwif->port_ops = &m8xx_port_ops;
+
+ idx[0] = hwif->index;
+ }
+ }
#ifdef IDE1_BASE_OFFSET
- idx[1] = 1;
+ memset(&hw, 0, sizeof(hw));
+ if (!m8xx_ide_init_ports(&hw, 1)) {
+ ide_hwif_t *mate = ide_find_port();
+
+ if (mate) {
+ ide_init_port_hw(mate, &hw);
+ mate->pio_mask = ATA_PIO4;
+ mate->port_ops = &m8xx_port_ops;
+
+ idx[1] = mate->index;
+ }
+ }
#endif
#endif
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index d9ca52e6cdab..48aa019127bc 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -79,9 +79,6 @@ typedef struct pmac_ide_hwif {
} pmac_ide_hwif_t;
-static pmac_ide_hwif_t pmac_ide[MAX_HWIFS];
-static int pmac_ide_count;
-
enum {
controller_ohare, /* OHare based */
controller_heathrow, /* Heathrow/Paddington */
@@ -412,45 +409,15 @@ 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);
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
-/*
- * N.B. this can't be an initfunc, because the media-bay task can
- * call ide_[un]register at any time.
- */
-void
-pmac_ide_init_hwif_ports(hw_regs_t *hw,
- unsigned long data_port, unsigned long ctrl_port,
- int *irq)
-{
- int i, ix;
-
- if (data_port == 0)
- return;
-
- for (ix = 0; ix < MAX_HWIFS; ++ix)
- if (data_port == pmac_ide[ix].regbase)
- break;
-
- if (ix >= MAX_HWIFS)
- return; /* not an IDE PMAC interface */
-
- for (i = 0; i < 8; ++i)
- hw->io_ports[i] = data_port + i * 0x10;
- hw->io_ports[8] = data_port + 0x160;
-
- if (irq != NULL)
- *irq = pmac_ide[ix].irq;
-
- hw->dev = &pmac_ide[ix].mdev->ofdev.dev;
-}
-
-#define PMAC_IDE_REG(x) ((void __iomem *)(IDE_DATA_REG+(x)))
+#define PMAC_IDE_REG(x) \
+ ((void __iomem *)((drive)->hwif->io_ports.data_addr + (x)))
/*
* Apply the timings of the proper unit (master/slave) to the shared
@@ -886,58 +853,6 @@ sanitize_timings(pmac_ide_hwif_t *pmif)
pmif->timings[2] = pmif->timings[3] = value2;
}
-unsigned long
-pmac_ide_get_base(int index)
-{
- return pmac_ide[index].regbase;
-}
-
-int
-pmac_ide_check_base(unsigned long base)
-{
- int ix;
-
- for (ix = 0; ix < MAX_HWIFS; ++ix)
- if (base == pmac_ide[ix].regbase)
- return ix;
- return -1;
-}
-
-int
-pmac_ide_get_irq(unsigned long base)
-{
- int ix;
-
- for (ix = 0; ix < MAX_HWIFS; ++ix)
- if (base == pmac_ide[ix].regbase)
- return pmac_ide[ix].irq;
- return 0;
-}
-
-static int ide_majors[] = { 3, 22, 33, 34, 56, 57 };
-
-dev_t __init
-pmac_find_ide_boot(char *bootdevice, int n)
-{
- int i;
-
- /*
- * Look through the list of IDE interfaces for this one.
- */
- for (i = 0; i < pmac_ide_count; ++i) {
- char *name;
- if (!pmac_ide[i].node || !pmac_ide[i].node->full_name)
- continue;
- name = pmac_ide[i].node->full_name;
- if (memcmp(name, bootdevice, n) == 0 && name[n] == 0) {
- /* XXX should cope with the 2nd drive as well... */
- return MKDEV(ide_majors[i], 0);
- }
- }
-
- return 0;
-}
-
/* Suspend call back, should be called after the child devices
* have actually been suspended
*/
@@ -1003,12 +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_PIO_NO_DOWNGRADE |
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,
@@ -1033,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) {
@@ -1088,7 +1024,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
if (np->parent && np->parent->name
&& strcasecmp(np->parent->name, "media-bay") == 0) {
#ifdef CONFIG_PMAC_MEDIABAY
- media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq, hwif->index);
+ media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq,
+ hwif);
#endif /* CONFIG_PMAC_MEDIABAY */
pmif->mediabay = 1;
if (!bidp)
@@ -1114,38 +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->hold = 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;
@@ -1154,6 +1082,16 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
return 0;
}
+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_array[i] = base + i * 0x10;
+
+ hw->io_ports.ctl_addr = base + 0x160;
+}
+
/*
* Attach to a macio probed interface
*/
@@ -1162,35 +1100,36 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
void __iomem *base;
unsigned long regbase;
- int irq;
ide_hwif_t *hwif;
pmac_ide_hwif_t *pmif;
- int i, rc;
+ int irq, rc;
hw_regs_t hw;
- i = 0;
- while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0
- || pmac_ide[i].node != NULL))
- ++i;
- if (i >= MAX_HWIFS) {
+ pmif = kzalloc(sizeof(*pmif), GFP_KERNEL);
+ if (pmif == NULL)
+ return -ENOMEM;
+
+ hwif = ide_find_port();
+ if (hwif == NULL) {
printk(KERN_ERR "ide-pmac: MacIO interface attach with no slot\n");
printk(KERN_ERR " %s\n", mdev->ofdev.node->full_name);
- return -ENODEV;
+ rc = -ENODEV;
+ goto out_free_pmif;
}
- pmif = &pmac_ide[i];
- hwif = &ide_hwifs[i];
-
if (macio_resource_count(mdev) == 0) {
- printk(KERN_WARNING "ide%d: no address for %s\n",
- i, mdev->ofdev.node->full_name);
- return -ENXIO;
+ printk(KERN_WARNING "ide-pmac: no address for %s\n",
+ mdev->ofdev.node->full_name);
+ rc = -ENXIO;
+ goto out_free_pmif;
}
/* Request memory resource for IO ports */
if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) {
- printk(KERN_ERR "ide%d: can't request mmio resource !\n", i);
- return -EBUSY;
+ printk(KERN_ERR "ide-pmac: can't request MMIO resource for "
+ "%s!\n", mdev->ofdev.node->full_name);
+ rc = -EBUSY;
+ goto out_free_pmif;
}
/* XXX This is bogus. Should be fixed in the registry by checking
@@ -1199,8 +1138,8 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
* where that happens though...
*/
if (macio_irq_count(mdev) == 0) {
- printk(KERN_WARNING "ide%d: no intrs for device %s, using 13\n",
- i, mdev->ofdev.node->full_name);
+ printk(KERN_WARNING "ide-pmac: no intrs for device %s, using "
+ "13\n", mdev->ofdev.node->full_name);
irq = irq_create_mapping(NULL, 13);
} else
irq = macio_irq(mdev, 0);
@@ -1218,7 +1157,9 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
if (macio_resource_count(mdev) >= 2) {
if (macio_request_resource(mdev, 1, "ide-pmac (dma)"))
- printk(KERN_WARNING "ide%d: can't request DMA resource !\n", i);
+ printk(KERN_WARNING "ide-pmac: can't request DMA "
+ "resource for %s!\n",
+ mdev->ofdev.node->full_name);
else
pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000);
} else
@@ -1227,7 +1168,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
dev_set_drvdata(&mdev->ofdev.dev, hwif);
memset(&hw, 0, sizeof(hw));
- pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, NULL);
+ pmac_ide_init_ports(&hw, pmif->regbase);
hw.irq = irq;
hw.dev = &mdev->ofdev.dev;
@@ -1240,11 +1181,15 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
iounmap(pmif->dma_regs);
macio_release_resource(mdev, 1);
}
- memset(pmif, 0, sizeof(*pmif));
macio_release_resource(mdev, 0);
+ kfree(pmif);
}
return rc;
+
+out_free_pmif:
+ kfree(pmif);
+ return rc;
}
static int
@@ -1289,7 +1234,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
pmac_ide_hwif_t *pmif;
void __iomem *base;
unsigned long rbase, rlen;
- int i, rc;
+ int rc;
hw_regs_t hw;
np = pci_device_to_OF_node(pdev);
@@ -1297,30 +1242,32 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
printk(KERN_ERR "ide-pmac: cannot find MacIO node for Kauai ATA interface\n");
return -ENODEV;
}
- i = 0;
- while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0
- || pmac_ide[i].node != NULL))
- ++i;
- if (i >= MAX_HWIFS) {
+
+ pmif = kzalloc(sizeof(*pmif), GFP_KERNEL);
+ if (pmif == NULL)
+ return -ENOMEM;
+
+ hwif = ide_find_port();
+ if (hwif == NULL) {
printk(KERN_ERR "ide-pmac: PCI interface attach with no slot\n");
printk(KERN_ERR " %s\n", np->full_name);
- return -ENODEV;
+ rc = -ENODEV;
+ goto out_free_pmif;
}
- pmif = &pmac_ide[i];
- hwif = &ide_hwifs[i];
-
if (pci_enable_device(pdev)) {
- printk(KERN_WARNING "ide%i: Can't enable PCI device for %s\n",
- i, np->full_name);
- return -ENXIO;
+ printk(KERN_WARNING "ide-pmac: Can't enable PCI device for "
+ "%s\n", np->full_name);
+ rc = -ENXIO;
+ goto out_free_pmif;
}
pci_set_master(pdev);
if (pci_request_regions(pdev, "Kauai ATA")) {
- printk(KERN_ERR "ide%d: Cannot obtain PCI resources for %s\n",
- i, np->full_name);
- return -ENXIO;
+ printk(KERN_ERR "ide-pmac: Cannot obtain PCI resources for "
+ "%s\n", np->full_name);
+ rc = -ENXIO;
+ goto out_free_pmif;
}
hwif->dev = &pdev->dev;
@@ -1341,7 +1288,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_drvdata(pdev, hwif);
memset(&hw, 0, sizeof(hw));
- pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, NULL);
+ pmac_ide_init_ports(&hw, pmif->regbase);
hw.irq = pdev->irq;
hw.dev = &pdev->dev;
@@ -1350,11 +1297,15 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
/* The inteface is released to the common IDE layer */
pci_set_drvdata(pdev, NULL);
iounmap(base);
- memset(pmif, 0, sizeof(*pmif));
pci_release_regions(pdev);
+ kfree(pmif);
}
return rc;
+
+out_free_pmif:
+ kfree(pmif);
+ return rc;
}
static int
@@ -1726,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.
@@ -1756,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 634e3f6a9608..5171601fb255 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -20,84 +20,6 @@
#include <asm/io.h>
#include <asm/irq.h>
-
-/**
- * ide_match_hwif - match a PCI IDE against an ide_hwif
- * @io_base: I/O base of device
- * @bootable: set if its bootable
- * @name: name of device
- *
- * Match a PCI IDE port against an entry in ide_hwifs[],
- * based on io_base port if possible. Return the matching hwif,
- * or a new hwif. If we find an error (clashing, out of devices, etc)
- * return NULL
- *
- * FIXME: we need to handle mmio matches here too
- */
-
-static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char *name)
-{
- int h;
- ide_hwif_t *hwif;
-
- /*
- * Look for a hwif with matching io_base specified using
- * parameters to ide_setup().
- */
- for (h = 0; h < MAX_HWIFS; ++h) {
- hwif = &ide_hwifs[h];
- if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) {
- if (hwif->chipset == ide_forced)
- return hwif; /* a perfect match */
- }
- }
- /*
- * Look for a hwif with matching io_base default value.
- * If chipset is "ide_unknown", then claim that hwif slot.
- * Otherwise, some other chipset has already claimed it.. :(
- */
- for (h = 0; h < MAX_HWIFS; ++h) {
- hwif = &ide_hwifs[h];
- if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) {
- if (hwif->chipset == ide_unknown)
- return hwif; /* match */
- printk(KERN_ERR "%s: port 0x%04lx already claimed by %s\n",
- name, io_base, hwif->name);
- return NULL; /* already claimed */
- }
- }
- /*
- * Okay, there is no hwif matching our io_base,
- * so we'll just claim an unassigned slot.
- * Give preference to claiming other slots before claiming ide0/ide1,
- * just in case there's another interface yet-to-be-scanned
- * which uses ports 1f0/170 (the ide0/ide1 defaults).
- *
- * Unless there is a bootable card that does not use the standard
- * ports 1f0/170 (the ide0/ide1 defaults). The (bootable) flag.
- */
- if (bootable) {
- for (h = 0; h < MAX_HWIFS; ++h) {
- hwif = &ide_hwifs[h];
- if (hwif->chipset == ide_unknown)
- return hwif; /* pick an unused entry */
- }
- } else {
- for (h = 2; h < MAX_HWIFS; ++h) {
- hwif = ide_hwifs + h;
- if (hwif->chipset == ide_unknown)
- return hwif; /* pick an unused entry */
- }
- }
- for (h = 0; h < 2 && h < MAX_HWIFS; ++h) {
- hwif = ide_hwifs + h;
- if (hwif->chipset == ide_unknown)
- return hwif; /* pick an unused entry */
- }
- printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", name);
- return NULL;
-}
-
/**
* ide_setup_pci_baseregs - place a PCI IDE controller native
* @dev: PCI device of interface to switch native
@@ -105,13 +27,13 @@ static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char
*
* We attempt to place the PCI interface into PCI native mode. If
* we succeed the BARs are ok and the controller is in PCI mode.
- * Returns 0 on success or an errno code.
+ * Returns 0 on success or an errno code.
*
* FIXME: if we program the interface and then fail to set the BARS
* we don't switch it back to legacy mode. Do we actually care ??
*/
-
-static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name)
+
+static int ide_setup_pci_baseregs(struct pci_dev *dev, const char *name)
{
u8 progif = 0;
@@ -150,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;
@@ -210,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)
@@ -218,7 +165,6 @@ void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d)
" PCI slot %s\n", d->name, dev->vendor, dev->device,
dev->revision, pci_name(dev));
}
-
EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
@@ -231,13 +177,13 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
* but if that fails then we only need IO space. The PCI code should
* have setup the proper resources for us already for controllers in
* legacy mode.
- *
+ *
* Returns zero on success or an error code
*/
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);
@@ -260,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;
+
+ if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
+ if (d->host_flags & IDE_HFLAG_CS5520)
+ bars |= (1 << 2);
+ else
+ bars |= (1 << 4);
+ }
- pci_release_region(dev, 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;
}
@@ -290,8 +244,8 @@ static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d)
* Maybe the user deliberately *disabled* the device,
* but we'll eventually ignore it again if no drives respond.
*/
- if (ide_setup_pci_baseregs(dev, d->name) || pci_write_config_word(dev, PCI_COMMAND, pcicmd|PCI_COMMAND_IO))
- {
+ if (ide_setup_pci_baseregs(dev, d->name) ||
+ pci_write_config_word(dev, PCI_COMMAND, pcicmd | PCI_COMMAND_IO)) {
printk(KERN_INFO "%s: device disabled (BIOS)\n", d->name);
return -ENODEV;
}
@@ -312,26 +266,24 @@ static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d)
* @d: IDE port info
* @bar: BAR number
*
- * Checks if a BAR is configured and points to MMIO space. If so
- * print an error and return an error code. Otherwise return 0
+ * Checks if a BAR is configured and points to MMIO space. If so,
+ * return an error code. Otherwise return 0
*/
-static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d, int bar)
+static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d,
+ int bar)
{
ulong flags = pci_resource_flags(dev, bar);
-
+
/* Unconfigured ? */
if (!flags || pci_resource_len(dev, bar) == 0)
return 0;
- /* I/O space */
- if(flags & PCI_BASE_ADDRESS_IO_MASK)
+ /* I/O space */
+ if (flags & IORESOURCE_IO)
return 0;
-
+
/* Bad */
- printk(KERN_ERR "%s: IO baseregs (BIOS) are reported "
- "as MEM, report to "
- "<andre@linux-ide.org>.\n", d->name);
return -EINVAL;
}
@@ -355,15 +307,16 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
{
unsigned long ctl = 0, base = 0;
ide_hwif_t *hwif;
- u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0;
- u8 oldnoprobe = 0;
struct hw_regs_s hw;
if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) {
- /* Possibly we should fail if these checks report true */
- ide_pci_check_iomem(dev, d, 2*port);
- ide_pci_check_iomem(dev, d, 2*port+1);
-
+ if (ide_pci_check_iomem(dev, d, 2 * port) ||
+ ide_pci_check_iomem(dev, d, 2 * port + 1)) {
+ printk(KERN_ERR "%s: I/O baseregs (BIOS) are reported "
+ "as MEM for port %d!\n", d->name, port);
+ return NULL;
+ }
+
ctl = pci_resource_start(dev, 2*port+1);
base = pci_resource_start(dev, 2*port);
if ((ctl && !base) || (base && !ctl)) {
@@ -372,31 +325,28 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
return NULL;
}
}
- if (!ctl)
- {
+ if (!ctl) {
/* Use default values */
ctl = port ? 0x374 : 0x3f4;
base = port ? 0x170 : 0x1f0;
}
- if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL)
- return NULL; /* no room in ide_hwifs[] */
+
+ hwif = ide_find_port_slot(d);
+ if (hwif == NULL) {
+ printk(KERN_ERR "%s: too many IDE interfaces, no room in "
+ "table\n", d->name);
+ return NULL;
+ }
memset(&hw, 0, sizeof(hw));
- hw.irq = hwif->irq ? hwif->irq : irq;
+ hw.irq = irq;
hw.dev = &dev->dev;
hw.chipset = d->chipset ? d->chipset : ide_pci;
ide_std_init_ports(&hw, base, ctl | 2);
- if (hwif->io_ports[IDE_DATA_OFFSET] == base &&
- hwif->io_ports[IDE_CONTROL_OFFSET] == (ctl | 2))
- oldnoprobe = hwif->noprobe;
-
ide_init_port_hw(hwif, &hw);
- hwif->noprobe = oldnoprobe;
-
hwif->dev = &dev->dev;
- hwif->cds = d;
return hwif;
}
@@ -412,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 */
@@ -532,7 +475,6 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int
*(idx + port) = hwif->index;
}
}
-
EXPORT_SYMBOL_GPL(ide_pci_setup_ports);
/*
@@ -615,7 +557,6 @@ int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d)
return ret;
}
-
EXPORT_SYMBOL_GPL(ide_setup_pci_device);
int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
@@ -639,5 +580,4 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
out:
return ret;
}
-
EXPORT_SYMBOL_GPL(ide_setup_pci_devices);