aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/Kconfig93
-rw-r--r--drivers/ide/Makefile11
-rw-r--r--drivers/ide/arm/Makefile1
-rw-r--r--drivers/ide/arm/bast-ide.c89
-rw-r--r--drivers/ide/arm/icside.c105
-rw-r--r--drivers/ide/arm/ide_arm.c1
-rw-r--r--drivers/ide/arm/palm_bk3710.c67
-rw-r--r--drivers/ide/arm/rapide.c33
-rw-r--r--drivers/ide/h8300/ide-h8300.c25
-rw-r--r--drivers/ide/ide-acpi.c6
-rw-r--r--drivers/ide/ide-atapi.c296
-rw-r--r--drivers/ide/ide-cd.c282
-rw-r--r--drivers/ide/ide-cd.h4
-rw-r--r--drivers/ide/ide-cd_ioctl.c113
-rw-r--r--drivers/ide/ide-disk.c14
-rw-r--r--drivers/ide/ide-dma.c4
-rw-r--r--drivers/ide/ide-floppy.c389
-rw-r--r--drivers/ide/ide-generic.c10
-rw-r--r--drivers/ide/ide-io.c186
-rw-r--r--drivers/ide/ide-iops.c62
-rw-r--r--drivers/ide/ide-lib.c151
-rw-r--r--drivers/ide/ide-pio-blacklist.c94
-rw-r--r--drivers/ide/ide-pnp.c5
-rw-r--r--drivers/ide/ide-probe.c47
-rw-r--r--drivers/ide/ide-proc.c3
-rw-r--r--drivers/ide/ide-tape.c569
-rw-r--r--drivers/ide/ide-taskfile.c77
-rw-r--r--drivers/ide/ide-timings.c (renamed from drivers/ide/ide-timing.h)205
-rw-r--r--drivers/ide/ide.c460
-rw-r--r--drivers/ide/legacy/ali14xx.c5
-rw-r--r--drivers/ide/legacy/buddha.c3
-rw-r--r--drivers/ide/legacy/falconide.c3
-rw-r--r--drivers/ide/legacy/gayle.c7
-rw-r--r--drivers/ide/legacy/hd.c815
-rw-r--r--drivers/ide/legacy/ht6560b.c17
-rw-r--r--drivers/ide/legacy/ide-4drives.c25
-rw-r--r--drivers/ide/legacy/ide-cs.c61
-rw-r--r--drivers/ide/legacy/ide_platform.c9
-rw-r--r--drivers/ide/legacy/macide.c3
-rw-r--r--drivers/ide/legacy/q40ide.c3
-rw-r--r--drivers/ide/legacy/qd65xx.c23
-rw-r--r--drivers/ide/mips/au1xxx-ide.c13
-rw-r--r--drivers/ide/mips/swarm.c28
-rw-r--r--drivers/ide/pci/aec62xx.c2
-rw-r--r--drivers/ide/pci/alim15x3.c8
-rw-r--r--drivers/ide/pci/amd74xx.c18
-rw-r--r--drivers/ide/pci/cmd640.c141
-rw-r--r--drivers/ide/pci/cmd64x.c10
-rw-r--r--drivers/ide/pci/cs5535.c6
-rw-r--r--drivers/ide/pci/cy82c693.c11
-rw-r--r--drivers/ide/pci/delkin_cb.c29
-rw-r--r--drivers/ide/pci/hpt366.c3
-rw-r--r--drivers/ide/pci/it8213.c3
-rw-r--r--drivers/ide/pci/it821x.c6
-rw-r--r--drivers/ide/pci/ns87415.c10
-rw-r--r--drivers/ide/pci/opti621.c221
-rw-r--r--drivers/ide/pci/scc_pata.c20
-rw-r--r--drivers/ide/pci/sgiioc4.c30
-rw-r--r--drivers/ide/pci/siimage.c28
-rw-r--r--drivers/ide/pci/sis5513.c8
-rw-r--r--drivers/ide/pci/sl82c105.c3
-rw-r--r--drivers/ide/pci/via82cxxx.c18
-rw-r--r--drivers/ide/ppc/Makefile1
-rw-r--r--drivers/ide/ppc/mpc8xx.c847
-rw-r--r--drivers/ide/ppc/pmac.c87
-rw-r--r--drivers/ide/setup-pci.c29
66 files changed, 1633 insertions, 4323 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index b4f3aefa12b6..15b09b89588a 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -98,6 +98,12 @@ if BLK_DEV_IDE
comment "Please see Documentation/ide/ide.txt for help/info on IDE drives"
+config IDE_TIMINGS
+ bool
+
+config IDE_ATAPI
+ bool
+
config BLK_DEV_IDE_SATA
bool "Support for SATA (deprecated; conflicts with libata SATA driver)"
default n
@@ -201,6 +207,7 @@ config BLK_DEV_IDECD_VERBOSE_ERRORS
config BLK_DEV_IDETAPE
tristate "Include IDE/ATAPI TAPE support"
+ select IDE_ATAPI
help
If you have an IDE tape drive using the ATAPI protocol, say Y.
ATAPI is a newer protocol used by IDE tape and CD-ROM drives,
@@ -223,6 +230,7 @@ config BLK_DEV_IDETAPE
config BLK_DEV_IDEFLOPPY
tristate "Include IDE/ATAPI FLOPPY support"
+ select IDE_ATAPI
---help---
If you have an IDE floppy drive which uses the ATAPI protocol,
answer Y. ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy
@@ -246,6 +254,7 @@ config BLK_DEV_IDEFLOPPY
config BLK_DEV_IDESCSI
tristate "SCSI emulation support"
depends on SCSI
+ select IDE_ATAPI
---help---
WARNING: ide-scsi is no longer needed for cd writing applications!
The 2.6 kernel supports direct writing to ide-cd, which eliminates
@@ -320,6 +329,7 @@ config BLK_DEV_PLATFORM
config BLK_DEV_CMD640
tristate "CMD640 chipset bugfix/support"
depends on X86
+ select IDE_TIMINGS
---help---
The CMD-Technologies CMD640 IDE chip is used on many common 486 and
Pentium motherboards, usually in combination with a "Neptune" or
@@ -449,6 +459,7 @@ config BLK_DEV_AEC62XX
config BLK_DEV_ALI15X3
tristate "ALI M15x3 chipset support"
+ select IDE_TIMINGS
select BLK_DEV_IDEDMA_PCI
help
This driver ensures (U)DMA support for ALI 1533, 1543 and 1543C
@@ -463,6 +474,7 @@ config BLK_DEV_ALI15X3
config BLK_DEV_AMD74XX
tristate "AMD and nVidia IDE support"
depends on !ARM
+ select IDE_TIMINGS
select BLK_DEV_IDEDMA_PCI
help
This driver adds explicit support for AMD-7xx and AMD-8111 chips
@@ -483,6 +495,7 @@ config BLK_DEV_ATIIXP
config BLK_DEV_CMD64X
tristate "CMD64{3|6|8|9} chipset support"
+ select IDE_TIMINGS
select BLK_DEV_IDEDMA_PCI
help
Say Y here if you have an IDE controller which uses any of these
@@ -497,6 +510,7 @@ config BLK_DEV_TRIFLEX
config BLK_DEV_CY82C693
tristate "CY82C693 chipset support"
+ select IDE_TIMINGS
select BLK_DEV_IDEDMA_PCI
help
This driver adds detection and support for the CY82C693 chipset
@@ -689,6 +703,7 @@ config BLK_DEV_SIS5513
config BLK_DEV_SL82C105
tristate "Winbond SL82c105 support"
depends on (PPC || ARM)
+ select IDE_TIMINGS
select BLK_DEV_IDEDMA_PCI
help
If you have a Winbond SL82c105 IDE controller, say Y here to enable
@@ -719,6 +734,7 @@ config BLK_DEV_TRM290
config BLK_DEV_VIA82CXXX
tristate "VIA82CXXX chipset support"
+ select IDE_TIMINGS
select BLK_DEV_IDEDMA_PCI
help
This driver adds explicit support for VIA BusMastering IDE chips.
@@ -745,6 +761,7 @@ endif
config BLK_DEV_IDE_PMAC
tristate "PowerMac on-board IDE support"
depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y
+ select IDE_TIMINGS
help
This driver provides support for the on-board IDE controller on
most of the recent Apple Power Macintoshes and PowerBooks.
@@ -823,13 +840,6 @@ config BLK_DEV_IDE_RAPIDE
Say Y here if you want to support the Yellowstone RapIDE controller
manufactured for use with Acorn computers.
-config BLK_DEV_IDE_BAST
- tristate "Simtec BAST / Thorcom VR1000 IDE support"
- depends on ARM && (ARCH_BAST || MACH_VR1000)
- help
- Say Y here if you want to support the onboard IDE channels on the
- Simtec BAST or the Thorcom VR1000
-
config IDE_H8300
tristate "H8300 IDE support"
depends on H8300
@@ -913,51 +923,12 @@ config BLK_DEV_Q40IDE
config BLK_DEV_PALMCHIP_BK3710
tristate "Palmchip bk3710 IDE controller support"
depends on ARCH_DAVINCI
+ select IDE_TIMINGS
select BLK_DEV_IDEDMA_SFF
help
Say Y here if you want to support the onchip IDE controller on the
TI DaVinci SoC
-
-config BLK_DEV_MPC8xx_IDE
- tristate "MPC8xx IDE support"
- depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE
- help
- This option provides support for IDE on Motorola MPC8xx Systems.
- Please see 'Type of MPC8xx IDE interface' for details.
-
- If unsure, say N.
-
-choice
- prompt "Type of MPC8xx IDE interface"
- depends on BLK_DEV_MPC8xx_IDE
- default IDE_8xx_PCCARD
-
-config IDE_8xx_PCCARD
- bool "8xx_PCCARD"
- ---help---
- Select how the IDE devices are connected to the MPC8xx system:
-
- 8xx_PCCARD uses the 8xx internal PCMCIA interface in combination
- with a PC Card (e.g. ARGOSY portable Hard Disk Adapter),
- ATA PC Card HDDs or ATA PC Flash Cards (example: TQM8xxL
- systems)
-
- 8xx_DIRECT is used for directly connected IDE devices using the 8xx
- internal PCMCIA interface (example: IVMS8 systems)
-
- EXT_DIRECT is used for IDE devices directly connected to the 8xx
- bus using some glue logic, but _not_ the 8xx internal
- PCMCIA interface (example: IDIF860 systems)
-
-config IDE_8xx_DIRECT
- bool "8xx_DIRECT"
-
-config IDE_EXT_DIRECT
- bool "EXT_DIRECT"
-
-endchoice
-
# no isa -> no vlb
if ISA && (ALPHA || X86 || MIPS)
@@ -975,6 +946,7 @@ config BLK_DEV_4DRIVES
config BLK_DEV_ALI14XX
tristate "ALI M14xx support"
+ select IDE_TIMINGS
help
This driver is enabled at runtime using the "ali14xx.probe" kernel
boot parameter. It enables support for the secondary IDE interface
@@ -994,6 +966,7 @@ config BLK_DEV_DTC2278
config BLK_DEV_HT6560B
tristate "Holtek HT6560B support"
+ select IDE_TIMINGS
help
This driver is enabled at runtime using the "ht6560b.probe" kernel
boot parameter. It enables support for the secondary IDE interface
@@ -1003,6 +976,7 @@ config BLK_DEV_HT6560B
config BLK_DEV_QD65XX
tristate "QDI QD65xx support"
+ select IDE_TIMINGS
help
This driver is enabled at runtime using the "qd65xx.probe" kernel
boot parameter. It permits faster I/O speeds to be set. See the
@@ -1026,29 +1000,4 @@ config BLK_DEV_IDEDMA
endif
-config BLK_DEV_HD_ONLY
- bool "Old hard disk (MFM/RLL/IDE) driver"
- 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
- reasons. Some older systems have strange timing problems and seem to
- work only with the old driver (which itself does not work with some
- newer systems). The other reason is that the old driver is smaller,
- since it lacks the enhanced functionality of the new one. This makes
- it a good choice for systems with very tight memory restrictions, or
- 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_ONLY
-
endif # IDE
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index f94b679b611e..5d414e301a5a 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -11,9 +11,12 @@
EXTRA_CFLAGS += -Idrivers/ide
-ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o
+ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o \
+ ide-pio-blacklist.o
# core IDE code
+ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o
+ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o
ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o
ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o
ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o
@@ -58,9 +61,3 @@ ifeq ($(CONFIG_BLK_DEV_PLATFORM), y)
endif
obj-$(CONFIG_BLK_DEV_IDE) += arm/ mips/
-
-# old hd driver must be last
-ifeq ($(CONFIG_BLK_DEV_HD), y)
- hd-core-y += legacy/hd.o
- obj-y += hd-core.o
-endif
diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile
index 936e7b0237f5..5bc26053afa6 100644
--- a/drivers/ide/arm/Makefile
+++ b/drivers/ide/arm/Makefile
@@ -1,7 +1,6 @@
obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o
obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o
-obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o
obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o
ifeq ($(CONFIG_IDE_ARM), m)
diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c
deleted file mode 100644
index 713cef20622e..000000000000
--- a/drivers/ide/arm/bast-ide.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2003-2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/ide.h>
-#include <linux/init.h>
-
-#include <asm/mach-types.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/arch/map.h>
-#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;
- hw_regs_t hw;
- int i;
- u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-
- memset(&hw, 0, sizeof(hw));
-
- base += BAST_IDE_CS;
- aux += BAST_IDE_CS;
-
- for (i = 0; i <= 7; i++) {
- hw.io_ports_array[i] = (unsigned long)base;
- base += 0x20;
- }
-
- hw.io_ports.ctl_addr = aux + (6 * 0x20);
- hw.irq = irq;
-
- hwif = ide_find_port();
- if (hwif == NULL)
- goto out;
-
- i = hwif->index;
-
- ide_init_port_data(hwif, i);
- ide_init_port_hw(hwif, &hw);
- hwif->port_ops = NULL;
-
- idx[0] = i;
-
- ide_device_add(idx, NULL);
-out:
- return 0;
-}
-
-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()))
- return 0;
-
- 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);
-
- return 0;
-}
-
-module_init(bastide_init);
-
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Simtec BAST / Thorcom VR1000 IDE driver");
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index 061456914ca3..52f58c885783 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -21,6 +21,8 @@
#include <asm/dma.h>
#include <asm/ecard.h>
+#define DRV_NAME "icside"
+
#define ICS_IDENT_OFFSET 0x2280
#define ICS_ARCIN_V5_INTRSTAT 0x0000
@@ -68,6 +70,7 @@ struct icside_state {
unsigned int enabled;
void __iomem *irq_port;
void __iomem *ioc_base;
+ unsigned int sel;
unsigned int type;
ide_hwif_t *hwif[2];
};
@@ -165,7 +168,8 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = {
static void icside_maskproc(ide_drive_t *drive, int mask)
{
ide_hwif_t *hwif = HWIF(drive);
- struct icside_state *state = hwif->hwif_data;
+ struct expansion_card *ec = ECARD_DEV(hwif->dev);
+ struct icside_state *state = ecard_get_drvdata(ec);
unsigned long flags;
local_irq_save(flags);
@@ -308,6 +312,7 @@ static int icside_dma_setup(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct expansion_card *ec = ECARD_DEV(hwif->dev);
+ struct icside_state *state = ecard_get_drvdata(ec);
struct request *rq = hwif->hwgroup->rq;
unsigned int dma_mode;
@@ -331,7 +336,7 @@ static int icside_dma_setup(ide_drive_t *drive)
/*
* Route the DMA signals to the correct interface.
*/
- writeb(hwif->select_data, hwif->config_data);
+ writeb(state->sel | hwif->channel, state->ioc_base);
/*
* Select the correct timing for this drive.
@@ -359,7 +364,8 @@ static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd)
static int icside_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
- struct icside_state *state = hwif->hwif_data;
+ struct expansion_card *ec = ECARD_DEV(hwif->dev);
+ struct icside_state *state = ecard_get_drvdata(ec);
return readb(state->irq_port +
(hwif->channel ?
@@ -411,36 +417,24 @@ 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)
+static void icside_setup_ports(hw_regs_t *hw, 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();
- if (hwif) {
- /*
- * Ensure we're using MMIO
- */
- default_hwif_mmiops(hwif);
-
- 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->chipset = ide_acorn;
- hwif->gendev.parent = &ec->dev;
- hwif->dev = &ec->dev;
- }
-
- return hwif;
+ hw->io_ports.data_addr = port;
+ hw->io_ports.error_addr = port + (1 << info->stepping);
+ hw->io_ports.nsect_addr = port + (2 << info->stepping);
+ hw->io_ports.lbal_addr = port + (3 << info->stepping);
+ hw->io_ports.lbam_addr = port + (4 << info->stepping);
+ hw->io_ports.lbah_addr = port + (5 << info->stepping);
+ hw->io_ports.device_addr = port + (6 << info->stepping);
+ hw->io_ports.status_addr = port + (7 << info->stepping);
+ hw->io_ports.ctl_addr = (unsigned long)base + info->ctrloffset;
+
+ hw->irq = ec->irq;
+ hw->dev = &ec->dev;
+ hw->chipset = ide_acorn;
}
static int __init
@@ -449,6 +443,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
ide_hwif_t *hwif;
void __iomem *base;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+ hw_regs_t hw;
base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
if (!base)
@@ -466,12 +461,19 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
*/
icside_irqdisable_arcin_v5(ec, 0);
- hwif = icside_setup(base, &icside_cardinfo_v5, ec);
+ icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec);
+
+ hwif = ide_find_port();
if (!hwif)
return -ENODEV;
+ ide_init_port_hw(hwif, &hw);
+ default_hwif_mmiops(hwif);
+
state->hwif[0] = hwif;
+ ecard_set_drvdata(ec, state);
+
idx[0] = hwif->index;
ide_device_add(idx, NULL);
@@ -497,6 +499,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
int ret;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
struct ide_port_info d = icside_v6_port_info;
+ hw_regs_t hw[2];
ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
if (!ioc_base) {
@@ -525,43 +528,47 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
state->irq_port = easi_base;
state->ioc_base = ioc_base;
+ state->sel = sel;
/*
* Be on the safe side - disable interrupts
*/
icside_irqdisable_arcin_v6(ec, 0);
+ icside_setup_ports(&hw[0], easi_base, &icside_cardinfo_v6_1, ec);
+ icside_setup_ports(&hw[1], easi_base, &icside_cardinfo_v6_2, ec);
+
/*
* Find and register the interfaces.
*/
- hwif = icside_setup(easi_base, &icside_cardinfo_v6_1, ec);
- mate = icside_setup(easi_base, &icside_cardinfo_v6_2, ec);
+ hwif = ide_find_port();
+ if (hwif == NULL)
+ return -ENODEV;
- if (!hwif || !mate) {
- ret = -ENODEV;
- goto out;
+ ide_init_port_hw(hwif, &hw[0]);
+ default_hwif_mmiops(hwif);
+
+ idx[0] = hwif->index;
+
+ mate = ide_find_port();
+ if (mate) {
+ ide_init_port_hw(mate, &hw[1]);
+ default_hwif_mmiops(mate);
+
+ idx[1] = mate->index;
}
state->hwif[0] = hwif;
state->hwif[1] = mate;
- hwif->hwif_data = state;
- hwif->config_data = (unsigned long)ioc_base;
- hwif->select_data = sel;
-
- mate->hwif_data = state;
- mate->config_data = (unsigned long)ioc_base;
- mate->select_data = sel | 1;
+ ecard_set_drvdata(ec, state);
- if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) {
+ if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) {
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;
-
ide_device_add(idx, &d);
return 0;
@@ -627,10 +634,8 @@ icside_probe(struct expansion_card *ec, const struct ecard_id *id)
break;
}
- if (ret == 0) {
- ecard_set_drvdata(ec, state);
+ if (ret == 0)
goto out;
- }
kfree(state);
release:
diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c
index 4263ffd4ab20..2f311da4c963 100644
--- a/drivers/ide/arm/ide_arm.c
+++ b/drivers/ide/arm/ide_arm.c
@@ -49,6 +49,7 @@ static int __init ide_arm_init(void)
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, base, ctl);
hw.irq = IDE_ARM_IRQ;
+ hw.chipset = ide_generic;
hwif = ide_find_port();
if (hwif) {
diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c
index 96378ebfb31f..c79b85b6e4a3 100644
--- a/drivers/ide/arm/palm_bk3710.c
+++ b/drivers/ide/arm/palm_bk3710.c
@@ -74,20 +74,16 @@ struct palm_bk3710_udmatiming {
#define BK3710_IORDYTMP 0x78
#define BK3710_IORDYTMS 0x7C
-#include "../ide-timing.h"
-
-static long ide_palm_clk;
+static unsigned ideclk_period; /* in nanoseconds */
static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = {
{160, 240}, /* UDMA Mode 0 */
{125, 160}, /* UDMA Mode 1 */
{100, 120}, /* UDMA Mode 2 */
{100, 90}, /* UDMA Mode 3 */
- {85, 60}, /* UDMA Mode 4 */
+ {100, 60}, /* UDMA Mode 4 */
};
-static struct clk *ideclkp;
-
static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
unsigned int mode)
{
@@ -97,10 +93,10 @@ static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
/* DMA Data Setup */
t0 = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].cycletime,
- ide_palm_clk) - 1;
- tenv = DIV_ROUND_UP(20, ide_palm_clk) - 1;
+ ideclk_period) - 1;
+ tenv = DIV_ROUND_UP(20, ideclk_period) - 1;
trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime,
- ide_palm_clk) - 1;
+ ideclk_period) - 1;
/* udmatim Register */
val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0);
@@ -141,8 +137,8 @@ static void palm_bk3710_setdmamode(void __iomem *base, unsigned int dev,
cycletime = max_t(int, t->cycle, min_cycle);
/* DMA Data Setup */
- t0 = DIV_ROUND_UP(cycletime, ide_palm_clk);
- td = DIV_ROUND_UP(t->active, ide_palm_clk);
+ t0 = DIV_ROUND_UP(cycletime, ideclk_period);
+ td = DIV_ROUND_UP(t->active, ideclk_period);
tkw = t0 - td - 1;
td -= 1;
@@ -168,9 +164,9 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
struct ide_timing *t;
/* PIO Data Setup */
- t0 = DIV_ROUND_UP(cycletime, ide_palm_clk);
+ t0 = DIV_ROUND_UP(cycletime, ideclk_period);
t2 = DIV_ROUND_UP(ide_timing_find_mode(XFER_PIO_0 + mode)->active,
- ide_palm_clk);
+ ideclk_period);
t2i = t0 - t2 - 1;
t2 -= 1;
@@ -192,8 +188,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 = DIV_ROUND_UP(t->cyc8b, ide_palm_clk);
- t2 = DIV_ROUND_UP(t->act8b, ide_palm_clk);
+ t0 = DIV_ROUND_UP(t->cyc8b, ideclk_period);
+ t2 = DIV_ROUND_UP(t->act8b, ideclk_period);
t2i = t0 - t2 - 1;
t2 -= 1;
@@ -350,22 +346,22 @@ static const struct ide_port_info __devinitdata palm_bk3710_port_info = {
static int __devinit palm_bk3710_probe(struct platform_device *pdev)
{
- struct clk *clkp;
+ struct clk *clk;
struct resource *mem, *irq;
ide_hwif_t *hwif;
- void __iomem *base;
- int pribase, i;
+ unsigned long base, rate;
+ int i;
hw_regs_t hw;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
- clkp = clk_get(NULL, "IDECLK");
- if (IS_ERR(clkp))
+ clk = clk_get(NULL, "IDECLK");
+ if (IS_ERR(clk))
return -ENODEV;
- ideclkp = clkp;
- clk_enable(ideclkp);
- ide_palm_clk = clk_get_rate(ideclkp)/100000;
- ide_palm_clk = (10000/ide_palm_clk) + 1;
+ clk_enable(clk);
+ rate = clk_get_rate(clk);
+ ideclk_period = 1000000000UL / rate;
+
/* Register the IDE interface with Linux ATA Interface */
memset(&hw, 0, sizeof(hw));
@@ -374,22 +370,27 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev)
printk(KERN_ERR "failed to get memory region resource\n");
return -ENODEV;
}
+
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (irq == NULL) {
printk(KERN_ERR "failed to get IRQ resource\n");
return -ENODEV;
}
- base = (void *)mem->start;
+ if (request_mem_region(mem->start, mem->end - mem->start + 1,
+ "palm_bk3710") == NULL) {
+ printk(KERN_ERR "failed to request memory region\n");
+ return -EBUSY;
+ }
+
+ base = IO_ADDRESS(mem->start);
/* Configure the Palm Chip controller */
- palm_bk3710_chipinit(base);
+ palm_bk3710_chipinit((void __iomem *)base);
- pribase = mem->start + IDE_PALM_ATA_PRI_REG_OFFSET;
for (i = 0; i < IDE_NR_PORTS - 2; i++)
- hw.io_ports_array[i] = pribase + i;
- hw.io_ports.ctl_addr = mem->start +
- IDE_PALM_ATA_PRI_CTL_OFFSET;
+ hw.io_ports_array[i] = base + IDE_PALM_ATA_PRI_REG_OFFSET + i;
+ hw.io_ports.ctl_addr = base + IDE_PALM_ATA_PRI_CTL_OFFSET;
hw.irq = irq->start;
hw.chipset = ide_palm3710;
@@ -399,19 +400,14 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev)
i = hwif->index;
- ide_init_port_data(hwif, i);
ide_init_port_hw(hwif, &hw);
- hwif->mmio = 1;
default_hwif_mmiops(hwif);
idx[0] = i;
ide_device_add(idx, &palm_bk3710_port_info);
- if (!hwif->present)
- goto out;
-
return 0;
out:
printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n");
@@ -437,4 +433,3 @@ static int __init palm_bk3710_init(void)
module_init(palm_bk3710_init);
MODULE_LICENSE("GPL");
-
diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c
index 1747b2358775..43057e0303c8 100644
--- a/drivers/ide/arm/rapide.c
+++ b/drivers/ide/arm/rapide.c
@@ -11,6 +11,10 @@
#include <asm/ecard.h>
+static struct const ide_port_info rapide_port_info = {
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+};
+
static void rapide_setup_ports(hw_regs_t *hw, void __iomem *base,
void __iomem *ctrl, unsigned int sz, int irq)
{
@@ -44,25 +48,26 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
goto release;
}
- hwif = ide_find_port();
- if (hwif) {
- memset(&hw, 0, sizeof(hw));
- rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq);
- hw.chipset = ide_generic;
- hw.dev = &ec->dev;
+ memset(&hw, 0, sizeof(hw));
+ rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq);
+ hw.chipset = ide_generic;
+ hw.dev = &ec->dev;
- ide_init_port_hw(hwif, &hw);
+ hwif = ide_find_port();
+ if (hwif == NULL) {
+ ret = -ENOENT;
+ goto release;
+ }
- hwif->host_flags = IDE_HFLAG_MMIO;
- default_hwif_mmiops(hwif);
+ ide_init_port_hw(hwif, &hw);
+ default_hwif_mmiops(hwif);
- idx[0] = hwif->index;
+ idx[0] = hwif->index;
- ide_device_add(idx, NULL);
+ ide_device_add(idx, &rapide_port_info);
- ecard_set_drvdata(ec, hwif);
- goto out;
- }
+ ecard_set_drvdata(ec, hwif);
+ goto out;
release:
ecard_release_resources(ec);
diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c
index ecf53bb0d2aa..20fad6d542cc 100644
--- a/drivers/ide/h8300/ide-h8300.c
+++ b/drivers/ide/h8300/ide-h8300.c
@@ -8,6 +8,8 @@
#include <asm/io.h>
#include <asm/irq.h>
+#define DRV_NAME "ide-h8300"
+
#define bswap(d) \
({ \
u16 r; \
@@ -52,8 +54,6 @@ static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task)
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);
@@ -98,7 +98,7 @@ static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task)
}
/* be sure we're looking at the low order bits */
- outb(drive->ctl & ~0x80, io_ports->ctl_addr);
+ outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
@@ -112,7 +112,7 @@ static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task)
tf->device = inb(io_ports->device_addr);
if (task->tf_flags & IDE_TFLAG_LBA48) {
- outb(drive->ctl | 0x80, io_ports->ctl_addr);
+ outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = inb(io_ports->feature_addr);
@@ -178,6 +178,10 @@ static inline void hwif_setup(ide_hwif_t *hwif)
hwif->output_data = h8300_output_data;
}
+static const struct ide_port_info h8300_port_info = {
+ .host_flags = IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_NO_DMA,
+};
+
static int __init h8300_ide_init(void)
{
hw_regs_t hw;
@@ -185,6 +189,8 @@ static int __init h8300_ide_init(void)
int index;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+ printk(KERN_INFO DRV_NAME ": H8/300 generic IDE interface\n");
+
if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300"))
goto out_busy;
if (!request_region(CONFIG_H8300_IDE_ALT, H8300_IDE_GAP, "ide-h8300")) {
@@ -194,22 +200,17 @@ static int __init h8300_ide_init(void)
hw_setup(&hw);
- hwif = ide_find_port();
- if (hwif == NULL) {
- printk(KERN_ERR "ide-h8300: IDE I/F register failed\n");
+ hwif = ide_find_port_slot(&h8300_port_info);
+ if (hwif == NULL)
return -ENOENT;
- }
index = hwif->index;
- ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
hwif_setup(hwif);
- hwif->host_flags = IDE_HFLAG_NO_IO_32BIT;
- printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", index);
idx[0] = index;
- ide_device_add(idx, NULL);
+ ide_device_add(idx, &h8300_port_info);
return 0;
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index 9d3601fa5680..6f704628c27d 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -60,15 +60,15 @@ struct ide_acpi_hwif_link {
#define DEBPRINT(fmt, args...) do {} while (0)
#endif /* DEBUGGING */
-int ide_noacpi;
+static int ide_noacpi;
module_param_named(noacpi, ide_noacpi, bool, 0);
MODULE_PARM_DESC(noacpi, "disable IDE ACPI support");
-int ide_acpigtf;
+static int ide_acpigtf;
module_param_named(acpigtf, ide_acpigtf, bool, 0);
MODULE_PARM_DESC(acpigtf, "enable IDE ACPI _GTF support");
-int ide_acpionboot;
+static int ide_acpionboot;
module_param_named(acpionboot, ide_acpionboot, bool, 0);
MODULE_PARM_DESC(acpionboot, "call IDE ACPI methods on boot");
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
new file mode 100644
index 000000000000..2802031de670
--- /dev/null
+++ b/drivers/ide/ide-atapi.c
@@ -0,0 +1,296 @@
+/*
+ * ATAPI support.
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <scsi/scsi.h>
+
+#ifdef DEBUG
+#define debug_log(fmt, args...) \
+ printk(KERN_INFO "ide: " fmt, ## args)
+#else
+#define debug_log(fmt, args...) do {} while (0)
+#endif
+
+/* TODO: unify the code thus making some arguments go away */
+ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
+ ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
+ void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
+ void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *),
+ void (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))
+{
+ ide_hwif_t *hwif = drive->hwif;
+ xfer_func_t *xferfunc;
+ unsigned int temp;
+ u16 bcount;
+ u8 stat, ireason, scsi = drive->scsi;
+
+ debug_log("Enter %s - interrupt handler\n", __func__);
+
+ if (pc->flags & PC_FLAG_TIMEDOUT) {
+ pc->callback(drive);
+ return ide_stopped;
+ }
+
+ /* Clear the interrupt */
+ stat = ide_read_status(drive);
+
+ if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
+ if (hwif->dma_ops->dma_end(drive) ||
+ (drive->media == ide_tape && !scsi && (stat & ERR_STAT))) {
+ if (drive->media == ide_floppy && !scsi)
+ printk(KERN_ERR "%s: DMA %s error\n",
+ drive->name, rq_data_dir(pc->rq)
+ ? "write" : "read");
+ pc->flags |= PC_FLAG_DMA_ERROR;
+ } else {
+ pc->xferred = pc->req_xfer;
+ if (update_buffers)
+ update_buffers(drive, pc);
+ }
+ debug_log("%s: DMA finished\n", drive->name);
+ }
+
+ /* No more interrupts */
+ if ((stat & DRQ_STAT) == 0) {
+ debug_log("Packet command completed, %d bytes transferred\n",
+ pc->xferred);
+
+ pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
+
+ local_irq_enable_in_hardirq();
+
+ if (drive->media == ide_tape && !scsi &&
+ (stat & ERR_STAT) && pc->c[0] == REQUEST_SENSE)
+ stat &= ~ERR_STAT;
+ if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
+ /* Error detected */
+ debug_log("%s: I/O error\n", drive->name);
+
+ if (drive->media != ide_tape || scsi) {
+ pc->rq->errors++;
+ if (scsi)
+ goto cmd_finished;
+ }
+
+ if (pc->c[0] == REQUEST_SENSE) {
+ printk(KERN_ERR "%s: I/O error in request sense"
+ " command\n", drive->name);
+ return ide_do_reset(drive);
+ }
+
+ debug_log("[cmd %x]: check condition\n", pc->c[0]);
+
+ /* Retry operation */
+ retry_pc(drive);
+ /* queued, but not started */
+ return ide_stopped;
+ }
+cmd_finished:
+ pc->error = 0;
+ if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) &&
+ (stat & SEEK_STAT) == 0) {
+ dsc_handle(drive);
+ return ide_stopped;
+ }
+ /* Command finished - Call the callback function */
+ pc->callback(drive);
+ return ide_stopped;
+ }
+
+ if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
+ pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
+ printk(KERN_ERR "%s: The device wants to issue more interrupts "
+ "in DMA mode\n", drive->name);
+ ide_dma_off(drive);
+ return ide_do_reset(drive);
+ }
+ /* Get the number of bytes to transfer on this interrupt. */
+ bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
+ hwif->INB(hwif->io_ports.lbam_addr);
+
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
+
+ if (ireason & CD) {
+ printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__);
+ return ide_do_reset(drive);
+ }
+ if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
+ /* Hopefully, we will never get here */
+ printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
+ "to %s!\n", drive->name,
+ (ireason & IO) ? "Write" : "Read",
+ (ireason & IO) ? "Read" : "Write");
+ return ide_do_reset(drive);
+ }
+ if (!(pc->flags & PC_FLAG_WRITING)) {
+ /* Reading - Check that we have enough space */
+ temp = pc->xferred + bcount;
+ if (temp > pc->req_xfer) {
+ if (temp > pc->buf_size) {
+ printk(KERN_ERR "%s: The device wants to send "
+ "us more data than expected - "
+ "discarding data\n",
+ drive->name);
+ if (scsi)
+ temp = pc->buf_size - pc->xferred;
+ else
+ temp = 0;
+ if (temp) {
+ if (pc->sg)
+ io_buffers(drive, pc, temp, 0);
+ else
+ hwif->input_data(drive, NULL,
+ pc->cur_pos, temp);
+ printk(KERN_ERR "%s: transferred %d of "
+ "%d bytes\n",
+ drive->name,
+ temp, bcount);
+ }
+ pc->xferred += temp;
+ pc->cur_pos += temp;
+ ide_pad_transfer(drive, 0, bcount - temp);
+ ide_set_handler(drive, handler, timeout,
+ expiry);
+ return ide_started;
+ }
+ debug_log("The device wants to send us more data than "
+ "expected - allowing transfer\n");
+ }
+ xferfunc = hwif->input_data;
+ } else
+ xferfunc = hwif->output_data;
+
+ if ((drive->media == ide_floppy && !scsi && !pc->buf) ||
+ (drive->media == ide_tape && !scsi && pc->bh) ||
+ (scsi && pc->sg))
+ io_buffers(drive, pc, bcount, !!(pc->flags & PC_FLAG_WRITING));
+ else
+ xferfunc(drive, NULL, pc->cur_pos, bcount);
+
+ /* Update the current position */
+ pc->xferred += bcount;
+ pc->cur_pos += bcount;
+
+ debug_log("[cmd %x] transferred %d bytes on that intr.\n",
+ pc->c[0], bcount);
+
+ /* And set the interrupt handler again */
+ ide_set_handler(drive, handler, timeout, expiry);
+ return ide_started;
+}
+EXPORT_SYMBOL_GPL(ide_pc_intr);
+
+static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ int retries = 100;
+
+ while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) {
+ printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
+ "a packet command, retrying\n", drive->name);
+ udelay(100);
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
+ if (retries == 0) {
+ printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
+ "a packet command, ignoring\n",
+ drive->name);
+ ireason |= CD;
+ ireason &= ~IO;
+ }
+ }
+
+ return ireason;
+}
+
+ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
+ ide_handler_t *handler, unsigned int timeout,
+ ide_expiry_t *expiry)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ ide_startstop_t startstop;
+ u8 ireason;
+
+ if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
+ printk(KERN_ERR "%s: Strange, packet command initiated yet "
+ "DRQ isn't asserted\n", drive->name);
+ return startstop;
+ }
+
+ ireason = hwif->INB(hwif->io_ports.nsect_addr);
+ if (drive->media == ide_tape && !drive->scsi)
+ ireason = ide_wait_ireason(drive, ireason);
+
+ if ((ireason & CD) == 0 || (ireason & IO)) {
+ printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing "
+ "a packet command\n", drive->name);
+ return ide_do_reset(drive);
+ }
+
+ /* Set the interrupt routine */
+ ide_set_handler(drive, handler, timeout, expiry);
+
+ /* Begin DMA, if necessary */
+ if (pc->flags & PC_FLAG_DMA_OK) {
+ pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
+ hwif->dma_ops->dma_start(drive);
+ }
+
+ /* Send the actual packet */
+ if ((pc->flags & PC_FLAG_ZIP_DRIVE) == 0)
+ hwif->output_data(drive, NULL, pc->c, 12);
+
+ return ide_started;
+}
+EXPORT_SYMBOL_GPL(ide_transfer_pc);
+
+ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
+ ide_handler_t *handler, unsigned int timeout,
+ ide_expiry_t *expiry)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u16 bcount;
+ u8 dma = 0;
+
+ /* We haven't transferred any data yet */
+ pc->xferred = 0;
+ pc->cur_pos = pc->buf;
+
+ /* Request to transfer the entire buffer at once */
+ if (drive->media == ide_tape && !drive->scsi)
+ bcount = pc->req_xfer;
+ else
+ bcount = min(pc->req_xfer, 63 * 1024);
+
+ if (pc->flags & PC_FLAG_DMA_ERROR) {
+ pc->flags &= ~PC_FLAG_DMA_ERROR;
+ ide_dma_off(drive);
+ }
+
+ if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) {
+ if (drive->scsi)
+ hwif->sg_mapped = 1;
+ dma = !hwif->dma_ops->dma_setup(drive);
+ if (drive->scsi)
+ hwif->sg_mapped = 0;
+ }
+
+ if (!dma)
+ pc->flags &= ~PC_FLAG_DMA_OK;
+
+ ide_pktcmd_tf_load(drive, drive->scsi ? 0 : IDE_TFLAG_OUT_DEVICE,
+ bcount, dma);
+
+ /* Issue the packet command */
+ if (pc->flags & PC_FLAG_DRQ_INTERRUPT) {
+ ide_execute_command(drive, WIN_PACKETCMD, handler,
+ timeout, NULL);
+ return ide_started;
+ } else {
+ ide_execute_pkt_cmd(drive);
+ return (*handler)(drive);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_issue_pc);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 68e7f19dc036..6e29dd532090 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -188,16 +188,6 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
ide_cd_log_error(drive->name, failed_command, sense);
}
-/* 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;
-
- ide_init_drive_cmd(rq);
- rq->cmd_type = REQ_TYPE_ATA_PC;
- rq->rq_disk = cd->disk;
-}
-
static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
struct request *failed_command)
{
@@ -208,7 +198,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
sense = &info->sense_data;
/* stuff the sense request in front of our current request */
- ide_cd_init_rq(drive, rq);
+ blk_rq_init(NULL, rq);
+ rq->cmd_type = REQ_TYPE_ATA_PC;
+ rq->rq_disk = info->disk;
rq->data = sense;
rq->cmd[0] = GPCMD_REQUEST_SENSE;
@@ -216,11 +208,12 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
rq->data_len = 18;
rq->cmd_type = REQ_TYPE_SENSE;
+ rq->cmd_flags |= REQ_PREEMPT;
/* NOTE! Save the failed command in "rq->buffer" */
rq->buffer = (void *) failed_command;
- (void) ide_do_drive_cmd(drive, rq, ide_preempt);
+ ide_do_drive_cmd(drive, rq);
}
static void cdrom_end_request(ide_drive_t *drive, int uptodate)
@@ -524,21 +517,16 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
int xferlen,
ide_handler_t *handler)
{
- ide_startstop_t startstop;
struct cdrom_info *info = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
- /* 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_ops->dma_setup(drive);
/* 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);
+ ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL,
+ xferlen, info->dma);
if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) {
/* waiting for CDB interrupt, not DMA yet. */
@@ -611,28 +599,6 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
}
/*
- * 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, NULL, &dum, sizeof(dum));
- len -= sizeof(dum);
- }
-}
-
-static void ide_cd_drain_data(ide_drive_t *drive, int nsects)
-{
- while (nsects > 0) {
- static char dum[SECTOR_SIZE];
-
- drive->hwif->input_data(drive, NULL, dum, sizeof(dum));
- nsects--;
- }
-}
-
-/*
* 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.
@@ -647,15 +613,12 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
if (ireason == (!rw << 1))
return 0;
else if (ireason == (rw << 1)) {
- ide_hwif_t *hwif = drive->hwif;
- xfer_func_t *xf;
/* whoops... */
printk(KERN_ERR "%s: %s: wrong transfer direction!\n",
drive->name, __func__);
- xf = rw ? hwif->output_data : hwif->input_data;
- ide_cd_pad_transfer(drive, xf, len);
+ ide_pad_transfer(drive, rw, len);
} else if (rw == 0 && ireason == 1) {
/*
* Some drives (ASUS) seem to tell us that status info is
@@ -703,16 +666,9 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);
-/*
- * Routine to send a read/write packet command to the drive. This is usually
- * called directly from cdrom_start_{read,write}(). However, for drq_interrupt
- * devices, it is called from an interrupt when the drive is ready to accept
- * the command.
- */
-static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
+static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
+ struct request *rq)
{
- struct request *rq = HWGROUP(drive)->rq;
-
if (rq_data_dir(rq) == READ) {
unsigned short sectors_per_frame =
queue_hardsect_size(drive->queue) >> SECTOR_BITS;
@@ -749,6 +705,19 @@ static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
/* set up the command */
rq->timeout = ATAPI_WAIT_PC;
+ return ide_started;
+}
+
+/*
+ * 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)
+{
+ struct request *rq = drive->hwif->hwgroup->rq;
+
/* send the command to the drive and return */
return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
}
@@ -775,9 +744,8 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive)
return ide_stopped;
}
-static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive)
+static void ide_cd_prepare_seek_request(ide_drive_t *drive, struct request *rq)
{
- struct request *rq = HWGROUP(drive)->rq;
sector_t frame = rq->sector;
sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS);
@@ -787,17 +755,13 @@ static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive)
put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]);
rq->timeout = ATAPI_WAIT_PC;
- 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_continuation(ide_drive_t *drive)
{
- struct cdrom_info *info = drive->driver_data;
+ struct request *rq = drive->hwif->hwgroup->rq;
- info->dma = 0;
- info->start_seek = jiffies;
- return cdrom_start_packet_command(drive, 0,
- cdrom_start_seek_continuation);
+ return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr);
}
/*
@@ -838,34 +802,54 @@ static void ide_cd_request_sense_fixup(struct request *rq)
}
}
-int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq)
+int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
+ int write, void *buffer, unsigned *bufflen,
+ struct request_sense *sense, int timeout,
+ unsigned int cmd_flags)
{
- struct request_sense sense;
+ struct cdrom_info *info = drive->driver_data;
+ struct request_sense local_sense;
int retries = 10;
- unsigned int flags = rq->cmd_flags;
+ unsigned int flags = 0;
- if (rq->sense == NULL)
- rq->sense = &sense;
+ if (!sense)
+ sense = &local_sense;
/* start of retry loop */
do {
+ struct request *rq;
int error;
- unsigned long time = jiffies;
- rq->cmd_flags = flags;
- error = ide_do_drive_cmd(drive, rq, ide_wait);
- time = jiffies - time;
+ rq = blk_get_request(drive->queue, write, __GFP_WAIT);
+
+ memcpy(rq->cmd, cmd, BLK_MAX_CDB);
+ rq->cmd_type = REQ_TYPE_ATA_PC;
+ rq->sense = sense;
+ rq->cmd_flags |= cmd_flags;
+ rq->timeout = timeout;
+ if (buffer) {
+ rq->data = buffer;
+ rq->data_len = *bufflen;
+ }
+
+ error = blk_execute_rq(drive->queue, info->disk, rq, 0);
+
+ if (buffer)
+ *bufflen = rq->data_len;
+
+ flags = rq->cmd_flags;
+ blk_put_request(rq);
/*
* FIXME: we should probably abort/retry or something in case of
* failure.
*/
- if (rq->cmd_flags & REQ_FAILED) {
+ if (flags & REQ_FAILED) {
/*
* The request failed. Retry if it was due to a unit
* attention status (usually means media was changed).
*/
- struct request_sense *reqbuf = rq->sense;
+ struct request_sense *reqbuf = sense;
if (reqbuf->sense_key == UNIT_ATTENTION)
cdrom_saw_media_change(drive);
@@ -885,10 +869,10 @@ int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq)
}
/* end of retry loop */
- } while ((rq->cmd_flags & REQ_FAILED) && retries >= 0);
+ } while ((flags & REQ_FAILED) && retries >= 0);
/* return an error if the command failed */
- return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0;
+ return (flags & REQ_FAILED) ? -EIO : 0;
}
/*
@@ -998,7 +982,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
- bio_cur_sectors(rq->bio),
thislen >> 9);
if (nskip > 0) {
- ide_cd_drain_data(drive, nskip);
+ ide_pad_transfer(drive, write, nskip << 9);
rq->current_nr_sectors -= nskip;
thislen -= (nskip << 9);
}
@@ -1035,7 +1019,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
* If the buffers are full, pipe the rest into
* oblivion.
*/
- ide_cd_drain_data(drive, thislen >> 9);
+ ide_pad_transfer(drive, 0, thislen);
else {
printk(KERN_ERR "%s: confused, missing data\n",
drive->name);
@@ -1083,7 +1067,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
/* pad, if necessary */
if (!blk_fs_request(rq) && len > 0)
- ide_cd_pad_transfer(drive, xferfunc, len);
+ ide_pad_transfer(drive, write, len);
if (blk_pc_request(rq)) {
timeout = rq->timeout;
@@ -1152,21 +1136,17 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
if (write)
cd->devinfo.media_written = 1;
- /* start sending the read/write request to the drive */
- return cdrom_start_packet_command(drive, 32768, cdrom_start_rw_cont);
+ return ide_started;
}
static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
- if (!rq->timeout)
- rq->timeout = ATAPI_WAIT_PC;
-
return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
}
-static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
+static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
{
struct cdrom_info *info = drive->driver_data;
@@ -1178,10 +1158,16 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
info->dma = 0;
/* sg request */
- if (rq->bio) {
- int mask = drive->queue->dma_alignment;
- unsigned long addr =
- (unsigned long)page_address(bio_page(rq->bio));
+ if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) {
+ struct request_queue *q = drive->queue;
+ unsigned int alignment;
+ unsigned long addr;
+ unsigned long stack_mask = ~(THREAD_SIZE - 1);
+
+ if (rq->bio)
+ addr = (unsigned long)bio_data(rq->bio);
+ else
+ addr = (unsigned long)rq->data;
info->dma = drive->using_dma;
@@ -1191,23 +1177,25 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
* NOTE! The "len" and "addr" checks should possibly have
* separate masks.
*/
- if ((rq->data_len & 15) || (addr & mask))
+ alignment = queue_dma_alignment(q) | q->dma_pad_mask;
+ if (addr & alignment || rq->data_len & alignment)
info->dma = 0;
- }
- /* start sending the command to the drive */
- return cdrom_start_packet_command(drive, rq->data_len,
- cdrom_do_newpc_cont);
+ if (!((addr & stack_mask) ^
+ ((unsigned long)current->stack & stack_mask)))
+ info->dma = 0;
+ }
}
/*
* cdrom driver request routine.
*/
-static ide_startstop_t ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq,
+static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
sector_t block)
{
- ide_startstop_t action;
struct cdrom_info *info = drive->driver_data;
+ ide_handler_t *fn;
+ int xferlen;
if (blk_fs_request(rq)) {
if (info->cd_flags & IDE_CD_FLAG_SEEKING) {
@@ -1227,29 +1215,48 @@ static ide_startstop_t ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq,
}
if (rq_data_dir(rq) == READ &&
IDE_LARGE_SEEK(info->last_block, block,
- IDECD_SEEK_THRESHOLD) &&
- drive->dsc_overlap)
- action = cdrom_start_seek(drive, block);
- else
- action = cdrom_start_rw(drive, rq);
+ IDECD_SEEK_THRESHOLD) &&
+ drive->dsc_overlap) {
+ xferlen = 0;
+ fn = cdrom_start_seek_continuation;
+
+ info->dma = 0;
+ info->start_seek = jiffies;
+
+ ide_cd_prepare_seek_request(drive, rq);
+ } else {
+ xferlen = 32768;
+ fn = cdrom_start_rw_cont;
+
+ if (cdrom_start_rw(drive, rq) == ide_stopped)
+ return ide_stopped;
+
+ if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped)
+ return ide_stopped;
+ }
info->last_block = block;
- return action;
} else if (blk_sense_request(rq) || blk_pc_request(rq) ||
rq->cmd_type == REQ_TYPE_ATA_PC) {
- return cdrom_do_block_pc(drive, rq);
+ xferlen = rq->data_len;
+ fn = cdrom_do_newpc_cont;
+
+ if (!rq->timeout)
+ rq->timeout = ATAPI_WAIT_PC;
+
+ cdrom_do_block_pc(drive, rq);
} else if (blk_special_request(rq)) {
/* right now this can only be a reset... */
cdrom_end_request(drive, 1);
return ide_stopped;
+ } else {
+ blk_dump_rq_flags(rq, "ide-cd bad flags");
+ cdrom_end_request(drive, 0);
+ return ide_stopped;
}
- blk_dump_rq_flags(rq, "ide-cd bad flags");
- cdrom_end_request(drive, 0);
- return ide_stopped;
+ return cdrom_start_packet_command(drive, xferlen, fn);
}
-
-
/*
* Ioctl handling.
*
@@ -1268,23 +1275,20 @@ static void msf_from_bcd(struct atapi_msf *msf)
int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
{
- struct request req;
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *cdi = &info->devinfo;
+ unsigned char cmd[BLK_MAX_CDB];
- ide_cd_init_rq(drive, &req);
-
- req.sense = sense;
- req.cmd[0] = GPCMD_TEST_UNIT_READY;
- req.cmd_flags |= REQ_QUIET;
+ memset(cmd, 0, BLK_MAX_CDB);
+ cmd[0] = GPCMD_TEST_UNIT_READY;
/*
* 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;
+ cmd[7] = cdi->sanyo_slot % 3;
- return ide_cd_queue_pc(drive, &req);
+ return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, sense, 0, REQ_QUIET);
}
static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
@@ -1297,17 +1301,14 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
} capbuf;
int stat;
- struct request req;
-
- ide_cd_init_rq(drive, &req);
+ unsigned char cmd[BLK_MAX_CDB];
+ unsigned len = sizeof(capbuf);
- req.sense = sense;
- req.cmd[0] = GPCMD_READ_CDVD_CAPACITY;
- req.data = (char *)&capbuf;
- req.data_len = sizeof(capbuf);
- req.cmd_flags |= REQ_QUIET;
+ memset(cmd, 0, BLK_MAX_CDB);
+ cmd[0] = GPCMD_READ_CDVD_CAPACITY;
- stat = ide_cd_queue_pc(drive, &req);
+ stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0,
+ REQ_QUIET);
if (stat == 0) {
*capacity = 1 + be32_to_cpu(capbuf.lba);
*sectors_per_frame =
@@ -1321,24 +1322,20 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
int format, char *buf, int buflen,
struct request_sense *sense)
{
- struct request req;
+ unsigned char cmd[BLK_MAX_CDB];
- ide_cd_init_rq(drive, &req);
+ memset(cmd, 0, BLK_MAX_CDB);
- req.sense = sense;
- req.data = buf;
- req.data_len = buflen;
- req.cmd_flags |= REQ_QUIET;
- req.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
- req.cmd[6] = trackno;
- req.cmd[7] = (buflen >> 8);
- req.cmd[8] = (buflen & 0xff);
- req.cmd[9] = (format << 6);
+ cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
+ cmd[6] = trackno;
+ cmd[7] = (buflen >> 8);
+ cmd[8] = (buflen & 0xff);
+ cmd[9] = (format << 6);
if (msf_flag)
- req.cmd[1] = 2;
+ cmd[1] = 2;
- return ide_cd_queue_pc(drive, &req);
+ return ide_cd_queue_pc(drive, cmd, 0, buf, &buflen, sense, 0, REQ_QUIET);
}
/* Try to read the entire TOC for the disk into our internal buffer. */
@@ -1869,6 +1866,7 @@ static int ide_cdrom_setup(ide_drive_t *drive)
blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
blk_queue_dma_alignment(drive->queue, 31);
+ blk_queue_update_dma_pad(drive->queue, 15);
drive->queue->unplug_delay = (1 * HZ) / 1000;
if (!drive->queue->unplug_delay)
drive->queue->unplug_delay = 1;
@@ -1951,10 +1949,9 @@ static ide_driver_t ide_cdrom_driver = {
.version = IDECD_VERSION,
.media = ide_cdrom,
.supports_dsc_overlap = 1,
- .do_request = ide_do_rw_cdrom,
+ .do_request = ide_cd_do_request,
.end_request = ide_end_request,
.error = __ide_error,
- .abort = __ide_abort,
#ifdef CONFIG_IDE_PROC_FS
.proc = idecd_proc,
#endif
@@ -2103,11 +2100,6 @@ static int ide_cd_probe(ide_drive_t *drive)
goto failed;
}
}
- if (drive->scsi) {
- 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",
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index a58801c4484d..fe0ea36e4124 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -143,8 +143,8 @@ struct cdrom_info {
void ide_cd_log_error(const char *, struct request *, struct request_sense *);
/* ide-cd.c functions used by ide-cd_ioctl.c */
-void ide_cd_init_rq(ide_drive_t *, struct request *);
-int ide_cd_queue_pc(ide_drive_t *, struct request *);
+int ide_cd_queue_pc(ide_drive_t *, const unsigned char *, int, void *,
+ unsigned *, struct request_sense *, int, unsigned int);
int ide_cd_read_toc(ide_drive_t *, struct request_sense *);
int ide_cdrom_get_capabilities(ide_drive_t *, u8 *);
void ide_cdrom_update_speed(ide_drive_t *, u8 *);
diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c
index 6d147ce6782f..24d002addf73 100644
--- a/drivers/ide/ide-cd_ioctl.c
+++ b/drivers/ide/ide-cd_ioctl.c
@@ -104,8 +104,8 @@ int cdrom_eject(ide_drive_t *drive, int ejectflag,
{
struct cdrom_info *cd = drive->driver_data;
struct cdrom_device_info *cdi = &cd->devinfo;
- struct request req;
char loej = 0x02;
+ unsigned char cmd[BLK_MAX_CDB];
if ((cd->cd_flags & IDE_CD_FLAG_NO_EJECT) && !ejectflag)
return -EDRIVE_CANT_DO_THIS;
@@ -114,17 +114,16 @@ int cdrom_eject(ide_drive_t *drive, int ejectflag,
if ((cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED) && ejectflag)
return 0;
- ide_cd_init_rq(drive, &req);
-
/* only tell drive to close tray if open, if it can do that */
if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY))
loej = 0;
- req.sense = sense;
- req.cmd[0] = GPCMD_START_STOP_UNIT;
- req.cmd[4] = loej | (ejectflag != 0);
+ memset(cmd, 0, BLK_MAX_CDB);
+
+ cmd[0] = GPCMD_START_STOP_UNIT;
+ cmd[4] = loej | (ejectflag != 0);
- return ide_cd_queue_pc(drive, &req);
+ return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, sense, 0, 0);
}
/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
@@ -134,7 +133,6 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
{
struct cdrom_info *cd = drive->driver_data;
struct request_sense my_sense;
- struct request req;
int stat;
if (sense == NULL)
@@ -144,11 +142,15 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
if (cd->cd_flags & IDE_CD_FLAG_NO_DOORLOCK) {
stat = 0;
} else {
- ide_cd_init_rq(drive, &req);
- req.sense = sense;
- req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
- req.cmd[4] = lockflag ? 1 : 0;
- stat = ide_cd_queue_pc(drive, &req);
+ unsigned char cmd[BLK_MAX_CDB];
+
+ memset(cmd, 0, BLK_MAX_CDB);
+
+ cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
+ cmd[4] = lockflag ? 1 : 0;
+
+ stat = ide_cd_queue_pc(drive, cmd, 0, NULL, 0,
+ sense, 0, 0);
}
/* If we got an illegal field error, the drive
@@ -206,32 +208,30 @@ int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed)
{
ide_drive_t *drive = cdi->handle;
struct cdrom_info *cd = drive->driver_data;
- struct request rq;
struct request_sense sense;
u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
int stat;
-
- ide_cd_init_rq(drive, &rq);
-
- rq.sense = &sense;
+ unsigned char cmd[BLK_MAX_CDB];
if (speed == 0)
speed = 0xffff; /* set to max */
else
speed *= 177; /* Nx to kbytes/s */
- rq.cmd[0] = GPCMD_SET_SPEED;
+ memset(cmd, 0, BLK_MAX_CDB);
+
+ cmd[0] = GPCMD_SET_SPEED;
/* Read Drive speed in kbytes/second MSB/LSB */
- rq.cmd[2] = (speed >> 8) & 0xff;
- rq.cmd[3] = speed & 0xff;
+ cmd[2] = (speed >> 8) & 0xff;
+ cmd[3] = speed & 0xff;
if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) !=
(CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) {
/* Write Drive speed in kbytes/second MSB/LSB */
- rq.cmd[4] = (speed >> 8) & 0xff;
- rq.cmd[5] = speed & 0xff;
+ cmd[4] = (speed >> 8) & 0xff;
+ cmd[5] = speed & 0xff;
}
- stat = ide_cd_queue_pc(drive, &rq);
+ stat = ide_cd_queue_pc(drive, cmd, 0, NULL, 0, &sense, 0, 0);
if (!ide_cdrom_get_capabilities(drive, buf)) {
ide_cdrom_update_speed(drive, buf);
@@ -268,21 +268,19 @@ int ide_cdrom_get_mcn(struct cdrom_device_info *cdi,
{
ide_drive_t *drive = cdi->handle;
int stat, mcnlen;
- struct request rq;
char buf[24];
+ unsigned char cmd[BLK_MAX_CDB];
+ unsigned len = sizeof(buf);
- ide_cd_init_rq(drive, &rq);
+ memset(cmd, 0, BLK_MAX_CDB);
- rq.data = buf;
- rq.data_len = sizeof(buf);
+ cmd[0] = GPCMD_READ_SUBCHANNEL;
+ cmd[1] = 2; /* MSF addressing */
+ cmd[2] = 0x40; /* request subQ data */
+ cmd[3] = 2; /* format */
+ cmd[8] = len;
- rq.cmd[0] = GPCMD_READ_SUBCHANNEL;
- rq.cmd[1] = 2; /* MSF addressing */
- rq.cmd[2] = 0x40; /* request subQ data */
- rq.cmd[3] = 2; /* format */
- rq.cmd[8] = sizeof(buf);
-
- stat = ide_cd_queue_pc(drive, &rq);
+ stat = ide_cd_queue_pc(drive, cmd, 0, buf, &len, NULL, 0, 0);
if (stat)
return stat;
@@ -298,14 +296,14 @@ int ide_cdrom_reset(struct cdrom_device_info *cdi)
ide_drive_t *drive = cdi->handle;
struct cdrom_info *cd = drive->driver_data;
struct request_sense sense;
- struct request req;
+ struct request *rq;
int ret;
- ide_cd_init_rq(drive, &req);
- req.cmd_type = REQ_TYPE_SPECIAL;
- req.cmd_flags = REQ_QUIET;
- ret = ide_do_drive_cmd(drive, &req, ide_wait);
-
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd_flags = REQ_QUIET;
+ ret = blk_execute_rq(drive->queue, cd->disk, rq, 0);
+ blk_put_request(rq);
/*
* A reset will unlock the door. If it was previously locked,
* lock it again.
@@ -351,8 +349,8 @@ static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg)
struct atapi_toc_entry *first_toc, *last_toc;
unsigned long lba_start, lba_end;
int stat;
- struct request rq;
struct request_sense sense;
+ unsigned char cmd[BLK_MAX_CDB];
stat = ide_cd_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
if (stat)
@@ -370,14 +368,13 @@ static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg)
if (lba_end <= lba_start)
return -EINVAL;
- ide_cd_init_rq(drive, &rq);
+ memset(cmd, 0, BLK_MAX_CDB);
- rq.sense = &sense;
- rq.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
- lba_to_msf(lba_start, &rq.cmd[3], &rq.cmd[4], &rq.cmd[5]);
- lba_to_msf(lba_end - 1, &rq.cmd[6], &rq.cmd[7], &rq.cmd[8]);
+ cmd[0] = GPCMD_PLAY_AUDIO_MSF;
+ lba_to_msf(lba_start, &cmd[3], &cmd[4], &cmd[5]);
+ lba_to_msf(lba_end - 1, &cmd[6], &cmd[7], &cmd[8]);
- return ide_cd_queue_pc(drive, &rq);
+ return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, &sense, 0, 0);
}
static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg)
@@ -447,8 +444,9 @@ int ide_cdrom_audio_ioctl(struct cdrom_device_info *cdi,
int ide_cdrom_packet(struct cdrom_device_info *cdi,
struct packet_command *cgc)
{
- struct request req;
ide_drive_t *drive = cdi->handle;
+ unsigned int flags = 0;
+ unsigned len = cgc->buflen;
if (cgc->timeout <= 0)
cgc->timeout = ATAPI_WAIT_PC;
@@ -456,24 +454,21 @@ int ide_cdrom_packet(struct cdrom_device_info *cdi,
/* here we queue the commands from the uniform CD-ROM
layer. the packet must be complete, as we do not
touch it at all. */
- ide_cd_init_rq(drive, &req);
if (cgc->data_direction == CGC_DATA_WRITE)
- req.cmd_flags |= REQ_RW;
+ flags |= REQ_RW;
- memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE);
if (cgc->sense)
memset(cgc->sense, 0, sizeof(struct request_sense));
- req.data = cgc->buffer;
- req.data_len = cgc->buflen;
- req.timeout = cgc->timeout;
if (cgc->quiet)
- req.cmd_flags |= REQ_QUIET;
+ flags |= REQ_QUIET;
- req.sense = cgc->sense;
- cgc->stat = ide_cd_queue_pc(drive, &req);
+ cgc->stat = ide_cd_queue_pc(drive, cgc->cmd,
+ cgc->data_direction == CGC_DATA_WRITE,
+ cgc->buffer, &len,
+ cgc->sense, cgc->timeout, flags);
if (!cgc->stat)
- cgc->buflen -= req.data_len;
+ cgc->buflen -= len;
return cgc->stat;
}
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 8e08d083fce9..3a2e80237c10 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -198,8 +198,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
}
memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_NO_SELECT_MASK; /* FIXME? */
- task.tf_flags |= (IDE_TFLAG_TF | IDE_TFLAG_DEVICE);
+ task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (drive->select.b.lba) {
if (lba48) {
@@ -617,7 +616,8 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
*/
static int set_multcount(ide_drive_t *drive, int arg)
{
- struct request rq;
+ struct request *rq;
+ int error;
if (arg < 0 || arg > drive->id->max_multsect)
return -EINVAL;
@@ -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);
- rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ 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);
+ error = blk_execute_rq(drive->queue, NULL, rq, 0);
+ blk_put_request(rq);
return (drive->mult_count == arg) ? 0 : -EIO;
}
@@ -984,7 +985,6 @@ static ide_driver_t idedisk_driver = {
.do_request = ide_do_rw_disk,
.end_request = ide_end_request,
.error = __ide_error,
- .abort = __ide_abort,
#ifdef CONFIG_IDE_PROC_FS
.proc = idedisk_proc,
#endif
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 653b1ade13d3..7ee44f86bc54 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -463,7 +463,7 @@ int ide_dma_setup(ide_drive_t *drive)
}
/* PRD table */
- if (hwif->mmio)
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
writel(hwif->dmatable_dma,
(void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS));
else
@@ -692,7 +692,7 @@ static int ide_tune_dma(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 speed;
- if (noautodma || drive->nodma || (drive->id->capability & 1) == 0)
+ if (drive->nodma || (drive->id->capability & 1) == 0)
return 0;
/* consult the list of known "bad" drives */
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index f05fbc2bd7a8..011d72011cc4 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -286,11 +286,12 @@ static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
{
struct ide_floppy_obj *floppy = drive->driver_data;
- ide_init_drive_cmd(rq);
+ blk_rq_init(NULL, rq);
rq->buffer = (char *) pc;
rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd_flags |= REQ_PREEMPT;
rq->rq_disk = floppy->disk;
- (void) ide_do_drive_cmd(drive, rq, ide_preempt);
+ ide_do_drive_cmd(drive, rq);
}
static struct ide_atapi_pc *idefloppy_next_pc_storage(ide_drive_t *drive)
@@ -311,61 +312,49 @@ static struct request *idefloppy_next_rq_storage(ide_drive_t *drive)
return (&floppy->rq_stack[floppy->rq_stack_index++]);
}
-static void idefloppy_request_sense_callback(ide_drive_t *drive)
+static void ide_floppy_callback(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
- u8 *buf = floppy->pc->buf;
+ struct ide_atapi_pc *pc = floppy->pc;
+ int uptodate = pc->error ? 0 : 1;
debug_log("Reached %s\n", __func__);
- if (!floppy->pc->error) {
- floppy->sense_key = buf[2] & 0x0F;
- floppy->asc = buf[12];
- floppy->ascq = buf[13];
- floppy->progress_indication = buf[15] & 0x80 ?
- (u16)get_unaligned((u16 *)&buf[16]) : 0x10000;
-
- if (floppy->failed_pc)
- debug_log("pc = %x, sense key = %x, asc = %x,"
- " ascq = %x\n",
- floppy->failed_pc->c[0],
- floppy->sense_key,
- floppy->asc,
- floppy->ascq);
- else
- debug_log("sense key = %x, asc = %x, ascq = %x\n",
- floppy->sense_key,
- floppy->asc,
- floppy->ascq);
+ if (floppy->failed_pc == pc)
+ floppy->failed_pc = NULL;
+ if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
+ (pc->rq && blk_pc_request(pc->rq)))
+ uptodate = 1; /* FIXME */
+ else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
+ u8 *buf = floppy->pc->buf;
- idefloppy_end_request(drive, 1, 0);
- } else {
- printk(KERN_ERR "Error in REQUEST SENSE itself - Aborting"
- " request!\n");
- idefloppy_end_request(drive, 0, 0);
- }
-}
+ if (!pc->error) {
+ floppy->sense_key = buf[2] & 0x0F;
+ floppy->asc = buf[12];
+ floppy->ascq = buf[13];
+ floppy->progress_indication = buf[15] & 0x80 ?
+ (u16)get_unaligned((u16 *)&buf[16]) : 0x10000;
-/* General packet command callback function. */
-static void idefloppy_pc_callback(ide_drive_t *drive)
-{
- idefloppy_floppy_t *floppy = drive->driver_data;
+ if (floppy->failed_pc)
+ debug_log("pc = %x, ", floppy->failed_pc->c[0]);
- debug_log("Reached %s\n", __func__);
+ debug_log("sense key = %x, asc = %x, ascq = %x\n",
+ floppy->sense_key, floppy->asc, floppy->ascq);
+ } else
+ printk(KERN_ERR "Error in REQUEST SENSE itself - "
+ "Aborting request!\n");
+ }
- idefloppy_end_request(drive, floppy->pc->error ? 0 : 1, 0);
+ idefloppy_end_request(drive, uptodate, 0);
}
static void idefloppy_init_pc(struct ide_atapi_pc *pc)
{
- memset(pc->c, 0, 12);
- pc->retries = 0;
- pc->flags = 0;
- pc->req_xfer = 0;
+ memset(pc, 0, sizeof(*pc));
pc->buf = pc->pc_buf;
pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE;
- pc->idefloppy_callback = &idefloppy_pc_callback;
+ pc->callback = ide_floppy_callback;
}
static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc)
@@ -374,7 +363,6 @@ static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc)
pc->c[0] = GPCMD_REQUEST_SENSE;
pc->c[4] = 255;
pc->req_xfer = 18;
- pc->idefloppy_callback = &idefloppy_request_sense_callback;
}
/*
@@ -397,174 +385,19 @@ static void idefloppy_retry_pc(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;
- struct ide_atapi_pc *pc = floppy->pc;
- struct request *rq = pc->rq;
- xfer_func_t *xferfunc;
- unsigned int temp;
- int dma_error = 0;
- u16 bcount;
- u8 stat, ireason;
-
- debug_log("Reached %s interrupt handler\n", __func__);
-
- if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- 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->xferred = pc->req_xfer;
- idefloppy_update_buffers(drive, pc);
- }
- debug_log("DMA finished\n");
- }
-
- /* Clear the interrupt */
- stat = ide_read_status(drive);
-
- /* No more interrupts */
- if ((stat & DRQ_STAT) == 0) {
- debug_log("Packet command completed, %d bytes transferred\n",
- pc->xferred);
- pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
-
- local_irq_enable_in_hardirq();
-
- if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
- /* Error detected */
- debug_log("%s: I/O error\n", drive->name);
- rq->errors++;
- if (pc->c[0] == GPCMD_REQUEST_SENSE) {
- printk(KERN_ERR "ide-floppy: I/O error in "
- "request sense command\n");
- return ide_do_reset(drive);
- }
- /* Retry operation */
- idefloppy_retry_pc(drive);
- /* queued, but not started */
- return ide_stopped;
- }
- pc->error = 0;
- if (floppy->failed_pc == pc)
- floppy->failed_pc = NULL;
- /* Command finished - Call the callback function */
- pc->idefloppy_callback(drive);
- return ide_stopped;
- }
-
- if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
- printk(KERN_ERR "ide-floppy: The floppy wants to issue "
- "more interrupts in DMA mode\n");
- ide_dma_off(drive);
- return ide_do_reset(drive);
- }
-
- /* Get the number of bytes to transfer */
- bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
- hwif->INB(hwif->io_ports.lbam_addr);
- /* on this interrupt */
- ireason = hwif->INB(hwif->io_ports.nsect_addr);
-
- if (ireason & CD) {
- printk(KERN_ERR "ide-floppy: CoD != 0 in %s\n", __func__);
- return ide_do_reset(drive);
- }
- if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
- /* Hopefully, we will never get here */
- printk(KERN_ERR "ide-floppy: We wanted to %s, ",
- (ireason & IO) ? "Write" : "Read");
- printk(KERN_ERR "but the floppy wants us to %s !\n",
- (ireason & IO) ? "Read" : "Write");
- return ide_do_reset(drive);
- }
- if (!(pc->flags & PC_FLAG_WRITING)) {
- /* Reading - Check that we have enough space */
- 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");
- ide_pad_transfer(drive, 0, bcount);
-
- ide_set_handler(drive,
- &idefloppy_pc_intr,
- IDEFLOPPY_WAIT_CMD,
- NULL);
- return ide_started;
- }
- debug_log("The floppy wants to send us more data than"
- " expected - allowing transfer\n");
- }
- }
- if (pc->flags & PC_FLAG_WRITING)
- xferfunc = hwif->output_data;
- else
- xferfunc = hwif->input_data;
-
- 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->xferred += bcount;
- pc->cur_pos += bcount;
-
- /* And set the interrupt handler again */
- ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);
- return ide_started;
+ return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr,
+ IDEFLOPPY_WAIT_CMD, NULL, idefloppy_update_buffers,
+ idefloppy_retry_pc, NULL, ide_floppy_io_buffers);
}
/*
- * This is the original routine that did the packet transfer.
- * It fails at high speeds on the Iomega ZIP drive, so there's a slower version
- * for that drive below. The algorithm is chosen based on drive type
- */
-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;
-
- if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
- printk(KERN_ERR "ide-floppy: Strange, packet command "
- "initiated yet DRQ isn't asserted\n");
- return startstop;
- }
- 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");
- return ide_do_reset(drive);
- }
-
- /* Set the interrupt routine */
- ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);
-
- /* Send the actual packet */
- hwif->output_data(drive, NULL, floppy->pc->c, 12);
-
- return ide_started;
-}
-
-
-/*
* What we have here is a classic case of a top half / bottom half interrupt
* service routine. In interrupt mode, the device sends an interrupt to signal
* that it is ready to receive a packet. However, we need to delay about 2-3
* ticks before issuing the packet or we gets in trouble.
- *
- * So, follow carefully. transfer_pc1 is called as an interrupt (or directly).
- * In either case, when the device says it's ready for a packet, we schedule
- * the packet transfer to occur about 2-3 ticks later in transfer_pc2.
*/
-static int idefloppy_transfer_pc2(ide_drive_t *drive)
+static int idefloppy_transfer_pc(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
@@ -575,24 +408,19 @@ static int idefloppy_transfer_pc2(ide_drive_t *drive)
return IDEFLOPPY_WAIT_CMD;
}
-static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive)
+
+/*
+ * Called as an interrupt (or directly). When the device says it's ready for a
+ * packet, we schedule the packet transfer to occur about 2-3 ticks later in
+ * transfer_pc.
+ */
+static ide_startstop_t idefloppy_start_pc_transfer(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
idefloppy_floppy_t *floppy = drive->driver_data;
- ide_startstop_t startstop;
- u8 ireason;
+ struct ide_atapi_pc *pc = floppy->pc;
+ ide_expiry_t *expiry;
+ unsigned int timeout;
- if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
- printk(KERN_ERR "ide-floppy: Strange, packet command "
- "initiated yet DRQ isn't asserted\n");
- return startstop;
- }
- 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");
- return ide_do_reset(drive);
- }
/*
* The following delay solves a problem with ATAPI Zip 100 drives
* where the Busy flag was apparently being deasserted before the
@@ -601,10 +429,15 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive)
* 40 and 50msec work well. idefloppy_pc_intr will not be actually
* used until after the packet is moved in about 50 msec.
*/
+ if (pc->flags & PC_FLAG_ZIP_DRIVE) {
+ timeout = floppy->ticks;
+ expiry = &idefloppy_transfer_pc;
+ } else {
+ timeout = IDEFLOPPY_WAIT_CMD;
+ expiry = NULL;
+ }
- ide_set_handler(drive, &idefloppy_pc_intr, floppy->ticks,
- &idefloppy_transfer_pc2);
- return ide_started;
+ return ide_transfer_pc(drive, pc, idefloppy_pc_intr, timeout, expiry);
}
static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
@@ -627,10 +460,6 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
struct ide_atapi_pc *pc)
{
idefloppy_floppy_t *floppy = drive->driver_data;
- ide_hwif_t *hwif = drive->hwif;
- ide_handler_t *pkt_xfer_routine;
- u16 bcount;
- u8 dma;
if (floppy->failed_pc == NULL &&
pc->c[0] != GPCMD_REQUEST_SENSE)
@@ -645,65 +474,16 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
pc->error = IDEFLOPPY_ERROR_GENERAL;
floppy->failed_pc = NULL;
- pc->idefloppy_callback(drive);
+ pc->callback(drive);
return ide_stopped;
}
debug_log("Retry number - %d\n", pc->retries);
pc->retries++;
- /* We haven't transferred any data yet */
- 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;
- ide_dma_off(drive);
- }
- dma = 0;
-
- if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma)
- dma = !hwif->dma_ops->dma_setup(drive);
-
- ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK |
- IDE_TFLAG_OUT_DEVICE, bcount, dma);
- if (dma) {
- /* Begin DMA, if necessary */
- pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
- hwif->dma_ops->dma_start(drive);
- }
-
- /* Can we transfer the packet when we get the interrupt or wait? */
- if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) {
- /* wait */
- pkt_xfer_routine = &idefloppy_transfer_pc1;
- } else {
- /* immediate */
- pkt_xfer_routine = &idefloppy_transfer_pc;
- }
-
- if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT) {
- /* Issue the packet command */
- ide_execute_command(drive, WIN_PACKETCMD,
- pkt_xfer_routine,
- IDEFLOPPY_WAIT_CMD,
- NULL);
- return ide_started;
- } else {
- /* Issue the packet command */
- ide_execute_pkt_cmd(drive);
- return (*pkt_xfer_routine) (drive);
- }
-}
-
-static void idefloppy_rw_callback(ide_drive_t *drive)
-{
- debug_log("Reached %s\n", __func__);
-
- idefloppy_end_request(drive, 1, 0);
- return;
+ return ide_issue_pc(drive, pc, idefloppy_start_pc_transfer,
+ IDEFLOPPY_WAIT_CMD, NULL);
}
static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent)
@@ -778,12 +558,6 @@ static void idefloppy_create_start_stop_cmd(struct ide_atapi_pc *pc, int start)
pc->c[4] = start;
}
-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,
struct ide_atapi_pc *pc, struct request *rq,
unsigned long sector)
@@ -800,21 +574,19 @@ 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->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->buf = NULL;
pc->req_xfer = pc->buf_size = blocks * floppy->block_size;
- pc->flags |= PC_FLAG_DMA_RECOMMENDED;
+ pc->flags |= PC_FLAG_DMA_OK;
}
static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
struct ide_atapi_pc *pc, struct request *rq)
{
idefloppy_init_pc(pc);
- pc->idefloppy_callback = &idefloppy_rw_callback;
memcpy(pc->c, rq->cmd, sizeof(pc->c));
pc->rq = rq;
pc->b_count = rq->data_len;
@@ -822,7 +594,7 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
pc->flags |= PC_FLAG_WRITING;
pc->buf = rq->data;
if (rq->bio)
- pc->flags |= PC_FLAG_DMA_RECOMMENDED;
+ pc->flags |= PC_FLAG_DMA_OK;
/*
* possibly problematic, doesn't look like ide-floppy correctly
* handled scattered requests if dma fails...
@@ -875,7 +647,14 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
return ide_stopped;
}
+ if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT)
+ pc->flags |= PC_FLAG_DRQ_INTERRUPT;
+
+ if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE)
+ pc->flags |= PC_FLAG_ZIP_DRIVE;
+
pc->rq = rq;
+
return idefloppy_issue_pc(drive, pc);
}
@@ -886,14 +665,16 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
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;
+ struct request *rq;
+ int error;
- ide_init_drive_cmd(&rq);
- rq.buffer = (char *) pc;
- rq.cmd_type = REQ_TYPE_SPECIAL;
- rq.rq_disk = floppy->disk;
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq->buffer = (char *) pc;
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ error = blk_execute_rq(drive->queue, floppy->disk, rq, 0);
+ blk_put_request(rq);
- return ide_do_drive_cmd(drive, &rq, ide_wait);
+ return error;
}
/*
@@ -921,10 +702,10 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
set_disk_ro(floppy->disk, floppy->wp);
page = &pc.buf[8];
- 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]);
+ transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]);
+ sector_size = be16_to_cpup((__be16 *)&pc.buf[8 + 6]);
+ cyls = be16_to_cpup((__be16 *)&pc.buf[8 + 8]);
+ rpm = be16_to_cpup((__be16 *)&pc.buf[8 + 28]);
heads = pc.buf[8 + 4];
sectors = pc.buf[8 + 5];
@@ -999,8 +780,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
for (i = 0; i < desc_cnt; i++) {
unsigned int desc_start = 4 + i*8;
- blocks = be32_to_cpu(*(u32 *)&pc.buf[desc_start]);
- length = be16_to_cpu(*(u16 *)&pc.buf[desc_start + 6]);
+ blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]);
+ length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
debug_log("Descriptor %d: %dkB, %d blocks, %d sector size\n",
i, blocks * length / 1024, blocks, length);
@@ -1121,8 +902,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.buf[desc_start]);
- length = be16_to_cpu(*(u16 *)&pc.buf[desc_start + 6]);
+ blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]);
+ length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
if (put_user(blocks, argp))
return(-EFAULT);
@@ -1348,7 +1129,6 @@ static ide_driver_t idefloppy_driver = {
.do_request = idefloppy_do_request,
.end_request = idefloppy_end_request,
.error = __ide_error,
- .abort = __ide_abort,
#ifdef CONFIG_IDE_PROC_FS
.proc = idefloppy_proc,
#endif
@@ -1376,7 +1156,9 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
/* Just in case */
- idefloppy_create_test_unit_ready_cmd(&pc);
+ idefloppy_init_pc(&pc);
+ pc.c[0] = GPCMD_TEST_UNIT_READY;
+
if (idefloppy_queue_pc_tail(drive, &pc)) {
idefloppy_create_start_stop_cmd(&pc, 1);
(void) idefloppy_queue_pc_tail(drive, &pc);
@@ -1622,11 +1404,6 @@ static int ide_floppy_probe(ide_drive_t *drive)
" of ide-floppy\n", drive->name);
goto failed;
}
- if (drive->scsi) {
- printk(KERN_INFO "ide-floppy: passing drive %s to ide-scsi"
- " emulation.\n", drive->name);
- goto failed;
- }
floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL);
if (!floppy) {
printk(KERN_ERR "ide-floppy: %s: Can't allocate a floppy"
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index a6073e248f45..2d92214096ab 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -22,6 +22,10 @@
#define DRV_NAME "ide_generic"
+static int probe_mask = 0x03;
+module_param(probe_mask, int, 0);
+MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports");
+
static ssize_t store_add(struct class *cls, const char *buf, size_t n)
{
ide_hwif_t *hwif;
@@ -89,6 +93,9 @@ static int __init ide_generic_init(void)
u8 idx[MAX_HWIFS];
int i;
+ printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module "
+ "parameter for probing all legacy ISA IDE ports\n");
+
for (i = 0; i < MAX_HWIFS; i++) {
ide_hwif_t *hwif;
unsigned long io_addr = ide_default_io_base(i);
@@ -96,7 +103,7 @@ static int __init ide_generic_init(void)
idx[i] = 0xff;
- if (io_addr) {
+ if ((probe_mask & (1 << i)) && io_addr) {
if (!request_region(io_addr, 8, DRV_NAME)) {
printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX "
"not free.\n",
@@ -125,6 +132,7 @@ static int __init ide_generic_init(void)
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, io_addr, io_addr + 0x206);
hw.irq = ide_default_irq(io_addr);
+ hw.chipset = ide_generic;
ide_init_port_hw(hwif, &hw);
idx[i] = i;
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 696525342e9a..661b75a89d4d 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -358,31 +358,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
EXPORT_SYMBOL(ide_end_drive_cmd);
-/**
- * try_to_flush_leftover_data - flush junk
- * @drive: drive to flush
- *
- * try_to_flush_leftover_data() is invoked in response to a drive
- * unexpectedly having its DRQ_STAT bit set. As an alternative to
- * resetting the drive, this routine tries to clear the condition
- * by read a sector's worth of data from the drive. Of course,
- * this may not help if the drive is *waiting* for data from *us*.
- */
-static void try_to_flush_leftover_data (ide_drive_t *drive)
-{
- int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS;
-
- if (drive->media != ide_disk)
- return;
- while (i > 0) {
- u32 buffer[16];
- u32 wcount = (i > 16) ? 16 : i;
-
- i -= wcount;
- drive->hwif->input_data(drive, NULL, buffer, wcount * 4);
- }
-}
-
static void ide_kill_rq(ide_drive_t *drive, struct request *rq)
{
if (rq->rq_disk) {
@@ -422,8 +397,11 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
}
if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ &&
- (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0)
- try_to_flush_leftover_data(drive);
+ (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
+ int nsect = drive->mult_count ? drive->mult_count : 1;
+
+ ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
+ }
if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
ide_kill_rq(drive, rq);
@@ -459,7 +437,7 @@ 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->OUTBSYNC(drive, WIN_IDLEIMMEDIATE,
+ hwif->OUTBSYNC(hwif, WIN_IDLEIMMEDIATE,
hwif->io_ports.command_addr);
if (rq->errors >= ERROR_MAX) {
@@ -526,55 +504,6 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
EXPORT_SYMBOL_GPL(ide_error);
-ide_startstop_t __ide_abort(ide_drive_t *drive, struct request *rq)
-{
- if (drive->media != ide_disk)
- rq->errors |= ERROR_RESET;
-
- ide_kill_rq(drive, rq);
-
- return ide_stopped;
-}
-
-EXPORT_SYMBOL_GPL(__ide_abort);
-
-/**
- * ide_abort - abort pending IDE operations
- * @drive: drive the error occurred on
- * @msg: message to report
- *
- * ide_abort kills and cleans up when we are about to do a
- * host initiated reset on active commands. Longer term we
- * want handlers to have sensible abort handling themselves
- *
- * This differs fundamentally from ide_error because in
- * this case the command is doing just fine when we
- * blow it away.
- */
-
-ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg)
-{
- struct request *rq;
-
- if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
- return ide_stopped;
-
- /* retry only "normal" I/O: */
- if (!blk_fs_request(rq)) {
- rq->errors = 1;
- ide_end_drive_cmd(drive, BUSY_STAT, 0);
- return ide_stopped;
- }
-
- if (rq->rq_disk) {
- ide_driver_t *drv;
-
- drv = *(ide_driver_t **)rq->rq_disk->private_data;
- return drv->abort(drive, rq);
- } else
- return __ide_abort(drive, rq);
-}
-
static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
{
tf->nsect = drive->sect;
@@ -788,6 +717,18 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
return ide_stopped;
}
+static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
+{
+ switch (rq->cmd[0]) {
+ case REQ_DRIVE_RESET:
+ return ide_do_reset(drive);
+ default:
+ blk_dump_rq_flags(rq, "ide_special_rq - bad request");
+ ide_end_request(drive, 0, 0);
+ return ide_stopped;
+ }
+}
+
static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
{
struct request_pm_state *pm = rq->data;
@@ -891,7 +832,16 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
pm->pm_step == ide_pm_state_completed)
ide_complete_pm_request(drive, rq);
return startstop;
- }
+ } else if (!rq->rq_disk && blk_special_request(rq))
+ /*
+ * TODO: Once all ULDs have been modified to
+ * check for specific op codes rather than
+ * blindly accepting any special request, the
+ * check for ->rq_disk above may be replaced
+ * by a more suitable mechanism or even
+ * dropped entirely.
+ */
+ return ide_special_rq(drive, rq);
drv = *(ide_driver_t **)rq->rq_disk->private_data;
return drv->do_request(drive, rq, block);
@@ -1539,88 +1489,30 @@ irqreturn_t ide_intr (int irq, void *dev_id)
}
/**
- * ide_init_drive_cmd - initialize a drive command request
- * @rq: request object
- *
- * Initialize a request before we fill it in and send it down to
- * ide_do_drive_cmd. Commands must be set up by this function. Right
- * now it doesn't do a lot, but if that changes abusers will have a
- * nasty surprise.
- */
-
-void ide_init_drive_cmd (struct request *rq)
-{
- blk_rq_init(NULL, rq);
-}
-
-EXPORT_SYMBOL(ide_init_drive_cmd);
-
-/**
* ide_do_drive_cmd - issue IDE special command
* @drive: device to issue command
* @rq: request to issue
- * @action: action for processing
*
* This function issues a special IDE device request
* onto the request queue.
*
- * If action is ide_wait, then the rq is queued at the end of the
- * request queue, and the function sleeps until it has been processed.
- * This is for use when invoked from an ioctl handler.
- *
- * If action is ide_preempt, then the rq is queued at the head of
- * the request queue, displacing the currently-being-processed
- * request and this function returns immediately without waiting
- * for the new rq to be completed. This is VERY DANGEROUS, and is
- * intended for careful use by the ATAPI tape/cdrom driver code.
- *
- * If action is ide_end, then the rq is queued at the end of the
- * request queue, and the function returns immediately without waiting
- * for the new rq to be completed. This is again intended for careful
- * use by the ATAPI tape/cdrom driver code.
+ * the rq is queued at the head of the request queue, displacing
+ * the currently-being-processed request and this function
+ * returns immediately without waiting for the new rq to be
+ * completed. This is VERY DANGEROUS, and is intended for
+ * careful use by the ATAPI tape/cdrom driver code.
*/
-
-int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action)
+
+void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq)
{
unsigned long flags;
ide_hwgroup_t *hwgroup = HWGROUP(drive);
- DECLARE_COMPLETION_ONSTACK(wait);
- int where = ELEVATOR_INSERT_BACK, err;
- int must_wait = (action == ide_wait || action == ide_head_wait);
-
- rq->errors = 0;
-
- /*
- * we need to hold an extra reference to request for safe inspection
- * after completion
- */
- if (must_wait) {
- rq->ref_count++;
- rq->end_io_data = &wait;
- rq->end_io = blk_end_sync_rq;
- }
spin_lock_irqsave(&ide_lock, flags);
- if (action == ide_preempt)
- hwgroup->rq = NULL;
- if (action == ide_preempt || action == ide_head_wait) {
- where = ELEVATOR_INSERT_FRONT;
- rq->cmd_flags |= REQ_PREEMPT;
- }
- __elv_add_request(drive->queue, rq, where, 0);
- ide_do_request(hwgroup, IDE_NO_IRQ);
+ hwgroup->rq = NULL;
+ __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 1);
+ __generic_unplug_device(drive->queue);
spin_unlock_irqrestore(&ide_lock, flags);
-
- err = 0;
- if (must_wait) {
- wait_for_completion(&wait);
- if (rq->errors)
- err = -EIO;
-
- blk_put_request(rq);
- }
-
- return err;
}
EXPORT_SYMBOL(ide_do_drive_cmd);
@@ -1637,6 +1529,8 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
task.tf.lbah = (bcount >> 8) & 0xff;
ide_tf_dump(drive->name, &task.tf);
+ ide_set_irq(drive, 1);
+ SELECT_MASK(drive, 0);
drive->hwif->tf_load(drive, &task);
}
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 0daf923541ff..44aaec256a30 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -42,7 +42,7 @@ static void ide_outb (u8 val, unsigned long port)
outb(val, port);
}
-static void ide_outbsync (ide_drive_t *drive, u8 addr, unsigned long port)
+static void ide_outbsync(ide_hwif_t *hwif, u8 addr, unsigned long port)
{
outb(addr, port);
}
@@ -68,7 +68,7 @@ static void ide_mm_outb (u8 value, unsigned long port)
writeb(value, (void __iomem *) port);
}
-static void ide_mm_outbsync (ide_drive_t *drive, u8 value, unsigned long port)
+static void ide_mm_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port)
{
writeb(value, (void __iomem *) port);
}
@@ -95,7 +95,7 @@ void SELECT_DRIVE (ide_drive_t *drive)
hwif->OUTB(drive->select.all, hwif->io_ports.device_addr);
}
-static void SELECT_MASK(ide_drive_t *drive, int mask)
+void SELECT_MASK(ide_drive_t *drive, int mask)
{
const struct ide_port_ops *port_ops = drive->hwif->port_ops;
@@ -120,11 +120,6 @@ static void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
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;
@@ -191,7 +186,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
}
/* be sure we're looking at the low order bits */
- tf_outb(drive->ctl & ~0x80, io_ports->ctl_addr);
+ tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tf_inb(io_ports->nsect_addr);
@@ -205,7 +200,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
tf->device = tf_inb(io_ports->device_addr);
if (task->tf_flags & IDE_TFLAG_LBA48) {
- tf_outb(drive->ctl | 0x80, io_ports->ctl_addr);
+ tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = tf_inb(io_ports->feature_addr);
@@ -689,9 +684,9 @@ int ide_driveid_update(ide_drive_t *drive)
*/
SELECT_MASK(drive, 1);
- ide_set_irq(drive, 1);
+ ide_set_irq(drive, 0);
msleep(50);
- hwif->OUTBSYNC(drive, WIN_IDENTIFY, hwif->io_ports.command_addr);
+ hwif->OUTBSYNC(hwif, WIN_IDENTIFY, hwif->io_ports.command_addr);
timeout = jiffies + WAIT_WORSTCASE;
do {
if (time_after(jiffies, timeout)) {
@@ -744,9 +739,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
int error = 0;
u8 stat;
-// while (HWGROUP(drive)->busy)
-// msleep(50);
-
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_ops) /* check if host supports DMA */
hwif->dma_ops->dma_host_set(drive, 0);
@@ -781,7 +773,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
ide_set_irq(drive, 0);
hwif->OUTB(speed, io_ports->nsect_addr);
hwif->OUTB(SETFEATURES_XFER, io_ports->feature_addr);
- hwif->OUTBSYNC(drive, WIN_SETFEATURES, io_ports->command_addr);
+ hwif->OUTBSYNC(hwif, WIN_SETFEATURES, io_ports->command_addr);
if (drive->quirk_list == 2)
ide_set_irq(drive, 1);
@@ -889,7 +881,7 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
spin_lock_irqsave(&ide_lock, flags);
__ide_set_handler(drive, handler, timeout, expiry);
- hwif->OUTBSYNC(drive, cmd, hwif->io_ports.command_addr);
+ hwif->OUTBSYNC(hwif, cmd, hwif->io_ports.command_addr);
/*
* Drive takes 400nS to respond, we must avoid the IRQ being
* serviced before that.
@@ -907,12 +899,20 @@ void ide_execute_pkt_cmd(ide_drive_t *drive)
unsigned long flags;
spin_lock_irqsave(&ide_lock, flags);
- hwif->OUTBSYNC(drive, WIN_PACKETCMD, hwif->io_ports.command_addr);
+ hwif->OUTBSYNC(hwif, WIN_PACKETCMD, hwif->io_ports.command_addr);
ndelay(400);
spin_unlock_irqrestore(&ide_lock, flags);
}
EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd);
+static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
+{
+ struct request *rq = drive->hwif->hwgroup->rq;
+
+ if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET)
+ ide_end_request(drive, err ? err : 1, 0);
+}
+
/* needed below */
static ide_startstop_t do_reset1 (ide_drive_t *, int);
@@ -948,7 +948,7 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
}
/* done polling */
hwgroup->polling = 0;
- hwgroup->resetting = 0;
+ ide_complete_drive_reset(drive, 0);
return ide_stopped;
}
@@ -964,12 +964,14 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
ide_hwif_t *hwif = HWIF(drive);
const struct ide_port_ops *port_ops = hwif->port_ops;
u8 tmp;
+ int err = 0;
if (port_ops && port_ops->reset_poll) {
- if (port_ops->reset_poll(drive)) {
+ err = port_ops->reset_poll(drive);
+ if (err) {
printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
hwif->name, drive->name);
- return ide_stopped;
+ goto out;
}
}
@@ -983,6 +985,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
}
printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
drive->failures++;
+ err = -EIO;
} else {
printk("%s: reset: ", hwif->name);
tmp = ide_read_error(drive);
@@ -1009,10 +1012,12 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
if (tmp & 0x80)
printk("; slave: failed");
printk("\n");
+ err = -EIO;
}
}
+out:
hwgroup->polling = 0; /* done polling */
- hwgroup->resetting = 0; /* done reset attempt */
+ ide_complete_drive_reset(drive, err);
return ide_stopped;
}
@@ -1098,11 +1103,10 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
/* For an ATAPI device, first try an ATAPI SRST. */
if (drive->media != ide_disk && !do_not_try_atapi) {
- hwgroup->resetting = 1;
pre_reset(drive);
SELECT_DRIVE(drive);
udelay (20);
- hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr);
+ hwif->OUTBSYNC(hwif, WIN_SRST, io_ports->command_addr);
ndelay(400);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
hwgroup->polling = 1;
@@ -1120,10 +1124,10 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
if (io_ports->ctl_addr == 0) {
spin_unlock_irqrestore(&ide_lock, flags);
+ ide_complete_drive_reset(drive, -ENXIO);
return ide_stopped;
}
- hwgroup->resetting = 1;
/*
* Note that we also set nIEN while resetting the device,
* to mask unwanted interrupts from the interface during the reset.
@@ -1133,14 +1137,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, io_ports->ctl_addr);
+ hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS | 6, io_ports->ctl_addr);
/* more than enough time */
udelay(10);
if (drive->quirk_list == 2)
- ctl = drive->ctl; /* clear SRST and nIEN */
+ ctl = ATA_DEVCTL_OBS; /* clear SRST and nIEN */
else
- ctl = drive->ctl | 2; /* clear SRST, leave nIEN */
- hwif->OUTBSYNC(drive, ctl, io_ports->ctl_addr);
+ ctl = ATA_DEVCTL_OBS | 2; /* clear SRST, leave nIEN */
+ hwif->OUTBSYNC(hwif, ctl, io_ports->ctl_addr);
/* more than enough time */
udelay(10);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 47af80df6872..13af72f09ec4 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -1,26 +1,11 @@
-#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
#include <linux/interrupt.h>
-#include <linux/major.h>
-#include <linux/errno.h>
-#include <linux/genhd.h>
-#include <linux/blkpg.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/bitops.h>
-#include <asm/byteorder.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
static const char *udma_str[] =
{ "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44",
"UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
@@ -90,142 +75,6 @@ static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
return min(speed, mode);
}
-/*
- * Standard (generic) timings for PIO modes, from ATA2 specification.
- * These timings are for access to the IDE data port register *only*.
- * Some drives may specify a mode, while also specifying a different
- * value for cycle_time (from drive identification data).
- */
-const ide_pio_timings_t ide_pio_timings[6] = {
- { 70, 165, 600 }, /* PIO Mode 0 */
- { 50, 125, 383 }, /* PIO Mode 1 */
- { 30, 100, 240 }, /* PIO Mode 2 */
- { 30, 80, 180 }, /* PIO Mode 3 with IORDY */
- { 25, 70, 120 }, /* PIO Mode 4 with IORDY */
- { 20, 50, 100 } /* PIO Mode 5 with IORDY (nonstandard) */
-};
-
-EXPORT_SYMBOL_GPL(ide_pio_timings);
-
-/*
- * Shared data/functions for determining best PIO mode for an IDE drive.
- * Most of this stuff originally lived in cmd640.c, and changes to the
- * ide_pio_blacklist[] table should be made with EXTREME CAUTION to avoid
- * breaking the fragile cmd640.c support.
- */
-
-/*
- * Black list. Some drives incorrectly report their maximal PIO mode,
- * at least in respect to CMD640. Here we keep info on some known drives.
- */
-static struct ide_pio_info {
- const char *name;
- int pio;
-} ide_pio_blacklist [] = {
- { "Conner Peripherals 540MB - CFS540A", 3 },
-
- { "WDC AC2700", 3 },
- { "WDC AC2540", 3 },
- { "WDC AC2420", 3 },
- { "WDC AC2340", 3 },
- { "WDC AC2250", 0 },
- { "WDC AC2200", 0 },
- { "WDC AC21200", 4 },
- { "WDC AC2120", 0 },
- { "WDC AC2850", 3 },
- { "WDC AC1270", 3 },
- { "WDC AC1170", 1 },
- { "WDC AC1210", 1 },
- { "WDC AC280", 0 },
- { "WDC AC31000", 3 },
- { "WDC AC31200", 3 },
-
- { "Maxtor 7131 AT", 1 },
- { "Maxtor 7171 AT", 1 },
- { "Maxtor 7213 AT", 1 },
- { "Maxtor 7245 AT", 1 },
- { "Maxtor 7345 AT", 1 },
- { "Maxtor 7546 AT", 3 },
- { "Maxtor 7540 AV", 3 },
-
- { "SAMSUNG SHD-3121A", 1 },
- { "SAMSUNG SHD-3122A", 1 },
- { "SAMSUNG SHD-3172A", 1 },
-
- { "ST5660A", 3 },
- { "ST3660A", 3 },
- { "ST3630A", 3 },
- { "ST3655A", 3 },
- { "ST3391A", 3 },
- { "ST3390A", 1 },
- { "ST3600A", 1 },
- { "ST3290A", 0 },
- { "ST3144A", 0 },
- { "ST3491A", 1 }, /* reports 3, should be 1 or 2 (depending on */
- /* drive) according to Seagates FIND-ATA program */
-
- { "QUANTUM ELS127A", 0 },
- { "QUANTUM ELS170A", 0 },
- { "QUANTUM LPS240A", 0 },
- { "QUANTUM LPS210A", 3 },
- { "QUANTUM LPS270A", 3 },
- { "QUANTUM LPS365A", 3 },
- { "QUANTUM LPS540A", 3 },
- { "QUANTUM LIGHTNING 540A", 3 },
- { "QUANTUM LIGHTNING 730A", 3 },
-
- { "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */
- { "QUANTUM FIREBALL_640", 3 },
- { "QUANTUM FIREBALL_1080", 3 },
- { "QUANTUM FIREBALL_1280", 3 },
- { NULL, 0 }
-};
-
-/**
- * ide_scan_pio_blacklist - check for a blacklisted drive
- * @model: Drive model string
- *
- * This routine searches the ide_pio_blacklist for an entry
- * matching the start/whole of the supplied model name.
- *
- * Returns -1 if no match found.
- * Otherwise returns the recommended PIO mode from ide_pio_blacklist[].
- */
-
-static int ide_scan_pio_blacklist (char *model)
-{
- struct ide_pio_info *p;
-
- for (p = ide_pio_blacklist; p->name != NULL; p++) {
- if (strncmp(p->name, model, strlen(p->name)) == 0)
- return p->pio;
- }
- return -1;
-}
-
-unsigned int ide_pio_cycle_time(ide_drive_t *drive, u8 pio)
-{
- struct hd_driveid *id = drive->id;
- int cycle_time = 0;
-
- if (id->field_valid & 2) {
- if (id->capability & 8)
- cycle_time = id->eide_pio_iordy;
- else
- cycle_time = id->eide_pio;
- }
-
- /* conservative "downgrade" for all pre-ATA2 drives */
- if (pio < 3) {
- if (cycle_time && cycle_time < ide_pio_timings[pio].cycle_time)
- cycle_time = 0; /* use standard timing */
- }
-
- return cycle_time ? cycle_time : ide_pio_timings[pio].cycle_time;
-}
-
-EXPORT_SYMBOL_GPL(ide_pio_cycle_time);
-
/**
* ide_get_best_pio_mode - get PIO mode from drive
* @drive: drive to consider
diff --git a/drivers/ide/ide-pio-blacklist.c b/drivers/ide/ide-pio-blacklist.c
new file mode 100644
index 000000000000..a8c2c8f8660a
--- /dev/null
+++ b/drivers/ide/ide-pio-blacklist.c
@@ -0,0 +1,94 @@
+/*
+ * PIO blacklist. Some drives incorrectly report their maximal PIO mode,
+ * at least in respect to CMD640. Here we keep info on some known drives.
+ *
+ * Changes to the ide_pio_blacklist[] should be made with EXTREME CAUTION
+ * to avoid breaking the fragile cmd640.c support.
+ */
+
+#include <linux/string.h>
+
+static struct ide_pio_info {
+ const char *name;
+ int pio;
+} ide_pio_blacklist [] = {
+ { "Conner Peripherals 540MB - CFS540A", 3 },
+
+ { "WDC AC2700", 3 },
+ { "WDC AC2540", 3 },
+ { "WDC AC2420", 3 },
+ { "WDC AC2340", 3 },
+ { "WDC AC2250", 0 },
+ { "WDC AC2200", 0 },
+ { "WDC AC21200", 4 },
+ { "WDC AC2120", 0 },
+ { "WDC AC2850", 3 },
+ { "WDC AC1270", 3 },
+ { "WDC AC1170", 1 },
+ { "WDC AC1210", 1 },
+ { "WDC AC280", 0 },
+ { "WDC AC31000", 3 },
+ { "WDC AC31200", 3 },
+
+ { "Maxtor 7131 AT", 1 },
+ { "Maxtor 7171 AT", 1 },
+ { "Maxtor 7213 AT", 1 },
+ { "Maxtor 7245 AT", 1 },
+ { "Maxtor 7345 AT", 1 },
+ { "Maxtor 7546 AT", 3 },
+ { "Maxtor 7540 AV", 3 },
+
+ { "SAMSUNG SHD-3121A", 1 },
+ { "SAMSUNG SHD-3122A", 1 },
+ { "SAMSUNG SHD-3172A", 1 },
+
+ { "ST5660A", 3 },
+ { "ST3660A", 3 },
+ { "ST3630A", 3 },
+ { "ST3655A", 3 },
+ { "ST3391A", 3 },
+ { "ST3390A", 1 },
+ { "ST3600A", 1 },
+ { "ST3290A", 0 },
+ { "ST3144A", 0 },
+ { "ST3491A", 1 }, /* reports 3, should be 1 or 2 (depending on drive)
+ according to Seagate's FIND-ATA program */
+
+ { "QUANTUM ELS127A", 0 },
+ { "QUANTUM ELS170A", 0 },
+ { "QUANTUM LPS240A", 0 },
+ { "QUANTUM LPS210A", 3 },
+ { "QUANTUM LPS270A", 3 },
+ { "QUANTUM LPS365A", 3 },
+ { "QUANTUM LPS540A", 3 },
+ { "QUANTUM LIGHTNING 540A", 3 },
+ { "QUANTUM LIGHTNING 730A", 3 },
+
+ { "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */
+ { "QUANTUM FIREBALL_640", 3 },
+ { "QUANTUM FIREBALL_1080", 3 },
+ { "QUANTUM FIREBALL_1280", 3 },
+ { NULL, 0 }
+};
+
+/**
+ * ide_scan_pio_blacklist - check for a blacklisted drive
+ * @model: Drive model string
+ *
+ * This routine searches the ide_pio_blacklist for an entry
+ * matching the start/whole of the supplied model name.
+ *
+ * Returns -1 if no match found.
+ * Otherwise returns the recommended PIO mode from ide_pio_blacklist[].
+ */
+
+int ide_scan_pio_blacklist(char *model)
+{
+ struct ide_pio_info *p;
+
+ for (p = ide_pio_blacklist; p->name != NULL; p++) {
+ if (strncmp(p->name, model, strlen(p->name)) == 0)
+ return p->pio;
+ }
+ return -1;
+}
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
index 6a8953f68e9f..03f2ef5470a3 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -33,6 +33,8 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
ide_hwif_t *hwif;
unsigned long base, ctl;
+ printk(KERN_INFO DRV_NAME ": generic PnP IDE interface\n");
+
if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0)))
return -1;
@@ -55,16 +57,15 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, base, ctl);
hw.irq = pnp_irq(dev, 0);
+ hw.chipset = ide_generic;
hwif = ide_find_port();
if (hwif) {
u8 index = hwif->index;
u8 idx[4] = { index, 0xff, 0xff, 0xff };
- ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
- printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
pnp_set_drvdata(dev, hwif);
ide_device_add(idx, NULL);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 655ec7ef568a..235ebdb29b28 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -39,6 +39,8 @@
#include <asm/uaccess.h>
#include <asm/io.h>
+static ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */
+
/**
* generic_id - add a generic drive id
* @drive: drive to make an ID block for
@@ -293,7 +295,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
hwif->OUTB(0, io_ports->feature_addr);
/* ask drive for ID */
- hwif->OUTBSYNC(drive, cmd, io_ports->command_addr);
+ hwif->OUTBSYNC(hwif, cmd, hwif->io_ports.command_addr);
timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
timeout += jiffies;
@@ -478,9 +480,9 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
printk(KERN_ERR "%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name, stat);
msleep(50);
- hwif->OUTB(drive->select.all, io_ports->device_addr);
+ SELECT_DRIVE(drive);
msleep(50);
- hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr);
+ hwif->OUTBSYNC(hwif, WIN_SRST, io_ports->command_addr);
(void)ide_busy_sleep(hwif);
rc = try_to_identify(drive, cmd);
}
@@ -516,7 +518,7 @@ static void enable_nest (ide_drive_t *drive)
printk("%s: enabling %s -- ", hwif->name, drive->id->model);
SELECT_DRIVE(drive);
msleep(50);
- hwif->OUTBSYNC(drive, EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr);
+ hwif->OUTBSYNC(hwif, EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr);
if (ide_busy_sleep(hwif)) {
printk(KERN_CONT "failed (timeout)\n");
@@ -646,8 +648,6 @@ static int ide_register_port(ide_hwif_t *hwif)
goto out;
}
- get_device(&hwif->gendev);
-
hwif->portdev = device_create_drvdata(ide_port_class, &hwif->gendev,
MKDEV(0, 0), hwif, hwif->name);
if (IS_ERR(hwif->portdev)) {
@@ -1067,7 +1067,7 @@ static int init_irq (ide_hwif_t *hwif)
if (io_ports->ctl_addr)
/* clear nIEN */
- hwif->OUTB(0x08, io_ports->ctl_addr);
+ hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS, io_ports->ctl_addr);
if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup))
goto out_unlink;
@@ -1220,16 +1220,12 @@ 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) {
- hwif->irq = ide_default_irq(hwif->io_ports.data_addr);
+ hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
if (!hwif->irq) {
printk("%s: DISABLED, NO IRQ\n", hwif->name);
return 0;
@@ -1259,7 +1255,7 @@ static int hwif_init(ide_hwif_t *hwif)
* It failed to initialise. Find the default IRQ for
* this port and try that.
*/
- hwif->irq = ide_default_irq(hwif->io_ports.data_addr);
+ 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);
@@ -1324,17 +1320,16 @@ 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 (port_ops && port_ops->port_init_devs)
- port_ops->port_init_devs(hwif);
+ if (port_ops && port_ops->init_dev)
+ port_ops->init_dev(drive);
+ }
}
static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
const struct ide_port_info *d)
{
- if (d->chipset != ide_etrax100)
- hwif->channel = port;
+ hwif->channel = port;
if (d->chipset)
hwif->chipset = d->chipset;
@@ -1480,22 +1475,29 @@ ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d)
for (; i < MAX_HWIFS; i++) {
hwif = &ide_hwifs[i];
if (hwif->chipset == ide_unknown)
- return hwif;
+ goto out_found;
}
} else {
for (i = 2; i < MAX_HWIFS; i++) {
hwif = &ide_hwifs[i];
if (hwif->chipset == ide_unknown)
- return hwif;
+ goto out_found;
}
for (i = 0; i < 2 && i < MAX_HWIFS; i++) {
hwif = &ide_hwifs[i];
if (hwif->chipset == ide_unknown)
- return hwif;
+ goto out_found;
}
}
+ printk(KERN_ERR "%s: no free slot for interface\n",
+ d ? d->name : "ide");
+
return NULL;
+
+out_found:
+ ide_init_port_data(hwif, i);
+ return hwif;
}
EXPORT_SYMBOL_GPL(ide_find_port_slot);
@@ -1519,7 +1521,7 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
continue;
}
- if (d->chipset != ide_etrax100 && (i & 1) && mate) {
+ if ((i & 1) && mate) {
hwif->mate = mate;
mate->mate = hwif;
}
@@ -1665,6 +1667,7 @@ static void ide_legacy_init_one(u8 *idx, hw_regs_t *hw, u8 port_no,
ide_std_init_ports(hw, base, ctl);
hw->irq = irq;
+ hw->chipset = d->chipset;
hwif = ide_find_port_slot(d);
if (hwif) {
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 8d6ad812a014..8af88bf0969b 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -63,7 +63,6 @@ static int proc_ide_read_imodel
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;
}
@@ -77,7 +76,7 @@ static int proc_ide_read_mate
ide_hwif_t *hwif = (ide_hwif_t *) data;
int len;
- if (hwif && hwif->mate && hwif->mate->present)
+ if (hwif && hwif->mate)
len = sprintf(page, "%s\n", hwif->mate->name);
else
len = sprintf(page, "(none)\n");
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 1e1f26331a24..b711ab96e287 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -144,9 +144,6 @@ enum {
/*************************** End of tunable parameters ***********************/
-/* Read/Write error simulation */
-#define SIMULATE_ERRORS 0
-
/* tape directions */
enum {
IDETAPE_DIR_NONE = (1 << 0),
@@ -442,7 +439,7 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
}
}
-static void idetape_update_buffers(struct ide_atapi_pc *pc)
+static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
{
struct idetape_bh *bh = pc->bh;
int count;
@@ -506,18 +503,6 @@ static struct request *idetape_next_rq_storage(ide_drive_t *drive)
return (&tape->rq_stack[tape->rq_stack_index++]);
}
-static void idetape_init_pc(struct ide_atapi_pc *pc)
-{
- memset(pc->c, 0, 12);
- pc->retries = 0;
- pc->flags = 0;
- pc->req_xfer = 0;
- pc->buf = pc->pc_buf;
- pc->buf_size = IDETAPE_PC_BUFFER_SIZE;
- pc->bh = NULL;
- pc->b_data = NULL;
-}
-
/*
* called on each failed packet command retry to analyze the request sense. We
* currently do not utilize this information.
@@ -538,8 +523,8 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
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);
+ get_unaligned_be32(&sense[3]);
+ idetape_update_buffers(drive, pc);
}
/*
@@ -634,21 +619,78 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
return 0;
}
-static ide_startstop_t idetape_request_sense_callback(ide_drive_t *drive)
+static void ide_tape_callback(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
+ struct ide_atapi_pc *pc = tape->pc;
+ int uptodate = pc->error ? 0 : 1;
debug_log(DBG_PROCS, "Enter %s\n", __func__);
- if (!tape->pc->error) {
- idetape_analyze_error(drive, tape->pc->buf);
- idetape_end_request(drive, 1, 0);
- } else {
- printk(KERN_ERR "ide-tape: Error in REQUEST SENSE itself - "
- "Aborting request!\n");
- idetape_end_request(drive, 0, 0);
+ if (tape->failed_pc == pc)
+ tape->failed_pc = NULL;
+
+ if (pc->c[0] == REQUEST_SENSE) {
+ if (uptodate)
+ idetape_analyze_error(drive, pc->buf);
+ else
+ printk(KERN_ERR "ide-tape: Error in REQUEST SENSE "
+ "itself - Aborting request!\n");
+ } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
+ struct request *rq = drive->hwif->hwgroup->rq;
+ int blocks = pc->xferred / tape->blk_size;
+
+ tape->avg_size += blocks * tape->blk_size;
+
+ if (time_after_eq(jiffies, tape->avg_time + HZ)) {
+ tape->avg_speed = tape->avg_size * HZ /
+ (jiffies - tape->avg_time) / 1024;
+ tape->avg_size = 0;
+ tape->avg_time = jiffies;
+ }
+
+ tape->first_frame += blocks;
+ rq->current_nr_sectors -= blocks;
+
+ if (pc->error)
+ uptodate = pc->error;
+ } else if (pc->c[0] == READ_POSITION && uptodate) {
+ u8 *readpos = tape->pc->buf;
+
+ debug_log(DBG_SENSE, "BOP - %s\n",
+ (readpos[0] & 0x80) ? "Yes" : "No");
+ debug_log(DBG_SENSE, "EOP - %s\n",
+ (readpos[0] & 0x40) ? "Yes" : "No");
+
+ if (readpos[0] & 0x4) {
+ printk(KERN_INFO "ide-tape: Block location is unknown"
+ "to the tape\n");
+ clear_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags);
+ uptodate = 0;
+ } else {
+ debug_log(DBG_SENSE, "Block Location - %u\n",
+ be32_to_cpu(*(u32 *)&readpos[4]));
+
+ tape->partition = readpos[1];
+ tape->first_frame = be32_to_cpu(*(u32 *)&readpos[4]);
+ set_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags);
+ }
}
- return ide_stopped;
+
+ idetape_end_request(drive, uptodate, 0);
+}
+
+static void idetape_init_pc(struct ide_atapi_pc *pc)
+{
+ memset(pc->c, 0, 12);
+ pc->retries = 0;
+ pc->flags = 0;
+ pc->req_xfer = 0;
+ pc->buf = pc->pc_buf;
+ pc->buf_size = IDETAPE_PC_BUFFER_SIZE;
+ pc->bh = NULL;
+ pc->b_data = NULL;
+ pc->callback = ide_tape_callback;
}
static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc)
@@ -657,7 +699,6 @@ static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc)
pc->c[0] = REQUEST_SENSE;
pc->c[4] = 20;
pc->req_xfer = 20;
- pc->idetape_callback = &idetape_request_sense_callback;
}
static void idetape_init_rq(struct request *rq, u8 cmd)
@@ -688,9 +729,10 @@ static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
struct ide_tape_obj *tape = drive->driver_data;
idetape_init_rq(rq, REQ_IDETAPE_PC1);
+ rq->cmd_flags |= REQ_PREEMPT;
rq->buffer = (char *) pc;
rq->rq_disk = tape->disk;
- (void) ide_do_drive_cmd(drive, rq, ide_preempt);
+ ide_do_drive_cmd(drive, rq);
}
/*
@@ -698,7 +740,7 @@ static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
* last packet command. We queue a request sense packet command in
* the head of the request list.
*/
-static ide_startstop_t idetape_retry_pc (ide_drive_t *drive)
+static void idetape_retry_pc(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc *pc;
@@ -710,7 +752,6 @@ static ide_startstop_t idetape_retry_pc (ide_drive_t *drive)
idetape_create_request_sense_cmd(pc);
set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags);
idetape_queue_pc_head(drive, pc, rq);
- return ide_stopped;
}
/*
@@ -727,7 +768,26 @@ 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 *, struct ide_atapi_pc *, unsigned int);
+static void ide_tape_handle_dsc(ide_drive_t *drive)
+{
+ idetape_tape_t *tape = drive->driver_data;
+
+ /* Media access command */
+ tape->dsc_polling_start = jiffies;
+ tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST;
+ tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT;
+ /* Allow ide.c to handle other requests */
+ idetape_postpone_request(drive);
+}
+
+static void ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+ unsigned int bcount, int write)
+{
+ if (write)
+ idetape_output_buffers(drive, pc, bcount);
+ else
+ idetape_input_buffers(drive, pc, bcount);
+}
/*
* This is the usual interrupt handler which will be called during a packet
@@ -738,169 +798,11 @@ typedef void idetape_io_buf(ide_drive_t *, struct ide_atapi_pc *, unsigned int);
*/
static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
idetape_tape_t *tape = drive->driver_data;
- struct ide_atapi_pc *pc = tape->pc;
- xfer_func_t *xferfunc;
- idetape_io_buf *iobuf;
- unsigned int temp;
-#if SIMULATE_ERRORS
- static int error_sim_count;
-#endif
- u16 bcount;
- u8 stat, ireason;
-
- debug_log(DBG_PROCS, "Enter %s - interrupt handler\n", __func__);
- /* Clear the interrupt */
- stat = ide_read_status(drive);
-
- 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
- * READ command, it will issue an irq and position
- * itself before the filemark, so that only a partial
- * data transfer will occur (which causes the DMA
- * error). In that case, we will later ask the tape
- * how much bytes of the original request were
- * actually transferred (we can't receive that
- * information from the DMA engine on most chipsets).
- */
-
- /*
- * On the contrary, a DMA error is never expected;
- * it usually indicates a hardware error or abort.
- * If the tape crosses a filemark during a READ
- * command, it will issue an irq and position itself
- * after the filemark (not before). Only a partial
- * data transfer will occur, but no DMA error.
- * (AS, 19 Apr 2001)
- */
- pc->flags |= PC_FLAG_DMA_ERROR;
- } else {
- pc->xferred = pc->req_xfer;
- idetape_update_buffers(pc);
- }
- debug_log(DBG_PROCS, "DMA finished\n");
-
- }
-
- /* No more interrupts */
- if ((stat & DRQ_STAT) == 0) {
- debug_log(DBG_SENSE, "Packet command completed, %d bytes"
- " transferred\n", pc->xferred);
-
- pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
- local_irq_enable();
-
-#if SIMULATE_ERRORS
- if ((pc->c[0] == WRITE_6 || pc->c[0] == READ_6) &&
- (++error_sim_count % 100) == 0) {
- printk(KERN_INFO "ide-tape: %s: simulating error\n",
- tape->name);
- stat |= ERR_STAT;
- }
-#endif
- if ((stat & ERR_STAT) && pc->c[0] == REQUEST_SENSE)
- stat &= ~ERR_STAT;
- if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
- /* Error detected */
- debug_log(DBG_ERR, "%s: I/O error\n", tape->name);
-
- if (pc->c[0] == REQUEST_SENSE) {
- printk(KERN_ERR "ide-tape: I/O error in request"
- " sense command\n");
- return ide_do_reset(drive);
- }
- debug_log(DBG_ERR, "[cmd %x]: check condition\n",
- pc->c[0]);
-
- /* Retry operation */
- return idetape_retry_pc(drive);
- }
- pc->error = 0;
- if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) &&
- (stat & SEEK_STAT) == 0) {
- /* Media access command */
- tape->dsc_polling_start = jiffies;
- tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST;
- tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT;
- /* Allow ide.c to handle other requests */
- idetape_postpone_request(drive);
- return ide_stopped;
- }
- if (tape->failed_pc == pc)
- tape->failed_pc = NULL;
- /* Command finished - Call the callback function */
- return pc->idetape_callback(drive);
- }
-
- 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");
- ide_dma_off(drive);
- return ide_do_reset(drive);
- }
- /* Get the number of bytes to transfer on this interrupt. */
- bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
- hwif->INB(hwif->io_ports.lbam_addr);
-
- 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) == !!(pc->flags & PC_FLAG_WRITING)) {
- /* Hopefully, we will never get here */
- printk(KERN_ERR "ide-tape: We wanted to %s, ",
- (ireason & IO) ? "Write" : "Read");
- printk(KERN_ERR "ide-tape: but the tape wants us to %s !\n",
- (ireason & IO) ? "Read" : "Write");
- return ide_do_reset(drive);
- }
- if (!(pc->flags & PC_FLAG_WRITING)) {
- /* Reading - Check that we have enough space */
- 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");
- ide_pad_transfer(drive, 0, bcount);
- ide_set_handler(drive, &idetape_pc_intr,
- IDETAPE_WAIT_CMD, NULL);
- return ide_started;
- }
- debug_log(DBG_SENSE, "The tape wants to send us more "
- "data than expected - allowing transfer\n");
- }
- iobuf = &idetape_input_buffers;
- xferfunc = hwif->input_data;
- } else {
- iobuf = &idetape_output_buffers;
- xferfunc = hwif->output_data;
- }
-
- if (pc->bh)
- iobuf(drive, pc, bcount);
- else
- xferfunc(drive, NULL, pc->cur_pos, bcount);
-
- /* Update the current position */
- pc->xferred += bcount;
- pc->cur_pos += bcount;
-
- debug_log(DBG_SENSE, "[cmd %x] transferred %d bytes on that intr.\n",
- pc->c[0], bcount);
-
- /* And set the interrupt handler again */
- ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
- return ide_started;
+ return ide_pc_intr(drive, tape->pc, idetape_pc_intr, IDETAPE_WAIT_CMD,
+ NULL, idetape_update_buffers, idetape_retry_pc,
+ ide_tape_handle_dsc, ide_tape_io_buffers);
}
/*
@@ -941,56 +843,16 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
*/
static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
idetape_tape_t *tape = drive->driver_data;
- struct ide_atapi_pc *pc = tape->pc;
- int retries = 100;
- ide_startstop_t startstop;
- u8 ireason;
-
- if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
- printk(KERN_ERR "ide-tape: Strange, packet command initiated "
- "yet DRQ isn't asserted\n");
- return startstop;
- }
- ireason = hwif->INB(hwif->io_ports.nsect_addr);
- while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) {
- printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing "
- "a packet command, retrying\n");
- udelay(100);
- ireason = hwif->INB(hwif->io_ports.nsect_addr);
- if (retries == 0) {
- printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while "
- "issuing a packet command, ignoring\n");
- ireason |= CD;
- ireason &= ~IO;
- }
- }
- if ((ireason & CD) == 0 || (ireason & IO)) {
- printk(KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing "
- "a packet command\n");
- return ide_do_reset(drive);
- }
- /* Set the interrupt routine */
- ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
-#ifdef CONFIG_BLK_DEV_IDEDMA
- /* Begin DMA, if necessary */
- if (pc->flags & PC_FLAG_DMA_IN_PROGRESS)
- hwif->dma_ops->dma_start(drive);
-#endif
- /* Send the actual packet */
- hwif->output_data(drive, NULL, pc->c, 12);
- return ide_started;
+ return ide_transfer_pc(drive, tape->pc, idetape_pc_intr,
+ IDETAPE_WAIT_CMD, NULL);
}
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;
- int dma_ok = 0;
- u16 bcount;
if (tape->pc->c[0] == REQUEST_SENSE &&
pc->c[0] == REQUEST_SENSE) {
@@ -1025,50 +887,15 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
pc->error = IDETAPE_ERROR_GENERAL;
}
tape->failed_pc = NULL;
- return pc->idetape_callback(drive);
+ pc->callback(drive);
+ return ide_stopped;
}
debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]);
pc->retries++;
- /* We haven't transferred any data yet */
- pc->xferred = 0;
- pc->cur_pos = pc->buf;
- /* Request to transfer the entire buffer at once */
- bcount = pc->req_xfer;
-
- 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 ((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 */
- 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 {
- ide_execute_pkt_cmd(drive);
- return idetape_transfer_pc(drive);
- }
-}
-
-static ide_startstop_t idetape_pc_callback(ide_drive_t *drive)
-{
- idetape_tape_t *tape = drive->driver_data;
-
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
- idetape_end_request(drive, tape->pc->error ? 0 : 1, 0);
- return ide_stopped;
+ return ide_issue_pc(drive, pc, idetape_transfer_pc,
+ IDETAPE_WAIT_CMD, NULL);
}
/* A mode sense command is used to "sense" tape parameters. */
@@ -1096,7 +923,6 @@ static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code)
pc->req_xfer = 24;
else
pc->req_xfer = 50;
- pc->idetape_callback = &idetape_pc_callback;
}
static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
@@ -1114,80 +940,41 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
printk(KERN_ERR "ide-tape: %s: I/O error, ",
tape->name);
/* Retry operation */
- return idetape_retry_pc(drive);
+ idetape_retry_pc(drive);
+ return ide_stopped;
}
pc->error = 0;
- if (tape->failed_pc == pc)
- tape->failed_pc = NULL;
} else {
pc->error = IDETAPE_ERROR_GENERAL;
tape->failed_pc = NULL;
}
- 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->xferred / tape->blk_size;
-
- tape->avg_size += blocks * tape->blk_size;
-
- if (time_after_eq(jiffies, tape->avg_time + HZ)) {
- tape->avg_speed = tape->avg_size * HZ /
- (jiffies - tape->avg_time) / 1024;
- tape->avg_size = 0;
- tape->avg_time = jiffies;
- }
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
-
- tape->first_frame += blocks;
- rq->current_nr_sectors -= blocks;
-
- if (!tape->pc->error)
- idetape_end_request(drive, 1, 0);
- else
- idetape_end_request(drive, tape->pc->error, 0);
+ pc->callback(drive);
return ide_stopped;
}
-static void idetape_create_read_cmd(idetape_tape_t *tape,
- struct ide_atapi_pc *pc,
- unsigned int length, struct idetape_bh *bh)
+static void ide_tape_create_rw_cmd(idetape_tape_t *tape,
+ struct ide_atapi_pc *pc, unsigned int length,
+ struct idetape_bh *bh, u8 opcode)
{
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->idetape_callback = &idetape_rw_callback;
pc->bh = bh;
- atomic_set(&bh->b_count, 0);
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;
-}
+ pc->flags |= PC_FLAG_DMA_OK;
-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->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->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;
+ if (opcode == READ_6) {
+ pc->c[0] = READ_6;
+ atomic_set(&bh->b_count, 0);
+ } else if (opcode == WRITE_6) {
+ pc->c[0] = WRITE_6;
+ pc->flags |= PC_FLAG_WRITING;
+ pc->b_data = bh->b_data;
+ pc->b_count = atomic_read(&bh->b_count);
+ }
}
static ide_startstop_t idetape_do_request(ide_drive_t *drive,
@@ -1211,8 +998,10 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
}
/* Retry a failed packet command */
- if (tape->failed_pc && tape->pc->c[0] == REQUEST_SENSE)
- return idetape_issue_pc(drive, tape->failed_pc);
+ if (tape->failed_pc && tape->pc->c[0] == REQUEST_SENSE) {
+ pc = tape->failed_pc;
+ goto out;
+ }
if (postponed_rq != NULL)
if (rq != postponed_rq) {
@@ -1262,14 +1051,16 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
}
if (rq->cmd[0] & REQ_IDETAPE_READ) {
pc = idetape_next_pc_storage(drive);
- idetape_create_read_cmd(tape, pc, rq->current_nr_sectors,
- (struct idetape_bh *)rq->special);
+ ide_tape_create_rw_cmd(tape, pc, rq->current_nr_sectors,
+ (struct idetape_bh *)rq->special,
+ READ_6);
goto out;
}
if (rq->cmd[0] & REQ_IDETAPE_WRITE) {
pc = idetape_next_pc_storage(drive);
- idetape_create_write_cmd(tape, pc, rq->current_nr_sectors,
- (struct idetape_bh *)rq->special);
+ ide_tape_create_rw_cmd(tape, pc, rq->current_nr_sectors,
+ (struct idetape_bh *)rq->special,
+ WRITE_6);
goto out;
}
if (rq->cmd[0] & REQ_IDETAPE_PC1) {
@@ -1284,6 +1075,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
}
BUG();
out:
+ if (test_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags))
+ pc->flags |= PC_FLAG_DRQ_INTERRUPT;
+
return idetape_issue_pc(drive, pc);
}
@@ -1447,40 +1241,6 @@ static void idetape_init_merge_buffer(idetape_tape_t *tape)
}
}
-static ide_startstop_t idetape_read_position_callback(ide_drive_t *drive)
-{
- idetape_tape_t *tape = drive->driver_data;
- u8 *readpos = tape->pc->buf;
-
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
-
- if (!tape->pc->error) {
- debug_log(DBG_SENSE, "BOP - %s\n",
- (readpos[0] & 0x80) ? "Yes" : "No");
- debug_log(DBG_SENSE, "EOP - %s\n",
- (readpos[0] & 0x40) ? "Yes" : "No");
-
- if (readpos[0] & 0x4) {
- printk(KERN_INFO "ide-tape: Block location is unknown"
- "to the tape\n");
- clear_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags);
- idetape_end_request(drive, 0, 0);
- } else {
- debug_log(DBG_SENSE, "Block Location - %u\n",
- be32_to_cpu(*(u32 *)&readpos[4]));
-
- tape->partition = readpos[1];
- tape->first_frame =
- be32_to_cpu(*(u32 *)&readpos[4]);
- set_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags);
- idetape_end_request(drive, 1, 0);
- }
- } else {
- idetape_end_request(drive, 0, 0);
- }
- return ide_stopped;
-}
-
/*
* Write a filemark if write_filemark=1. Flush the device buffers without
* writing a filemark otherwise.
@@ -1492,14 +1252,12 @@ static void idetape_create_write_filemark_cmd(ide_drive_t *drive,
pc->c[0] = WRITE_FILEMARKS;
pc->c[4] = write_filemark;
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
- pc->idetape_callback = &idetape_pc_callback;
}
static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc)
{
idetape_init_pc(pc);
pc->c[0] = TEST_UNIT_READY;
- pc->idetape_callback = &idetape_pc_callback;
}
/*
@@ -1518,12 +1276,16 @@ static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc)
static int idetape_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
{
struct ide_tape_obj *tape = drive->driver_data;
- struct request rq;
+ struct request *rq;
+ int error;
- idetape_init_rq(&rq, REQ_IDETAPE_PC1);
- rq.buffer = (char *) pc;
- rq.rq_disk = tape->disk;
- return ide_do_drive_cmd(drive, &rq, ide_wait);
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd[0] = REQ_IDETAPE_PC1;
+ rq->buffer = (char *)pc;
+ error = blk_execute_rq(drive->queue, tape->disk, rq, 0);
+ blk_put_request(rq);
+ return error;
}
static void idetape_create_load_unload_cmd(ide_drive_t *drive,
@@ -1533,7 +1295,6 @@ static void idetape_create_load_unload_cmd(ide_drive_t *drive,
pc->c[0] = START_STOP;
pc->c[4] = cmd;
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)
@@ -1585,7 +1346,6 @@ static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc)
idetape_init_pc(pc);
pc->c[0] = READ_POSITION;
pc->req_xfer = 20;
- pc->idetape_callback = &idetape_read_position_callback;
}
static int idetape_read_position(ide_drive_t *drive)
@@ -1613,7 +1373,6 @@ static void idetape_create_locate_cmd(ide_drive_t *drive,
put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[3]);
pc->c[8] = partition;
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
- pc->idetape_callback = &idetape_pc_callback;
}
static int idetape_create_prevent_cmd(ide_drive_t *drive,
@@ -1628,7 +1387,6 @@ static int idetape_create_prevent_cmd(ide_drive_t *drive,
idetape_init_pc(pc);
pc->c[0] = ALLOW_MEDIUM_REMOVAL;
pc->c[4] = prevent;
- pc->idetape_callback = &idetape_pc_callback;
return 1;
}
@@ -1700,26 +1458,33 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
struct idetape_bh *bh)
{
idetape_tape_t *tape = drive->driver_data;
- struct request rq;
+ struct request *rq;
+ int ret, errors;
debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd);
- idetape_init_rq(&rq, cmd);
- rq.rq_disk = tape->disk;
- rq.special = (void *)bh;
- rq.sector = tape->first_frame;
- rq.nr_sectors = blocks;
- rq.current_nr_sectors = blocks;
- (void) ide_do_drive_cmd(drive, &rq, ide_wait);
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd[0] = cmd;
+ rq->rq_disk = tape->disk;
+ rq->special = (void *)bh;
+ rq->sector = tape->first_frame;
+ rq->nr_sectors = blocks;
+ rq->current_nr_sectors = blocks;
+ blk_execute_rq(drive->queue, tape->disk, rq, 0);
+
+ errors = rq->errors;
+ ret = tape->blk_size * (blocks - rq->current_nr_sectors);
+ blk_put_request(rq);
if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0)
return 0;
if (tape->merge_bh)
idetape_init_merge_buffer(tape);
- if (rq.errors == IDETAPE_ERROR_GENERAL)
+ if (errors == IDETAPE_ERROR_GENERAL)
return -EIO;
- return (tape->blk_size * (blocks-rq.current_nr_sectors));
+ return ret;
}
static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc)
@@ -1728,7 +1493,6 @@ static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc)
pc->c[0] = INQUIRY;
pc->c[4] = 254;
pc->req_xfer = 254;
- pc->idetape_callback = &idetape_pc_callback;
}
static void idetape_create_rewind_cmd(ide_drive_t *drive,
@@ -1737,7 +1501,6 @@ static void idetape_create_rewind_cmd(ide_drive_t *drive,
idetape_init_pc(pc);
pc->c[0] = REZERO_UNIT;
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
- pc->idetape_callback = &idetape_pc_callback;
}
static void idetape_create_erase_cmd(struct ide_atapi_pc *pc)
@@ -1746,7 +1509,6 @@ static void idetape_create_erase_cmd(struct ide_atapi_pc *pc)
pc->c[0] = ERASE;
pc->c[1] = 1;
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
- pc->idetape_callback = &idetape_pc_callback;
}
static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd)
@@ -1756,7 +1518,6 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd)
put_unaligned(cpu_to_be32(count), (unsigned int *) &pc->c[1]);
pc->c[1] = cmd;
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
- pc->idetape_callback = &idetape_pc_callback;
}
/* Queue up a character device originated write request. */
@@ -2421,9 +2182,12 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
if (i >= MAX_HWIFS * MAX_DRIVES)
return -ENXIO;
+ lock_kernel();
tape = ide_tape_chrdev_get(i);
- if (!tape)
+ if (!tape) {
+ unlock_kernel();
return -ENXIO;
+ }
debug_log(DBG_CHRDEV, "Enter %s\n", __func__);
@@ -2482,10 +2246,12 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
}
}
}
+ unlock_kernel();
return 0;
out_put_tape:
ide_tape_put(tape);
+ unlock_kernel();
return retval;
}
@@ -2746,9 +2512,8 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
* Ensure that the number we got makes sense; limit it within
* IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX.
*/
- tape->best_dsc_rw_freq = max_t(unsigned long,
- min_t(unsigned long, t, IDETAPE_DSC_RW_MAX),
- IDETAPE_DSC_RW_MIN);
+ tape->best_dsc_rw_freq = clamp_t(unsigned long, t, IDETAPE_DSC_RW_MIN,
+ IDETAPE_DSC_RW_MAX);
printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, "
"%lums tDSC%s\n",
drive->name, tape->name, *(u16 *)&tape->caps[14],
@@ -2826,7 +2591,6 @@ static ide_driver_t idetape_driver = {
.do_request = idetape_do_request,
.end_request = idetape_end_request,
.error = __ide_error,
- .abort = __ide_abort,
#ifdef CONFIG_IDE_PROC_FS
.proc = idetape_proc,
#endif
@@ -2900,11 +2664,6 @@ static int ide_tape_probe(ide_drive_t *drive)
" the driver\n", drive->name);
goto failed;
}
- if (drive->scsi) {
- printk(KERN_INFO "ide-tape: passing drive %s to ide-scsi"
- " emulation.\n", drive->name);
- goto failed;
- }
tape = kzalloc(sizeof(idetape_tape_t), GFP_KERNEL);
if (tape == NULL) {
printk(KERN_ERR "ide-tape: %s: Can't allocate a tape struct\n",
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 0c908ca3ff79..1fbdb746dc88 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -8,28 +8,18 @@
* The big the bad and the ugly.
*/
-#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include <linux/major.h>
#include <linux/errno.h>
-#include <linux/genhd.h>
-#include <linux/blkpg.h>
#include <linux/slab.h>
-#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
-#include <linux/bitops.h>
#include <linux/scatterlist.h>
-#include <asm/byteorder.h>
-#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -62,25 +52,6 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
return ide_raw_taskfile(drive, &args, buf, 1);
}
-static int inline task_dma_ok(ide_task_t *task)
-{
- if (blk_fs_request(task->rq) || (task->tf_flags & IDE_TFLAG_FLAGGED))
- return 1;
-
- switch (task->tf.command) {
- case WIN_WRITEDMA_ONCE:
- case WIN_WRITEDMA:
- case WIN_WRITEDMA_EXT:
- case WIN_READDMA_ONCE:
- case WIN_READDMA:
- case WIN_READDMA_EXT:
- case WIN_IDENTIFY_DMA:
- return 1;
- }
-
- return 0;
-}
-
static ide_startstop_t task_no_data_intr(ide_drive_t *);
static ide_startstop_t set_geometry_intr(ide_drive_t *);
static ide_startstop_t recal_intr(ide_drive_t *);
@@ -109,13 +80,15 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
ide_tf_dump(drive->name, tf);
+ ide_set_irq(drive, 1);
+ SELECT_MASK(drive, 0);
hwif->tf_load(drive, task);
}
switch (task->data_phase) {
case TASKFILE_MULTI_OUT:
case TASKFILE_OUT:
- hwif->OUTBSYNC(drive, tf->command, hwif->io_ports.command_addr);
+ hwif->OUTBSYNC(hwif, tf->command, hwif->io_ports.command_addr);
ndelay(400); /* FIXME */
return pre_task_out_intr(drive, task->rq);
case TASKFILE_MULTI_IN:
@@ -137,8 +110,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
WAIT_WORSTCASE, NULL);
return ide_started;
default:
- if (task_dma_ok(task) == 0 || drive->using_dma == 0 ||
- dma_ops->dma_setup(drive))
+ if (drive->using_dma == 0 || dma_ops->dma_setup(drive))
return ide_stopped;
dma_ops->dma_exec_cmd(drive, tf->command);
dma_ops->dma_start(drive);
@@ -181,7 +153,6 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
if (stat & (ERR_STAT|DRQ_STAT))
return ide_error(drive, "set_geometry_intr", stat);
- BUG_ON(HWGROUP(drive)->handler != NULL);
ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL);
return ide_started;
}
@@ -225,10 +196,10 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
u8 stat;
/*
- * Last sector was transfered, wait until drive is ready.
- * This can take up to 10 usec, but we will wait max 1 ms.
+ * Last sector was transfered, wait until device is ready. This can
+ * take up to 6 ms on some ATAPI devices, so we will wait max 10 ms.
*/
- for (retries = 0; retries < 100; retries++) {
+ for (retries = 0; retries < 1000; retries++) {
stat = ide_read_status(drive);
if (stat & BUSY_STAT)
@@ -492,11 +463,12 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
{
- struct request rq;
+ struct request *rq;
+ int error;
- blk_rq_init(NULL, &rq);
- rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
- rq.buffer = buf;
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
+ rq->buffer = buf;
/*
* (ks) We transfer currently only whole sectors.
@@ -504,16 +476,19 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
* if we would find a solution to transfer any size.
* To support special commands like READ LONG.
*/
- rq.hard_nr_sectors = rq.nr_sectors = nsect;
- rq.hard_cur_sectors = rq.current_nr_sectors = nsect;
+ rq->hard_nr_sectors = rq->nr_sectors = nsect;
+ rq->hard_cur_sectors = rq->current_nr_sectors = nsect;
if (task->tf_flags & IDE_TFLAG_WRITE)
- rq.cmd_flags |= REQ_RW;
+ rq->cmd_flags |= REQ_RW;
+
+ rq->special = task;
+ task->rq = rq;
- rq.special = task;
- task->rq = &rq;
+ error = blk_execute_rq(drive->queue, NULL, rq, 0);
+ blk_put_request(rq);
- return ide_do_drive_cmd(drive, &rq, ide_wait);
+ return error;
}
EXPORT_SYMBOL(ide_raw_taskfile);
@@ -739,12 +714,14 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
struct hd_driveid *id = drive->id;
if (NULL == (void *) arg) {
- struct request rq;
+ struct request *rq;
- ide_init_drive_cmd(&rq);
- rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
+ err = blk_execute_rq(drive->queue, NULL, rq, 0);
+ blk_put_request(rq);
- return ide_do_drive_cmd(drive, &rq, ide_wait);
+ return err;
}
if (copy_from_user(args, (void __user *)arg, 4))
diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timings.c
index 3b12ffe77071..8c2f8327f487 100644
--- a/drivers/ide/ide-timing.h
+++ b/drivers/ide/ide-timings.c
@@ -1,11 +1,7 @@
-#ifndef _IDE_TIMING_H
-#define _IDE_TIMING_H
-
/*
* Copyright (c) 1999-2001 Vojtech Pavlik
- */
-
-/*
+ * Copyright (c) 2007-2008 Bartlomiej Zolnierkiewicz
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -27,27 +23,14 @@
#include <linux/kernel.h>
#include <linux/hdreg.h>
-
-#define XFER_PIO_5 0x0d
-#define XFER_UDMA_SLOW 0x4f
-
-struct ide_timing {
- short mode;
- short setup; /* t1 */
- short act8b; /* t2 for 8-bit io */
- short rec8b; /* t2i for 8-bit io */
- short cyc8b; /* t0 for 8-bit io */
- short active; /* t2 or tD */
- short recover; /* t2i or tK */
- short cycle; /* t0 */
- short udma; /* t2CYCTYP/2 */
-};
+#include <linux/ide.h>
+#include <linux/module.h>
/*
* PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds).
* These were taken from ATA/ATAPI-6 standard, rev 0a, except
* for PIO 5, which is a nonstandard extension and UDMA6, which
- * is currently supported only by Maxtor drives.
+ * is currently supported only by Maxtor drives.
*/
static struct ide_timing ide_timing[] = {
@@ -61,12 +44,10 @@ static struct ide_timing ide_timing[] = {
{ XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 },
{ XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 },
- { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 150 },
-
{ XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 },
{ XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 },
{ XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 },
-
+
{ XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 },
{ XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 },
{ XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 },
@@ -81,30 +62,46 @@ static struct ide_timing ide_timing[] = {
{ XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 },
- { -1 }
+ { 0xff }
};
-#define IDE_TIMING_SETUP 0x01
-#define IDE_TIMING_ACT8B 0x02
-#define IDE_TIMING_REC8B 0x04
-#define IDE_TIMING_CYC8B 0x08
-#define IDE_TIMING_8BIT 0x0e
-#define IDE_TIMING_ACTIVE 0x10
-#define IDE_TIMING_RECOVER 0x20
-#define IDE_TIMING_CYCLE 0x40
-#define IDE_TIMING_UDMA 0x80
-#define IDE_TIMING_ALL 0xff
-
-#define FIT(v,vmin,vmax) max_t(short,min_t(short,v,vmax),vmin)
-#define ENOUGH(v,unit) (((v)-1)/(unit)+1)
-#define EZ(v,unit) ((v)?ENOUGH(v,unit):0)
-
-#define XFER_MODE 0xf0
-#define XFER_MWDMA 0x20
-#define XFER_EPIO 0x01
-#define XFER_PIO 0x00
-
-static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int T, int UT)
+struct ide_timing *ide_timing_find_mode(u8 speed)
+{
+ struct ide_timing *t;
+
+ for (t = ide_timing; t->mode != speed; t++)
+ if (t->mode == 0xff)
+ return NULL;
+ return t;
+}
+EXPORT_SYMBOL_GPL(ide_timing_find_mode);
+
+u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio)
+{
+ struct hd_driveid *id = drive->id;
+ struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
+ u16 cycle = 0;
+
+ if (id->field_valid & 2) {
+ if (id->capability & 8)
+ cycle = id->eide_pio_iordy;
+ else
+ cycle = id->eide_pio;
+
+ /* conservative "downgrade" for all pre-ATA2 drives */
+ if (pio < 3 && cycle < t->cycle)
+ cycle = 0; /* use standard timing */
+ }
+
+ return cycle ? cycle : t->cycle;
+}
+EXPORT_SYMBOL_GPL(ide_pio_cycle_time);
+
+#define ENOUGH(v, unit) (((v) - 1) / (unit) + 1)
+#define EZ(v, unit) ((v) ? ENOUGH(v, unit) : 0)
+
+static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q,
+ int T, int UT)
{
q->setup = EZ(t->setup * 1000, T);
q->act8b = EZ(t->act8b * 1000, T);
@@ -116,92 +113,83 @@ static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int
q->udma = EZ(t->udma * 1000, UT);
}
-static void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, struct ide_timing *m, unsigned int what)
-{
- if (what & IDE_TIMING_SETUP ) m->setup = max(a->setup, b->setup);
- if (what & IDE_TIMING_ACT8B ) m->act8b = max(a->act8b, b->act8b);
- if (what & IDE_TIMING_REC8B ) m->rec8b = max(a->rec8b, b->rec8b);
- if (what & IDE_TIMING_CYC8B ) m->cyc8b = max(a->cyc8b, b->cyc8b);
- if (what & IDE_TIMING_ACTIVE ) m->active = max(a->active, b->active);
- if (what & IDE_TIMING_RECOVER) m->recover = max(a->recover, b->recover);
- if (what & IDE_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle);
- if (what & IDE_TIMING_UDMA ) m->udma = max(a->udma, b->udma);
-}
-
-static struct ide_timing* ide_timing_find_mode(short speed)
+void ide_timing_merge(struct ide_timing *a, struct ide_timing *b,
+ struct ide_timing *m, unsigned int what)
{
- struct ide_timing *t;
-
- for (t = ide_timing; t->mode != speed; t++)
- if (t->mode < 0)
- return NULL;
- return t;
+ if (what & IDE_TIMING_SETUP)
+ m->setup = max(a->setup, b->setup);
+ if (what & IDE_TIMING_ACT8B)
+ m->act8b = max(a->act8b, b->act8b);
+ if (what & IDE_TIMING_REC8B)
+ m->rec8b = max(a->rec8b, b->rec8b);
+ if (what & IDE_TIMING_CYC8B)
+ m->cyc8b = max(a->cyc8b, b->cyc8b);
+ if (what & IDE_TIMING_ACTIVE)
+ m->active = max(a->active, b->active);
+ if (what & IDE_TIMING_RECOVER)
+ m->recover = max(a->recover, b->recover);
+ if (what & IDE_TIMING_CYCLE)
+ m->cycle = max(a->cycle, b->cycle);
+ if (what & IDE_TIMING_UDMA)
+ m->udma = max(a->udma, b->udma);
}
+EXPORT_SYMBOL_GPL(ide_timing_merge);
-static int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing *t, int T, int UT)
+int ide_timing_compute(ide_drive_t *drive, u8 speed,
+ struct ide_timing *t, int T, int UT)
{
struct hd_driveid *id = drive->id;
struct ide_timing *s, p;
-/*
- * Find the mode.
- */
-
- if (!(s = ide_timing_find_mode(speed)))
+ /*
+ * Find the mode.
+ */
+ s = ide_timing_find_mode(speed);
+ if (s == NULL)
return -EINVAL;
-/*
- * Copy the timing from the table.
- */
-
+ /*
+ * Copy the timing from the table.
+ */
*t = *s;
-/*
- * If the drive is an EIDE drive, it can tell us it needs extended
- * PIO/MWDMA cycle timing.
- */
-
+ /*
+ * If the drive is an EIDE drive, it can tell us it needs extended
+ * PIO/MWDMA cycle timing.
+ */
if (id && id->field_valid & 2) { /* EIDE drive */
memset(&p, 0, sizeof(p));
- switch (speed & XFER_MODE) {
-
- case XFER_PIO:
- if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = id->eide_pio;
- else p.cycle = p.cyc8b = id->eide_pio_iordy;
- break;
-
- case XFER_MWDMA:
- p.cycle = id->eide_dma_min;
- break;
- }
+ if (speed <= XFER_PIO_2)
+ p.cycle = p.cyc8b = id->eide_pio;
+ else if (speed <= XFER_PIO_5)
+ p.cycle = p.cyc8b = id->eide_pio_iordy;
+ else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
+ p.cycle = id->eide_dma_min;
ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B);
}
-/*
- * Convert the timing to bus clock counts.
- */
-
+ /*
+ * Convert the timing to bus clock counts.
+ */
ide_timing_quantize(t, t, T, UT);
-/*
- * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T
- * and some other commands. We have to ensure that the DMA cycle timing is
- * slower/equal than the fastest PIO timing.
- */
-
- if ((speed & XFER_MODE) != XFER_PIO) {
+ /*
+ * Even in DMA/UDMA modes we still use PIO access for IDENTIFY,
+ * S.M.A.R.T and some other commands. We have to ensure that the
+ * DMA cycle timing is slower/equal than the fastest PIO timing.
+ */
+ if (speed >= XFER_SW_DMA_0) {
u8 pio = ide_get_best_pio_mode(drive, 255, 5);
ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT);
ide_timing_merge(&p, t, t, IDE_TIMING_ALL);
}
-/*
- * Lengthen active & recovery time so that cycle time is correct.
- */
-
+ /*
+ * Lengthen active & recovery time so that cycle time is correct.
+ */
if (t->act8b + t->rec8b < t->cyc8b) {
t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2;
t->rec8b = t->cyc8b - t->act8b;
@@ -214,5 +202,4 @@ static int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing
return 0;
}
-
-#endif
+EXPORT_SYMBOL_GPL(ide_timing_compute);
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index c758dcb13b14..d4a6b102a772 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -50,29 +50,16 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/genhd.h>
-#include <linux/blkpg.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/pci.h>
-#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/completion.h>
-#include <linux/reboot.h>
-#include <linux/cdrom.h>
-#include <linux/seq_file.h>
#include <linux/device.h>
-#include <linux/bitops.h>
-
-#include <asm/byteorder.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
/* default maximum number of failures */
@@ -86,15 +73,10 @@ static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR,
IDE6_MAJOR, IDE7_MAJOR,
IDE8_MAJOR, IDE9_MAJOR };
-static int idebus_parameter; /* holds the "idebus=" parameter */
-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);
-
-int noautodma = 0;
-ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */
+__cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock);
+EXPORT_SYMBOL(ide_lock);
static void ide_port_init_devices_data(ide_hwif_t *);
@@ -124,7 +106,6 @@ void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
ide_port_init_devices_data(hwif);
}
-EXPORT_SYMBOL_GPL(ide_init_port_data);
static void ide_port_init_devices_data(ide_hwif_t *hwif)
{
@@ -139,7 +120,6 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif)
drive->media = ide_disk;
drive->select.all = (unit<<4)|0xa0;
drive->hwif = hwif;
- drive->ctl = 0x08;
drive->ready_stat = READY_STAT;
drive->bad_wstat = BAD_W_STAT;
drive->special.b.recalibrate = 1;
@@ -154,73 +134,6 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif)
}
}
-/*
- * init_ide_data() sets reasonable default values into all fields
- * of all instances of the hwifs and drives, but only on the first call.
- * Subsequent calls have no effect (they don't wipe out anything).
- *
- * This routine is normally called at driver initialization time,
- * but may also be called MUCH earlier during kernel "command-line"
- * parameter processing. As such, we cannot depend on any other parts
- * of the kernel (such as memory allocation) to be functioning yet.
- *
- * This is too bad, as otherwise we could dynamically allocate the
- * ide_drive_t structs as needed, rather than always consuming memory
- * for the max possible number (MAX_HWIFS * MAX_DRIVES) of them.
- *
- * FIXME: We should stuff the setup data into __init and copy the
- * relevant hwifs/allocate them properly during boot.
- */
-#define MAGIC_COOKIE 0x12345678
-static void __init init_ide_data (void)
-{
- unsigned int index;
- static unsigned long magic_cookie = MAGIC_COOKIE;
-
- if (magic_cookie != MAGIC_COOKIE)
- return; /* already initialized */
- magic_cookie = 0;
-
- /* Initialise all interface structures */
- for (index = 0; index < MAX_HWIFS; ++index) {
- ide_hwif_t *hwif = &ide_hwifs[index];
-
- ide_init_port_data(hwif, index);
- }
-}
-
-/**
- * ide_system_bus_speed - guess bus speed
- *
- * ide_system_bus_speed() returns what we think is the system VESA/PCI
- * bus speed (in MHz). This is used for calculating interface PIO timings.
- * The default is 40 for known PCI systems, 50 otherwise.
- * The "idebus=xx" parameter can be used to override this value.
- * The actual value to be used is computed/displayed the first time
- * through. Drivers should only use this as a last resort.
- *
- * Returns a guessed speed in MHz.
- */
-
-static int ide_system_bus_speed(void)
-{
-#ifdef CONFIG_PCI
- static struct pci_device_id pci_default[] = {
- { PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID) },
- { }
- };
-#else
-#define pci_default 0
-#endif /* CONFIG_PCI */
-
- /* user supplied value */
- if (idebus_parameter)
- return idebus_parameter;
-
- /* safe default value for PCI or VESA and PCI*/
- return pci_dev_present(pci_default) ? 33 : 50;
-}
-
void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
{
ide_hwgroup_t *hwgroup = hwif->hwgroup;
@@ -315,13 +228,14 @@ void ide_unregister(ide_hwif_t *hwif)
BUG_ON(in_interrupt());
BUG_ON(irqs_disabled());
+
mutex_lock(&ide_cfg_mtx);
- spin_lock_irq(&ide_lock);
- if (!hwif->present)
- goto abort;
- __ide_port_unregister_devices(hwif);
- hwif->present = 0;
+ spin_lock_irq(&ide_lock);
+ if (hwif->present) {
+ __ide_port_unregister_devices(hwif);
+ hwif->present = 0;
+ }
spin_unlock_irq(&ide_lock);
ide_proc_unregister_port(hwif);
@@ -351,16 +265,15 @@ void ide_unregister(ide_hwif_t *hwif)
blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS);
kfree(hwif->sg_table);
unregister_blkdev(hwif->major, hwif->name);
- spin_lock_irq(&ide_lock);
if (hwif->dma_base)
ide_release_dma_engine(hwif);
+ spin_lock_irq(&ide_lock);
/* restore hwif data to pristine status */
ide_init_port_data(hwif, hwif->index);
-
-abort:
spin_unlock_irq(&ide_lock);
+
mutex_unlock(&ide_cfg_mtx);
}
@@ -371,7 +284,8 @@ void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports));
hwif->irq = hw->irq;
hwif->chipset = hw->chipset;
- hwif->gendev.parent = hw->dev;
+ hwif->dev = hw->dev;
+ hwif->gendev.parent = hw->parent ? hw->parent : hw->dev;
hwif->ack_intr = hw->ack_intr;
}
EXPORT_SYMBOL_GPL(ide_init_port_hw);
@@ -498,7 +412,7 @@ out:
int set_pio_mode(ide_drive_t *drive, int arg)
{
- struct request rq;
+ struct request *rq;
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;
@@ -512,12 +426,15 @@ int set_pio_mode(ide_drive_t *drive, int arg)
if (drive->special.b.set_tune)
return -EBUSY;
- ide_init_drive_cmd(&rq);
- rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
drive->tune_req = (u8) arg;
drive->special.b.set_tune = 1;
- (void) ide_do_drive_cmd(drive, &rq, ide_wait);
+
+ blk_execute_rq(drive->queue, NULL, rq, 0);
+ blk_put_request(rq);
+
return 0;
}
@@ -537,25 +454,11 @@ static int set_unmaskirq(ide_drive_t *drive, int arg)
return 0;
}
-/**
- * system_bus_clock - clock guess
- *
- * External version of the bus clock guess used by very old IDE drivers
- * for things like VLB timings. Should not be used.
- */
-
-int system_bus_clock (void)
-{
- return system_bus_speed;
-}
-
-EXPORT_SYMBOL(system_bus_clock);
-
static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
{
ide_drive_t *drive = dev->driver_data;
ide_hwif_t *hwif = HWIF(drive);
- struct request rq;
+ struct request *rq;
struct request_pm_state rqpm;
ide_task_t args;
int ret;
@@ -564,18 +467,19 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
if (!(drive->dn % 2))
ide_acpi_get_timing(hwif);
- blk_rq_init(NULL, &rq);
memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args));
- rq.cmd_type = REQ_TYPE_PM_SUSPEND;
- rq.special = &args;
- rq.data = &rqpm;
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_PM_SUSPEND;
+ rq->special = &args;
+ rq->data = &rqpm;
rqpm.pm_step = ide_pm_state_start_suspend;
if (mesg.event == PM_EVENT_PRETHAW)
mesg.event = PM_EVENT_FREEZE;
rqpm.pm_state = mesg.event;
- ret = ide_do_drive_cmd(drive, &rq, ide_wait);
+ ret = blk_execute_rq(drive->queue, NULL, rq, 0);
+ blk_put_request(rq);
/* only call ACPI _PS3 after both drivers are suspended */
if (!ret && (((drive->dn % 2) && hwif->drives[0].present
&& hwif->drives[1].present)
@@ -589,7 +493,7 @@ static int generic_ide_resume(struct device *dev)
{
ide_drive_t *drive = dev->driver_data;
ide_hwif_t *hwif = HWIF(drive);
- struct request rq;
+ struct request *rq;
struct request_pm_state rqpm;
ide_task_t args;
int err;
@@ -602,16 +506,18 @@ static int generic_ide_resume(struct device *dev)
ide_acpi_exec_tfs(drive);
- blk_rq_init(NULL, &rq);
memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args));
- rq.cmd_type = REQ_TYPE_PM_RESUME;
- rq.special = &args;
- rq.data = &rqpm;
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_PM_RESUME;
+ rq->cmd_flags |= REQ_PREEMPT;
+ rq->special = &args;
+ rq->data = &rqpm;
rqpm.pm_step = ide_pm_state_start_resume;
rqpm.pm_state = PM_EVENT_ON;
- err = ide_do_drive_cmd(drive, &rq, ide_head_wait);
+ err = blk_execute_rq(drive->queue, NULL, rq, 1);
+ blk_put_request(rq);
if (err == 0 && dev->driver) {
ide_driver_t *drv = to_ide_driver(dev->driver);
@@ -623,6 +529,22 @@ static int generic_ide_resume(struct device *dev)
return err;
}
+static int generic_drive_reset(ide_drive_t *drive)
+{
+ struct request *rq;
+ int ret = 0;
+
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd_len = 1;
+ rq->cmd[0] = REQ_DRIVE_RESET;
+ rq->cmd_flags |= REQ_SOFTBARRIER;
+ if (blk_execute_rq(drive->queue, NULL, rq, 1))
+ ret = rq->errors;
+ blk_put_request(rq);
+ return ret;
+}
+
int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev,
unsigned int cmd, unsigned long arg)
{
@@ -697,33 +619,8 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- /*
- * Abort the current command on the
- * group if there is one, taking
- * care not to allow anything else
- * to be queued and to die on the
- * spot if we miss one somehow
- */
-
- spin_lock_irqsave(&ide_lock, flags);
-
- if (HWGROUP(drive)->resetting) {
- spin_unlock_irqrestore(&ide_lock, flags);
- return -EBUSY;
- }
-
- ide_abort(drive, "drive reset");
+ return generic_drive_reset(drive);
- BUG_ON(HWGROUP(drive)->handler);
-
- /* Ensure nothing gets queued after we
- drop the lock. Reset will clear the busy */
-
- HWGROUP(drive)->busy = 1;
- spin_unlock_irqrestore(&ide_lock, flags);
- (void) ide_do_reset(drive);
-
- return 0;
case HDIO_GET_BUSSTATE:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -764,212 +661,6 @@ set_val:
EXPORT_SYMBOL(generic_ide_ioctl);
-/*
- * stridx() returns the offset of c within s,
- * or -1 if c is '\0' or not found within s.
- */
-static int __init stridx (const char *s, char c)
-{
- char *i = strchr(s, c);
- return (i && c) ? i - s : -1;
-}
-
-/*
- * match_parm() does parsing for ide_setup():
- *
- * 1. the first char of s must be '='.
- * 2. if the remainder matches one of the supplied keywords,
- * the index (1 based) of the keyword is negated and returned.
- * 3. if the remainder is a series of no more than max_vals numbers
- * separated by commas, the numbers are saved in vals[] and a
- * count of how many were saved is returned. Base10 is assumed,
- * and base16 is allowed when prefixed with "0x".
- * 4. otherwise, zero is returned.
- */
-static int __init match_parm (char *s, const char *keywords[], int vals[], int max_vals)
-{
- static const char *decimal = "0123456789";
- static const char *hex = "0123456789abcdef";
- int i, n;
-
- if (*s++ == '=') {
- /*
- * Try matching against the supplied keywords,
- * and return -(index+1) if we match one
- */
- if (keywords != NULL) {
- for (i = 0; *keywords != NULL; ++i) {
- if (!strcmp(s, *keywords++))
- return -(i+1);
- }
- }
- /*
- * Look for a series of no more than "max_vals"
- * numeric values separated by commas, in base10,
- * or base16 when prefixed with "0x".
- * Return a count of how many were found.
- */
- for (n = 0; (i = stridx(decimal, *s)) >= 0;) {
- vals[n] = i;
- while ((i = stridx(decimal, *++s)) >= 0)
- vals[n] = (vals[n] * 10) + i;
- if (*s == 'x' && !vals[n]) {
- while ((i = stridx(hex, *++s)) >= 0)
- vals[n] = (vals[n] * 0x10) + i;
- }
- if (++n == max_vals)
- break;
- if (*s == ',' || *s == ';')
- ++s;
- }
- if (!*s)
- return n;
- }
- return 0; /* zero = nothing matched */
-}
-
-/*
- * ide_setup() gets called VERY EARLY during initialization,
- * to handle kernel "command line" strings beginning with "hdx=" or "ide".
- *
- * Remember to update Documentation/ide/ide.txt if you change something here.
- */
-static int __init ide_setup(char *s)
-{
- 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);
-
- if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */
- return 0; /* driver and not us */
-
- if (strncmp(s,"ide",3) && strncmp(s,"idebus",6) && strncmp(s,"hd",2))
- return 0;
-
- printk(KERN_INFO "ide_setup: %s", s);
- init_ide_data ();
-
-#ifdef CONFIG_BLK_DEV_IDEDOUBLER
- if (!strcmp(s, "ide=doubler")) {
- extern int ide_doubler;
-
- printk(" : Enabled support for IDE doublers\n");
- ide_doubler = 1;
- goto obsolete_option;
- }
-#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
-
- if (!strcmp(s, "ide=nodma")) {
- printk(" : Prevented DMA\n");
- noautodma = 1;
- goto obsolete_option;
- }
-
-#ifdef CONFIG_BLK_DEV_IDEACPI
- if (!strcmp(s, "ide=noacpi")) {
- //printk(" : Disable IDE ACPI support.\n");
- ide_noacpi = 1;
- goto obsolete_option;
- }
- if (!strcmp(s, "ide=acpigtf")) {
- //printk(" : Enable IDE ACPI _GTF support.\n");
- ide_acpigtf = 1;
- goto obsolete_option;
- }
- if (!strcmp(s, "ide=acpionboot")) {
- //printk(" : Call IDE ACPI methods on boot.\n");
- ide_acpionboot = 1;
- goto obsolete_option;
- }
-#endif /* CONFIG_BLK_DEV_IDEACPI */
-
- /*
- * Look for drive options: "hdx="
- */
- if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
- const char *hd_words[] = {
- "none", "noprobe", "nowerr", "cdrom", "nodma",
- "-6", "-7", "-8", "-9", "-10",
- "noflush", "remap", "remap63", "scsi", NULL };
- unit = s[2] - 'a';
- hw = unit / MAX_DRIVES;
- unit = unit % MAX_DRIVES;
- hwif = &ide_hwifs[hw];
- drive = &hwif->drives[unit];
- if (strncmp(s + 4, "ide-", 4) == 0) {
- strlcpy(drive->driver_req, s + 4, sizeof(drive->driver_req));
- goto obsolete_option;
- }
- switch (match_parm(&s[3], hd_words, vals, 3)) {
- case -1: /* "none" */
- case -2: /* "noprobe" */
- drive->noprobe = 1;
- goto obsolete_option;
- case -3: /* "nowerr" */
- drive->bad_wstat = BAD_R_STAT;
- goto obsolete_option;
- case -4: /* "cdrom" */
- drive->present = 1;
- drive->media = ide_cdrom;
- /* an ATAPI device ignores DRDY */
- drive->ready_stat = 0;
- goto obsolete_option;
- case -5: /* nodma */
- drive->nodma = 1;
- goto obsolete_option;
- case -11: /* noflush */
- drive->noflush = 1;
- goto obsolete_option;
- case -12: /* "remap" */
- drive->remap_0_to_1 = 1;
- goto obsolete_option;
- case -13: /* "remap63" */
- drive->sect0 = 63;
- goto obsolete_option;
- case -14: /* "scsi" */
- drive->scsi = 1;
- goto obsolete_option;
- case 3: /* cyl,head,sect */
- drive->media = ide_disk;
- drive->ready_stat = READY_STAT;
- drive->cyl = drive->bios_cyl = vals[0];
- drive->head = drive->bios_head = vals[1];
- drive->sect = drive->bios_sect = vals[2];
- drive->present = 1;
- drive->forced_geom = 1;
- goto obsolete_option;
- default:
- goto bad_option;
- }
- }
-
- if (s[0] != 'i' || s[1] != 'd' || s[2] != 'e')
- goto bad_option;
- /*
- * Look for bus speed option: "idebus="
- */
- if (s[3] == 'b' && s[4] == 'u' && s[5] == 's') {
- if (match_parm(&s[6], NULL, vals, 1) != 1)
- goto bad_option;
- if (vals[0] >= 20 && vals[0] <= 66) {
- idebus_parameter = vals[0];
- } else
- printk(" -- BAD BUS SPEED! Expected value from 20 to 66");
- goto obsolete_option;
- }
-
-bad_option:
- printk(" -- BAD OPTION\n");
- return 1;
-obsolete_option:
- printk(" -- OBSOLETE OPTION, WILL BE REMOVED SOON!\n");
- return 1;
-}
-
-EXPORT_SYMBOL(ide_lock);
-
static int ide_bus_match(struct device *dev, struct device_driver *drv)
{
return 1;
@@ -1094,13 +785,6 @@ 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);
@@ -1288,11 +972,6 @@ static int __init ide_init(void)
int ret;
printk(KERN_INFO "Uniform Multi-Platform E-IDE driver\n");
- system_bus_speed = ide_system_bus_speed();
-
- printk(KERN_INFO "ide: Assuming %dMHz system bus speed "
- "for PIO modes%s\n", system_bus_speed,
- idebus_parameter ? "" : "; override with idebus=xx");
ret = bus_register(&ide_bus_type);
if (ret < 0) {
@@ -1305,9 +984,6 @@ static int __init ide_init(void)
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();
@@ -1319,32 +995,7 @@ out_port_class:
return ret;
}
-#ifdef MODULE
-static char *options = NULL;
-module_param(options, charp, 0);
-MODULE_LICENSE("GPL");
-
-static void __init parse_options (char *line)
-{
- char *next = line;
-
- if (line == NULL || !*line)
- return;
- while ((line = next) != NULL) {
- if ((next = strchr(line,' ')) != NULL)
- *next++ = 0;
- if (!ide_setup(line))
- printk (KERN_INFO "Unknown option '%s'\n", line);
- }
-}
-
-int __init init_module (void)
-{
- parse_options(options);
- return ide_init();
-}
-
-void __exit cleanup_module (void)
+static void __exit ide_exit(void)
{
proc_ide_destroy();
@@ -1353,10 +1004,7 @@ void __exit cleanup_module (void)
bus_unregister(&ide_bus_type);
}
-#else /* !MODULE */
-
-__setup("", ide_setup);
-
module_init(ide_init);
+module_exit(ide_exit);
-#endif /* MODULE */
+MODULE_LICENSE("GPL");
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c
index 90c65cf97448..4ec19737f3c5 100644
--- a/drivers/ide/legacy/ali14xx.c
+++ b/drivers/ide/legacy/ali14xx.c
@@ -116,11 +116,12 @@ 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 = ide_vlb_clk ? ide_vlb_clk : system_bus_clock();
+ int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
+ struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
/* calculate timing, according to PIO mode */
time1 = ide_pio_cycle_time(drive, pio);
- time2 = ide_pio_timings[pio].active_time;
+ time2 = t->active;
param3 = param1 = (time2 * bus_speed + 999) / 1000;
param4 = param2 = (time1 * bus_speed + 999) / 1000 - param1;
if (pio < 3) {
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c
index 5c730e4dd735..0497e7f85b09 100644
--- a/drivers/ide/legacy/buddha.c
+++ b/drivers/ide/legacy/buddha.c
@@ -138,6 +138,8 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base,
hw->irq = IRQ_AMIGA_PORTS;
hw->ack_intr = ack_intr;
+
+ hw->chipset = ide_generic;
}
/*
@@ -225,7 +227,6 @@ fail_base2:
if (hwif) {
u8 index = hwif->index;
- ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
idx[i] = index;
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c
index 9e449a0c623f..129a812bb57f 100644
--- a/drivers/ide/legacy/falconide.c
+++ b/drivers/ide/legacy/falconide.c
@@ -81,6 +81,8 @@ static void __init falconide_setup_ports(hw_regs_t *hw)
hw->irq = IRQ_MFP_IDE;
hw->ack_intr = NULL;
+
+ hw->chipset = ide_generic;
}
/*
@@ -109,7 +111,6 @@ static int __init falconide_init(void)
u8 index = hwif->index;
u8 idx[4] = { index, 0xff, 0xff, 0xff };
- ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
/* Atari has a byte-swapped IDE interface */
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
index a9c2593a898c..7e74b20202df 100644
--- a/drivers/ide/legacy/gayle.c
+++ b/drivers/ide/legacy/gayle.c
@@ -16,6 +16,7 @@
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/zorro.h>
+#include <linux/module.h>
#include <asm/setup.h>
#include <asm/amigahw.h>
@@ -62,7 +63,8 @@
GAYLE_NUM_HWIFS-1)
#define GAYLE_HAS_CONTROL_REG (!ide_doubler)
#define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000)
-int ide_doubler = 0; /* support IDE doublers? */
+
+static int ide_doubler;
module_param_named(doubler, ide_doubler, bool, 0);
MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
@@ -112,6 +114,8 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base,
hw->irq = IRQ_AMIGA_PORTS;
hw->ack_intr = ack_intr;
+
+ hw->chipset = ide_generic;
}
/*
@@ -181,7 +185,6 @@ found:
if (hwif) {
u8 index = hwif->index;
- ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
idx[i] = index;
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
deleted file mode 100644
index abdedf56643e..000000000000
--- a/drivers/ide/legacy/hd.c
+++ /dev/null
@@ -1,815 +0,0 @@
-/*
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * This is the low-level hd interrupt support. It traverses the
- * request-list, using interrupts to jump between functions. As
- * all the functions are called within interrupts, we may not
- * sleep. Special care is recommended.
- *
- * modified by Drew Eckhardt to check nr of hd's from the CMOS.
- *
- * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
- * in the early extended-partition checks and added DM partitions
- *
- * IRQ-unmask, drive-id, multiple-mode, support for ">16 heads",
- * and general streamlining by Mark Lord.
- *
- * Removed 99% of above. Use Mark's ide driver for those options.
- * This is now a lightweight ST-506 driver. (Paul Gortmaker)
- *
- * Modified 1995 Russell King for ARM processor.
- *
- * Bugfix: max_sectors must be <= 255 or the wheels tend to come
- * off in a hurry once you queue things up - Paul G. 02/2001
- */
-
-/* Uncomment the following if you want verbose error reports. */
-/* #define VERBOSE_ERRORS */
-
-#include <linux/blkdev.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/genhd.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/mc146818rtc.h> /* CMOS defines */
-#include <linux/init.h>
-#include <linux/blkpg.h>
-#include <linux/hdreg.h>
-
-#define REALLY_SLOW_IO
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#ifdef __arm__
-#undef HD_IRQ
-#endif
-#include <asm/irq.h>
-#ifdef __arm__
-#define HD_IRQ IRQ_HARDDISK
-#endif
-
-/* Hd controller regster ports */
-
-#define HD_DATA 0x1f0 /* _CTL when writing */
-#define HD_ERROR 0x1f1 /* see err-bits */
-#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */
-#define HD_SECTOR 0x1f3 /* starting sector */
-#define HD_LCYL 0x1f4 /* starting cylinder */
-#define HD_HCYL 0x1f5 /* high byte of starting cyl */
-#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */
-#define HD_STATUS 0x1f7 /* see status-bits */
-#define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */
-#define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */
-#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */
-
-#define HD_CMD 0x3f6 /* used for resets */
-#define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */
-
-/* Bits of HD_STATUS */
-#define ERR_STAT 0x01
-#define INDEX_STAT 0x02
-#define ECC_STAT 0x04 /* Corrected error */
-#define DRQ_STAT 0x08
-#define SEEK_STAT 0x10
-#define SERVICE_STAT SEEK_STAT
-#define WRERR_STAT 0x20
-#define READY_STAT 0x40
-#define BUSY_STAT 0x80
-
-/* Bits for HD_ERROR */
-#define MARK_ERR 0x01 /* Bad address mark */
-#define TRK0_ERR 0x02 /* couldn't find track 0 */
-#define ABRT_ERR 0x04 /* Command aborted */
-#define MCR_ERR 0x08 /* media change request */
-#define ID_ERR 0x10 /* ID field not found */
-#define MC_ERR 0x20 /* media changed */
-#define ECC_ERR 0x40 /* Uncorrectable ECC error */
-#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */
-#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
-
-static DEFINE_SPINLOCK(hd_lock);
-static struct request_queue *hd_queue;
-
-#define MAJOR_NR HD_MAJOR
-#define QUEUE (hd_queue)
-#define CURRENT elv_next_request(hd_queue)
-
-#define TIMEOUT_VALUE (6*HZ)
-#define HD_DELAY 0
-
-#define MAX_ERRORS 16 /* Max read/write errors/sector */
-#define RESET_FREQ 8 /* Reset controller every 8th retry */
-#define RECAL_FREQ 4 /* Recalibrate every 4th retry */
-#define MAX_HD 2
-
-#define STAT_OK (READY_STAT|SEEK_STAT)
-#define OK_STATUS(s) (((s)&(STAT_OK|(BUSY_STAT|WRERR_STAT|ERR_STAT)))==STAT_OK)
-
-static void recal_intr(void);
-static void bad_rw_intr(void);
-
-static int reset;
-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;
- 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);
-#else
-static struct hd_i_struct hd_info[MAX_HD];
-static int NR_HD;
-#endif
-
-static struct gendisk *hd_gendisk[MAX_HD];
-
-static struct timer_list device_timer;
-
-#define TIMEOUT_VALUE (6*HZ)
-
-#define SET_TIMER \
- do { \
- mod_timer(&device_timer, jiffies + TIMEOUT_VALUE); \
- } while (0)
-
-static void (*do_hd)(void) = NULL;
-#define SET_HANDLER(x) \
-if ((do_hd = (x)) != NULL) \
- SET_TIMER; \
-else \
- del_timer(&device_timer);
-
-
-#if (HD_DELAY > 0)
-
-#include <asm/i8253.h>
-
-unsigned long last_req;
-
-unsigned long read_timer(void)
-{
- unsigned long t, flags;
- int i;
-
- spin_lock_irqsave(&i8253_lock, flags);
- t = jiffies * 11932;
- outb_p(0, 0x43);
- i = inb_p(0x40);
- i |= inb(0x40) << 8;
- spin_unlock_irqrestore(&i8253_lock, flags);
- return(t - i);
-}
-#endif
-
-static void __init hd_setup(char *str, int *ints)
-{
- int hdind = 0;
-
- if (ints[0] != 3)
- return;
- if (hd_info[0].head != 0)
- hdind = 1;
- hd_info[hdind].head = ints[2];
- hd_info[hdind].sect = ints[3];
- hd_info[hdind].cyl = ints[1];
- hd_info[hdind].wpcom = 0;
- hd_info[hdind].lzone = ints[1];
- hd_info[hdind].ctl = (ints[2] > 8 ? 8 : 0);
- NR_HD = hdind+1;
-}
-
-static void dump_status(const char *msg, unsigned int stat)
-{
- char *name = "hd?";
- if (CURRENT)
- name = CURRENT->rq_disk->disk_name;
-
-#ifdef VERBOSE_ERRORS
- printk("%s: %s: status=0x%02x { ", name, msg, stat & 0xff);
- if (stat & BUSY_STAT) printk("Busy ");
- if (stat & READY_STAT) printk("DriveReady ");
- if (stat & WRERR_STAT) printk("WriteFault ");
- if (stat & SEEK_STAT) printk("SeekComplete ");
- if (stat & DRQ_STAT) printk("DataRequest ");
- if (stat & ECC_STAT) printk("CorrectedError ");
- if (stat & INDEX_STAT) printk("Index ");
- if (stat & ERR_STAT) printk("Error ");
- printk("}\n");
- if ((stat & ERR_STAT) == 0) {
- hd_error = 0;
- } else {
- hd_error = inb(HD_ERROR);
- printk("%s: %s: error=0x%02x { ", name, msg, hd_error & 0xff);
- if (hd_error & BBD_ERR) printk("BadSector ");
- if (hd_error & ECC_ERR) printk("UncorrectableError ");
- if (hd_error & ID_ERR) printk("SectorIdNotFound ");
- if (hd_error & ABRT_ERR) printk("DriveStatusError ");
- if (hd_error & TRK0_ERR) printk("TrackZeroNotFound ");
- if (hd_error & MARK_ERR) printk("AddrMarkNotFound ");
- printk("}");
- if (hd_error & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) {
- printk(", CHS=%d/%d/%d", (inb(HD_HCYL)<<8) + inb(HD_LCYL),
- inb(HD_CURRENT) & 0xf, inb(HD_SECTOR));
- if (CURRENT)
- printk(", sector=%ld", CURRENT->sector);
- }
- printk("\n");
- }
-#else
- printk("%s: %s: status=0x%02x.\n", name, msg, stat & 0xff);
- if ((stat & ERR_STAT) == 0) {
- hd_error = 0;
- } else {
- hd_error = inb(HD_ERROR);
- printk("%s: %s: error=0x%02x.\n", name, msg, hd_error & 0xff);
- }
-#endif
-}
-
-static void check_status(void)
-{
- int i = inb_p(HD_STATUS);
-
- if (!OK_STATUS(i)) {
- dump_status("check_status", i);
- bad_rw_intr();
- }
-}
-
-static int controller_busy(void)
-{
- int retries = 100000;
- unsigned char status;
-
- do {
- status = inb_p(HD_STATUS);
- } while ((status & BUSY_STAT) && --retries);
- return status;
-}
-
-static int status_ok(void)
-{
- unsigned char status = inb_p(HD_STATUS);
-
- if (status & BUSY_STAT)
- return 1; /* Ancient, but does it make sense??? */
- if (status & WRERR_STAT)
- return 0;
- if (!(status & READY_STAT))
- return 0;
- if (!(status & SEEK_STAT))
- return 0;
- return 1;
-}
-
-static int controller_ready(unsigned int drive, unsigned int head)
-{
- int retry = 100;
-
- do {
- if (controller_busy() & BUSY_STAT)
- return 0;
- outb_p(0xA0 | (drive<<4) | head, HD_CURRENT);
- if (status_ok())
- return 1;
- } while (--retry);
- return 0;
-}
-
-static void hd_out(struct hd_i_struct *disk,
- unsigned int nsect,
- unsigned int sect,
- unsigned int head,
- unsigned int cyl,
- unsigned int cmd,
- void (*intr_addr)(void))
-{
- unsigned short port;
-
-#if (HD_DELAY > 0)
- while (read_timer() - last_req < HD_DELAY)
- /* nothing */;
-#endif
- if (reset)
- return;
- if (!controller_ready(disk->unit, head)) {
- reset = 1;
- 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);
-}
-
-static void hd_request (void);
-
-static int drive_busy(void)
-{
- unsigned int i;
- unsigned char c;
-
- for (i = 0; i < 500000 ; i++) {
- c = inb_p(HD_STATUS);
- if ((c & (BUSY_STAT | READY_STAT | SEEK_STAT)) == STAT_OK)
- return 0;
- }
- dump_status("reset timed out", c);
- return 1;
-}
-
-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();
- 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);
-}
-
-static void reset_hd(void)
-{
- static int i;
-
-repeat:
- if (reset) {
- reset = 0;
- i = -1;
- reset_controller();
- } else {
- check_status();
- if (reset)
- goto 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);
- if (reset)
- goto repeat;
- } else
- hd_request();
-}
-
-/*
- * Ok, don't know what to do with the unexpected interrupts: on some machines
- * doing a reset and a retry seems to result in an eternal loop. Right now I
- * ignore it, and just set the timeout.
- *
- * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the
- * drive enters "idle", "standby", or "sleep" mode, so if the status looks
- * "good", we just ignore the interrupt completely.
- */
-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);
- SET_TIMER;
- }
-}
-
-/*
- * bad_rw_intr() now tries to be a bit smarter and does things
- * according to the error returned by the controller.
- * -Mika Liljeberg (liljeber@cs.Helsinki.FI)
- */
-static void bad_rw_intr(void)
-{
- struct request *req = CURRENT;
- if (req != NULL) {
- struct hd_i_struct *disk = req->rq_disk->private_data;
- if (++req->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) {
- end_request(req, 0);
- disk->special_op = disk->recalibrate = 1;
- } else if (req->errors % RESET_FREQ == 0)
- reset = 1;
- else if ((hd_error & TRK0_ERR) || req->errors % RECAL_FREQ == 0)
- disk->special_op = disk->recalibrate = 1;
- /* Otherwise just retry */
- }
-}
-
-static inline int wait_DRQ(void)
-{
- int retries;
- int stat;
-
- for (retries = 0; retries < 100000; retries++) {
- stat = inb_p(HD_STATUS);
- if (stat & DRQ_STAT)
- return 0;
- }
- dump_status("wait_DRQ", stat);
- return -1;
-}
-
-static void read_intr(void)
-{
- struct request *req;
- int i, retries = 100000;
-
- do {
- i = (unsigned) inb_p(HD_STATUS);
- if (i & BUSY_STAT)
- continue;
- if (!OK_STATUS(i))
- break;
- if (i & DRQ_STAT)
- goto ok_to_read;
- } while (--retries > 0);
- dump_status("read_intr", i);
- bad_rw_intr();
- hd_request();
- return;
-ok_to_read:
- req = CURRENT;
- insw(HD_DATA, req->buffer, 256);
- req->sector++;
- req->buffer += 512;
- req->errors = 0;
- i = --req->nr_sectors;
- --req->current_nr_sectors;
-#ifdef DEBUG
- printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n",
- req->rq_disk->disk_name, req->sector, req->nr_sectors,
- req->buffer+512);
-#endif
- if (req->current_nr_sectors <= 0)
- end_request(req, 1);
- if (i > 0) {
- SET_HANDLER(&read_intr);
- return;
- }
- (void) inb_p(HD_STATUS);
-#if (HD_DELAY > 0)
- last_req = read_timer();
-#endif
- if (elv_next_request(QUEUE))
- hd_request();
- return;
-}
-
-static void write_intr(void)
-{
- struct request *req = CURRENT;
- int i;
- int retries = 100000;
-
- do {
- i = (unsigned) inb_p(HD_STATUS);
- if (i & BUSY_STAT)
- continue;
- if (!OK_STATUS(i))
- break;
- if ((req->nr_sectors <= 1) || (i & DRQ_STAT))
- goto ok_to_write;
- } while (--retries > 0);
- dump_status("write_intr", i);
- bad_rw_intr();
- hd_request();
- return;
-ok_to_write:
- req->sector++;
- i = --req->nr_sectors;
- --req->current_nr_sectors;
- req->buffer += 512;
- if (!i || (req->bio && req->current_nr_sectors <= 0))
- end_request(req, 1);
- if (i > 0) {
- SET_HANDLER(&write_intr);
- outsw(HD_DATA, req->buffer, 256);
- local_irq_enable();
- } else {
-#if (HD_DELAY > 0)
- last_req = read_timer();
-#endif
- hd_request();
- }
- return;
-}
-
-static void recal_intr(void)
-{
- check_status();
-#if (HD_DELAY > 0)
- last_req = read_timer();
-#endif
- hd_request();
-}
-
-/*
- * This is another of the error-routines I don't know what to do with. The
- * best idea seems to just set reset, and start all over again.
- */
-static void hd_times_out(unsigned long dummy)
-{
- char *name;
-
- do_hd = NULL;
-
- if (!CURRENT)
- return;
-
- disable_irq(HD_IRQ);
- local_irq_enable();
- reset = 1;
- name = CURRENT->rq_disk->disk_name;
- printk("%s: timeout\n", name);
- if (++CURRENT->errors >= MAX_ERRORS) {
-#ifdef DEBUG
- printk("%s: too many errors\n", name);
-#endif
- end_request(CURRENT, 0);
- }
- local_irq_disable();
- hd_request();
- enable_irq(HD_IRQ);
-}
-
-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);
- return reset;
- }
- if (disk->head > 16) {
- 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;
- return 1;
-}
-
-/*
- * The driver enables interrupts as much as possible. In order to do this,
- * (a) the device-interrupt is disabled before entering hd_request(),
- * and (b) the timeout-interrupt is disabled before the sti().
- *
- * Interrupts are still masked (by default) whenever we are exchanging
- * data/cmds with a drive, because some drives seem to have very poor
- * tolerance for latency during I/O. The IDE driver has support to unmask
- * interrupts for non-broken hardware, so use that driver if required.
- */
-static void hd_request(void)
-{
- unsigned int block, nsect, sec, track, head, cyl;
- struct hd_i_struct *disk;
- struct request *req;
-
- if (do_hd)
- return;
-repeat:
- del_timer(&device_timer);
- local_irq_enable();
-
- req = CURRENT;
- if (!req) {
- do_hd = NULL;
- return;
- }
-
- if (reset) {
- local_irq_disable();
- reset_hd();
- return;
- }
- disk = req->rq_disk->private_data;
- block = req->sector;
- nsect = req->nr_sectors;
- if (block >= get_capacity(req->rq_disk) ||
- ((block+nsect) > get_capacity(req->rq_disk))) {
- printk("%s: bad access: block=%d, count=%d\n",
- req->rq_disk->disk_name, block, nsect);
- end_request(req, 0);
- goto repeat;
- }
-
- if (disk->special_op) {
- if (do_special_op(disk, req))
- goto repeat;
- return;
- }
- sec = block % disk->sect + 1;
- track = block / disk->sect;
- head = track % disk->head;
- cyl = track / disk->head;
-#ifdef DEBUG
- printk("%s: %sing: CHS=%d/%d/%d, sectors=%d, buffer=%p\n",
- req->rq_disk->disk_name,
- req_data_dir(req) == READ ? "read" : "writ",
- cyl, head, sec, nsect, req->buffer);
-#endif
- if (blk_fs_request(req)) {
- switch (rq_data_dir(req)) {
- case READ:
- 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);
- if (reset)
- goto repeat;
- if (wait_DRQ()) {
- bad_rw_intr();
- goto repeat;
- }
- outsw(HD_DATA, req->buffer, 256);
- break;
- default:
- printk("unknown hd-command\n");
- end_request(req, 0);
- break;
- }
- }
-}
-
-static void do_hd_request(struct request_queue *q)
-{
- disable_irq(HD_IRQ);
- hd_request();
- enable_irq(HD_IRQ);
-}
-
-static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
- struct hd_i_struct *disk = bdev->bd_disk->private_data;
-
- geo->heads = disk->head;
- geo->sectors = disk->sect;
- geo->cylinders = disk->cyl;
- return 0;
-}
-
-/*
- * Releasing a block device means we sync() it, so that it can safely
- * be forgotten about...
- */
-
-static irqreturn_t hd_interrupt(int irq, void *dev_id)
-{
- void (*handler)(void) = do_hd;
-
- do_hd = NULL;
- del_timer(&device_timer);
- if (!handler)
- handler = unexpected_hd_interrupt;
- handler();
- local_irq_enable();
- return IRQ_HANDLED;
-}
-
-static struct block_device_operations hd_fops = {
- .getgeo = hd_getgeo,
-};
-
-/*
- * This is the hard disk IRQ description. The IRQF_DISABLED in sa_flags
- * means we run the IRQ-handler with interrupts disabled: this is bad for
- * interrupt latency, but anything else has led to problems on some
- * machines.
- *
- * We enable interrupts in some of the routines after making sure it's
- * safe.
- */
-
-static int __init hd_init(void)
-{
- int drive;
-
- 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");
- return -ENOMEM;
- }
-
- blk_queue_max_sectors(hd_queue, 255);
- init_timer(&device_timer);
- device_timer.function = hd_times_out;
- blk_queue_hardsect_size(hd_queue, 512);
-
- if (!NR_HD) {
- /*
- * We don't know anything about the drive. This means
- * that you *MUST* specify the drive parameters to the
- * kernel yourself.
- *
- * If we were on an i386, we used to read this info from
- * the BIOS or CMOS. This doesn't work all that well,
- * since this assumes that this is a primary or secondary
- * drive, and if we're using this legacy driver, it's
- * probably an auxilliary controller added to recover
- * legacy data off an ST-506 drive. Either way, it's
- * definitely safest to have the user explicitly specify
- * the information.
- */
- printk("hd: no drives specified - use hd=cyl,head,sectors"
- " on kernel command line\n");
- goto out;
- }
-
- for (drive = 0 ; drive < NR_HD ; drive++) {
- struct gendisk *disk = alloc_disk(64);
- struct hd_i_struct *p = &hd_info[drive];
- if (!disk)
- goto Enomem;
- disk->major = MAJOR_NR;
- disk->first_minor = drive << 6;
- disk->fops = &hd_fops;
- sprintf(disk->disk_name, "hd%c", 'a'+drive);
- disk->private_data = p;
- set_capacity(disk, p->head * p->sect * p->cyl);
- disk->queue = hd_queue;
- p->unit = drive;
- hd_gendisk[drive] = disk;
- printk("%s: %luMB, CHS=%d/%d/%d\n",
- disk->disk_name, (unsigned long)get_capacity(disk)/2048,
- p->cyl, p->head, p->sect);
- }
-
- if (request_irq(HD_IRQ, hd_interrupt, IRQF_DISABLED, "hd", NULL)) {
- printk("hd: unable to get IRQ%d for the hard disk driver\n",
- HD_IRQ);
- goto out1;
- }
- if (!request_region(HD_DATA, 8, "hd")) {
- printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
- goto out2;
- }
- if (!request_region(HD_CMD, 1, "hd(cmd)")) {
- printk(KERN_WARNING "hd: port 0x%x busy\n", HD_CMD);
- goto out3;
- }
-
- /* Let them fly */
- for (drive = 0; drive < NR_HD; drive++)
- add_disk(hd_gendisk[drive]);
-
- return 0;
-
-out3:
- release_region(HD_DATA, 8);
-out2:
- free_irq(HD_IRQ, NULL);
-out1:
- for (drive = 0; drive < NR_HD; drive++)
- put_disk(hd_gendisk[drive]);
- NR_HD = 0;
-out:
- del_timer(&device_timer);
- unregister_blkdev(MAJOR_NR, "hd");
- blk_cleanup_queue(hd_queue);
- return -1;
-Enomem:
- while (drive--)
- put_disk(hd_gendisk[drive]);
- goto out;
-}
-
-static int __init parse_hd_setup(char *line)
-{
- int ints[6];
-
- (void) get_options(line, ARRAY_SIZE(ints), ints);
- hd_setup(NULL, ints);
-
- return 1;
-}
-__setup("hd=", parse_hd_setup);
-
-module_init(hd_init);
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
index 4fe516df9f74..7bc8fd59ea9e 100644
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -212,10 +212,11 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
{
int active_time, recovery_time;
int active_cycles, recovery_cycles;
- int bus_speed = ide_vlb_clk ? ide_vlb_clk : system_bus_clock();
+ int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
if (pio) {
unsigned int cycle_time;
+ struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
cycle_time = ide_pio_cycle_time(drive, pio);
@@ -224,10 +225,8 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
* actual cycle time for recovery and activity
* according system bus speed.
*/
- active_time = ide_pio_timings[pio].active_time;
- recovery_time = cycle_time
- - active_time
- - ide_pio_timings[pio].setup_time;
+ active_time = t->active;
+ recovery_time = cycle_time - active_time - t->setup;
/*
* Cycle times should be Vesa bus cycles
*/
@@ -311,16 +310,16 @@ static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio)
#endif
}
-static void __init ht6560b_port_init_devs(ide_hwif_t *hwif)
+static void __init ht6560b_init_dev(ide_drive_t *drive)
{
+ ide_hwif_t *hwif = drive->hwif;
/* Setting default configurations for drives. */
int t = (HT_CONFIG_DEFAULT << 8) | HT_TIMING_DEFAULT;
if (hwif->channel)
t |= (HT_SECONDARY_IF << 8);
- hwif->drives[0].drive_data = t;
- hwif->drives[1].drive_data = t;
+ drive->drive_data = t;
}
static int probe_ht6560b;
@@ -329,7 +328,7 @@ 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,
+ .init_dev = ht6560b_init_dev,
.set_pio_mode = ht6560b_set_pio_mode,
.selectproc = ht6560b_selectproc,
};
diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c
index ecae916a3385..89c8ff0a4d08 100644
--- a/drivers/ide/legacy/ide-4drives.c
+++ b/drivers/ide/legacy/ide-4drives.c
@@ -11,6 +11,21 @@ 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 void ide_4drives_init_dev(ide_drive_t *drive)
+{
+ if (drive->hwif->channel)
+ drive->select.all ^= 0x20;
+}
+
+static const struct ide_port_ops ide_4drives_port_ops = {
+ .init_dev = ide_4drives_init_dev,
+};
+
+static const struct ide_port_info ide_4drives_port_info = {
+ .port_ops = &ide_4drives_port_ops,
+ .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA,
+};
+
static int __init ide_4drives_init(void)
{
ide_hwif_t *hwif, *mate;
@@ -49,18 +64,10 @@ static int __init ide_4drives_init(void)
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);
+ ide_device_add(idx, &ide_4drives_port_info);
return 0;
}
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index aa2ea3deac85..27b1e0b7ecb4 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -63,11 +63,9 @@ MODULE_LICENSE("Dual MPL/GPL");
#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
+#ifdef CONFIG_PCMCIA_DEBUG
+INT_MODULE_PARM(pc_debug, 0);
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"ide-cs.c 1.3 2002/10/26 05:45:31 (David Hinds)";
#else
#define DEBUG(n, args...)
#endif
@@ -135,13 +133,17 @@ static void ide_detach(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
ide_hwif_t *hwif = info->hwif;
+ unsigned long data_addr, ctl_addr;
DEBUG(0, "ide_detach(0x%p)\n", link);
+ data_addr = hwif->io_ports.data_addr;
+ ctl_addr = hwif->io_ports.ctl_addr;
+
ide_release(link);
- release_region(hwif->io_ports.ctl_addr, 1);
- release_region(hwif->io_ports.data_addr, 8);
+ release_region(ctl_addr, 1);
+ release_region(data_addr, 8);
kfree(info);
} /* ide_detach */
@@ -150,6 +152,11 @@ static const struct ide_port_ops idecs_port_ops = {
.quirkproc = ide_undecoded_slave,
};
+static const struct ide_port_info idecs_port_info = {
+ .port_ops = &idecs_port_ops,
+ .host_flags = IDE_HFLAG_NO_DMA,
+};
+
static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl,
unsigned long irq, struct pcmcia_device *handle)
{
@@ -183,17 +190,25 @@ static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl,
i = hwif->index;
- ide_init_port_data(hwif, i);
ide_init_port_hw(hwif, &hw);
- hwif->port_ops = &idecs_port_ops;
idx[0] = i;
- ide_device_add(idx, NULL);
+ ide_device_add(idx, &idecs_port_info);
if (hwif->present)
return hwif;
+ /* retry registration in case device is still spinning up */
+ for (i = 0; i < 10; i++) {
+ msleep(100);
+ ide_port_scan(hwif);
+ if (hwif->present)
+ return hwif;
+ }
+
+ return hwif;
+
out_release:
release_region(ctl, 1);
release_region(io, 8);
@@ -222,7 +237,7 @@ 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, is_kme = 0;
+ int pass, last_ret = 0, last_fn = 0, is_kme = 0;
unsigned long io_base, ctl_base;
ide_hwif_t *hwif;
@@ -319,30 +334,15 @@ static int ide_config(struct pcmcia_device *link)
if (is_kme)
outb(0x81, ctl_base+1);
- /* retry registration in case device is still spinning up */
- 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) {
+ hwif = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link);
+ if (hwif == NULL && link->io.NumPorts1 == 0x20) {
outb(0x02, ctl_base + 0x10);
hwif = idecs_register(io_base + 0x10, ctl_base + 0x10,
link->irq.AssignedIRQ, link);
- if (hwif) {
- io_base += 0x10;
- ctl_base += 0x10;
- break;
- }
- }
- msleep(100);
}
- 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);
+ if (hwif == NULL)
goto failed;
- }
info->ndev = 1;
sprintf(info->node.dev_name, "hd%c", 'a' + hwif->index * 2);
@@ -376,7 +376,7 @@ failed:
======================================================================*/
-void ide_release(struct pcmcia_device *link)
+static void ide_release(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
ide_hwif_t *hwif = info->hwif;
@@ -411,6 +411,7 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */
+ PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */
PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
@@ -440,6 +441,7 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b),
+ PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF300", 0x7ed2ad87, 0x7e9e78ee),
PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c),
PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
@@ -450,6 +452,7 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443),
+ PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF45", 0x709b1bf1, 0xf68b6f32),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c
index d3bc3f24e05d..a249562b34b5 100644
--- a/drivers/ide/legacy/ide_platform.c
+++ b/drivers/ide/legacy/ide_platform.c
@@ -44,6 +44,10 @@ static void __devinit plat_ide_setup_ports(hw_regs_t *hw,
hw->chipset = ide_generic;
}
+static const struct ide_port_info platform_ide_port_info = {
+ .host_flags = IDE_HFLAG_NO_DMA,
+};
+
static int __devinit plat_ide_probe(struct platform_device *pdev)
{
struct resource *res_base, *res_alt, *res_irq;
@@ -54,6 +58,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
int ret = 0;
int mmio = 0;
hw_regs_t hw;
+ struct ide_port_info d = platform_ide_port_info;
pdata = pdev->dev.platform_data;
@@ -102,13 +107,13 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
ide_init_port_hw(hwif, &hw);
if (mmio) {
- hwif->host_flags = IDE_HFLAG_MMIO;
+ d.host_flags |= IDE_HFLAG_MMIO;
default_hwif_mmiops(hwif);
}
idx[0] = hwif->index;
- ide_device_add(idx, NULL);
+ ide_device_add(idx, &d);
platform_set_drvdata(pdev, hwif);
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index caa2632dd08e..0a6195bcfeda 100644
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -78,6 +78,8 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base,
hw->irq = irq;
hw->ack_intr = ack_intr;
+
+ hw->chipset = ide_generic;
}
static const char *mac_ide_name[] =
@@ -128,7 +130,6 @@ static int __init macide_init(void)
u8 index = hwif->index;
u8 idx[4] = { index, 0xff, 0xff, 0xff };
- ide_init_port_data(hwif, index);
ide_init_port_hw(hwif, &hw);
ide_device_add(idx, NULL);
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
index 6f535d00e638..9c2b9d078f69 100644
--- a/drivers/ide/legacy/q40ide.c
+++ b/drivers/ide/legacy/q40ide.c
@@ -70,6 +70,8 @@ static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base,
hw->irq = irq;
hw->ack_intr = ack_intr;
+
+ hw->chipset = ide_generic;
}
static void q40ide_input_data(ide_drive_t *drive, struct request *rq,
@@ -140,7 +142,6 @@ static int __init q40ide_init(void)
hwif = ide_find_port();
if (hwif) {
- ide_init_port_data(hwif, hwif->index);
ide_init_port_hw(hwif, &hw);
/* Q40 has a byte-swapped IDE interface */
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c
index 6424af154325..2338f344ea24 100644
--- a/drivers/ide/legacy/qd65xx.c
+++ b/drivers/ide/legacy/qd65xx.c
@@ -110,7 +110,7 @@ static void qd65xx_select(ide_drive_t *drive)
static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time)
{
- int clk = ide_vlb_clk ? ide_vlb_clk : system_bus_clock();
+ int clk = ide_vlb_clk ? ide_vlb_clk : 50;
u8 act_cyc, rec_cyc;
if (clk <= 33) {
@@ -132,7 +132,7 @@ 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)
{
- int clk = ide_vlb_clk ? ide_vlb_clk : system_bus_clock();
+ int clk = ide_vlb_clk ? ide_vlb_clk : 50;
u8 act_cyc, rec_cyc;
act_cyc = 17 - IDE_IN(active_time * clk / 1000 + 1, 2, 17);
@@ -207,6 +207,7 @@ 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)
{
ide_hwif_t *hwif = drive->hwif;
+ struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
unsigned int cycle_time;
int active_time = 175;
int recovery_time = 415; /* worst case values from the dos driver */
@@ -236,7 +237,7 @@ static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
active_time = 110;
recovery_time = cycle_time - 120;
} else {
- active_time = ide_pio_timings[pio].active_time;
+ active_time = t->active;
recovery_time = cycle_time - active_time;
}
}
@@ -281,17 +282,18 @@ static int __init qd_testreg(int port)
return (readreg != QD_TESTVAL);
}
-static void __init qd6500_port_init_devs(ide_hwif_t *hwif)
+static void __init qd6500_init_dev(ide_drive_t *drive)
{
+ ide_hwif_t *hwif = drive->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;
+ drive->drive_data = QD6500_DEF_DATA;
}
-static void __init qd6580_port_init_devs(ide_hwif_t *hwif)
+static void __init qd6580_init_dev(ide_drive_t *drive)
{
+ ide_hwif_t *hwif = drive->hwif;
u16 t1, t2;
u8 base = (hwif->config_data & 0xff00) >> 8;
u8 config = QD_CONFIG(hwif);
@@ -302,18 +304,17 @@ static void __init qd6580_port_init_devs(ide_hwif_t *hwif)
} else
t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA;
- hwif->drives[0].drive_data = t1;
- hwif->drives[1].drive_data = t2;
+ drive->drive_data = drive->select.b.unit ? t2 : t1;
}
static const struct ide_port_ops qd6500_port_ops = {
- .port_init_devs = qd6500_port_init_devs,
+ .init_dev = qd6500_init_dev,
.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,
+ .init_dev = qd6580_init_dev,
.set_pio_mode = qd6580_set_pio_mode,
.selectproc = qd65xx_select,
};
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 1a6c27b32498..48d57cae63c6 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -213,10 +213,8 @@ static int auide_build_dmatable(ide_drive_t *drive)
{
int i, iswrite, count = 0;
ide_hwif_t *hwif = HWIF(drive);
-
struct request *rq = HWGROUP(drive)->rq;
-
- _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ _auide_hwif *ahwif = &auide_hwif;
struct scatterlist *sg;
iswrite = (rq_data_dir(rq) == WRITE);
@@ -402,7 +400,7 @@ static const struct ide_dma_ops au1xxx_dma_ops = {
static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
{
- _auide_hwif *auide = (_auide_hwif *)hwif->hwif_data;
+ _auide_hwif *auide = &auide_hwif;
dbdev_tab_t source_dev_tab, target_dev_tab;
u32 dev_id, tsize, devwidth, flags;
@@ -463,7 +461,7 @@ static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
#else
static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
{
- _auide_hwif *auide = (_auide_hwif *)hwif->hwif_data;
+ _auide_hwif *auide = &auide_hwif;
dbdev_tab_t source_dev_tab;
int flags;
@@ -600,8 +598,6 @@ static int au_ide_probe(struct device *dev)
ide_init_port_hw(hwif, &hw);
- hwif->dev = dev;
-
/* If the user has selected DDMA assisted copies,
then set up a few local I/O function entry points
*/
@@ -610,11 +606,8 @@ static int au_ide_probe(struct device *dev)
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 */
auide_hwif.hwif = hwif;
- hwif->hwif_data = &auide_hwif;
idx[0] = hwif->index;
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
index 52fee3d2771a..9f1212cc4aed 100644
--- a/drivers/ide/mips/swarm.c
+++ b/drivers/ide/mips/swarm.c
@@ -61,6 +61,11 @@ static struct resource swarm_ide_resource = {
static struct platform_device *swarm_ide_dev;
+static const struct ide_port_info swarm_port_info = {
+ .name = DRV_NAME,
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+};
+
/*
* swarm_ide_probe - if the board header indicates the existence of
* Generic Bus IDE, allocate a HWIF for it.
@@ -77,12 +82,6 @@ static int __devinit swarm_ide_probe(struct device *dev)
if (!SIBYTE_HAVE_IDE)
return -ENODEV;
- hwif = ide_find_port();
- if (hwif == NULL) {
- printk(KERN_ERR DRV_NAME ": no free slot for interface\n");
- return -ENOMEM;
- }
-
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));
@@ -109,10 +108,6 @@ 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);
-
for (i = 0; i <= 7; i++)
hw.io_ports_array[i] =
(unsigned long)(base + ((0x1f0 + i) << 5));
@@ -121,15 +116,26 @@ static int __devinit swarm_ide_probe(struct device *dev)
hw.irq = K_INT_GB_IDE;
hw.chipset = ide_generic;
+ hwif = ide_find_port_slot(&swarm_port_info);
+ if (hwif == NULL)
+ goto err;
+
ide_init_port_hw(hwif, &hw);
+ /* Setup MMIO ops. */
+ default_hwif_mmiops(hwif);
+
idx[0] = hwif->index;
- ide_device_add(idx, NULL);
+ ide_device_add(idx, &swarm_port_info);
dev_set_drvdata(dev, hwif);
return 0;
+err:
+ release_resource(&swarm_ide_resource);
+ iounmap(base);
+ return -ENOMEM;
}
static struct device_driver swarm_ide_driver = {
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index 7f46c224b7c4..ae7a4329a581 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -140,7 +140,7 @@ static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name)
{
- int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock();
+ int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
if (bus_speed <= 33)
pci_set_drvdata(dev, (void *) aec6xxx_33_base);
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index f2129d5e07f2..80d19c0eb780 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -69,22 +69,20 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = to_pci_dev(hwif->dev);
- int s_time, a_time, c_time;
+ struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
+ int s_time = t->setup, a_time = t->active, c_time = t->cycle;
u8 s_clc, a_clc, r_clc;
unsigned long flags;
- int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock();
+ int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
int port = hwif->channel ? 0x5c : 0x58;
int portFIFO = hwif->channel ? 0x55 : 0x54;
u8 cd_dma_fifo = 0;
int unit = drive->select.b.unit & 1;
- s_time = ide_pio_timings[pio].setup_time;
- a_time = ide_pio_timings[pio].active_time;
if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8)
s_clc = 0;
if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8)
a_clc = 0;
- c_time = ide_pio_timings[pio].cycle_time;
if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) {
r_clc = 1;
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index efcf54338be7..0bfcdd0e77b3 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -21,8 +21,6 @@
#include <linux/init.h>
#include <linux/ide.h>
-#include "ide-timing.h"
-
enum {
AMD_IDE_CONFIG = 0x41,
AMD_CABLE_DETECT = 0x42,
@@ -53,20 +51,20 @@ static void amd_set_speed(struct pci_dev *dev, u8 dn, u8 udma_mask,
u8 t = 0, offset = amd_offset(dev);
pci_read_config_byte(dev, AMD_ADDRESS_SETUP + offset, &t);
- t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
+ t = (t & ~(3 << ((3 - dn) << 1))) | ((clamp_val(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
pci_write_config_byte(dev, AMD_ADDRESS_SETUP + offset, t);
pci_write_config_byte(dev, AMD_8BIT_TIMING + offset + (1 - (dn >> 1)),
- ((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1));
+ ((clamp_val(timing->act8b, 1, 16) - 1) << 4) | (clamp_val(timing->rec8b, 1, 16) - 1));
pci_write_config_byte(dev, AMD_DRIVE_TIMING + offset + (3 - dn),
- ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
+ ((clamp_val(timing->active, 1, 16) - 1) << 4) | (clamp_val(timing->recover, 1, 16) - 1));
switch (udma_mask) {
- case ATA_UDMA2: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
- case ATA_UDMA4: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break;
- case ATA_UDMA5: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break;
- case ATA_UDMA6: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break;
+ case ATA_UDMA2: t = timing->udma ? (0xc0 | (clamp_val(timing->udma, 2, 5) - 2)) : 0x03; break;
+ case ATA_UDMA4: t = timing->udma ? (0xc0 | amd_cyc2udma[clamp_val(timing->udma, 2, 10)]) : 0x03; break;
+ case ATA_UDMA5: t = timing->udma ? (0xc0 | amd_cyc2udma[clamp_val(timing->udma, 1, 10)]) : 0x03; break;
+ case ATA_UDMA6: t = timing->udma ? (0xc0 | amd_cyc2udma[clamp_val(timing->udma, 1, 15)]) : 0x03; break;
default: return;
}
@@ -179,7 +177,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev,
* Determine the system bus clock.
*/
- amd_clock = (ide_pci_clk ? ide_pci_clk : system_bus_clock()) * 1000;
+ amd_clock = (ide_pci_clk ? ide_pci_clk : 33) * 1000;
switch (amd_clock) {
case 33000: amd_clock = 33333; break;
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
index aaf38109eaec..1ad1e23e3105 100644
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -521,21 +521,23 @@ static void program_drive_counts(ide_drive_t *drive, unsigned int index)
static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
u8 pio_mode, unsigned int cycle_time)
{
+ struct ide_timing *t;
int setup_time, active_time, recovery_time, clock_time;
u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count;
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;
+ if (cmd640_vlb)
+ bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
else
- bus_speed = system_bus_clock();
+ bus_speed = ide_pci_clk ? ide_pci_clk : 33;
if (pio_mode > 5)
pio_mode = 5;
- setup_time = ide_pio_timings[pio_mode].setup_time;
- active_time = ide_pio_timings[pio_mode].active_time;
+
+ t = ide_timing_find_mode(XFER_PIO_0 + pio_mode);
+ setup_time = t->setup;
+ active_time = t->active;
+
recovery_time = cycle_time - (setup_time + active_time);
clock_time = 1000 / bus_speed;
cycle_count = DIV_ROUND_UP(cycle_time, clock_time);
@@ -609,11 +611,40 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
display_clocks(index);
}
+#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
+
+static void cmd640_init_dev(ide_drive_t *drive)
+{
+ unsigned int i = drive->hwif->channel * 2 + drive->select.b.unit;
+
+#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[i] = 4; /* max possible */
+ active_counts[i] = 16; /* max possible */
+ recovery_counts[i] = 16; /* max possible */
+ program_drive_counts(drive, i);
+ set_prefetch_mode(drive, i, 0);
+ printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch cleared\n", i);
+#else
+ /*
+ * Set the drive unmask flags to match the prefetch setting.
+ */
+ check_prefetch(drive, i);
+ printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch(%s) preserved\n",
+ i, drive->no_io_32bit ? "off" : "on");
+#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
+}
+
static const struct ide_port_ops cmd640_port_ops = {
+ .init_dev = cmd640_init_dev,
+#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
.set_pio_mode = cmd640_set_pio_mode,
+#endif
};
-#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
static int pci_conf1(void)
{
@@ -656,10 +687,8 @@ static const struct ide_port_info cmd640_port_info __initdata = {
IDE_HFLAG_NO_DMA |
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)
@@ -685,12 +714,8 @@ static int cmd640x_init_one(unsigned long base, unsigned long ctl)
*/
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, rc;
const char *bus_type, *port2;
- unsigned int index;
u8 b, cfr;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
hw_regs_t hw[2];
@@ -747,9 +772,11 @@ static int __init cmd640x_init(void)
ide_std_init_ports(&hw[0], 0x1f0, 0x3f6);
hw[0].irq = 14;
+ hw[0].chipset = ide_cmd640;
ide_std_init_ports(&hw[1], 0x170, 0x376);
hw[1].irq = 15;
+ hw[1].chipset = ide_cmd640;
printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x"
"\n", 'a' + cmd640_chip_version - 1, bus_type, cfr);
@@ -774,88 +801,44 @@ static int __init cmd640x_init(void)
put_cmd640_reg(CMDTIM, 0);
put_cmd640_reg(BRST, 0x40);
- cmd_hwif1 = ide_find_port();
+ b = get_cmd640_reg(CNTRL);
/*
* Try to enable the secondary interface, if not already enabled
*/
- if (cmd_hwif1 &&
- cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe) {
- port2 = "not probed";
+ if (secondary_port_responding()) {
+ if ((b & CNTRL_ENA_2ND)) {
+ second_port_cmd640 = 1;
+ port2 = "okay";
+ } else if (cmd640_vlb) {
+ second_port_cmd640 = 1;
+ port2 = "alive";
+ } else
+ port2 = "not cmd640";
} else {
- b = get_cmd640_reg(CNTRL);
+ put_cmd640_reg(CNTRL, b ^ CNTRL_ENA_2ND); /* toggle the bit */
if (secondary_port_responding()) {
- if ((b & CNTRL_ENA_2ND)) {
- second_port_cmd640 = 1;
- port2 = "okay";
- } else if (cmd640_vlb) {
- second_port_cmd640 = 1;
- port2 = "alive";
- } else
- port2 = "not cmd640";
+ second_port_cmd640 = 1;
+ port2 = "enabled";
} else {
- put_cmd640_reg(CNTRL, b ^ CNTRL_ENA_2ND); /* toggle the bit */
- if (secondary_port_responding()) {
- second_port_cmd640 = 1;
-#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
- second_port_toggled = 1;
-#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
- port2 = "enabled";
- } else {
- put_cmd640_reg(CNTRL, b); /* restore original setting */
- port2 = "not responding";
- }
+ put_cmd640_reg(CNTRL, b); /* restore original setting */
+ port2 = "not responding";
}
}
/*
* Initialize data for secondary cmd640 port, if enabled
*/
- if (second_port_cmd640 && cmd_hwif1) {
- ide_init_port_hw(cmd_hwif1, &hw[1]);
- idx[1] = cmd_hwif1->index;
+ if (second_port_cmd640) {
+ cmd_hwif1 = ide_find_port();
+ if (cmd_hwif1) {
+ ide_init_port_hw(cmd_hwif1, &hw[1]);
+ idx[1] = cmd_hwif1->index;
+ }
}
printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n",
second_port_cmd640 ? "" : "not ", port2);
- /*
- * Establish initial timings/prefetch for all drives.
- * Do not unnecessarily disturb any prior BIOS setup of these.
- */
- for (index = 0; index < (2 + (second_port_cmd640 << 1)); 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(drive, index);
- printk("cmd640: drive%d timings/prefetch(%s) preserved\n",
- index, drive->no_io_32bit ? "off" : "on");
-#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
- }
-
#ifdef CMD640_DUMP_REGS
cmd640_dump_regs();
#endif
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index 08674711d089..cfa784bacf48 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -69,7 +69,7 @@ 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 / (ide_pci_clk ? ide_pci_clk : system_bus_clock());
+ int clock_time = 1000 / (ide_pci_clk ? ide_pci_clk : 33);
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};
@@ -116,6 +116,7 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = to_pci_dev(hwif->dev);
+ struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
unsigned int cycle_time;
u8 setup_count, arttim = 0;
@@ -124,11 +125,10 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
cycle_time = ide_pio_cycle_time(drive, pio);
- program_cycle_times(drive, cycle_time,
- ide_pio_timings[pio].active_time);
+ program_cycle_times(drive, cycle_time, t->active);
- setup_count = quantize_timing(ide_pio_timings[pio].setup_time,
- 1000 / (ide_pci_clk ? ide_pci_clk : system_bus_clock()));
+ setup_count = quantize_timing(t->setup,
+ 1000 / (ide_pci_clk ? ide_pci_clk : 33));
/*
* The primary channel has individual address setup timing registers
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index 99fe91a191b8..dc97c48623f3 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -26,8 +26,6 @@
#include <linux/pci.h>
#include <linux/ide.h>
-#include "ide-timing.h"
-
#define MSR_ATAC_BASE 0x51300000
#define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0)
#define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01)
@@ -75,13 +73,11 @@ static unsigned int cs5535_udma_timings[5] =
*/
static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
{
-
u32 reg = 0, dummy;
int unit = drive->select.b.unit;
-
/* Set the PIO timings */
- if ((speed & XFER_MODE) == XFER_PIO) {
+ if (speed < XFER_SW_DMA_0) {
ide_drive_t *pair = ide_get_paired_drive(drive);
u8 cmd, pioa;
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 77cc22c2ad45..e14ad5530fa4 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -133,23 +133,22 @@ static int calc_clk(int time, int bus_speed)
*/
static void compute_clocks(u8 pio, pio_clocks_t *p_pclk)
{
+ struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
int clk1, clk2;
- int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock();
+ int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
/* we don't check against CY82C693's min and max speed,
* so you can play with the idebus=xx parameter
*/
/* let's calc the address setup time clocks */
- p_pclk->address_time = (u8)calc_clk(ide_pio_timings[pio].setup_time, bus_speed);
+ p_pclk->address_time = (u8)calc_clk(t->setup, bus_speed);
/* let's calc the active and recovery time clocks */
- clk1 = calc_clk(ide_pio_timings[pio].active_time, bus_speed);
+ clk1 = calc_clk(t->active, bus_speed);
/* calc recovery timing */
- clk2 = ide_pio_timings[pio].cycle_time -
- ide_pio_timings[pio].active_time -
- ide_pio_timings[pio].setup_time;
+ clk2 = t->cycle - t->active - t->setup;
clk2 = calc_clk(clk2, bus_speed);
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
index b9e457996d0e..0106e2a2df77 100644
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -47,13 +47,18 @@ static const struct ide_port_ops delkin_cb_port_ops = {
.quirkproc = ide_undecoded_slave,
};
+static const struct ide_port_info delkin_cb_port_info = {
+ .port_ops = &delkin_cb_port_ops,
+ .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS |
+ IDE_HFLAG_NO_DMA,
+};
+
static int __devinit
delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
unsigned long base;
hw_regs_t hw;
ide_hwif_t *hwif = NULL;
- ide_drive_t *drive;
int i, rc;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
@@ -79,6 +84,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, base + 0x10, base + 0x1e);
hw.irq = dev->irq;
+ hw.dev = &dev->dev;
hw.chipset = ide_pci; /* this enables IRQ sharing */
hwif = ide_find_port();
@@ -87,28 +93,17 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
i = hwif->index;
- ide_init_port_data(hwif, i);
ide_init_port_hw(hwif, &hw);
- hwif->port_ops = &delkin_cb_port_ops;
idx[0] = i;
- ide_device_add(idx, NULL);
-
- if (!hwif->present)
- goto out_disable;
+ ide_device_add(idx, &delkin_cb_port_info);
pci_set_drvdata(dev, hwif);
- hwif->dev = &dev->dev;
- drive = &hwif->drives[0];
- if (drive->present) {
- drive->io_32bit = 1;
- drive->unmask = 1;
- }
+
return 0;
out_disable:
- printk(KERN_ERR "delkin_cb: no IDE devices found\n");
pci_release_regions(dev);
pci_disable_device(dev);
return -ENODEV;
@@ -139,14 +134,12 @@ static struct pci_driver driver = {
.remove = delkin_cb_remove,
};
-static int
-delkin_cb_init (void)
+static int __init delkin_cb_init(void)
{
return pci_register_driver(&driver);
}
-static void
-delkin_cb_exit (void)
+static void __exit delkin_cb_exit(void)
{
pci_unregister_driver(&driver);
}
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index c929dadaaaff..397c6cbe953c 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -759,8 +759,7 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
enable_irq (hwif->irq);
}
} else
- outb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
- hwif->io_ports.ctl_addr);
+ outb(ATA_DEVCTL_OBS | (mask ? 2 : 0), hwif->io_ports.ctl_addr);
}
/*
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index 9053c8771e6e..2b71bdf74e73 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -184,8 +184,7 @@ static const struct ide_port_info it8213_chipsets[] __devinitdata = {
static int __devinit it8213_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_setup_pci_device(dev, &it8213_chipsets[id->driver_data]);
- return 0;
+ return ide_setup_pci_device(dev, &it8213_chipsets[id->driver_data]);
}
static const struct pci_device_id it8213_pci_tbl[] = {
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index 6ab04115286b..cbf647202994 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -512,8 +512,14 @@ static void __devinit it821x_quirkproc(ide_drive_t *drive)
}
static struct ide_dma_ops it821x_pass_through_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = it821x_dma_start,
.dma_end = it821x_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_timeout = ide_dma_timeout,
+ .dma_lost_irq = ide_dma_lost_irq,
};
/**
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index fec4955f449b..45ba71a7182f 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -76,7 +76,7 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
}
/* be sure we're looking at the low order bits */
- outb(drive->ctl & ~0x80, io_ports->ctl_addr);
+ outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
@@ -90,7 +90,7 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
tf->device = superio_ide_inb(io_ports->device_addr);
if (task->tf_flags & IDE_TFLAG_LBA48) {
- outb(drive->ctl | 0x80, io_ports->ctl_addr);
+ outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = inb(io_ports->feature_addr);
@@ -225,10 +225,6 @@ static int ns87415_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);
@@ -288,7 +284,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
}
if (!using_inta)
- hwif->irq = ide_default_irq(hwif->io_ports.data_addr);
+ 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 */
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index 6e99080497bf..725c80508d90 100644
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -81,8 +81,6 @@
* 0.5 doesn't work.
*/
-#define OPTI621_DEBUG /* define for debug messages */
-
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -92,28 +90,6 @@
#include <asm/io.h>
-//#define OPTI621_MAX_PIO 3
-/* In fact, I do not have any PIO 4 drive
- * (address: 25 ns, data: 70 ns, recovery: 35 ns),
- * but OPTi 82C621 is programmable and it can do (minimal values):
- * on 40MHz PCI bus (pulse 25 ns):
- * address: 25 ns, data: 25 ns, recovery: 50 ns;
- * on 20MHz PCI bus (pulse 50 ns):
- * address: 50 ns, data: 50 ns, recovery: 100 ns.
- */
-
-/* #define READ_PREFETCH 0 */
-/* Uncomment for disable read prefetch.
- * There is some readprefetch capatibility in hdparm,
- * but when I type hdparm -P 1 /dev/hda, I got errors
- * and till reset drive is inaccessible.
- * This (hw) read prefetch is safe on my drive.
- */
-
-#ifndef READ_PREFETCH
-#define READ_PREFETCH 0x40 /* read prefetch is enabled */
-#endif /* else read prefetch is disabled */
-
#define READ_REG 0 /* index of Read cycle timing register */
#define WRITE_REG 1 /* index of Write cycle timing register */
#define CNTRL_REG 3 /* index of Control register */
@@ -122,51 +98,8 @@
static int reg_base;
-#define PIO_NOT_EXIST 254
-#define PIO_DONT_KNOW 255
-
static DEFINE_SPINLOCK(opti621_lock);
-/* there are stored pio numbers from other calls of opti621_set_pio_mode */
-static void compute_pios(ide_drive_t *drive, const u8 pio)
-/* Store values into drive->drive_data
- * second_contr - 0 for primary controller, 1 for secondary
- * slave_drive - 0 -> pio is for master, 1 -> pio is for slave
- * pio - PIO mode for selected drive (for other we don't know)
- */
-{
- int d;
- ide_hwif_t *hwif = HWIF(drive);
-
- drive->drive_data = pio;
-
- for (d = 0; d < 2; ++d) {
- drive = &hwif->drives[d];
- if (drive->present) {
- if (drive->drive_data == PIO_DONT_KNOW)
- drive->drive_data = ide_get_best_pio_mode(drive, 255, 3);
-#ifdef OPTI621_DEBUG
- printk("%s: Selected PIO mode %d\n",
- drive->name, drive->drive_data);
-#endif
- } else {
- drive->drive_data = PIO_NOT_EXIST;
- }
- }
-}
-
-static int cmpt_clk(int time, int bus_speed)
-/* Returns (rounded up) time in clocks for time in ns,
- * with bus_speed in MHz.
- * Example: bus_speed = 40 MHz, time = 80 ns
- * 1000/40 = 25 ns (clk value),
- * 80/25 = 3.2, rounded up to 4 (I hope ;-)).
- * Use idebus=xx to select right frequency.
- */
-{
- return ((time*bus_speed+999)/1000);
-}
-
/* Write value to register reg, base of register
* is at reg_base (0x1f0 primary, 0x170 secondary,
* if not changed by PCI configuration).
@@ -199,83 +132,29 @@ static u8 read_reg(int reg)
return ret;
}
-typedef struct pio_clocks_s {
- int address_time; /* Address setup (clocks) */
- int data_time; /* Active/data pulse (clocks) */
- int recovery_time; /* Recovery time (clocks) */
-} pio_clocks_t;
-
-static void compute_clocks(int pio, pio_clocks_t *clks)
-{
- 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)
{
- /* primary and secondary drives share some registers,
- * so we have to program both drives
- */
+ ide_hwif_t *hwif = drive->hwif;
+ ide_drive_t *pair = ide_get_paired_drive(drive);
unsigned long flags;
- u8 pio1 = 0, pio2 = 0;
- pio_clocks_t first, second;
- int ax, drdy;
- u8 cycle1, cycle2, misc;
- ide_hwif_t *hwif = HWIF(drive);
-
- /* sets drive->drive_data for both drives */
- compute_pios(drive, pio);
- pio1 = hwif->drives[0].drive_data;
- pio2 = hwif->drives[1].drive_data;
-
- compute_clocks(pio1, &first);
- compute_clocks(pio2, &second);
-
- /* ax = max(a1,a2) */
- ax = (first.address_time < second.address_time) ? second.address_time : first.address_time;
-
- drdy = 2; /* DRDY is default 2 (by OPTi Databook) */
-
- cycle1 = ((first.data_time-1)<<4) | (first.recovery_time-2);
- cycle2 = ((second.data_time-1)<<4) | (second.recovery_time-2);
- misc = READ_PREFETCH | ((ax-1)<<4) | ((drdy-2)<<1);
-
-#ifdef OPTI621_DEBUG
- printk("%s: master: address: %d, data: %d, "
- "recovery: %d, drdy: %d [clk]\n",
- hwif->name, ax, first.data_time,
- first.recovery_time, drdy);
- printk("%s: slave: address: %d, data: %d, "
- "recovery: %d, drdy: %d [clk]\n",
- hwif->name, ax, second.data_time,
- second.recovery_time, drdy);
-#endif
+ u8 tim, misc, addr_pio = pio, clk;
+
+ /* DRDY is default 2 (by OPTi Databook) */
+ static const u8 addr_timings[2][5] = {
+ { 0x20, 0x10, 0x00, 0x00, 0x00 }, /* 33 MHz */
+ { 0x10, 0x10, 0x00, 0x00, 0x00 }, /* 25 MHz */
+ };
+ static const u8 data_rec_timings[2][5] = {
+ { 0x5b, 0x45, 0x32, 0x21, 0x20 }, /* 33 MHz */
+ { 0x48, 0x34, 0x21, 0x10, 0x10 } /* 25 MHz */
+ };
+
+ drive->drive_data = XFER_PIO_0 + pio;
+
+ if (pair->present) {
+ if (pair->drive_data && pair->drive_data < drive->drive_data)
+ addr_pio = pair->drive_data - XFER_PIO_0;
+ }
spin_lock_irqsave(&opti621_lock, flags);
@@ -289,24 +168,21 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
(void)inb(reg_base + CNTRL_REG);
/* if reads 0xc0, no interface exist? */
read_reg(CNTRL_REG);
- /* read version, probably 0 */
- read_reg(STRAP_REG);
- /* program primary drive */
- /* select Index-0 for Register-A */
- write_reg(0, MISC_REG);
- /* set read cycle timings */
- write_reg(cycle1, READ_REG);
- /* set write cycle timings */
- write_reg(cycle1, WRITE_REG);
+ /* check CLK speed */
+ clk = read_reg(STRAP_REG) & 1;
+
+ printk(KERN_INFO "%s: CLK = %d MHz\n", hwif->name, clk ? 25 : 33);
- /* program secondary drive */
- /* select Index-1 for Register-B */
- write_reg(1, MISC_REG);
+ tim = data_rec_timings[clk][pio];
+ misc = addr_timings[clk][addr_pio];
+
+ /* select Index-0/1 for Register-A/B */
+ write_reg(drive->select.b.unit, MISC_REG);
/* set read cycle timings */
- write_reg(cycle2, READ_REG);
+ write_reg(tim, READ_REG);
/* set write cycle timings */
- write_reg(cycle2, WRITE_REG);
+ write_reg(tim, WRITE_REG);
/* use Register-A for drive 0 */
/* use Register-B for drive 1 */
@@ -319,45 +195,26 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
spin_unlock_irqrestore(&opti621_lock, flags);
}
-static void __devinit opti621_port_init_devs(ide_hwif_t *hwif)
-{
- hwif->drives[0].drive_data = PIO_DONT_KNOW;
- hwif->drives[1].drive_data = PIO_DONT_KNOW;
-}
-
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",
- .enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} },
- .port_ops = &opti621_port_ops,
- .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
- .pio_mask = ATA_PIO3,
- .swdma_mask = ATA_SWDMA2,
- .mwdma_mask = ATA_MWDMA2,
- }, { /* 1 */
- .name = "OPTI621X",
- .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,
- }
+static const struct ide_port_info opti621_chipset __devinitdata = {
+ .name = "OPTI621/X",
+ .enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} },
+ .port_ops = &opti621_port_ops,
+ .host_flags = IDE_HFLAG_NO_DMA,
+ .pio_mask = ATA_PIO4,
};
static int __devinit opti621_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- return ide_setup_pci_device(dev, &opti621_chipsets[id->driver_data]);
+ return ide_setup_pci_device(dev, &opti621_chipset);
}
static const struct pci_device_id opti621_pci_tbl[] = {
{ PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C621), 0 },
- { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C825), 1 },
+ { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C825), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, opti621_pci_tbl);
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index 910fb00deb71..789c66dfbde5 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -148,11 +148,8 @@ static void scc_ide_outb(u8 addr, unsigned long port)
out_be32((void*)port, addr);
}
-static void
-scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port)
+static void scc_ide_outbsync(ide_hwif_t *hwif, u8 addr, unsigned long port)
{
- ide_hwif_t *hwif = HWIF(drive);
-
out_be32((void*)port, addr);
eieio();
in_be32((void*)(hwif->dma_base + 0x01c));
@@ -561,12 +558,9 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev,
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);
+ hwif = ide_find_port_slot(d);
+ if (hwif == NULL)
return -ENOMEM;
- }
memset(&hw, 0, sizeof(hw));
for (i = 0; i <= 8; i++)
@@ -575,7 +569,6 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev,
hw.dev = &dev->dev;
hw.chipset = ide_pci;
ide_init_port_hw(hwif, &hw);
- hwif->dev = &dev->dev;
idx[0] = hwif->index;
@@ -662,8 +655,6 @@ static void scc_tf_load(ide_drive_t *drive, ide_task_t *task)
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);
@@ -708,7 +699,7 @@ static void scc_tf_read(ide_drive_t *drive, ide_task_t *task)
}
/* be sure we're looking at the low order bits */
- scc_ide_outb(drive->ctl & ~0x80, io_ports->ctl_addr);
+ scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = scc_ide_inb(io_ports->nsect_addr);
@@ -722,7 +713,7 @@ static void scc_tf_read(ide_drive_t *drive, ide_task_t *task)
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);
+ scc_ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = scc_ide_inb(io_ports->feature_addr);
@@ -795,7 +786,6 @@ static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif)
hwif->dma_base = dma_base;
hwif->config_data = ports->ctl;
- hwif->mmio = 1;
}
/**
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 16a0bce17d69..c79ff5b41088 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -111,7 +111,7 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
static void
sgiioc4_maskproc(ide_drive_t * drive, int mask)
{
- writeb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
+ writeb(ATA_DEVCTL_OBS | (mask ? 2 : 0),
(void __iomem *)drive->hwif->io_ports.ctl_addr);
}
@@ -369,8 +369,7 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
hwif->sg_max_nents = IOC4_PRD_ENTRIES;
pad = pci_alloc_consistent(dev, IOC4_IDE_CACHELINE_SIZE,
- (dma_addr_t *) &(hwif->dma_status));
-
+ (dma_addr_t *)&hwif->extra_base);
if (pad) {
ide_set_hwifdata(hwif, pad);
return 0;
@@ -439,7 +438,7 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
/* Address of the Ending DMA */
memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
- ending_dma_addr = cpu_to_le32(hwif->dma_status);
+ ending_dma_addr = cpu_to_le32(hwif->extra_base);
writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
writel(dma_direction, (void __iomem *)ioc4_dma_addr);
@@ -569,6 +568,7 @@ static const struct ide_dma_ops sgiioc4_dma_ops = {
};
static const struct ide_port_info sgiioc4_port_info __devinitdata = {
+ .name = DRV_NAME,
.chipset = ide_pci,
.init_dma = ide_dma_sgiioc4,
.port_ops = &sgiioc4_port_ops,
@@ -588,13 +588,6 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
hw_regs_t hw;
struct ide_port_info d = sgiioc4_port_info;
- hwif = ide_find_port();
- if (hwif == NULL) {
- printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n",
- DRV_NAME);
- return -ENOMEM;
- }
-
/* Get the CmdBlk and CtrlBlk Base Registers */
bar0 = pci_resource_start(dev, 0);
virt_base = ioremap(bar0, pci_resource_len(dev, 0));
@@ -609,11 +602,11 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
cmd_phys_base = bar0 + IOC4_CMD_OFFSET;
if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
- hwif->name)) {
+ DRV_NAME)) {
printk(KERN_ERR
"%s : %s -- ERROR, Addresses "
"0x%p to 0x%p ALREADY in use\n",
- __func__, hwif->name, (void *) cmd_phys_base,
+ __func__, DRV_NAME, (void *) cmd_phys_base,
(void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE);
return -ENOMEM;
}
@@ -624,9 +617,12 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
hw.irq = dev->irq;
hw.chipset = ide_pci;
hw.dev = &dev->dev;
- ide_init_port_hw(hwif, &hw);
- hwif->dev = &dev->dev;
+ hwif = ide_find_port_slot(&d);
+ if (hwif == NULL)
+ goto err;
+
+ ide_init_port_hw(hwif, &hw);
/* The IOC4 uses MMIO rather than Port IO. */
default_hwif_mmiops(hwif);
@@ -642,6 +638,10 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
return -EIO;
return 0;
+err:
+ release_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE);
+ iounmap(virt_base);
+ return -ENOMEM;
}
static unsigned int __devinit
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 0006b9e58567..6e9d7655d89c 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -94,7 +94,7 @@ 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)
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
base += hwif->channel << 6;
else
base += hwif->channel << 4;
@@ -117,7 +117,7 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
unsigned long base = (unsigned long)hwif->hwif_data;
base += 0xA0 + r;
- if (hwif->mmio)
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
base += hwif->channel << 6;
else
base += hwif->channel << 4;
@@ -190,7 +190,9 @@ static u8 sil_pata_udma_filter(ide_drive_t *drive)
unsigned long base = (unsigned long)hwif->hwif_data;
u8 scsc, mask = 0;
- scsc = sil_ioread8(dev, base + (hwif->mmio ? 0x4A : 0x8A));
+ base += (hwif->host_flags & IDE_HFLAG_MMIO) ? 0x4A : 0x8A;
+
+ scsc = sil_ioread8(dev, base);
switch (scsc & 0x30) {
case 0x10: /* 133 */
@@ -238,8 +240,9 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
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)
- : (hwif->mmio ? 0xB4 : 0x80);
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+ u8 addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84)
+ : (mmio ? 0xB4 : 0x80);
u8 mode = 0;
u8 unit = drive->select.b.unit;
@@ -290,13 +293,13 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
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 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+ u8 scsc = 0, addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84)
+ : (mmio ? 0xB4 : 0x80);
unsigned long ma = siimage_seldev(drive, 0x08);
unsigned long ua = siimage_seldev(drive, 0x0C);
- scsc = sil_ioread8 (dev, base + (hwif->mmio ? 0x4A : 0x8A));
+ scsc = sil_ioread8 (dev, base + (mmio ? 0x4A : 0x8A));
mode = sil_ioread8 (dev, base + addr_mask);
multi = sil_ioread16(dev, ma);
ultra = sil_ioread16(dev, ua);
@@ -391,7 +394,7 @@ static int siimage_mmio_dma_test_irq(ide_drive_t *drive)
static int siimage_dma_test_irq(ide_drive_t *drive)
{
- if (drive->hwif->mmio)
+ if (drive->hwif->host_flags & IDE_HFLAG_MMIO)
return siimage_mmio_dma_test_irq(drive);
else
return siimage_io_dma_test_irq(drive);
@@ -418,8 +421,7 @@ static int sil_sata_reset_poll(ide_drive_t *drive)
if ((sata_stat & 0x03) != 0x03) {
printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",
hwif->name, sata_stat);
- HWGROUP(drive)->polling = 0;
- return ide_started;
+ return -ENXIO;
}
}
@@ -640,8 +642,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
hwif->irq = dev->irq;
hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00);
-
- hwif->mmio = 1;
}
static int is_dev_seagate_sata(ide_drive_t *drive)
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 4b0b85d8faf5..2389945ca95d 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -52,8 +52,6 @@
#include <linux/init.h>
#include <linux/ide.h>
-#include "ide-timing.h"
-
/* registers layout and init values are chipset family dependant */
#define ATA_16 0x01
@@ -569,6 +567,11 @@ static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_devi
{
struct ide_port_info d = sis5513_chipset;
u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f };
+ int rc;
+
+ rc = pci_enable_device(dev);
+ if (rc)
+ return rc;
if (sis_find_family(dev) == 0)
return -ENOTSUPP;
@@ -611,7 +614,6 @@ MODULE_LICENSE("GPL");
/*
* TODO:
* - CLEANUP
- * - Use drivers/ide/ide-timing.h !
* - More checks in the config registers (force values instead of
* relying on the BIOS setting them correctly).
* - Further optimisations ?
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index ce84fa045d39..6efbde297174 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -47,10 +47,11 @@
*/
static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
{
+ struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
unsigned int cmd_on, cmd_off;
u8 iordy = 0;
- cmd_on = (ide_pio_timings[pio].active_time + 29) / 30;
+ cmd_on = (t->active + 29) / 30;
cmd_off = (ide_pio_cycle_time(drive, pio) - 30 * cmd_on + 29) / 30;
if (cmd_on == 0)
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 566e0ecb8db1..e47384c70c40 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -35,8 +35,6 @@
#include <asm/processor.h>
#endif
-#include "ide-timing.h"
-
#define VIA_IDE_ENABLE 0x40
#define VIA_IDE_CONFIG 0x41
#define VIA_FIFO_CONFIG 0x43
@@ -120,21 +118,21 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
if (~vdev->via_config->flags & VIA_BAD_AST) {
pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
- t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
+ t = (t & ~(3 << ((3 - dn) << 1))) | ((clamp_val(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t);
}
pci_write_config_byte(dev, VIA_8BIT_TIMING + (1 - (dn >> 1)),
- ((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1));
+ ((clamp_val(timing->act8b, 1, 16) - 1) << 4) | (clamp_val(timing->rec8b, 1, 16) - 1));
pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
- ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
+ ((clamp_val(timing->active, 1, 16) - 1) << 4) | (clamp_val(timing->recover, 1, 16) - 1));
switch (vdev->via_config->udma_mask) {
- case ATA_UDMA2: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
- case ATA_UDMA4: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
- case ATA_UDMA5: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
- case ATA_UDMA6: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
+ case ATA_UDMA2: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 5) - 2)) : 0x03; break;
+ case ATA_UDMA4: t = timing->udma ? (0xe8 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x0f; break;
+ case ATA_UDMA5: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
+ case ATA_UDMA6: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
default: return;
}
@@ -340,7 +338,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
* Determine system bus clock.
*/
- via_clock = (ide_pci_clk ? ide_pci_clk : system_bus_clock()) * 1000;
+ via_clock = (ide_pci_clk ? ide_pci_clk : 33) * 1000;
switch (via_clock) {
case 33000: via_clock = 33333; break;
diff --git a/drivers/ide/ppc/Makefile b/drivers/ide/ppc/Makefile
index 65af5848b28c..74e52adcdf4b 100644
--- a/drivers/ide/ppc/Makefile
+++ b/drivers/ide/ppc/Makefile
@@ -1,3 +1,2 @@
obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o
-obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += mpc8xx.o
diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c
deleted file mode 100644
index f0e638dcc3ab..000000000000
--- a/drivers/ide/ppc/mpc8xx.c
+++ /dev/null
@@ -1,847 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Wolfgang Denk, wd@denx.de
- * Modified for direct IDE interface
- * by Thomas Lange, thomas@corelatus.com
- * Modified for direct IDE interface on 8xx without using the PCMCIA
- * controller
- * by Steven.Scholz@imc-berlin.de
- * Moved out of arch/ppc/kernel/m8xx_setup.c, other minor cleanups
- * by Mathew Locke <mattl@mvista.com>
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/tty.h>
-#include <linux/major.h>
-#include <linux/interrupt.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/ide.h>
-#include <linux/bootmem.h>
-
-#include <asm/mpc8xx.h>
-#include <asm/mmu.h>
-#include <asm/processor.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/ide.h>
-#include <asm/8xx_immap.h>
-#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);
-static int check_ide_device (unsigned long base);
-
-static void ide_interrupt_ack (void *dev);
-static void m8xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio);
-
-typedef struct ide_ioport_desc {
- unsigned long base_off; /* Offset to PCMCIA memory */
- unsigned long reg_off[IDE_NR_PORTS]; /* controller register offsets */
- int irq; /* IRQ */
-} ide_ioport_desc_t;
-
-ide_ioport_desc_t ioport_dsc[MAX_HWIFS] = {
-#ifdef IDE0_BASE_OFFSET
- { IDE0_BASE_OFFSET,
- {
- IDE0_DATA_REG_OFFSET,
- IDE0_ERROR_REG_OFFSET,
- IDE0_NSECTOR_REG_OFFSET,
- IDE0_SECTOR_REG_OFFSET,
- IDE0_LCYL_REG_OFFSET,
- IDE0_HCYL_REG_OFFSET,
- IDE0_SELECT_REG_OFFSET,
- IDE0_STATUS_REG_OFFSET,
- IDE0_CONTROL_REG_OFFSET,
- IDE0_IRQ_REG_OFFSET,
- },
- IDE0_INTERRUPT,
- },
-#ifdef IDE1_BASE_OFFSET
- { IDE1_BASE_OFFSET,
- {
- IDE1_DATA_REG_OFFSET,
- IDE1_ERROR_REG_OFFSET,
- IDE1_NSECTOR_REG_OFFSET,
- IDE1_SECTOR_REG_OFFSET,
- IDE1_LCYL_REG_OFFSET,
- IDE1_HCYL_REG_OFFSET,
- IDE1_SELECT_REG_OFFSET,
- IDE1_STATUS_REG_OFFSET,
- IDE1_CONTROL_REG_OFFSET,
- IDE1_IRQ_REG_OFFSET,
- },
- IDE1_INTERRUPT,
- },
-#endif /* IDE1_BASE_OFFSET */
-#endif /* IDE0_BASE_OFFSET */
-};
-
-ide_pio_timings_t ide_pio_clocks[6];
-int hold_time[6] = {30, 20, 15, 10, 10, 10 }; /* PIO Mode 5 with IORDY (nonstandard) */
-
-/*
- * Warning: only 1 (ONE) PCMCIA slot supported here,
- * which must be correctly initialized by the firmware (PPCBoot).
- */
-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 )
-
-#define M8XX_PCMCIA_CD2(slot) (0x10000000 >> (slot << 4))
-#define M8XX_PCMCIA_CD1(slot) (0x08000000 >> (slot << 4))
-
-/*
- * The TQM850L hardware has two pins swapped! Grrrrgh!
- */
-#ifdef CONFIG_TQM850L
-#define __MY_PCMCIA_GCRX_CXRESET PCMCIA_GCRX_CXOE
-#define __MY_PCMCIA_GCRX_CXOE PCMCIA_GCRX_CXRESET
-#else
-#define __MY_PCMCIA_GCRX_CXRESET PCMCIA_GCRX_CXRESET
-#define __MY_PCMCIA_GCRX_CXOE PCMCIA_GCRX_CXOE
-#endif
-
-#if defined(CONFIG_BLK_DEV_MPC8xx_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
-#define PCMCIA_SCHLVL IDE0_INTERRUPT /* Status Change Interrupt Level */
-static int pcmcia_schlvl = PCMCIA_SCHLVL;
-#endif
-
-/*
- * See include/linux/ide.h for definition of hw_regs_t (p, base)
- */
-
-/*
- * 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 int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
-{
- unsigned long *p = hw->io_ports_array;
- int i;
-
- typedef struct {
- ulong br;
- ulong or;
- } pcmcia_win_t;
- volatile pcmcia_win_t *win;
- volatile pcmconf8xx_t *pcmp;
-
- uint *pgcrx;
- u32 pcmcia_phy_base;
- u32 pcmcia_phy_end;
- static unsigned long pcmcia_base = 0;
- unsigned long base;
-
- *p = 0;
-
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
-
- if (!pcmcia_base) {
- /*
- * Read out PCMCIA registers. Since the reset values
- * are undefined, we sure hope that they have been
- * set up by firmware
- */
-
- /* Scan all registers for valid settings */
- pcmcia_phy_base = 0xFFFFFFFF;
- pcmcia_phy_end = 0;
- /* br0 is start of brX and orX regs */
- win = (pcmcia_win_t *) \
- (&(((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0));
- for (i = 0; i < 8; i++) {
- if (win->or & 1) { /* This bank is marked as valid */
- if (win->br < pcmcia_phy_base) {
- pcmcia_phy_base = win->br;
- }
- if ((win->br + PCMCIA_MEM_SIZE) > pcmcia_phy_end) {
- pcmcia_phy_end = win->br + PCMCIA_MEM_SIZE;
- }
- /* Check which slot that has been defined */
- _slot_ = (win->or >> 2) & 1;
-
- } /* Valid bank */
- win++;
- } /* for */
-
- printk ("PCMCIA slot %c: phys mem %08x...%08x (size %08x)\n",
- 'A' + _slot_,
- 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);
-
-#ifdef DEBUG
- printk ("PCMCIA virt base: %08lx\n", pcmcia_base);
-#endif
- /* Compute clock cycles for PIO timings */
- for (i=0; i<6; ++i) {
- bd_t *binfo = (bd_t *)__res;
-
- hold_time[i] =
- PCMCIA_MK_CLKS (hold_time[i],
- binfo->bi_busfreq);
- ide_pio_clocks[i].setup_time =
- PCMCIA_MK_CLKS (ide_pio_timings[i].setup_time,
- binfo->bi_busfreq);
- ide_pio_clocks[i].active_time =
- PCMCIA_MK_CLKS (ide_pio_timings[i].active_time,
- binfo->bi_busfreq);
- ide_pio_clocks[i].cycle_time =
- PCMCIA_MK_CLKS (ide_pio_timings[i].cycle_time,
- binfo->bi_busfreq);
-#if 0
- printk ("PIO mode %d timings: %d/%d/%d => %d/%d/%d\n",
- i,
- ide_pio_clocks[i].setup_time,
- ide_pio_clocks[i].active_time,
- ide_pio_clocks[i].hold_time,
- ide_pio_clocks[i].cycle_time,
- ide_pio_timings[i].setup_time,
- ide_pio_timings[i].active_time,
- ide_pio_timings[i].hold_time,
- ide_pio_timings[i].cycle_time);
-#endif
- }
- }
-
- if (_slot_ == -1) {
- printk ("PCMCIA slot has not been defined! Using A as default\n");
- _slot_ = 0;
- }
-
-#ifdef CONFIG_IDE_8xx_PCCARD
-
-#ifdef DEBUG
- printk ("PIPR = 0x%08X slot %c ==> mask = 0x%X\n",
- pcmp->pcmc_pipr,
- 'A' + _slot_,
- M8XX_PCMCIA_CD1(_slot_) | M8XX_PCMCIA_CD2(_slot_) );
-#endif /* DEBUG */
-
- 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 -ENODEV; /* No card in slot */
- }
-
- check_ide_device (pcmcia_base);
-
-#endif /* CONFIG_IDE_8xx_PCCARD */
-
- base = pcmcia_base + ioport_dsc[data_port].base_off;
-#ifdef DEBUG
- printk ("base: %08x + %08x = %08x\n",
- pcmcia_base, ioport_dsc[data_port].base_off, base);
-#endif
-
- for (i = 0; i < IDE_NR_PORTS; ++i) {
-#ifdef DEBUG
- printk ("port[%d]: %08x + %08x = %08x\n",
- i,
- base,
- ioport_dsc[data_port].reg_off[i],
- i, base + ioport_dsc[data_port].reg_off[i]);
-#endif
- *p++ = base + ioport_dsc[data_port].reg_off[i];
- }
-
- 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;
-
- if (_slot_)
- pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcrb;
- else
- pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcra;
-
- reg = *pgcrx;
- reg |= mk_int_int_mask (pcmcia_schlvl) << 24;
- reg |= mk_int_int_mask (pcmcia_schlvl) << 16;
- *pgcrx = reg;
- }
-#endif /* CONFIG_IDE_8xx_PCCARD */
-
- /* Enable Harddisk Interrupt,
- * and make it edge sensitive
- */
- /* (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);
-
-#ifdef CONFIG_IDE_8xx_PCCARD
- /* Make sure we don't get garbage irq */
- ((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pscr = 0xFFFF;
-
- /* Enable falling edge irq */
- pcmp->pcmc_per = 0x100000 >> (16 * _slot_);
-#endif /* CONFIG_IDE_8xx_PCCARD */
-
- return 0;
-}
-#endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */
-
-/*
- * m8xx_ide_init_ports() for a direct IDE interface _not_ using
- * MPC8xx's internal PCMCIA interface
- */
-#if defined(CONFIG_IDE_EXT_DIRECT)
-static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
-{
- unsigned long *p = hw->io_ports_array;
- int i;
-
- u32 ide_phy_base;
- u32 ide_phy_end;
- static unsigned long ide_base = 0;
- unsigned long base;
-
- *p = 0;
-
- if (!ide_base) {
-
- /* TODO:
- * - add code to read ORx, BRx
- */
- ide_phy_base = CFG_ATA_BASE_ADDR;
- ide_phy_end = CFG_ATA_BASE_ADDR + 0x200;
-
- 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);
-
-#ifdef DEBUG
- printk ("IDE virt base: %08lx\n", ide_base);
-#endif
- }
-
- base = ide_base + ioport_dsc[data_port].base_off;
-#ifdef DEBUG
- printk ("base: %08x + %08x = %08x\n",
- ide_base, ioport_dsc[data_port].base_off, base);
-#endif
-
- for (i = 0; i < IDE_NR_PORTS; ++i) {
-#ifdef DEBUG
- printk ("port[%d]: %08x + %08x = %08x\n",
- i,
- base,
- ioport_dsc[data_port].reg_off[i],
- i, base + ioport_dsc[data_port].reg_off[i]);
-#endif
- *p++ = base + ioport_dsc[data_port].reg_off[i];
- }
-
- /* 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
- */
- /* (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);
-
- return 0;
-}
-#endif /* CONFIG_IDE_8xx_DIRECT */
-
-
-/* -------------------------------------------------------------------- */
-
-
-/* PCMCIA Timing */
-#ifndef PCMCIA_SHT
-#define PCMCIA_SHT(t) ((t & 0x0F)<<16) /* Strobe Hold Time */
-#define PCMCIA_SST(t) ((t & 0x0F)<<12) /* Strobe Setup Time */
-#define PCMCIA_SL(t) ((t==32) ? 0 : ((t & 0x1F)<<7)) /* Strobe Length */
-#endif
-
-/* Calculate PIO timings */
-static void m8xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT)
- volatile pcmconf8xx_t *pcmp;
- ulong timing, mask, reg;
-
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
-
- mask = ~(PCMCIA_SHT(0xFF) | PCMCIA_SST(0xFF) | PCMCIA_SL(0xFF));
-
- timing = PCMCIA_SHT(hold_time[pio] )
- | PCMCIA_SST(ide_pio_clocks[pio].setup_time )
- | PCMCIA_SL (ide_pio_clocks[pio].active_time)
- ;
-
-#if 1
- printk ("Setting timing bits 0x%08lx in PCMCIA controller\n", timing);
-#endif
- if ((reg = pcmp->pcmc_por0 & mask) != 0)
- pcmp->pcmc_por0 = reg | timing;
-
- if ((reg = pcmp->pcmc_por1 & mask) != 0)
- pcmp->pcmc_por1 = reg | timing;
-
- if ((reg = pcmp->pcmc_por2 & mask) != 0)
- pcmp->pcmc_por2 = reg | timing;
-
- if ((reg = pcmp->pcmc_por3 & mask) != 0)
- pcmp->pcmc_por3 = reg | timing;
-
- if ((reg = pcmp->pcmc_por4 & mask) != 0)
- pcmp->pcmc_por4 = reg | timing;
-
- if ((reg = pcmp->pcmc_por5 & mask) != 0)
- pcmp->pcmc_por5 = reg | timing;
-
- if ((reg = pcmp->pcmc_por6 & mask) != 0)
- pcmp->pcmc_por6 = reg | timing;
-
- if ((reg = pcmp->pcmc_por7 & mask) != 0)
- pcmp->pcmc_por7 = reg | timing;
-
-#elif defined(CONFIG_IDE_EXT_DIRECT)
-
- printk("%s[%d] %s: not implemented yet!\n",
- __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)
-{
-#ifdef CONFIG_IDE_8xx_PCCARD
- u_int pscr, pipr;
-
-#if (PCMCIA_SOCKETS_NO == 2)
- u_int _slot_;
-#endif
-
- /* get interrupt sources */
-
- pscr = ((volatile immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr;
- pipr = ((volatile immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
-
- /*
- * report only if both card detect signals are the same
- * not too nice done,
- * we depend on that CD2 is the bit to the left of CD1...
- */
-
- if(_slot_==-1){
- printk("PCMCIA slot has not been defined! Using A as default\n");
- _slot_=0;
- }
-
- if(((pipr & M8XX_PCMCIA_CD2(_slot_)) >> 1) ^
- (pipr & M8XX_PCMCIA_CD1(_slot_)) ) {
- printk ("card detect interrupt\n");
- }
- /* clear the interrupt sources */
- ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr;
-
-#else /* ! CONFIG_IDE_8xx_PCCARD */
- /*
- * Only CONFIG_IDE_8xx_PCCARD is using the interrupt of the
- * MPC8xx's PCMCIA controller, so there is nothing to be done here
- * for CONFIG_IDE_8xx_DIRECT and CONFIG_IDE_EXT_DIRECT.
- * The interrupt is handled somewhere else. -- Steven
- */
-#endif /* CONFIG_IDE_8xx_PCCARD */
-}
-
-
-
-/*
- * CIS Tupel codes
- */
-#define CISTPL_NULL 0x00
-#define CISTPL_DEVICE 0x01
-#define CISTPL_LONGLINK_CB 0x02
-#define CISTPL_INDIRECT 0x03
-#define CISTPL_CONFIG_CB 0x04
-#define CISTPL_CFTABLE_ENTRY_CB 0x05
-#define CISTPL_LONGLINK_MFC 0x06
-#define CISTPL_BAR 0x07
-#define CISTPL_PWR_MGMNT 0x08
-#define CISTPL_EXTDEVICE 0x09
-#define CISTPL_CHECKSUM 0x10
-#define CISTPL_LONGLINK_A 0x11
-#define CISTPL_LONGLINK_C 0x12
-#define CISTPL_LINKTARGET 0x13
-#define CISTPL_NO_LINK 0x14
-#define CISTPL_VERS_1 0x15
-#define CISTPL_ALTSTR 0x16
-#define CISTPL_DEVICE_A 0x17
-#define CISTPL_JEDEC_C 0x18
-#define CISTPL_JEDEC_A 0x19
-#define CISTPL_CONFIG 0x1a
-#define CISTPL_CFTABLE_ENTRY 0x1b
-#define CISTPL_DEVICE_OC 0x1c
-#define CISTPL_DEVICE_OA 0x1d
-#define CISTPL_DEVICE_GEO 0x1e
-#define CISTPL_DEVICE_GEO_A 0x1f
-#define CISTPL_MANFID 0x20
-#define CISTPL_FUNCID 0x21
-#define CISTPL_FUNCE 0x22
-#define CISTPL_SWIL 0x23
-#define CISTPL_END 0xff
-
-/*
- * CIS Function ID codes
- */
-#define CISTPL_FUNCID_MULTI 0x00
-#define CISTPL_FUNCID_MEMORY 0x01
-#define CISTPL_FUNCID_SERIAL 0x02
-#define CISTPL_FUNCID_PARALLEL 0x03
-#define CISTPL_FUNCID_FIXED 0x04
-#define CISTPL_FUNCID_VIDEO 0x05
-#define CISTPL_FUNCID_NETWORK 0x06
-#define CISTPL_FUNCID_AIMS 0x07
-#define CISTPL_FUNCID_SCSI 0x08
-
-/*
- * Fixed Disk FUNCE codes
- */
-#define CISTPL_IDE_INTERFACE 0x01
-
-#define CISTPL_FUNCE_IDE_IFACE 0x01
-#define CISTPL_FUNCE_IDE_MASTER 0x02
-#define CISTPL_FUNCE_IDE_SLAVE 0x03
-
-/* First feature byte */
-#define CISTPL_IDE_SILICON 0x04
-#define CISTPL_IDE_UNIQUE 0x08
-#define CISTPL_IDE_DUAL 0x10
-
-/* Second feature byte */
-#define CISTPL_IDE_HAS_SLEEP 0x01
-#define CISTPL_IDE_HAS_STANDBY 0x02
-#define CISTPL_IDE_HAS_IDLE 0x04
-#define CISTPL_IDE_LOW_POWER 0x08
-#define CISTPL_IDE_REG_INHIBIT 0x10
-#define CISTPL_IDE_HAS_INDEX 0x20
-#define CISTPL_IDE_IOIS16 0x40
-
-
-/* -------------------------------------------------------------------- */
-
-
-#define MAX_TUPEL_SZ 512
-#define MAX_FEATURES 4
-
-static int check_ide_device (unsigned long base)
-{
- volatile u8 *ident = NULL;
- volatile u8 *feature_p[MAX_FEATURES];
- volatile u8 *p, *start;
- int n_features = 0;
- u8 func_id = ~0;
- u8 code, len;
- unsigned short config_base = 0;
- int found = 0;
- int i;
-
-#ifdef DEBUG
- printk ("PCMCIA MEM: %08lX\n", base);
-#endif
- start = p = (volatile u8 *) base;
-
- while ((p - start) < MAX_TUPEL_SZ) {
-
- code = *p; p += 2;
-
- if (code == 0xFF) { /* End of chain */
- break;
- }
-
- len = *p; p += 2;
-#ifdef DEBUG_PCMCIA
- { volatile u8 *q = p;
- printk ("\nTuple code %02x length %d\n\tData:",
- code, len);
-
- for (i = 0; i < len; ++i) {
- printk (" %02x", *q);
- q+= 2;
- }
- }
-#endif /* DEBUG_PCMCIA */
- switch (code) {
- case CISTPL_VERS_1:
- ident = p + 4;
- break;
- case CISTPL_FUNCID:
- func_id = *p;
- break;
- case CISTPL_FUNCE:
- if (n_features < MAX_FEATURES)
- feature_p[n_features++] = p;
- break;
- case CISTPL_CONFIG:
- config_base = (*(p+6) << 8) + (*(p+4));
- default:
- break;
- }
- p += 2 * len;
- }
-
- found = identify (ident);
-
- if (func_id != ((u8)~0)) {
- print_funcid (func_id);
-
- if (func_id == CISTPL_FUNCID_FIXED)
- found = 1;
- else
- return (1); /* no disk drive */
- }
-
- for (i=0; i<n_features; ++i) {
- print_fixed (feature_p[i]);
- }
-
- if (!found) {
- printk ("unknown card type\n");
- return (1);
- }
-
- /* set level mode irq and I/O mapped device in config reg*/
- *((u8 *)(base + config_base)) = 0x41;
-
- return (0);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void print_funcid (int func)
-{
- switch (func) {
- case CISTPL_FUNCID_MULTI:
- printk (" Multi-Function");
- break;
- case CISTPL_FUNCID_MEMORY:
- printk (" Memory");
- break;
- case CISTPL_FUNCID_SERIAL:
- printk (" Serial Port");
- break;
- case CISTPL_FUNCID_PARALLEL:
- printk (" Parallel Port");
- break;
- case CISTPL_FUNCID_FIXED:
- printk (" Fixed Disk");
- break;
- case CISTPL_FUNCID_VIDEO:
- printk (" Video Adapter");
- break;
- case CISTPL_FUNCID_NETWORK:
- printk (" Network Adapter");
- break;
- case CISTPL_FUNCID_AIMS:
- printk (" AIMS Card");
- break;
- case CISTPL_FUNCID_SCSI:
- printk (" SCSI Adapter");
- break;
- default:
- printk (" Unknown");
- break;
- }
- printk (" Card\n");
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void print_fixed (volatile u8 *p)
-{
- if (p == NULL)
- return;
-
- switch (*p) {
- case CISTPL_FUNCE_IDE_IFACE:
- { u8 iface = *(p+2);
-
- printk ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
- printk (" interface ");
- break;
- }
- case CISTPL_FUNCE_IDE_MASTER:
- case CISTPL_FUNCE_IDE_SLAVE:
- { u8 f1 = *(p+2);
- u8 f2 = *(p+4);
-
- printk ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
-
- if (f1 & CISTPL_IDE_UNIQUE)
- printk (" [unique]");
-
- printk ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
-
- if (f2 & CISTPL_IDE_HAS_SLEEP)
- printk (" [sleep]");
-
- if (f2 & CISTPL_IDE_HAS_STANDBY)
- printk (" [standby]");
-
- if (f2 & CISTPL_IDE_HAS_IDLE)
- printk (" [idle]");
-
- if (f2 & CISTPL_IDE_LOW_POWER)
- printk (" [low power]");
-
- if (f2 & CISTPL_IDE_REG_INHIBIT)
- printk (" [reg inhibit]");
-
- if (f2 & CISTPL_IDE_HAS_INDEX)
- printk (" [index]");
-
- if (f2 & CISTPL_IDE_IOIS16)
- printk (" [IOis16]");
-
- break;
- }
- }
- printk ("\n");
-}
-
-/* ------------------------------------------------------------------------- */
-
-
-#define MAX_IDENT_CHARS 64
-#define MAX_IDENT_FIELDS 4
-
-static u8 *known_cards[] = {
- "ARGOSY PnPIDE D5",
- NULL
-};
-
-static int identify (volatile u8 *p)
-{
- u8 id_str[MAX_IDENT_CHARS];
- u8 data;
- u8 *t;
- u8 **card;
- int i, done;
-
- if (p == NULL)
- return (0); /* Don't know */
-
- t = id_str;
- done =0;
-
- for (i=0; i<=4 && !done; ++i, p+=2) {
- while ((data = *p) != '\0') {
- if (data == 0xFF) {
- done = 1;
- break;
- }
- *t++ = data;
- if (t == &id_str[MAX_IDENT_CHARS-1]) {
- done = 1;
- break;
- }
- p += 2;
- }
- if (!done)
- *t++ = ' ';
- }
- *t = '\0';
- while (--t > id_str) {
- if (*t == ' ')
- *t = '\0';
- else
- break;
- }
- printk ("Card ID: %s\n", id_str);
-
- for (card=known_cards; *card; ++card) {
- if (strcmp(*card, id_str) == 0) { /* found! */
- return (1);
- }
- }
-
- return (0); /* don't know */
-}
-
-static int __init mpc8xx_ide_probe(void)
-{
- hw_regs_t hw;
- u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-
-#ifdef IDE0_BASE_OFFSET
- 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
- 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
-
- ide_device_add(idx, NULL);
-
- return 0;
-}
-
-module_init(mpc8xx_ide_probe);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 48aa019127bc..93fb9067c043 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -5,7 +5,7 @@
* for doing DMA.
*
* Copyright (C) 1998-2003 Paul Mackerras & Ben. Herrenschmidt
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2008 Bartlomiej Zolnierkiewicz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -48,8 +48,6 @@
#include <asm/mediabay.h>
#endif
-#include "../ide-timing.h"
-
#undef IDE_PMAC_DEBUG
#define DMA_WAIT_TIMEOUT 50
@@ -59,7 +57,6 @@ typedef struct pmac_ide_hwif {
int irq;
int kind;
int aapl_bus_id;
- unsigned cable_80 : 1;
unsigned mediabay : 1;
unsigned broken_dma : 1;
unsigned broken_dma_warn : 1;
@@ -481,13 +478,13 @@ pmac_ide_do_update_timings(ide_drive_t *drive)
pmac_ide_selectproc(drive);
}
-static void
-pmac_outbsync(ide_drive_t *drive, u8 value, unsigned long port)
+static void pmac_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port)
{
u32 tmp;
writeb(value, (void __iomem *) port);
- tmp = readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
+ tmp = readl((void __iomem *)(hwif->io_ports.data_addr
+ + IDE_TIMING_CONFIG));
}
/*
@@ -496,6 +493,7 @@ pmac_outbsync(ide_drive_t *drive, u8 value, unsigned long port)
static void
pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
+ struct ide_timing *tim = ide_timing_find_mode(XFER_PIO_0 + pio);
u32 *timings, t;
unsigned accessTicks, recTicks;
unsigned accessTime, recTime;
@@ -527,10 +525,9 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
}
case controller_kl_ata4:
/* 66Mhz cell */
- recTime = cycle_time - ide_pio_timings[pio].active_time
- - ide_pio_timings[pio].setup_time;
+ recTime = cycle_time - tim->active - tim->setup;
recTime = max(recTime, 150U);
- accessTime = ide_pio_timings[pio].active_time;
+ accessTime = tim->active;
accessTime = max(accessTime, 150U);
accessTicks = SYSCLK_TICKS_66(accessTime);
accessTicks = min(accessTicks, 0x1fU);
@@ -543,10 +540,9 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
default: {
/* 33Mhz cell */
int ebit = 0;
- recTime = cycle_time - ide_pio_timings[pio].active_time
- - ide_pio_timings[pio].setup_time;
+ recTime = cycle_time - tim->active - tim->setup;
recTime = max(recTime, 150U);
- accessTime = ide_pio_timings[pio].active_time;
+ accessTime = tim->active;
accessTime = max(accessTime, 150U);
accessTicks = SYSCLK_TICKS(accessTime);
accessTicks = min(accessTicks, 0x1fU);
@@ -918,10 +914,40 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
return 0;
}
+static u8 pmac_ide_cable_detect(ide_hwif_t *hwif)
+{
+ pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)ide_get_hwifdata(hwif);
+ struct device_node *np = pmif->node;
+ const char *cable = of_get_property(np, "cable-type", NULL);
+
+ /* Get cable type from device-tree. */
+ if (cable && !strncmp(cable, "80-", 3))
+ return ATA_CBL_PATA80;
+
+ /*
+ * G5's seem to have incorrect cable type in device-tree.
+ * Let's assume they have a 80 conductor cable, this seem
+ * to be always the case unless the user mucked around.
+ */
+ if (of_device_is_compatible(np, "K2-UATA") ||
+ of_device_is_compatible(np, "shasta-ata"))
+ return ATA_CBL_PATA80;
+
+ return ATA_CBL_PATA40;
+}
+
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,
+ .cable_detect = pmac_ide_cable_detect,
+};
+
+static const struct ide_port_ops pmac_ide_ata4_port_ops = {
+ .set_pio_mode = pmac_ide_set_pio_mode,
+ .set_dma_mode = pmac_ide_set_dma_mode,
+ .selectproc = pmac_ide_selectproc,
+ .cable_detect = pmac_ide_cable_detect,
};
static const struct ide_port_ops pmac_ide_port_ops = {
@@ -949,10 +975,7 @@ static const struct ide_port_info pmac_port_info = {
/*
* Setup, register & probe an IDE channel driven by this driver, this is
- * called by one of the 2 probe functions (macio or PCI). Note that a channel
- * that ends up beeing free of any device is not kept around by this driver
- * (it is kept in 2.4). This introduce an interface numbering change on some
- * rare machines unfortunately, but it's better this way.
+ * called by one of the 2 probe functions (macio or PCI).
*/
static int __devinit
pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
@@ -962,7 +985,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
struct ide_port_info d = pmac_port_info;
- pmif->cable_80 = 0;
pmif->broken_dma = pmif->broken_dma_warn = 0;
if (of_device_is_compatible(np, "shasta-ata")) {
pmif->kind = controller_sh_ata6;
@@ -979,6 +1001,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
} else if (of_device_is_compatible(np, "keylargo-ata")) {
if (strcmp(np->name, "ata-4") == 0) {
pmif->kind = controller_kl_ata4;
+ d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA4;
} else
pmif->kind = controller_kl_ata3;
@@ -992,22 +1015,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
bidp = of_get_property(np, "AAPL,bus-id", NULL);
pmif->aapl_bus_id = bidp ? *bidp : 0;
- /* Get cable type from device-tree */
- if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6
- || pmif->kind == controller_k2_ata6
- || pmif->kind == controller_sh_ata6) {
- const char* cable = of_get_property(np, "cable-type", NULL);
- if (cable && !strncmp(cable, "80-", 3))
- pmif->cable_80 = 1;
- }
- /* G5's seem to have incorrect cable type in device-tree. Let's assume
- * they have a 80 conductor cable, this seem to be always the case unless
- * the user mucked around
- */
- if (of_device_is_compatible(np, "K2-UATA") ||
- of_device_is_compatible(np, "shasta-ata"))
- pmif->cable_80 = 1;
-
/* On Kauai-type controllers, we make sure the FCR is correct */
if (pmif->kauai_fcr)
writel(KAUAI_FCR_UATA_MAGIC |
@@ -1053,7 +1060,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
hwif->hwif_data = pmif;
ide_init_port_hw(hwif, hw);
- hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
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,
@@ -1070,11 +1076,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
}
}
-#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
- if (pmif->cable_80 == 0)
- d.udma_mask &= ATA_UDMA2;
-#endif
-
idx[0] = hwif->index;
ide_device_add(idx, &d);
@@ -1147,8 +1148,6 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
base = ioremap(macio_resource_start(mdev, 0), 0x400);
regbase = (unsigned long) base;
- hwif->dev = &mdev->bus->pdev->dev;
-
pmif->mdev = mdev;
pmif->node = mdev->ofdev.node;
pmif->regbase = regbase;
@@ -1170,7 +1169,8 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
memset(&hw, 0, sizeof(hw));
pmac_ide_init_ports(&hw, pmif->regbase);
hw.irq = irq;
- hw.dev = &mdev->ofdev.dev;
+ hw.dev = &mdev->bus->pdev->dev;
+ hw.parent = &mdev->ofdev.dev;
rc = pmac_ide_setup_device(pmif, hwif, &hw);
if (rc != 0) {
@@ -1270,7 +1270,6 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_free_pmif;
}
- hwif->dev = &pdev->dev;
pmif->mdev = NULL;
pmif->node = np;
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 5171601fb255..65fc08b6b6d0 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -6,19 +6,15 @@
* May be copied or modified under the terms of the GNU General Public License
*/
-#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/ide.h>
#include <linux/dma-mapping.h>
#include <asm/io.h>
-#include <asm/irq.h>
/**
* ide_setup_pci_baseregs - place a PCI IDE controller native
@@ -87,7 +83,7 @@ unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d)
unsigned long dma_base = 0;
u8 dma_stat = 0;
- if (hwif->mmio)
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
return hwif->dma_base;
if (hwif->mate && hwif->mate->dma_base) {
@@ -319,25 +315,22 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
ctl = pci_resource_start(dev, 2*port+1);
base = pci_resource_start(dev, 2*port);
- if ((ctl && !base) || (base && !ctl)) {
- printk(KERN_ERR "%s: inconsistent baseregs (BIOS) "
- "for port %d, skipping\n", d->name, port);
- return NULL;
- }
- }
- if (!ctl) {
+ } else {
/* Use default values */
ctl = port ? 0x374 : 0x3f4;
base = port ? 0x170 : 0x1f0;
}
- hwif = ide_find_port_slot(d);
- if (hwif == NULL) {
- printk(KERN_ERR "%s: too many IDE interfaces, no room in "
- "table\n", d->name);
+ if (!base || !ctl) {
+ printk(KERN_ERR "%s: bad PCI BARs for port %d, skipping\n",
+ d->name, port);
return NULL;
}
+ hwif = ide_find_port_slot(d);
+ if (hwif == NULL)
+ return NULL;
+
memset(&hw, 0, sizeof(hw));
hw.irq = irq;
hw.dev = &dev->dev;
@@ -346,8 +339,6 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
ide_init_port_hw(hwif, &hw);
- hwif->dev = &dev->dev;
-
return hwif;
}
@@ -374,7 +365,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
if (base == 0 || ide_pci_set_master(dev, d->name) < 0)
return -1;
- if (hwif->mmio)
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name);
else
printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n",